You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

10534 lines
307 KiB

/*
THIS IS A GENERATED/BUNDLED FILE BY ROLLUP
if you want to view the source visit the plugins github repository
*/
'use strict';
var obsidian = require('obsidian');
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
function noop() { }
function assign(tar, src) {
// @ts-ignore
for (const k in src)
tar[k] = src[k];
return tar;
}
function run(fn) {
return fn();
}
function blank_object() {
return Object.create(null);
}
function run_all(fns) {
fns.forEach(run);
}
function is_function(thing) {
return typeof thing === 'function';
}
function safe_not_equal(a, b) {
return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function');
}
function is_empty(obj) {
return Object.keys(obj).length === 0;
}
function subscribe(store, ...callbacks) {
if (store == null) {
return noop;
}
const unsub = store.subscribe(...callbacks);
return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub;
}
function get_store_value(store) {
let value;
subscribe(store, _ => value = _)();
return value;
}
function component_subscribe(component, store, callback) {
component.$$.on_destroy.push(subscribe(store, callback));
}
function create_slot(definition, ctx, $$scope, fn) {
if (definition) {
const slot_ctx = get_slot_context(definition, ctx, $$scope, fn);
return definition[0](slot_ctx);
}
}
function get_slot_context(definition, ctx, $$scope, fn) {
return definition[1] && fn
? assign($$scope.ctx.slice(), definition[1](fn(ctx)))
: $$scope.ctx;
}
function get_slot_changes(definition, $$scope, dirty, fn) {
if (definition[2] && fn) {
const lets = definition[2](fn(dirty));
if ($$scope.dirty === undefined) {
return lets;
}
if (typeof lets === 'object') {
const merged = [];
const len = Math.max($$scope.dirty.length, lets.length);
for (let i = 0; i < len; i += 1) {
merged[i] = $$scope.dirty[i] | lets[i];
}
return merged;
}
return $$scope.dirty | lets;
}
return $$scope.dirty;
}
function update_slot(slot, slot_definition, ctx, $$scope, dirty, get_slot_changes_fn, get_slot_context_fn) {
const slot_changes = get_slot_changes(slot_definition, $$scope, dirty, get_slot_changes_fn);
if (slot_changes) {
const slot_context = get_slot_context(slot_definition, ctx, $$scope, get_slot_context_fn);
slot.p(slot_context, slot_changes);
}
}
function exclude_internal_props(props) {
const result = {};
for (const k in props)
if (k[0] !== '$')
result[k] = props[k];
return result;
}
function set_store_value(store, ret, value = ret) {
store.set(value);
return ret;
}
function append(target, node) {
target.appendChild(node);
}
function insert(target, node, anchor) {
target.insertBefore(node, anchor || null);
}
function detach(node) {
node.parentNode.removeChild(node);
}
function destroy_each(iterations, detaching) {
for (let i = 0; i < iterations.length; i += 1) {
if (iterations[i])
iterations[i].d(detaching);
}
}
function element(name) {
return document.createElement(name);
}
function text(data) {
return document.createTextNode(data);
}
function space() {
return text(' ');
}
function empty() {
return text('');
}
function listen(node, event, handler, options) {
node.addEventListener(event, handler, options);
return () => node.removeEventListener(event, handler, options);
}
function prevent_default(fn) {
return function (event) {
event.preventDefault();
// @ts-ignore
return fn.call(this, event);
};
}
function attr(node, attribute, value) {
if (value == null)
node.removeAttribute(attribute);
else if (node.getAttribute(attribute) !== value)
node.setAttribute(attribute, value);
}
function children(element) {
return Array.from(element.childNodes);
}
function set_data(text, data) {
data = '' + data;
if (text.wholeText !== data)
text.data = data;
}
function set_input_value(input, value) {
input.value = value == null ? '' : value;
}
function select_option(select, value) {
for (let i = 0; i < select.options.length; i += 1) {
const option = select.options[i];
if (option.__value === value) {
option.selected = true;
return;
}
}
}
function select_value(select) {
const selected_option = select.querySelector(':checked') || select.options[0];
return selected_option && selected_option.__value;
}
function toggle_class(element, name, toggle) {
element.classList[toggle ? 'add' : 'remove'](name);
}
function custom_event(type, detail) {
const e = document.createEvent('CustomEvent');
e.initCustomEvent(type, false, false, detail);
return e;
}
let current_component;
function set_current_component(component) {
current_component = component;
}
function get_current_component() {
if (!current_component)
throw new Error('Function called outside component initialization');
return current_component;
}
function onMount(fn) {
get_current_component().$$.on_mount.push(fn);
}
function onDestroy(fn) {
get_current_component().$$.on_destroy.push(fn);
}
function createEventDispatcher() {
const component = get_current_component();
return (type, detail) => {
const callbacks = component.$$.callbacks[type];
if (callbacks) {
// TODO are there situations where events could be dispatched
// in a server (non-DOM) environment?
const event = custom_event(type, detail);
callbacks.slice().forEach(fn => {
fn.call(component, event);
});
}
};
}
function setContext(key, context) {
get_current_component().$$.context.set(key, context);
}
function getContext(key) {
return get_current_component().$$.context.get(key);
}
const dirty_components = [];
const binding_callbacks = [];
const render_callbacks = [];
const flush_callbacks = [];
const resolved_promise = Promise.resolve();
let update_scheduled = false;
function schedule_update() {
if (!update_scheduled) {
update_scheduled = true;
resolved_promise.then(flush);
}
}
function add_render_callback(fn) {
render_callbacks.push(fn);
}
function add_flush_callback(fn) {
flush_callbacks.push(fn);
}
let flushing = false;
const seen_callbacks = new Set();
function flush() {
if (flushing)
return;
flushing = true;
do {
// first, call beforeUpdate functions
// and update components
for (let i = 0; i < dirty_components.length; i += 1) {
const component = dirty_components[i];
set_current_component(component);
update(component.$$);
}
set_current_component(null);
dirty_components.length = 0;
while (binding_callbacks.length)
binding_callbacks.pop()();
// then, once components are updated, call
// afterUpdate functions. This may cause
// subsequent updates...
for (let i = 0; i < render_callbacks.length; i += 1) {
const callback = render_callbacks[i];
if (!seen_callbacks.has(callback)) {
// ...so guard against infinite loops
seen_callbacks.add(callback);
callback();
}
}
render_callbacks.length = 0;
} while (dirty_components.length);
while (flush_callbacks.length) {
flush_callbacks.pop()();
}
update_scheduled = false;
flushing = false;
seen_callbacks.clear();
}
function update($$) {
if ($$.fragment !== null) {
$$.update();
run_all($$.before_update);
const dirty = $$.dirty;
$$.dirty = [-1];
$$.fragment && $$.fragment.p($$.ctx, dirty);
$$.after_update.forEach(add_render_callback);
}
}
const outroing = new Set();
let outros;
function group_outros() {
outros = {
r: 0,
c: [],
p: outros // parent group
};
}
function check_outros() {
if (!outros.r) {
run_all(outros.c);
}
outros = outros.p;
}
function transition_in(block, local) {
if (block && block.i) {
outroing.delete(block);
block.i(local);
}
}
function transition_out(block, local, detach, callback) {
if (block && block.o) {
if (outroing.has(block))
return;
outroing.add(block);
outros.c.push(() => {
outroing.delete(block);
if (callback) {
if (detach)
block.d(1);
callback();
}
});
block.o(local);
}
}
const globals = (typeof window !== 'undefined'
? window
: typeof globalThis !== 'undefined'
? globalThis
: global);
function outro_and_destroy_block(block, lookup) {
transition_out(block, 1, 1, () => {
lookup.delete(block.key);
});
}
function update_keyed_each(old_blocks, dirty, get_key, dynamic, ctx, list, lookup, node, destroy, create_each_block, next, get_context) {
let o = old_blocks.length;
let n = list.length;
let i = o;
const old_indexes = {};
while (i--)
old_indexes[old_blocks[i].key] = i;
const new_blocks = [];
const new_lookup = new Map();
const deltas = new Map();
i = n;
while (i--) {
const child_ctx = get_context(ctx, list, i);
const key = get_key(child_ctx);
let block = lookup.get(key);
if (!block) {
block = create_each_block(key, child_ctx);
block.c();
}
else if (dynamic) {
block.p(child_ctx, dirty);
}
new_lookup.set(key, new_blocks[i] = block);
if (key in old_indexes)
deltas.set(key, Math.abs(i - old_indexes[key]));
}
const will_move = new Set();
const did_move = new Set();
function insert(block) {
transition_in(block, 1);
block.m(node, next);
lookup.set(block.key, block);
next = block.first;
n--;
}
while (o && n) {
const new_block = new_blocks[n - 1];
const old_block = old_blocks[o - 1];
const new_key = new_block.key;
const old_key = old_block.key;
if (new_block === old_block) {
// do nothing
next = new_block.first;
o--;
n--;
}
else if (!new_lookup.has(old_key)) {
// remove old block
destroy(old_block, lookup);
o--;
}
else if (!lookup.has(new_key) || will_move.has(new_key)) {
insert(new_block);
}
else if (did_move.has(old_key)) {
o--;
}
else if (deltas.get(new_key) > deltas.get(old_key)) {
did_move.add(new_key);
insert(new_block);
}
else {
will_move.add(old_key);
o--;
}
}
while (o--) {
const old_block = old_blocks[o];
if (!new_lookup.has(old_block.key))
destroy(old_block, lookup);
}
while (n)
insert(new_blocks[n - 1]);
return new_blocks;
}
function bind(component, name, callback) {
const index = component.$$.props[name];
if (index !== undefined) {
component.$$.bound[index] = callback;
callback(component.$$.ctx[index]);
}
}
function create_component(block) {
block && block.c();
}
function mount_component(component, target, anchor, customElement) {
const { fragment, on_mount, on_destroy, after_update } = component.$$;
fragment && fragment.m(target, anchor);
if (!customElement) {
// onMount happens before the initial afterUpdate
add_render_callback(() => {
const new_on_destroy = on_mount.map(run).filter(is_function);
if (on_destroy) {
on_destroy.push(...new_on_destroy);
}
else {
// Edge case - component was destroyed immediately,
// most likely as a result of a binding initialising
run_all(new_on_destroy);
}
component.$$.on_mount = [];
});
}
after_update.forEach(add_render_callback);
}
function destroy_component(component, detaching) {
const $$ = component.$$;
if ($$.fragment !== null) {
run_all($$.on_destroy);
$$.fragment && $$.fragment.d(detaching);
// TODO null out other refs, including component.$$ (but need to
// preserve final state?)
$$.on_destroy = $$.fragment = null;
$$.ctx = [];
}
}
function make_dirty(component, i) {
if (component.$$.dirty[0] === -1) {
dirty_components.push(component);
schedule_update();
component.$$.dirty.fill(0);
}
component.$$.dirty[(i / 31) | 0] |= (1 << (i % 31));
}
function init(component, options, instance, create_fragment, not_equal, props, dirty = [-1]) {
const parent_component = current_component;
set_current_component(component);
const $$ = component.$$ = {
fragment: null,
ctx: null,
// state
props,
update: noop,
not_equal,
bound: blank_object(),
// lifecycle
on_mount: [],
on_destroy: [],
on_disconnect: [],
before_update: [],
after_update: [],
context: new Map(parent_component ? parent_component.$$.context : options.context || []),
// everything else
callbacks: blank_object(),
dirty,
skip_bound: false
};
let ready = false;
$$.ctx = instance
? instance(component, options.props || {}, (i, ret, ...rest) => {
const value = rest.length ? rest[0] : ret;
if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) {
if (!$$.skip_bound && $$.bound[i])
$$.bound[i](value);
if (ready)
make_dirty(component, i);
}
return ret;
})
: [];
$$.update();
ready = true;
run_all($$.before_update);
// `false` as a special case of no DOM component
$$.fragment = create_fragment ? create_fragment($$.ctx) : false;
if (options.target) {
if (options.hydrate) {
const nodes = children(options.target);
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
$$.fragment && $$.fragment.l(nodes);
nodes.forEach(detach);
}
else {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
$$.fragment && $$.fragment.c();
}
if (options.intro)
transition_in(component.$$.fragment);
mount_component(component, options.target, options.anchor, options.customElement);
flush();
}
set_current_component(parent_component);
}
/**
* Base class for Svelte components. Used when dev=false.
*/
class SvelteComponent {
$destroy() {
destroy_component(this, 1);
this.$destroy = noop;
}
$on(type, callback) {
const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = []));
callbacks.push(callback);
return () => {
const index = callbacks.indexOf(callback);
if (index !== -1)
callbacks.splice(index, 1);
};
}
$set($$props) {
if (this.$$set && !is_empty($$props)) {
this.$$.skip_bound = true;
this.$$set($$props);
this.$$.skip_bound = false;
}
}
}
const subscriber_queue = [];
/**
* Creates a `Readable` store that allows reading by subscription.
* @param value initial value
* @param {StartStopNotifier}start start and stop notifications for subscriptions
*/
function readable(value, start) {
return {
subscribe: writable(value, start).subscribe
};
}
/**
* Create a `Writable` store that allows both updating and reading by subscription.
* @param {*=}value initial value
* @param {StartStopNotifier=}start start and stop notifications for subscriptions
*/
function writable(value, start = noop) {
let stop;
const subscribers = [];
function set(new_value) {
if (safe_not_equal(value, new_value)) {
value = new_value;
if (stop) { // store is ready
const run_queue = !subscriber_queue.length;
for (let i = 0; i < subscribers.length; i += 1) {
const s = subscribers[i];
s[1]();
subscriber_queue.push(s, value);
}
if (run_queue) {
for (let i = 0; i < subscriber_queue.length; i += 2) {
subscriber_queue[i][0](subscriber_queue[i + 1]);
}
subscriber_queue.length = 0;
}
}
}
}
function update(fn) {
set(fn(value));
}
function subscribe(run, invalidate = noop) {
const subscriber = [run, invalidate];
subscribers.push(subscriber);
if (subscribers.length === 1) {
stop = start(set) || noop;
}
run(value);
return () => {
const index = subscribers.indexOf(subscriber);
if (index !== -1) {
subscribers.splice(index, 1);
}
if (subscribers.length === 0) {
stop();
stop = null;
}
};
}
return { set, update, subscribe };
}
function derived(stores, fn, initial_value) {
const single = !Array.isArray(stores);
const stores_array = single
? [stores]
: stores;
const auto = fn.length < 2;
return readable(initial_value, (set) => {
let inited = false;
const values = [];
let pending = 0;
let cleanup = noop;
const sync = () => {
if (pending) {
return;
}
cleanup();
const result = fn(single ? values[0] : values, set);
if (auto) {
set(result);
}
else {
cleanup = is_function(result) ? result : noop;
}
};
const unsubscribers = stores_array.map((store, i) => subscribe(store, (value) => {
values[i] = value;
pending &= ~(1 << i);
if (inited) {
sync();
}
}, () => {
pending |= (1 << i);
}));
inited = true;
sync();
return function stop() {
run_all(unsubscribers);
cleanup();
};
});
}
const ICON_NAME = "longform";
const ICON_SVG = '<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#clip0)"><path d="M56.8466 47.4236C57.1415 48.0004 57.7282 48.3336 58.3349 48.3336C58.5882 48.3336 58.8481 48.2752 59.0899 48.152C59.1882 48.102 68.9983 43.1186 73.8365 41.5903C74.7133 41.312 75.1998 40.3753 74.9215 39.4987C74.6447 38.622 73.7148 38.1337 72.8299 38.4104C67.7332 40.0221 57.99 44.9721 57.5767 45.1821C56.7566 45.5987 56.43 46.6022 56.8466 47.4236Z" fill="currentColor"/><path d="M58.3351 28.334C58.5884 28.334 58.8484 28.2756 59.0902 28.1523C59.1884 28.1023 68.9985 23.119 73.8367 21.5907C74.7135 21.3123 75.2 20.3756 74.9217 19.4991C74.6449 18.6223 73.715 18.134 72.8301 18.4108C67.7334 20.0225 57.9902 24.9725 57.5769 25.1824C56.757 25.599 56.4302 26.6023 56.8468 27.424C57.1417 28.0006 57.7284 28.334 58.3351 28.334Z" fill="currentColor"/><path d="M98.3326 25.0006C97.4109 25.0006 96.666 25.7473 96.666 26.6672V91.6667C96.666 94.4233 94.4227 96.6666 91.6661 96.6666H51.6664V92.8317C54.0964 91.9817 60.4263 90.0001 66.6663 90.0001C81.1845 90.0001 91.0428 93.2151 91.1411 93.2483C91.6426 93.4149 92.2028 93.3317 92.6411 93.0182C93.076 92.7049 93.3327 92.2016 93.3327 91.6665V18.334C93.3327 17.5524 92.7911 16.8757 92.0276 16.7073C92.0276 16.7073 90.721 16.4157 88.4876 16.0055C87.5858 15.8389 86.7144 16.4389 86.5476 17.3423C86.381 18.2489 86.9792 19.1172 87.8843 19.2838C88.736 19.4405 89.4493 19.5788 89.9993 19.6889V89.4517C86.2226 88.4616 77.8361 86.6667 66.6661 86.6667C59.4044 86.6667 52.2713 89.0517 50.0645 89.86C48.1027 88.9935 42.1729 86.6667 34.9995 86.6667C23.5195 86.6667 14.063 88.5601 9.99973 89.5218V19.6239C13.328 18.8055 23.158 16.6673 34.9995 16.6673C41.0762 16.6673 46.2877 18.5589 48.3328 19.4139V85.0001C48.3328 85.6001 48.6561 86.1552 49.1777 86.4501C49.6994 86.7468 50.3428 86.7384 50.8578 86.4284C51.0228 86.3302 67.536 76.4668 82.1925 71.5819C82.8741 71.3536 83.3325 70.7186 83.3325 70.0002V1.66738C83.3325 1.12071 83.0642 0.608992 82.6142 0.297471C82.1675 -0.0142452 81.5943 -0.0859243 81.0792 0.105871C67.7444 5.10739 54.2513 13.504 54.1162 13.5874C53.3361 14.0757 53.0978 15.104 53.5861 15.8841C54.0728 16.6641 55.1011 16.9024 55.8828 16.4141C56.006 16.3358 67.7444 9.03256 79.9992 4.10428V68.8071C68.6225 72.7604 56.7443 79.2154 51.666 82.1052V18.334C51.666 17.7024 51.3094 17.1257 50.7443 16.8425C50.4576 16.7009 43.6278 13.3341 34.9995 13.3341C19.9397 13.3341 8.36146 16.5925 7.87474 16.7323C7.15971 16.9356 6.66635 17.5907 6.66635 18.334V91.6669C6.66635 92.1885 6.91303 92.6819 7.32807 92.9969C7.62142 93.2186 7.97474 93.3337 8.33314 93.3337C8.48646 93.3337 8.63978 93.312 8.78977 93.2686C8.90481 93.237 20.4297 90.0003 34.9995 90.0003C41.0928 90.0003 46.2994 91.8969 48.3328 92.7485V96.6668H8.33314C5.57652 96.6668 3.33318 94.4235 3.33318 91.6669V26.6674C3.33318 25.7475 2.5865 25.0008 1.66659 25.0008C0.746674 25.0008 0 25.7475 0 26.6674V91.6669C0 96.2618 3.73825 100 8.33333 100H91.6661C96.261 100 99.9994 96.262 99.9994 91.6669V26.6674C99.9992 25.7473 99.2543 25.0006 98.3326 25.0006Z" fill="currentColor"/><path d="M56.8466 37.4237C57.1415 38.0005 57.7282 38.3337 58.3349 38.3337C58.5882 38.3337 58.8481 38.2753 59.0899 38.152C59.1882 38.102 68.9983 33.1187 73.8365 31.5904C74.7133 31.3121 75.1998 30.3753 74.9215 29.4988C74.6447 28.622 73.7148 28.1338 72.8299 28.4105C67.7332 30.0222 57.99 34.9722 57.5767 35.1821C56.7566 35.5987 56.43 36.6023 56.8466 37.4237Z" fill="currentColor"/><path d="M56.8466 57.4236C57.1415 58.0003 57.7282 58.3335 58.3349 58.3335C58.5882 58.3335 58.8481 58.2751 59.0899 58.1519C59.1882 58.1019 68.9983 53.1185 73.8365 51.5902C74.7133 51.3119 75.1998 50.3752 74.9215 49.4986C74.6447 48.6219 73.7148 48.1336 72.8299 48.4104C67.7332 50.0221 57.99 54.972 57.5767 55.182C56.7566 55.5986 56.43 56.6021 56.8466 57.4236Z" fill="currentColor"/><path d="M40.3801 30.9306C30.0886 28.5156 18.3936 31.5923 17.902 31.724C17.0137 31.9623 16.4854 32.8755 16.7237 33.7656C16.9237 34.5105 17.5969 35.0005 18.3321 35.0005C18.4754 35.0005 18.6203 34.9822 18.7655 34.9439C18.8772 34.9122 30.1371 31
const LONGFORM_CURRENT_PLUGIN_DATA_VERSION = 1;
const LONGFORM_CURRENT_INDEX_VERSION = 1;
var ProjectLoadError;
(function (ProjectLoadError) {
ProjectLoadError[ProjectLoadError["None"] = 0] = "None";
ProjectLoadError["MissingMetadata"] = "This project\u2019s metadata is either missing or invalid. Please check its index file. If all else fails, you can reset all project tracking in settings and re-mark folders as Longform projects.";
})(ProjectLoadError || (ProjectLoadError = {}));
const DEFAULT_SETTINGS = {
version: LONGFORM_CURRENT_PLUGIN_DATA_VERSION,
projects: {},
selectedProject: null,
selectedDraft: null,
};
// Writable stores
const initialized = writable(false);
const pluginSettings = writable(DEFAULT_SETTINGS);
const projectMetadata = writable({});
const currentProjectPath = writable(null);
const currentDraftPath = writable(null);
const activeFile = writable(null);
// Derived stores
const projects = derived([pluginSettings, projectMetadata], ([$pluginSettings, $projectMetadata]) => {
const p = {};
Object.keys($pluginSettings.projects).forEach((projectPath) => {
if ($projectMetadata[projectPath]) {
p[projectPath] = Object.assign(Object.assign(Object.assign({}, $pluginSettings.projects[projectPath]), $projectMetadata[projectPath]), { error: ProjectLoadError.None });
}
else {
p[projectPath] = Object.assign(Object.assign({}, $pluginSettings.projects[projectPath]), { version: -1, drafts: [], error: ProjectLoadError.MissingMetadata });
}
});
return p;
});
const currentProject = derived([projects, currentProjectPath], ([$projects, $currentProjectPath]) => {
const project = $projects[$currentProjectPath];
return project || null;
});
const currentDraft = derived([currentProject, currentDraftPath], ([$currentProject, $currentDraftPath]) => {
if (!$currentProject || !$currentProject.drafts || !$currentDraftPath) {
return null;
}
return ($currentProject.drafts.find((d) => d.folder === $currentDraftPath) || null);
});
function compile(vault, projectPath, draftName, targetPath, options) {
return __awaiter(this, void 0, void 0, function* () {
// Grab draft path and metadata
const projectSettings = get_store_value(pluginSettings).projects[projectPath];
if (!projectSettings) {
console.error(`[Longform] No tracked project at ${projectPath} exists for compilation.`);
return;
}
const scenePath = (scene) => obsidian.normalizePath(`${projectPath}/${projectSettings.draftsPath}/${draftName}/${scene}.md`);
const draftMetadata = get_store_value(projectMetadata)[projectPath].drafts.find((d) => d.folder === draftName);
if (!draftMetadata) {
console.error(`[Longform] No draft named ${draftName} exists in ${projectPath} for compilation.`);
return;
}
let result = "";
const report = (status, complete) => {
console.log(`[Longform] ${status}`);
options.reportProgress(status, complete);
};
for (const scene of draftMetadata.scenes) {
const path = scenePath(scene);
const sceneContents = yield vault.adapter.read(path);
report(`Compiling ${path}`, false);
if (options.includeHeaders) {
result += `# ${scene}\n\n`;
}
result += `${sceneContents}\n\n`;
}
const finalTarget = targetPath.endsWith(".md")
? targetPath
: targetPath + ".md";
report(`Writing compile result to ${finalTarget}`, false);
yield vault.adapter.write(finalTarget, result);
report(`Compiled ${draftName} to ${finalTarget}`, true);
});
}
/* src/view/compile/CompileView.svelte generated by Svelte v3.38.2 */
function add_css$8() {
var style = element("style");
style.id = "svelte-1vu6mjk-style";
style.textContent = ".explanation.svelte-1vu6mjk{font-size:10px;line-height:12px}.compile-container.svelte-1vu6mjk{border-top:1px solid var(--text-muted)}.compile-option.svelte-1vu6mjk{margin:12px 0}label.svelte-1vu6mjk{font-size:12px;color:var(--text-muted)}#compile-target-path.svelte-1vu6mjk{width:100%;font-size:14px;line-height:20px}#compile-target-path.invalid.svelte-1vu6mjk{color:var(--text-error)}.compile-button.svelte-1vu6mjk{background-color:var(--interactive-accent);color:var(--text-on-accent)}.compile-button.svelte-1vu6mjk:disabled{background-color:var(--text-muted);color:var(--text-faint)}.compile-status.svelte-1vu6mjk{color:var(--interactive-success);font-size:10px;line-height:12px}";
append(document.head, style);
}
// (51:0) {#if $currentProject && $currentDraft}
function create_if_block$5(ctx) {
let div2;
let div0;
let label0;
let t1;
let input0;
let t2;
let p0;
let t4;
let t5;
let div1;
let label1;
let t7;
let input1;
let t8;
let p1;
let t10;
let button;
let t11;
let button_disabled_value;
let t12;
let mounted;
let dispose;
let if_block0 = /*error*/ ctx[3] && create_if_block_2$2(ctx);
let if_block1 = /*status*/ ctx[2].length > 0 && create_if_block_1$3(ctx);
return {
c() {
div2 = element("div");
div0 = element("div");
label0 = element("label");
label0.textContent = "Write compiled result to:";
t1 = space();
input0 = element("input");
t2 = space();
p0 = element("p");
p0.textContent = "The parent folders of this path must already exist in your vault.";
t4 = space();
if (if_block0) if_block0.c();
t5 = space();
div1 = element("div");
label1 = element("label");
label1.textContent = "Add note titles as chapter headings";
t7 = space();
input1 = element("input");
t8 = space();
p1 = element("p");
p1.textContent = "When selected, this option inserts a # tag with each notes title above\n that notes contents in the compilation result.";
t10 = space();
button = element("button");
t11 = text("Compile!");
t12 = space();
if (if_block1) if_block1.c();
attr(label0, "for", "compile-target");
attr(label0, "class", "svelte-1vu6mjk");
attr(input0, "id", "compile-target-path");
attr(input0, "name", "compile-target");
attr(input0, "type", "text");
attr(input0, "placeholder", "vault/path/to/compiled-note");
attr(input0, "class", "svelte-1vu6mjk");
toggle_class(input0, "invalid", !!/*error*/ ctx[3]);
attr(p0, "class", "explanation svelte-1vu6mjk");
attr(div0, "class", "compile-option svelte-1vu6mjk");
attr(label1, "for", "include-headers");
attr(label1, "class", "svelte-1vu6mjk");
attr(input1, "type", "checkbox");
attr(input1, "name", "include-headers");
attr(p1, "class", "explanation svelte-1vu6mjk");
attr(div1, "class", "compile-option svelte-1vu6mjk");
attr(button, "class", "compile-button svelte-1vu6mjk");
button.disabled = button_disabled_value = /*targetPath*/ ctx[0].length === 0 || !!/*error*/ ctx[3];
attr(div2, "class", "compile-container svelte-1vu6mjk");
},
m(target, anchor) {
insert(target, div2, anchor);
append(div2, div0);
append(div0, label0);
append(div0, t1);
append(div0, input0);
set_input_value(input0, /*targetPath*/ ctx[0]);
append(div0, t2);
append(div0, p0);
append(div0, t4);
if (if_block0) if_block0.m(div0, null);
append(div2, t5);
append(div2, div1);
append(div1, label1);
append(div1, t7);
append(div1, input1);
input1.checked = /*includeHeaders*/ ctx[1];
append(div1, t8);
append(div1, p1);
append(div2, t10);
append(div2, button);
append(button, t11);
append(div2, t12);
if (if_block1) if_block1.m(div2, null);
if (!mounted) {
dispose = [
listen(input0, "input", /*input0_input_handler*/ ctx[7]),
listen(input1, "change", /*input1_change_handler*/ ctx[8]),
listen(button, "click", /*doCompile*/ ctx[6])
];
mounted = true;
}
},
p(ctx, dirty) {
if (dirty & /*targetPath*/ 1 && input0.value !== /*targetPath*/ ctx[0]) {
set_input_value(input0, /*targetPath*/ ctx[0]);
}
if (dirty & /*error*/ 8) {
toggle_class(input0, "invalid", !!/*error*/ ctx[3]);
}
if (/*error*/ ctx[3]) {
if (if_block0) {
if_block0.p(ctx, dirty);
} else {
if_block0 = create_if_block_2$2(ctx);
if_block0.c();
if_block0.m(div0, null);
}
} else if (if_block0) {
if_block0.d(1);
if_block0 = null;
}
if (dirty & /*includeHeaders*/ 2) {
input1.checked = /*includeHeaders*/ ctx[1];
}
if (dirty & /*targetPath, error*/ 9 && button_disabled_value !== (button_disabled_value = /*targetPath*/ ctx[0].length === 0 || !!/*error*/ ctx[3])) {
button.disabled = button_disabled_value;
}
if (/*status*/ ctx[2].length > 0) {
if (if_block1) {
if_block1.p(ctx, dirty);
} else {
if_block1 = create_if_block_1$3(ctx);
if_block1.c();
if_block1.m(div2, null);
}
} else if (if_block1) {
if_block1.d(1);
if_block1 = null;
}
},
d(detaching) {
if (detaching) detach(div2);
if (if_block0) if_block0.d();
if (if_block1) if_block1.d();
mounted = false;
run_all(dispose);
}
};
}
// (66:6) {#if error}
function create_if_block_2$2(ctx) {
let p;
let t;
return {
c() {
p = element("p");
t = text(/*error*/ ctx[3]);
},
m(target, anchor) {
insert(target, p, anchor);
append(p, t);
},
p(ctx, dirty) {
if (dirty & /*error*/ 8) set_data(t, /*error*/ ctx[3]);
},
d(detaching) {
if (detaching) detach(p);
}
};
}
// (88:4) {#if status.length > 0}
function create_if_block_1$3(ctx) {
let p;
let t;
return {
c() {
p = element("p");
t = text(/*status*/ ctx[2]);
attr(p, "class", "compile-status svelte-1vu6mjk");
},
m(target, anchor) {
insert(target, p, anchor);
append(p, t);
},
p(ctx, dirty) {
if (dirty & /*status*/ 4) set_data(t, /*status*/ ctx[2]);
},
d(detaching) {
if (detaching) detach(p);
}
};
}
function create_fragment$b(ctx) {
let p;
let t3;
let if_block_anchor;
let if_block = /*$currentProject*/ ctx[4] && /*$currentDraft*/ ctx[5] && create_if_block$5(ctx);
return {
c() {
p = element("p");
p.innerHTML = `Compilation is a <a href="https://github.com/kevboh/longform/labels/compile">work in progress</a>. While I plan to add support for many custom workflows, for now you can use
the Compile feature to stitch all the scenes in a draft together into one big
note.`;
t3 = space();
if (if_block) if_block.c();
if_block_anchor = empty();
attr(p, "class", "explanation svelte-1vu6mjk");
},
m(target, anchor) {
insert(target, p, anchor);
insert(target, t3, anchor);
if (if_block) if_block.m(target, anchor);
insert(target, if_block_anchor, anchor);
},
p(ctx, [dirty]) {
if (/*$currentProject*/ ctx[4] && /*$currentDraft*/ ctx[5]) {
if (if_block) {
if_block.p(ctx, dirty);
} else {
if_block = create_if_block$5(ctx);
if_block.c();
if_block.m(if_block_anchor.parentNode, if_block_anchor);
}
} else if (if_block) {
if_block.d(1);
if_block = null;
}
},
i: noop,
o: noop,
d(detaching) {
if (detaching) detach(p);
if (detaching) detach(t3);
if (if_block) if_block.d(detaching);
if (detaching) detach(if_block_anchor);
}
};
}
function instance$b($$self, $$props, $$invalidate) {
let $currentProjectPath;
let $pluginSettings;
let $currentDraftPath;
let $currentProject;
let $currentDraft;
component_subscribe($$self, currentProjectPath, $$value => $$invalidate(9, $currentProjectPath = $$value));
component_subscribe($$self, pluginSettings, $$value => $$invalidate(10, $pluginSettings = $$value));
component_subscribe($$self, currentDraftPath, $$value => $$invalidate(11, $currentDraftPath = $$value));
component_subscribe($$self, currentProject, $$value => $$invalidate(4, $currentProject = $$value));
component_subscribe($$self, currentDraft, $$value => $$invalidate(5, $currentDraft = $$value));
let targetPath = "";
if ($currentProjectPath && $pluginSettings.projects[$currentProjectPath]) {
const draftsFolder = $pluginSettings.projects[$currentProjectPath].draftsPath;
targetPath = obsidian.normalizePath(`${$currentProjectPath}/${draftsFolder}/${$currentDraftPath}-compiled`);
}
let includeHeaders = false;
let status = "";
const getVault = getContext("getVault");
function doCompile() {
compile(getVault(), $currentProjectPath, $currentDraftPath, targetPath, {
includeHeaders,
reportProgress: (_status, complete) => {
$$invalidate(2, status = _status);
if (complete) {
setTimeout(
() => {
$$invalidate(2, status = "");
},
5000
);
}
}
});
}
let error = null;
function input0_input_handler() {
targetPath = this.value;
$$invalidate(0, targetPath);
}
function input1_change_handler() {
includeHeaders = this.checked;
$$invalidate(1, includeHeaders);
}
$$self.$$.update = () => {
if ($$self.$$.dirty & /*targetPath*/ 1) {
{
if (targetPath.length === 0) {
$$invalidate(3, error = null);
} else if (targetPath.split("/").slice(-1)[0].match(/[\/\\:]/g)) {
$$invalidate(3, error = "A file cannot contain the characters: \\ / :");
} else {
$$invalidate(3, error = null);
}
}
}
};
return [
targetPath,
includeHeaders,
status,
error,
$currentProject,
$currentDraft,
doCompile,
input0_input_handler,
input1_change_handler
];
}
class CompileView extends SvelteComponent {
constructor(options) {
super();
if (!document.getElementById("svelte-1vu6mjk-style")) add_css$8();
init(this, options, instance$b, create_fragment$b, safe_not_equal, {});
}
}
/* src/view/tabs/Tabs.svelte generated by Svelte v3.38.2 */
function create_fragment$a(ctx) {
let div;
let current;
const default_slot_template = /*#slots*/ ctx[1].default;
const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[0], null);
return {
c() {
div = element("div");
if (default_slot) default_slot.c();
attr(div, "class", "tabs");
},
m(target, anchor) {
insert(target, div, anchor);
if (default_slot) {
default_slot.m(div, null);
}
current = true;
},
p(ctx, [dirty]) {
if (default_slot) {
if (default_slot.p && (!current || dirty & /*$$scope*/ 1)) {
update_slot(default_slot, default_slot_template, ctx, /*$$scope*/ ctx[0], dirty, null, null);
}
}
},
i(local) {
if (current) return;
transition_in(default_slot, local);
current = true;
},
o(local) {
transition_out(default_slot, local);
current = false;
},
d(detaching) {
if (detaching) detach(div);
if (default_slot) default_slot.d(detaching);
}
};
}
const TABS = {};
function instance$a($$self, $$props, $$invalidate) {
let { $$slots: slots = {}, $$scope } = $$props;
const tabs = [];
const panels = [];
const selectedTab = writable(null);
const selectedPanel = writable(null);
setContext(TABS, {
registerTab: tab => {
tabs.push(tab);
selectedTab.update(current => current || tab);
onDestroy(() => {
const i = tabs.indexOf(tab);
tabs.splice(i, 1);
selectedTab.update(current => current === tab
? tabs[i] || tabs[tabs.length - 1]
: current);
});
},
registerPanel: panel => {
panels.push(panel);
selectedPanel.update(current => current || panel);
onDestroy(() => {
const i = panels.indexOf(panel);
panels.splice(i, 1);
selectedPanel.update(current => current === panel
? panels[i] || panels[panels.length - 1]
: current);
});
},
selectTab: tab => {
const i = tabs.indexOf(tab);
selectedTab.set(tab);
selectedPanel.set(panels[i]);
},
selectedTab,
selectedPanel
});
$$self.$$set = $$props => {
if ("$$scope" in $$props) $$invalidate(0, $$scope = $$props.$$scope);
};
return [$$scope, slots];
}
class Tabs extends SvelteComponent {
constructor(options) {
super();
init(this, options, instance$a, create_fragment$a, safe_not_equal, {});
}
}
/* src/view/tabs/TabList.svelte generated by Svelte v3.38.2 */
function add_css$7() {
var style = element("style");
style.id = "svelte-1bo97vk-style";
style.textContent = ".tab-list.svelte-1bo97vk{margin:4px 8px;border-bottom:1px solid var(--text-muted)}";
append(document.head, style);
}
function create_fragment$9(ctx) {
let div;
let current;
const default_slot_template = /*#slots*/ ctx[1].default;
const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[0], null);
return {
c() {
div = element("div");
if (default_slot) default_slot.c();
attr(div, "class", "tab-list svelte-1bo97vk");
},
m(target, anchor) {
insert(target, div, anchor);
if (default_slot) {
default_slot.m(div, null);
}
current = true;
},
p(ctx, [dirty]) {
if (default_slot) {
if (default_slot.p && (!current || dirty & /*$$scope*/ 1)) {
update_slot(default_slot, default_slot_template, ctx, /*$$scope*/ ctx[0], dirty, null, null);
}
}
},
i(local) {
if (current) return;
transition_in(default_slot, local);
current = true;
},
o(local) {
transition_out(default_slot, local);
current = false;
},
d(detaching) {
if (detaching) detach(div);
if (default_slot) default_slot.d(detaching);
}
};
}
function instance$9($$self, $$props, $$invalidate) {
let { $$slots: slots = {}, $$scope } = $$props;
$$self.$$set = $$props => {
if ("$$scope" in $$props) $$invalidate(0, $$scope = $$props.$$scope);
};
return [$$scope, slots];
}
class TabList extends SvelteComponent {
constructor(options) {
super();
if (!document.getElementById("svelte-1bo97vk-style")) add_css$7();
init(this, options, instance$9, create_fragment$9, safe_not_equal, {});
}
}
/* src/view/tabs/TabPanel.svelte generated by Svelte v3.38.2 */
function add_css$6() {
var style = element("style");
style.id = "svelte-11pvpwl-style";
style.textContent = ".tab-panel-container.svelte-11pvpwl{padding:0 8px}";
append(document.head, style);
}
// (11:0) {#if $selectedPanel === panel}
function create_if_block$4(ctx) {
let div;
let current;
const default_slot_template = /*#slots*/ ctx[4].default;
const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[3], null);
return {
c() {
div = element("div");
if (default_slot) default_slot.c();
attr(div, "class", "tab-panel-container svelte-11pvpwl");
},
m(target, anchor) {
insert(target, div, anchor);
if (default_slot) {
default_slot.m(div, null);
}
current = true;
},
p(ctx, dirty) {
if (default_slot) {
if (default_slot.p && (!current || dirty & /*$$scope*/ 8)) {
update_slot(default_slot, default_slot_template, ctx, /*$$scope*/ ctx[3], dirty, null, null);
}
}
},
i(local) {
if (current) return;
transition_in(default_slot, local);
current = true;
},
o(local) {
transition_out(default_slot, local);
current = false;
},
d(detaching) {
if (detaching) detach(div);
if (default_slot) default_slot.d(detaching);
}
};
}
function create_fragment$8(ctx) {
let if_block_anchor;
let current;
let if_block = /*$selectedPanel*/ ctx[0] === /*panel*/ ctx[1] && create_if_block$4(ctx);
return {
c() {
if (if_block) if_block.c();
if_block_anchor = empty();
},
m(target, anchor) {
if (if_block) if_block.m(target, anchor);
insert(target, if_block_anchor, anchor);
current = true;
},
p(ctx, [dirty]) {
if (/*$selectedPanel*/ ctx[0] === /*panel*/ ctx[1]) {
if (if_block) {
if_block.p(ctx, dirty);
if (dirty & /*$selectedPanel*/ 1) {
transition_in(if_block, 1);
}
} else {
if_block = create_if_block$4(ctx);
if_block.c();
transition_in(if_block, 1);
if_block.m(if_block_anchor.parentNode, if_block_anchor);
}
} else if (if_block) {
group_outros();
transition_out(if_block, 1, 1, () => {
if_block = null;
});
check_outros();
}
},
i(local) {
if (current) return;
transition_in(if_block);
current = true;
},
o(local) {
transition_out(if_block);
current = false;
},
d(detaching) {
if (if_block) if_block.d(detaching);
if (detaching) detach(if_block_anchor);
}
};
}
function instance$8($$self, $$props, $$invalidate) {
let $selectedPanel;
let { $$slots: slots = {}, $$scope } = $$props;
const panel = {};
const { registerPanel, selectedPanel } = getContext(TABS);
component_subscribe($$self, selectedPanel, value => $$invalidate(0, $selectedPanel = value));
registerPanel(panel);
$$self.$$set = $$props => {
if ("$$scope" in $$props) $$invalidate(3, $$scope = $$props.$$scope);
};
return [$selectedPanel, panel, selectedPanel, $$scope, slots];
}
class TabPanel extends SvelteComponent {
constructor(options) {
super();
if (!document.getElementById("svelte-11pvpwl-style")) add_css$6();
init(this, options, instance$8, create_fragment$8, safe_not_equal, {});
}
}
/* src/view/tabs/Tab.svelte generated by Svelte v3.38.2 */
function add_css$5() {
var style = element("style");
style.id = "svelte-htpziy-style";
style.textContent = "button.svelte-htpziy{background:none;border:none;border-bottom:none;border-radius:0;margin:0;color:var(--interactive-accent)}.selected.svelte-htpziy{border-bottom:2px solid var(--text-muted);color:var(--text-accent)}";
append(document.head, style);
}
function create_fragment$7(ctx) {
let button;
let current;
let mounted;
let dispose;
const default_slot_template = /*#slots*/ ctx[5].default;
const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[4], null);
return {
c() {
button = element("button");
if (default_slot) default_slot.c();
attr(button, "class", "svelte-htpziy");
toggle_class(button, "selected", /*$selectedTab*/ ctx[0] === /*tab*/ ctx[1]);
},
m(target, anchor) {
insert(target, button, anchor);
if (default_slot) {
default_slot.m(button, null);
}
current = true;
if (!mounted) {
dispose = listen(button, "click", /*click_handler*/ ctx[6]);
mounted = true;
}
},
p(ctx, [dirty]) {
if (default_slot) {
if (default_slot.p && (!current || dirty & /*$$scope*/ 16)) {
update_slot(default_slot, default_slot_template, ctx, /*$$scope*/ ctx[4], dirty, null, null);
}
}
if (dirty & /*$selectedTab, tab*/ 3) {
toggle_class(button, "selected", /*$selectedTab*/ ctx[0] === /*tab*/ ctx[1]);
}
},
i(local) {
if (current) return;
transition_in(default_slot, local);
current = true;
},
o(local) {
transition_out(default_slot, local);
current = false;
},
d(detaching) {
if (detaching) detach(button);
if (default_slot) default_slot.d(detaching);
mounted = false;
dispose();
}
};
}
function instance$7($$self, $$props, $$invalidate) {
let $selectedTab;
let { $$slots: slots = {}, $$scope } = $$props;
const tab = {};
const { registerTab, selectTab, selectedTab } = getContext(TABS);
component_subscribe($$self, selectedTab, value => $$invalidate(0, $selectedTab = value));
registerTab(tab);
const click_handler = () => selectTab(tab);
$$self.$$set = $$props => {
if ("$$scope" in $$props) $$invalidate(4, $$scope = $$props.$$scope);
};
return [$selectedTab, tab, selectTab, selectedTab, $$scope, slots, click_handler];
}
class Tab extends SvelteComponent {
constructor(options) {
super();
if (!document.getElementById("svelte-htpziy-style")) add_css$5();
init(this, options, instance$7, create_fragment$7, safe_not_equal, {});
}
}
/**!
* Sortable 1.14.0
* @author RubaXa <trash@rubaxa.org>
* @author owenm <owen23355@gmail.com>
* @license MIT
*/
function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object);
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(object);
if (enumerableOnly) {
symbols = symbols.filter(function (sym) {
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
});
}
keys.push.apply(keys, symbols);
}
return keys;
}
function _objectSpread2(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i] != null ? arguments[i] : {};
if (i % 2) {
ownKeys(Object(source), true).forEach(function (key) {
_defineProperty$1(target, key, source[key]);
});
} else if (Object.getOwnPropertyDescriptors) {
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
} else {
ownKeys(Object(source)).forEach(function (key) {
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
});
}
}
return target;
}
function _typeof(obj) {
"@babel/helpers - typeof";
if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
_typeof = function (obj) {
return typeof obj;
};
} else {
_typeof = function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
}
return _typeof(obj);
}
function _defineProperty$1(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function _extends() {
_extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
function _objectWithoutPropertiesLoose(source, excluded) {
if (source == null) return {};
var target = {};
var sourceKeys = Object.keys(source);
var key, i;
for (i = 0; i < sourceKeys.length; i++) {
key = sourceKeys[i];
if (excluded.indexOf(key) >= 0) continue;
target[key] = source[key];
}
return target;
}
function _objectWithoutProperties(source, excluded) {
if (source == null) return {};
var target = _objectWithoutPropertiesLoose(source, excluded);
var key, i;
if (Object.getOwnPropertySymbols) {
var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
for (i = 0; i < sourceSymbolKeys.length; i++) {
key = sourceSymbolKeys[i];
if (excluded.indexOf(key) >= 0) continue;
if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
target[key] = source[key];
}
}
return target;
}
var version = "1.14.0";
function userAgent(pattern) {
if (typeof window !== 'undefined' && window.navigator) {
return !! /*@__PURE__*/navigator.userAgent.match(pattern);
}
}
var IE11OrLess = userAgent(/(?:Trident.*rv[ :]?11\.|msie|iemobile|Windows Phone)/i);
var Edge = userAgent(/Edge/i);
var FireFox = userAgent(/firefox/i);
var Safari = userAgent(/safari/i) && !userAgent(/chrome/i) && !userAgent(/android/i);
var IOS = userAgent(/iP(ad|od|hone)/i);
var ChromeForAndroid = userAgent(/chrome/i) && userAgent(/android/i);
var captureMode = {
capture: false,
passive: false
};
function on(el, event, fn) {
el.addEventListener(event, fn, !IE11OrLess && captureMode);
}
function off(el, event, fn) {
el.removeEventListener(event, fn, !IE11OrLess && captureMode);
}
function matches(
/**HTMLElement*/
el,
/**String*/
selector) {
if (!selector) return;
selector[0] === '>' && (selector = selector.substring(1));
if (el) {
try {
if (el.matches) {
return el.matches(selector);
} else if (el.msMatchesSelector) {
return el.msMatchesSelector(selector);
} else if (el.webkitMatchesSelector) {
return el.webkitMatchesSelector(selector);
}
} catch (_) {
return false;
}
}
return false;
}
function getParentOrHost(el) {
return el.host && el !== document && el.host.nodeType ? el.host : el.parentNode;
}
function closest(
/**HTMLElement*/
el,
/**String*/
selector,
/**HTMLElement*/
ctx, includeCTX) {
if (el) {
ctx = ctx || document;
do {
if (selector != null && (selector[0] === '>' ? el.parentNode === ctx && matches(el, selector) : matches(el, selector)) || includeCTX && el === ctx) {
return el;
}
if (el === ctx) break;
/* jshint boss:true */
} while (el = getParentOrHost(el));
}
return null;
}
var R_SPACE = /\s+/g;
function toggleClass(el, name, state) {
if (el && name) {
if (el.classList) {
el.classList[state ? 'add' : 'remove'](name);
} else {
var className = (' ' + el.className + ' ').replace(R_SPACE, ' ').replace(' ' + name + ' ', ' ');
el.className = (className + (state ? ' ' + name : '')).replace(R_SPACE, ' ');
}
}
}
function css(el, prop, val) {
var style = el && el.style;
if (style) {
if (val === void 0) {
if (document.defaultView && document.defaultView.getComputedStyle) {
val = document.defaultView.getComputedStyle(el, '');
} else if (el.currentStyle) {
val = el.currentStyle;
}
return prop === void 0 ? val : val[prop];
} else {
if (!(prop in style) && prop.indexOf('webkit') === -1) {
prop = '-webkit-' + prop;
}
style[prop] = val + (typeof val === 'string' ? '' : 'px');
}
}
}
function matrix(el, selfOnly) {
var appliedTransforms = '';
if (typeof el === 'string') {
appliedTransforms = el;
} else {
do {
var transform = css(el, 'transform');
if (transform && transform !== 'none') {
appliedTransforms = transform + ' ' + appliedTransforms;
}
/* jshint boss:true */
} while (!selfOnly && (el = el.parentNode));
}
var matrixFn = window.DOMMatrix || window.WebKitCSSMatrix || window.CSSMatrix || window.MSCSSMatrix;
/*jshint -W056 */
return matrixFn && new matrixFn(appliedTransforms);
}
function find(ctx, tagName, iterator) {
if (ctx) {
var list = ctx.getElementsByTagName(tagName),
i = 0,
n = list.length;
if (iterator) {
for (; i < n; i++) {
iterator(list[i], i);
}
}
return list;
}
return [];
}
function getWindowScrollingElement() {
var scrollingElement = document.scrollingElement;
if (scrollingElement) {
return scrollingElement;
} else {
return document.documentElement;
}
}
/**
* Returns the "bounding client rect" of given element
* @param {HTMLElement} el The element whose boundingClientRect is wanted
* @param {[Boolean]} relativeToContainingBlock Whether the rect should be relative to the containing block of (including) the container
* @param {[Boolean]} relativeToNonStaticParent Whether the rect should be relative to the relative parent of (including) the contaienr
* @param {[Boolean]} undoScale Whether the container's scale() should be undone
* @param {[HTMLElement]} container The parent the element will be placed in
* @return {Object} The boundingClientRect of el, with specified adjustments
*/
function getRect(el, relativeToContainingBlock, relativeToNonStaticParent, undoScale, container) {
if (!el.getBoundingClientRect && el !== window) return;
var elRect, top, left, bottom, right, height, width;
if (el !== window && el.parentNode && el !== getWindowScrollingElement()) {
elRect = el.getBoundingClientRect();
top = elRect.top;
left = elRect.left;
bottom = elRect.bottom;
right = elRect.right;
height = elRect.height;
width = elRect.width;
} else {
top = 0;
left = 0;
bottom = window.innerHeight;
right = window.innerWidth;
height = window.innerHeight;
width = window.innerWidth;
}
if ((relativeToContainingBlock || relativeToNonStaticParent) && el !== window) {
// Adjust for translate()
container = container || el.parentNode; // solves #1123 (see: https://stackoverflow.com/a/37953806/6088312)
// Not needed on <= IE11
if (!IE11OrLess) {
do {
if (container && container.getBoundingClientRect && (css(container, 'transform') !== 'none' || relativeToNonStaticParent && css(container, 'position') !== 'static')) {
var containerRect = container.getBoundingClientRect(); // Set relative to edges of padding box of container
top -= containerRect.top + parseInt(css(container, 'border-top-width'));
left -= containerRect.left + parseInt(css(container, 'border-left-width'));
bottom = top + elRect.height;
right = left + elRect.width;
break;
}
/* jshint boss:true */
} while (container = container.parentNode);
}
}
if (undoScale && el !== window) {
// Adjust for scale()
var elMatrix = matrix(container || el),
scaleX = elMatrix && elMatrix.a,
scaleY = elMatrix && elMatrix.d;
if (elMatrix) {
top /= scaleY;
left /= scaleX;
width /= scaleX;
height /= scaleY;
bottom = top + height;
right = left + width;
}
}
return {
top: top,
left: left,
bottom: bottom,
right: right,
width: width,
height: height
};
}
/**
* Checks if a side of an element is scrolled past a side of its parents
* @param {HTMLElement} el The element who's side being scrolled out of view is in question
* @param {String} elSide Side of the element in question ('top', 'left', 'right', 'bottom')
* @param {String} parentSide Side of the parent in question ('top', 'left', 'right', 'bottom')
* @return {HTMLElement} The parent scroll element that the el's side is scrolled past, or null if there is no such element
*/
function isScrolledPast(el, elSide, parentSide) {
var parent = getParentAutoScrollElement(el, true),
elSideVal = getRect(el)[elSide];
/* jshint boss:true */
while (parent) {
var parentSideVal = getRect(parent)[parentSide],
visible = void 0;
if (parentSide === 'top' || parentSide === 'left') {
visible = elSideVal >= parentSideVal;
} else {
visible = elSideVal <= parentSideVal;
}
if (!visible) return parent;
if (parent === getWindowScrollingElement()) break;
parent = getParentAutoScrollElement(parent, false);
}
return false;
}
/**
* Gets nth child of el, ignoring hidden children, sortable's elements (does not ignore clone if it's visible)
* and non-draggable elements
* @param {HTMLElement} el The parent element
* @param {Number} childNum The index of the child
* @param {Object} options Parent Sortable's options
* @return {HTMLElement} The child at index childNum, or null if not found
*/
function getChild(el, childNum, options, includeDragEl) {
var currentChild = 0,
i = 0,
children = el.children;
while (i < children.length) {
if (children[i].style.display !== 'none' && children[i] !== Sortable.ghost && (includeDragEl || children[i] !== Sortable.dragged) && closest(children[i], options.draggable, el, false)) {
if (currentChild === childNum) {
return children[i];
}
currentChild++;
}
i++;
}
return null;
}
/**
* Gets the last child in the el, ignoring ghostEl or invisible elements (clones)
* @param {HTMLElement} el Parent element
* @param {selector} selector Any other elements that should be ignored
* @return {HTMLElement} The last child, ignoring ghostEl
*/
function lastChild(el, selector) {
var last = el.lastElementChild;
while (last && (last === Sortable.ghost || css(last, 'display') === 'none' || selector && !matches(last, selector))) {
last = last.previousElementSibling;
}
return last || null;
}
/**
* Returns the index of an element within its parent for a selected set of
* elements
* @param {HTMLElement} el
* @param {selector} selector
* @return {number}
*/
function index(el, selector) {
var index = 0;
if (!el || !el.parentNode) {
return -1;
}
/* jshint boss:true */
while (el = el.previousElementSibling) {
if (el.nodeName.toUpperCase() !== 'TEMPLATE' && el !== Sortable.clone && (!selector || matches(el, selector))) {
index++;
}
}
return index;
}
/**
* Returns the scroll offset of the given element, added with all the scroll offsets of parent elements.
* The value is returned in real pixels.
* @param {HTMLElement} el
* @return {Array} Offsets in the format of [left, top]
*/
function getRelativeScrollOffset(el) {
var offsetLeft = 0,
offsetTop = 0,
winScroller = getWindowScrollingElement();
if (el) {
do {
var elMatrix = matrix(el),
scaleX = elMatrix.a,
scaleY = elMatrix.d;
offsetLeft += el.scrollLeft * scaleX;
offsetTop += el.scrollTop * scaleY;
} while (el !== winScroller && (el = el.parentNode));
}
return [offsetLeft, offsetTop];
}
/**
* Returns the index of the object within the given array
* @param {Array} arr Array that may or may not hold the object
* @param {Object} obj An object that has a key-value pair unique to and identical to a key-value pair in the object you want to find
* @return {Number} The index of the object in the array, or -1
*/
function indexOfObject(arr, obj) {
for (var i in arr) {
if (!arr.hasOwnProperty(i)) continue;
for (var key in obj) {
if (obj.hasOwnProperty(key) && obj[key] === arr[i][key]) return Number(i);
}
}
return -1;
}
function getParentAutoScrollElement(el, includeSelf) {
// skip to window
if (!el || !el.getBoundingClientRect) return getWindowScrollingElement();
var elem = el;
var gotSelf = false;
do {
// we don't need to get elem css if it isn't even overflowing in the first place (performance)
if (elem.clientWidth < elem.scrollWidth || elem.clientHeight < elem.scrollHeight) {
var elemCSS = css(elem);
if (elem.clientWidth < elem.scrollWidth && (elemCSS.overflowX == 'auto' || elemCSS.overflowX == 'scroll') || elem.clientHeight < elem.scrollHeight && (elemCSS.overflowY == 'auto' || elemCSS.overflowY == 'scroll')) {
if (!elem.getBoundingClientRect || elem === document.body) return getWindowScrollingElement();
if (gotSelf || includeSelf) return elem;
gotSelf = true;
}
}
/* jshint boss:true */
} while (elem = elem.parentNode);
return getWindowScrollingElement();
}
function extend(dst, src) {
if (dst && src) {
for (var key in src) {
if (src.hasOwnProperty(key)) {
dst[key] = src[key];
}
}
}
return dst;
}
function isRectEqual(rect1, rect2) {
return Math.round(rect1.top) === Math.round(rect2.top) && Math.round(rect1.left) === Math.round(rect2.left) && Math.round(rect1.height) === Math.round(rect2.height) && Math.round(rect1.width) === Math.round(rect2.width);
}
var _throttleTimeout;
function throttle(callback, ms) {
return function () {
if (!_throttleTimeout) {
var args = arguments,
_this = this;
if (args.length === 1) {
callback.call(_this, args[0]);
} else {
callback.apply(_this, args);
}
_throttleTimeout = setTimeout(function () {
_throttleTimeout = void 0;
}, ms);
}
};
}
function scrollBy(el, x, y) {
el.scrollLeft += x;
el.scrollTop += y;
}
function clone(el) {
var Polymer = window.Polymer;
var $ = window.jQuery || window.Zepto;
if (Polymer && Polymer.dom) {
return Polymer.dom(el).cloneNode(true);
} else if ($) {
return $(el).clone(true)[0];
} else {
return el.cloneNode(true);
}
}
var expando = 'Sortable' + new Date().getTime();
function AnimationStateManager() {
var animationStates = [],
animationCallbackId;
return {
captureAnimationState: function captureAnimationState() {
animationStates = [];
if (!this.options.animation) return;
var children = [].slice.call(this.el.children);
children.forEach(function (child) {
if (css(child, 'display') === 'none' || child === Sortable.ghost) return;
animationStates.push({
target: child,
rect: getRect(child)
});
var fromRect = _objectSpread2({}, animationStates[animationStates.length - 1].rect); // If animating: compensate for current animation
if (child.thisAnimationDuration) {
var childMatrix = matrix(child, true);
if (childMatrix) {
fromRect.top -= childMatrix.f;
fromRect.left -= childMatrix.e;
}
}
child.fromRect = fromRect;
});
},
addAnimationState: function addAnimationState(state) {
animationStates.push(state);
},
removeAnimationState: function removeAnimationState(target) {
animationStates.splice(indexOfObject(animationStates, {
target: target
}), 1);
},
animateAll: function animateAll(callback) {
var _this = this;
if (!this.options.animation) {
clearTimeout(animationCallbackId);
if (typeof callback === 'function') callback();
return;
}
var animating = false,
animationTime = 0;
animationStates.forEach(function (state) {
var time = 0,
target = state.target,
fromRect = target.fromRect,
toRect = getRect(target),
prevFromRect = target.prevFromRect,
prevToRect = target.prevToRect,
animatingRect = state.rect,
targetMatrix = matrix(target, true);
if (targetMatrix) {
// Compensate for current animation
toRect.top -= targetMatrix.f;
toRect.left -= targetMatrix.e;
}
target.toRect = toRect;
if (target.thisAnimationDuration) {
// Could also check if animatingRect is between fromRect and toRect
if (isRectEqual(prevFromRect, toRect) && !isRectEqual(fromRect, toRect) && // Make sure animatingRect is on line between toRect & fromRect
(animatingRect.top - toRect.top) / (animatingRect.left - toRect.left) === (fromRect.top - toRect.top) / (fromRect.left - toRect.left)) {
// If returning to same place as started from animation and on same axis
time = calculateRealTime(animatingRect, prevFromRect, prevToRect, _this.options);
}
} // if fromRect != toRect: animate
if (!isRectEqual(toRect, fromRect)) {
target.prevFromRect = fromRect;
target.prevToRect = toRect;
if (!time) {
time = _this.options.animation;
}
_this.animate(target, animatingRect, toRect, time);
}
if (time) {
animating = true;
animationTime = Math.max(animationTime, time);
clearTimeout(target.animationResetTimer);
target.animationResetTimer = setTimeout(function () {
target.animationTime = 0;
target.prevFromRect = null;
target.fromRect = null;
target.prevToRect = null;
target.thisAnimationDuration = null;
}, time);
target.thisAnimationDuration = time;
}
});
clearTimeout(animationCallbackId);
if (!animating) {
if (typeof callback === 'function') callback();
} else {
animationCallbackId = setTimeout(function () {
if (typeof callback === 'function') callback();
}, animationTime);
}
animationStates = [];
},
animate: function animate(target, currentRect, toRect, duration) {
if (duration) {
css(target, 'transition', '');
css(target, 'transform', '');
var elMatrix = matrix(this.el),
scaleX = elMatrix && elMatrix.a,
scaleY = elMatrix && elMatrix.d,
translateX = (currentRect.left - toRect.left) / (scaleX || 1),
translateY = (currentRect.top - toRect.top) / (scaleY || 1);
target.animatingX = !!translateX;
target.animatingY = !!translateY;
css(target, 'transform', 'translate3d(' + translateX + 'px,' + translateY + 'px,0)');
this.forRepaintDummy = repaint(target); // repaint
css(target, 'transition', 'transform ' + duration + 'ms' + (this.options.easing ? ' ' + this.options.easing : ''));
css(target, 'transform', 'translate3d(0,0,0)');
typeof target.animated === 'number' && clearTimeout(target.animated);
target.animated = setTimeout(function () {
css(target, 'transition', '');
css(target, 'transform', '');
target.animated = false;
target.animatingX = false;
target.animatingY = false;
}, duration);
}
}
};
}
function repaint(target) {
return target.offsetWidth;
}
function calculateRealTime(animatingRect, fromRect, toRect, options) {
return Math.sqrt(Math.pow(fromRect.top - animatingRect.top, 2) + Math.pow(fromRect.left - animatingRect.left, 2)) / Math.sqrt(Math.pow(fromRect.top - toRect.top, 2) + Math.pow(fromRect.left - toRect.left, 2)) * options.animation;
}
var plugins = [];
var defaults = {
initializeByDefault: true
};
var PluginManager = {
mount: function mount(plugin) {
// Set default static properties
for (var option in defaults) {
if (defaults.hasOwnProperty(option) && !(option in plugin)) {
plugin[option] = defaults[option];
}
}
plugins.forEach(function (p) {
if (p.pluginName === plugin.pluginName) {
throw "Sortable: Cannot mount plugin ".concat(plugin.pluginName, " more than once");
}
});
plugins.push(plugin);
},
pluginEvent: function pluginEvent(eventName, sortable, evt) {
var _this = this;
this.eventCanceled = false;
evt.cancel = function () {
_this.eventCanceled = true;
};
var eventNameGlobal = eventName + 'Global';
plugins.forEach(function (plugin) {
if (!sortable[plugin.pluginName]) return; // Fire global events if it exists in this sortable
if (sortable[plugin.pluginName][eventNameGlobal]) {
sortable[plugin.pluginName][eventNameGlobal](_objectSpread2({
sortable: sortable
}, evt));
} // Only fire plugin event if plugin is enabled in this sortable,
// and plugin has event defined
if (sortable.options[plugin.pluginName] && sortable[plugin.pluginName][eventName]) {
sortable[plugin.pluginName][eventName](_objectSpread2({
sortable: sortable
}, evt));
}
});
},
initializePlugins: function initializePlugins(sortable, el, defaults, options) {
plugins.forEach(function (plugin) {
var pluginName = plugin.pluginName;
if (!sortable.options[pluginName] && !plugin.initializeByDefault) return;
var initialized = new plugin(sortable, el, sortable.options);
initialized.sortable = sortable;
initialized.options = sortable.options;
sortable[pluginName] = initialized; // Add default options from plugin
_extends(defaults, initialized.defaults);
});
for (var option in sortable.options) {
if (!sortable.options.hasOwnProperty(option)) continue;
var modified = this.modifyOption(sortable, option, sortable.options[option]);
if (typeof modified !== 'undefined') {
sortable.options[option] = modified;
}
}
},
getEventProperties: function getEventProperties(name, sortable) {
var eventProperties = {};
plugins.forEach(function (plugin) {
if (typeof plugin.eventProperties !== 'function') return;
_extends(eventProperties, plugin.eventProperties.call(sortable[plugin.pluginName], name));
});
return eventProperties;
},
modifyOption: function modifyOption(sortable, name, value) {
var modifiedValue;
plugins.forEach(function (plugin) {
// Plugin must exist on the Sortable
if (!sortable[plugin.pluginName]) return; // If static option listener exists for this option, call in the context of the Sortable's instance of this plugin
if (plugin.optionListeners && typeof plugin.optionListeners[name] === 'function') {
modifiedValue = plugin.optionListeners[name].call(sortable[plugin.pluginName], value);
}
});
return modifiedValue;
}
};
function dispatchEvent(_ref) {
var sortable = _ref.sortable,
rootEl = _ref.rootEl,
name = _ref.name,
targetEl = _ref.targetEl,
cloneEl = _ref.cloneEl,
toEl = _ref.toEl,
fromEl = _ref.fromEl,
oldIndex = _ref.oldIndex,
newIndex = _ref.newIndex,
oldDraggableIndex = _ref.oldDraggableIndex,
newDraggableIndex = _ref.newDraggableIndex,
originalEvent = _ref.originalEvent,
putSortable = _ref.putSortable,
extraEventProperties = _ref.extraEventProperties;
sortable = sortable || rootEl && rootEl[expando];
if (!sortable) return;
var evt,
options = sortable.options,
onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1); // Support for new CustomEvent feature
if (window.CustomEvent && !IE11OrLess && !Edge) {
evt = new CustomEvent(name, {
bubbles: true,
cancelable: true
});
} else {
evt = document.createEvent('Event');
evt.initEvent(name, true, true);
}
evt.to = toEl || rootEl;
evt.from = fromEl || rootEl;
evt.item = targetEl || rootEl;
evt.clone = cloneEl;
evt.oldIndex = oldIndex;
evt.newIndex = newIndex;
evt.oldDraggableIndex = oldDraggableIndex;
evt.newDraggableIndex = newDraggableIndex;
evt.originalEvent = originalEvent;
evt.pullMode = putSortable ? putSortable.lastPutMode : undefined;
var allEventProperties = _objectSpread2(_objectSpread2({}, extraEventProperties), PluginManager.getEventProperties(name, sortable));
for (var option in allEventProperties) {
evt[option] = allEventProperties[option];
}
if (rootEl) {
rootEl.dispatchEvent(evt);
}
if (options[onName]) {
options[onName].call(sortable, evt);
}
}
var _excluded = ["evt"];
var pluginEvent = function pluginEvent(eventName, sortable) {
var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
originalEvent = _ref.evt,
data = _objectWithoutProperties(_ref, _excluded);
PluginManager.pluginEvent.bind(Sortable)(eventName, sortable, _objectSpread2({
dragEl: dragEl,
parentEl: parentEl,
ghostEl: ghostEl,
rootEl: rootEl,
nextEl: nextEl,
lastDownEl: lastDownEl,
cloneEl: cloneEl,
cloneHidden: cloneHidden,
dragStarted: moved,
putSortable: putSortable,
activeSortable: Sortable.active,
originalEvent: originalEvent,
oldIndex: oldIndex,
oldDraggableIndex: oldDraggableIndex,
newIndex: newIndex,
newDraggableIndex: newDraggableIndex,
hideGhostForTarget: _hideGhostForTarget,
unhideGhostForTarget: _unhideGhostForTarget,
cloneNowHidden: function cloneNowHidden() {
cloneHidden = true;
},
cloneNowShown: function cloneNowShown() {
cloneHidden = false;
},
dispatchSortableEvent: function dispatchSortableEvent(name) {
_dispatchEvent({
sortable: sortable,
name: name,
originalEvent: originalEvent
});
}
}, data));
};
function _dispatchEvent(info) {
dispatchEvent(_objectSpread2({
putSortable: putSortable,
cloneEl: cloneEl,
targetEl: dragEl,
rootEl: rootEl,
oldIndex: oldIndex,
oldDraggableIndex: oldDraggableIndex,
newIndex: newIndex,
newDraggableIndex: newDraggableIndex
}, info));
}
var dragEl,
parentEl,
ghostEl,
rootEl,
nextEl,
lastDownEl,
cloneEl,
cloneHidden,
oldIndex,
newIndex,
oldDraggableIndex,
newDraggableIndex,
activeGroup,
putSortable,
awaitingDragStarted = false,
ignoreNextClick = false,
sortables = [],
tapEvt,
touchEvt,
lastDx,
lastDy,
tapDistanceLeft,
tapDistanceTop,
moved,
lastTarget,
lastDirection,
pastFirstInvertThresh = false,
isCircumstantialInvert = false,
targetMoveDistance,
// For positioning ghost absolutely
ghostRelativeParent,
ghostRelativeParentInitialScroll = [],
// (left, top)
_silent = false,
savedInputChecked = [];
/** @const */
var documentExists = typeof document !== 'undefined',
PositionGhostAbsolutely = IOS,
CSSFloatProperty = Edge || IE11OrLess ? 'cssFloat' : 'float',
// This will not pass for IE9, because IE9 DnD only works on anchors
supportDraggable = documentExists && !ChromeForAndroid && !IOS && 'draggable' in document.createElement('div'),
supportCssPointerEvents = function () {
if (!documentExists) return; // false when <= IE11
if (IE11OrLess) {
return false;
}
var el = document.createElement('x');
el.style.cssText = 'pointer-events:auto';
return el.style.pointerEvents === 'auto';
}(),
_detectDirection = function _detectDirection(el, options) {
var elCSS = css(el),
elWidth = parseInt(elCSS.width) - parseInt(elCSS.paddingLeft) - parseInt(elCSS.paddingRight) - parseInt(elCSS.borderLeftWidth) - parseInt(elCSS.borderRightWidth),
child1 = getChild(el, 0, options),
child2 = getChild(el, 1, options),
firstChildCSS = child1 && css(child1),
secondChildCSS = child2 && css(child2),
firstChildWidth = firstChildCSS && parseInt(firstChildCSS.marginLeft) + parseInt(firstChildCSS.marginRight) + getRect(child1).width,
secondChildWidth = secondChildCSS && parseInt(secondChildCSS.marginLeft) + parseInt(secondChildCSS.marginRight) + getRect(child2).width;
if (elCSS.display === 'flex') {
return elCSS.flexDirection === 'column' || elCSS.flexDirection === 'column-reverse' ? 'vertical' : 'horizontal';
}
if (elCSS.display === 'grid') {
return elCSS.gridTemplateColumns.split(' ').length <= 1 ? 'vertical' : 'horizontal';
}
if (child1 && firstChildCSS["float"] && firstChildCSS["float"] !== 'none') {
var touchingSideChild2 = firstChildCSS["float"] === 'left' ? 'left' : 'right';
return child2 && (secondChildCSS.clear === 'both' || secondChildCSS.clear === touchingSideChild2) ? 'vertical' : 'horizontal';
}
return child1 && (firstChildCSS.display === 'block' || firstChildCSS.display === 'flex' || firstChildCSS.display === 'table' || firstChildCSS.display === 'grid' || firstChildWidth >= elWidth && elCSS[CSSFloatProperty] === 'none' || child2 && elCSS[CSSFloatProperty] === 'none' && firstChildWidth + secondChildWidth > elWidth) ? 'vertical' : 'horizontal';
},
_dragElInRowColumn = function _dragElInRowColumn(dragRect, targetRect, vertical) {
var dragElS1Opp = vertical ? dragRect.left : dragRect.top,
dragElS2Opp = vertical ? dragRect.right : dragRect.bottom,
dragElOppLength = vertical ? dragRect.width : dragRect.height,
targetS1Opp = vertical ? targetRect.left : targetRect.top,
targetS2Opp = vertical ? targetRect.right : targetRect.bottom,
targetOppLength = vertical ? targetRect.width : targetRect.height;
return dragElS1Opp === targetS1Opp || dragElS2Opp === targetS2Opp || dragElS1Opp + dragElOppLength / 2 === targetS1Opp + targetOppLength / 2;
},
/**
* Detects first nearest empty sortable to X and Y position using emptyInsertThreshold.
* @param {Number} x X position
* @param {Number} y Y position
* @return {HTMLElement} Element of the first found nearest Sortable
*/
_detectNearestEmptySortable = function _detectNearestEmptySortable(x, y) {
var ret;
sortables.some(function (sortable) {
var threshold = sortable[expando].options.emptyInsertThreshold;
if (!threshold || lastChild(sortable)) return;
var rect = getRect(sortable),
insideHorizontally = x >= rect.left - threshold && x <= rect.right + threshold,
insideVertically = y >= rect.top - threshold && y <= rect.bottom + threshold;
if (insideHorizontally && insideVertically) {
return ret = sortable;
}
});
return ret;
},
_prepareGroup = function _prepareGroup(options) {
function toFn(value, pull) {
return function (to, from, dragEl, evt) {
var sameGroup = to.options.group.name && from.options.group.name && to.options.group.name === from.options.group.name;
if (value == null && (pull || sameGroup)) {
// Default pull value
// Default pull and put value if same group
return true;
} else if (value == null || value === false) {
return false;
} else if (pull && value === 'clone') {
return value;
} else if (typeof value === 'function') {
return toFn(value(to, from, dragEl, evt), pull)(to, from, dragEl, evt);
} else {
var otherGroup = (pull ? to : from).options.group.name;
return value === true || typeof value === 'string' && value === otherGroup || value.join && value.indexOf(otherGroup) > -1;
}
};
}
var group = {};
var originalGroup = options.group;
if (!originalGroup || _typeof(originalGroup) != 'object') {
originalGroup = {
name: originalGroup
};
}
group.name = originalGroup.name;
group.checkPull = toFn(originalGroup.pull, true);
group.checkPut = toFn(originalGroup.put);
group.revertClone = originalGroup.revertClone;
options.group = group;
},
_hideGhostForTarget = function _hideGhostForTarget() {
if (!supportCssPointerEvents && ghostEl) {
css(ghostEl, 'display', 'none');
}
},
_unhideGhostForTarget = function _unhideGhostForTarget() {
if (!supportCssPointerEvents && ghostEl) {
css(ghostEl, 'display', '');
}
}; // #1184 fix - Prevent click event on fallback if dragged but item not changed position
if (documentExists) {
document.addEventListener('click', function (evt) {
if (ignoreNextClick) {
evt.preventDefault();
evt.stopPropagation && evt.stopPropagation();
evt.stopImmediatePropagation && evt.stopImmediatePropagation();
ignoreNextClick = false;
return false;
}
}, true);
}
var nearestEmptyInsertDetectEvent = function nearestEmptyInsertDetectEvent(evt) {
if (dragEl) {
evt = evt.touches ? evt.touches[0] : evt;
var nearest = _detectNearestEmptySortable(evt.clientX, evt.clientY);
if (nearest) {
// Create imitation event
var event = {};
for (var i in evt) {
if (evt.hasOwnProperty(i)) {
event[i] = evt[i];
}
}
event.target = event.rootEl = nearest;
event.preventDefault = void 0;
event.stopPropagation = void 0;
nearest[expando]._onDragOver(event);
}
}
};
var _checkOutsideTargetEl = function _checkOutsideTargetEl(evt) {
if (dragEl) {
dragEl.parentNode[expando]._isOutsideThisEl(evt.target);
}
};
/**
* @class Sortable
* @param {HTMLElement} el
* @param {Object} [options]
*/
function Sortable(el, options) {
if (!(el && el.nodeType && el.nodeType === 1)) {
throw "Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(el));
}
this.el = el; // root element
this.options = options = _extends({}, options); // Export instance
el[expando] = this;
var defaults = {
group: null,
sort: true,
disabled: false,
store: null,
handle: null,
draggable: /^[uo]l$/i.test(el.nodeName) ? '>li' : '>*',
swapThreshold: 1,
// percentage; 0 <= x <= 1
invertSwap: false,
// invert always
invertedSwapThreshold: null,
// will be set to same as swapThreshold if default
removeCloneOnHide: true,
direction: function direction() {
return _detectDirection(el, this.options);
},
ghostClass: 'sortable-ghost',
chosenClass: 'sortable-chosen',
dragClass: 'sortable-drag',
ignore: 'a, img',
filter: null,
preventOnFilter: true,
animation: 0,
easing: null,
setData: function setData(dataTransfer, dragEl) {
dataTransfer.setData('Text', dragEl.textContent);
},
dropBubble: false,
dragoverBubble: false,
dataIdAttr: 'data-id',
delay: 0,
delayOnTouchOnly: false,
touchStartThreshold: (Number.parseInt ? Number : window).parseInt(window.devicePixelRatio, 10) || 1,
forceFallback: false,
fallbackClass: 'sortable-fallback',
fallbackOnBody: false,
fallbackTolerance: 0,
fallbackOffset: {
x: 0,
y: 0
},
supportPointer: Sortable.supportPointer !== false && 'PointerEvent' in window && !Safari,
emptyInsertThreshold: 5
};
PluginManager.initializePlugins(this, el, defaults); // Set default options
for (var name in defaults) {
!(name in options) && (options[name] = defaults[name]);
}
_prepareGroup(options); // Bind all private methods
for (var fn in this) {
if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
this[fn] = this[fn].bind(this);
}
} // Setup drag mode
this.nativeDraggable = options.forceFallback ? false : supportDraggable;
if (this.nativeDraggable) {
// Touch start threshold cannot be greater than the native dragstart threshold
this.options.touchStartThreshold = 1;
} // Bind events
if (options.supportPointer) {
on(el, 'pointerdown', this._onTapStart);
} else {
on(el, 'mousedown', this._onTapStart);
on(el, 'touchstart', this._onTapStart);
}
if (this.nativeDraggable) {
on(el, 'dragover', this);
on(el, 'dragenter', this);
}
sortables.push(this.el); // Restore sorting
options.store && options.store.get && this.sort(options.store.get(this) || []); // Add animation state manager
_extends(this, AnimationStateManager());
}
Sortable.prototype =
/** @lends Sortable.prototype */
{
constructor: Sortable,
_isOutsideThisEl: function _isOutsideThisEl(target) {
if (!this.el.contains(target) && target !== this.el) {
lastTarget = null;
}
},
_getDirection: function _getDirection(evt, target) {
return typeof this.options.direction === 'function' ? this.options.direction.call(this, evt, target, dragEl) : this.options.direction;
},
_onTapStart: function _onTapStart(
/** Event|TouchEvent */
evt) {
if (!evt.cancelable) return;
var _this = this,
el = this.el,
options = this.options,
preventOnFilter = options.preventOnFilter,
type = evt.type,
touch = evt.touches && evt.touches[0] || evt.pointerType && evt.pointerType === 'touch' && evt,
target = (touch || evt).target,
originalTarget = evt.target.shadowRoot && (evt.path && evt.path[0] || evt.composedPath && evt.composedPath()[0]) || target,
filter = options.filter;
_saveInputCheckedState(el); // Don't trigger start event when an element is been dragged, otherwise the evt.oldindex always wrong when set option.group.
if (dragEl) {
return;
}
if (/mousedown|pointerdown/.test(type) && evt.button !== 0 || options.disabled) {
return; // only left button and enabled
} // cancel dnd if original target is content editable
if (originalTarget.isContentEditable) {
return;
} // Safari ignores further event handling after mousedown
if (!this.nativeDraggable && Safari && target && target.tagName.toUpperCase() === 'SELECT') {
return;
}
target = closest(target, options.draggable, el, false);
if (target && target.animated) {
return;
}
if (lastDownEl === target) {
// Ignoring duplicate `down`
return;
} // Get the index of the dragged element within its parent
oldIndex = index(target);
oldDraggableIndex = index(target, options.draggable); // Check filter
if (typeof filter === 'function') {
if (filter.call(this, evt, target, this)) {
_dispatchEvent({
sortable: _this,
rootEl: originalTarget,
name: 'filter',
targetEl: target,
toEl: el,
fromEl: el
});
pluginEvent('filter', _this, {
evt: evt
});
preventOnFilter && evt.cancelable && evt.preventDefault();
return; // cancel dnd
}
} else if (filter) {
filter = filter.split(',').some(function (criteria) {
criteria = closest(originalTarget, criteria.trim(), el, false);
if (criteria) {
_dispatchEvent({
sortable: _this,
rootEl: criteria,
name: 'filter',
targetEl: target,
fromEl: el,
toEl: el
});
pluginEvent('filter', _this, {
evt: evt
});
return true;
}
});
if (filter) {
preventOnFilter && evt.cancelable && evt.preventDefault();
return; // cancel dnd
}
}
if (options.handle && !closest(originalTarget, options.handle, el, false)) {
return;
} // Prepare `dragstart`
this._prepareDragStart(evt, touch, target);
},
_prepareDragStart: function _prepareDragStart(
/** Event */
evt,
/** Touch */
touch,
/** HTMLElement */
target) {
var _this = this,
el = _this.el,
options = _this.options,
ownerDocument = el.ownerDocument,
dragStartFn;
if (target && !dragEl && target.parentNode === el) {
var dragRect = getRect(target);
rootEl = el;
dragEl = target;
parentEl = dragEl.parentNode;
nextEl = dragEl.nextSibling;
lastDownEl = target;
activeGroup = options.group;
Sortable.dragged = dragEl;
tapEvt = {
target: dragEl,
clientX: (touch || evt).clientX,
clientY: (touch || evt).clientY
};
tapDistanceLeft = tapEvt.clientX - dragRect.left;
tapDistanceTop = tapEvt.clientY - dragRect.top;
this._lastX = (touch || evt).clientX;
this._lastY = (touch || evt).clientY;
dragEl.style['will-change'] = 'all';
dragStartFn = function dragStartFn() {
pluginEvent('delayEnded', _this, {
evt: evt
});
if (Sortable.eventCanceled) {
_this._onDrop();
return;
} // Delayed drag has been triggered
// we can re-enable the events: touchmove/mousemove
_this._disableDelayedDragEvents();
if (!FireFox && _this.nativeDraggable) {
dragEl.draggable = true;
} // Bind the events: dragstart/dragend
_this._triggerDragStart(evt, touch); // Drag start event
_dispatchEvent({
sortable: _this,
name: 'choose',
originalEvent: evt
}); // Chosen item
toggleClass(dragEl, options.chosenClass, true);
}; // Disable "draggable"
options.ignore.split(',').forEach(function (criteria) {
find(dragEl, criteria.trim(), _disableDraggable);
});
on(ownerDocument, 'dragover', nearestEmptyInsertDetectEvent);
on(ownerDocument, 'mousemove', nearestEmptyInsertDetectEvent);
on(ownerDocument, 'touchmove', nearestEmptyInsertDetectEvent);
on(ownerDocument, 'mouseup', _this._onDrop);
on(ownerDocument, 'touchend', _this._onDrop);
on(ownerDocument, 'touchcancel', _this._onDrop); // Make dragEl draggable (must be before delay for FireFox)
if (FireFox && this.nativeDraggable) {
this.options.touchStartThreshold = 4;
dragEl.draggable = true;
}
pluginEvent('delayStart', this, {
evt: evt
}); // Delay is impossible for native DnD in Edge or IE
if (options.delay && (!options.delayOnTouchOnly || touch) && (!this.nativeDraggable || !(Edge || IE11OrLess))) {
if (Sortable.eventCanceled) {
this._onDrop();
return;
} // If the user moves the pointer or let go the click or touch
// before the delay has been reached:
// disable the delayed drag
on(ownerDocument, 'mouseup', _this._disableDelayedDrag);
on(ownerDocument, 'touchend', _this._disableDelayedDrag);
on(ownerDocument, 'touchcancel', _this._disableDelayedDrag);
on(ownerDocument, 'mousemove', _this._delayedDragTouchMoveHandler);
on(ownerDocument, 'touchmove', _this._delayedDragTouchMoveHandler);
options.supportPointer && on(ownerDocument, 'pointermove', _this._delayedDragTouchMoveHandler);
_this._dragStartTimer = setTimeout(dragStartFn, options.delay);
} else {
dragStartFn();
}
}
},
_delayedDragTouchMoveHandler: function _delayedDragTouchMoveHandler(
/** TouchEvent|PointerEvent **/
e) {
var touch = e.touches ? e.touches[0] : e;
if (Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) >= Math.floor(this.options.touchStartThreshold / (this.nativeDraggable && window.devicePixelRatio || 1))) {
this._disableDelayedDrag();
}
},
_disableDelayedDrag: function _disableDelayedDrag() {
dragEl && _disableDraggable(dragEl);
clearTimeout(this._dragStartTimer);
this._disableDelayedDragEvents();
},
_disableDelayedDragEvents: function _disableDelayedDragEvents() {
var ownerDocument = this.el.ownerDocument;
off(ownerDocument, 'mouseup', this._disableDelayedDrag);
off(ownerDocument, 'touchend', this._disableDelayedDrag);
off(ownerDocument, 'touchcancel', this._disableDelayedDrag);
off(ownerDocument, 'mousemove', this._delayedDragTouchMoveHandler);
off(ownerDocument, 'touchmove', this._delayedDragTouchMoveHandler);
off(ownerDocument, 'pointermove', this._delayedDragTouchMoveHandler);
},
_triggerDragStart: function _triggerDragStart(
/** Event */
evt,
/** Touch */
touch) {
touch = touch || evt.pointerType == 'touch' && evt;
if (!this.nativeDraggable || touch) {
if (this.options.supportPointer) {
on(document, 'pointermove', this._onTouchMove);
} else if (touch) {
on(document, 'touchmove', this._onTouchMove);
} else {
on(document, 'mousemove', this._onTouchMove);
}
} else {
on(dragEl, 'dragend', this);
on(rootEl, 'dragstart', this._onDragStart);
}
try {
if (document.selection) {
// Timeout neccessary for IE9
_nextTick(function () {
document.selection.empty();
});
} else {
window.getSelection().removeAllRanges();
}
} catch (err) {}
},
_dragStarted: function _dragStarted(fallback, evt) {
awaitingDragStarted = false;
if (rootEl && dragEl) {
pluginEvent('dragStarted', this, {
evt: evt
});
if (this.nativeDraggable) {
on(document, 'dragover', _checkOutsideTargetEl);
}
var options = this.options; // Apply effect
!fallback && toggleClass(dragEl, options.dragClass, false);
toggleClass(dragEl, options.ghostClass, true);
Sortable.active = this;
fallback && this._appendGhost(); // Drag start event
_dispatchEvent({
sortable: this,
name: 'start',
originalEvent: evt
});
} else {
this._nulling();
}
},
_emulateDragOver: function _emulateDragOver() {
if (touchEvt) {
this._lastX = touchEvt.clientX;
this._lastY = touchEvt.clientY;
_hideGhostForTarget();
var target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY);
var parent = target;
while (target && target.shadowRoot) {
target = target.shadowRoot.elementFromPoint(touchEvt.clientX, touchEvt.clientY);
if (target === parent) break;
parent = target;
}
dragEl.parentNode[expando]._isOutsideThisEl(target);
if (parent) {
do {
if (parent[expando]) {
var inserted = void 0;
inserted = parent[expando]._onDragOver({
clientX: touchEvt.clientX,
clientY: touchEvt.clientY,
target: target,
rootEl: parent
});
if (inserted && !this.options.dragoverBubble) {
break;
}
}
target = parent; // store last element
}
/* jshint boss:true */
while (parent = parent.parentNode);
}
_unhideGhostForTarget();
}
},
_onTouchMove: function _onTouchMove(
/**TouchEvent*/
evt) {
if (tapEvt) {
var options = this.options,
fallbackTolerance = options.fallbackTolerance,
fallbackOffset = options.fallbackOffset,
touch = evt.touches ? evt.touches[0] : evt,
ghostMatrix = ghostEl && matrix(ghostEl, true),
scaleX = ghostEl && ghostMatrix && ghostMatrix.a,
scaleY = ghostEl && ghostMatrix && ghostMatrix.d,
relativeScrollOffset = PositionGhostAbsolutely && ghostRelativeParent && getRelativeScrollOffset(ghostRelativeParent),
dx = (touch.clientX - tapEvt.clientX + fallbackOffset.x) / (scaleX || 1) + (relativeScrollOffset ? relativeScrollOffset[0] - ghostRelativeParentInitialScroll[0] : 0) / (scaleX || 1),
dy = (touch.clientY - tapEvt.clientY + fallbackOffset.y) / (scaleY || 1) + (relativeScrollOffset ? relativeScrollOffset[1] - ghostRelativeParentInitialScroll[1] : 0) / (scaleY || 1); // only set the status to dragging, when we are actually dragging
if (!Sortable.active && !awaitingDragStarted) {
if (fallbackTolerance && Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) < fallbackTolerance) {
return;
}
this._onDragStart(evt, true);
}
if (ghostEl) {
if (ghostMatrix) {
ghostMatrix.e += dx - (lastDx || 0);
ghostMatrix.f += dy - (lastDy || 0);
} else {
ghostMatrix = {
a: 1,
b: 0,
c: 0,
d: 1,
e: dx,
f: dy
};
}
var cssMatrix = "matrix(".concat(ghostMatrix.a, ",").concat(ghostMatrix.b, ",").concat(ghostMatrix.c, ",").concat(ghostMatrix.d, ",").concat(ghostMatrix.e, ",").concat(ghostMatrix.f, ")");
css(ghostEl, 'webkitTransform', cssMatrix);
css(ghostEl, 'mozTransform', cssMatrix);
css(ghostEl, 'msTransform', cssMatrix);
css(ghostEl, 'transform', cssMatrix);
lastDx = dx;
lastDy = dy;
touchEvt = touch;
}
evt.cancelable && evt.preventDefault();
}
},
_appendGhost: function _appendGhost() {
// Bug if using scale(): https://stackoverflow.com/questions/2637058
// Not being adjusted for
if (!ghostEl) {
var container = this.options.fallbackOnBody ? document.body : rootEl,
rect = getRect(dragEl, true, PositionGhostAbsolutely, true, container),
options = this.options; // Position absolutely
if (PositionGhostAbsolutely) {
// Get relatively positioned parent
ghostRelativeParent = container;
while (css(ghostRelativeParent, 'position') === 'static' && css(ghostRelativeParent, 'transform') === 'none' && ghostRelativeParent !== document) {
ghostRelativeParent = ghostRelativeParent.parentNode;
}
if (ghostRelativeParent !== document.body && ghostRelativeParent !== document.documentElement) {
if (ghostRelativeParent === document) ghostRelativeParent = getWindowScrollingElement();
rect.top += ghostRelativeParent.scrollTop;
rect.left += ghostRelativeParent.scrollLeft;
} else {
ghostRelativeParent = getWindowScrollingElement();
}
ghostRelativeParentInitialScroll = getRelativeScrollOffset(ghostRelativeParent);
}
ghostEl = dragEl.cloneNode(true);
toggleClass(ghostEl, options.ghostClass, false);
toggleClass(ghostEl, options.fallbackClass, true);
toggleClass(ghostEl, options.dragClass, true);
css(ghostEl, 'transition', '');
css(ghostEl, 'transform', '');
css(ghostEl, 'box-sizing', 'border-box');
css(ghostEl, 'margin', 0);
css(ghostEl, 'top', rect.top);
css(ghostEl, 'left', rect.left);
css(ghostEl, 'width', rect.width);
css(ghostEl, 'height', rect.height);
css(ghostEl, 'opacity', '0.8');
css(ghostEl, 'position', PositionGhostAbsolutely ? 'absolute' : 'fixed');
css(ghostEl, 'zIndex', '100000');
css(ghostEl, 'pointerEvents', 'none');
Sortable.ghost = ghostEl;
container.appendChild(ghostEl); // Set transform-origin
css(ghostEl, 'transform-origin', tapDistanceLeft / parseInt(ghostEl.style.width) * 100 + '% ' + tapDistanceTop / parseInt(ghostEl.style.height) * 100 + '%');
}
},
_onDragStart: function _onDragStart(
/**Event*/
evt,
/**boolean*/
fallback) {
var _this = this;
var dataTransfer = evt.dataTransfer;
var options = _this.options;
pluginEvent('dragStart', this, {
evt: evt
});
if (Sortable.eventCanceled) {
this._onDrop();
return;
}
pluginEvent('setupClone', this);
if (!Sortable.eventCanceled) {
cloneEl = clone(dragEl);
cloneEl.draggable = false;
cloneEl.style['will-change'] = '';
this._hideClone();
toggleClass(cloneEl, this.options.chosenClass, false);
Sortable.clone = cloneEl;
} // #1143: IFrame support workaround
_this.cloneId = _nextTick(function () {
pluginEvent('clone', _this);
if (Sortable.eventCanceled) return;
if (!_this.options.removeCloneOnHide) {
rootEl.insertBefore(cloneEl, dragEl);
}
_this._hideClone();
_dispatchEvent({
sortable: _this,
name: 'clone'
});
});
!fallback && toggleClass(dragEl, options.dragClass, true); // Set proper drop events
if (fallback) {
ignoreNextClick = true;
_this._loopId = setInterval(_this._emulateDragOver, 50);
} else {
// Undo what was set in _prepareDragStart before drag started
off(document, 'mouseup', _this._onDrop);
off(document, 'touchend', _this._onDrop);
off(document, 'touchcancel', _this._onDrop);
if (dataTransfer) {
dataTransfer.effectAllowed = 'move';
options.setData && options.setData.call(_this, dataTransfer, dragEl);
}
on(document, 'drop', _this); // #1276 fix:
css(dragEl, 'transform', 'translateZ(0)');
}
awaitingDragStarted = true;
_this._dragStartId = _nextTick(_this._dragStarted.bind(_this, fallback, evt));
on(document, 'selectstart', _this);
moved = true;
if (Safari) {
css(document.body, 'user-select', 'none');
}
},
// Returns true - if no further action is needed (either inserted or another condition)
_onDragOver: function _onDragOver(
/**Event*/
evt) {
var el = this.el,
target = evt.target,
dragRect,
targetRect,
revert,
options = this.options,
group = options.group,
activeSortable = Sortable.active,
isOwner = activeGroup === group,
canSort = options.sort,
fromSortable = putSortable || activeSortable,
vertical,
_this = this,
completedFired = false;
if (_silent) return;
function dragOverEvent(name, extra) {
pluginEvent(name, _this, _objectSpread2({
evt: evt,
isOwner: isOwner,
axis: vertical ? 'vertical' : 'horizontal',
revert: revert,
dragRect: dragRect,
targetRect: targetRect,
canSort: canSort,
fromSortable: fromSortable,
target: target,
completed: completed,
onMove: function onMove(target, after) {
return _onMove(rootEl, el, dragEl, dragRect, target, getRect(target), evt, after);
},
changed: changed
}, extra));
} // Capture animation state
function capture() {
dragOverEvent('dragOverAnimationCapture');
_this.captureAnimationState();
if (_this !== fromSortable) {
fromSortable.captureAnimationState();
}
} // Return invocation when dragEl is inserted (or completed)
function completed(insertion) {
dragOverEvent('dragOverCompleted', {
insertion: insertion
});
if (insertion) {
// Clones must be hidden before folding animation to capture dragRectAbsolute properly
if (isOwner) {
activeSortable._hideClone();
} else {
activeSortable._showClone(_this);
}
if (_this !== fromSortable) {
// Set ghost class to new sortable's ghost class
toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : activeSortable.options.ghostClass, false);
toggleClass(dragEl, options.ghostClass, true);
}
if (putSortable !== _this && _this !== Sortable.active) {
putSortable = _this;
} else if (_this === Sortable.active && putSortable) {
putSortable = null;
} // Animation
if (fromSortable === _this) {
_this._ignoreWhileAnimating = target;
}
_this.animateAll(function () {
dragOverEvent('dragOverAnimationComplete');
_this._ignoreWhileAnimating = null;
});
if (_this !== fromSortable) {
fromSortable.animateAll();
fromSortable._ignoreWhileAnimating = null;
}
} // Null lastTarget if it is not inside a previously swapped element
if (target === dragEl && !dragEl.animated || target === el && !target.animated) {
lastTarget = null;
} // no bubbling and not fallback
if (!options.dragoverBubble && !evt.rootEl && target !== document) {
dragEl.parentNode[expando]._isOutsideThisEl(evt.target); // Do not detect for empty insert if already inserted
!insertion && nearestEmptyInsertDetectEvent(evt);
}
!options.dragoverBubble && evt.stopPropagation && evt.stopPropagation();
return completedFired = true;
} // Call when dragEl has been inserted
function changed() {
newIndex = index(dragEl);
newDraggableIndex = index(dragEl, options.draggable);
_dispatchEvent({
sortable: _this,
name: 'change',
toEl: el,
newIndex: newIndex,
newDraggableIndex: newDraggableIndex,
originalEvent: evt
});
}
if (evt.preventDefault !== void 0) {
evt.cancelable && evt.preventDefault();
}
target = closest(target, options.draggable, el, true);
dragOverEvent('dragOver');
if (Sortable.eventCanceled) return completedFired;
if (dragEl.contains(evt.target) || target.animated && target.animatingX && target.animatingY || _this._ignoreWhileAnimating === target) {
return completed(false);
}
ignoreNextClick = false;
if (activeSortable && !options.disabled && (isOwner ? canSort || (revert = parentEl !== rootEl) // Reverting item into the original list
: putSortable === this || (this.lastPutMode = activeGroup.checkPull(this, activeSortable, dragEl, evt)) && group.checkPut(this, activeSortable, dragEl, evt))) {
vertical = this._getDirection(evt, target) === 'vertical';
dragRect = getRect(dragEl);
dragOverEvent('dragOverValid');
if (Sortable.eventCanceled) return completedFired;
if (revert) {
parentEl = rootEl; // actualization
capture();
this._hideClone();
dragOverEvent('revert');
if (!Sortable.eventCanceled) {
if (nextEl) {
rootEl.insertBefore(dragEl, nextEl);
} else {
rootEl.appendChild(dragEl);
}
}
return completed(true);
}
var elLastChild = lastChild(el, options.draggable);
if (!elLastChild || _ghostIsLast(evt, vertical, this) && !elLastChild.animated) {
// Insert to end of list
// If already at end of list: Do not insert
if (elLastChild === dragEl) {
return completed(false);
} // if there is a last element, it is the target
if (elLastChild && el === evt.target) {
target = elLastChild;
}
if (target) {
targetRect = getRect(target);
}
if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, !!target) !== false) {
capture();
el.appendChild(dragEl);
parentEl = el; // actualization
changed();
return completed(true);
}
} else if (elLastChild && _ghostIsFirst(evt, vertical, this)) {
// Insert to start of list
var firstChild = getChild(el, 0, options, true);
if (firstChild === dragEl) {
return completed(false);
}
target = firstChild;
targetRect = getRect(target);
if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, false) !== false) {
capture();
el.insertBefore(dragEl, firstChild);
parentEl = el; // actualization
changed();
return completed(true);
}
} else if (target.parentNode === el) {
targetRect = getRect(target);
var direction = 0,
targetBeforeFirstSwap,
differentLevel = dragEl.parentNode !== el,
differentRowCol = !_dragElInRowColumn(dragEl.animated && dragEl.toRect || dragRect, target.animated && target.toRect || targetRect, vertical),
side1 = vertical ? 'top' : 'left',
scrolledPastTop = isScrolledPast(target, 'top', 'top') || isScrolledPast(dragEl, 'top', 'top'),
scrollBefore = scrolledPastTop ? scrolledPastTop.scrollTop : void 0;
if (lastTarget !== target) {
targetBeforeFirstSwap = targetRect[side1];
pastFirstInvertThresh = false;
isCircumstantialInvert = !differentRowCol && options.invertSwap || differentLevel;
}
direction = _getSwapDirection(evt, target, targetRect, vertical, differentRowCol ? 1 : options.swapThreshold, options.invertedSwapThreshold == null ? options.swapThreshold : options.invertedSwapThreshold, isCircumstantialInvert, lastTarget === target);
var sibling;
if (direction !== 0) {
// Check if target is beside dragEl in respective direction (ignoring hidden elements)
var dragIndex = index(dragEl);
do {
dragIndex -= direction;
sibling = parentEl.children[dragIndex];
} while (sibling && (css(sibling, 'display') === 'none' || sibling === ghostEl));
} // If dragEl is already beside target: Do not insert
if (direction === 0 || sibling === target) {
return completed(false);
}
lastTarget = target;
lastDirection = direction;
var nextSibling = target.nextElementSibling,
after = false;
after = direction === 1;
var moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, after);
if (moveVector !== false) {
if (moveVector === 1 || moveVector === -1) {
after = moveVector === 1;
}
_silent = true;
setTimeout(_unsilent, 30);
capture();
if (after && !nextSibling) {
el.appendChild(dragEl);
} else {
target.parentNode.insertBefore(dragEl, after ? nextSibling : target);
} // Undo chrome's scroll adjustment (has no effect on other browsers)
if (scrolledPastTop) {
scrollBy(scrolledPastTop, 0, scrollBefore - scrolledPastTop.scrollTop);
}
parentEl = dragEl.parentNode; // actualization
// must be done before animation
if (targetBeforeFirstSwap !== undefined && !isCircumstantialInvert) {
targetMoveDistance = Math.abs(targetBeforeFirstSwap - getRect(target)[side1]);
}
changed();
return completed(true);
}
}
if (el.contains(dragEl)) {
return completed(false);
}
}
return false;
},
_ignoreWhileAnimating: null,
_offMoveEvents: function _offMoveEvents() {
off(document, 'mousemove', this._onTouchMove);
off(document, 'touchmove', this._onTouchMove);
off(document, 'pointermove', this._onTouchMove);
off(document, 'dragover', nearestEmptyInsertDetectEvent);
off(document, 'mousemove', nearestEmptyInsertDetectEvent);
off(document, 'touchmove', nearestEmptyInsertDetectEvent);
},
_offUpEvents: function _offUpEvents() {
var ownerDocument = this.el.ownerDocument;
off(ownerDocument, 'mouseup', this._onDrop);
off(ownerDocument, 'touchend', this._onDrop);
off(ownerDocument, 'pointerup', this._onDrop);
off(ownerDocument, 'touchcancel', this._onDrop);
off(document, 'selectstart', this);
},
_onDrop: function _onDrop(
/**Event*/
evt) {
var el = this.el,
options = this.options; // Get the index of the dragged element within its parent
newIndex = index(dragEl);
newDraggableIndex = index(dragEl, options.draggable);
pluginEvent('drop', this, {
evt: evt
});
parentEl = dragEl && dragEl.parentNode; // Get again after plugin event
newIndex = index(dragEl);
newDraggableIndex = index(dragEl, options.draggable);
if (Sortable.eventCanceled) {
this._nulling();
return;
}
awaitingDragStarted = false;
isCircumstantialInvert = false;
pastFirstInvertThresh = false;
clearInterval(this._loopId);
clearTimeout(this._dragStartTimer);
_cancelNextTick(this.cloneId);
_cancelNextTick(this._dragStartId); // Unbind events
if (this.nativeDraggable) {
off(document, 'drop', this);
off(el, 'dragstart', this._onDragStart);
}
this._offMoveEvents();
this._offUpEvents();
if (Safari) {
css(document.body, 'user-select', '');
}
css(dragEl, 'transform', '');
if (evt) {
if (moved) {
evt.cancelable && evt.preventDefault();
!options.dropBubble && evt.stopPropagation();
}
ghostEl && ghostEl.parentNode && ghostEl.parentNode.removeChild(ghostEl);
if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') {
// Remove clone(s)
cloneEl && cloneEl.parentNode && cloneEl.parentNode.removeChild(cloneEl);
}
if (dragEl) {
if (this.nativeDraggable) {
off(dragEl, 'dragend', this);
}
_disableDraggable(dragEl);
dragEl.style['will-change'] = ''; // Remove classes
// ghostClass is added in dragStarted
if (moved && !awaitingDragStarted) {
toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : this.options.ghostClass, false);
}
toggleClass(dragEl, this.options.chosenClass, false); // Drag stop event
_dispatchEvent({
sortable: this,
name: 'unchoose',
toEl: parentEl,
newIndex: null,
newDraggableIndex: null,
originalEvent: evt
});
if (rootEl !== parentEl) {
if (newIndex >= 0) {
// Add event
_dispatchEvent({
rootEl: parentEl,
name: 'add',
toEl: parentEl,
fromEl: rootEl,
originalEvent: evt
}); // Remove event
_dispatchEvent({
sortable: this,
name: 'remove',
toEl: parentEl,
originalEvent: evt
}); // drag from one list and drop into another
_dispatchEvent({
rootEl: parentEl,
name: 'sort',
toEl: parentEl,
fromEl: rootEl,
originalEvent: evt
});
_dispatchEvent({
sortable: this,
name: 'sort',
toEl: parentEl,
originalEvent: evt
});
}
putSortable && putSortable.save();
} else {
if (newIndex !== oldIndex) {
if (newIndex >= 0) {
// drag & drop within the same list
_dispatchEvent({
sortable: this,
name: 'update',
toEl: parentEl,
originalEvent: evt
});
_dispatchEvent({
sortable: this,
name: 'sort',
toEl: parentEl,
originalEvent: evt
});
}
}
}
if (Sortable.active) {
/* jshint eqnull:true */
if (newIndex == null || newIndex === -1) {
newIndex = oldIndex;
newDraggableIndex = oldDraggableIndex;
}
_dispatchEvent({
sortable: this,
name: 'end',
toEl: parentEl,
originalEvent: evt
}); // Save sorting
this.save();
}
}
}
this._nulling();
},
_nulling: function _nulling() {
pluginEvent('nulling', this);
rootEl = dragEl = parentEl = ghostEl = nextEl = cloneEl = lastDownEl = cloneHidden = tapEvt = touchEvt = moved = newIndex = newDraggableIndex = oldIndex = oldDraggableIndex = lastTarget = lastDirection = putSortable = activeGroup = Sortable.dragged = Sortable.ghost = Sortable.clone = Sortable.active = null;
savedInputChecked.forEach(function (el) {
el.checked = true;
});
savedInputChecked.length = lastDx = lastDy = 0;
},
handleEvent: function handleEvent(
/**Event*/
evt) {
switch (evt.type) {
case 'drop':
case 'dragend':
this._onDrop(evt);
break;
case 'dragenter':
case 'dragover':
if (dragEl) {
this._onDragOver(evt);
_globalDragOver(evt);
}
break;
case 'selectstart':
evt.preventDefault();
break;
}
},
/**
* Serializes the item into an array of string.
* @returns {String[]}
*/
toArray: function toArray() {
var order = [],
el,
children = this.el.children,
i = 0,
n = children.length,
options = this.options;
for (; i < n; i++) {
el = children[i];
if (closest(el, options.draggable, this.el, false)) {
order.push(el.getAttribute(options.dataIdAttr) || _generateId(el));
}
}
return order;
},
/**
* Sorts the elements according to the array.
* @param {String[]} order order of the items
*/
sort: function sort(order, useAnimation) {
var items = {},
rootEl = this.el;
this.toArray().forEach(function (id, i) {
var el = rootEl.children[i];
if (closest(el, this.options.draggable, rootEl, false)) {
items[id] = el;
}
}, this);
useAnimation && this.captureAnimationState();
order.forEach(function (id) {
if (items[id]) {
rootEl.removeChild(items[id]);
rootEl.appendChild(items[id]);
}
});
useAnimation && this.animateAll();
},
/**
* Save the current sorting
*/
save: function save() {
var store = this.options.store;
store && store.set && store.set(this);
},
/**
* For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree.
* @param {HTMLElement} el
* @param {String} [selector] default: `options.draggable`
* @returns {HTMLElement|null}
*/
closest: function closest$1(el, selector) {
return closest(el, selector || this.options.draggable, this.el, false);
},
/**
* Set/get option
* @param {string} name
* @param {*} [value]
* @returns {*}
*/
option: function option(name, value) {
var options = this.options;
if (value === void 0) {
return options[name];
} else {
var modifiedValue = PluginManager.modifyOption(this, name, value);
if (typeof modifiedValue !== 'undefined') {
options[name] = modifiedValue;
} else {
options[name] = value;
}
if (name === 'group') {
_prepareGroup(options);
}
}
},
/**
* Destroy
*/
destroy: function destroy() {
pluginEvent('destroy', this);
var el = this.el;
el[expando] = null;
off(el, 'mousedown', this._onTapStart);
off(el, 'touchstart', this._onTapStart);
off(el, 'pointerdown', this._onTapStart);
if (this.nativeDraggable) {
off(el, 'dragover', this);
off(el, 'dragenter', this);
} // Remove draggable attributes
Array.prototype.forEach.call(el.querySelectorAll('[draggable]'), function (el) {
el.removeAttribute('draggable');
});
this._onDrop();
this._disableDelayedDragEvents();
sortables.splice(sortables.indexOf(this.el), 1);
this.el = el = null;
},
_hideClone: function _hideClone() {
if (!cloneHidden) {
pluginEvent('hideClone', this);
if (Sortable.eventCanceled) return;
css(cloneEl, 'display', 'none');
if (this.options.removeCloneOnHide && cloneEl.parentNode) {
cloneEl.parentNode.removeChild(cloneEl);
}
cloneHidden = true;
}
},
_showClone: function _showClone(putSortable) {
if (putSortable.lastPutMode !== 'clone') {
this._hideClone();
return;
}
if (cloneHidden) {
pluginEvent('showClone', this);
if (Sortable.eventCanceled) return; // show clone at dragEl or original position
if (dragEl.parentNode == rootEl && !this.options.group.revertClone) {
rootEl.insertBefore(cloneEl, dragEl);
} else if (nextEl) {
rootEl.insertBefore(cloneEl, nextEl);
} else {
rootEl.appendChild(cloneEl);
}
if (this.options.group.revertClone) {
this.animate(dragEl, cloneEl);
}
css(cloneEl, 'display', '');
cloneHidden = false;
}
}
};
function _globalDragOver(
/**Event*/
evt) {
if (evt.dataTransfer) {
evt.dataTransfer.dropEffect = 'move';
}
evt.cancelable && evt.preventDefault();
}
function _onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect, originalEvent, willInsertAfter) {
var evt,
sortable = fromEl[expando],
onMoveFn = sortable.options.onMove,
retVal; // Support for new CustomEvent feature
if (window.CustomEvent && !IE11OrLess && !Edge) {
evt = new CustomEvent('move', {
bubbles: true,
cancelable: true
});
} else {
evt = document.createEvent('Event');
evt.initEvent('move', true, true);
}
evt.to = toEl;
evt.from = fromEl;
evt.dragged = dragEl;
evt.draggedRect = dragRect;
evt.related = targetEl || toEl;
evt.relatedRect = targetRect || getRect(toEl);
evt.willInsertAfter = willInsertAfter;
evt.originalEvent = originalEvent;
fromEl.dispatchEvent(evt);
if (onMoveFn) {
retVal = onMoveFn.call(sortable, evt, originalEvent);
}
return retVal;
}
function _disableDraggable(el) {
el.draggable = false;
}
function _unsilent() {
_silent = false;
}
function _ghostIsFirst(evt, vertical, sortable) {
var rect = getRect(getChild(sortable.el, 0, sortable.options, true));
var spacer = 10;
return vertical ? evt.clientX < rect.left - spacer || evt.clientY < rect.top && evt.clientX < rect.right : evt.clientY < rect.top - spacer || evt.clientY < rect.bottom && evt.clientX < rect.left;
}
function _ghostIsLast(evt, vertical, sortable) {
var rect = getRect(lastChild(sortable.el, sortable.options.draggable));
var spacer = 10;
return vertical ? evt.clientX > rect.right + spacer || evt.clientX <= rect.right && evt.clientY > rect.bottom && evt.clientX >= rect.left : evt.clientX > rect.right && evt.clientY > rect.top || evt.clientX <= rect.right && evt.clientY > rect.bottom + spacer;
}
function _getSwapDirection(evt, target, targetRect, vertical, swapThreshold, invertedSwapThreshold, invertSwap, isLastTarget) {
var mouseOnAxis = vertical ? evt.clientY : evt.clientX,
targetLength = vertical ? targetRect.height : targetRect.width,
targetS1 = vertical ? targetRect.top : targetRect.left,
targetS2 = vertical ? targetRect.bottom : targetRect.right,
invert = false;
if (!invertSwap) {
// Never invert or create dragEl shadow when target movemenet causes mouse to move past the end of regular swapThreshold
if (isLastTarget && targetMoveDistance < targetLength * swapThreshold) {
// multiplied only by swapThreshold because mouse will already be inside target by (1 - threshold) * targetLength / 2
// check if past first invert threshold on side opposite of lastDirection
if (!pastFirstInvertThresh && (lastDirection === 1 ? mouseOnAxis > targetS1 + targetLength * invertedSwapThreshold / 2 : mouseOnAxis < targetS2 - targetLength * invertedSwapThreshold / 2)) {
// past first invert threshold, do not restrict inverted threshold to dragEl shadow
pastFirstInvertThresh = true;
}
if (!pastFirstInvertThresh) {
// dragEl shadow (target move distance shadow)
if (lastDirection === 1 ? mouseOnAxis < targetS1 + targetMoveDistance // over dragEl shadow
: mouseOnAxis > targetS2 - targetMoveDistance) {
return -lastDirection;
}
} else {
invert = true;
}
} else {
// Regular
if (mouseOnAxis > targetS1 + targetLength * (1 - swapThreshold) / 2 && mouseOnAxis < targetS2 - targetLength * (1 - swapThreshold) / 2) {
return _getInsertDirection(target);
}
}
}
invert = invert || invertSwap;
if (invert) {
// Invert of regular
if (mouseOnAxis < targetS1 + targetLength * invertedSwapThreshold / 2 || mouseOnAxis > targetS2 - targetLength * invertedSwapThreshold / 2) {
return mouseOnAxis > targetS1 + targetLength / 2 ? 1 : -1;
}
}
return 0;
}
/**
* Gets the direction dragEl must be swapped relative to target in order to make it
* seem that dragEl has been "inserted" into that element's position
* @param {HTMLElement} target The target whose position dragEl is being inserted at
* @return {Number} Direction dragEl must be swapped
*/
function _getInsertDirection(target) {
if (index(dragEl) < index(target)) {
return 1;
} else {
return -1;
}
}
/**
* Generate id
* @param {HTMLElement} el
* @returns {String}
* @private
*/
function _generateId(el) {
var str = el.tagName + el.className + el.src + el.href + el.textContent,
i = str.length,
sum = 0;
while (i--) {
sum += str.charCodeAt(i);
}
return sum.toString(36);
}
function _saveInputCheckedState(root) {
savedInputChecked.length = 0;
var inputs = root.getElementsByTagName('input');
var idx = inputs.length;
while (idx--) {
var el = inputs[idx];
el.checked && savedInputChecked.push(el);
}
}
function _nextTick(fn) {
return setTimeout(fn, 0);
}
function _cancelNextTick(id) {
return clearTimeout(id);
} // Fixed #973:
if (documentExists) {
on(document, 'touchmove', function (evt) {
if ((Sortable.active || awaitingDragStarted) && evt.cancelable) {
evt.preventDefault();
}
});
} // Export utils
Sortable.utils = {
on: on,
off: off,
css: css,
find: find,
is: function is(el, selector) {
return !!closest(el, selector, el, false);
},
extend: extend,
throttle: throttle,
closest: closest,
toggleClass: toggleClass,
clone: clone,
index: index,
nextTick: _nextTick,
cancelNextTick: _cancelNextTick,
detectDirection: _detectDirection,
getChild: getChild
};
/**
* Get the Sortable instance of an element
* @param {HTMLElement} element The element
* @return {Sortable|undefined} The instance of Sortable
*/
Sortable.get = function (element) {
return element[expando];
};
/**
* Mount a plugin to Sortable
* @param {...SortablePlugin|SortablePlugin[]} plugins Plugins being mounted
*/
Sortable.mount = function () {
for (var _len = arguments.length, plugins = new Array(_len), _key = 0; _key < _len; _key++) {
plugins[_key] = arguments[_key];
}
if (plugins[0].constructor === Array) plugins = plugins[0];
plugins.forEach(function (plugin) {
if (!plugin.prototype || !plugin.prototype.constructor) {
throw "Sortable: Mounted plugin must be a constructor function, not ".concat({}.toString.call(plugin));
}
if (plugin.utils) Sortable.utils = _objectSpread2(_objectSpread2({}, Sortable.utils), plugin.utils);
PluginManager.mount(plugin);
});
};
/**
* Create sortable instance
* @param {HTMLElement} el
* @param {Object} [options]
*/
Sortable.create = function (el, options) {
return new Sortable(el, options);
}; // Export
Sortable.version = version;
var drop = function drop(_ref) {
var originalEvent = _ref.originalEvent,
putSortable = _ref.putSortable,
dragEl = _ref.dragEl,
activeSortable = _ref.activeSortable,
dispatchSortableEvent = _ref.dispatchSortableEvent,
hideGhostForTarget = _ref.hideGhostForTarget,
unhideGhostForTarget = _ref.unhideGhostForTarget;
if (!originalEvent) return;
var toSortable = putSortable || activeSortable;
hideGhostForTarget();
var touch = originalEvent.changedTouches && originalEvent.changedTouches.length ? originalEvent.changedTouches[0] : originalEvent;
var target = document.elementFromPoint(touch.clientX, touch.clientY);
unhideGhostForTarget();
if (toSortable && !toSortable.el.contains(target)) {
dispatchSortableEvent('spill');
this.onSpill({
dragEl: dragEl,
putSortable: putSortable
});
}
};
function Revert() {}
Revert.prototype = {
startIndex: null,
dragStart: function dragStart(_ref2) {
var oldDraggableIndex = _ref2.oldDraggableIndex;
this.startIndex = oldDraggableIndex;
},
onSpill: function onSpill(_ref3) {
var dragEl = _ref3.dragEl,
putSortable = _ref3.putSortable;
this.sortable.captureAnimationState();
if (putSortable) {
putSortable.captureAnimationState();
}
var nextSibling = getChild(this.sortable.el, this.startIndex, this.options);
if (nextSibling) {
this.sortable.el.insertBefore(dragEl, nextSibling);
} else {
this.sortable.el.appendChild(dragEl);
}
this.sortable.animateAll();
if (putSortable) {
putSortable.animateAll();
}
},
drop: drop
};
_extends(Revert, {
pluginName: 'revertOnSpill'
});
function Remove() {}
Remove.prototype = {
onSpill: function onSpill(_ref4) {
var dragEl = _ref4.dragEl,
putSortable = _ref4.putSortable;
var parentSortable = putSortable || this.sortable;
parentSortable.captureAnimationState();
dragEl.parentNode && dragEl.parentNode.removeChild(dragEl);
parentSortable.animateAll();
},
drop: drop
};
_extends(Remove, {
pluginName: 'removeOnSpill'
});
/* src/view/sortable/SortableList.svelte generated by Svelte v3.38.2 */
function get_each_context$2(ctx, list, i) {
const child_ctx = ctx.slice();
child_ctx[10] = list[i];
return child_ctx;
}
const get_default_slot_changes = dirty => ({ item: dirty & /*items*/ 1 });
const get_default_slot_context = ctx => ({ item: /*item*/ ctx[10] });
// (33:2) {#each items as item (item.id)}
function create_each_block$2(key_1, ctx) {
let li;
let t;
let li_data_id_value;
let current;
const default_slot_template = /*#slots*/ ctx[5].default;
const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[4], get_default_slot_context);
return {
key: key_1,
first: null,
c() {
li = element("li");
if (default_slot) default_slot.c();
t = space();
attr(li, "data-id", li_data_id_value = /*item*/ ctx[10].id);
this.first = li;
},
m(target, anchor) {
insert(target, li, anchor);
if (default_slot) {
default_slot.m(li, null);
}
append(li, t);
current = true;
},
p(new_ctx, dirty) {
ctx = new_ctx;
if (default_slot) {
if (default_slot.p && (!current || dirty & /*$$scope, items*/ 17)) {
update_slot(default_slot, default_slot_template, ctx, /*$$scope*/ ctx[4], dirty, get_default_slot_changes, get_default_slot_context);
}
}
if (!current || dirty & /*items*/ 1 && li_data_id_value !== (li_data_id_value = /*item*/ ctx[10].id)) {
attr(li, "data-id", li_data_id_value);
}
},
i(local) {
if (current) return;
transition_in(default_slot, local);
current = true;
},
o(local) {
transition_out(default_slot, local);
current = false;
},
d(detaching) {
if (detaching) detach(li);
if (default_slot) default_slot.d(detaching);
}
};
}
function create_fragment$6(ctx) {
let ul;
let each_blocks = [];
let each_1_lookup = new Map();
let ul_class_value;
let current;
let each_value = /*items*/ ctx[0];
const get_key = ctx => /*item*/ ctx[10].id;
for (let i = 0; i < each_value.length; i += 1) {
let child_ctx = get_each_context$2(ctx, each_value, i);
let key = get_key(child_ctx);
each_1_lookup.set(key, each_blocks[i] = create_each_block$2(key, child_ctx));
}
return {
c() {
ul = element("ul");
for (let i = 0; i < each_blocks.length; i += 1) {
each_blocks[i].c();
}
attr(ul, "class", ul_class_value = /*$$props*/ ctx[2].class);
},
m(target, anchor) {
insert(target, ul, anchor);
for (let i = 0; i < each_blocks.length; i += 1) {
each_blocks[i].m(ul, null);
}
/*ul_binding*/ ctx[6](ul);
current = true;
},
p(ctx, [dirty]) {
if (dirty & /*items, $$scope*/ 17) {
each_value = /*items*/ ctx[0];
group_outros();
each_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, ul, outro_and_destroy_block, create_each_block$2, null, get_each_context$2);
check_outros();
}
if (!current || dirty & /*$$props*/ 4 && ul_class_value !== (ul_class_value = /*$$props*/ ctx[2].class)) {
attr(ul, "class", ul_class_value);
}
},
i(local) {
if (current) return;
for (let i = 0; i < each_value.length; i += 1) {
transition_in(each_blocks[i]);
}
current = true;
},
o(local) {
for (let i = 0; i < each_blocks.length; i += 1) {
transition_out(each_blocks[i]);
}
current = false;
},
d(detaching) {
if (detaching) detach(ul);
for (let i = 0; i < each_blocks.length; i += 1) {
each_blocks[i].d();
}
/*ul_binding*/ ctx[6](null);
}
};
}
function instance$6($$self, $$props, $$invalidate) {
let { $$slots: slots = {}, $$scope } = $$props;
let { items = [] } = $$props;
let { sortableOptions = {} } = $$props;
// Prepare sortable bits. Set up a dispatcher for sort events,
// and proxy the store.set function to fire it.
const dispatcher = createEventDispatcher();
sortableOptions = Object.assign({}, sortableOptions);
sortableOptions.store = sortableOptions.store || {
set: () => {
},
get: sortable => sortable.toArray()
};
const oldStoreSet = sortableOptions.store.set;
sortableOptions.store.set = sortable => {
const sortedItems = sortable.toArray().map(k => items.find(i => i.id === k));
dispatcher("orderChanged", sortedItems);
oldStoreSet(sortable);
};
let listElement;
onMount(() => {
Sortable.create(listElement, sortableOptions);
});
function ul_binding($$value) {
binding_callbacks[$$value ? "unshift" : "push"](() => {
listElement = $$value;
$$invalidate(1, listElement);
});
}
$$self.$$set = $$new_props => {
$$invalidate(2, $$props = assign(assign({}, $$props), exclude_internal_props($$new_props)));
if ("items" in $$new_props) $$invalidate(0, items = $$new_props.items);
if ("sortableOptions" in $$new_props) $$invalidate(3, sortableOptions = $$new_props.sortableOptions);
if ("$$scope" in $$new_props) $$invalidate(4, $$scope = $$new_props.$$scope);
};
$$props = exclude_internal_props($$props);
return [items, listElement, $$props, sortableOptions, $$scope, slots, ul_binding];
}
class SortableList extends SvelteComponent {
constructor(options) {
super();
init(this, options, instance$6, create_fragment$6, safe_not_equal, { items: 0, sortableOptions: 3 });
}
}
/* src/view/explorer/DraftList.svelte generated by Svelte v3.38.2 */
const { document: document_1$1 } = globals;
function add_css$4() {
var style = element("style");
style.id = "svelte-1jmafs-style";
style.textContent = "#draft-list.svelte-1jmafs.svelte-1jmafs{margin:4px 0px}#draft-list.svelte-1jmafs .sortable-draft-list{list-style-type:none;padding:0px;margin:0px}.draft-container.svelte-1jmafs.svelte-1jmafs{display:flex;border:1px solid transparent;border-radius:3px;cursor:pointer;color:var(--text-muted);font-size:14px;line-height:20px;white-space:nowrap;padding:2px 0px}.selected.svelte-1jmafs.svelte-1jmafs,.svelte-1jmafs:not(.dragging) .draft-container.svelte-1jmafs:hover{background-color:var(--background-secondary-alt);color:var(--text-normal)}.draft-container.svelte-1jmafs.svelte-1jmafs:active{background-color:inherit;color:var(--text-muted)}.draft-ghost{background-color:var(--interactive-accent-hover);color:var(--text-on-accent)}";
append(document_1$1.head, style);
}
// (89:2) <SortableList bind:items let:item on:orderChanged={itemOrderChanged} {sortableOptions} class="sortable-draft-list" >
function create_default_slot$2(ctx) {
let div;
let t_value = /*item*/ ctx[18].name + "";
let t;
let div_data_draft_path_value;
let div_contenteditable_value;
let mounted;
let dispose;
function click_handler() {
return /*click_handler*/ ctx[11](/*item*/ ctx[18]);
}
return {
c() {
div = element("div");
t = text(t_value);
attr(div, "class", "draft-container svelte-1jmafs");
attr(div, "data-draft-path", div_data_draft_path_value = /*item*/ ctx[18].id);
attr(div, "contenteditable", div_contenteditable_value = /*item*/ ctx[18].id === /*editingPath*/ ctx[2]);
toggle_class(div, "selected", /*$currentDraftPath*/ ctx[3] && /*$currentDraftPath*/ ctx[3] === /*item*/ ctx[18].id);
},
m(target, anchor) {
insert(target, div, anchor);
append(div, t);
if (!mounted) {
dispose = [
listen(div, "click", click_handler),
listen(div, "contextmenu", prevent_default(/*onContext*/ ctx[7])),
listen(div, "keydown", function () {
if (is_function(/*item*/ ctx[18].id === /*editingPath*/ ctx[2]
? /*onKeydown*/ ctx[8]
: null)) (/*item*/ ctx[18].id === /*editingPath*/ ctx[2]
? /*onKeydown*/ ctx[8]
: null).apply(this, arguments);
}),
listen(div, "blur", function () {
if (is_function(/*item*/ ctx[18].id === /*editingPath*/ ctx[2]
? /*onBlur*/ ctx[9]
: null)) (/*item*/ ctx[18].id === /*editingPath*/ ctx[2]
? /*onBlur*/ ctx[9]
: null).apply(this, arguments);
})
];
mounted = true;
}
},
p(new_ctx, dirty) {
ctx = new_ctx;
if (dirty & /*item*/ 262144 && t_value !== (t_value = /*item*/ ctx[18].name + "")) set_data(t, t_value);
if (dirty & /*item*/ 262144 && div_data_draft_path_value !== (div_data_draft_path_value = /*item*/ ctx[18].id)) {
attr(div, "data-draft-path", div_data_draft_path_value);
}
if (dirty & /*item, editingPath*/ 262148 && div_contenteditable_value !== (div_contenteditable_value = /*item*/ ctx[18].id === /*editingPath*/ ctx[2])) {
attr(div, "contenteditable", div_contenteditable_value);
}
if (dirty & /*$currentDraftPath, item*/ 262152) {
toggle_class(div, "selected", /*$currentDraftPath*/ ctx[3] && /*$currentDraftPath*/ ctx[3] === /*item*/ ctx[18].id);
}
},
d(detaching) {
if (detaching) detach(div);
mounted = false;
run_all(dispose);
}
};
}
function create_fragment$5(ctx) {
let div;
let sortablelist;
let updating_items;
let current;
function sortablelist_items_binding(value) {
/*sortablelist_items_binding*/ ctx[12](value);
}
let sortablelist_props = {
sortableOptions: /*sortableOptions*/ ctx[4],
class: "sortable-draft-list",
$$slots: {
default: [
create_default_slot$2,
({ item }) => ({ 18: item }),
({ item }) => item ? 262144 : 0
]
},
$$scope: { ctx }
};
if (/*items*/ ctx[0] !== void 0) {
sortablelist_props.items = /*items*/ ctx[0];
}
sortablelist = new SortableList({ props: sortablelist_props });
binding_callbacks.push(() => bind(sortablelist, "items", sortablelist_items_binding));
sortablelist.$on("orderChanged", /*itemOrderChanged*/ ctx[5]);
return {
c() {
div = element("div");
create_component(sortablelist.$$.fragment);
attr(div, "id", "draft-list");
attr(div, "class", "svelte-1jmafs");
toggle_class(div, "dragging", /*isSorting*/ ctx[1]);
},
m(target, anchor) {
insert(target, div, anchor);
mount_component(sortablelist, div, null);
current = true;
},
p(ctx, [dirty]) {
const sortablelist_changes = {};
if (dirty & /*$$scope, item, editingPath, $currentDraftPath*/ 786444) {
sortablelist_changes.$$scope = { dirty, ctx };
}
if (!updating_items && dirty & /*items*/ 1) {
updating_items = true;
sortablelist_changes.items = /*items*/ ctx[0];
add_flush_callback(() => updating_items = false);
}
sortablelist.$set(sortablelist_changes);
if (dirty & /*isSorting*/ 2) {
toggle_class(div, "dragging", /*isSorting*/ ctx[1]);
}
},
i(local) {
if (current) return;
transition_in(sortablelist.$$.fragment, local);
current = true;
},
o(local) {
transition_out(sortablelist.$$.fragment, local);
current = false;
},
d(detaching) {
if (detaching) detach(div);
destroy_component(sortablelist);
}
};
}
function selectElementContents(el) {
var range = document.createRange();
range.selectNodeContents(el);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
function instance$5($$self, $$props, $$invalidate) {
let $currentProject;
let $projectMetadata;
let $currentProjectPath;
let $currentDraftPath;
component_subscribe($$self, currentProject, $$value => $$invalidate(10, $currentProject = $$value));
component_subscribe($$self, projectMetadata, $$value => $$invalidate(13, $projectMetadata = $$value));
component_subscribe($$self, currentProjectPath, $$value => $$invalidate(14, $currentProjectPath = $$value));
component_subscribe($$self, currentDraftPath, $$value => $$invalidate(3, $currentDraftPath = $$value));
let items;
// Track sort state for styling, set sorting options
let isSorting = false;
const sortableOptions = {
animation: 150,
ghostClass: "draft-ghost",
onStart: () => {
$$invalidate(1, isSorting = true);
},
onEnd: () => {
$$invalidate(1, isSorting = false);
}
};
// Called when sorting ends an the item order has been updated.
// Reorder scenes according and set into the store.
function itemOrderChanged(event) {
// Reorder metadata accounts to this new order
const reorderedDrafts = [...$currentProject.drafts].sort((a, b) => {
const aIndex = event.detail.findIndex(d => d.id === a.folder);
const bIndex = event.detail.findIndex(d => d.id === b.folder);
return aIndex - bIndex;
});
set_store_value(projectMetadata, $projectMetadata[$currentProjectPath].drafts = reorderedDrafts, $projectMetadata);
}
function onItemClick(path) {
if (path) {
set_store_value(currentDraftPath, $currentDraftPath = path, $currentDraftPath);
}
}
let editingPath = null;
const showRenameDraftMenu = getContext("showRenameDraftMenu");
function onContext(event) {
const { x, y } = event;
const element = document.elementFromPoint(x, y);
showRenameDraftMenu(x, y, () => {
if (element && element instanceof HTMLElement) {
const draftPath = element.dataset.draftPath;
$$invalidate(2, editingPath = draftPath);
setTimeout(() => selectElementContents(element), 0);
}
});
}
const renameFolder = getContext("renameFolder");
const makeDraftPath = getContext("makeDraftPath");
function onKeydown(event) {
if (editingPath && event.target instanceof HTMLElement) {
if (event.key === "Enter") {
const oldPath = makeDraftPath(editingPath);
const newPath = makeDraftPath(event.target.innerText);
renameFolder(oldPath, newPath);
$$invalidate(2, editingPath = null);
return false;
} else if (event.key === "Escape") {
event.target.blur();
return false;
}
}
return true;
}
function onBlur(event) {
if (event.target instanceof HTMLElement) {
event.target.innerText = editingPath;
}
$$invalidate(2, editingPath = null);
}
const click_handler = item => onItemClick(item.id);
function sortablelist_items_binding(value) {
items = value;
($$invalidate(0, items), $$invalidate(10, $currentProject));
}
$$self.$$.update = () => {
if ($$self.$$.dirty & /*$currentProject*/ 1024) {
{
$$invalidate(0, items = $currentProject
? $currentProject.drafts.map(d => ({ id: d.folder, name: d.name }))
: []);
}
}
};
return [
items,
isSorting,
editingPath,
$currentDraftPath,
sortableOptions,
itemOrderChanged,
onItemClick,
onContext,
onKeydown,
onBlur,
$currentProject,
click_handler,
sortablelist_items_binding
];
}
class DraftList extends SvelteComponent {
constructor(options) {
super();
if (!document_1$1.getElementById("svelte-1jmafs-style")) add_css$4();
init(this, options, instance$5, create_fragment$5, safe_not_equal, {});
}
}
/* src/view/explorer/NewDraftField.svelte generated by Svelte v3.38.2 */
function add_css$3() {
var style = element("style");
style.id = "svelte-1wkli4h-style";
style.textContent = ".new-draft-container.svelte-1wkli4h{margin:0;border-top:1px solid var(--text-muted);padding:4px 0}#new-draft.svelte-1wkli4h{padding:0;border:0;background:inherit;font-size:14px;line-height:20px;width:100%}#new-draft.invalid.svelte-1wkli4h{color:var(--text-error)}#new-draft.svelte-1wkli4h::placeholder{font-style:italic}.draft-description.svelte-1wkli4h{font-size:10px;line-height:12px;color:var(--text-muted)}";
append(document.head, style);
}
function get_each_context$1(ctx, list, i) {
const child_ctx = ctx.slice();
child_ctx[16] = list[i];
return child_ctx;
}
// (77:2) {#if error}
function create_if_block_3$1(ctx) {
let p;
let t;
return {
c() {
p = element("p");
t = text(/*error*/ ctx[4]);
},
m(target, anchor) {
insert(target, p, anchor);
append(p, t);
},
p(ctx, dirty) {
if (dirty & /*error*/ 16) set_data(t, /*error*/ ctx[4]);
},
d(detaching) {
if (detaching) detach(p);
}
};
}
// (80:2) {#if newDraftName.length > 0}
function create_if_block$3(ctx) {
let select;
let option;
let t1;
let p;
let mounted;
let dispose;
let each_value = /*$currentProject*/ ctx[1].drafts;
let each_blocks = [];
for (let i = 0; i < each_value.length; i += 1) {
each_blocks[i] = create_each_block$1(get_each_context$1(ctx, each_value, i));
}
function select_block_type(ctx, dirty) {
if (/*newDraftName*/ ctx[0] && /*copyFromDraft*/ ctx[3]) return create_if_block_1$2;
if (/*newDraftName*/ ctx[0]) return create_if_block_2$1;
}
let current_block_type = select_block_type(ctx);
let if_block = current_block_type && current_block_type(ctx);
return {
c() {
select = element("select");
option = element("option");
option.textContent = "Empty Draft";
for (let i = 0; i < each_blocks.length; i += 1) {
each_blocks[i].c();
}
t1 = space();
p = element("p");
if (if_block) if_block.c();
option.__value = null;
option.value = option.__value;
attr(select, "name", "copyFrom");
if (/*copyFromDraft*/ ctx[3] === void 0) add_render_callback(() => /*select_change_handler*/ ctx[9].call(select));
attr(p, "class", "draft-description svelte-1wkli4h");
},
m(target, anchor) {
insert(target, select, anchor);
append(select, option);
for (let i = 0; i < each_blocks.length; i += 1) {
each_blocks[i].m(select, null);
}
select_option(select, /*copyFromDraft*/ ctx[3]);
insert(target, t1, anchor);
insert(target, p, anchor);
if (if_block) if_block.m(p, null);
if (!mounted) {
dispose = listen(select, "change", /*select_change_handler*/ ctx[9]);
mounted = true;
}
},
p(ctx, dirty) {
if (dirty & /*$currentProject*/ 2) {
each_value = /*$currentProject*/ ctx[1].drafts;
let i;
for (i = 0; i < each_value.length; i += 1) {
const child_ctx = get_each_context$1(ctx, each_value, i);
if (each_blocks[i]) {
each_blocks[i].p(child_ctx, dirty);
} else {
each_blocks[i] = create_each_block$1(child_ctx);
each_blocks[i].c();
each_blocks[i].m(select, null);
}
}
for (; i < each_blocks.length; i += 1) {
each_blocks[i].d(1);
}
each_blocks.length = each_value.length;
}
if (dirty & /*copyFromDraft, $currentProject*/ 10) {
select_option(select, /*copyFromDraft*/ ctx[3]);
}
if (current_block_type === (current_block_type = select_block_type(ctx)) && if_block) {
if_block.p(ctx, dirty);
} else {
if (if_block) if_block.d(1);
if_block = current_block_type && current_block_type(ctx);
if (if_block) {
if_block.c();
if_block.m(p, null);
}
}
},
d(detaching) {
if (detaching) detach(select);
destroy_each(each_blocks, detaching);
if (detaching) detach(t1);
if (detaching) detach(p);
if (if_block) {
if_block.d();
}
mounted = false;
dispose();
}
};
}
// (83:6) {#each $currentProject.drafts as draftOption}
function create_each_block$1(ctx) {
let option;
let t_value = `Copy of ${/*draftOption*/ ctx[16].name}` + "";
let t;
let option_value_value;
return {
c() {
option = element("option");
t = text(t_value);
option.__value = option_value_value = /*draftOption*/ ctx[16].folder;
option.value = option.__value;
},
m(target, anchor) {
insert(target, option, anchor);
append(option, t);
},
p(ctx, dirty) {
if (dirty & /*$currentProject*/ 2 && t_value !== (t_value = `Copy of ${/*draftOption*/ ctx[16].name}` + "")) set_data(t, t_value);
if (dirty & /*$currentProject*/ 2 && option_value_value !== (option_value_value = /*draftOption*/ ctx[16].folder)) {
option.__value = option_value_value;
option.value = option.__value;
}
},
d(detaching) {
if (detaching) detach(option);
}
};
}
// (92:29)
function create_if_block_2$1(ctx) {
let t0;
let t1;
return {
c() {
t0 = text(/*newDraftName*/ ctx[0]);
t1 = text(" will start as an empty folder.");
},
m(target, anchor) {
insert(target, t0, anchor);
insert(target, t1, anchor);
},
p(ctx, dirty) {
if (dirty & /*newDraftName*/ 1) set_data(t0, /*newDraftName*/ ctx[0]);
},
d(detaching) {
if (detaching) detach(t0);
if (detaching) detach(t1);
}
};
}
// (90:6) {#if newDraftName && copyFromDraft}
function create_if_block_1$2(ctx) {
let t0;
let t1;
let t2;
let t3;
return {
c() {
t0 = text(/*newDraftName*/ ctx[0]);
t1 = text(" will start as a copy of ");
t2 = text(/*copyFromDraft*/ ctx[3]);
t3 = text(".");
},
m(target, anchor) {
insert(target, t0, anchor);
insert(target, t1, anchor);
insert(target, t2, anchor);
insert(target, t3, anchor);
},
p(ctx, dirty) {
if (dirty & /*newDraftName*/ 1) set_data(t0, /*newDraftName*/ ctx[0]);
if (dirty & /*copyFromDraft*/ 8) set_data(t2, /*copyFromDraft*/ ctx[3]);
},
d(detaching) {
if (detaching) detach(t0);
if (detaching) detach(t1);
if (detaching) detach(t2);
if (detaching) detach(t3);
}
};
}
function create_fragment$4(ctx) {
let div;
let input;
let t0;
let t1;
let mounted;
let dispose;
let if_block0 = /*error*/ ctx[4] && create_if_block_3$1(ctx);
let if_block1 = /*newDraftName*/ ctx[0].length > 0 && create_if_block$3(ctx);
return {
c() {
div = element("div");
input = element("input");
t0 = space();
if (if_block0) if_block0.c();
t1 = space();
if (if_block1) if_block1.c();
attr(input, "id", "new-draft");
attr(input, "type", "text");
attr(input, "placeholder", "New Draft…");
attr(input, "class", "svelte-1wkli4h");
toggle_class(input, "invalid", !!/*error*/ ctx[4]);
attr(div, "class", "new-draft-container svelte-1wkli4h");
},
m(target, anchor) {
insert(target, div, anchor);
append(div, input);
set_input_value(input, /*newDraftName*/ ctx[0]);
/*input_binding*/ ctx[7](input);
append(div, t0);
if (if_block0) if_block0.m(div, null);
append(div, t1);
if (if_block1) if_block1.m(div, null);
if (!mounted) {
dispose = [
listen(input, "input", /*input_input_handler*/ ctx[6]),
listen(input, "keydown", /*keydown_handler*/ ctx[8])
];
mounted = true;
}
},
p(ctx, [dirty]) {
if (dirty & /*newDraftName*/ 1 && input.value !== /*newDraftName*/ ctx[0]) {
set_input_value(input, /*newDraftName*/ ctx[0]);
}
if (dirty & /*error*/ 16) {
toggle_class(input, "invalid", !!/*error*/ ctx[4]);
}
if (/*error*/ ctx[4]) {
if (if_block0) {
if_block0.p(ctx, dirty);
} else {
if_block0 = create_if_block_3$1(ctx);
if_block0.c();
if_block0.m(div, t1);
}
} else if (if_block0) {
if_block0.d(1);
if_block0 = null;
}
if (/*newDraftName*/ ctx[0].length > 0) {
if (if_block1) {
if_block1.p(ctx, dirty);
} else {
if_block1 = create_if_block$3(ctx);
if_block1.c();
if_block1.m(div, null);
}
} else if (if_block1) {
if_block1.d(1);
if_block1 = null;
}
},
i: noop,
o: noop,
d(detaching) {
if (detaching) detach(div);
/*input_binding*/ ctx[7](null);
if (if_block0) if_block0.d();
if (if_block1) if_block1.d();
mounted = false;
run_all(dispose);
}
};
}
function instance$4($$self, $$props, $$invalidate) {
let $currentProject;
let $currentDraftPath;
let $projectMetadata;
let $currentProjectPath;
component_subscribe($$self, currentProject, $$value => $$invalidate(1, $currentProject = $$value));
component_subscribe($$self, currentDraftPath, $$value => $$invalidate(10, $currentDraftPath = $$value));
component_subscribe($$self, projectMetadata, $$value => $$invalidate(11, $projectMetadata = $$value));
component_subscribe($$self, currentProjectPath, $$value => $$invalidate(12, $currentProjectPath = $$value));
const makeDraftPath = getContext("makeDraftPath");
const makeScenePath = getContext("makeScenePath");
let newDraftName = "";
let newDraftInput;
let copyFromDraft = null;
let error = null;
const onNewDraft = getContext("onNewDraft");
function onNewDraftEnter() {
return __awaiter(this, void 0, void 0, function* () {
if (newDraftName.length > 0 && !error) {
const draftPath = makeDraftPath(newDraftName);
if (draftPath) {
let copying = [];
let newDraftSceneOrder;
if (copyFromDraft) {
const sourceDraft = $currentProject.drafts.find(d => d.folder === copyFromDraft);
if (sourceDraft) {
newDraftSceneOrder = sourceDraft.scenes;
copying = sourceDraft.scenes.map(s => ({
from: makeScenePath(s, sourceDraft.folder),
to: makeScenePath(s, newDraftName)
}));
}
}
yield onNewDraft(draftPath, copying);
set_store_value(currentDraftPath, $currentDraftPath = newDraftName, $currentDraftPath);
if (copyFromDraft && newDraftSceneOrder) {
const newDraftIndex = $projectMetadata[$currentProjectPath].drafts.findIndex(d => d.folder === newDraftName);
if (newDraftIndex >= 0) {
const newDraft = $projectMetadata[$currentProjectPath].drafts[newDraftIndex];
newDraft.scenes = newDraftSceneOrder;
set_store_value(projectMetadata, $projectMetadata[$currentProjectPath].drafts[newDraftIndex] = newDraft, $projectMetadata);
}
}
$$invalidate(0, newDraftName = "");
}
}
});
}
function input_input_handler() {
newDraftName = this.value;
$$invalidate(0, newDraftName);
}
function input_binding($$value) {
binding_callbacks[$$value ? "unshift" : "push"](() => {
newDraftInput = $$value;
$$invalidate(2, newDraftInput);
});
}
const keydown_handler = e => {
if (e.key === "Enter") {
onNewDraftEnter();
} else if (e.key === "Escape") {
$$invalidate(0, newDraftName = "");
newDraftInput.blur();
}
};
function select_change_handler() {
copyFromDraft = select_value(this);
$$invalidate(3, copyFromDraft);
}
$$self.$$.update = () => {
if ($$self.$$.dirty & /*newDraftName, $currentProject*/ 3) {
{
if (newDraftName.length === 0) {
$$invalidate(4, error = null);
} else if ($currentProject.drafts.find(d => d.folder === newDraftName)) {
$$invalidate(4, error = "A draft with this name already exists.");
} else if (newDraftName.match(/[\/\\:]/g)) {
$$invalidate(4, error = "A draft name cannot contain the characters: \\ / :");
} else {
$$invalidate(4, error = null);
}
}
}
};
return [
newDraftName,
$currentProject,
newDraftInput,
copyFromDraft,
error,
onNewDraftEnter,
input_input_handler,
input_binding,
keydown_handler,
select_change_handler
];
}
class NewDraftField extends SvelteComponent {
constructor(options) {
super();
if (!document.getElementById("svelte-1wkli4h-style")) add_css$3();
init(this, options, instance$4, create_fragment$4, safe_not_equal, {});
}
}
/* src/view/explorer/NewSceneField.svelte generated by Svelte v3.38.2 */
function add_css$2() {
var style = element("style");
style.id = "svelte-1lq63fp-style";
style.textContent = ".new-scene-container.svelte-1lq63fp{margin:0;border-top:1px solid var(--text-muted);padding:4px 0}#new-scene.svelte-1lq63fp{padding:0;border:0;background:inherit;font-size:14px;line-height:20px;width:100%}#new-scene.invalid.svelte-1lq63fp{color:var(--text-error)}#new-scene.svelte-1lq63fp::placeholder{font-style:italic}";
append(document.head, style);
}
// (50:2) {#if error}
function create_if_block$2(ctx) {
let p;
let t;
return {
c() {
p = element("p");
t = text(/*error*/ ctx[2]);
},
m(target, anchor) {
insert(target, p, anchor);
append(p, t);
},
p(ctx, dirty) {
if (dirty & /*error*/ 4) set_data(t, /*error*/ ctx[2]);
},
d(detaching) {
if (detaching) detach(p);
}
};
}
function create_fragment$3(ctx) {
let div;
let input;
let t;
let mounted;
let dispose;
let if_block = /*error*/ ctx[2] && create_if_block$2(ctx);
return {
c() {
div = element("div");
input = element("input");
t = space();
if (if_block) if_block.c();
attr(input, "id", "new-scene");
attr(input, "type", "text");
attr(input, "placeholder", "New Scene…");
attr(input, "class", "svelte-1lq63fp");
toggle_class(input, "invalid", !!/*error*/ ctx[2]);
attr(div, "class", "new-scene-container svelte-1lq63fp");
},
m(target, anchor) {
insert(target, div, anchor);
append(div, input);
set_input_value(input, /*newSceneName*/ ctx[0]);
/*input_binding*/ ctx[6](input);
append(div, t);
if (if_block) if_block.m(div, null);
if (!mounted) {
dispose = [
listen(input, "input", /*input_input_handler*/ ctx[5]),
listen(input, "keydown", /*keydown_handler*/ ctx[7])
];
mounted = true;
}
},
p(ctx, [dirty]) {
if (dirty & /*newSceneName*/ 1 && input.value !== /*newSceneName*/ ctx[0]) {
set_input_value(input, /*newSceneName*/ ctx[0]);
}
if (dirty & /*error*/ 4) {
toggle_class(input, "invalid", !!/*error*/ ctx[2]);
}
if (/*error*/ ctx[2]) {
if (if_block) {
if_block.p(ctx, dirty);
} else {
if_block = create_if_block$2(ctx);
if_block.c();
if_block.m(div, null);
}
} else if (if_block) {
if_block.d(1);
if_block = null;
}
},
i: noop,
o: noop,
d(detaching) {
if (detaching) detach(div);
/*input_binding*/ ctx[6](null);
if (if_block) if_block.d();
mounted = false;
run_all(dispose);
}
};
}
function instance$3($$self, $$props, $$invalidate) {
let $currentDraft;
component_subscribe($$self, currentDraft, $$value => $$invalidate(4, $currentDraft = $$value));
let newSceneName = "";
let newSceneInput;
let error = null;
const makeScenePath = getContext("makeScenePath");
const onNewScene = getContext("onNewScene");
function onNewSceneEnter() {
if (newSceneName.length > 0 && !error) {
const scenePath = makeScenePath(newSceneName);
if (scenePath) {
onNewScene(scenePath);
$$invalidate(0, newSceneName = "");
}
}
}
function input_input_handler() {
newSceneName = this.value;
$$invalidate(0, newSceneName);
}
function input_binding($$value) {
binding_callbacks[$$value ? "unshift" : "push"](() => {
newSceneInput = $$value;
$$invalidate(1, newSceneInput);
});
}
const keydown_handler = e => {
if (e.key === "Enter") {
onNewSceneEnter();
} else if (e.key === "Escape") {
$$invalidate(0, newSceneName = "");
newSceneInput.blur();
}
};
$$self.$$.update = () => {
if ($$self.$$.dirty & /*newSceneName, $currentDraft*/ 17) {
{
if (newSceneName.length === 0) {
$$invalidate(2, error = null);
} else if ($currentDraft.scenes.contains(newSceneName)) {
$$invalidate(2, error = "A scene with this name already exists in this draft.");
} else if (newSceneName.match(/[\/\\:]/g)) {
$$invalidate(2, error = "A scene name cannot contain the characters: \\ / :");
} else {
$$invalidate(2, error = null);
}
}
}
};
return [
newSceneName,
newSceneInput,
error,
onNewSceneEnter,
$currentDraft,
input_input_handler,
input_binding,
keydown_handler
];
}
class NewSceneField extends SvelteComponent {
constructor(options) {
super();
if (!document.getElementById("svelte-1lq63fp-style")) add_css$2();
init(this, options, instance$3, create_fragment$3, safe_not_equal, {});
}
}
/* src/view/explorer/ProjectPicker.svelte generated by Svelte v3.38.2 */
function add_css$1() {
var style = element("style");
style.id = "svelte-23avsr-style";
style.textContent = "#project-picker-container.svelte-23avsr.svelte-23avsr{margin-bottom:8px}select.svelte-23avsr.svelte-23avsr{background-color:transparent;border:none;padding:0;margin:0;width:100%;font-family:inherit;font-size:inherit;cursor:inherit;line-height:inherit;outline:none}.select.svelte-23avsr.svelte-23avsr{cursor:pointer}.select.svelte-23avsr>select.svelte-23avsr{color:var(--text-accent)}.select.svelte-23avsr>select.svelte-23avsr:hover{text-decoration:underline;color:var(--text-accent-hover)}#project-picker.svelte-23avsr.svelte-23avsr{display:flex;flex-direction:row;align-items:center;flex-wrap:wrap}.right-arrow.svelte-23avsr.svelte-23avsr{display:grid}.right-arrow.svelte-23avsr.svelte-23avsr::after{content:\"\";width:0.8em;height:0.5em;background-color:var(--text-muted);clip-path:polygon(50% 0%, 50% 100%, 100% 50%)}.current-draft-path.svelte-23avsr.svelte-23avsr{color:var(--text-muted);font-size:10px;padding:0 8px;line-height:12px}.project-error.svelte-23avsr.svelte-23avsr{color:var(--text-error);font-size:12px;line-height:14px}";
append(document.head, style);
}
function get_each_context(ctx, list, i) {
const child_ctx = ctx.slice();
child_ctx[8] = list[i];
return child_ctx;
}
function get_each_context_1(ctx, list, i) {
const child_ctx = ctx.slice();
child_ctx[11] = list[i];
return child_ctx;
}
// (54:2) {:else}
function create_else_block(ctx) {
let p;
return {
c() {
p = element("p");
p.textContent = "To use Longform, start by marking a folder as a Longform project by\n right-clicking it and selecting \"Mark as Longform project.\"";
},
m(target, anchor) {
insert(target, p, anchor);
},
p: noop,
d(detaching) {
if (detaching) detach(p);
}
};
}
// (27:2) {#if projectOptions.length > 0}
function create_if_block_1$1(ctx) {
let div1;
let div0;
let select;
let t0;
let t1;
let if_block1_anchor;
let mounted;
let dispose;
let each_value_1 = /*projectOptions*/ ctx[2];
let each_blocks = [];
for (let i = 0; i < each_value_1.length; i += 1) {
each_blocks[i] = create_each_block_1(get_each_context_1(ctx, each_value_1, i));
}
let if_block0 = /*$currentDraftPath*/ ctx[1] && /*$currentProject*/ ctx[0] && /*$currentProject*/ ctx[0].drafts && create_if_block_3(ctx);
let if_block1 = /*$currentDraftPath*/ ctx[1] && create_if_block_2(ctx);
return {
c() {
div1 = element("div");
div0 = element("div");
select = element("select");
for (let i = 0; i < each_blocks.length; i += 1) {
each_blocks[i].c();
}
t0 = space();
if (if_block0) if_block0.c();
t1 = space();
if (if_block1) if_block1.c();
if_block1_anchor = empty();
attr(select, "name", "projects");
attr(select, "class", "svelte-23avsr");
if (/*$currentProjectPath*/ ctx[3] === void 0) add_render_callback(() => /*select_change_handler*/ ctx[6].call(select));
attr(div0, "class", "select svelte-23avsr");
attr(div0, "id", "select-projects");
attr(div1, "id", "project-picker");
attr(div1, "class", "svelte-23avsr");
},
m(target, anchor) {
insert(target, div1, anchor);
append(div1, div0);
append(div0, select);
for (let i = 0; i < each_blocks.length; i += 1) {
each_blocks[i].m(select, null);
}
select_option(select, /*$currentProjectPath*/ ctx[3]);
append(div1, t0);
if (if_block0) if_block0.m(div1, null);
insert(target, t1, anchor);
if (if_block1) if_block1.m(target, anchor);
insert(target, if_block1_anchor, anchor);
if (!mounted) {
dispose = listen(select, "change", /*select_change_handler*/ ctx[6]);
mounted = true;
}
},
p(ctx, dirty) {
if (dirty & /*projectOptions*/ 4) {
each_value_1 = /*projectOptions*/ ctx[2];
let i;
for (i = 0; i < each_value_1.length; i += 1) {
const child_ctx = get_each_context_1(ctx, each_value_1, i);
if (each_blocks[i]) {
each_blocks[i].p(child_ctx, dirty);
} else {
each_blocks[i] = create_each_block_1(child_ctx);
each_blocks[i].c();
each_blocks[i].m(select, null);
}
}
for (; i < each_blocks.length; i += 1) {
each_blocks[i].d(1);
}
each_blocks.length = each_value_1.length;
}
if (dirty & /*$currentProjectPath, projectOptions*/ 12) {
select_option(select, /*$currentProjectPath*/ ctx[3]);
}
if (/*$currentDraftPath*/ ctx[1] && /*$currentProject*/ ctx[0] && /*$currentProject*/ ctx[0].drafts) {
if (if_block0) {
if_block0.p(ctx, dirty);
} else {
if_block0 = create_if_block_3(ctx);
if_block0.c();
if_block0.m(div1, null);
}
} else if (if_block0) {
if_block0.d(1);
if_block0 = null;
}
if (/*$currentDraftPath*/ ctx[1]) {
if (if_block1) {
if_block1.p(ctx, dirty);
} else {
if_block1 = create_if_block_2(ctx);
if_block1.c();
if_block1.m(if_block1_anchor.parentNode, if_block1_anchor);
}
} else if (if_block1) {
if_block1.d(1);
if_block1 = null;
}
},
d(detaching) {
if (detaching) detach(div1);
destroy_each(each_blocks, detaching);
if (if_block0) if_block0.d();
if (detaching) detach(t1);
if (if_block1) if_block1.d(detaching);
if (detaching) detach(if_block1_anchor);
mounted = false;
dispose();
}
};
}
// (31:10) {#each projectOptions as projectOption}
function create_each_block_1(ctx) {
let option;
let t_value = /*projectOption*/ ctx[11].name + "";
let t;
let option_value_value;
return {
c() {
option = element("option");
t = text(t_value);
attr(option, "class", "projectOption");
option.__value = option_value_value = /*projectOption*/ ctx[11].path;
option.value = option.__value;
},
m(target, anchor) {
insert(target, option, anchor);
append(option, t);
},
p(ctx, dirty) {
if (dirty & /*projectOptions*/ 4 && t_value !== (t_value = /*projectOption*/ ctx[11].name + "")) set_data(t, t_value);
if (dirty & /*projectOptions*/ 4 && option_value_value !== (option_value_value = /*projectOption*/ ctx[11].path)) {
option.__value = option_value_value;
option.value = option.__value;
}
},
d(detaching) {
if (detaching) detach(option);
}
};
}
// (38:6) {#if $currentDraftPath && $currentProject && $currentProject.drafts}
function create_if_block_3(ctx) {
let span;
let t;
let div;
let select;
let mounted;
let dispose;
let each_value = /*$currentProject*/ ctx[0].drafts;
let each_blocks = [];
for (let i = 0; i < each_value.length; i += 1) {
each_blocks[i] = create_each_block(get_each_context(ctx, each_value, i));
}
return {
c() {
span = element("span");
t = space();
div = element("div");
select = element("select");
for (let i = 0; i < each_blocks.length; i += 1) {
each_blocks[i].c();
}
attr(span, "class", "right-arrow svelte-23avsr");
attr(select, "name", "drafts");
attr(select, "class", "svelte-23avsr");
if (/*$currentDraftPath*/ ctx[1] === void 0) add_render_callback(() => /*select_change_handler_1*/ ctx[7].call(select));
attr(div, "class", "select svelte-23avsr");
attr(div, "id", "select-drafts");
},
m(target, anchor) {
insert(target, span, anchor);
insert(target, t, anchor);
insert(target, div, anchor);
append(div, select);
for (let i = 0; i < each_blocks.length; i += 1) {
each_blocks[i].m(select, null);
}
select_option(select, /*$currentDraftPath*/ ctx[1]);
if (!mounted) {
dispose = listen(select, "change", /*select_change_handler_1*/ ctx[7]);
mounted = true;
}
},
p(ctx, dirty) {
if (dirty & /*$currentProject*/ 1) {
each_value = /*$currentProject*/ ctx[0].drafts;
let i;
for (i = 0; i < each_value.length; i += 1) {
const child_ctx = get_each_context(ctx, each_value, i);
if (each_blocks[i]) {
each_blocks[i].p(child_ctx, dirty);
} else {
each_blocks[i] = create_each_block(child_ctx);
each_blocks[i].c();
each_blocks[i].m(select, null);
}
}
for (; i < each_blocks.length; i += 1) {
each_blocks[i].d(1);
}
each_blocks.length = each_value.length;
}
if (dirty & /*$currentDraftPath, $currentProject*/ 3) {
select_option(select, /*$currentDraftPath*/ ctx[1]);
}
},
d(detaching) {
if (detaching) detach(span);
if (detaching) detach(t);
if (detaching) detach(div);
destroy_each(each_blocks, detaching);
mounted = false;
dispose();
}
};
}
// (42:12) {#each $currentProject.drafts as draftOption}
function create_each_block(ctx) {
let option;
let t_value = /*draftOption*/ ctx[8].name + "";
let t;
let option_value_value;
return {
c() {
option = element("option");
t = text(t_value);
option.__value = option_value_value = /*draftOption*/ ctx[8].folder;
option.value = option.__value;
},
m(target, anchor) {
insert(target, option, anchor);
append(option, t);
},
p(ctx, dirty) {
if (dirty & /*$currentProject*/ 1 && t_value !== (t_value = /*draftOption*/ ctx[8].name + "")) set_data(t, t_value);
if (dirty & /*$currentProject*/ 1 && option_value_value !== (option_value_value = /*draftOption*/ ctx[8].folder)) {
option.__value = option_value_value;
option.value = option.__value;
}
},
d(detaching) {
if (detaching) detach(option);
}
};
}
// (49:4) {#if $currentDraftPath}
function create_if_block_2(ctx) {
let div;
let t_value = obsidian.normalizePath(`${/*$currentProjectPath*/ ctx[3]}/${/*$currentDraftPath*/ ctx[1]}`) + "";
let t;
return {
c() {
div = element("div");
t = text(t_value);
attr(div, "class", "current-draft-path svelte-23avsr");
},
m(target, anchor) {
insert(target, div, anchor);
append(div, t);
},
p(ctx, dirty) {
if (dirty & /*$currentProjectPath, $currentDraftPath*/ 10 && t_value !== (t_value = obsidian.normalizePath(`${/*$currentProjectPath*/ ctx[3]}/${/*$currentDraftPath*/ ctx[1]}`) + "")) set_data(t, t_value);
},
d(detaching) {
if (detaching) detach(div);
}
};
}
// (60:2) {#if $currentProject && $currentProject.error}
function create_if_block$1(ctx) {
let p;
let t_value = /*$currentProject*/ ctx[0].error + "";
let t;
return {
c() {
p = element("p");
t = text(t_value);
attr(p, "class", "project-error svelte-23avsr");
},
m(target, anchor) {
insert(target, p, anchor);
append(p, t);
},
p(ctx, dirty) {
if (dirty & /*$currentProject*/ 1 && t_value !== (t_value = /*$currentProject*/ ctx[0].error + "")) set_data(t, t_value);
},
d(detaching) {
if (detaching) detach(p);
}
};
}
function create_fragment$2(ctx) {
let div;
let t;
function select_block_type(ctx, dirty) {
if (/*projectOptions*/ ctx[2].length > 0) return create_if_block_1$1;
return create_else_block;
}
let current_block_type = select_block_type(ctx);
let if_block0 = current_block_type(ctx);
let if_block1 = /*$currentProject*/ ctx[0] && /*$currentProject*/ ctx[0].error && create_if_block$1(ctx);
return {
c() {
div = element("div");
if_block0.c();
t = space();
if (if_block1) if_block1.c();
attr(div, "id", "project-picker-container");
attr(div, "class", "svelte-23avsr");
},
m(target, anchor) {
insert(target, div, anchor);
if_block0.m(div, null);
append(div, t);
if (if_block1) if_block1.m(div, null);
},
p(ctx, [dirty]) {
if (current_block_type === (current_block_type = select_block_type(ctx)) && if_block0) {
if_block0.p(ctx, dirty);
} else {
if_block0.d(1);
if_block0 = current_block_type(ctx);
if (if_block0) {
if_block0.c();
if_block0.m(div, t);
}
}
if (/*$currentProject*/ ctx[0] && /*$currentProject*/ ctx[0].error) {
if (if_block1) {
if_block1.p(ctx, dirty);
} else {
if_block1 = create_if_block$1(ctx);
if_block1.c();
if_block1.m(div, null);
}
} else if (if_block1) {
if_block1.d(1);
if_block1 = null;
}
},
i: noop,
o: noop,
d(detaching) {
if (detaching) detach(div);
if_block0.d();
if (if_block1) if_block1.d();
}
};
}
function instance$2($$self, $$props, $$invalidate) {
let $projects;
let $initialized;
let $currentProject;
let $currentDraftPath;
let $currentProjectPath;
component_subscribe($$self, projects, $$value => $$invalidate(4, $projects = $$value));
component_subscribe($$self, initialized, $$value => $$invalidate(5, $initialized = $$value));
component_subscribe($$self, currentProject, $$value => $$invalidate(0, $currentProject = $$value));
component_subscribe($$self, currentDraftPath, $$value => $$invalidate(1, $currentDraftPath = $$value));
component_subscribe($$self, currentProjectPath, $$value => $$invalidate(3, $currentProjectPath = $$value));
let projectOptions = [];
function select_change_handler() {
$currentProjectPath = select_value(this);
currentProjectPath.set($currentProjectPath);
($$invalidate(2, projectOptions), $$invalidate(4, $projects));
}
function select_change_handler_1() {
$currentDraftPath = select_value(this);
currentDraftPath.set($currentDraftPath);
}
$$self.$$.update = () => {
if ($$self.$$.dirty & /*$projects*/ 16) {
{
$$invalidate(2, projectOptions = Object.keys($projects).map(path => ({ name: path.split("/").slice(-1)[0], path })));
}
}
if ($$self.$$.dirty & /*$initialized, $currentProject, $currentDraftPath*/ 35) {
// Recover if you've changed projects and there's no matching draft folder
// by setting the current draft to the last one in the project.
if ($initialized && $currentProject && !$currentProject.drafts.find(d => d.folder === $currentDraftPath)) {
const drafts = $currentProject.drafts;
if (drafts.length > 0) {
set_store_value(currentDraftPath, $currentDraftPath = drafts[drafts.length - 1].folder, $currentDraftPath);
} else {
set_store_value(currentDraftPath, $currentDraftPath = null, $currentDraftPath);
}
}
}
};
return [
$currentProject,
$currentDraftPath,
projectOptions,
$currentProjectPath,
$projects,
$initialized,
select_change_handler,
select_change_handler_1
];
}
class ProjectPicker extends SvelteComponent {
constructor(options) {
super();
if (!document.getElementById("svelte-23avsr-style")) add_css$1();
init(this, options, instance$2, create_fragment$2, safe_not_equal, {});
}
}
/* src/view/explorer/SceneList.svelte generated by Svelte v3.38.2 */
const { document: document_1 } = globals;
function add_css() {
var style = element("style");
style.id = "svelte-1wlkmbt-style";
style.textContent = "#scene-list.svelte-1wlkmbt.svelte-1wlkmbt{margin:4px 0px}#scene-list.svelte-1wlkmbt .sortable-scene-list{list-style-type:none;padding:0px;margin:0px}.scene-container.svelte-1wlkmbt.svelte-1wlkmbt{display:flex;border:1px solid transparent;border-radius:3px;cursor:pointer;color:var(--text-muted);font-size:14px;line-height:20px;white-space:nowrap;padding:2px 0px}.selected.svelte-1wlkmbt.svelte-1wlkmbt,.svelte-1wlkmbt:not(.dragging) .scene-container.svelte-1wlkmbt:hover{background-color:var(--background-secondary-alt);color:var(--text-normal)}.scene-container.svelte-1wlkmbt.svelte-1wlkmbt:active{background-color:inherit;color:var(--text-muted)}.scene-ghost{background-color:var(--interactive-accent-hover);color:var(--text-on-accent)}";
append(document_1.head, style);
}
// (57:2) <SortableList bind:items let:item on:orderChanged={itemOrderChanged} {sortableOptions} class="sortable-scene-list" >
function create_default_slot$1(ctx) {
let div;
let t_value = /*item*/ ctx[16].name + "";
let t;
let div_data_scene_path_value;
let mounted;
let dispose;
function click_handler(...args) {
return /*click_handler*/ ctx[8](/*item*/ ctx[16], ...args);
}
return {
c() {
div = element("div");
t = text(t_value);
attr(div, "class", "scene-container svelte-1wlkmbt");
attr(div, "data-scene-path", div_data_scene_path_value = /*item*/ ctx[16].path);
toggle_class(div, "selected", /*$activeFile*/ ctx[2] && /*$activeFile*/ ctx[2].path === /*item*/ ctx[16].path);
},
m(target, anchor) {
insert(target, div, anchor);
append(div, t);
if (!mounted) {
dispose = [
listen(div, "click", click_handler),
listen(div, "contextmenu", prevent_default(/*onContext*/ ctx[6]))
];
mounted = true;
}
},
p(new_ctx, dirty) {
ctx = new_ctx;
if (dirty & /*item*/ 65536 && t_value !== (t_value = /*item*/ ctx[16].name + "")) set_data(t, t_value);
if (dirty & /*item*/ 65536 && div_data_scene_path_value !== (div_data_scene_path_value = /*item*/ ctx[16].path)) {
attr(div, "data-scene-path", div_data_scene_path_value);
}
if (dirty & /*$activeFile, item*/ 65540) {
toggle_class(div, "selected", /*$activeFile*/ ctx[2] && /*$activeFile*/ ctx[2].path === /*item*/ ctx[16].path);
}
},
d(detaching) {
if (detaching) detach(div);
mounted = false;
run_all(dispose);
}
};
}
function create_fragment$1(ctx) {
let div;
let sortablelist;
let updating_items;
let current;
function sortablelist_items_binding(value) {
/*sortablelist_items_binding*/ ctx[9](value);
}
let sortablelist_props = {
sortableOptions: /*sortableOptions*/ ctx[3],
class: "sortable-scene-list",
$$slots: {
default: [
create_default_slot$1,
({ item }) => ({ 16: item }),
({ item }) => item ? 65536 : 0
]
},
$$scope: { ctx }
};
if (/*items*/ ctx[0] !== void 0) {
sortablelist_props.items = /*items*/ ctx[0];
}
sortablelist = new SortableList({ props: sortablelist_props });
binding_callbacks.push(() => bind(sortablelist, "items", sortablelist_items_binding));
sortablelist.$on("orderChanged", /*itemOrderChanged*/ ctx[4]);
return {
c() {
div = element("div");
create_component(sortablelist.$$.fragment);
attr(div, "id", "scene-list");
attr(div, "class", "svelte-1wlkmbt");
toggle_class(div, "dragging", /*isSorting*/ ctx[1]);
},
m(target, anchor) {
insert(target, div, anchor);
mount_component(sortablelist, div, null);
current = true;
},
p(ctx, [dirty]) {
const sortablelist_changes = {};
if (dirty & /*$$scope, item, $activeFile*/ 196612) {
sortablelist_changes.$$scope = { dirty, ctx };
}
if (!updating_items && dirty & /*items*/ 1) {
updating_items = true;
sortablelist_changes.items = /*items*/ ctx[0];
add_flush_callback(() => updating_items = false);
}
sortablelist.$set(sortablelist_changes);
if (dirty & /*isSorting*/ 2) {
toggle_class(div, "dragging", /*isSorting*/ ctx[1]);
}
},
i(local) {
if (current) return;
transition_in(sortablelist.$$.fragment, local);
current = true;
},
o(local) {
transition_out(sortablelist.$$.fragment, local);
current = false;
},
d(detaching) {
if (detaching) detach(div);
destroy_component(sortablelist);
}
};
}
function instance$1($$self, $$props, $$invalidate) {
let $currentDraft;
let $projectMetadata;
let $currentProjectPath;
let $currentDraftPath;
let $activeFile;
component_subscribe($$self, currentDraft, $$value => $$invalidate(7, $currentDraft = $$value));
component_subscribe($$self, projectMetadata, $$value => $$invalidate(10, $projectMetadata = $$value));
component_subscribe($$self, currentProjectPath, $$value => $$invalidate(11, $currentProjectPath = $$value));
component_subscribe($$self, currentDraftPath, $$value => $$invalidate(12, $currentDraftPath = $$value));
component_subscribe($$self, activeFile, $$value => $$invalidate(2, $activeFile = $$value));
// Function to make paths from scene names
const makeScenePath = getContext("makeScenePath");
let items;
// Track sort state for styling, set sorting options
let isSorting = false;
const sortableOptions = {
animation: 150,
ghostClass: "scene-ghost",
onStart: () => {
$$invalidate(1, isSorting = true);
},
onEnd: () => {
$$invalidate(1, isSorting = false);
}
};
// Called when sorting ends an the item order has been updated.
// Reorder scenes according and set into the store.
function itemOrderChanged(event) {
const currentDraftIndex = $projectMetadata[$currentProjectPath].drafts.findIndex(d => d.folder === $currentDraftPath);
set_store_value(projectMetadata, $projectMetadata[$currentProjectPath].drafts[currentDraftIndex].scenes = event.detail.map(d => d.name), $projectMetadata);
}
// Grab the click context function and call it when a valid scene is clicked.
const onSceneClick = getContext("onSceneClick");
function onItemClick(path, event) {
if (path) {
onSceneClick(path, event.metaKey);
}
}
// Grab the right-click context function and call it if the right-click
// happened on a scene element with a valid path.
const onContextClick = getContext("onContextClick");
function onContext(event) {
const { x, y } = event;
const element = document.elementFromPoint(x, y);
const scenePath = element && element instanceof HTMLElement && element.dataset.scenePath;
if (scenePath) {
onContextClick(scenePath, x, y);
}
}
const click_handler = (item, e) => typeof item.path === "string"
? onItemClick(item.path, e)
: {};
function sortablelist_items_binding(value) {
items = value;
($$invalidate(0, items), $$invalidate(7, $currentDraft));
}
$$self.$$.update = () => {
if ($$self.$$.dirty & /*$currentDraft*/ 128) {
{
$$invalidate(0, items = $currentDraft
? $currentDraft.scenes.map(s => ({ id: s, name: s, path: makeScenePath(s) }))
: []);
}
}
};
return [
items,
isSorting,
$activeFile,
sortableOptions,
itemOrderChanged,
onItemClick,
onContext,
$currentDraft,
click_handler,
sortablelist_items_binding
];
}
class SceneList extends SvelteComponent {
constructor(options) {
super();
if (!document_1.getElementById("svelte-1wlkmbt-style")) add_css();
init(this, options, instance$1, create_fragment$1, safe_not_equal, {});
}
}
/* src/view/explorer/ExplorerView.svelte generated by Svelte v3.38.2 */
function create_default_slot_7(ctx) {
let t;
return {
c() {
t = text("Scenes");
},
m(target, anchor) {
insert(target, t, anchor);
},
d(detaching) {
if (detaching) detach(t);
}
};
}
// (35:4) <Tab>
function create_default_slot_6(ctx) {
let t;
return {
c() {
t = text("Drafts");
},
m(target, anchor) {
insert(target, t, anchor);
},
d(detaching) {
if (detaching) detach(t);
}
};
}
// (36:4) <Tab>
function create_default_slot_5(ctx) {
let t;
return {
c() {
t = text("Compile");
},
m(target, anchor) {
insert(target, t, anchor);
},
d(detaching) {
if (detaching) detach(t);
}
};
}
// (33:2) <TabList>
function create_default_slot_4(ctx) {
let tab0;
let t0;
let tab1;
let t1;
let tab2;
let current;
tab0 = new Tab({
props: {
$$slots: { default: [create_default_slot_7] },
$$scope: { ctx }
}
});
tab1 = new Tab({
props: {
$$slots: { default: [create_default_slot_6] },
$$scope: { ctx }
}
});
tab2 = new Tab({
props: {
$$slots: { default: [create_default_slot_5] },
$$scope: { ctx }
}
});
return {
c() {
create_component(tab0.$$.fragment);
t0 = space();
create_component(tab1.$$.fragment);
t1 = space();
create_component(tab2.$$.fragment);
},
m(target, anchor) {
mount_component(tab0, target, anchor);
insert(target, t0, anchor);
mount_component(tab1, target, anchor);
insert(target, t1, anchor);
mount_component(tab2, target, anchor);
current = true;
},
p(ctx, dirty) {
const tab0_changes = {};
if (dirty & /*$$scope*/ 128) {
tab0_changes.$$scope = { dirty, ctx };
}
tab0.$set(tab0_changes);
const tab1_changes = {};
if (dirty & /*$$scope*/ 128) {
tab1_changes.$$scope = { dirty, ctx };
}
tab1.$set(tab1_changes);
const tab2_changes = {};
if (dirty & /*$$scope*/ 128) {
tab2_changes.$$scope = { dirty, ctx };
}
tab2.$set(tab2_changes);
},
i(local) {
if (current) return;
transition_in(tab0.$$.fragment, local);
transition_in(tab1.$$.fragment, local);
transition_in(tab2.$$.fragment, local);
current = true;
},
o(local) {
transition_out(tab0.$$.fragment, local);
transition_out(tab1.$$.fragment, local);
transition_out(tab2.$$.fragment, local);
current = false;
},
d(detaching) {
destroy_component(tab0, detaching);
if (detaching) detach(t0);
destroy_component(tab1, detaching);
if (detaching) detach(t1);
destroy_component(tab2, detaching);
}
};
}
// (39:4) {#if $currentDraft}
function create_if_block_1(ctx) {
let scenelist;
let t;
let newscenefield;
let current;
scenelist = new SceneList({});
newscenefield = new NewSceneField({});
return {
c() {
create_component(scenelist.$$.fragment);
t = space();
create_component(newscenefield.$$.fragment);
},
m(target, anchor) {
mount_component(scenelist, target, anchor);
insert(target, t, anchor);
mount_component(newscenefield, target, anchor);
current = true;
},
i(local) {
if (current) return;
transition_in(scenelist.$$.fragment, local);
transition_in(newscenefield.$$.fragment, local);
current = true;
},
o(local) {
transition_out(scenelist.$$.fragment, local);
transition_out(newscenefield.$$.fragment, local);
current = false;
},
d(detaching) {
destroy_component(scenelist, detaching);
if (detaching) detach(t);
destroy_component(newscenefield, detaching);
}
};
}
// (38:2) <TabPanel>
function create_default_slot_3(ctx) {
let if_block_anchor;
let current;
let if_block = /*$currentDraft*/ ctx[0] && create_if_block_1();
return {
c() {
if (if_block) if_block.c();
if_block_anchor = empty();
},
m(target, anchor) {
if (if_block) if_block.m(target, anchor);
insert(target, if_block_anchor, anchor);
current = true;
},
p(ctx, dirty) {
if (/*$currentDraft*/ ctx[0]) {
if (if_block) {
if (dirty & /*$currentDraft*/ 1) {
transition_in(if_block, 1);
}
} else {
if_block = create_if_block_1();
if_block.c();
transition_in(if_block, 1);
if_block.m(if_block_anchor.parentNode, if_block_anchor);
}
} else if (if_block) {
group_outros();
transition_out(if_block, 1, 1, () => {
if_block = null;
});
check_outros();
}
},
i(local) {
if (current) return;
transition_in(if_block);
current = true;
},
o(local) {
transition_out(if_block);
current = false;
},
d(detaching) {
if (if_block) if_block.d(detaching);
if (detaching) detach(if_block_anchor);
}
};
}
// (45:4) {#if $currentProject}
function create_if_block(ctx) {
let draftlist;
let t;
let newdraftfield;
let current;
draftlist = new DraftList({});
newdraftfield = new NewDraftField({});
return {
c() {
create_component(draftlist.$$.fragment);
t = space();
create_component(newdraftfield.$$.fragment);
},
m(target, anchor) {
mount_component(draftlist, target, anchor);
insert(target, t, anchor);
mount_component(newdraftfield, target, anchor);
current = true;
},
i(local) {
if (current) return;
transition_in(draftlist.$$.fragment, local);
transition_in(newdraftfield.$$.fragment, local);
current = true;
},
o(local) {
transition_out(draftlist.$$.fragment, local);
transition_out(newdraftfield.$$.fragment, local);
current = false;
},
d(detaching) {
destroy_component(draftlist, detaching);
if (detaching) detach(t);
destroy_component(newdraftfield, detaching);
}
};
}
// (44:2) <TabPanel>
function create_default_slot_2(ctx) {
let if_block_anchor;
let current;
let if_block = /*$currentProject*/ ctx[1] && create_if_block();
return {
c() {
if (if_block) if_block.c();
if_block_anchor = empty();
},
m(target, anchor) {
if (if_block) if_block.m(target, anchor);
insert(target, if_block_anchor, anchor);
current = true;
},
p(ctx, dirty) {
if (/*$currentProject*/ ctx[1]) {
if (if_block) {
if (dirty & /*$currentProject*/ 2) {
transition_in(if_block, 1);
}
} else {
if_block = create_if_block();
if_block.c();
transition_in(if_block, 1);
if_block.m(if_block_anchor.parentNode, if_block_anchor);
}
} else if (if_block) {
group_outros();
transition_out(if_block, 1, 1, () => {
if_block = null;
});
check_outros();
}
},
i(local) {
if (current) return;
transition_in(if_block);
current = true;
},
o(local) {
transition_out(if_block);
current = false;
},
d(detaching) {
if (if_block) if_block.d(detaching);
if (detaching) detach(if_block_anchor);
}
};
}
// (50:2) <TabPanel>
function create_default_slot_1(ctx) {
let compileview;
let current;
compileview = new CompileView({});
return {
c() {
create_component(compileview.$$.fragment);
},
m(target, anchor) {
mount_component(compileview, target, anchor);
current = true;
},
i(local) {
if (current) return;
transition_in(compileview.$$.fragment, local);
current = true;
},
o(local) {
transition_out(compileview.$$.fragment, local);
current = false;
},
d(detaching) {
destroy_component(compileview, detaching);
}
};
}
// (32:0) <Tabs>
function create_default_slot(ctx) {
let tablist;
let t0;
let tabpanel0;
let t1;
let tabpanel1;
let t2;
let tabpanel2;
let current;
tablist = new TabList({
props: {
$$slots: { default: [create_default_slot_4] },
$$scope: { ctx }
}
});
tabpanel0 = new TabPanel({
props: {
$$slots: { default: [create_default_slot_3] },
$$scope: { ctx }
}
});
tabpanel1 = new TabPanel({
props: {
$$slots: { default: [create_default_slot_2] },
$$scope: { ctx }
}
});
tabpanel2 = new TabPanel({
props: {
$$slots: { default: [create_default_slot_1] },
$$scope: { ctx }
}
});
return {
c() {
create_component(tablist.$$.fragment);
t0 = space();
create_component(tabpanel0.$$.fragment);
t1 = space();
create_component(tabpanel1.$$.fragment);
t2 = space();
create_component(tabpanel2.$$.fragment);
},
m(target, anchor) {
mount_component(tablist, target, anchor);
insert(target, t0, anchor);
mount_component(tabpanel0, target, anchor);
insert(target, t1, anchor);
mount_component(tabpanel1, target, anchor);
insert(target, t2, anchor);
mount_component(tabpanel2, target, anchor);
current = true;
},
p(ctx, dirty) {
const tablist_changes = {};
if (dirty & /*$$scope*/ 128) {
tablist_changes.$$scope = { dirty, ctx };
}
tablist.$set(tablist_changes);
const tabpanel0_changes = {};
if (dirty & /*$$scope, $currentDraft*/ 129) {
tabpanel0_changes.$$scope = { dirty, ctx };
}
tabpanel0.$set(tabpanel0_changes);
const tabpanel1_changes = {};
if (dirty & /*$$scope, $currentProject*/ 130) {
tabpanel1_changes.$$scope = { dirty, ctx };
}
tabpanel1.$set(tabpanel1_changes);
const tabpanel2_changes = {};
if (dirty & /*$$scope*/ 128) {
tabpanel2_changes.$$scope = { dirty, ctx };
}
tabpanel2.$set(tabpanel2_changes);
},
i(local) {
if (current) return;
transition_in(tablist.$$.fragment, local);
transition_in(tabpanel0.$$.fragment, local);
transition_in(tabpanel1.$$.fragment, local);
transition_in(tabpanel2.$$.fragment, local);
current = true;
},
o(local) {
transition_out(tablist.$$.fragment, local);
transition_out(tabpanel0.$$.fragment, local);
transition_out(tabpanel1.$$.fragment, local);
transition_out(tabpanel2.$$.fragment, local);
current = false;
},
d(detaching) {
destroy_component(tablist, detaching);
if (detaching) detach(t0);
destroy_component(tabpanel0, detaching);
if (detaching) detach(t1);
destroy_component(tabpanel1, detaching);
if (detaching) detach(t2);
destroy_component(tabpanel2, detaching);
}
};
}
function create_fragment(ctx) {
let projectpicker;
let t;
let tabs;
let current;
projectpicker = new ProjectPicker({});
tabs = new Tabs({
props: {
$$slots: { default: [create_default_slot] },
$$scope: { ctx }
}
});
return {
c() {
create_component(projectpicker.$$.fragment);
t = space();
create_component(tabs.$$.fragment);
},
m(target, anchor) {
mount_component(projectpicker, target, anchor);
insert(target, t, anchor);
mount_component(tabs, target, anchor);
current = true;
},
p(ctx, [dirty]) {
const tabs_changes = {};
if (dirty & /*$$scope, $currentProject, $currentDraft*/ 131) {
tabs_changes.$$scope = { dirty, ctx };
}
tabs.$set(tabs_changes);
},
i(local) {
if (current) return;
transition_in(projectpicker.$$.fragment, local);
transition_in(tabs.$$.fragment, local);
current = true;
},
o(local) {
transition_out(projectpicker.$$.fragment, local);
transition_out(tabs.$$.fragment, local);
current = false;
},
d(detaching) {
destroy_component(projectpicker, detaching);
if (detaching) detach(t);
destroy_component(tabs, detaching);
}
};
}
function instance($$self, $$props, $$invalidate) {
let $currentProjectPath;
let $pluginSettings;
let $currentDraftPath;
let $currentDraft;
let $currentProject;
component_subscribe($$self, currentProjectPath, $$value => $$invalidate(2, $currentProjectPath = $$value));
component_subscribe($$self, pluginSettings, $$value => $$invalidate(3, $pluginSettings = $$value));
component_subscribe($$self, currentDraftPath, $$value => $$invalidate(4, $currentDraftPath = $$value));
component_subscribe($$self, currentDraft, $$value => $$invalidate(0, $currentDraft = $$value));
component_subscribe($$self, currentProject, $$value => $$invalidate(1, $currentProject = $$value));
function makeDraftPath(name) {
if ($currentProjectPath) {
const draftsFolder = $pluginSettings.projects[$currentProjectPath].draftsPath;
return obsidian.normalizePath(`${$currentProjectPath}/${draftsFolder}/${name}/`);
}
return null;
}
setContext("makeDraftPath", makeDraftPath);
// Create a fully-qualified path to a scene from its name.
function makeScenePath(name, draft) {
const draftPath = makeDraftPath(draft || $currentDraftPath);
if (draftPath) {
return obsidian.normalizePath(`${draftPath}/${name}.md`);
}
return null;
}
setContext("makeScenePath", makeScenePath);
return [$currentDraft, $currentProject];
}
class ExplorerView extends SvelteComponent {
constructor(options) {
super();
init(this, options, instance, create_fragment, safe_not_equal, {});
}
}
const VIEW_TYPE_LONGFORM_EXPLORER = "VIEW_TYPE_LONGFORM_EXPLORER";
class ExplorerPane extends obsidian.ItemView {
constructor(leaf) {
super(leaf);
}
getViewType() {
return VIEW_TYPE_LONGFORM_EXPLORER;
}
getDisplayText() {
return "Longform";
}
getIcon() {
return ICON_NAME;
}
onOpen() {
return __awaiter(this, void 0, void 0, function* () {
const context = new Map();
// Context function for opening scene notes on click
context.set("onSceneClick", (path, newLeaf) => {
this.app.workspace.openLinkText(path, "/", newLeaf);
});
// Context function for creating new scene notes given a path
context.set("onNewScene", (path) => __awaiter(this, void 0, void 0, function* () {
yield this.app.vault.create(path, "");
this.app.workspace.openLinkText(path, "/", false);
}));
// Context function for creating new draft folders given a path
context.set("onNewDraft", (path, copying) => __awaiter(this, void 0, void 0, function* () {
if (copying) {
yield this.app.vault.createFolder(path);
// do copy
for (const toCopy of copying) {
yield this.app.vault.adapter.copy(toCopy.from, toCopy.to);
}
}
else {
yield this.app.vault.createFolder(path);
}
}));
// Context function for showing a right-click menu
context.set("onContextClick", (path, x, y) => {
const file = this.app.vault.getAbstractFileByPath(path);
if (!file) {
return;
}
const menu = new obsidian.Menu(this.app);
menu.addItem((item) => {
item.setTitle("Delete");
item.setIcon("trash");
item.onClick(() => __awaiter(this, void 0, void 0, function* () {
if (file) {
yield this.app.vault.trash(file, true);
}
}));
});
menu.addItem((item) => {
item.setTitle("Open in new pane");
item.setIcon("vertical-split");
item.onClick(() => this.app.workspace.openLinkText(path, "/", true));
});
// Triggering this event lets other apps insert menu items
// including Obsidian, giving us lots of stuff for free.
this.app.workspace.trigger("file-menu", menu, file, "longform");
menu.showAtPosition({ x, y });
});
context.set("showRenameDraftMenu", (x, y, action) => {
const menu = new obsidian.Menu(this.app);
menu.addItem((item) => {
item.setTitle("Rename");
item.setIcon("pencil");
item.onClick(action);
});
menu.showAtPosition({ x, y });
});
context.set("renameFolder", (oldPath, newPath) => {
this.app.vault.adapter.rename(oldPath, newPath);
});
context.set("getVault", () => this.app.vault);
this.explorerView = new ExplorerView({
target: this.contentEl,
context,
});
});
}
onClose() {
return __awaiter(this, void 0, void 0, function* () {
if (this.explorerView) {
this.explorerView.$destroy();
}
});
}
}
class AddProjectModal extends obsidian.Modal {
constructor(app, plugin, path) {
super(app);
this.plugin = plugin;
this.path = path;
}
onOpen() {
const { contentEl } = this;
const title = document.createElement("h1");
title.setText("Add to Longform");
contentEl.appendChild(title);
const indexFileField = this.addField(contentEl, "Index File Name", "Index", "Index", "A projects index file acts as storage for all the metadata necessary to make a Longform project work. You can edit it (its Markdown), but Longform will mostly be reading and writing it directly.");
const draftsFolderField = this.addField(contentEl, "Drafts Folder Name", "Drafts/", "Drafts/", "Every folder inside your drafts folder is a single draft of your project. You can name drafts whatever youd like: Drafts/1/, Drafts/First Draft/, etc. Each draft folder will hold the individual files (scenes) that make up your project. Scenes are ordered manually. Other folders and files in the project are always reachable in the Obsidian file explorer.");
const doAdd = () => __awaiter(this, void 0, void 0, function* () {
const indexFile = indexFileField.getValue();
const draftsPath = draftsFolderField.getValue();
yield this.plugin.markPathAsProject(this.path, {
path: this.path,
indexFile,
draftsPath,
});
this.close();
});
const saveButton = new obsidian.ButtonComponent(contentEl)
.setButtonText("Add to Longform")
.onClick(doAdd);
saveButton.buttonEl.id = "longform-add-button";
indexFileField.inputEl.focus();
}
onClose() {
const { contentEl } = this;
contentEl.empty();
}
addField(rootEl, label, placeholder, value = "", description = "") {
const inputId = label.replace(" ", "-").toLowerCase();
const container = document.createElement("div");
container.style.display = "flex";
container.style.flexDirection = "row";
container.style.justifyContent = "space-between";
container.style.alignContent = "center";
rootEl.appendChild(container);
const labelEl = document.createElement("label");
labelEl.setText(label);
labelEl.htmlFor = inputId;
labelEl.style.display = "flex";
labelEl.style.alignItems = "center";
labelEl.style.marginRight = "12px";
container.appendChild(labelEl);
const field = new obsidian.TextComponent(container).setPlaceholder(placeholder);
field.inputEl.value = value;
field.inputEl.style.flexGrow = "1";
field.inputEl.id = inputId;
if (description.length > 0) {
const descriptionEl = document.createElement("p");
descriptionEl.setText(description);
descriptionEl.style.color = "var(--text-muted)";
rootEl.appendChild(descriptionEl);
}
return field;
}
}
const WARNING = `
This file is managed by Longform. Please avoid editing it directly; doing so will almost certainly confuse the plugin, and may cause a loss of data.
Longform uses this file to organize your folders and notes into a project. For more details, please see [The Index File](https://github.com/kevboh/longform#the-index-file) section of the plugins README.
`;
const EmptyIndexFileMetadata = {
version: LONGFORM_CURRENT_INDEX_VERSION,
drafts: [
{
name: "Draft 1",
folder: "Draft 1",
scenes: [],
},
],
};
function indexBodyFor(state) {
const body = obsidian.stringifyYaml(state);
return `---\n${body}---\n\n${WARNING}\n`;
}
function buildDraftsLookup(drafts) {
return drafts.reduce((agg, d) => {
agg[d.folder] = d;
return agg;
}, {});
}
function addProject(path, project, settings) {
return Object.assign(Object.assign({}, settings), { projects: Object.assign(Object.assign({}, settings.projects), { [path]: project }) });
}
function removeProject(path, settings) {
const newSettings = settings;
delete newSettings.projects[path];
return newSettings;
}
function isLongformProject(path, settings) {
return !!settings.projects[path];
}
function isInLongformProject(path, settings) {
return !!Object.keys(settings.projects).find((p) => path.startsWith(p));
}
function indexFilePath(project) {
return obsidian.normalizePath(`${project.path}/${project.indexFile}.md`);
}
/**
* Removes all key-value entries from the list cache.
*
* @private
* @name clear
* @memberOf ListCache
*/
function listCacheClear() {
this.__data__ = [];
this.size = 0;
}
var _listCacheClear = listCacheClear;
/**
* Performs a
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
* comparison between two values to determine if they are equivalent.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to compare.
* @param {*} other The other value to compare.
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
* @example
*
* var object = { 'a': 1 };
* var other = { 'a': 1 };
*
* _.eq(object, object);
* // => true
*
* _.eq(object, other);
* // => false
*
* _.eq('a', 'a');
* // => true
*
* _.eq('a', Object('a'));
* // => false
*
* _.eq(NaN, NaN);
* // => true
*/
function eq(value, other) {
return value === other || (value !== value && other !== other);
}
var eq_1 = eq;
/**
* Gets the index at which the `key` is found in `array` of key-value pairs.
*
* @private
* @param {Array} array The array to inspect.
* @param {*} key The key to search for.
* @returns {number} Returns the index of the matched value, else `-1`.
*/
function assocIndexOf(array, key) {
var length = array.length;
while (length--) {
if (eq_1(array[length][0], key)) {
return length;
}
}
return -1;
}
var _assocIndexOf = assocIndexOf;
/** Used for built-in method references. */
var arrayProto = Array.prototype;
/** Built-in value references. */
var splice = arrayProto.splice;
/**
* Removes `key` and its value from the list cache.
*
* @private
* @name delete
* @memberOf ListCache
* @param {string} key The key of the value to remove.
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
*/
function listCacheDelete(key) {
var data = this.__data__,
index = _assocIndexOf(data, key);
if (index < 0) {
return false;
}
var lastIndex = data.length - 1;
if (index == lastIndex) {
data.pop();
} else {
splice.call(data, index, 1);
}
--this.size;
return true;
}
var _listCacheDelete = listCacheDelete;
/**
* Gets the list cache value for `key`.
*
* @private
* @name get
* @memberOf ListCache
* @param {string} key The key of the value to get.
* @returns {*} Returns the entry value.
*/
function listCacheGet(key) {
var data = this.__data__,
index = _assocIndexOf(data, key);
return index < 0 ? undefined : data[index][1];
}
var _listCacheGet = listCacheGet;
/**
* Checks if a list cache value for `key` exists.
*
* @private
* @name has
* @memberOf ListCache
* @param {string} key The key of the entry to check.
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
*/
function listCacheHas(key) {
return _assocIndexOf(this.__data__, key) > -1;
}
var _listCacheHas = listCacheHas;
/**
* Sets the list cache `key` to `value`.
*
* @private
* @name set
* @memberOf ListCache
* @param {string} key The key of the value to set.
* @param {*} value The value to set.
* @returns {Object} Returns the list cache instance.
*/
function listCacheSet(key, value) {
var data = this.__data__,
index = _assocIndexOf(data, key);
if (index < 0) {
++this.size;
data.push([key, value]);
} else {
data[index][1] = value;
}
return this;
}
var _listCacheSet = listCacheSet;
/**
* Creates an list cache object.
*
* @private
* @constructor
* @param {Array} [entries] The key-value pairs to cache.
*/
function ListCache(entries) {
var index = -1,
length = entries == null ? 0 : entries.length;
this.clear();
while (++index < length) {
var entry = entries[index];
this.set(entry[0], entry[1]);
}
}
// Add methods to `ListCache`.
ListCache.prototype.clear = _listCacheClear;
ListCache.prototype['delete'] = _listCacheDelete;
ListCache.prototype.get = _listCacheGet;
ListCache.prototype.has = _listCacheHas;
ListCache.prototype.set = _listCacheSet;
var _ListCache = ListCache;
/**
* Removes all key-value entries from the stack.
*
* @private
* @name clear
* @memberOf Stack
*/
function stackClear() {
this.__data__ = new _ListCache;
this.size = 0;
}
var _stackClear = stackClear;
/**
* Removes `key` and its value from the stack.
*
* @private
* @name delete
* @memberOf Stack
* @param {string} key The key of the value to remove.
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
*/
function stackDelete(key) {
var data = this.__data__,
result = data['delete'](key);
this.size = data.size;
return result;
}
var _stackDelete = stackDelete;
/**
* Gets the stack value for `key`.
*
* @private
* @name get
* @memberOf Stack
* @param {string} key The key of the value to get.
* @returns {*} Returns the entry value.
*/
function stackGet(key) {
return this.__data__.get(key);
}
var _stackGet = stackGet;
/**
* Checks if a stack value for `key` exists.
*
* @private
* @name has
* @memberOf Stack
* @param {string} key The key of the entry to check.
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
*/
function stackHas(key) {
return this.__data__.has(key);
}
var _stackHas = stackHas;
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
function createCommonjsModule(fn) {
var module = { exports: {} };
return fn(module, module.exports), module.exports;
}
/** Detect free variable `global` from Node.js. */
var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
var _freeGlobal = freeGlobal;
/** Detect free variable `self`. */
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
/** Used as a reference to the global object. */
var root = _freeGlobal || freeSelf || Function('return this')();
var _root = root;
/** Built-in value references. */
var Symbol$1 = _root.Symbol;
var _Symbol = Symbol$1;
/** Used for built-in method references. */
var objectProto$e = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty$b = objectProto$e.hasOwnProperty;
/**
* Used to resolve the
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
* of values.
*/
var nativeObjectToString$1 = objectProto$e.toString;
/** Built-in value references. */
var symToStringTag$1 = _Symbol ? _Symbol.toStringTag : undefined;
/**
* A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
*
* @private
* @param {*} value The value to query.
* @returns {string} Returns the raw `toStringTag`.
*/
function getRawTag(value) {
var isOwn = hasOwnProperty$b.call(value, symToStringTag$1),
tag = value[symToStringTag$1];
try {
value[symToStringTag$1] = undefined;
var unmasked = true;
} catch (e) {}
var result = nativeObjectToString$1.call(value);
if (unmasked) {
if (isOwn) {
value[symToStringTag$1] = tag;
} else {
delete value[symToStringTag$1];
}
}
return result;
}
var _getRawTag = getRawTag;
/** Used for built-in method references. */
var objectProto$d = Object.prototype;
/**
* Used to resolve the
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
* of values.
*/
var nativeObjectToString = objectProto$d.toString;
/**
* Converts `value` to a string using `Object.prototype.toString`.
*
* @private
* @param {*} value The value to convert.
* @returns {string} Returns the converted string.
*/
function objectToString(value) {
return nativeObjectToString.call(value);
}
var _objectToString = objectToString;
/** `Object#toString` result references. */
var nullTag = '[object Null]',
undefinedTag = '[object Undefined]';
/** Built-in value references. */
var symToStringTag = _Symbol ? _Symbol.toStringTag : undefined;
/**
* The base implementation of `getTag` without fallbacks for buggy environments.
*
* @private
* @param {*} value The value to query.
* @returns {string} Returns the `toStringTag`.
*/
function baseGetTag(value) {
if (value == null) {
return value === undefined ? undefinedTag : nullTag;
}
return (symToStringTag && symToStringTag in Object(value))
? _getRawTag(value)
: _objectToString(value);
}
var _baseGetTag = baseGetTag;
/**
* Checks if `value` is the
* [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
* @example
*
* _.isObject({});
* // => true
*
* _.isObject([1, 2, 3]);
* // => true
*
* _.isObject(_.noop);
* // => true
*
* _.isObject(null);
* // => false
*/
function isObject(value) {
var type = typeof value;
return value != null && (type == 'object' || type == 'function');
}
var isObject_1 = isObject;
/** `Object#toString` result references. */
var asyncTag = '[object AsyncFunction]',
funcTag$2 = '[object Function]',
genTag$1 = '[object GeneratorFunction]',
proxyTag = '[object Proxy]';
/**
* Checks if `value` is classified as a `Function` object.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a function, else `false`.
* @example
*
* _.isFunction(_);
* // => true
*
* _.isFunction(/abc/);
* // => false
*/
function isFunction(value) {
if (!isObject_1(value)) {
return false;
}
// The use of `Object#toString` avoids issues with the `typeof` operator
// in Safari 9 which returns 'object' for typed arrays and other constructors.
var tag = _baseGetTag(value);
return tag == funcTag$2 || tag == genTag$1 || tag == asyncTag || tag == proxyTag;
}
var isFunction_1 = isFunction;
/** Used to detect overreaching core-js shims. */
var coreJsData = _root['__core-js_shared__'];
var _coreJsData = coreJsData;
/** Used to detect methods masquerading as native. */
var maskSrcKey = (function() {
var uid = /[^.]+$/.exec(_coreJsData && _coreJsData.keys && _coreJsData.keys.IE_PROTO || '');
return uid ? ('Symbol(src)_1.' + uid) : '';
}());
/**
* Checks if `func` has its source masked.
*
* @private
* @param {Function} func The function to check.
* @returns {boolean} Returns `true` if `func` is masked, else `false`.
*/
function isMasked(func) {
return !!maskSrcKey && (maskSrcKey in func);
}
var _isMasked = isMasked;
/** Used for built-in method references. */
var funcProto$1 = Function.prototype;
/** Used to resolve the decompiled source of functions. */
var funcToString$1 = funcProto$1.toString;
/**
* Converts `func` to its source code.
*
* @private
* @param {Function} func The function to convert.
* @returns {string} Returns the source code.
*/
function toSource(func) {
if (func != null) {
try {
return funcToString$1.call(func);
} catch (e) {}
try {
return (func + '');
} catch (e) {}
}
return '';
}
var _toSource = toSource;
/**
* Used to match `RegExp`
* [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
*/
var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
/** Used to detect host constructors (Safari). */
var reIsHostCtor = /^\[object .+?Constructor\]$/;
/** Used for built-in method references. */
var funcProto = Function.prototype,
objectProto$c = Object.prototype;
/** Used to resolve the decompiled source of functions. */
var funcToString = funcProto.toString;
/** Used to check objects for own properties. */
var hasOwnProperty$a = objectProto$c.hasOwnProperty;
/** Used to detect if a method is native. */
var reIsNative = RegExp('^' +
funcToString.call(hasOwnProperty$a).replace(reRegExpChar, '\\$&')
.replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
);
/**
* The base implementation of `_.isNative` without bad shim checks.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a native function,
* else `false`.
*/
function baseIsNative(value) {
if (!isObject_1(value) || _isMasked(value)) {
return false;
}
var pattern = isFunction_1(value) ? reIsNative : reIsHostCtor;
return pattern.test(_toSource(value));
}
var _baseIsNative = baseIsNative;
/**
* Gets the value at `key` of `object`.
*
* @private
* @param {Object} [object] The object to query.
* @param {string} key The key of the property to get.
* @returns {*} Returns the property value.
*/
function getValue(object, key) {
return object == null ? undefined : object[key];
}
var _getValue = getValue;
/**
* Gets the native function at `key` of `object`.
*
* @private
* @param {Object} object The object to query.
* @param {string} key The key of the method to get.
* @returns {*} Returns the function if it's native, else `undefined`.
*/
function getNative(object, key) {
var value = _getValue(object, key);
return _baseIsNative(value) ? value : undefined;
}
var _getNative = getNative;
/* Built-in method references that are verified to be native. */
var Map$1 = _getNative(_root, 'Map');
var _Map = Map$1;
/* Built-in method references that are verified to be native. */
var nativeCreate = _getNative(Object, 'create');
var _nativeCreate = nativeCreate;
/**
* Removes all key-value entries from the hash.
*
* @private
* @name clear
* @memberOf Hash
*/
function hashClear() {
this.__data__ = _nativeCreate ? _nativeCreate(null) : {};
this.size = 0;
}
var _hashClear = hashClear;
/**
* Removes `key` and its value from the hash.
*
* @private
* @name delete
* @memberOf Hash
* @param {Object} hash The hash to modify.
* @param {string} key The key of the value to remove.
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
*/
function hashDelete(key) {
var result = this.has(key) && delete this.__data__[key];
this.size -= result ? 1 : 0;
return result;
}
var _hashDelete = hashDelete;
/** Used to stand-in for `undefined` hash values. */
var HASH_UNDEFINED$2 = '__lodash_hash_undefined__';
/** Used for built-in method references. */
var objectProto$b = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty$9 = objectProto$b.hasOwnProperty;
/**
* Gets the hash value for `key`.
*
* @private
* @name get
* @memberOf Hash
* @param {string} key The key of the value to get.
* @returns {*} Returns the entry value.
*/
function hashGet(key) {
var data = this.__data__;
if (_nativeCreate) {
var result = data[key];
return result === HASH_UNDEFINED$2 ? undefined : result;
}
return hasOwnProperty$9.call(data, key) ? data[key] : undefined;
}
var _hashGet = hashGet;
/** Used for built-in method references. */
var objectProto$a = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty$8 = objectProto$a.hasOwnProperty;
/**
* Checks if a hash value for `key` exists.
*
* @private
* @name has
* @memberOf Hash
* @param {string} key The key of the entry to check.
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
*/
function hashHas(key) {
var data = this.__data__;
return _nativeCreate ? (data[key] !== undefined) : hasOwnProperty$8.call(data, key);
}
var _hashHas = hashHas;
/** Used to stand-in for `undefined` hash values. */
var HASH_UNDEFINED$1 = '__lodash_hash_undefined__';
/**
* Sets the hash `key` to `value`.
*
* @private
* @name set
* @memberOf Hash
* @param {string} key The key of the value to set.
* @param {*} value The value to set.
* @returns {Object} Returns the hash instance.
*/
function hashSet(key, value) {
var data = this.__data__;
this.size += this.has(key) ? 0 : 1;
data[key] = (_nativeCreate && value === undefined) ? HASH_UNDEFINED$1 : value;
return this;
}
var _hashSet = hashSet;
/**
* Creates a hash object.
*
* @private
* @constructor
* @param {Array} [entries] The key-value pairs to cache.
*/
function Hash(entries) {
var index = -1,
length = entries == null ? 0 : entries.length;
this.clear();
while (++index < length) {
var entry = entries[index];
this.set(entry[0], entry[1]);
}
}
// Add methods to `Hash`.
Hash.prototype.clear = _hashClear;
Hash.prototype['delete'] = _hashDelete;
Hash.prototype.get = _hashGet;
Hash.prototype.has = _hashHas;
Hash.prototype.set = _hashSet;
var _Hash = Hash;
/**
* Removes all key-value entries from the map.
*
* @private
* @name clear
* @memberOf MapCache
*/
function mapCacheClear() {
this.size = 0;
this.__data__ = {
'hash': new _Hash,
'map': new (_Map || _ListCache),
'string': new _Hash
};
}
var _mapCacheClear = mapCacheClear;
/**
* Checks if `value` is suitable for use as unique object key.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is suitable, else `false`.
*/
function isKeyable(value) {
var type = typeof value;
return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
? (value !== '__proto__')
: (value === null);
}
var _isKeyable = isKeyable;
/**
* Gets the data for `map`.
*
* @private
* @param {Object} map The map to query.
* @param {string} key The reference key.
* @returns {*} Returns the map data.
*/
function getMapData(map, key) {
var data = map.__data__;
return _isKeyable(key)
? data[typeof key == 'string' ? 'string' : 'hash']
: data.map;
}
var _getMapData = getMapData;
/**
* Removes `key` and its value from the map.
*
* @private
* @name delete
* @memberOf MapCache
* @param {string} key The key of the value to remove.
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
*/
function mapCacheDelete(key) {
var result = _getMapData(this, key)['delete'](key);
this.size -= result ? 1 : 0;
return result;
}
var _mapCacheDelete = mapCacheDelete;
/**
* Gets the map value for `key`.
*
* @private
* @name get
* @memberOf MapCache
* @param {string} key The key of the value to get.
* @returns {*} Returns the entry value.
*/
function mapCacheGet(key) {
return _getMapData(this, key).get(key);
}
var _mapCacheGet = mapCacheGet;
/**
* Checks if a map value for `key` exists.
*
* @private
* @name has
* @memberOf MapCache
* @param {string} key The key of the entry to check.
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
*/
function mapCacheHas(key) {
return _getMapData(this, key).has(key);
}
var _mapCacheHas = mapCacheHas;
/**
* Sets the map `key` to `value`.
*
* @private
* @name set
* @memberOf MapCache
* @param {string} key The key of the value to set.
* @param {*} value The value to set.
* @returns {Object} Returns the map cache instance.
*/
function mapCacheSet(key, value) {
var data = _getMapData(this, key),
size = data.size;
data.set(key, value);
this.size += data.size == size ? 0 : 1;
return this;
}
var _mapCacheSet = mapCacheSet;
/**
* Creates a map cache object to store key-value pairs.
*
* @private
* @constructor
* @param {Array} [entries] The key-value pairs to cache.
*/
function MapCache(entries) {
var index = -1,
length = entries == null ? 0 : entries.length;
this.clear();
while (++index < length) {
var entry = entries[index];
this.set(entry[0], entry[1]);
}
}
// Add methods to `MapCache`.
MapCache.prototype.clear = _mapCacheClear;
MapCache.prototype['delete'] = _mapCacheDelete;
MapCache.prototype.get = _mapCacheGet;
MapCache.prototype.has = _mapCacheHas;
MapCache.prototype.set = _mapCacheSet;
var _MapCache = MapCache;
/** Used as the size to enable large array optimizations. */
var LARGE_ARRAY_SIZE = 200;
/**
* Sets the stack `key` to `value`.
*
* @private
* @name set
* @memberOf Stack
* @param {string} key The key of the value to set.
* @param {*} value The value to set.
* @returns {Object} Returns the stack cache instance.
*/
function stackSet(key, value) {
var data = this.__data__;
if (data instanceof _ListCache) {
var pairs = data.__data__;
if (!_Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
pairs.push([key, value]);
this.size = ++data.size;
return this;
}
data = this.__data__ = new _MapCache(pairs);
}
data.set(key, value);
this.size = data.size;
return this;
}
var _stackSet = stackSet;
/**
* Creates a stack cache object to store key-value pairs.
*
* @private
* @constructor
* @param {Array} [entries] The key-value pairs to cache.
*/
function Stack(entries) {
var data = this.__data__ = new _ListCache(entries);
this.size = data.size;
}
// Add methods to `Stack`.
Stack.prototype.clear = _stackClear;
Stack.prototype['delete'] = _stackDelete;
Stack.prototype.get = _stackGet;
Stack.prototype.has = _stackHas;
Stack.prototype.set = _stackSet;
var _Stack = Stack;
/** Used to stand-in for `undefined` hash values. */
var HASH_UNDEFINED = '__lodash_hash_undefined__';
/**
* Adds `value` to the array cache.
*
* @private
* @name add
* @memberOf SetCache
* @alias push
* @param {*} value The value to cache.
* @returns {Object} Returns the cache instance.
*/
function setCacheAdd(value) {
this.__data__.set(value, HASH_UNDEFINED);
return this;
}
var _setCacheAdd = setCacheAdd;
/**
* Checks if `value` is in the array cache.
*
* @private
* @name has
* @memberOf SetCache
* @param {*} value The value to search for.
* @returns {number} Returns `true` if `value` is found, else `false`.
*/
function setCacheHas(value) {
return this.__data__.has(value);
}
var _setCacheHas = setCacheHas;
/**
*
* Creates an array cache object to store unique values.
*
* @private
* @constructor
* @param {Array} [values] The values to cache.
*/
function SetCache(values) {
var index = -1,
length = values == null ? 0 : values.length;
this.__data__ = new _MapCache;
while (++index < length) {
this.add(values[index]);
}
}
// Add methods to `SetCache`.
SetCache.prototype.add = SetCache.prototype.push = _setCacheAdd;
SetCache.prototype.has = _setCacheHas;
var _SetCache = SetCache;
/**
* A specialized version of `_.some` for arrays without support for iteratee
* shorthands.
*
* @private
* @param {Array} [array] The array to iterate over.
* @param {Function} predicate The function invoked per iteration.
* @returns {boolean} Returns `true` if any element passes the predicate check,
* else `false`.
*/
function arraySome(array, predicate) {
var index = -1,
length = array == null ? 0 : array.length;
while (++index < length) {
if (predicate(array[index], index, array)) {
return true;
}
}
return false;
}
var _arraySome = arraySome;
/**
* Checks if a `cache` value for `key` exists.
*
* @private
* @param {Object} cache The cache to query.
* @param {string} key The key of the entry to check.
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
*/
function cacheHas(cache, key) {
return cache.has(key);
}
var _cacheHas = cacheHas;
/** Used to compose bitmasks for value comparisons. */
var COMPARE_PARTIAL_FLAG$3 = 1,
COMPARE_UNORDERED_FLAG$1 = 2;
/**
* A specialized version of `baseIsEqualDeep` for arrays with support for
* partial deep comparisons.
*
* @private
* @param {Array} array The array to compare.
* @param {Array} other The other array to compare.
* @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
* @param {Function} customizer The function to customize comparisons.
* @param {Function} equalFunc The function to determine equivalents of values.
* @param {Object} stack Tracks traversed `array` and `other` objects.
* @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
*/
function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
var isPartial = bitmask & COMPARE_PARTIAL_FLAG$3,
arrLength = array.length,
othLength = other.length;
if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
return false;
}
// Check that cyclic values are equal.
var arrStacked = stack.get(array);
var othStacked = stack.get(other);
if (arrStacked && othStacked) {
return arrStacked == other && othStacked == array;
}
var index = -1,
result = true,
seen = (bitmask & COMPARE_UNORDERED_FLAG$1) ? new _SetCache : undefined;
stack.set(array, other);
stack.set(other, array);
// Ignore non-index properties.
while (++index < arrLength) {
var arrValue = array[index],
othValue = other[index];
if (customizer) {
var compared = isPartial
? customizer(othValue, arrValue, index, other, array, stack)
: customizer(arrValue, othValue, index, array, other, stack);
}
if (compared !== undefined) {
if (compared) {
continue;
}
result = false;
break;
}
// Recursively compare arrays (susceptible to call stack limits).
if (seen) {
if (!_arraySome(other, function(othValue, othIndex) {
if (!_cacheHas(seen, othIndex) &&
(arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
return seen.push(othIndex);
}
})) {
result = false;
break;
}
} else if (!(
arrValue === othValue ||
equalFunc(arrValue, othValue, bitmask, customizer, stack)
)) {
result = false;
break;
}
}
stack['delete'](array);
stack['delete'](other);
return result;
}
var _equalArrays = equalArrays;
/** Built-in value references. */
var Uint8Array = _root.Uint8Array;
var _Uint8Array = Uint8Array;
/**
* Converts `map` to its key-value pairs.
*
* @private
* @param {Object} map The map to convert.
* @returns {Array} Returns the key-value pairs.
*/
function mapToArray(map) {
var index = -1,
result = Array(map.size);
map.forEach(function(value, key) {
result[++index] = [key, value];
});
return result;
}
var _mapToArray = mapToArray;
/**
* Converts `set` to an array of its values.
*
* @private
* @param {Object} set The set to convert.
* @returns {Array} Returns the values.
*/
function setToArray(set) {
var index = -1,
result = Array(set.size);
set.forEach(function(value) {
result[++index] = value;
});
return result;
}
var _setToArray = setToArray;
/** Used to compose bitmasks for value comparisons. */
var COMPARE_PARTIAL_FLAG$2 = 1,
COMPARE_UNORDERED_FLAG = 2;
/** `Object#toString` result references. */
var boolTag$3 = '[object Boolean]',
dateTag$3 = '[object Date]',
errorTag$2 = '[object Error]',
mapTag$5 = '[object Map]',
numberTag$3 = '[object Number]',
regexpTag$3 = '[object RegExp]',
setTag$5 = '[object Set]',
stringTag$3 = '[object String]',
symbolTag$2 = '[object Symbol]';
var arrayBufferTag$3 = '[object ArrayBuffer]',
dataViewTag$4 = '[object DataView]';
/** Used to convert symbols to primitives and strings. */
var symbolProto$1 = _Symbol ? _Symbol.prototype : undefined,
symbolValueOf$1 = symbolProto$1 ? symbolProto$1.valueOf : undefined;
/**
* A specialized version of `baseIsEqualDeep` for comparing objects of
* the same `toStringTag`.
*
* **Note:** This function only supports comparing values with tags of
* `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
*
* @private
* @param {Object} object The object to compare.
* @param {Object} other The other object to compare.
* @param {string} tag The `toStringTag` of the objects to compare.
* @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
* @param {Function} customizer The function to customize comparisons.
* @param {Function} equalFunc The function to determine equivalents of values.
* @param {Object} stack Tracks traversed `object` and `other` objects.
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
*/
function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
switch (tag) {
case dataViewTag$4:
if ((object.byteLength != other.byteLength) ||
(object.byteOffset != other.byteOffset)) {
return false;
}
object = object.buffer;
other = other.buffer;
case arrayBufferTag$3:
if ((object.byteLength != other.byteLength) ||
!equalFunc(new _Uint8Array(object), new _Uint8Array(other))) {
return false;
}
return true;
case boolTag$3:
case dateTag$3:
case numberTag$3:
// Coerce booleans to `1` or `0` and dates to milliseconds.
// Invalid dates are coerced to `NaN`.
return eq_1(+object, +other);
case errorTag$2:
return object.name == other.name && object.message == other.message;
case regexpTag$3:
case stringTag$3:
// Coerce regexes to strings and treat strings, primitives and objects,
// as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
// for more details.
return object == (other + '');
case mapTag$5:
var convert = _mapToArray;
case setTag$5:
var isPartial = bitmask & COMPARE_PARTIAL_FLAG$2;
convert || (convert = _setToArray);
if (object.size != other.size && !isPartial) {
return false;
}
// Assume cyclic values are equal.
var stacked = stack.get(object);
if (stacked) {
return stacked == other;
}
bitmask |= COMPARE_UNORDERED_FLAG;
// Recursively compare objects (susceptible to call stack limits).
stack.set(object, other);
var result = _equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
stack['delete'](object);
return result;
case symbolTag$2:
if (symbolValueOf$1) {
return symbolValueOf$1.call(object) == symbolValueOf$1.call(other);
}
}
return false;
}
var _equalByTag = equalByTag;
/**
* Appends the elements of `values` to `array`.
*
* @private
* @param {Array} array The array to modify.
* @param {Array} values The values to append.
* @returns {Array} Returns `array`.
*/
function arrayPush(array, values) {
var index = -1,
length = values.length,
offset = array.length;
while (++index < length) {
array[offset + index] = values[index];
}
return array;
}
var _arrayPush = arrayPush;
/**
* Checks if `value` is classified as an `Array` object.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an array, else `false`.
* @example
*
* _.isArray([1, 2, 3]);
* // => true
*
* _.isArray(document.body.children);
* // => false
*
* _.isArray('abc');
* // => false
*
* _.isArray(_.noop);
* // => false
*/
var isArray = Array.isArray;
var isArray_1 = isArray;
/**
* The base implementation of `getAllKeys` and `getAllKeysIn` which uses
* `keysFunc` and `symbolsFunc` to get the enumerable property names and
* symbols of `object`.
*
* @private
* @param {Object} object The object to query.
* @param {Function} keysFunc The function to get the keys of `object`.
* @param {Function} symbolsFunc The function to get the symbols of `object`.
* @returns {Array} Returns the array of property names and symbols.
*/
function baseGetAllKeys(object, keysFunc, symbolsFunc) {
var result = keysFunc(object);
return isArray_1(object) ? result : _arrayPush(result, symbolsFunc(object));
}
var _baseGetAllKeys = baseGetAllKeys;
/**
* A specialized version of `_.filter` for arrays without support for
* iteratee shorthands.
*
* @private
* @param {Array} [array] The array to iterate over.
* @param {Function} predicate The function invoked per iteration.
* @returns {Array} Returns the new filtered array.
*/
function arrayFilter(array, predicate) {
var index = -1,
length = array == null ? 0 : array.length,
resIndex = 0,
result = [];
while (++index < length) {
var value = array[index];
if (predicate(value, index, array)) {
result[resIndex++] = value;
}
}
return result;
}
var _arrayFilter = arrayFilter;
/**
* This method returns a new empty array.
*
* @static
* @memberOf _
* @since 4.13.0
* @category Util
* @returns {Array} Returns the new empty array.
* @example
*
* var arrays = _.times(2, _.stubArray);
*
* console.log(arrays);
* // => [[], []]
*
* console.log(arrays[0] === arrays[1]);
* // => false
*/
function stubArray() {
return [];
}
var stubArray_1 = stubArray;
/** Used for built-in method references. */
var objectProto$9 = Object.prototype;
/** Built-in value references. */
var propertyIsEnumerable$1 = objectProto$9.propertyIsEnumerable;
/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeGetSymbols$1 = Object.getOwnPropertySymbols;
/**
* Creates an array of the own enumerable symbols of `object`.
*
* @private
* @param {Object} object The object to query.
* @returns {Array} Returns the array of symbols.
*/
var getSymbols = !nativeGetSymbols$1 ? stubArray_1 : function(object) {
if (object == null) {
return [];
}
object = Object(object);
return _arrayFilter(nativeGetSymbols$1(object), function(symbol) {
return propertyIsEnumerable$1.call(object, symbol);
});
};
var _getSymbols = getSymbols;
/**
* The base implementation of `_.times` without support for iteratee shorthands
* or max array length checks.
*
* @private
* @param {number} n The number of times to invoke `iteratee`.
* @param {Function} iteratee The function invoked per iteration.
* @returns {Array} Returns the array of results.
*/
function baseTimes(n, iteratee) {
var index = -1,
result = Array(n);
while (++index < n) {
result[index] = iteratee(index);
}
return result;
}
var _baseTimes = baseTimes;
/**
* Checks if `value` is object-like. A value is object-like if it's not `null`
* and has a `typeof` result of "object".
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
* @example
*
* _.isObjectLike({});
* // => true
*
* _.isObjectLike([1, 2, 3]);
* // => true
*
* _.isObjectLike(_.noop);
* // => false
*
* _.isObjectLike(null);
* // => false
*/
function isObjectLike(value) {
return value != null && typeof value == 'object';
}
var isObjectLike_1 = isObjectLike;
/** `Object#toString` result references. */
var argsTag$3 = '[object Arguments]';
/**
* The base implementation of `_.isArguments`.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an `arguments` object,
*/
function baseIsArguments(value) {
return isObjectLike_1(value) && _baseGetTag(value) == argsTag$3;
}
var _baseIsArguments = baseIsArguments;
/** Used for built-in method references. */
var objectProto$8 = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty$7 = objectProto$8.hasOwnProperty;
/** Built-in value references. */
var propertyIsEnumerable = objectProto$8.propertyIsEnumerable;
/**
* Checks if `value` is likely an `arguments` object.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an `arguments` object,
* else `false`.
* @example
*
* _.isArguments(function() { return arguments; }());
* // => true
*
* _.isArguments([1, 2, 3]);
* // => false
*/
var isArguments = _baseIsArguments(function() { return arguments; }()) ? _baseIsArguments : function(value) {
return isObjectLike_1(value) && hasOwnProperty$7.call(value, 'callee') &&
!propertyIsEnumerable.call(value, 'callee');
};
var isArguments_1 = isArguments;
/**
* This method returns `false`.
*
* @static
* @memberOf _
* @since 4.13.0
* @category Util
* @returns {boolean} Returns `false`.
* @example
*
* _.times(2, _.stubFalse);
* // => [false, false]
*/
function stubFalse() {
return false;
}
var stubFalse_1 = stubFalse;
var isBuffer_1 = createCommonjsModule(function (module, exports) {
/** Detect free variable `exports`. */
var freeExports = exports && !exports.nodeType && exports;
/** Detect free variable `module`. */
var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;
/** Detect the popular CommonJS extension `module.exports`. */
var moduleExports = freeModule && freeModule.exports === freeExports;
/** Built-in value references. */
var Buffer = moduleExports ? _root.Buffer : undefined;
/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined;
/**
* Checks if `value` is a buffer.
*
* @static
* @memberOf _
* @since 4.3.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
* @example
*
* _.isBuffer(new Buffer(2));
* // => true
*
* _.isBuffer(new Uint8Array(2));
* // => false
*/
var isBuffer = nativeIsBuffer || stubFalse_1;
module.exports = isBuffer;
});
/** Used as references for various `Number` constants. */
var MAX_SAFE_INTEGER$1 = 9007199254740991;
/** Used to detect unsigned integer values. */
var reIsUint = /^(?:0|[1-9]\d*)$/;
/**
* Checks if `value` is a valid array-like index.
*
* @private
* @param {*} value The value to check.
* @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
* @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
*/
function isIndex(value, length) {
var type = typeof value;
length = length == null ? MAX_SAFE_INTEGER$1 : length;
return !!length &&
(type == 'number' ||
(type != 'symbol' && reIsUint.test(value))) &&
(value > -1 && value % 1 == 0 && value < length);
}
var _isIndex = isIndex;
/** Used as references for various `Number` constants. */
var MAX_SAFE_INTEGER = 9007199254740991;
/**
* Checks if `value` is a valid array-like length.
*
* **Note:** This method is loosely based on
* [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
* @example
*
* _.isLength(3);
* // => true
*
* _.isLength(Number.MIN_VALUE);
* // => false
*
* _.isLength(Infinity);
* // => false
*
* _.isLength('3');
* // => false
*/
function isLength(value) {
return typeof value == 'number' &&
value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
}
var isLength_1 = isLength;
/** `Object#toString` result references. */
var argsTag$2 = '[object Arguments]',
arrayTag$2 = '[object Array]',
boolTag$2 = '[object Boolean]',
dateTag$2 = '[object Date]',
errorTag$1 = '[object Error]',
funcTag$1 = '[object Function]',
mapTag$4 = '[object Map]',
numberTag$2 = '[object Number]',
objectTag$3 = '[object Object]',
regexpTag$2 = '[object RegExp]',
setTag$4 = '[object Set]',
stringTag$2 = '[object String]',
weakMapTag$2 = '[object WeakMap]';
var arrayBufferTag$2 = '[object ArrayBuffer]',
dataViewTag$3 = '[object DataView]',
float32Tag$2 = '[object Float32Array]',
float64Tag$2 = '[object Float64Array]',
int8Tag$2 = '[object Int8Array]',
int16Tag$2 = '[object Int16Array]',
int32Tag$2 = '[object Int32Array]',
uint8Tag$2 = '[object Uint8Array]',
uint8ClampedTag$2 = '[object Uint8ClampedArray]',
uint16Tag$2 = '[object Uint16Array]',
uint32Tag$2 = '[object Uint32Array]';
/** Used to identify `toStringTag` values of typed arrays. */
var typedArrayTags = {};
typedArrayTags[float32Tag$2] = typedArrayTags[float64Tag$2] =
typedArrayTags[int8Tag$2] = typedArrayTags[int16Tag$2] =
typedArrayTags[int32Tag$2] = typedArrayTags[uint8Tag$2] =
typedArrayTags[uint8ClampedTag$2] = typedArrayTags[uint16Tag$2] =
typedArrayTags[uint32Tag$2] = true;
typedArrayTags[argsTag$2] = typedArrayTags[arrayTag$2] =
typedArrayTags[arrayBufferTag$2] = typedArrayTags[boolTag$2] =
typedArrayTags[dataViewTag$3] = typedArrayTags[dateTag$2] =
typedArrayTags[errorTag$1] = typedArrayTags[funcTag$1] =
typedArrayTags[mapTag$4] = typedArrayTags[numberTag$2] =
typedArrayTags[objectTag$3] = typedArrayTags[regexpTag$2] =
typedArrayTags[setTag$4] = typedArrayTags[stringTag$2] =
typedArrayTags[weakMapTag$2] = false;
/**
* The base implementation of `_.isTypedArray` without Node.js optimizations.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
*/
function baseIsTypedArray(value) {
return isObjectLike_1(value) &&
isLength_1(value.length) && !!typedArrayTags[_baseGetTag(value)];
}
var _baseIsTypedArray = baseIsTypedArray;
/**
* The base implementation of `_.unary` without support for storing metadata.
*
* @private
* @param {Function} func The function to cap arguments for.
* @returns {Function} Returns the new capped function.
*/
function baseUnary(func) {
return function(value) {
return func(value);
};
}
var _baseUnary = baseUnary;
var _nodeUtil = createCommonjsModule(function (module, exports) {
/** Detect free variable `exports`. */
var freeExports = exports && !exports.nodeType && exports;
/** Detect free variable `module`. */
var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;
/** Detect the popular CommonJS extension `module.exports`. */
var moduleExports = freeModule && freeModule.exports === freeExports;
/** Detect free variable `process` from Node.js. */
var freeProcess = moduleExports && _freeGlobal.process;
/** Used to access faster Node.js helpers. */
var nodeUtil = (function() {
try {
// Use `util.types` for Node.js 10+.
var types = freeModule && freeModule.require && freeModule.require('util').types;
if (types) {
return types;
}
// Legacy `process.binding('util')` for Node.js < 10.
return freeProcess && freeProcess.binding && freeProcess.binding('util');
} catch (e) {}
}());
module.exports = nodeUtil;
});
/* Node.js helper references. */
var nodeIsTypedArray = _nodeUtil && _nodeUtil.isTypedArray;
/**
* Checks if `value` is classified as a typed array.
*
* @static
* @memberOf _
* @since 3.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
* @example
*
* _.isTypedArray(new Uint8Array);
* // => true
*
* _.isTypedArray([]);
* // => false
*/
var isTypedArray = nodeIsTypedArray ? _baseUnary(nodeIsTypedArray) : _baseIsTypedArray;
var isTypedArray_1 = isTypedArray;
/** Used for built-in method references. */
var objectProto$7 = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty$6 = objectProto$7.hasOwnProperty;
/**
* Creates an array of the enumerable property names of the array-like `value`.
*
* @private
* @param {*} value The value to query.
* @param {boolean} inherited Specify returning inherited property names.
* @returns {Array} Returns the array of property names.
*/
function arrayLikeKeys(value, inherited) {
var isArr = isArray_1(value),
isArg = !isArr && isArguments_1(value),
isBuff = !isArr && !isArg && isBuffer_1(value),
isType = !isArr && !isArg && !isBuff && isTypedArray_1(value),
skipIndexes = isArr || isArg || isBuff || isType,
result = skipIndexes ? _baseTimes(value.length, String) : [],
length = result.length;
for (var key in value) {
if ((inherited || hasOwnProperty$6.call(value, key)) &&
!(skipIndexes && (
// Safari 9 has enumerable `arguments.length` in strict mode.
key == 'length' ||
// Node.js 0.10 has enumerable non-index properties on buffers.
(isBuff && (key == 'offset' || key == 'parent')) ||
// PhantomJS 2 has enumerable non-index properties on typed arrays.
(isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
// Skip index properties.
_isIndex(key, length)
))) {
result.push(key);
}
}
return result;
}
var _arrayLikeKeys = arrayLikeKeys;
/** Used for built-in method references. */
var objectProto$6 = Object.prototype;
/**
* Checks if `value` is likely a prototype object.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
*/
function isPrototype(value) {
var Ctor = value && value.constructor,
proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$6;
return value === proto;
}
var _isPrototype = isPrototype;
/**
* Creates a unary function that invokes `func` with its argument transformed.
*
* @private
* @param {Function} func The function to wrap.
* @param {Function} transform The argument transform.
* @returns {Function} Returns the new function.
*/
function overArg(func, transform) {
return function(arg) {
return func(transform(arg));
};
}
var _overArg = overArg;
/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeKeys = _overArg(Object.keys, Object);
var _nativeKeys = nativeKeys;
/** Used for built-in method references. */
var objectProto$5 = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty$5 = objectProto$5.hasOwnProperty;
/**
* The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
*
* @private
* @param {Object} object The object to query.
* @returns {Array} Returns the array of property names.
*/
function baseKeys(object) {
if (!_isPrototype(object)) {
return _nativeKeys(object);
}
var result = [];
for (var key in Object(object)) {
if (hasOwnProperty$5.call(object, key) && key != 'constructor') {
result.push(key);
}
}
return result;
}
var _baseKeys = baseKeys;
/**
* Checks if `value` is array-like. A value is considered array-like if it's
* not a function and has a `value.length` that's an integer greater than or
* equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is array-like, else `false`.
* @example
*
* _.isArrayLike([1, 2, 3]);
* // => true
*
* _.isArrayLike(document.body.children);
* // => true
*
* _.isArrayLike('abc');
* // => true
*
* _.isArrayLike(_.noop);
* // => false
*/
function isArrayLike(value) {
return value != null && isLength_1(value.length) && !isFunction_1(value);
}
var isArrayLike_1 = isArrayLike;
/**
* Creates an array of the own enumerable property names of `object`.
*
* **Note:** Non-object values are coerced to objects. See the
* [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
* for more details.
*
* @static
* @since 0.1.0
* @memberOf _
* @category Object
* @param {Object} object The object to query.
* @returns {Array} Returns the array of property names.
* @example
*
* function Foo() {
* this.a = 1;
* this.b = 2;
* }
*
* Foo.prototype.c = 3;
*
* _.keys(new Foo);
* // => ['a', 'b'] (iteration order is not guaranteed)
*
* _.keys('hi');
* // => ['0', '1']
*/
function keys(object) {
return isArrayLike_1(object) ? _arrayLikeKeys(object) : _baseKeys(object);
}
var keys_1 = keys;
/**
* Creates an array of own enumerable property names and symbols of `object`.
*
* @private
* @param {Object} object The object to query.
* @returns {Array} Returns the array of property names and symbols.
*/
function getAllKeys(object) {
return _baseGetAllKeys(object, keys_1, _getSymbols);
}
var _getAllKeys = getAllKeys;
/** Used to compose bitmasks for value comparisons. */
var COMPARE_PARTIAL_FLAG$1 = 1;
/** Used for built-in method references. */
var objectProto$4 = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty$4 = objectProto$4.hasOwnProperty;
/**
* A specialized version of `baseIsEqualDeep` for objects with support for
* partial deep comparisons.
*
* @private
* @param {Object} object The object to compare.
* @param {Object} other The other object to compare.
* @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
* @param {Function} customizer The function to customize comparisons.
* @param {Function} equalFunc The function to determine equivalents of values.
* @param {Object} stack Tracks traversed `object` and `other` objects.
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
*/
function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
var isPartial = bitmask & COMPARE_PARTIAL_FLAG$1,
objProps = _getAllKeys(object),
objLength = objProps.length,
othProps = _getAllKeys(other),
othLength = othProps.length;
if (objLength != othLength && !isPartial) {
return false;
}
var index = objLength;
while (index--) {
var key = objProps[index];
if (!(isPartial ? key in other : hasOwnProperty$4.call(other, key))) {
return false;
}
}
// Check that cyclic values are equal.
var objStacked = stack.get(object);
var othStacked = stack.get(other);
if (objStacked && othStacked) {
return objStacked == other && othStacked == object;
}
var result = true;
stack.set(object, other);
stack.set(other, object);
var skipCtor = isPartial;
while (++index < objLength) {
key = objProps[index];
var objValue = object[key],
othValue = other[key];
if (customizer) {
var compared = isPartial
? customizer(othValue, objValue, key, other, object, stack)
: customizer(objValue, othValue, key, object, other, stack);
}
// Recursively compare objects (susceptible to call stack limits).
if (!(compared === undefined
? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
: compared
)) {
result = false;
break;
}
skipCtor || (skipCtor = key == 'constructor');
}
if (result && !skipCtor) {
var objCtor = object.constructor,
othCtor = other.constructor;
// Non `Object` object instances with different constructors are not equal.
if (objCtor != othCtor &&
('constructor' in object && 'constructor' in other) &&
!(typeof objCtor == 'function' && objCtor instanceof objCtor &&
typeof othCtor == 'function' && othCtor instanceof othCtor)) {
result = false;
}
}
stack['delete'](object);
stack['delete'](other);
return result;
}
var _equalObjects = equalObjects;
/* Built-in method references that are verified to be native. */
var DataView = _getNative(_root, 'DataView');
var _DataView = DataView;
/* Built-in method references that are verified to be native. */
var Promise$1 = _getNative(_root, 'Promise');
var _Promise = Promise$1;
/* Built-in method references that are verified to be native. */
var Set$1 = _getNative(_root, 'Set');
var _Set = Set$1;
/* Built-in method references that are verified to be native. */
var WeakMap = _getNative(_root, 'WeakMap');
var _WeakMap = WeakMap;
/** `Object#toString` result references. */
var mapTag$3 = '[object Map]',
objectTag$2 = '[object Object]',
promiseTag = '[object Promise]',
setTag$3 = '[object Set]',
weakMapTag$1 = '[object WeakMap]';
var dataViewTag$2 = '[object DataView]';
/** Used to detect maps, sets, and weakmaps. */
var dataViewCtorString = _toSource(_DataView),
mapCtorString = _toSource(_Map),
promiseCtorString = _toSource(_Promise),
setCtorString = _toSource(_Set),
weakMapCtorString = _toSource(_WeakMap);
/**
* Gets the `toStringTag` of `value`.
*
* @private
* @param {*} value The value to query.
* @returns {string} Returns the `toStringTag`.
*/
var getTag = _baseGetTag;
// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
if ((_DataView && getTag(new _DataView(new ArrayBuffer(1))) != dataViewTag$2) ||
(_Map && getTag(new _Map) != mapTag$3) ||
(_Promise && getTag(_Promise.resolve()) != promiseTag) ||
(_Set && getTag(new _Set) != setTag$3) ||
(_WeakMap && getTag(new _WeakMap) != weakMapTag$1)) {
getTag = function(value) {
var result = _baseGetTag(value),
Ctor = result == objectTag$2 ? value.constructor : undefined,
ctorString = Ctor ? _toSource(Ctor) : '';
if (ctorString) {
switch (ctorString) {
case dataViewCtorString: return dataViewTag$2;
case mapCtorString: return mapTag$3;
case promiseCtorString: return promiseTag;
case setCtorString: return setTag$3;
case weakMapCtorString: return weakMapTag$1;
}
}
return result;
};
}
var _getTag = getTag;
/** Used to compose bitmasks for value comparisons. */
var COMPARE_PARTIAL_FLAG = 1;
/** `Object#toString` result references. */
var argsTag$1 = '[object Arguments]',
arrayTag$1 = '[object Array]',
objectTag$1 = '[object Object]';
/** Used for built-in method references. */
var objectProto$3 = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty$3 = objectProto$3.hasOwnProperty;
/**
* A specialized version of `baseIsEqual` for arrays and objects which performs
* deep comparisons and tracks traversed objects enabling objects with circular
* references to be compared.
*
* @private
* @param {Object} object The object to compare.
* @param {Object} other The other object to compare.
* @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
* @param {Function} customizer The function to customize comparisons.
* @param {Function} equalFunc The function to determine equivalents of values.
* @param {Object} [stack] Tracks traversed `object` and `other` objects.
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
*/
function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
var objIsArr = isArray_1(object),
othIsArr = isArray_1(other),
objTag = objIsArr ? arrayTag$1 : _getTag(object),
othTag = othIsArr ? arrayTag$1 : _getTag(other);
objTag = objTag == argsTag$1 ? objectTag$1 : objTag;
othTag = othTag == argsTag$1 ? objectTag$1 : othTag;
var objIsObj = objTag == objectTag$1,
othIsObj = othTag == objectTag$1,
isSameTag = objTag == othTag;
if (isSameTag && isBuffer_1(object)) {
if (!isBuffer_1(other)) {
return false;
}
objIsArr = true;
objIsObj = false;
}
if (isSameTag && !objIsObj) {
stack || (stack = new _Stack);
return (objIsArr || isTypedArray_1(object))
? _equalArrays(object, other, bitmask, customizer, equalFunc, stack)
: _equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
}
if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
var objIsWrapped = objIsObj && hasOwnProperty$3.call(object, '__wrapped__'),
othIsWrapped = othIsObj && hasOwnProperty$3.call(other, '__wrapped__');
if (objIsWrapped || othIsWrapped) {
var objUnwrapped = objIsWrapped ? object.value() : object,
othUnwrapped = othIsWrapped ? other.value() : other;
stack || (stack = new _Stack);
return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
}
}
if (!isSameTag) {
return false;
}
stack || (stack = new _Stack);
return _equalObjects(object, other, bitmask, customizer, equalFunc, stack);
}
var _baseIsEqualDeep = baseIsEqualDeep;
/**
* The base implementation of `_.isEqual` which supports partial comparisons
* and tracks traversed objects.
*
* @private
* @param {*} value The value to compare.
* @param {*} other The other value to compare.
* @param {boolean} bitmask The bitmask flags.
* 1 - Unordered comparison
* 2 - Partial comparison
* @param {Function} [customizer] The function to customize comparisons.
* @param {Object} [stack] Tracks traversed `value` and `other` objects.
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
*/
function baseIsEqual(value, other, bitmask, customizer, stack) {
if (value === other) {
return true;
}
if (value == null || other == null || (!isObjectLike_1(value) && !isObjectLike_1(other))) {
return value !== value && other !== other;
}
return _baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
}
var _baseIsEqual = baseIsEqual;
/**
* Performs a deep comparison between two values to determine if they are
* equivalent.
*
* **Note:** This method supports comparing arrays, array buffers, booleans,
* date objects, error objects, maps, numbers, `Object` objects, regexes,
* sets, strings, symbols, and typed arrays. `Object` objects are compared
* by their own, not inherited, enumerable properties. Functions and DOM
* nodes are compared by strict equality, i.e. `===`.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to compare.
* @param {*} other The other value to compare.
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
* @example
*
* var object = { 'a': 1 };
* var other = { 'a': 1 };
*
* _.isEqual(object, other);
* // => true
*
* object === other;
* // => false
*/
function isEqual(value, other) {
return _baseIsEqual(value, other);
}
var isEqual_1 = isEqual;
/**
* A specialized version of `_.forEach` for arrays without support for
* iteratee shorthands.
*
* @private
* @param {Array} [array] The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @returns {Array} Returns `array`.
*/
function arrayEach(array, iteratee) {
var index = -1,
length = array == null ? 0 : array.length;
while (++index < length) {
if (iteratee(array[index], index, array) === false) {
break;
}
}
return array;
}
var _arrayEach = arrayEach;
var defineProperty = (function() {
try {
var func = _getNative(Object, 'defineProperty');
func({}, '', {});
return func;
} catch (e) {}
}());
var _defineProperty = defineProperty;
/**
* The base implementation of `assignValue` and `assignMergeValue` without
* value checks.
*
* @private
* @param {Object} object The object to modify.
* @param {string} key The key of the property to assign.
* @param {*} value The value to assign.
*/
function baseAssignValue(object, key, value) {
if (key == '__proto__' && _defineProperty) {
_defineProperty(object, key, {
'configurable': true,
'enumerable': true,
'value': value,
'writable': true
});
} else {
object[key] = value;
}
}
var _baseAssignValue = baseAssignValue;
/** Used for built-in method references. */
var objectProto$2 = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty$2 = objectProto$2.hasOwnProperty;
/**
* Assigns `value` to `key` of `object` if the existing value is not equivalent
* using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
* for equality comparisons.
*
* @private
* @param {Object} object The object to modify.
* @param {string} key The key of the property to assign.
* @param {*} value The value to assign.
*/
function assignValue(object, key, value) {
var objValue = object[key];
if (!(hasOwnProperty$2.call(object, key) && eq_1(objValue, value)) ||
(value === undefined && !(key in object))) {
_baseAssignValue(object, key, value);
}
}
var _assignValue = assignValue;
/**
* Copies properties of `source` to `object`.
*
* @private
* @param {Object} source The object to copy properties from.
* @param {Array} props The property identifiers to copy.
* @param {Object} [object={}] The object to copy properties to.
* @param {Function} [customizer] The function to customize copied values.
* @returns {Object} Returns `object`.
*/
function copyObject(source, props, object, customizer) {
var isNew = !object;
object || (object = {});
var index = -1,
length = props.length;
while (++index < length) {
var key = props[index];
var newValue = customizer
? customizer(object[key], source[key], key, object, source)
: undefined;
if (newValue === undefined) {
newValue = source[key];
}
if (isNew) {
_baseAssignValue(object, key, newValue);
} else {
_assignValue(object, key, newValue);
}
}
return object;
}
var _copyObject = copyObject;
/**
* The base implementation of `_.assign` without support for multiple sources
* or `customizer` functions.
*
* @private
* @param {Object} object The destination object.
* @param {Object} source The source object.
* @returns {Object} Returns `object`.
*/
function baseAssign(object, source) {
return object && _copyObject(source, keys_1(source), object);
}
var _baseAssign = baseAssign;
/**
* This function is like
* [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
* except that it includes inherited enumerable properties.
*
* @private
* @param {Object} object The object to query.
* @returns {Array} Returns the array of property names.
*/
function nativeKeysIn(object) {
var result = [];
if (object != null) {
for (var key in Object(object)) {
result.push(key);
}
}
return result;
}
var _nativeKeysIn = nativeKeysIn;
/** Used for built-in method references. */
var objectProto$1 = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty$1 = objectProto$1.hasOwnProperty;
/**
* The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
*
* @private
* @param {Object} object The object to query.
* @returns {Array} Returns the array of property names.
*/
function baseKeysIn(object) {
if (!isObject_1(object)) {
return _nativeKeysIn(object);
}
var isProto = _isPrototype(object),
result = [];
for (var key in object) {
if (!(key == 'constructor' && (isProto || !hasOwnProperty$1.call(object, key)))) {
result.push(key);
}
}
return result;
}
var _baseKeysIn = baseKeysIn;
/**
* Creates an array of the own and inherited enumerable property names of `object`.
*
* **Note:** Non-object values are coerced to objects.
*
* @static
* @memberOf _
* @since 3.0.0
* @category Object
* @param {Object} object The object to query.
* @returns {Array} Returns the array of property names.
* @example
*
* function Foo() {
* this.a = 1;
* this.b = 2;
* }
*
* Foo.prototype.c = 3;
*
* _.keysIn(new Foo);
* // => ['a', 'b', 'c'] (iteration order is not guaranteed)
*/
function keysIn(object) {
return isArrayLike_1(object) ? _arrayLikeKeys(object, true) : _baseKeysIn(object);
}
var keysIn_1 = keysIn;
/**
* The base implementation of `_.assignIn` without support for multiple sources
* or `customizer` functions.
*
* @private
* @param {Object} object The destination object.
* @param {Object} source The source object.
* @returns {Object} Returns `object`.
*/
function baseAssignIn(object, source) {
return object && _copyObject(source, keysIn_1(source), object);
}
var _baseAssignIn = baseAssignIn;
var _cloneBuffer = createCommonjsModule(function (module, exports) {
/** Detect free variable `exports`. */
var freeExports = exports && !exports.nodeType && exports;
/** Detect free variable `module`. */
var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;
/** Detect the popular CommonJS extension `module.exports`. */
var moduleExports = freeModule && freeModule.exports === freeExports;
/** Built-in value references. */
var Buffer = moduleExports ? _root.Buffer : undefined,
allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined;
/**
* Creates a clone of `buffer`.
*
* @private
* @param {Buffer} buffer The buffer to clone.
* @param {boolean} [isDeep] Specify a deep clone.
* @returns {Buffer} Returns the cloned buffer.
*/
function cloneBuffer(buffer, isDeep) {
if (isDeep) {
return buffer.slice();
}
var length = buffer.length,
result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
buffer.copy(result);
return result;
}
module.exports = cloneBuffer;
});
/**
* Copies the values of `source` to `array`.
*
* @private
* @param {Array} source The array to copy values from.
* @param {Array} [array=[]] The array to copy values to.
* @returns {Array} Returns `array`.
*/
function copyArray(source, array) {
var index = -1,
length = source.length;
array || (array = Array(length));
while (++index < length) {
array[index] = source[index];
}
return array;
}
var _copyArray = copyArray;
/**
* Copies own symbols of `source` to `object`.
*
* @private
* @param {Object} source The object to copy symbols from.
* @param {Object} [object={}] The object to copy symbols to.
* @returns {Object} Returns `object`.
*/
function copySymbols(source, object) {
return _copyObject(source, _getSymbols(source), object);
}
var _copySymbols = copySymbols;
/** Built-in value references. */
var getPrototype = _overArg(Object.getPrototypeOf, Object);
var _getPrototype = getPrototype;
/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeGetSymbols = Object.getOwnPropertySymbols;
/**
* Creates an array of the own and inherited enumerable symbols of `object`.
*
* @private
* @param {Object} object The object to query.
* @returns {Array} Returns the array of symbols.
*/
var getSymbolsIn = !nativeGetSymbols ? stubArray_1 : function(object) {
var result = [];
while (object) {
_arrayPush(result, _getSymbols(object));
object = _getPrototype(object);
}
return result;
};
var _getSymbolsIn = getSymbolsIn;
/**
* Copies own and inherited symbols of `source` to `object`.
*
* @private
* @param {Object} source The object to copy symbols from.
* @param {Object} [object={}] The object to copy symbols to.
* @returns {Object} Returns `object`.
*/
function copySymbolsIn(source, object) {
return _copyObject(source, _getSymbolsIn(source), object);
}
var _copySymbolsIn = copySymbolsIn;
/**
* Creates an array of own and inherited enumerable property names and
* symbols of `object`.
*
* @private
* @param {Object} object The object to query.
* @returns {Array} Returns the array of property names and symbols.
*/
function getAllKeysIn(object) {
return _baseGetAllKeys(object, keysIn_1, _getSymbolsIn);
}
var _getAllKeysIn = getAllKeysIn;
/** Used for built-in method references. */
var objectProto = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
/**
* Initializes an array clone.
*
* @private
* @param {Array} array The array to clone.
* @returns {Array} Returns the initialized clone.
*/
function initCloneArray(array) {
var length = array.length,
result = new array.constructor(length);
// Add properties assigned by `RegExp#exec`.
if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
result.index = array.index;
result.input = array.input;
}
return result;
}
var _initCloneArray = initCloneArray;
/**
* Creates a clone of `arrayBuffer`.
*
* @private
* @param {ArrayBuffer} arrayBuffer The array buffer to clone.
* @returns {ArrayBuffer} Returns the cloned array buffer.
*/
function cloneArrayBuffer(arrayBuffer) {
var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
new _Uint8Array(result).set(new _Uint8Array(arrayBuffer));
return result;
}
var _cloneArrayBuffer = cloneArrayBuffer;
/**
* Creates a clone of `dataView`.
*
* @private
* @param {Object} dataView The data view to clone.
* @param {boolean} [isDeep] Specify a deep clone.
* @returns {Object} Returns the cloned data view.
*/
function cloneDataView(dataView, isDeep) {
var buffer = isDeep ? _cloneArrayBuffer(dataView.buffer) : dataView.buffer;
return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
}
var _cloneDataView = cloneDataView;
/** Used to match `RegExp` flags from their coerced string values. */
var reFlags = /\w*$/;
/**
* Creates a clone of `regexp`.
*
* @private
* @param {Object} regexp The regexp to clone.
* @returns {Object} Returns the cloned regexp.
*/
function cloneRegExp(regexp) {
var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
result.lastIndex = regexp.lastIndex;
return result;
}
var _cloneRegExp = cloneRegExp;
/** Used to convert symbols to primitives and strings. */
var symbolProto = _Symbol ? _Symbol.prototype : undefined,
symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;
/**
* Creates a clone of the `symbol` object.
*
* @private
* @param {Object} symbol The symbol object to clone.
* @returns {Object} Returns the cloned symbol object.
*/
function cloneSymbol(symbol) {
return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
}
var _cloneSymbol = cloneSymbol;
/**
* Creates a clone of `typedArray`.
*
* @private
* @param {Object} typedArray The typed array to clone.
* @param {boolean} [isDeep] Specify a deep clone.
* @returns {Object} Returns the cloned typed array.
*/
function cloneTypedArray(typedArray, isDeep) {
var buffer = isDeep ? _cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
}
var _cloneTypedArray = cloneTypedArray;
/** `Object#toString` result references. */
var boolTag$1 = '[object Boolean]',
dateTag$1 = '[object Date]',
mapTag$2 = '[object Map]',
numberTag$1 = '[object Number]',
regexpTag$1 = '[object RegExp]',
setTag$2 = '[object Set]',
stringTag$1 = '[object String]',
symbolTag$1 = '[object Symbol]';
var arrayBufferTag$1 = '[object ArrayBuffer]',
dataViewTag$1 = '[object DataView]',
float32Tag$1 = '[object Float32Array]',
float64Tag$1 = '[object Float64Array]',
int8Tag$1 = '[object Int8Array]',
int16Tag$1 = '[object Int16Array]',
int32Tag$1 = '[object Int32Array]',
uint8Tag$1 = '[object Uint8Array]',
uint8ClampedTag$1 = '[object Uint8ClampedArray]',
uint16Tag$1 = '[object Uint16Array]',
uint32Tag$1 = '[object Uint32Array]';
/**
* Initializes an object clone based on its `toStringTag`.
*
* **Note:** This function only supports cloning values with tags of
* `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.
*
* @private
* @param {Object} object The object to clone.
* @param {string} tag The `toStringTag` of the object to clone.
* @param {boolean} [isDeep] Specify a deep clone.
* @returns {Object} Returns the initialized clone.
*/
function initCloneByTag(object, tag, isDeep) {
var Ctor = object.constructor;
switch (tag) {
case arrayBufferTag$1:
return _cloneArrayBuffer(object);
case boolTag$1:
case dateTag$1:
return new Ctor(+object);
case dataViewTag$1:
return _cloneDataView(object, isDeep);
case float32Tag$1: case float64Tag$1:
case int8Tag$1: case int16Tag$1: case int32Tag$1:
case uint8Tag$1: case uint8ClampedTag$1: case uint16Tag$1: case uint32Tag$1:
return _cloneTypedArray(object, isDeep);
case mapTag$2:
return new Ctor;
case numberTag$1:
case stringTag$1:
return new Ctor(object);
case regexpTag$1:
return _cloneRegExp(object);
case setTag$2:
return new Ctor;
case symbolTag$1:
return _cloneSymbol(object);
}
}
var _initCloneByTag = initCloneByTag;
/** Built-in value references. */
var objectCreate = Object.create;
/**
* The base implementation of `_.create` without support for assigning
* properties to the created object.
*
* @private
* @param {Object} proto The object to inherit from.
* @returns {Object} Returns the new object.
*/
var baseCreate = (function() {
function object() {}
return function(proto) {
if (!isObject_1(proto)) {
return {};
}
if (objectCreate) {
return objectCreate(proto);
}
object.prototype = proto;
var result = new object;
object.prototype = undefined;
return result;
};
}());
var _baseCreate = baseCreate;
/**
* Initializes an object clone.
*
* @private
* @param {Object} object The object to clone.
* @returns {Object} Returns the initialized clone.
*/
function initCloneObject(object) {
return (typeof object.constructor == 'function' && !_isPrototype(object))
? _baseCreate(_getPrototype(object))
: {};
}
var _initCloneObject = initCloneObject;
/** `Object#toString` result references. */
var mapTag$1 = '[object Map]';
/**
* The base implementation of `_.isMap` without Node.js optimizations.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a map, else `false`.
*/
function baseIsMap(value) {
return isObjectLike_1(value) && _getTag(value) == mapTag$1;
}
var _baseIsMap = baseIsMap;
/* Node.js helper references. */
var nodeIsMap = _nodeUtil && _nodeUtil.isMap;
/**
* Checks if `value` is classified as a `Map` object.
*
* @static
* @memberOf _
* @since 4.3.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a map, else `false`.
* @example
*
* _.isMap(new Map);
* // => true
*
* _.isMap(new WeakMap);
* // => false
*/
var isMap = nodeIsMap ? _baseUnary(nodeIsMap) : _baseIsMap;
var isMap_1 = isMap;
/** `Object#toString` result references. */
var setTag$1 = '[object Set]';
/**
* The base implementation of `_.isSet` without Node.js optimizations.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a set, else `false`.
*/
function baseIsSet(value) {
return isObjectLike_1(value) && _getTag(value) == setTag$1;
}
var _baseIsSet = baseIsSet;
/* Node.js helper references. */
var nodeIsSet = _nodeUtil && _nodeUtil.isSet;
/**
* Checks if `value` is classified as a `Set` object.
*
* @static
* @memberOf _
* @since 4.3.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a set, else `false`.
* @example
*
* _.isSet(new Set);
* // => true
*
* _.isSet(new WeakSet);
* // => false
*/
var isSet = nodeIsSet ? _baseUnary(nodeIsSet) : _baseIsSet;
var isSet_1 = isSet;
/** Used to compose bitmasks for cloning. */
var CLONE_DEEP_FLAG$1 = 1,
CLONE_FLAT_FLAG = 2,
CLONE_SYMBOLS_FLAG$1 = 4;
/** `Object#toString` result references. */
var argsTag = '[object Arguments]',
arrayTag = '[object Array]',
boolTag = '[object Boolean]',
dateTag = '[object Date]',
errorTag = '[object Error]',
funcTag = '[object Function]',
genTag = '[object GeneratorFunction]',
mapTag = '[object Map]',
numberTag = '[object Number]',
objectTag = '[object Object]',
regexpTag = '[object RegExp]',
setTag = '[object Set]',
stringTag = '[object String]',
symbolTag = '[object Symbol]',
weakMapTag = '[object WeakMap]';
var arrayBufferTag = '[object ArrayBuffer]',
dataViewTag = '[object DataView]',
float32Tag = '[object Float32Array]',
float64Tag = '[object Float64Array]',
int8Tag = '[object Int8Array]',
int16Tag = '[object Int16Array]',
int32Tag = '[object Int32Array]',
uint8Tag = '[object Uint8Array]',
uint8ClampedTag = '[object Uint8ClampedArray]',
uint16Tag = '[object Uint16Array]',
uint32Tag = '[object Uint32Array]';
/** Used to identify `toStringTag` values supported by `_.clone`. */
var cloneableTags = {};
cloneableTags[argsTag] = cloneableTags[arrayTag] =
cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =
cloneableTags[boolTag] = cloneableTags[dateTag] =
cloneableTags[float32Tag] = cloneableTags[float64Tag] =
cloneableTags[int8Tag] = cloneableTags[int16Tag] =
cloneableTags[int32Tag] = cloneableTags[mapTag] =
cloneableTags[numberTag] = cloneableTags[objectTag] =
cloneableTags[regexpTag] = cloneableTags[setTag] =
cloneableTags[stringTag] = cloneableTags[symbolTag] =
cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
cloneableTags[errorTag] = cloneableTags[funcTag] =
cloneableTags[weakMapTag] = false;
/**
* The base implementation of `_.clone` and `_.cloneDeep` which tracks
* traversed objects.
*
* @private
* @param {*} value The value to clone.
* @param {boolean} bitmask The bitmask flags.
* 1 - Deep clone
* 2 - Flatten inherited properties
* 4 - Clone symbols
* @param {Function} [customizer] The function to customize cloning.
* @param {string} [key] The key of `value`.
* @param {Object} [object] The parent object of `value`.
* @param {Object} [stack] Tracks traversed objects and their clone counterparts.
* @returns {*} Returns the cloned value.
*/
function baseClone(value, bitmask, customizer, key, object, stack) {
var result,
isDeep = bitmask & CLONE_DEEP_FLAG$1,
isFlat = bitmask & CLONE_FLAT_FLAG,
isFull = bitmask & CLONE_SYMBOLS_FLAG$1;
if (customizer) {
result = object ? customizer(value, key, object, stack) : customizer(value);
}
if (result !== undefined) {
return result;
}
if (!isObject_1(value)) {
return value;
}
var isArr = isArray_1(value);
if (isArr) {
result = _initCloneArray(value);
if (!isDeep) {
return _copyArray(value, result);
}
} else {
var tag = _getTag(value),
isFunc = tag == funcTag || tag == genTag;
if (isBuffer_1(value)) {
return _cloneBuffer(value, isDeep);
}
if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
result = (isFlat || isFunc) ? {} : _initCloneObject(value);
if (!isDeep) {
return isFlat
? _copySymbolsIn(value, _baseAssignIn(result, value))
: _copySymbols(value, _baseAssign(result, value));
}
} else {
if (!cloneableTags[tag]) {
return object ? value : {};
}
result = _initCloneByTag(value, tag, isDeep);
}
}
// Check for circular references and return its corresponding clone.
stack || (stack = new _Stack);
var stacked = stack.get(value);
if (stacked) {
return stacked;
}
stack.set(value, result);
if (isSet_1(value)) {
value.forEach(function(subValue) {
result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));
});
} else if (isMap_1(value)) {
value.forEach(function(subValue, key) {
result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));
});
}
var keysFunc = isFull
? (isFlat ? _getAllKeysIn : _getAllKeys)
: (isFlat ? keysIn_1 : keys_1);
var props = isArr ? undefined : keysFunc(value);
_arrayEach(props || value, function(subValue, key) {
if (props) {
key = subValue;
subValue = value[key];
}
// Recursively populate clone (susceptible to call stack limits).
_assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
});
return result;
}
var _baseClone = baseClone;
/** Used to compose bitmasks for cloning. */
var CLONE_DEEP_FLAG = 1,
CLONE_SYMBOLS_FLAG = 4;
/**
* This method is like `_.clone` except that it recursively clones `value`.
*
* @static
* @memberOf _
* @since 1.0.0
* @category Lang
* @param {*} value The value to recursively clone.
* @returns {*} Returns the deep cloned value.
* @see _.clone
* @example
*
* var objects = [{ 'a': 1 }, { 'b': 2 }];
*
* var deep = _.cloneDeep(objects);
* console.log(deep[0] === objects[0]);
* // => false
*/
function cloneDeep(value) {
return _baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);
}
var cloneDeep_1 = cloneDeep;
/**
* Observes all known project index files and keeps their frontmatters
* in sync with the corresponding store.
*
* Store updates are written to disk, and file edits are set to the store.
*
* When index files have invalid frontmatter, e.g. you're mid-edit, updates
* are ignored. This class must have `destroy()` called on plugin unload
* to avoid leaking store subscriptions.
*/
class IndexMetadataObserver {
constructor(app) {
this.ignoreNextMetadataUpdate = true;
this.lastKnownMetadataState = {};
this.vault = app.vault;
this.cache = app.metadataCache;
// Load project/index file paths
this.unsubscribeSettings = pluginSettings.subscribe((settings) => {
const indexPaths = [];
Object.keys(settings.projects).forEach((projectPath) => {
const project = settings.projects[projectPath];
indexPaths.push({
projectPath,
indexPath: indexFilePath(project),
});
});
this.watchedIndexPaths = indexPaths;
// Load existing projects' metadata
const allMetadata = {};
this.watchedIndexPaths.forEach((paths) => {
const metadata = this.cache.getCache(paths.indexPath);
// Sometimes this can be undefined, especially if you're creating a new project.
// In that case, we'll get the metadata event later, so it's okay to skip it here.
if (metadata) {
const frontmatter = metadata.frontmatter;
allMetadata[paths.projectPath] = filterMetadata(frontmatter);
}
});
this.lastKnownMetadataState = cloneDeep_1(allMetadata);
if (this.unsubscribeMetadata) {
this.ignoreNextMetadataUpdate = true;
}
projectMetadata.set(allMetadata);
});
// Pass store metadata changes (ie longform app changes)
// back to the index file
this.unsubscribeMetadata = projectMetadata.subscribe((value) => {
if (!this.ignoreNextMetadataUpdate) {
this.metadataStoreChanged(value);
}
this.ignoreNextMetadataUpdate = false;
this.lastKnownMetadataState = cloneDeep_1(value);
});
}
destroy() {
this.unsubscribeSettings();
this.unsubscribeMetadata();
}
metadataCacheChanged(file) {
// Is this a file we're watching?
const paths = this.watchedIndexPaths.find((p) => p.indexPath === file.path);
if (paths) {
const fileMetadata = this.cache.getFileCache(file);
// Ignore missing or invalid YAML results, file likely mid-edit
if (!fileMetadata || !fileMetadata.frontmatter) {
return;
}
const newProjectMetadata = fileMetadata.frontmatter;
this.ignoreNextMetadataUpdate = true;
projectMetadata.update((value) => {
const v = value;
v[paths.projectPath] = filterMetadata(newProjectMetadata);
this.lastKnownMetadataState = cloneDeep_1(v);
return v;
});
}
}
metadataStoreChanged(value) {
const lastKnownProjectPaths = Object.keys(this.lastKnownMetadataState);
Object.keys(value).forEach((projectPath) => {
const isKnownPath = lastKnownProjectPaths.contains(projectPath);
const paths = this.watchedIndexPaths.find((p) => p.projectPath === projectPath);
const newIndexMetadata = value[projectPath];
const isNew = !isKnownPath ||
!isEqual_1(this.lastKnownMetadataState[projectPath], newIndexMetadata);
if (paths && isNew) {
const contents = indexBodyFor(newIndexMetadata);
this.vault.adapter.write(paths.indexPath, contents);
}
});
this.lastKnownMetadataState = cloneDeep_1(value);
}
}
function filterMetadata(metadata) {
// Ideally TypeScript would do this for me, but that seems to be impossible.
// Instead, we have to manually strip out anything we know isn't a property of the type.
return {
version: metadata.version,
drafts: metadata.drafts,
};
}
var DraftsMembership;
(function (DraftsMembership) {
DraftsMembership[DraftsMembership["Draft"] = 0] = "Draft";
DraftsMembership[DraftsMembership["Scene"] = 1] = "Scene";
DraftsMembership[DraftsMembership["None"] = 2] = "None";
})(DraftsMembership || (DraftsMembership = {}));
function membership(abstractFile, draftsPath) {
if (abstractFile instanceof obsidian.TFolder &&
abstractFile.parent &&
abstractFile.parent.path === draftsPath) {
return DraftsMembership.Draft;
}
else if (abstractFile instanceof obsidian.TFile &&
abstractFile.parent &&
abstractFile.parent.parent &&
abstractFile.parent.parent.path === draftsPath) {
return DraftsMembership.Scene;
}
return DraftsMembership.None;
}
class FolderObserver {
constructor(app) {
this.vault = app.vault;
// Load project paths
this.unsubscribeSettings = pluginSettings.subscribe((settings) => {
this.watchedDraftFolders = Object.keys(settings.projects).map((projectPath) => ({
draftsPath: obsidian.normalizePath(`${projectPath}/${settings.projects[projectPath].draftsPath}`),
projectPath,
}));
});
}
loadProjects(renameInfo) {
const toStore = {};
this.watchedDraftFolders.forEach(({ draftsPath, projectPath }) => {
toStore[projectPath] = {};
const folder = this.vault.getAbstractFileByPath(draftsPath);
if (!(folder instanceof obsidian.TFolder)) {
return;
}
// Recurse all watched projects' draft folders.
// Because recursion, we know drafts will be encountered before their children.
obsidian.Vault.recurseChildren(folder, (abstractFile) => {
const status = membership(abstractFile, draftsPath);
if (status === DraftsMembership.Draft) {
toStore[projectPath][abstractFile.name] = [];
// We only care about folders if they're draft folders
}
else if (status === DraftsMembership.Scene &&
abstractFile instanceof obsidian.TFile) {
// We only care about files if they're members of a draft
toStore[projectPath][abstractFile.parent.name].push(abstractFile.basename);
}
});
});
projectMetadata.update((metadata) => {
// Sync files on disk with scenes in metadata;
// Existing files are sorted by scene order,
// new ones are added to the bottom.
let newMetadata = cloneDeep_1(metadata);
// javascript is stupid.
// eslint-disable-next-line
const functionalSplice = (arr, index, value) => {
const v = [...arr];
v.splice(index, 1, value);
return v;
};
const cleanlyReplaceDraft = (meta, _projectPath, _draftIndex, _draft) => (Object.assign(Object.assign({}, meta), { [_projectPath]: Object.assign(Object.assign({}, meta[_projectPath]), { drafts: functionalSplice(newMetadata[_projectPath].drafts, _draftIndex, _draft) }) }));
Object.keys(toStore).forEach((projectPath) => {
// Handle cases where the metadata cache hasn't caught up to disk yet
// and thus no project exists there at all.
if (!newMetadata[projectPath]) {
return;
}
// If a draft has been renamed, sub in the renamed draft in metadata
if (renameInfo && renameInfo.newFile instanceof obsidian.TFolder) {
const oldFolder = renameInfo.oldPath.split("/").slice(-1)[0];
const newFolder = renameInfo.newFile.name;
const draftIndex = newMetadata[projectPath].drafts.findIndex((d) => d.folder === oldFolder);
if (draftIndex >= 0) {
const draft = newMetadata[projectPath].drafts[draftIndex];
newMetadata = cleanlyReplaceDraft(newMetadata, projectPath, draftIndex, Object.assign(Object.assign({}, draft), { folder: newFolder, name: newFolder }));
}
}
const metadataLookup = buildDraftsLookup(newMetadata[projectPath].drafts);
Object.keys(toStore[projectPath]).forEach((draftPath) => {
const metadataDraft = metadataLookup[draftPath];
const metadataScenes = metadataDraft ? metadataDraft.scenes : [];
const fileScenes = toStore[projectPath][draftPath];
const existingScenes = [];
metadataScenes.forEach((s) => {
if (fileScenes.contains(s)) {
// Retain existing scene
existingScenes.push(s);
}
else if (renameInfo &&
renameInfo.newFile instanceof obsidian.TFile &&
fileScenes.contains(renameInfo.newFile.basename)) {
// Swap in a renamed file if it matches the full path
const f = this.watchedDraftFolders.find((f) => f.projectPath === projectPath);
if (f &&
obsidian.normalizePath(`${f.draftsPath}/${draftPath}/${s}.md`) ===
renameInfo.oldPath) {
existingScenes.push(renameInfo.newFile.basename);
}
}
});
const newScenes = fileScenes.filter((s) => !existingScenes.contains(s));
const scenes = [...existingScenes, ...newScenes];
const draftIndex = newMetadata[projectPath].drafts.findIndex((d) => d.folder === draftPath);
if (draftIndex >= 0) {
const draft = newMetadata[projectPath].drafts[draftIndex];
newMetadata = cleanlyReplaceDraft(newMetadata, projectPath, draftIndex, Object.assign(Object.assign({}, draft), { scenes }));
}
else {
const draft = {
name: draftPath,
folder: draftPath,
scenes,
};
newMetadata = cleanlyReplaceDraft(newMetadata, projectPath, newMetadata[projectPath].drafts.length, draft);
}
});
// Delete any orphaned drafts that are in metadata but no longer on disk
const fileDrafts = Object.keys(toStore[projectPath]);
newMetadata = Object.assign(Object.assign({}, newMetadata), { [projectPath]: Object.assign(Object.assign({}, newMetadata[projectPath]), { drafts: newMetadata[projectPath].drafts.filter((d) => fileDrafts.contains(d.folder)) }) });
});
return newMetadata;
});
}
destroy() {
this.unsubscribeSettings();
}
fileCreated(abstractFile) {
const status = this.anyMembership(abstractFile);
if (status === DraftsMembership.None) {
return;
}
// We could do this more intelligently by making minimal edits to the store,
// but for now let's just recalculate it. It's not clear to me yet how expensive
// recursing children is.
this.loadProjects();
}
fileDeleted(abstractFile) {
// We can't do normal status test here because a deleted file's parent is null.
const reload = !!this.watchedDraftFolders.find(({ draftsPath }) => abstractFile.path.startsWith(draftsPath));
if (!reload) {
return;
}
// We could do this more intelligently by making minimal edits to the store,
// but for now let's just recalculate it. It's not clear to me yet how expensive
// recursing children is.
this.loadProjects();
}
fileRenamed(abstractFile, oldPath) {
const newPath = abstractFile.path;
// First handle any project renames, as those happen in settings
const folder = this.watchedDraftFolders.find((f) => f.projectPath === oldPath);
if (folder) {
console.log("[Longform] A project has been renamed; updating caches…");
pluginSettings.update((s) => {
const projects = s.projects;
const project = s.projects[oldPath];
project.path = newPath;
projects[newPath] = project;
delete s.projects[oldPath];
let selectedProject = s.selectedProject;
if (selectedProject === oldPath) {
selectedProject = newPath;
}
const newSettings = Object.assign(Object.assign({}, s), { selectedProject,
projects });
return newSettings;
});
currentProjectPath.update((p) => {
if (p === oldPath) {
return newPath;
}
return p;
});
projectMetadata.update((m) => {
const project = m[oldPath];
m[newPath] = project;
delete m[oldPath];
return m;
});
return;
}
const status = this.anyMembership(abstractFile, oldPath);
if (status === DraftsMembership.None) {
return;
}
// If the current draft was renamed, update that store first.
if (status === DraftsMembership.Draft &&
oldPath.endsWith(get_store_value(currentDraftPath))) {
currentDraftPath.set(abstractFile.name);
}
// We could do this more intelligently by making minimal edits to the store,
// but for now let's just recalculate it. It's not clear to me yet how expensive
// recursing children is.
this.loadProjects({ newFile: abstractFile, oldPath });
}
anyMembership(abstractFile, oldPath) {
for (const { draftsPath } of this.watchedDraftFolders) {
if (oldPath && oldPath.startsWith(draftsPath)) {
return oldPath.endsWith(".md")
? DraftsMembership.Scene
: DraftsMembership.Draft;
}
const status = membership(abstractFile, draftsPath);
if (status !== DraftsMembership.None) {
return status;
}
}
return DraftsMembership.None;
}
}
class LongformSettingsTab extends obsidian.PluginSettingTab {
constructor(app, plugin) {
super(app, plugin);
this.plugin = plugin;
}
display() {
const { containerEl } = this;
containerEl.empty();
containerEl.createEl("h2", { text: "Longform" });
containerEl.createEl("p", {}, (el) => {
el.innerHTML =
'Longform written and maintained by <a href="https://kevinbarrett.org">Kevin Barrett</a>.';
});
containerEl.createEl("p", {}, (el) => {
el.innerHTML =
'Read the source code and report issues at <a href="https://github.com/kevboh/longform">https://github.com/kevboh/longform</a>.';
});
containerEl.createEl("p", {}, (el) => {
el.innerHTML =
'Icon made by <a href="https://www.flaticon.com/authors/zlatko-najdenovski" title="Zlatko Najdenovski">Zlatko Najdenovski</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a>.';
});
containerEl.createEl("hr");
containerEl.createEl("p", {
text: "If you find Longform to be misbehaving (logging errors in console, not syncing changes to index files) you can try resetting tracked projects. This will cause Longform to “forget” that various project folders in your vault should be watched and managed by Longform. You can then re-mark those folders as Longform projects by right-clicking them in the file explorer. You will not lose any notes.",
});
containerEl.createEl("button", {
text: "Untrack All Projects",
title: "Click to have Longform untrack all projects.",
}, (el) => {
el.classList.add("longform-settings-destructive-button");
el.onclick = () => __awaiter(this, void 0, void 0, function* () {
console.log("[Longform] Resetting plugin data to: ", DEFAULT_SETTINGS);
pluginSettings.set(DEFAULT_SETTINGS);
currentProjectPath.set(null);
currentDraftPath.set(null);
this.plugin.cachedSettings = get_store_value(pluginSettings);
yield this.plugin.saveSettings();
});
});
}
}
const LONGFORM_LEAF_CLASS = "longform-leaf";
// TODO: Try and abstract away more logic from actual plugin hooks here
class LongformPlugin extends obsidian.Plugin {
onload() {
return __awaiter(this, void 0, void 0, function* () {
console.log(`[Longform] Starting Longform ${this.manifest.version}`);
obsidian.addIcon(ICON_NAME, ICON_SVG);
this.registerView(VIEW_TYPE_LONGFORM_EXPLORER, (leaf) => new ExplorerPane(leaf));
this.registerEvent(this.app.workspace.on("file-menu", (menu, file) => {
if (!(file instanceof obsidian.TFolder)) {
return;
}
if (isLongformProject(file.path, this.cachedSettings)) {
menu.addItem((item) => {
item
.setTitle(`Unmark as Longform Project`)
.setIcon(ICON_NAME)
.onClick(() => __awaiter(this, void 0, void 0, function* () {
pluginSettings.update((settings) => {
return removeProject(file.path, settings);
});
// this.settings = removeProject(file.path, this.settings);
yield this.saveSettings();
new obsidian.Notice(`${file.path} is no longer a Longform project.`);
}));
});
}
else {
menu.addItem((item) => {
item
.setTitle(`Mark as Longform Project`)
.setIcon(ICON_NAME)
.onClick(() => __awaiter(this, void 0, void 0, function* () {
this.promptToAddProject(file.path);
}));
});
}
}));
// Settings
this.unsubscribeSettings = pluginSettings.subscribe((value) => {
this.cachedSettings = value;
});
yield this.loadSettings();
this.addSettingTab(new LongformSettingsTab(this.app, this));
this.app.workspace.onLayoutReady(this.postLayoutInit.bind(this));
// Track active file
activeFile.set(this.app.workspace.getActiveFile());
this.registerEvent(this.app.workspace.on("active-leaf-change", (leaf) => {
if (leaf.view instanceof obsidian.FileView) {
activeFile.set(leaf.view.file);
}
}));
this.addCommand({
id: "longform-show-view",
name: "Open Longform Pane",
callback: () => {
this.initLeaf();
const leaf = this.app.workspace
.getLeavesOfType(VIEW_TYPE_LONGFORM_EXPLORER)
.first();
if (leaf) {
this.app.workspace.revealLeaf(leaf);
}
},
});
// Dynamically style longform scenes
this.registerEvent(this.app.workspace.on("layout-change", () => {
this.app.workspace.getLeavesOfType("markdown").forEach((leaf) => {
if (leaf.view instanceof obsidian.FileView) {
if (isInLongformProject(leaf.view.file.path, this.cachedSettings)) {
leaf.view.containerEl.classList.add(LONGFORM_LEAF_CLASS);
}
else {
leaf.view.containerEl.classList.remove(LONGFORM_LEAF_CLASS);
}
}
// @ts-ignore
const leafId = leaf.id;
if (leafId) {
leaf.view.containerEl.dataset.leafId = leafId;
}
});
}));
});
}
onunload() {
this.metadataObserver.destroy();
this.foldersObserver.destroy();
this.unsubscribeSettings();
this.unsubscribeCurrentProjectPath();
this.unsubscribeCurrentDraftPath();
this.app.workspace
.getLeavesOfType(VIEW_TYPE_LONGFORM_EXPLORER)
.forEach((leaf) => leaf.detach());
}
loadSettings() {
return __awaiter(this, void 0, void 0, function* () {
const settings = Object.assign({}, DEFAULT_SETTINGS, yield this.loadData());
pluginSettings.set(settings);
currentDraftPath.set(settings.selectedDraft);
currentProjectPath.set(settings.selectedProject);
});
}
saveSettings() {
return __awaiter(this, void 0, void 0, function* () {
yield this.saveData(this.cachedSettings);
});
}
promptToAddProject(path) {
const modal = new AddProjectModal(this.app, this, path);
modal.open();
}
markPathAsProject(path, project) {
return __awaiter(this, void 0, void 0, function* () {
// Conditionally create index file and drafts folder
const indexFilePath = obsidian.normalizePath(`${path}/${project.indexFile}.md`);
let indexFile = this.app.vault.getAbstractFileByPath(indexFilePath);
if (!indexFile) {
const contents = indexBodyFor(EmptyIndexFileMetadata);
indexFile = yield this.app.vault.create(indexFilePath, contents);
}
const draftsFolderPath = obsidian.normalizePath(`${path}/${project.draftsPath}`);
const draftsFolder = this.app.vault.getAbstractFileByPath(draftsFolderPath);
if (!draftsFolder) {
yield this.app.vault.createFolder(draftsFolderPath);
const defaultDrafts = EmptyIndexFileMetadata.drafts;
if (defaultDrafts.length > 0) {
const firstDraftFolderName = defaultDrafts[0].folder;
const firstDraftFolderPath = obsidian.normalizePath(`${draftsFolderPath}/${firstDraftFolderName}`);
yield this.app.vault.createFolder(firstDraftFolderPath);
}
}
// Add to tracked projects
pluginSettings.update((settings) => {
return addProject(path, project, settings);
});
yield this.saveSettings();
this.foldersObserver.loadProjects();
// If this is the only project, make it current
const projects = Object.keys(get_store_value(pluginSettings).projects);
if (projects.length === 1) {
currentProjectPath.set(projects[0]);
}
new obsidian.Notice(`${path} is now a Longform project.`);
});
}
postLayoutInit() {
this.metadataObserver = new IndexMetadataObserver(this.app);
this.foldersObserver = new FolderObserver(this.app);
this.watchProjects();
this.unsubscribeCurrentProjectPath = currentProjectPath.subscribe((selectedProject) => __awaiter(this, void 0, void 0, function* () {
if (!get_store_value(initialized)) {
return;
}
pluginSettings.update((s) => (Object.assign(Object.assign({}, s), { selectedProject })));
// Force cached settings update immediately for save to work
this.cachedSettings = get_store_value(pluginSettings);
yield this.saveSettings();
}));
this.unsubscribeCurrentDraftPath = currentDraftPath.subscribe((selectedDraft) => __awaiter(this, void 0, void 0, function* () {
if (!get_store_value(initialized)) {
return;
}
pluginSettings.update((s) => (Object.assign(Object.assign({}, s), { selectedDraft })));
// Force cached settings update immediately for save to work
// test
this.cachedSettings = get_store_value(pluginSettings);
yield this.saveSettings();
}));
this.initLeaf();
initialized.set(true);
}
initLeaf() {
if (this.app.workspace.getLeavesOfType(VIEW_TYPE_LONGFORM_EXPLORER).length) {
return;
}
this.app.workspace.getLeftLeaf(false).setViewState({
type: VIEW_TYPE_LONGFORM_EXPLORER,
});
}
watchProjects() {
this.foldersObserver.loadProjects();
this.registerEvent(this.app.vault.on("create", this.foldersObserver.fileCreated.bind(this.foldersObserver)));
this.registerEvent(this.app.vault.on("delete", this.foldersObserver.fileDeleted.bind(this.foldersObserver)));
this.registerEvent(this.app.vault.on("rename", this.foldersObserver.fileRenamed.bind(this.foldersObserver)));
this.registerEvent(this.app.metadataCache.on("changed", this.metadataObserver.metadataCacheChanged.bind(this.metadataObserver)));
console.log(`[Longform] Loaded and watching projects.`);
}
}
module.exports = LongformPlugin;