/*
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());
    });
}

/**
 * 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;

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;

/**
 * Gets the timestamp of the number of milliseconds that have elapsed since
 * the Unix epoch (1 January 1970 00:00:00 UTC).
 *
 * @static
 * @memberOf _
 * @since 2.4.0
 * @category Date
 * @returns {number} Returns the timestamp.
 * @example
 *
 * _.defer(function(stamp) {
 *   console.log(_.now() - stamp);
 * }, _.now());
 * // => Logs the number of milliseconds it took for the deferred invocation.
 */
var now = function() {
  return _root.Date.now();
};

var now_1 = now;

/** Used to match a single whitespace character. */
var reWhitespace = /\s/;

/**
 * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace
 * character of `string`.
 *
 * @private
 * @param {string} string The string to inspect.
 * @returns {number} Returns the index of the last non-whitespace character.
 */
function trimmedEndIndex(string) {
  var index = string.length;

  while (index-- && reWhitespace.test(string.charAt(index))) {}
  return index;
}

var _trimmedEndIndex = trimmedEndIndex;

/** Used to match leading whitespace. */
var reTrimStart = /^\s+/;

/**
 * The base implementation of `_.trim`.
 *
 * @private
 * @param {string} string The string to trim.
 * @returns {string} Returns the trimmed string.
 */
function baseTrim(string) {
  return string
    ? string.slice(0, _trimmedEndIndex(string) + 1).replace(reTrimStart, '')
    : string;
}

var _baseTrim = baseTrim;

/** Built-in value references. */
var Symbol$1 = _root.Symbol;

var _Symbol = Symbol$1;

/** Used for built-in method references. */
var objectProto$f = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty$c = objectProto$f.hasOwnProperty;

/**
 * Used to resolve the
 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
 * of values.
 */
var nativeObjectToString$1 = objectProto$f.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$c.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$e = Object.prototype;

/**
 * Used to resolve the
 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
 * of values.
 */
var nativeObjectToString = objectProto$e.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 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 symbolTag$3 = '[object Symbol]';

/**
 * Checks if `value` is classified as a `Symbol` primitive or object.
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
 * @example
 *
 * _.isSymbol(Symbol.iterator);
 * // => true
 *
 * _.isSymbol('abc');
 * // => false
 */
function isSymbol(value) {
  return typeof value == 'symbol' ||
    (isObjectLike_1(value) && _baseGetTag(value) == symbolTag$3);
}

var isSymbol_1 = isSymbol;

/** Used as references for various `Number` constants. */
var NAN = 0 / 0;

/** Used to detect bad signed hexadecimal string values. */
var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;

/** Used to detect binary string values. */
var reIsBinary = /^0b[01]+$/i;

/** Used to detect octal string values. */
var reIsOctal = /^0o[0-7]+$/i;

/** Built-in method references without a dependency on `root`. */
var freeParseInt = parseInt;

/**
 * Converts `value` to a number.
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to process.
 * @returns {number} Returns the number.
 * @example
 *
 * _.toNumber(3.2);
 * // => 3.2
 *
 * _.toNumber(Number.MIN_VALUE);
 * // => 5e-324
 *
 * _.toNumber(Infinity);
 * // => Infinity
 *
 * _.toNumber('3.2');
 * // => 3.2
 */
function toNumber(value) {
  if (typeof value == 'number') {
    return value;
  }
  if (isSymbol_1(value)) {
    return NAN;
  }
  if (isObject_1(value)) {
    var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
    value = isObject_1(other) ? (other + '') : other;
  }
  if (typeof value != 'string') {
    return value === 0 ? value : +value;
  }
  value = _baseTrim(value);
  var isBinary = reIsBinary.test(value);
  return (isBinary || reIsOctal.test(value))
    ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
    : (reIsBadHex.test(value) ? NAN : +value);
}

var toNumber_1 = toNumber;

/** Error message constants. */
var FUNC_ERROR_TEXT$1 = 'Expected a function';

/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax$1 = Math.max,
    nativeMin = Math.min;

/**
 * Creates a debounced function that delays invoking `func` until after `wait`
 * milliseconds have elapsed since the last time the debounced function was
 * invoked. The debounced function comes with a `cancel` method to cancel
 * delayed `func` invocations and a `flush` method to immediately invoke them.
 * Provide `options` to indicate whether `func` should be invoked on the
 * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
 * with the last arguments provided to the debounced function. Subsequent
 * calls to the debounced function return the result of the last `func`
 * invocation.
 *
 * **Note:** If `leading` and `trailing` options are `true`, `func` is
 * invoked on the trailing edge of the timeout only if the debounced function
 * is invoked more than once during the `wait` timeout.
 *
 * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
 * until to the next tick, similar to `setTimeout` with a timeout of `0`.
 *
 * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
 * for details over the differences between `_.debounce` and `_.throttle`.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Function
 * @param {Function} func The function to debounce.
 * @param {number} [wait=0] The number of milliseconds to delay.
 * @param {Object} [options={}] The options object.
 * @param {boolean} [options.leading=false]
 *  Specify invoking on the leading edge of the timeout.
 * @param {number} [options.maxWait]
 *  The maximum time `func` is allowed to be delayed before it's invoked.
 * @param {boolean} [options.trailing=true]
 *  Specify invoking on the trailing edge of the timeout.
 * @returns {Function} Returns the new debounced function.
 * @example
 *
 * // Avoid costly calculations while the window size is in flux.
 * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
 *
 * // Invoke `sendMail` when clicked, debouncing subsequent calls.
 * jQuery(element).on('click', _.debounce(sendMail, 300, {
 *   'leading': true,
 *   'trailing': false
 * }));
 *
 * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
 * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
 * var source = new EventSource('/stream');
 * jQuery(source).on('message', debounced);
 *
 * // Cancel the trailing debounced invocation.
 * jQuery(window).on('popstate', debounced.cancel);
 */
function debounce$1(func, wait, options) {
  var lastArgs,
      lastThis,
      maxWait,
      result,
      timerId,
      lastCallTime,
      lastInvokeTime = 0,
      leading = false,
      maxing = false,
      trailing = true;

  if (typeof func != 'function') {
    throw new TypeError(FUNC_ERROR_TEXT$1);
  }
  wait = toNumber_1(wait) || 0;
  if (isObject_1(options)) {
    leading = !!options.leading;
    maxing = 'maxWait' in options;
    maxWait = maxing ? nativeMax$1(toNumber_1(options.maxWait) || 0, wait) : maxWait;
    trailing = 'trailing' in options ? !!options.trailing : trailing;
  }

  function invokeFunc(time) {
    var args = lastArgs,
        thisArg = lastThis;

    lastArgs = lastThis = undefined;
    lastInvokeTime = time;
    result = func.apply(thisArg, args);
    return result;
  }

  function leadingEdge(time) {
    // Reset any `maxWait` timer.
    lastInvokeTime = time;
    // Start the timer for the trailing edge.
    timerId = setTimeout(timerExpired, wait);
    // Invoke the leading edge.
    return leading ? invokeFunc(time) : result;
  }

  function remainingWait(time) {
    var timeSinceLastCall = time - lastCallTime,
        timeSinceLastInvoke = time - lastInvokeTime,
        timeWaiting = wait - timeSinceLastCall;

    return maxing
      ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)
      : timeWaiting;
  }

  function shouldInvoke(time) {
    var timeSinceLastCall = time - lastCallTime,
        timeSinceLastInvoke = time - lastInvokeTime;

    // Either this is the first call, activity has stopped and we're at the
    // trailing edge, the system time has gone backwards and we're treating
    // it as the trailing edge, or we've hit the `maxWait` limit.
    return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
      (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
  }

  function timerExpired() {
    var time = now_1();
    if (shouldInvoke(time)) {
      return trailingEdge(time);
    }
    // Restart the timer.
    timerId = setTimeout(timerExpired, remainingWait(time));
  }

  function trailingEdge(time) {
    timerId = undefined;

    // Only invoke if we have `lastArgs` which means `func` has been
    // debounced at least once.
    if (trailing && lastArgs) {
      return invokeFunc(time);
    }
    lastArgs = lastThis = undefined;
    return result;
  }

  function cancel() {
    if (timerId !== undefined) {
      clearTimeout(timerId);
    }
    lastInvokeTime = 0;
    lastArgs = lastCallTime = lastThis = timerId = undefined;
  }

  function flush() {
    return timerId === undefined ? result : trailingEdge(now_1());
  }

  function debounced() {
    var time = now_1(),
        isInvoking = shouldInvoke(time);

    lastArgs = arguments;
    lastThis = this;
    lastCallTime = time;

    if (isInvoking) {
      if (timerId === undefined) {
        return leadingEdge(lastCallTime);
      }
      if (maxing) {
        // Handle invocations in a tight loop.
        clearTimeout(timerId);
        timerId = setTimeout(timerExpired, wait);
        return invokeFunc(lastCallTime);
      }
    }
    if (timerId === undefined) {
      timerId = setTimeout(timerExpired, wait);
    }
    return result;
  }
  debounced.cancel = cancel;
  debounced.flush = flush;
  return debounced;
}

var debounce_1 = debounce$1;

/**
 * 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;

/** Used to match property names within property paths. */
var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
    reIsPlainProp = /^\w*$/;

/**
 * Checks if `value` is a property name and not a property path.
 *
 * @private
 * @param {*} value The value to check.
 * @param {Object} [object] The object to query keys on.
 * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
 */
function isKey(value, object) {
  if (isArray_1(value)) {
    return false;
  }
  var type = typeof value;
  if (type == 'number' || type == 'symbol' || type == 'boolean' ||
      value == null || isSymbol_1(value)) {
    return true;
  }
  return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
    (object != null && value in Object(object));
}

var _isKey = isKey;

/** `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$2 = Function.prototype;

/** Used to resolve the decompiled source of functions. */
var funcToString$2 = funcProto$2.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$2.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$1 = Function.prototype,
    objectProto$d = Object.prototype;

/** Used to resolve the decompiled source of functions. */
var funcToString$1 = funcProto$1.toString;

/** Used to check objects for own properties. */
var hasOwnProperty$b = objectProto$d.hasOwnProperty;

/** Used to detect if a method is native. */
var reIsNative = RegExp('^' +
  funcToString$1.call(hasOwnProperty$b).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 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$c = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty$a = objectProto$c.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$a.call(data, key) ? data[key] : undefined;
}

var _hashGet = hashGet;

/** Used for built-in method references. */
var objectProto$b = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty$9 = objectProto$b.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$9.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 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;

/* Built-in method references that are verified to be native. */
var Map$1 = _getNative(_root, 'Map');

var _Map = Map$1;

/**
 * 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;

/** Error message constants. */
var FUNC_ERROR_TEXT = 'Expected a function';

/**
 * Creates a function that memoizes the result of `func`. If `resolver` is
 * provided, it determines the cache key for storing the result based on the
 * arguments provided to the memoized function. By default, the first argument
 * provided to the memoized function is used as the map cache key. The `func`
 * is invoked with the `this` binding of the memoized function.
 *
 * **Note:** The cache is exposed as the `cache` property on the memoized
 * function. Its creation may be customized by replacing the `_.memoize.Cache`
 * constructor with one whose instances implement the
 * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
 * method interface of `clear`, `delete`, `get`, `has`, and `set`.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Function
 * @param {Function} func The function to have its output memoized.
 * @param {Function} [resolver] The function to resolve the cache key.
 * @returns {Function} Returns the new memoized function.
 * @example
 *
 * var object = { 'a': 1, 'b': 2 };
 * var other = { 'c': 3, 'd': 4 };
 *
 * var values = _.memoize(_.values);
 * values(object);
 * // => [1, 2]
 *
 * values(other);
 * // => [3, 4]
 *
 * object.a = 2;
 * values(object);
 * // => [1, 2]
 *
 * // Modify the result cache.
 * values.cache.set(object, ['a', 'b']);
 * values(object);
 * // => ['a', 'b']
 *
 * // Replace `_.memoize.Cache`.
 * _.memoize.Cache = WeakMap;
 */
function memoize(func, resolver) {
  if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
    throw new TypeError(FUNC_ERROR_TEXT);
  }
  var memoized = function() {
    var args = arguments,
        key = resolver ? resolver.apply(this, args) : args[0],
        cache = memoized.cache;

    if (cache.has(key)) {
      return cache.get(key);
    }
    var result = func.apply(this, args);
    memoized.cache = cache.set(key, result) || cache;
    return result;
  };
  memoized.cache = new (memoize.Cache || _MapCache);
  return memoized;
}

// Expose `MapCache`.
memoize.Cache = _MapCache;

var memoize_1 = memoize;

/** Used as the maximum memoize cache size. */
var MAX_MEMOIZE_SIZE = 500;

/**
 * A specialized version of `_.memoize` which clears the memoized function's
 * cache when it exceeds `MAX_MEMOIZE_SIZE`.
 *
 * @private
 * @param {Function} func The function to have its output memoized.
 * @returns {Function} Returns the new memoized function.
 */
function memoizeCapped(func) {
  var result = memoize_1(func, function(key) {
    if (cache.size === MAX_MEMOIZE_SIZE) {
      cache.clear();
    }
    return key;
  });

  var cache = result.cache;
  return result;
}

var _memoizeCapped = memoizeCapped;

/** Used to match property names within property paths. */
var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;

/** Used to match backslashes in property paths. */
var reEscapeChar = /\\(\\)?/g;

/**
 * Converts `string` to a property path array.
 *
 * @private
 * @param {string} string The string to convert.
 * @returns {Array} Returns the property path array.
 */
var stringToPath = _memoizeCapped(function(string) {
  var result = [];
  if (string.charCodeAt(0) === 46 /* . */) {
    result.push('');
  }
  string.replace(rePropName, function(match, number, quote, subString) {
    result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));
  });
  return result;
});

var _stringToPath = stringToPath;

/**
 * A specialized version of `_.map` 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 the new mapped array.
 */
function arrayMap(array, iteratee) {
  var index = -1,
      length = array == null ? 0 : array.length,
      result = Array(length);

  while (++index < length) {
    result[index] = iteratee(array[index], index, array);
  }
  return result;
}

var _arrayMap = arrayMap;

/** Used as references for various `Number` constants. */
var INFINITY$1 = 1 / 0;

/** Used to convert symbols to primitives and strings. */
var symbolProto$2 = _Symbol ? _Symbol.prototype : undefined,
    symbolToString = symbolProto$2 ? symbolProto$2.toString : undefined;

/**
 * The base implementation of `_.toString` which doesn't convert nullish
 * values to empty strings.
 *
 * @private
 * @param {*} value The value to process.
 * @returns {string} Returns the string.
 */
function baseToString(value) {
  // Exit early for strings to avoid a performance hit in some environments.
  if (typeof value == 'string') {
    return value;
  }
  if (isArray_1(value)) {
    // Recursively convert values (susceptible to call stack limits).
    return _arrayMap(value, baseToString) + '';
  }
  if (isSymbol_1(value)) {
    return symbolToString ? symbolToString.call(value) : '';
  }
  var result = (value + '');
  return (result == '0' && (1 / value) == -INFINITY$1) ? '-0' : result;
}

var _baseToString = baseToString;

/**
 * Converts `value` to a string. An empty string is returned for `null`
 * and `undefined` values. The sign of `-0` is preserved.
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to convert.
 * @returns {string} Returns the converted string.
 * @example
 *
 * _.toString(null);
 * // => ''
 *
 * _.toString(-0);
 * // => '-0'
 *
 * _.toString([1, 2, 3]);
 * // => '1,2,3'
 */
function toString(value) {
  return value == null ? '' : _baseToString(value);
}

var toString_1 = toString;

/**
 * Casts `value` to a path array if it's not one.
 *
 * @private
 * @param {*} value The value to inspect.
 * @param {Object} [object] The object to query keys on.
 * @returns {Array} Returns the cast property path array.
 */
function castPath(value, object) {
  if (isArray_1(value)) {
    return value;
  }
  return _isKey(value, object) ? [value] : _stringToPath(toString_1(value));
}

var _castPath = castPath;

/** Used as references for various `Number` constants. */
var INFINITY = 1 / 0;

/**
 * Converts `value` to a string key if it's not a string or symbol.
 *
 * @private
 * @param {*} value The value to inspect.
 * @returns {string|symbol} Returns the key.
 */
function toKey(value) {
  if (typeof value == 'string' || isSymbol_1(value)) {
    return value;
  }
  var result = (value + '');
  return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
}

var _toKey = toKey;

/**
 * The base implementation of `_.get` without support for default values.
 *
 * @private
 * @param {Object} object The object to query.
 * @param {Array|string} path The path of the property to get.
 * @returns {*} Returns the resolved value.
 */
function baseGet(object, path) {
  path = _castPath(path, object);

  var index = 0,
      length = path.length;

  while (object != null && index < length) {
    object = object[_toKey(path[index++])];
  }
  return (index && index == length) ? object : undefined;
}

var _baseGet = baseGet;

var defineProperty = (function() {
  try {
    var func = _getNative(Object, 'defineProperty');
    func({}, '', {});
    return func;
  } catch (e) {}
}());

var _defineProperty$1 = 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$1) {
    _defineProperty$1(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$a = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty$8 = objectProto$a.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$8.call(object, key) && eq_1(objValue, value)) ||
      (value === undefined && !(key in object))) {
    _baseAssignValue(object, key, value);
  }
}

var _assignValue = assignValue;

/** 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;

/**
 * The base implementation of `_.set`.
 *
 * @private
 * @param {Object} object The object to modify.
 * @param {Array|string} path The path of the property to set.
 * @param {*} value The value to set.
 * @param {Function} [customizer] The function to customize path creation.
 * @returns {Object} Returns `object`.
 */
function baseSet(object, path, value, customizer) {
  if (!isObject_1(object)) {
    return object;
  }
  path = _castPath(path, object);

  var index = -1,
      length = path.length,
      lastIndex = length - 1,
      nested = object;

  while (nested != null && ++index < length) {
    var key = _toKey(path[index]),
        newValue = value;

    if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
      return object;
    }

    if (index != lastIndex) {
      var objValue = nested[key];
      newValue = customizer ? customizer(objValue, key, nested) : undefined;
      if (newValue === undefined) {
        newValue = isObject_1(objValue)
          ? objValue
          : (_isIndex(path[index + 1]) ? [] : {});
      }
    }
    _assignValue(nested, key, newValue);
    nested = nested[key];
  }
  return object;
}

var _baseSet = baseSet;

/**
 * The base implementation of  `_.pickBy` without support for iteratee shorthands.
 *
 * @private
 * @param {Object} object The source object.
 * @param {string[]} paths The property paths to pick.
 * @param {Function} predicate The function invoked per property.
 * @returns {Object} Returns the new object.
 */
function basePickBy(object, paths, predicate) {
  var index = -1,
      length = paths.length,
      result = {};

  while (++index < length) {
    var path = paths[index],
        value = _baseGet(object, path);

    if (predicate(value, path)) {
      _baseSet(result, _castPath(path, object), value);
    }
  }
  return result;
}

var _basePickBy = basePickBy;

/**
 * The base implementation of `_.hasIn` without support for deep paths.
 *
 * @private
 * @param {Object} [object] The object to query.
 * @param {Array|string} key The key to check.
 * @returns {boolean} Returns `true` if `key` exists, else `false`.
 */
function baseHasIn(object, key) {
  return object != null && key in Object(object);
}

var _baseHasIn = baseHasIn;

/** `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$9 = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty$7 = objectProto$9.hasOwnProperty;

/** Built-in value references. */
var propertyIsEnumerable$1 = objectProto$9.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$1.call(value, 'callee');
};

var isArguments_1 = isArguments;

/** 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;

/**
 * Checks if `path` exists on `object`.
 *
 * @private
 * @param {Object} object The object to query.
 * @param {Array|string} path The path to check.
 * @param {Function} hasFunc The function to check properties.
 * @returns {boolean} Returns `true` if `path` exists, else `false`.
 */
function hasPath(object, path, hasFunc) {
  path = _castPath(path, object);

  var index = -1,
      length = path.length,
      result = false;

  while (++index < length) {
    var key = _toKey(path[index]);
    if (!(result = object != null && hasFunc(object, key))) {
      break;
    }
    object = object[key];
  }
  if (result || ++index != length) {
    return result;
  }
  length = object == null ? 0 : object.length;
  return !!length && isLength_1(length) && _isIndex(key, length) &&
    (isArray_1(object) || isArguments_1(object));
}

var _hasPath = hasPath;

/**
 * Checks if `path` is a direct or inherited property of `object`.
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Object
 * @param {Object} object The object to query.
 * @param {Array|string} path The path to check.
 * @returns {boolean} Returns `true` if `path` exists, else `false`.
 * @example
 *
 * var object = _.create({ 'a': _.create({ 'b': 2 }) });
 *
 * _.hasIn(object, 'a');
 * // => true
 *
 * _.hasIn(object, 'a.b');
 * // => true
 *
 * _.hasIn(object, ['a', 'b']);
 * // => true
 *
 * _.hasIn(object, 'b');
 * // => false
 */
function hasIn(object, path) {
  return object != null && _hasPath(object, path, _baseHasIn);
}

var hasIn_1 = hasIn;

/**
 * The base implementation of `_.pick` without support for individual
 * property identifiers.
 *
 * @private
 * @param {Object} object The source object.
 * @param {string[]} paths The property paths to pick.
 * @returns {Object} Returns the new object.
 */
function basePick(object, paths) {
  return _basePickBy(object, paths, function(value, path) {
    return hasIn_1(object, path);
  });
}

var _basePick = basePick;

/**
 * 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;

/** Built-in value references. */
var spreadableSymbol = _Symbol ? _Symbol.isConcatSpreadable : undefined;

/**
 * Checks if `value` is a flattenable `arguments` object or array.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
 */
function isFlattenable(value) {
  return isArray_1(value) || isArguments_1(value) ||
    !!(spreadableSymbol && value && value[spreadableSymbol]);
}

var _isFlattenable = isFlattenable;

/**
 * The base implementation of `_.flatten` with support for restricting flattening.
 *
 * @private
 * @param {Array} array The array to flatten.
 * @param {number} depth The maximum recursion depth.
 * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
 * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
 * @param {Array} [result=[]] The initial result value.
 * @returns {Array} Returns the new flattened array.
 */
function baseFlatten(array, depth, predicate, isStrict, result) {
  var index = -1,
      length = array.length;

  predicate || (predicate = _isFlattenable);
  result || (result = []);

  while (++index < length) {
    var value = array[index];
    if (depth > 0 && predicate(value)) {
      if (depth > 1) {
        // Recursively flatten arrays (susceptible to call stack limits).
        baseFlatten(value, depth - 1, predicate, isStrict, result);
      } else {
        _arrayPush(result, value);
      }
    } else if (!isStrict) {
      result[result.length] = value;
    }
  }
  return result;
}

var _baseFlatten = baseFlatten;

/**
 * Flattens `array` a single level deep.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Array
 * @param {Array} array The array to flatten.
 * @returns {Array} Returns the new flattened array.
 * @example
 *
 * _.flatten([1, [2, [3, [4]], 5]]);
 * // => [1, 2, [3, [4]], 5]
 */
function flatten(array) {
  var length = array == null ? 0 : array.length;
  return length ? _baseFlatten(array, 1) : [];
}

var flatten_1 = flatten;

/**
 * A faster alternative to `Function#apply`, this function invokes `func`
 * with the `this` binding of `thisArg` and the arguments of `args`.
 *
 * @private
 * @param {Function} func The function to invoke.
 * @param {*} thisArg The `this` binding of `func`.
 * @param {Array} args The arguments to invoke `func` with.
 * @returns {*} Returns the result of `func`.
 */
function apply(func, thisArg, args) {
  switch (args.length) {
    case 0: return func.call(thisArg);
    case 1: return func.call(thisArg, args[0]);
    case 2: return func.call(thisArg, args[0], args[1]);
    case 3: return func.call(thisArg, args[0], args[1], args[2]);
  }
  return func.apply(thisArg, args);
}

var _apply = apply;

/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max;

/**
 * A specialized version of `baseRest` which transforms the rest array.
 *
 * @private
 * @param {Function} func The function to apply a rest parameter to.
 * @param {number} [start=func.length-1] The start position of the rest parameter.
 * @param {Function} transform The rest array transform.
 * @returns {Function} Returns the new function.
 */
function overRest(func, start, transform) {
  start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
  return function() {
    var args = arguments,
        index = -1,
        length = nativeMax(args.length - start, 0),
        array = Array(length);

    while (++index < length) {
      array[index] = args[start + index];
    }
    index = -1;
    var otherArgs = Array(start + 1);
    while (++index < start) {
      otherArgs[index] = args[index];
    }
    otherArgs[start] = transform(array);
    return _apply(func, this, otherArgs);
  };
}

var _overRest = overRest;

/**
 * Creates a function that returns `value`.
 *
 * @static
 * @memberOf _
 * @since 2.4.0
 * @category Util
 * @param {*} value The value to return from the new function.
 * @returns {Function} Returns the new constant function.
 * @example
 *
 * var objects = _.times(2, _.constant({ 'a': 1 }));
 *
 * console.log(objects);
 * // => [{ 'a': 1 }, { 'a': 1 }]
 *
 * console.log(objects[0] === objects[1]);
 * // => true
 */
function constant(value) {
  return function() {
    return value;
  };
}

var constant_1 = constant;

/**
 * This method returns the first argument it receives.
 *
 * @static
 * @since 0.1.0
 * @memberOf _
 * @category Util
 * @param {*} value Any value.
 * @returns {*} Returns `value`.
 * @example
 *
 * var object = { 'a': 1 };
 *
 * console.log(_.identity(object) === object);
 * // => true
 */
function identity(value) {
  return value;
}

var identity_1 = identity;

/**
 * The base implementation of `setToString` without support for hot loop shorting.
 *
 * @private
 * @param {Function} func The function to modify.
 * @param {Function} string The `toString` result.
 * @returns {Function} Returns `func`.
 */
var baseSetToString = !_defineProperty$1 ? identity_1 : function(func, string) {
  return _defineProperty$1(func, 'toString', {
    'configurable': true,
    'enumerable': false,
    'value': constant_1(string),
    'writable': true
  });
};

var _baseSetToString = baseSetToString;

/** Used to detect hot functions by number of calls within a span of milliseconds. */
var HOT_COUNT = 800,
    HOT_SPAN = 16;

/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeNow = Date.now;

/**
 * Creates a function that'll short out and invoke `identity` instead
 * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
 * milliseconds.
 *
 * @private
 * @param {Function} func The function to restrict.
 * @returns {Function} Returns the new shortable function.
 */
function shortOut(func) {
  var count = 0,
      lastCalled = 0;

  return function() {
    var stamp = nativeNow(),
        remaining = HOT_SPAN - (stamp - lastCalled);

    lastCalled = stamp;
    if (remaining > 0) {
      if (++count >= HOT_COUNT) {
        return arguments[0];
      }
    } else {
      count = 0;
    }
    return func.apply(undefined, arguments);
  };
}

var _shortOut = shortOut;

/**
 * Sets the `toString` method of `func` to return `string`.
 *
 * @private
 * @param {Function} func The function to modify.
 * @param {Function} string The `toString` result.
 * @returns {Function} Returns `func`.
 */
var setToString = _shortOut(_baseSetToString);

var _setToString = setToString;

/**
 * A specialized version of `baseRest` which flattens the rest array.
 *
 * @private
 * @param {Function} func The function to apply a rest parameter to.
 * @returns {Function} Returns the new function.
 */
function flatRest(func) {
  return _setToString(_overRest(func, undefined, flatten_1), func + '');
}

var _flatRest = flatRest;

/**
 * Creates an object composed of the picked `object` properties.
 *
 * @static
 * @since 0.1.0
 * @memberOf _
 * @category Object
 * @param {Object} object The source object.
 * @param {...(string|string[])} [paths] The property paths to pick.
 * @returns {Object} Returns the new object.
 * @example
 *
 * var object = { 'a': 1, 'b': '2', 'c': 3 };
 *
 * _.pick(object, ['a', 'c']);
 * // => { 'a': 1, 'c': 3 }
 */
var pick = _flatRest(function(object, paths) {
  return object == null ? {} : _basePick(object, paths);
});

var pick_1 = pick;

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_base(slot, slot_definition, ctx, $$scope, slot_changes, get_slot_context_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 get_all_dirty_from_scope($$scope) {
    if ($$scope.ctx.length > 32) {
        const dirty = [];
        const length = $$scope.ctx.length / 32;
        for (let i = 0; i < length; i++) {
            dirty[i] = -1;
        }
        return dirty;
    }
    return -1;
}
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) {
    store.set(value);
    return ret;
}
function action_destroyer(action_result) {
    return action_result && is_function(action_result.destroy) ? action_result.destroy : noop;
}
function append(target, node) {
    target.appendChild(node);
}
function append_styles(target, style_sheet_id, styles) {
    const append_styles_to = get_root_for_style(target);
    if (!append_styles_to.getElementById(style_sheet_id)) {
        const style = element('style');
        style.id = style_sheet_id;
        style.textContent = styles;
        append_stylesheet(append_styles_to, style);
    }
}
function get_root_for_style(node) {
    if (!node)
        return document;
    const root = node.getRootNode ? node.getRootNode() : node.ownerDocument;
    if (root && root.host) {
        return root;
    }
    return node.ownerDocument;
}
function append_stylesheet(node, style) {
    append(node.head || node, style);
}
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 set_attributes(node, attributes) {
    // @ts-ignore
    const descriptors = Object.getOwnPropertyDescriptors(node.__proto__);
    for (const key in attributes) {
        if (attributes[key] == null) {
            node.removeAttribute(key);
        }
        else if (key === 'style') {
            node.style.cssText = attributes[key];
        }
        else if (key === '__value') {
            node.value = node[key] = attributes[key];
        }
        else if (descriptors[key] && descriptors[key].set) {
            node[key] = attributes[key];
        }
        else {
            attr(node, key, attributes[key]);
        }
    }
}
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 set_style(node, key, value, important) {
    node.style.setProperty(key, value, important ? 'important' : '');
}
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;
        }
    }
    select.selectedIndex = -1; // no option should be selected
}
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, bubbles = false) {
    const e = document.createEvent('CustomEvent');
    e.initCustomEvent(type, bubbles, 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);
    }
}
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 get_spread_update(levels, updates) {
    const update = {};
    const to_null_out = {};
    const accounted_for = { $$scope: 1 };
    let i = levels.length;
    while (i--) {
        const o = levels[i];
        const n = updates[i];
        if (n) {
            for (const key in o) {
                if (!(key in n))
                    to_null_out[key] = 1;
            }
            for (const key in n) {
                if (!accounted_for[key]) {
                    update[key] = n[key];
                    accounted_for[key] = 1;
                }
            }
            levels[i] = n;
        }
        else {
            for (const key in o) {
                accounted_for[key] = 1;
            }
        }
    }
    for (const key in to_null_out) {
        if (!(key in update))
            update[key] = undefined;
    }
    return update;
}

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, append_styles, 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(options.context || (parent_component ? parent_component.$$.context : [])),
        // everything else
        callbacks: blank_object(),
        dirty,
        skip_bound: false,
        root: options.target || parent_component.$$.root
    };
    append_styles && append_styles($$.root);
    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 = new Set();
    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 (const subscriber of subscribers) {
                    subscriber[1]();
                    subscriber_queue.push(subscriber, 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.add(subscriber);
        if (subscribers.size === 1) {
            stop = start(set) || noop;
        }
        run(value);
        return () => {
            subscribers.delete(subscriber);
            if (subscribers.size === 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 LONGFORM_CURRENT_PLUGIN_DATA_VERSION = 2;
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,
    workflows: null,
    userScriptFolder: null,
};
const TRACKED_SETTINGS_PATHS = [
    "version",
    "projects",
    "selectedProject",
    "selectedDraft",
    "userScriptFolder",
];

// Writable stores
const initialized = writable(false);
const pluginSettings = writable(null);
const projectMetadata = writable({});
const currentProjectPath = writable(null);
const currentDraftPath = writable(null);
const activeFile = writable(null);
const workflows = writable({});
const userScriptSteps = 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, workflow: null, 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);
});
// Compile stores
const currentWorkflow = derived([workflows, projectMetadata, currentProjectPath], ([$workflows, $projectMetadata, $currentProjectPath]) => {
    const metadata = $projectMetadata[$currentProjectPath];
    if (metadata) {
        const currentWorkflowName = $projectMetadata[$currentProjectPath].workflow;
        if (currentWorkflowName) {
            const workflow = $workflows[currentWorkflowName];
            return workflow;
        }
        return null;
    }
    return null;
});

var CompileStepKind;
(function (CompileStepKind) {
    /** Takes an array of scene files, processes them in some way, and outputs an array of scene files. */
    CompileStepKind["Scene"] = "Scene";
    /** Takes an array of scene files and processes them such that the output is a single manuscript file. */
    CompileStepKind["Join"] = "Join";
    /** Takes a single manuscript file, processes it in some way, and outputs a single manuscript file. */
    CompileStepKind["Manuscript"] = "Manuscript";
})(CompileStepKind || (CompileStepKind = {}));
function formatStepKind(k) {
    switch (k) {
        case CompileStepKind.Scene:
            return "Scene";
        case CompileStepKind.Join:
            return "Join";
        case CompileStepKind.Manuscript:
            return "Manuscript";
    }
}
function explainStepKind(k) {
    switch (k) {
        case CompileStepKind.Scene:
            return "Runs on every scene in your manuscript and outputs the resulting scenes.";
        case CompileStepKind.Join:
            return "Accepts all scenes as input and outputs a single manuscript.";
        case CompileStepKind.Manuscript:
            return "Runs once on your compiled manuscript.";
    }
}
var CompileStepOptionType;
(function (CompileStepOptionType) {
    CompileStepOptionType[CompileStepOptionType["Boolean"] = 0] = "Boolean";
    CompileStepOptionType[CompileStepOptionType["Text"] = 1] = "Text";
})(CompileStepOptionType || (CompileStepOptionType = {}));
function makeBuiltinStep(v, isScript = false) {
    return Object.assign(Object.assign({}, v), { description: Object.assign(Object.assign({}, v.description), { canonicalID: v.id, isScript: isScript }), optionValues: v.description.options.reduce((agg, opt) => {
            return Object.assign(Object.assign({}, agg), { [opt.id]: opt.default });
        }, {}) });
}
function typeMismatchError(expected, got, context) {
    return new Error(`[Longform] A compile step received a type it did not expect. It expected "${expected}", but got "${got}" with step kind "${context.kind}"`);
}
const PLACEHOLDER_MISSING_STEP = {
    id: "placeholder-missing-step",
    description: {
        canonicalID: "placeholder-missing-step",
        name: "",
        description: "",
        isScript: false,
        availableKinds: [],
        options: [],
    },
    optionValues: {},
    compile: (a) => a,
};

function formatOptionValues(values) {
    const formattedOptions = {};
    for (const key of Object.keys(values)) {
        let v = values[key];
        if (typeof v === "string") {
            v = v.split("\\n").join("\n");
        }
        formattedOptions[key] = v;
    }
    return formattedOptions;
}
function compile(app, projectPath, draftName, workflow, kinds, statusCallback) {
    return __awaiter(this, void 0, void 0, function* () {
        // Grab draft path and metadata
        const projectSettings = get_store_value(pluginSettings).projects[projectPath];
        if (!projectSettings) {
            const error = `No tracked project at ${projectPath} exists for compilation.`;
            console.error(`[Longform] ${error}`);
            statusCallback({
                kind: "CompileStatusError",
                error,
            });
            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) {
            const error = `No draft named ${draftName} exists in ${projectPath} for compilation.`;
            console.error(`[Longform] ${error}`);
            statusCallback({
                kind: "CompileStatusError",
                error,
            });
            return;
        }
        let currentInput = [];
        // Build initial inputs
        for (const scene of draftMetadata.scenes) {
            const path = scenePath(scene);
            const contents = yield app.vault.adapter.read(path);
            const metadata = app.metadataCache.getCache(path);
            currentInput.push({
                path,
                name: scene,
                contents,
                metadata,
            });
        }
        for (let index = 0; index < workflow.steps.length; index++) {
            const step = workflow.steps[index];
            const kind = index < kinds.length ? kinds[index] : null;
            if (kind === null) {
                const error = `No step kind data for step at position ${index}.`;
                console.error(`[Longform] ${error}`);
                statusCallback({
                    kind: "CompileStatusError",
                    error,
                });
                return;
            }
            const context = {
                kind,
                optionValues: formatOptionValues(step.optionValues),
                projectPath,
                app,
            };
            console.log(`[Longform] Running compile step ${step.description.name} with context:`, context);
            statusCallback({
                kind: "CompileStatusStep",
                stepIndex: index,
                totalSteps: workflow.steps.length,
                stepKind: kind,
            });
            // TODO: how to enforce typings here?
            try {
                currentInput = yield step.compile(currentInput, context);
            }
            catch (error) {
                console.error("[Longform]", error);
                statusCallback({
                    kind: "CompileStatusError",
                    error: `${error}`,
                });
                return;
            }
        }
        console.log(`[Longform] Compile workflow "${workflow.name}" finished with final result:`, currentInput);
        statusCallback({
            kind: "CompileStatusSuccess",
        });
    });
}
const DEFAULT_WORKFLOWS = {
    "Default Workflow": {
        name: "Default Workflow",
        description: "A starter workflow. Feel free to edit, rename, or delete it and create your own.",
        steps: [
            {
                id: "strip-frontmatter",
                optionValues: {},
            },
            {
                id: "remove-links",
                optionValues: {
                    "remove-wikilinks": true,
                    "remove-external-links": true,
                },
            },
            {
                id: "prepend-title",
                optionValues: {
                    format: "## $1",
                    separator: "\n\n",
                },
            },
            {
                id: "concatenate-text",
                optionValues: {
                    separator: "\\n\\n---\\n\\n",
                },
            },
            {
                id: "write-to-note",
                optionValues: {
                    target: "manuscript.md",
                    "open-after": true,
                },
            },
        ],
    },
};

const ConcatenateTextStep = makeBuiltinStep({
    id: "concatenate-text",
    description: {
        name: "Concatenate Text",
        description: "Combines all scenes together in order into a manuscript.",
        availableKinds: [CompileStepKind.Join],
        options: [
            {
                id: "separator",
                name: "Separator",
                description: "Text to put between joined scenes.",
                type: CompileStepOptionType.Text,
                default: "\n\n",
            },
        ],
    },
    compile(input, context) {
        if (!Array.isArray(input)) {
            throw typeMismatchError("string[]", typeof input, context);
        }
        const separator = context.optionValues["separator"];
        return {
            contents: input.map((i) => i.contents).join(separator),
        };
    },
});

const PrependTitleStep = makeBuiltinStep({
    id: "prepend-title",
    description: {
        name: "Prepend Title",
        description: "Prepends the scene title to the scene text.",
        availableKinds: [CompileStepKind.Scene],
        options: [
            {
                id: "format",
                name: "Title Format",
                description: "Format of title. $1 will be replaced with title. $2, if present, will be replaced with scene number.",
                type: CompileStepOptionType.Text,
                default: "$1",
            },
            {
                id: "separator",
                name: "Separator",
                description: "Text to put between title and scene text.",
                type: CompileStepOptionType.Text,
                default: "\n\n",
            },
        ],
    },
    compile(input, context) {
        const format = context.optionValues["format"];
        const separator = context.optionValues["separator"];
        return input.map((sceneInput, index) => {
            const title = format
                .replace("$1", sceneInput.name)
                .replace("$2", `${index + 1}`);
            const contents = `${title}${separator}${sceneInput.contents}`;
            return Object.assign(Object.assign({}, sceneInput), { contents });
        });
    },
});

const MARKDOWN_COMMENTS_REGEX = /%%([\s\S]*?)%%/gm;
const HTML_COMMENTS_REGEX = /<!--([\s\S]*?)-->/gm;
const RemoveCommentsStep = makeBuiltinStep({
    id: "remove-comments",
    description: {
        name: "Remove Comments",
        description: "Removes markdown and/or html comments.",
        availableKinds: [CompileStepKind.Scene, CompileStepKind.Manuscript],
        options: [
            {
                id: "remove-markdown-comments",
                name: "Remove Markdown Comments",
                description: "Remove markdown-style comments (%% text %%)",
                type: CompileStepOptionType.Boolean,
                default: true,
            },
            {
                id: "remove-html-comments",
                name: "Remove HTML Comments",
                description: "Remove HTML-style comments (<!-- text -->)",
                type: CompileStepOptionType.Boolean,
                default: true,
            },
        ],
    },
    compile(input, context) {
        const removeMarkdownComments = context.optionValues["remove-markdown-comments"];
        const removeHTMLComments = context.optionValues["remove-html-comments"];
        const replaceComments = (contents) => {
            if (removeMarkdownComments) {
                contents = contents.replace(MARKDOWN_COMMENTS_REGEX, () => "");
            }
            if (removeHTMLComments) {
                contents = contents.replace(HTML_COMMENTS_REGEX, () => "");
            }
            return contents;
        };
        if (context.kind === CompileStepKind.Scene) {
            return input.map((sceneInput) => {
                const contents = replaceComments(sceneInput.contents);
                return Object.assign(Object.assign({}, sceneInput), { contents });
            });
        }
        else {
            return Object.assign(Object.assign({}, input), { contents: replaceComments(input.contents) });
        }
    },
});

const WIKILINKS_REGEX = /\[\[([^[|]+)(|[^[]+)?\]\]/gm;
const EXTERNAL_LINKS_REGEX = /\[([^[]+)\](\(.*\))/gm;
const RemoveLinksStep = makeBuiltinStep({
    id: "remove-links",
    description: {
        name: "Remove Links",
        description: "Removes wiki and/or external links.",
        availableKinds: [CompileStepKind.Scene, CompileStepKind.Manuscript],
        options: [
            {
                id: "remove-wikilinks",
                name: "Remove Wikilinks",
                description: "Remove brackets from [[wikilinks]].",
                type: CompileStepOptionType.Boolean,
                default: true,
            },
            {
                id: "remove-external-links",
                name: "Remove External Links",
                description: "Remove external links, leaving only the anchor text.",
                type: CompileStepOptionType.Boolean,
                default: true,
            },
        ],
    },
    compile(input, context) {
        const removeWikilinks = context.optionValues["remove-wikilinks"];
        const removeExternalLinks = context.optionValues["remove-external-links"];
        const replaceLinks = (contents) => {
            if (removeWikilinks) {
                contents = contents.replace(WIKILINKS_REGEX, (_match, p1, p2) => {
                    if (p2) {
                        return p2.slice(1);
                    }
                    else {
                        return p1;
                    }
                });
            }
            if (removeExternalLinks) {
                contents = contents.replace(EXTERNAL_LINKS_REGEX, (_match, p1) => p1);
            }
            return contents;
        };
        if (context.kind === CompileStepKind.Scene) {
            return input.map((sceneInput) => {
                const contents = replaceLinks(sceneInput.contents);
                return Object.assign(Object.assign({}, sceneInput), { contents });
            });
        }
        else {
            return Object.assign(Object.assign({}, input), { contents: replaceLinks(input.contents) });
        }
    },
});

const STRIKETHROUGH_REGEX = /~~(.*?)~~/gm;
const RemoveStrikethroughsStep = makeBuiltinStep({
    id: "remove-strikethroughs",
    description: {
        name: "Remove Strikethroughs",
        description: "Removes struck-through ~~text~~.",
        availableKinds: [CompileStepKind.Scene, CompileStepKind.Manuscript],
        options: [],
    },
    compile(input, context) {
        if (context.kind === CompileStepKind.Scene) {
            return input.map((sceneInput) => {
                return Object.assign(Object.assign({}, sceneInput), { contents: sceneInput.contents.replace(STRIKETHROUGH_REGEX, () => "") });
            });
        }
        else {
            return Object.assign(Object.assign({}, input), { contents: input.contents.replace(STRIKETHROUGH_REGEX, () => "") });
        }
    },
});

const StripFrontmatterStep = makeBuiltinStep({
    id: "strip-frontmatter",
    description: {
        name: "Strip Frontmatter",
        description: "Removes the YAML frontmatter section from the scene or manuscript.",
        availableKinds: [CompileStepKind.Scene, CompileStepKind.Manuscript],
        options: [],
    },
    compile(input, context) {
        if (context.kind === CompileStepKind.Scene) {
            return input.map((sceneInput) => {
                const contents = sceneInput.contents.replace(/^---(.*?\n)*---\n*/gm, "");
                return Object.assign(Object.assign({}, sceneInput), { contents });
            });
        }
        else {
            return Object.assign(Object.assign({}, input), { contents: input.contents.replace(/^---(.*?\n)*---\n*/gm, "") });
        }
    },
});

const WriteToNoteStep = makeBuiltinStep({
    id: "write-to-note",
    description: {
        name: "Save as Note",
        description: "Saves your manuscript as a note in your vault.",
        availableKinds: [CompileStepKind.Manuscript],
        options: [
            {
                id: "target",
                name: "Output path",
                description: "Path for the created manuscript note, relative to your project.",
                type: CompileStepOptionType.Text,
                default: "manuscript.md",
            },
            {
                id: "open-after",
                name: "Open Compiled Manuscript",
                description: "If checked, open the compiled manuscript in a new pane.",
                type: CompileStepOptionType.Boolean,
                default: true,
            },
        ],
    },
    compile(input, context) {
        return __awaiter(this, void 0, void 0, function* () {
            if (context.kind !== CompileStepKind.Manuscript) {
                throw new Error("Cannot write non-manuscript as note.");
            }
            else {
                const target = context.optionValues["target"];
                const openAfter = context.optionValues["open-after"];
                if (!target || target.length == 0) {
                    throw new Error("Invalid path for Save as Note.");
                }
                const file = target.endsWith(".md") ? target : target + ".md";
                const path = obsidian.normalizePath(`${context.projectPath}/${file}`);
                const pathComponents = path.split("/");
                pathComponents.pop();
                try {
                    yield context.app.vault.createFolder(pathComponents.join("/"));
                }
                catch (e) {
                    // do nothing, folder already existed
                }
                yield context.app.vault.adapter.write(path, input.contents);
                if (openAfter) {
                    context.app.workspace.openLinkText(path, "/", true);
                }
                return input;
            }
        });
    },
});

const BUILTIN_STEPS = [
    ConcatenateTextStep,
    PrependTitleStep,
    RemoveCommentsStep,
    RemoveLinksStep,
    RemoveStrikethroughsStep,
    StripFrontmatterStep,
    WriteToNoteStep,
];

/* src/view/compile/add-step-modal/AddStepModal.svelte generated by Svelte v3.43.1 */

function add_css$b(target) {
	append_styles(target, "svelte-voc2lx", ".longform-steps-grid.svelte-voc2lx.svelte-voc2lx{display:grid;grid-template-columns:1fr 1fr;gap:1rem;grid-auto-rows:auto}.longform-compile-step.svelte-voc2lx.svelte-voc2lx{cursor:pointer;grid-column:auto;grid-row:auto;background-color:var(--background-secondary);border:2px solid var(--background-modifier-border);border-radius:1rem;padding:0.5rem}.longform-compile-step.svelte-voc2lx.svelte-voc2lx:hover{border:2px solid var(--text-accent);background-color:var(--background-modifier-form-field)}.longform-compile-step.svelte-voc2lx h3.svelte-voc2lx{padding:8px 0;margin:0}.longform-compile-step.svelte-voc2lx .longform-step-kind-pill.svelte-voc2lx{background-color:var(--text-accent);color:var(--text-on-accent);border-radius:10px;font-size:0.7rem;font-weight:bold;padding:0.25rem;margin-right:0.25rem;height:1.2rem}");
}

function get_each_context$5(ctx, list, i) {
	const child_ctx = ctx.slice();
	child_ctx[9] = list[i];
	return child_ctx;
}

function get_each_context_1$1(ctx, list, i) {
	const child_ctx = ctx.slice();
	child_ctx[12] = list[i];
	return child_ctx;
}

function get_each_context_2(ctx, list, i) {
	const child_ctx = ctx.slice();
	child_ctx[9] = list[i];
	return child_ctx;
}

function get_each_context_3(ctx, list, i) {
	const child_ctx = ctx.slice();
	child_ctx[12] = list[i];
	return child_ctx;
}

// (31:10) {#each step.description.availableKinds as kind}
function create_each_block_3(ctx) {
	let span;
	let t_value = formatStepKind(/*kind*/ ctx[12]) + "";
	let t;
	let span_title_value;

	return {
		c() {
			span = element("span");
			t = text(t_value);
			attr(span, "class", "longform-step-kind-pill svelte-voc2lx");
			attr(span, "title", span_title_value = explainStepKind(/*kind*/ ctx[12]));
		},
		m(target, anchor) {
			insert(target, span, anchor);
			append(span, t);
		},
		p: noop,
		d(detaching) {
			if (detaching) detach(span);
		}
	};
}

// (27:4) {#each BUILTIN_STEPS as step}
function create_each_block_2(ctx) {
	let div1;
	let h3;
	let t0_value = /*step*/ ctx[9].description.name + "";
	let t0;
	let t1;
	let div0;
	let t2;
	let p;
	let t3_value = /*step*/ ctx[9].description.description + "";
	let t3;
	let t4;
	let mounted;
	let dispose;
	let each_value_3 = /*step*/ ctx[9].description.availableKinds;
	let each_blocks = [];

	for (let i = 0; i < each_value_3.length; i += 1) {
		each_blocks[i] = create_each_block_3(get_each_context_3(ctx, each_value_3, i));
	}

	function click_handler() {
		return /*click_handler*/ ctx[2](/*step*/ ctx[9]);
	}

	return {
		c() {
			div1 = element("div");
			h3 = element("h3");
			t0 = text(t0_value);
			t1 = space();
			div0 = element("div");

			for (let i = 0; i < each_blocks.length; i += 1) {
				each_blocks[i].c();
			}

			t2 = space();
			p = element("p");
			t3 = text(t3_value);
			t4 = space();
			attr(h3, "class", "svelte-voc2lx");
			attr(div0, "class", "longform-step-pill-container");
			attr(div1, "class", "longform-compile-step svelte-voc2lx");
		},
		m(target, anchor) {
			insert(target, div1, anchor);
			append(div1, h3);
			append(h3, t0);
			append(div1, t1);
			append(div1, div0);

			for (let i = 0; i < each_blocks.length; i += 1) {
				each_blocks[i].m(div0, null);
			}

			append(div0, t2);
			append(div0, p);
			append(p, t3);
			append(div1, t4);

			if (!mounted) {
				dispose = listen(div1, "click", click_handler);
				mounted = true;
			}
		},
		p(new_ctx, dirty) {
			ctx = new_ctx;

			if (dirty & /*explainStepKind, BUILTIN_STEPS, formatStepKind*/ 0) {
				each_value_3 = /*step*/ ctx[9].description.availableKinds;
				let i;

				for (i = 0; i < each_value_3.length; i += 1) {
					const child_ctx = get_each_context_3(ctx, each_value_3, i);

					if (each_blocks[i]) {
						each_blocks[i].p(child_ctx, dirty);
					} else {
						each_blocks[i] = create_each_block_3(child_ctx);
						each_blocks[i].c();
						each_blocks[i].m(div0, t2);
					}
				}

				for (; i < each_blocks.length; i += 1) {
					each_blocks[i].d(1);
				}

				each_blocks.length = each_value_3.length;
			}
		},
		d(detaching) {
			if (detaching) detach(div1);
			destroy_each(each_blocks, detaching);
			mounted = false;
			dispose();
		}
	};
}

// (41:2) {#if $userScriptSteps}
function create_if_block$7(ctx) {
	let h2;
	let t1;
	let div;
	let each_value = /*$userScriptSteps*/ ctx[0];
	let each_blocks = [];

	for (let i = 0; i < each_value.length; i += 1) {
		each_blocks[i] = create_each_block$5(get_each_context$5(ctx, each_value, i));
	}

	return {
		c() {
			h2 = element("h2");
			h2.textContent = "User Script Steps";
			t1 = space();
			div = element("div");

			for (let i = 0; i < each_blocks.length; i += 1) {
				each_blocks[i].c();
			}

			attr(div, "class", "longform-steps-grid svelte-voc2lx");
		},
		m(target, anchor) {
			insert(target, h2, anchor);
			insert(target, t1, anchor);
			insert(target, div, anchor);

			for (let i = 0; i < each_blocks.length; i += 1) {
				each_blocks[i].m(div, null);
			}
		},
		p(ctx, dirty) {
			if (dirty & /*onStepClick, $userScriptSteps, explainStepKind, formatStepKind*/ 3) {
				each_value = /*$userScriptSteps*/ ctx[0];
				let i;

				for (i = 0; i < each_value.length; i += 1) {
					const child_ctx = get_each_context$5(ctx, each_value, i);

					if (each_blocks[i]) {
						each_blocks[i].p(child_ctx, dirty);
					} else {
						each_blocks[i] = create_each_block$5(child_ctx);
						each_blocks[i].c();
						each_blocks[i].m(div, null);
					}
				}

				for (; i < each_blocks.length; i += 1) {
					each_blocks[i].d(1);
				}

				each_blocks.length = each_value.length;
			}
		},
		d(detaching) {
			if (detaching) detach(h2);
			if (detaching) detach(t1);
			if (detaching) detach(div);
			destroy_each(each_blocks, detaching);
		}
	};
}

// (48:12) {#each step.description.availableKinds as kind}
function create_each_block_1$1(ctx) {
	let span;
	let t_value = formatStepKind(/*kind*/ ctx[12]) + "";
	let t;
	let span_title_value;

	return {
		c() {
			span = element("span");
			t = text(t_value);
			attr(span, "class", "longform-step-kind-pill svelte-voc2lx");
			attr(span, "title", span_title_value = explainStepKind(/*kind*/ ctx[12]));
		},
		m(target, anchor) {
			insert(target, span, anchor);
			append(span, t);
		},
		p(ctx, dirty) {
			if (dirty & /*$userScriptSteps*/ 1 && t_value !== (t_value = formatStepKind(/*kind*/ ctx[12]) + "")) set_data(t, t_value);

			if (dirty & /*$userScriptSteps*/ 1 && span_title_value !== (span_title_value = explainStepKind(/*kind*/ ctx[12]))) {
				attr(span, "title", span_title_value);
			}
		},
		d(detaching) {
			if (detaching) detach(span);
		}
	};
}

// (44:6) {#each $userScriptSteps as step}
function create_each_block$5(ctx) {
	let div1;
	let h3;
	let t0_value = /*step*/ ctx[9].description.name + "";
	let t0;
	let t1;
	let div0;
	let t2;
	let p;
	let t3_value = /*step*/ ctx[9].description.description + "";
	let t3;
	let t4;
	let mounted;
	let dispose;
	let each_value_1 = /*step*/ ctx[9].description.availableKinds;
	let each_blocks = [];

	for (let i = 0; i < each_value_1.length; i += 1) {
		each_blocks[i] = create_each_block_1$1(get_each_context_1$1(ctx, each_value_1, i));
	}

	function click_handler_1() {
		return /*click_handler_1*/ ctx[3](/*step*/ ctx[9]);
	}

	return {
		c() {
			div1 = element("div");
			h3 = element("h3");
			t0 = text(t0_value);
			t1 = space();
			div0 = element("div");

			for (let i = 0; i < each_blocks.length; i += 1) {
				each_blocks[i].c();
			}

			t2 = space();
			p = element("p");
			t3 = text(t3_value);
			t4 = space();
			attr(h3, "class", "svelte-voc2lx");
			attr(div0, "class", "longform-step-pill-container");
			attr(div1, "class", "longform-compile-step svelte-voc2lx");
		},
		m(target, anchor) {
			insert(target, div1, anchor);
			append(div1, h3);
			append(h3, t0);
			append(div1, t1);
			append(div1, div0);

			for (let i = 0; i < each_blocks.length; i += 1) {
				each_blocks[i].m(div0, null);
			}

			append(div0, t2);
			append(div0, p);
			append(p, t3);
			append(div1, t4);

			if (!mounted) {
				dispose = listen(div1, "click", click_handler_1);
				mounted = true;
			}
		},
		p(new_ctx, dirty) {
			ctx = new_ctx;
			if (dirty & /*$userScriptSteps*/ 1 && t0_value !== (t0_value = /*step*/ ctx[9].description.name + "")) set_data(t0, t0_value);

			if (dirty & /*explainStepKind, $userScriptSteps, formatStepKind*/ 1) {
				each_value_1 = /*step*/ ctx[9].description.availableKinds;
				let i;

				for (i = 0; i < each_value_1.length; i += 1) {
					const child_ctx = get_each_context_1$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$1(child_ctx);
						each_blocks[i].c();
						each_blocks[i].m(div0, t2);
					}
				}

				for (; i < each_blocks.length; i += 1) {
					each_blocks[i].d(1);
				}

				each_blocks.length = each_value_1.length;
			}

			if (dirty & /*$userScriptSteps*/ 1 && t3_value !== (t3_value = /*step*/ ctx[9].description.description + "")) set_data(t3, t3_value);
		},
		d(detaching) {
			if (detaching) detach(div1);
			destroy_each(each_blocks, detaching);
			mounted = false;
			dispose();
		}
	};
}

function create_fragment$e(ctx) {
	let div1;
	let p;
	let t1;
	let h2;
	let t3;
	let div0;
	let t4;
	let each_value_2 = BUILTIN_STEPS;
	let each_blocks = [];

	for (let i = 0; i < each_value_2.length; i += 1) {
		each_blocks[i] = create_each_block_2(get_each_context_2(ctx, each_value_2, i));
	}

	let if_block = /*$userScriptSteps*/ ctx[0] && create_if_block$7(ctx);

	return {
		c() {
			div1 = element("div");
			p = element("p");
			p.textContent = "Choose a step from the following options to add to your current compile\n    workflow.";
			t1 = space();
			h2 = element("h2");
			h2.textContent = "Built-in Steps";
			t3 = space();
			div0 = element("div");

			for (let i = 0; i < each_blocks.length; i += 1) {
				each_blocks[i].c();
			}

			t4 = space();
			if (if_block) if_block.c();
			attr(div0, "class", "longform-steps-grid svelte-voc2lx");
			attr(div1, "class", "longform-add-step-modal-contents");
		},
		m(target, anchor) {
			insert(target, div1, anchor);
			append(div1, p);
			append(div1, t1);
			append(div1, h2);
			append(div1, t3);
			append(div1, div0);

			for (let i = 0; i < each_blocks.length; i += 1) {
				each_blocks[i].m(div0, null);
			}

			append(div1, t4);
			if (if_block) if_block.m(div1, null);
		},
		p(ctx, [dirty]) {
			if (dirty & /*onStepClick, BUILTIN_STEPS, explainStepKind, formatStepKind*/ 2) {
				each_value_2 = BUILTIN_STEPS;
				let i;

				for (i = 0; i < each_value_2.length; i += 1) {
					const child_ctx = get_each_context_2(ctx, each_value_2, i);

					if (each_blocks[i]) {
						each_blocks[i].p(child_ctx, dirty);
					} else {
						each_blocks[i] = create_each_block_2(child_ctx);
						each_blocks[i].c();
						each_blocks[i].m(div0, null);
					}
				}

				for (; i < each_blocks.length; i += 1) {
					each_blocks[i].d(1);
				}

				each_blocks.length = each_value_2.length;
			}

			if (/*$userScriptSteps*/ ctx[0]) {
				if (if_block) {
					if_block.p(ctx, dirty);
				} else {
					if_block = create_if_block$7(ctx);
					if_block.c();
					if_block.m(div1, null);
				}
			} else if (if_block) {
				if_block.d(1);
				if_block = null;
			}
		},
		i: noop,
		o: noop,
		d(detaching) {
			if (detaching) detach(div1);
			destroy_each(each_blocks, detaching);
			if (if_block) if_block.d();
		}
	};
}

function instance$e($$self, $$props, $$invalidate) {
	let $workflows;
	let $currentProjectPath;
	let $projectMetadata;
	let $currentWorkflow;
	let $userScriptSteps;
	component_subscribe($$self, workflows, $$value => $$invalidate(4, $workflows = $$value));
	component_subscribe($$self, currentProjectPath, $$value => $$invalidate(5, $currentProjectPath = $$value));
	component_subscribe($$self, projectMetadata, $$value => $$invalidate(6, $projectMetadata = $$value));
	component_subscribe($$self, currentWorkflow, $$value => $$invalidate(7, $currentWorkflow = $$value));
	component_subscribe($$self, userScriptSteps, $$value => $$invalidate(0, $userScriptSteps = $$value));
	const close = getContext("close");

	function onStepClick(step) {
		// Inject the current epoch into the step ID to allow
		// multiple same-typed steps.
		const newWorkflow = Object.assign(Object.assign({}, $currentWorkflow), {
			steps: [
				...$currentWorkflow.steps,
				Object.assign(Object.assign({}, step), { id: `${step.id}-${Date.now()}` })
			]
		});

		const currentWorkflowName = $projectMetadata[$currentProjectPath].workflow;
		set_store_value(workflows, $workflows[currentWorkflowName] = newWorkflow, $workflows);
		close();
	}

	const click_handler = step => onStepClick(step);
	const click_handler_1 = step => onStepClick(step);
	return [$userScriptSteps, onStepClick, click_handler, click_handler_1];
}

class AddStepModal extends SvelteComponent {
	constructor(options) {
		super();
		init(this, options, instance$e, create_fragment$e, safe_not_equal, {}, add_css$b);
	}
}

class AddStepModalContainer extends obsidian.Modal {
    constructor(app) {
        super(app);
    }
    onOpen() {
        const { contentEl } = this;
        contentEl.createEl("h1", { text: "Add Compile Step to Workfow" });
        const entrypoint = contentEl.createDiv("longform-add-step-root");
        const context = new Map();
        context.set("close", () => this.close());
        this.contents = new AddStepModal({
            target: entrypoint,
            context,
        });
    }
    onClose() {
        const { contentEl } = this;
        contentEl.empty();
    }
}

class ConfirmActionModal extends obsidian.Modal {
    constructor(app, title, explanation, yesText, yesAction, noText = "Cancel", noAction = () => this.close()) {
        super(app);
        this.title = title;
        this.explanation = explanation;
        this.yesText = yesText;
        this.yesAction = yesAction;
        this.noText = noText;
        this.noAction = noAction;
    }
    onOpen() {
        const { contentEl } = this;
        contentEl.createEl("h1", { text: this.title });
        contentEl.createEl("p", { text: this.explanation });
        new obsidian.ButtonComponent(contentEl)
            .setButtonText(this.noText)
            .onClick(this.noAction);
        new obsidian.ButtonComponent(contentEl)
            .setButtonText(this.yesText)
            .setWarning()
            .onClick(() => {
            this.yesAction();
            this.close();
        });
    }
    onClose() {
        const { contentEl } = this;
        contentEl.empty();
    }
}

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.9505 39.6204 34.1755C40.512 34.3839 41.4137 33.8288 41.6237 32.9322C41.8334 32.0373 41.2768 31.1406 40.3801 30.9306Z" fill="currentColor"/><path d="M40.3801 40.9305C30.0886 38.5173 18.3936 41.5923 17.902 41.7239C17.0137 41.9622 16.4854 42.8756 16.7237 43.7655C16.9237 44.5104 17.5969 45.0004 18.3321 45.0004C18.4754 45.0004 18.6203 44.9821 18.7655 44.9438C18.8772 44.9121 30.1371 41.9504 39.6204 44.1754C40.512 44.3838 41.4137 43.8288 41.6237 42.9321C41.8334 42.0372 41.2768 41.1405 40.3801 40.9305Z" fill="currentColor"/><path d="M56.8466 67.4235C57.1415 68.0003 57.7282 68.3335 58.3349 68.3335C58.5882 68.3335 58.8481 68.2751 59.0899 68.1518C59.1882 68.1018 68.9983 63.1185 73.8365 61.5902C74.7133 61.3118 75.1998 60.3751 74.9215 59.4986C74.6447 58.622 73.7148 58.1335 72.8299 58.4103C67.7332 60.022 57.99 64.972 57.5767 65.1819C56.7566 65.5985 56.43 66.602 56.8466 67.4235Z" fill="currentColor"/><path d="M40.3801 50.9305C30.0886 48.5172 18.3936 51.5904 17.902 51.7238C17.0137 51.9621 16.4854 52.8756 16.7237 53.7654C16.9237 54.5103 17.5969 55.0021 18.3321 55.0021C18.4754 55.0021 18.6203 54.9822 18.7655 54.9437C18.8772 54.9121 30.1371 51.9504 39.6204 54.1753C40.512 54.3837 41.4137 53.8287 41.6237 52.932C41.8334 52.0371 41.2768 51.1404 40.3801 50.9305Z" fill="currentColor"/><path d="M40.3801 70.9303C30.0886 68.5153 18.3936 71.592 17.902 71.7237C17.0137 71.9619 16.4854 72.8754 16.7237 73.7653C16.9237 74.5102 17.5969 75.002 18.3321 75.002C18.4754 75.002 18.6203 74.982 18.7655 74.9436C18.8772 74.9119 30.1371 71.9502 39.6204 74.1752C40.512 74.3818 41.4137 73.8285 41.6237 72.9319C41.8334 72.0369 41.2768 71.1403 40.3801 70.9303Z" fill="currentColor"/><path d="M40.3801 60.9304C30.0886 58.5154 18.3936 61.5903 17.902 61.7237C17.0137 61.962 16.4854 62.8755 16.7237 63.7653C16.9237 64.5102 17.5969 65.002 18.3321 65.002C18.4754 65.002 18.6203 64.9821 18.7655 64.9436C18.8772 64.912 30.1371 61.9503 39.6204 64.1753C40.512 64.3837 41.4137 63.8286 41.6237 62.9319C41.8334 62.037 41.2768 61.1403 40.3801 60.9304Z" fill="currentColor"/></g><defs><clipPath id="clip0"><rect width="100" height="100" fill="white"/></clipPath></defs></svg>';

/* src/view/compile/CompileStepView.svelte generated by Svelte v3.43.1 */

function add_css$a(target) {
	append_styles(target, "svelte-4icvr1", ".longform-compile-step.svelte-4icvr1.svelte-4icvr1{background-color:var(--background-modifier-form-field);border-radius:5px;padding:0.25rem 0.25rem 0.75rem 0.25rem;margin-bottom:1rem}.longform-compile-step-title-outer.svelte-4icvr1.svelte-4icvr1{display:flex;flex-direction:row;justify-content:space-between;align-items:flex-start}.longform-compile-step-title-container.svelte-4icvr1.svelte-4icvr1{display:flex;flex-direction:row;align-items:center;flex-wrap:wrap}.longform-compile-step-title-container.svelte-4icvr1 h4.svelte-4icvr1{display:inline-block;margin:0 0.5rem 0 0;padding:0}.longform-compile-step-title-container.svelte-4icvr1 .longform-step-kind-pill.svelte-4icvr1{display:flex;justify-content:center;align-items:center;background-color:var(--text-accent);color:var(--text-on-accent);border-radius:10px;font-size:0.7rem;font-weight:bold;padding:0.25rem;margin-right:0.25rem;height:1.2rem}.longform-remove-step-button.svelte-4icvr1.svelte-4icvr1{display:flex;width:20px;margin:0;align-items:center;justify-content:center;font-weight:bold}.longform-compile-step.svelte-4icvr1 p.svelte-4icvr1{margin:0;padding:0}.longform-compile-step-description.svelte-4icvr1.svelte-4icvr1{font-size:80%;color:var(--text-muted);margin-top:2px}.longform-compile-step-options.svelte-4icvr1.svelte-4icvr1{padding-left:0.5rem;border-left:1px solid var(--interactive-accent)}.longform-compile-step-option.svelte-4icvr1.svelte-4icvr1{margin-top:0.5rem}.longform-compile-step-option.svelte-4icvr1 label.svelte-4icvr1{display:block;font-weight:600;font-size:0.8rem}.longform-compile-step-option.svelte-4icvr1 input.svelte-4icvr1{color:var(--text-accent)}.longform-compile-step-checkbox-container.svelte-4icvr1.svelte-4icvr1{display:flex;flex-direction:row;align-items:center;justify-content:flex-start}.longform-compile-step-option.svelte-4icvr1 input[type=\"text\"].svelte-4icvr1{color:var(--text-accent);margin:0 0 4px 0}.longform-compile-step-option.svelte-4icvr1 input[type=\"checkbox\"].svelte-4icvr1{color:var(--text-accent);margin:0 0.5rem 2px 0}.longform-compile-step-option.svelte-4icvr1 input.svelte-4icvr1:focus{color:var(--text-accent-hover)}.longform-compile-step-option-description.svelte-4icvr1.svelte-4icvr1{font-size:0.8rem;line-height:0.9rem;color:var(--text-faint)}.longform-compile-step-error-container.svelte-4icvr1.svelte-4icvr1{margin-top:0.5rem}.longform-compile-step-error.svelte-4icvr1.svelte-4icvr1{color:var(--text-error);font-size:0.8rem;line-height:0.9rem}");
}

function get_each_context$4(ctx, list, i) {
	const child_ctx = ctx.slice();
	child_ctx[8] = list[i];
	child_ctx[9] = list;
	child_ctx[10] = i;
	return child_ctx;
}

// (31:2) {:else}
function create_else_block$2(ctx) {
	let div1;
	let div0;
	let h4;
	let t0;
	let t1;
	let t2_value = /*step*/ ctx[0].description.name + "";
	let t2;
	let t3;
	let t4;
	let button;
	let t6;
	let p;
	let t7_value = /*step*/ ctx[0].description.description + "";
	let t7;
	let t8;
	let div2;
	let t9;
	let if_block1_anchor;
	let mounted;
	let dispose;
	let if_block0 = /*calculatedKind*/ ctx[2] !== null && create_if_block_3$3(ctx);
	let each_value = /*step*/ ctx[0].description.options;
	let each_blocks = [];

	for (let i = 0; i < each_value.length; i += 1) {
		each_blocks[i] = create_each_block$4(get_each_context$4(ctx, each_value, i));
	}

	let if_block1 = /*error*/ ctx[3] && create_if_block_1$4(ctx);

	return {
		c() {
			div1 = element("div");
			div0 = element("div");
			h4 = element("h4");
			t0 = text(/*ordinal*/ ctx[1]);
			t1 = text(". ");
			t2 = text(t2_value);
			t3 = space();
			if (if_block0) if_block0.c();
			t4 = space();
			button = element("button");
			button.textContent = "X";
			t6 = space();
			p = element("p");
			t7 = text(t7_value);
			t8 = space();
			div2 = element("div");

			for (let i = 0; i < each_blocks.length; i += 1) {
				each_blocks[i].c();
			}

			t9 = space();
			if (if_block1) if_block1.c();
			if_block1_anchor = empty();
			attr(h4, "class", "svelte-4icvr1");
			attr(div0, "class", "longform-compile-step-title-container svelte-4icvr1");
			attr(button, "class", "longform-remove-step-button svelte-4icvr1");
			attr(div1, "class", "longform-compile-step-title-outer svelte-4icvr1");
			attr(p, "class", "longform-compile-step-description svelte-4icvr1");
			attr(div2, "class", "longform-compile-step-options svelte-4icvr1");
		},
		m(target, anchor) {
			insert(target, div1, anchor);
			append(div1, div0);
			append(div0, h4);
			append(h4, t0);
			append(h4, t1);
			append(h4, t2);
			append(div0, t3);
			if (if_block0) if_block0.m(div0, null);
			append(div1, t4);
			append(div1, button);
			insert(target, t6, anchor);
			insert(target, p, anchor);
			append(p, t7);
			insert(target, t8, anchor);
			insert(target, div2, anchor);

			for (let i = 0; i < each_blocks.length; i += 1) {
				each_blocks[i].m(div2, null);
			}

			insert(target, t9, anchor);
			if (if_block1) if_block1.m(target, anchor);
			insert(target, if_block1_anchor, anchor);

			if (!mounted) {
				dispose = listen(button, "click", /*removeStep*/ ctx[4]);
				mounted = true;
			}
		},
		p(ctx, dirty) {
			if (dirty & /*ordinal*/ 2) set_data(t0, /*ordinal*/ ctx[1]);
			if (dirty & /*step*/ 1 && t2_value !== (t2_value = /*step*/ ctx[0].description.name + "")) set_data(t2, t2_value);

			if (/*calculatedKind*/ ctx[2] !== null) {
				if (if_block0) {
					if_block0.p(ctx, dirty);
				} else {
					if_block0 = create_if_block_3$3(ctx);
					if_block0.c();
					if_block0.m(div0, null);
				}
			} else if (if_block0) {
				if_block0.d(1);
				if_block0 = null;
			}

			if (dirty & /*step*/ 1 && t7_value !== (t7_value = /*step*/ ctx[0].description.description + "")) set_data(t7, t7_value);

			if (dirty & /*step, CompileStepOptionType*/ 1) {
				each_value = /*step*/ ctx[0].description.options;
				let i;

				for (i = 0; i < each_value.length; i += 1) {
					const child_ctx = get_each_context$4(ctx, each_value, i);

					if (each_blocks[i]) {
						each_blocks[i].p(child_ctx, dirty);
					} else {
						each_blocks[i] = create_each_block$4(child_ctx);
						each_blocks[i].c();
						each_blocks[i].m(div2, null);
					}
				}

				for (; i < each_blocks.length; i += 1) {
					each_blocks[i].d(1);
				}

				each_blocks.length = each_value.length;
			}

			if (/*error*/ ctx[3]) {
				if (if_block1) {
					if_block1.p(ctx, dirty);
				} else {
					if_block1 = create_if_block_1$4(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);
			if (if_block0) if_block0.d();
			if (detaching) detach(t6);
			if (detaching) detach(p);
			if (detaching) detach(t8);
			if (detaching) detach(div2);
			destroy_each(each_blocks, detaching);
			if (detaching) detach(t9);
			if (if_block1) if_block1.d(detaching);
			if (detaching) detach(if_block1_anchor);
			mounted = false;
			dispose();
		}
	};
}

// (15:2) {#if step.description.canonicalID === PLACEHOLDER_MISSING_STEP.description.canonicalID}
function create_if_block$6(ctx) {
	let div1;
	let div0;
	let t1;
	let button;
	let t3;
	let div2;
	let mounted;
	let dispose;

	return {
		c() {
			div1 = element("div");
			div0 = element("div");
			div0.innerHTML = `<h4 class="svelte-4icvr1">Invalid Step</h4>`;
			t1 = space();
			button = element("button");
			button.textContent = "X";
			t3 = space();
			div2 = element("div");

			div2.innerHTML = `<p class="longform-compile-step-error svelte-4icvr1">This workflow contains a step that could not be loaded. Please delete
        the step to be able to run this workflow. If you’re on mobile, this may
        be a user script step that did not load.</p>`;

			attr(div0, "class", "longform-compile-step-title-container svelte-4icvr1");
			attr(button, "class", "longform-remove-step-button svelte-4icvr1");
			attr(div1, "class", "longform-compile-step-title-outer svelte-4icvr1");
			attr(div2, "class", "longform-compile-step-error-container svelte-4icvr1");
		},
		m(target, anchor) {
			insert(target, div1, anchor);
			append(div1, div0);
			append(div1, t1);
			append(div1, button);
			insert(target, t3, anchor);
			insert(target, div2, anchor);

			if (!mounted) {
				dispose = listen(button, "click", /*removeStep*/ ctx[4]);
				mounted = true;
			}
		},
		p: noop,
		d(detaching) {
			if (detaching) detach(div1);
			if (detaching) detach(t3);
			if (detaching) detach(div2);
			mounted = false;
			dispose();
		}
	};
}

// (35:8) {#if calculatedKind !== null}
function create_if_block_3$3(ctx) {
	let div;
	let t_value = formatStepKind(/*calculatedKind*/ ctx[2]) + "";
	let t;
	let div_title_value;

	return {
		c() {
			div = element("div");
			t = text(t_value);
			attr(div, "class", "longform-step-kind-pill svelte-4icvr1");
			attr(div, "title", div_title_value = explainStepKind(/*calculatedKind*/ ctx[2]));
		},
		m(target, anchor) {
			insert(target, div, anchor);
			append(div, t);
		},
		p(ctx, dirty) {
			if (dirty & /*calculatedKind*/ 4 && t_value !== (t_value = formatStepKind(/*calculatedKind*/ ctx[2]) + "")) set_data(t, t_value);

			if (dirty & /*calculatedKind*/ 4 && div_title_value !== (div_title_value = explainStepKind(/*calculatedKind*/ ctx[2]))) {
				attr(div, "title", div_title_value);
			}
		},
		d(detaching) {
			if (detaching) detach(div);
		}
	};
}

// (62:10) {:else}
function create_else_block_1$1(ctx) {
	let div;
	let input;
	let input_id_value;
	let t0;
	let label;
	let t1_value = /*option*/ ctx[8].name + "";
	let t1;
	let label_for_value;
	let mounted;
	let dispose;

	function input_change_handler() {
		/*input_change_handler*/ ctx[6].call(input, /*option*/ ctx[8]);
	}

	return {
		c() {
			div = element("div");
			input = element("input");
			t0 = space();
			label = element("label");
			t1 = text(t1_value);
			attr(input, "id", input_id_value = /*step*/ ctx[0].id + "-" + /*option*/ ctx[8].id);
			attr(input, "type", "checkbox");
			attr(input, "class", "svelte-4icvr1");
			attr(label, "for", label_for_value = /*step*/ ctx[0].id + "-" + /*option*/ ctx[8].id);
			attr(label, "class", "svelte-4icvr1");
			attr(div, "class", "longform-compile-step-checkbox-container svelte-4icvr1");
		},
		m(target, anchor) {
			insert(target, div, anchor);
			append(div, input);
			input.checked = /*step*/ ctx[0].optionValues[/*option*/ ctx[8].id];
			append(div, t0);
			append(div, label);
			append(label, t1);

			if (!mounted) {
				dispose = listen(input, "change", input_change_handler);
				mounted = true;
			}
		},
		p(new_ctx, dirty) {
			ctx = new_ctx;

			if (dirty & /*step*/ 1 && input_id_value !== (input_id_value = /*step*/ ctx[0].id + "-" + /*option*/ ctx[8].id)) {
				attr(input, "id", input_id_value);
			}

			if (dirty & /*step*/ 1) {
				input.checked = /*step*/ ctx[0].optionValues[/*option*/ ctx[8].id];
			}

			if (dirty & /*step*/ 1 && t1_value !== (t1_value = /*option*/ ctx[8].name + "")) set_data(t1, t1_value);

			if (dirty & /*step*/ 1 && label_for_value !== (label_for_value = /*step*/ ctx[0].id + "-" + /*option*/ ctx[8].id)) {
				attr(label, "for", label_for_value);
			}
		},
		d(detaching) {
			if (detaching) detach(div);
			mounted = false;
			dispose();
		}
	};
}

// (54:10) {#if option.type === CompileStepOptionType.Text}
function create_if_block_2$3(ctx) {
	let label;
	let t0_value = /*option*/ ctx[8].name + "";
	let t0;
	let label_for_value;
	let t1;
	let input;
	let input_id_value;
	let input_placeholder_value;
	let mounted;
	let dispose;

	function input_input_handler() {
		/*input_input_handler*/ ctx[5].call(input, /*option*/ ctx[8]);
	}

	return {
		c() {
			label = element("label");
			t0 = text(t0_value);
			t1 = space();
			input = element("input");
			attr(label, "for", label_for_value = /*step*/ ctx[0].id + "-" + /*option*/ ctx[8].id);
			attr(label, "class", "svelte-4icvr1");
			attr(input, "id", input_id_value = /*step*/ ctx[0].id + "-" + /*option*/ ctx[8].id);
			attr(input, "type", "text");
			attr(input, "placeholder", input_placeholder_value = /*option*/ ctx[8].default.replace(/\n/g, "\\n"));
			attr(input, "class", "svelte-4icvr1");
		},
		m(target, anchor) {
			insert(target, label, anchor);
			append(label, t0);
			insert(target, t1, anchor);
			insert(target, input, anchor);
			set_input_value(input, /*step*/ ctx[0].optionValues[/*option*/ ctx[8].id]);

			if (!mounted) {
				dispose = listen(input, "input", input_input_handler);
				mounted = true;
			}
		},
		p(new_ctx, dirty) {
			ctx = new_ctx;
			if (dirty & /*step*/ 1 && t0_value !== (t0_value = /*option*/ ctx[8].name + "")) set_data(t0, t0_value);

			if (dirty & /*step*/ 1 && label_for_value !== (label_for_value = /*step*/ ctx[0].id + "-" + /*option*/ ctx[8].id)) {
				attr(label, "for", label_for_value);
			}

			if (dirty & /*step*/ 1 && input_id_value !== (input_id_value = /*step*/ ctx[0].id + "-" + /*option*/ ctx[8].id)) {
				attr(input, "id", input_id_value);
			}

			if (dirty & /*step*/ 1 && input_placeholder_value !== (input_placeholder_value = /*option*/ ctx[8].default.replace(/\n/g, "\\n"))) {
				attr(input, "placeholder", input_placeholder_value);
			}

			if (dirty & /*step*/ 1 && input.value !== /*step*/ ctx[0].optionValues[/*option*/ ctx[8].id]) {
				set_input_value(input, /*step*/ ctx[0].optionValues[/*option*/ ctx[8].id]);
			}
		},
		d(detaching) {
			if (detaching) detach(label);
			if (detaching) detach(t1);
			if (detaching) detach(input);
			mounted = false;
			dispose();
		}
	};
}

// (52:6) {#each step.description.options as option}
function create_each_block$4(ctx) {
	let div;
	let t0;
	let p;
	let t1_value = /*option*/ ctx[8].description + "";
	let t1;
	let t2;

	function select_block_type_1(ctx, dirty) {
		if (/*option*/ ctx[8].type === CompileStepOptionType.Text) return create_if_block_2$3;
		return create_else_block_1$1;
	}

	let current_block_type = select_block_type_1(ctx);
	let if_block = current_block_type(ctx);

	return {
		c() {
			div = element("div");
			if_block.c();
			t0 = space();
			p = element("p");
			t1 = text(t1_value);
			t2 = space();
			attr(p, "class", "longform-compile-step-option-description svelte-4icvr1");
			attr(div, "class", "longform-compile-step-option svelte-4icvr1");
		},
		m(target, anchor) {
			insert(target, div, anchor);
			if_block.m(div, null);
			append(div, t0);
			append(div, p);
			append(p, t1);
			append(div, t2);
		},
		p(ctx, dirty) {
			if (current_block_type === (current_block_type = select_block_type_1(ctx)) && if_block) {
				if_block.p(ctx, dirty);
			} else {
				if_block.d(1);
				if_block = current_block_type(ctx);

				if (if_block) {
					if_block.c();
					if_block.m(div, t0);
				}
			}

			if (dirty & /*step*/ 1 && t1_value !== (t1_value = /*option*/ ctx[8].description + "")) set_data(t1, t1_value);
		},
		d(detaching) {
			if (detaching) detach(div);
			if_block.d();
		}
	};
}

// (78:4) {#if error}
function create_if_block_1$4(ctx) {
	let div;
	let p;
	let t;

	return {
		c() {
			div = element("div");
			p = element("p");
			t = text(/*error*/ ctx[3]);
			attr(p, "class", "longform-compile-step-error svelte-4icvr1");
			attr(div, "class", "longform-compile-step-error-container svelte-4icvr1");
		},
		m(target, anchor) {
			insert(target, div, anchor);
			append(div, p);
			append(p, t);
		},
		p(ctx, dirty) {
			if (dirty & /*error*/ 8) set_data(t, /*error*/ ctx[3]);
		},
		d(detaching) {
			if (detaching) detach(div);
		}
	};
}

function create_fragment$d(ctx) {
	let div;

	function select_block_type(ctx, dirty) {
		if (/*step*/ ctx[0].description.canonicalID === PLACEHOLDER_MISSING_STEP.description.canonicalID) return create_if_block$6;
		return create_else_block$2;
	}

	let current_block_type = select_block_type(ctx);
	let if_block = current_block_type(ctx);

	return {
		c() {
			div = element("div");
			if_block.c();
			attr(div, "class", "longform-compile-step svelte-4icvr1");
		},
		m(target, anchor) {
			insert(target, div, anchor);
			if_block.m(div, null);
		},
		p(ctx, [dirty]) {
			if (current_block_type === (current_block_type = select_block_type(ctx)) && if_block) {
				if_block.p(ctx, dirty);
			} else {
				if_block.d(1);
				if_block = current_block_type(ctx);

				if (if_block) {
					if_block.c();
					if_block.m(div, null);
				}
			}
		},
		i: noop,
		o: noop,
		d(detaching) {
			if (detaching) detach(div);
			if_block.d();
		}
	};
}

function instance$d($$self, $$props, $$invalidate) {
	let { step } = $$props;
	let { ordinal } = $$props;
	let { calculatedKind } = $$props;
	let { error } = $$props;
	const dispatch = createEventDispatcher();

	function removeStep() {
		dispatch("removeStep");
	}

	function input_input_handler(option) {
		step.optionValues[option.id] = this.value;
		$$invalidate(0, step);
	}

	function input_change_handler(option) {
		step.optionValues[option.id] = this.checked;
		$$invalidate(0, step);
	}

	$$self.$$set = $$props => {
		if ('step' in $$props) $$invalidate(0, step = $$props.step);
		if ('ordinal' in $$props) $$invalidate(1, ordinal = $$props.ordinal);
		if ('calculatedKind' in $$props) $$invalidate(2, calculatedKind = $$props.calculatedKind);
		if ('error' in $$props) $$invalidate(3, error = $$props.error);
	};

	return [
		step,
		ordinal,
		calculatedKind,
		error,
		removeStep,
		input_input_handler,
		input_change_handler
	];
}

class CompileStepView extends SvelteComponent {
	constructor(options) {
		super();

		init(
			this,
			options,
			instance$d,
			create_fragment$d,
			safe_not_equal,
			{
				step: 0,
				ordinal: 1,
				calculatedKind: 2,
				error: 3
			},
			add_css$a
		);
	}
}

/**!
 * 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(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(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.43.1 */

function get_each_context$3(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] });

// (31:2) {#each items as item (item.id)}
function create_each_block$3(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_base(
						default_slot,
						default_slot_template,
						ctx,
						/*$$scope*/ ctx[4],
						!current
						? get_all_dirty_from_scope(/*$$scope*/ ctx[4])
						: get_slot_changes(default_slot_template, /*$$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$c(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$3(ctx, each_value, i);
		let key = get_key(child_ctx);
		each_1_lookup.set(key, each_blocks[i] = create_each_block$3(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$3, null, get_each_context$3);
				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$c($$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$c, create_fragment$c, safe_not_equal, { items: 0, sortableOptions: 3 });
	}
}

/**
 * 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;

/** 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;

/**
 * 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;

/**
 * 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 `_.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;

/**
 * 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;
});

/** `Object#toString` result references. */
var argsTag$2 = '[object Arguments]',
    arrayTag$2 = '[object Array]',
    boolTag$3 = '[object Boolean]',
    dateTag$3 = '[object Date]',
    errorTag$2 = '[object Error]',
    funcTag$1 = '[object Function]',
    mapTag$5 = '[object Map]',
    numberTag$3 = '[object Number]',
    objectTag$4 = '[object Object]',
    regexpTag$3 = '[object RegExp]',
    setTag$5 = '[object Set]',
    stringTag$3 = '[object String]',
    weakMapTag$2 = '[object WeakMap]';

var arrayBufferTag$3 = '[object ArrayBuffer]',
    dataViewTag$4 = '[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$3] = typedArrayTags[boolTag$3] =
typedArrayTags[dataViewTag$4] = typedArrayTags[dateTag$3] =
typedArrayTags[errorTag$2] = typedArrayTags[funcTag$1] =
typedArrayTags[mapTag$5] = typedArrayTags[numberTag$3] =
typedArrayTags[objectTag$4] = typedArrayTags[regexpTag$3] =
typedArrayTags[setTag$5] = typedArrayTags[stringTag$3] =
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$8 = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty$6 = objectProto$8.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$7 = 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$7;

  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$6 = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty$5 = objectProto$6.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;

/**
 * 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$5 = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty$4 = objectProto$5.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$4.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;

/**
 * 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$4 = Object.prototype;

/** Built-in value references. */
var propertyIsEnumerable = objectProto$4.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.call(object, symbol);
  });
};

var _getSymbols = getSymbols;

/**
 * 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;

/**
 * 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;

/**
 * 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;

/**
 * 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;

/* 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$4 = '[object Map]',
    objectTag$3 = '[object Object]',
    promiseTag = '[object Promise]',
    setTag$4 = '[object Set]',
    weakMapTag$1 = '[object WeakMap]';

var dataViewTag$3 = '[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$3) ||
    (_Map && getTag(new _Map) != mapTag$4) ||
    (_Promise && getTag(_Promise.resolve()) != promiseTag) ||
    (_Set && getTag(new _Set) != setTag$4) ||
    (_WeakMap && getTag(new _WeakMap) != weakMapTag$1)) {
  getTag = function(value) {
    var result = _baseGetTag(value),
        Ctor = result == objectTag$3 ? value.constructor : undefined,
        ctorString = Ctor ? _toSource(Ctor) : '';

    if (ctorString) {
      switch (ctorString) {
        case dataViewCtorString: return dataViewTag$3;
        case mapCtorString: return mapTag$4;
        case promiseCtorString: return promiseTag;
        case setCtorString: return setTag$4;
        case weakMapCtorString: return weakMapTag$1;
      }
    }
    return result;
  };
}

var _getTag = getTag;

/** Used for built-in method references. */
var objectProto$3 = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty$3 = objectProto$3.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$3.call(array, 'index')) {
    result.index = array.index;
    result.input = array.input;
  }
  return result;
}

var _initCloneArray = initCloneArray;

/** Built-in value references. */
var Uint8Array = _root.Uint8Array;

var _Uint8Array = Uint8Array;

/**
 * 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$1 = _Symbol ? _Symbol.prototype : undefined,
    symbolValueOf$1 = symbolProto$1 ? symbolProto$1.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$1 ? Object(symbolValueOf$1.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$2 = '[object Boolean]',
    dateTag$2 = '[object Date]',
    mapTag$3 = '[object Map]',
    numberTag$2 = '[object Number]',
    regexpTag$2 = '[object RegExp]',
    setTag$3 = '[object Set]',
    stringTag$2 = '[object String]',
    symbolTag$2 = '[object Symbol]';

var arrayBufferTag$2 = '[object ArrayBuffer]',
    dataViewTag$2 = '[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$2:
      return _cloneArrayBuffer(object);

    case boolTag$2:
    case dateTag$2:
      return new Ctor(+object);

    case dataViewTag$2:
      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$3:
      return new Ctor;

    case numberTag$2:
    case stringTag$2:
      return new Ctor(object);

    case regexpTag$2:
      return _cloneRegExp(object);

    case setTag$3:
      return new Ctor;

    case symbolTag$2:
      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$2 = '[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$2;
}

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$2 = '[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$2;
}

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$2 = 1,
    CLONE_FLAT_FLAG$1 = 2,
    CLONE_SYMBOLS_FLAG$2 = 4;

/** `Object#toString` result references. */
var argsTag$1 = '[object Arguments]',
    arrayTag$1 = '[object Array]',
    boolTag$1 = '[object Boolean]',
    dateTag$1 = '[object Date]',
    errorTag$1 = '[object Error]',
    funcTag = '[object Function]',
    genTag = '[object GeneratorFunction]',
    mapTag$1 = '[object Map]',
    numberTag$1 = '[object Number]',
    objectTag$2 = '[object Object]',
    regexpTag$1 = '[object RegExp]',
    setTag$1 = '[object Set]',
    stringTag$1 = '[object String]',
    symbolTag$1 = '[object Symbol]',
    weakMapTag = '[object WeakMap]';

var arrayBufferTag$1 = '[object ArrayBuffer]',
    dataViewTag$1 = '[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$1] = cloneableTags[arrayTag$1] =
cloneableTags[arrayBufferTag$1] = cloneableTags[dataViewTag$1] =
cloneableTags[boolTag$1] = cloneableTags[dateTag$1] =
cloneableTags[float32Tag] = cloneableTags[float64Tag] =
cloneableTags[int8Tag] = cloneableTags[int16Tag] =
cloneableTags[int32Tag] = cloneableTags[mapTag$1] =
cloneableTags[numberTag$1] = cloneableTags[objectTag$2] =
cloneableTags[regexpTag$1] = cloneableTags[setTag$1] =
cloneableTags[stringTag$1] = cloneableTags[symbolTag$1] =
cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
cloneableTags[errorTag$1] = 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$2,
      isFlat = bitmask & CLONE_FLAT_FLAG$1,
      isFull = bitmask & CLONE_SYMBOLS_FLAG$2;

  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$2 || tag == argsTag$1 || (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;

/**
 * Gets the last element of `array`.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Array
 * @param {Array} array The array to query.
 * @returns {*} Returns the last element of `array`.
 * @example
 *
 * _.last([1, 2, 3]);
 * // => 3
 */
function last(array) {
  var length = array == null ? 0 : array.length;
  return length ? array[length - 1] : undefined;
}

var last_1 = last;

/**
 * The base implementation of `_.slice` without an iteratee call guard.
 *
 * @private
 * @param {Array} array The array to slice.
 * @param {number} [start=0] The start position.
 * @param {number} [end=array.length] The end position.
 * @returns {Array} Returns the slice of `array`.
 */
function baseSlice(array, start, end) {
  var index = -1,
      length = array.length;

  if (start < 0) {
    start = -start > length ? 0 : (length + start);
  }
  end = end > length ? length : end;
  if (end < 0) {
    end += length;
  }
  length = start > end ? 0 : ((end - start) >>> 0);
  start >>>= 0;

  var result = Array(length);
  while (++index < length) {
    result[index] = array[index + start];
  }
  return result;
}

var _baseSlice = baseSlice;

/**
 * Gets the parent value at `path` of `object`.
 *
 * @private
 * @param {Object} object The object to query.
 * @param {Array} path The path to get the parent value of.
 * @returns {*} Returns the parent value.
 */
function parent(object, path) {
  return path.length < 2 ? object : _baseGet(object, _baseSlice(path, 0, -1));
}

var _parent = parent;

/**
 * The base implementation of `_.unset`.
 *
 * @private
 * @param {Object} object The object to modify.
 * @param {Array|string} path The property path to unset.
 * @returns {boolean} Returns `true` if the property is deleted, else `false`.
 */
function baseUnset(object, path) {
  path = _castPath(path, object);
  object = _parent(object, path);
  return object == null || delete object[_toKey(last_1(path))];
}

var _baseUnset = baseUnset;

/** `Object#toString` result references. */
var objectTag$1 = '[object Object]';

/** Used for built-in method references. */
var funcProto = Function.prototype,
    objectProto$2 = Object.prototype;

/** Used to resolve the decompiled source of functions. */
var funcToString = funcProto.toString;

/** Used to check objects for own properties. */
var hasOwnProperty$2 = objectProto$2.hasOwnProperty;

/** Used to infer the `Object` constructor. */
var objectCtorString = funcToString.call(Object);

/**
 * Checks if `value` is a plain object, that is, an object created by the
 * `Object` constructor or one with a `[[Prototype]]` of `null`.
 *
 * @static
 * @memberOf _
 * @since 0.8.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
 * @example
 *
 * function Foo() {
 *   this.a = 1;
 * }
 *
 * _.isPlainObject(new Foo);
 * // => false
 *
 * _.isPlainObject([1, 2, 3]);
 * // => false
 *
 * _.isPlainObject({ 'x': 0, 'y': 0 });
 * // => true
 *
 * _.isPlainObject(Object.create(null));
 * // => true
 */
function isPlainObject(value) {
  if (!isObjectLike_1(value) || _baseGetTag(value) != objectTag$1) {
    return false;
  }
  var proto = _getPrototype(value);
  if (proto === null) {
    return true;
  }
  var Ctor = hasOwnProperty$2.call(proto, 'constructor') && proto.constructor;
  return typeof Ctor == 'function' && Ctor instanceof Ctor &&
    funcToString.call(Ctor) == objectCtorString;
}

var isPlainObject_1 = isPlainObject;

/**
 * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain
 * objects.
 *
 * @private
 * @param {*} value The value to inspect.
 * @param {string} key The key of the property to inspect.
 * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.
 */
function customOmitClone(value) {
  return isPlainObject_1(value) ? undefined : value;
}

var _customOmitClone = customOmitClone;

/** Used to compose bitmasks for cloning. */
var CLONE_DEEP_FLAG$1 = 1,
    CLONE_FLAT_FLAG = 2,
    CLONE_SYMBOLS_FLAG$1 = 4;

/**
 * The opposite of `_.pick`; this method creates an object composed of the
 * own and inherited enumerable property paths of `object` that are not omitted.
 *
 * **Note:** This method is considerably slower than `_.pick`.
 *
 * @static
 * @since 0.1.0
 * @memberOf _
 * @category Object
 * @param {Object} object The source object.
 * @param {...(string|string[])} [paths] The property paths to omit.
 * @returns {Object} Returns the new object.
 * @example
 *
 * var object = { 'a': 1, 'b': '2', 'c': 3 };
 *
 * _.omit(object, ['a', 'c']);
 * // => { 'b': '2' }
 */
var omit = _flatRest(function(object, paths) {
  var result = {};
  if (object == null) {
    return result;
  }
  var isDeep = false;
  paths = _arrayMap(paths, function(path) {
    path = _castPath(path, object);
    isDeep || (isDeep = path.length > 1);
    return path;
  });
  _copyObject(object, _getAllKeysIn(object), result);
  if (isDeep) {
    result = _baseClone(result, CLONE_DEEP_FLAG$1 | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG$1, _customOmitClone);
  }
  var length = paths.length;
  while (length--) {
    _baseUnset(result, paths[length]);
  }
  return result;
});

var omit_1 = omit;

/* src/view/components/AutoTextArea.svelte generated by Svelte v3.43.1 */

function add_css$9(target) {
	append_styles(target, "svelte-15olgdc", ".container.svelte-15olgdc{position:relative}pre.svelte-15olgdc,textarea.svelte-15olgdc{font-family:inherit;padding:0.5rem;box-sizing:border-box;border:none;line-height:1.2;overflow:hidden}textarea.svelte-15olgdc{position:absolute;width:100%;height:100%;top:0;resize:none}");
}

function create_fragment$b(ctx) {
	let div;
	let pre;
	let t0_value = /*value*/ ctx[0] + "\n" + "";
	let t0;
	let t1;
	let textarea;
	let mounted;
	let dispose;
	let textarea_levels = [/*props*/ ctx[3]];
	let textarea_data = {};

	for (let i = 0; i < textarea_levels.length; i += 1) {
		textarea_data = assign(textarea_data, textarea_levels[i]);
	}

	return {
		c() {
			div = element("div");
			pre = element("pre");
			t0 = text(t0_value);
			t1 = space();
			textarea = element("textarea");
			attr(pre, "aria-hidden", "true");
			set_style(pre, "min-height", /*minHeight*/ ctx[2]);
			set_style(pre, "max-height", /*maxHeight*/ ctx[1]);
			attr(pre, "class", "svelte-15olgdc");
			set_attributes(textarea, textarea_data);
			toggle_class(textarea, "svelte-15olgdc", true);
			attr(div, "class", "container svelte-15olgdc");
		},
		m(target, anchor) {
			insert(target, div, anchor);
			append(div, pre);
			append(pre, t0);
			append(div, t1);
			append(div, textarea);
			if (textarea.autofocus) textarea.focus();
			set_input_value(textarea, /*value*/ ctx[0]);

			if (!mounted) {
				dispose = listen(textarea, "input", /*textarea_input_handler*/ ctx[6]);
				mounted = true;
			}
		},
		p(ctx, [dirty]) {
			if (dirty & /*value*/ 1 && t0_value !== (t0_value = /*value*/ ctx[0] + "\n" + "")) set_data(t0, t0_value);

			if (dirty & /*minHeight*/ 4) {
				set_style(pre, "min-height", /*minHeight*/ ctx[2]);
			}

			if (dirty & /*maxHeight*/ 2) {
				set_style(pre, "max-height", /*maxHeight*/ ctx[1]);
			}

			set_attributes(textarea, textarea_data = get_spread_update(textarea_levels, [/*props*/ ctx[3]]));

			if (dirty & /*value*/ 1) {
				set_input_value(textarea, /*value*/ ctx[0]);
			}

			toggle_class(textarea, "svelte-15olgdc", true);
		},
		i: noop,
		o: noop,
		d(detaching) {
			if (detaching) detach(div);
			mounted = false;
			dispose();
		}
	};
}

function instance$b($$self, $$props, $$invalidate) {
	let minHeight;
	let maxHeight;
	let { value = "" } = $$props;
	let { minRows = 1 } = $$props;
	let { maxRows } = $$props;
	const props = omit_1($$props, ["children", "$$slots", "$$scope"]);

	function textarea_input_handler() {
		value = this.value;
		$$invalidate(0, value);
	}

	$$self.$$set = $$new_props => {
		$$invalidate(7, $$props = assign(assign({}, $$props), exclude_internal_props($$new_props)));
		if ('value' in $$new_props) $$invalidate(0, value = $$new_props.value);
		if ('minRows' in $$new_props) $$invalidate(4, minRows = $$new_props.minRows);
		if ('maxRows' in $$new_props) $$invalidate(5, maxRows = $$new_props.maxRows);
	};

	$$self.$$.update = () => {
		if ($$self.$$.dirty & /*minRows*/ 16) {
			$$invalidate(2, minHeight = `${minRows * 1.2}rem`);
		}

		if ($$self.$$.dirty & /*maxRows*/ 32) {
			$$invalidate(1, maxHeight = maxRows ? `${1 + maxRows * 1.2}rem` : `auto`);
		}
	};

	$$props = exclude_internal_props($$props);
	return [value, maxHeight, minHeight, props, minRows, maxRows, textarea_input_handler];
}

class AutoTextArea extends SvelteComponent {
	constructor(options) {
		super();
		init(this, options, instance$b, create_fragment$b, safe_not_equal, { value: 0, minRows: 4, maxRows: 5 }, add_css$9);
	}
}

/* src/view/compile/CompileView.svelte generated by Svelte v3.43.1 */

function add_css$8(target) {
	append_styles(target, "svelte-1ylbuwy", ".longform-workflow-picker-container.svelte-1ylbuwy.svelte-1ylbuwy{margin-bottom:2rem;padding:0.5rem 0;border-bottom:1px solid var(--background-modifier-border);display:flex;flex-direction:column}.longform-workflow-picker.svelte-1ylbuwy.svelte-1ylbuwy{display:flex;flex-direction:row;justify-content:space-between;align-items:center;flex-wrap:wrap;margin-bottom:0.5rem}.longform-workflow-picker.svelte-1ylbuwy .longform-hint.svelte-1ylbuwy{font-size:1rem}select.svelte-1ylbuwy.svelte-1ylbuwy{background-color:transparent;border:none;padding:5px 0;margin:0;font-family:inherit;font-size:inherit;cursor:inherit;line-height:inherit;outline:none}.select.svelte-1ylbuwy.svelte-1ylbuwy{cursor:pointer}.select.svelte-1ylbuwy>select.svelte-1ylbuwy{color:var(--text-accent)}.select.svelte-1ylbuwy>select.svelte-1ylbuwy:hover{text-decoration:underline;color:var(--text-accent-hover)}.longform-compile-container.svelte-1ylbuwy .longform-sortable-step-list{list-style-type:none;padding:0px;margin:0px}.options-button.svelte-1ylbuwy.svelte-1ylbuwy{background-color:var(--background-secondary-alt);color:var(--text-accent)}.options-button.svelte-1ylbuwy.svelte-1ylbuwy:hover{background-color:var(--background-primary);color:var(--text-accent-hover)}.add-step-container.svelte-1ylbuwy.svelte-1ylbuwy{display:flex;flex-direction:row;align-items:center;justify-content:center}.add-step-container.svelte-1ylbuwy button.svelte-1ylbuwy{font-weight:bold;color:var(--text-accent)}.add-step-container.svelte-1ylbuwy button.svelte-1ylbuwy:hover{text-decoration:underline;color:var(--text-accent-hover)}.compile-button.svelte-1ylbuwy.svelte-1ylbuwy{font-weight:bold;background-color:var(--interactive-accent);color:var(--text-on-accent)}.compile-button.svelte-1ylbuwy.svelte-1ylbuwy:hover{background-color:var(--interactive-accent-hover);color:var(--text-on-accent)}.compile-button.svelte-1ylbuwy.svelte-1ylbuwy:disabled{background-color:var(--text-muted);color:var(--text-faint)}.longform-compile-run-container.svelte-1ylbuwy.svelte-1ylbuwy{display:flex;flex-direction:row;align-items:center;justify-content:space-between;margin-top:2rem}.longform-compile-run-container.svelte-1ylbuwy .compile-status.svelte-1ylbuwy{color:var(--text-muted)}.compile-status-error{color:var(--text-error) !important}.compile-status-success{color:var(--interactive-success) !important}.step-ghost{background-color:var(--interactive-accent-hover);color:var(--text-on-accent)}");
}

function get_each_context$2(ctx, list, i) {
	const child_ctx = ctx.slice();
	child_ctx[49] = list[i];
	return child_ctx;
}

// (254:0) {#if $currentProject && $currentDraft}
function create_if_block$5(ctx) {
	let div3;
	let div1;
	let div0;
	let t0;
	let t1;
	let t2;
	let p;
	let t12;
	let div2;
	let current;

	function select_block_type(ctx, dirty) {
		if (/*workflowInputState*/ ctx[7] !== "hidden") return create_if_block_5;
		return create_else_block$1;
	}

	let current_block_type = select_block_type(ctx);
	let if_block0 = current_block_type(ctx);
	let if_block1 = /*$workflows*/ ctx[4][/*currentWorkflowName*/ ctx[1]] && create_if_block_4(ctx);
	let if_block2 = /*$workflows*/ ctx[4][/*currentWorkflowName*/ ctx[1]] && create_if_block_2$2(ctx);
	let if_block3 = /*$currentWorkflow*/ ctx[2] && /*$currentWorkflow*/ ctx[2].steps.length > 0 && create_if_block_1$3(ctx);

	return {
		c() {
			div3 = element("div");
			div1 = element("div");
			div0 = element("div");
			if_block0.c();
			t0 = space();
			if (if_block1) if_block1.c();
			t1 = space();
			if (if_block2) if_block2.c();
			t2 = space();
			p = element("p");

			p.innerHTML = `Compile workflows run their steps in order.<br/><b>Scene</b> workflows
      run once per scene.<br/><b>Join</b> workflows run once and combine the
      rest of your scene steps into a single manuscript.<br/><b>Manuscript</b>
      steps run once on the joined manuscript.<br/>Drag to rearrange.
      <a href="https://github.com/kevboh/longform/blob/main/docs/COMPILE.md">Documentation here.</a>`;

			t12 = space();
			div2 = element("div");
			if (if_block3) if_block3.c();
			attr(div0, "class", "longform-workflow-picker svelte-1ylbuwy");
			attr(div1, "class", "longform-workflow-picker-container svelte-1ylbuwy");
			attr(div2, "class", "longform-compile-run-container svelte-1ylbuwy");
			attr(div3, "class", "longform-compile-container svelte-1ylbuwy");
		},
		m(target, anchor) {
			insert(target, div3, anchor);
			append(div3, div1);
			append(div1, div0);
			if_block0.m(div0, null);
			append(div1, t0);
			if (if_block1) if_block1.m(div1, null);
			append(div3, t1);
			if (if_block2) if_block2.m(div3, null);
			append(div3, t2);
			append(div3, p);
			append(div3, t12);
			append(div3, div2);
			if (if_block3) if_block3.m(div2, null);
			current = true;
		},
		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(div0, null);
				}
			}

			if (/*$workflows*/ ctx[4][/*currentWorkflowName*/ ctx[1]]) {
				if (if_block1) {
					if_block1.p(ctx, dirty);

					if (dirty[0] & /*$workflows, currentWorkflowName*/ 18) {
						transition_in(if_block1, 1);
					}
				} else {
					if_block1 = create_if_block_4(ctx);
					if_block1.c();
					transition_in(if_block1, 1);
					if_block1.m(div1, null);
				}
			} else if (if_block1) {
				group_outros();

				transition_out(if_block1, 1, 1, () => {
					if_block1 = null;
				});

				check_outros();
			}

			if (/*$workflows*/ ctx[4][/*currentWorkflowName*/ ctx[1]]) {
				if (if_block2) {
					if_block2.p(ctx, dirty);

					if (dirty[0] & /*$workflows, currentWorkflowName*/ 18) {
						transition_in(if_block2, 1);
					}
				} else {
					if_block2 = create_if_block_2$2(ctx);
					if_block2.c();
					transition_in(if_block2, 1);
					if_block2.m(div3, t2);
				}
			} else if (if_block2) {
				group_outros();

				transition_out(if_block2, 1, 1, () => {
					if_block2 = null;
				});

				check_outros();
			}

			if (/*$currentWorkflow*/ ctx[2] && /*$currentWorkflow*/ ctx[2].steps.length > 0) {
				if (if_block3) {
					if_block3.p(ctx, dirty);
				} else {
					if_block3 = create_if_block_1$3(ctx);
					if_block3.c();
					if_block3.m(div2, null);
				}
			} else if (if_block3) {
				if_block3.d(1);
				if_block3 = null;
			}
		},
		i(local) {
			if (current) return;
			transition_in(if_block1);
			transition_in(if_block2);
			current = true;
		},
		o(local) {
			transition_out(if_block1);
			transition_out(if_block2);
			current = false;
		},
		d(detaching) {
			if (detaching) detach(div3);
			if_block0.d();
			if (if_block1) if_block1.d();
			if (if_block2) if_block2.d();
			if (if_block3) if_block3.d();
		}
	};
}

// (277:8) {:else}
function create_else_block$1(ctx) {
	let t0;
	let button;
	let mounted;
	let dispose;

	function select_block_type_1(ctx, dirty) {
		if (/*allWorkflowNames*/ ctx[0].length == 0) return create_if_block_6;
		return create_else_block_1;
	}

	let current_block_type = select_block_type_1(ctx);
	let if_block = current_block_type(ctx);

	return {
		c() {
			if_block.c();
			t0 = space();
			button = element("button");
			button.textContent = "▼";
			attr(button, "class", "options-button svelte-1ylbuwy");
			attr(button, "title", "Workflow Actions");
		},
		m(target, anchor) {
			if_block.m(target, anchor);
			insert(target, t0, anchor);
			insert(target, button, anchor);
			/*button_binding*/ ctx[32](button);

			if (!mounted) {
				dispose = listen(button, "click", /*click_handler*/ ctx[33]);
				mounted = true;
			}
		},
		p(ctx, dirty) {
			if (current_block_type === (current_block_type = select_block_type_1(ctx)) && if_block) {
				if_block.p(ctx, dirty);
			} else {
				if_block.d(1);
				if_block = current_block_type(ctx);

				if (if_block) {
					if_block.c();
					if_block.m(t0.parentNode, t0);
				}
			}
		},
		d(detaching) {
			if_block.d(detaching);
			if (detaching) detach(t0);
			if (detaching) detach(button);
			/*button_binding*/ ctx[32](null);
			mounted = false;
			dispose();
		}
	};
}

// (258:8) {#if workflowInputState !== "hidden"}
function create_if_block_5(ctx) {
	let input;
	let input_placeholder_value;
	let mounted;
	let dispose;

	return {
		c() {
			input = element("input");
			attr(input, "type", "text");

			attr(input, "placeholder", input_placeholder_value = /*workflowInputState*/ ctx[7] == "new"
			? "New Workflow…"
			: "My Cool Workflow");
		},
		m(target, anchor) {
			insert(target, input, anchor);
			set_input_value(input, /*workflowInputValue*/ ctx[8]);
			/*input_binding*/ ctx[29](input);

			if (!mounted) {
				dispose = [
					listen(input, "input", /*input_input_handler*/ ctx[28]),
					listen(input, "keydown", /*keydown_handler*/ ctx[30]),
					action_destroyer(focusOnInit.call(null, input))
				];

				mounted = true;
			}
		},
		p(ctx, dirty) {
			if (dirty[0] & /*workflowInputState*/ 128 && input_placeholder_value !== (input_placeholder_value = /*workflowInputState*/ ctx[7] == "new"
			? "New Workflow…"
			: "My Cool Workflow")) {
				attr(input, "placeholder", input_placeholder_value);
			}

			if (dirty[0] & /*workflowInputValue*/ 256 && input.value !== /*workflowInputValue*/ ctx[8]) {
				set_input_value(input, /*workflowInputValue*/ ctx[8]);
			}
		},
		d(detaching) {
			if (detaching) detach(input);
			/*input_binding*/ ctx[29](null);
			mounted = false;
			run_all(dispose);
		}
	};
}

// (280:10) {:else}
function create_else_block_1(ctx) {
	let div;
	let select;
	let mounted;
	let dispose;
	let each_value = /*allWorkflowNames*/ ctx[0];
	let each_blocks = [];

	for (let i = 0; i < each_value.length; i += 1) {
		each_blocks[i] = create_each_block$2(get_each_context$2(ctx, each_value, i));
	}

	return {
		c() {
			div = element("div");
			select = element("select");

			for (let i = 0; i < each_blocks.length; i += 1) {
				each_blocks[i].c();
			}

			attr(select, "id", "longform-workflows");
			attr(select, "class", "svelte-1ylbuwy");
			if (/*$projectMetadata*/ ctx[5][/*$currentProjectPath*/ ctx[3]].workflow === void 0) add_render_callback(() => /*select_change_handler*/ ctx[31].call(select));
			attr(div, "class", "select svelte-1ylbuwy");
		},
		m(target, 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, /*$projectMetadata*/ ctx[5][/*$currentProjectPath*/ ctx[3]].workflow);

			if (!mounted) {
				dispose = listen(select, "change", /*select_change_handler*/ ctx[31]);
				mounted = true;
			}
		},
		p(ctx, dirty) {
			if (dirty[0] & /*allWorkflowNames*/ 1) {
				each_value = /*allWorkflowNames*/ ctx[0];
				let i;

				for (i = 0; i < each_value.length; i += 1) {
					const child_ctx = get_each_context$2(ctx, each_value, i);

					if (each_blocks[i]) {
						each_blocks[i].p(child_ctx, dirty);
					} else {
						each_blocks[i] = create_each_block$2(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[0] & /*$projectMetadata, $currentProjectPath, allWorkflowNames*/ 41) {
				select_option(select, /*$projectMetadata*/ ctx[5][/*$currentProjectPath*/ ctx[3]].workflow);
			}
		},
		d(detaching) {
			if (detaching) detach(div);
			destroy_each(each_blocks, detaching);
			mounted = false;
			dispose();
		}
	};
}

// (278:10) {#if allWorkflowNames.length == 0}
function create_if_block_6(ctx) {
	let span;

	return {
		c() {
			span = element("span");
			span.textContent = "Create a new workflow to begin →";
			attr(span, "class", "longform-hint svelte-1ylbuwy");
		},
		m(target, anchor) {
			insert(target, span, anchor);
		},
		p: noop,
		d(detaching) {
			if (detaching) detach(span);
		}
	};
}

// (286:16) {#each allWorkflowNames as workflowOption}
function create_each_block$2(ctx) {
	let option;
	let t_value = /*workflowOption*/ ctx[49] + "";
	let t;
	let option_value_value;

	return {
		c() {
			option = element("option");
			t = text(t_value);
			option.__value = option_value_value = /*workflowOption*/ ctx[49];
			option.value = option.__value;
		},
		m(target, anchor) {
			insert(target, option, anchor);
			append(option, t);
		},
		p(ctx, dirty) {
			if (dirty[0] & /*allWorkflowNames*/ 1 && t_value !== (t_value = /*workflowOption*/ ctx[49] + "")) set_data(t, t_value);

			if (dirty[0] & /*allWorkflowNames*/ 1 && option_value_value !== (option_value_value = /*workflowOption*/ ctx[49])) {
				option.__value = option_value_value;
				option.value = option.__value;
			}
		},
		d(detaching) {
			if (detaching) detach(option);
		}
	};
}

// (308:6) {#if $workflows[currentWorkflowName]}
function create_if_block_4(ctx) {
	let autotextarea;
	let updating_value;
	let current;

	function autotextarea_value_binding(value) {
		/*autotextarea_value_binding*/ ctx[34](value);
	}

	let autotextarea_props = {
		placeholder: "Click here to leave a description of your workflow…",
		minRows: 2,
		maxRows: 5
	};

	if (/*$workflows*/ ctx[4][/*currentWorkflowName*/ ctx[1]].description !== void 0) {
		autotextarea_props.value = /*$workflows*/ ctx[4][/*currentWorkflowName*/ ctx[1]].description;
	}

	autotextarea = new AutoTextArea({ props: autotextarea_props });
	binding_callbacks.push(() => bind(autotextarea, 'value', autotextarea_value_binding));

	return {
		c() {
			create_component(autotextarea.$$.fragment);
		},
		m(target, anchor) {
			mount_component(autotextarea, target, anchor);
			current = true;
		},
		p(ctx, dirty) {
			const autotextarea_changes = {};

			if (!updating_value && dirty[0] & /*$workflows, currentWorkflowName*/ 18) {
				updating_value = true;
				autotextarea_changes.value = /*$workflows*/ ctx[4][/*currentWorkflowName*/ ctx[1]].description;
				add_flush_callback(() => updating_value = false);
			}

			autotextarea.$set(autotextarea_changes);
		},
		i(local) {
			if (current) return;
			transition_in(autotextarea.$$.fragment, local);
			current = true;
		},
		o(local) {
			transition_out(autotextarea.$$.fragment, local);
			current = false;
		},
		d(detaching) {
			destroy_component(autotextarea, detaching);
		}
	};
}

// (317:4) {#if $workflows[currentWorkflowName]}
function create_if_block_2$2(ctx) {
	let sortablelist;
	let updating_items;
	let t;
	let div;
	let show_if = Object.keys(/*$workflows*/ ctx[4]).length > 0;
	let current;

	function sortablelist_items_binding(value) {
		/*sortablelist_items_binding*/ ctx[37](value);
	}

	let sortablelist_props = {
		sortableOptions: /*sortableOptions*/ ctx[23],
		class: "longform-sortable-step-list",
		$$slots: {
			default: [
				create_default_slot$3,
				({ item }) => ({ 48: item }),
				({ item }) => [0, item ? 131072 : 0]
			]
		},
		$$scope: { ctx }
	};

	if (/*items*/ ctx[14] !== void 0) {
		sortablelist_props.items = /*items*/ ctx[14];
	}

	sortablelist = new SortableList({ props: sortablelist_props });
	binding_callbacks.push(() => bind(sortablelist, 'items', sortablelist_items_binding));
	sortablelist.$on("orderChanged", /*itemOrderChanged*/ ctx[24]);
	let if_block = show_if && create_if_block_3$2(ctx);

	return {
		c() {
			create_component(sortablelist.$$.fragment);
			t = space();
			div = element("div");
			if (if_block) if_block.c();
			attr(div, "class", "add-step-container svelte-1ylbuwy");
		},
		m(target, anchor) {
			mount_component(sortablelist, target, anchor);
			insert(target, t, anchor);
			insert(target, div, anchor);
			if (if_block) if_block.m(div, null);
			current = true;
		},
		p(ctx, dirty) {
			const sortablelist_changes = {};

			if (dirty[0] & /*$workflows, currentWorkflowName, $currentWorkflow*/ 22 | dirty[1] & /*$$scope, item*/ 2228224) {
				sortablelist_changes.$$scope = { dirty, ctx };
			}

			if (!updating_items && dirty[0] & /*items*/ 16384) {
				updating_items = true;
				sortablelist_changes.items = /*items*/ ctx[14];
				add_flush_callback(() => updating_items = false);
			}

			sortablelist.$set(sortablelist_changes);
			if (dirty[0] & /*$workflows*/ 16) show_if = Object.keys(/*$workflows*/ ctx[4]).length > 0;

			if (show_if) {
				if (if_block) {
					if_block.p(ctx, dirty);
				} else {
					if_block = create_if_block_3$2(ctx);
					if_block.c();
					if_block.m(div, null);
				}
			} else if (if_block) {
				if_block.d(1);
				if_block = null;
			}
		},
		i(local) {
			if (current) return;
			transition_in(sortablelist.$$.fragment, local);
			current = true;
		},
		o(local) {
			transition_out(sortablelist.$$.fragment, local);
			current = false;
		},
		d(detaching) {
			destroy_component(sortablelist, detaching);
			if (detaching) detach(t);
			if (detaching) detach(div);
			if (if_block) if_block.d();
		}
	};
}

// (318:6) <SortableList         bind:items         let:item         {sortableOptions}         on:orderChanged={itemOrderChanged}         class="longform-sortable-step-list"       >
function create_default_slot$3(ctx) {
	let compilestepview;
	let updating_step;
	let current;

	function compilestepview_step_binding(value) {
		/*compilestepview_step_binding*/ ctx[35](value, /*item*/ ctx[48]);
	}

	function removeStep_handler() {
		return /*removeStep_handler*/ ctx[36](/*item*/ ctx[48]);
	}

	let compilestepview_props = {
		ordinal: /*item*/ ctx[48].index + 1,
		calculatedKind: /*kindAtIndex*/ ctx[21](/*item*/ ctx[48].index),
		error: /*errorAtIndex*/ ctx[22](/*item*/ ctx[48].index)
	};

	if (/*$workflows*/ ctx[4][/*currentWorkflowName*/ ctx[1]].steps[/*item*/ ctx[48].index] !== void 0) {
		compilestepview_props.step = /*$workflows*/ ctx[4][/*currentWorkflowName*/ ctx[1]].steps[/*item*/ ctx[48].index];
	}

	compilestepview = new CompileStepView({ props: compilestepview_props });
	binding_callbacks.push(() => bind(compilestepview, 'step', compilestepview_step_binding));
	compilestepview.$on("removeStep", removeStep_handler);

	return {
		c() {
			create_component(compilestepview.$$.fragment);
		},
		m(target, anchor) {
			mount_component(compilestepview, target, anchor);
			current = true;
		},
		p(new_ctx, dirty) {
			ctx = new_ctx;
			const compilestepview_changes = {};
			if (dirty[1] & /*item*/ 131072) compilestepview_changes.ordinal = /*item*/ ctx[48].index + 1;
			if (dirty[1] & /*item*/ 131072) compilestepview_changes.calculatedKind = /*kindAtIndex*/ ctx[21](/*item*/ ctx[48].index);
			if (dirty[1] & /*item*/ 131072) compilestepview_changes.error = /*errorAtIndex*/ ctx[22](/*item*/ ctx[48].index);

			if (!updating_step && dirty[0] & /*$workflows, currentWorkflowName*/ 18 | dirty[1] & /*item*/ 131072) {
				updating_step = true;
				compilestepview_changes.step = /*$workflows*/ ctx[4][/*currentWorkflowName*/ ctx[1]].steps[/*item*/ ctx[48].index];
				add_flush_callback(() => updating_step = false);
			}

			compilestepview.$set(compilestepview_changes);
		},
		i(local) {
			if (current) return;
			transition_in(compilestepview.$$.fragment, local);
			current = true;
		},
		o(local) {
			transition_out(compilestepview.$$.fragment, local);
			current = false;
		},
		d(detaching) {
			destroy_component(compilestepview, detaching);
		}
	};
}

// (342:8) {#if Object.keys($workflows).length > 0}
function create_if_block_3$2(ctx) {
	let button;
	let mounted;
	let dispose;

	return {
		c() {
			button = element("button");
			button.textContent = "+ Add Step";
			attr(button, "class", "svelte-1ylbuwy");
		},
		m(target, anchor) {
			insert(target, button, anchor);

			if (!mounted) {
				dispose = listen(button, "click", /*addStep*/ ctx[20]);
				mounted = true;
			}
		},
		p: noop,
		d(detaching) {
			if (detaching) detach(button);
			mounted = false;
			dispose();
		}
	};
}

// (359:6) {#if $currentWorkflow && $currentWorkflow.steps.length > 0}
function create_if_block_1$3(ctx) {
	let button;
	let t0;
	let button_disabled_value;
	let button_aria_label_value;
	let t1;
	let span;

	let t2_value = (/*validation*/ ctx[13].error === /*WorkflowError*/ ctx[12].Valid
	? /*defaultCompileStatus*/ ctx[11]
	: /*validation*/ ctx[13].error) + "";

	let t2;
	let mounted;
	let dispose;

	return {
		c() {
			button = element("button");
			t0 = text("Compile");
			t1 = space();
			span = element("span");
			t2 = text(t2_value);
			attr(button, "class", "compile-button svelte-1ylbuwy");
			button.disabled = button_disabled_value = /*validation*/ ctx[13].error !== /*WorkflowError*/ ctx[12].Valid;
			attr(button, "aria-label", button_aria_label_value = /*validation*/ ctx[13].error);
			attr(span, "class", "compile-status svelte-1ylbuwy");
		},
		m(target, anchor) {
			insert(target, button, anchor);
			append(button, t0);
			insert(target, t1, anchor);
			insert(target, span, anchor);
			append(span, t2);
			/*span_binding*/ ctx[38](span);

			if (!mounted) {
				dispose = listen(button, "click", /*doCompile*/ ctx[25]);
				mounted = true;
			}
		},
		p(ctx, dirty) {
			if (dirty[0] & /*validation, WorkflowError*/ 12288 && button_disabled_value !== (button_disabled_value = /*validation*/ ctx[13].error !== /*WorkflowError*/ ctx[12].Valid)) {
				button.disabled = button_disabled_value;
			}

			if (dirty[0] & /*validation*/ 8192 && button_aria_label_value !== (button_aria_label_value = /*validation*/ ctx[13].error)) {
				attr(button, "aria-label", button_aria_label_value);
			}

			if (dirty[0] & /*validation, WorkflowError, defaultCompileStatus*/ 14336 && t2_value !== (t2_value = (/*validation*/ ctx[13].error === /*WorkflowError*/ ctx[12].Valid
			? /*defaultCompileStatus*/ ctx[11]
			: /*validation*/ ctx[13].error) + "")) set_data(t2, t2_value);
		},
		d(detaching) {
			if (detaching) detach(button);
			if (detaching) detach(t1);
			if (detaching) detach(span);
			/*span_binding*/ ctx[38](null);
			mounted = false;
			dispose();
		}
	};
}

function create_fragment$a(ctx) {
	let if_block_anchor;
	let current;
	let if_block = /*$currentProject*/ ctx[15] && /*$currentDraft*/ ctx[16] && create_if_block$5(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 (/*$currentProject*/ ctx[15] && /*$currentDraft*/ ctx[16]) {
				if (if_block) {
					if_block.p(ctx, dirty);

					if (dirty[0] & /*$currentProject, $currentDraft*/ 98304) {
						transition_in(if_block, 1);
					}
				} else {
					if_block = create_if_block$5(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 focusOnInit(el) {
	el.focus();
}

function instance$a($$self, $$props, $$invalidate) {
	let $currentWorkflow;
	let $currentDraftPath;
	let $currentProjectPath;
	let $workflows;
	let $projectMetadata;
	let $currentProject;
	let $currentDraft;
	component_subscribe($$self, currentWorkflow, $$value => $$invalidate(2, $currentWorkflow = $$value));
	component_subscribe($$self, currentDraftPath, $$value => $$invalidate(40, $currentDraftPath = $$value));
	component_subscribe($$self, currentProjectPath, $$value => $$invalidate(3, $currentProjectPath = $$value));
	component_subscribe($$self, workflows, $$value => $$invalidate(4, $workflows = $$value));
	component_subscribe($$self, projectMetadata, $$value => $$invalidate(5, $projectMetadata = $$value));
	component_subscribe($$self, currentProject, $$value => $$invalidate(15, $currentProject = $$value));
	component_subscribe($$self, currentDraft, $$value => $$invalidate(16, $currentDraft = $$value));
	var _a;
	let workflowContextButton;
	let workflowInputState = "hidden";
	let workflowInputValue = "";
	let workflowInput;
	let allWorkflowNames = [];
	let currentWorkflowName = null;
	let compileStatus;
	let defaultCompileStatus;
	let isDeletingWorkflow = false;
	const showConfirmModal = getContext("showConfirmModal");
	const showCompileActionsMenu = getContext("showCompileActionsMenu");

	function workflowAction(type) {
		if (type == "new") {
			$$invalidate(7, workflowInputState = "new");
		} else if (type == "rename") {
			$$invalidate(8, workflowInputValue = currentWorkflowName);
			$$invalidate(7, workflowInputState = "rename");
		} else if (type == "delete") {
			showConfirmModal(`Delete ${currentWorkflowName}?`, "Really delete this workflow? This can’t be undone.", "Delete", () => {
				$$invalidate(27, isDeletingWorkflow = true);
				const toDelete = currentWorkflowName;
				const remaining = allWorkflowNames.filter(n => n != toDelete);

				if (remaining.length > 0) {
					set_store_value(projectMetadata, $projectMetadata[$currentProjectPath].workflow = remaining[0], $projectMetadata);
				} else {
					set_store_value(projectMetadata, $projectMetadata[$currentProjectPath].workflow = null, $projectMetadata);
				}

				set_store_value(workflows, $workflows = delete $workflows[toDelete] && $workflows, $workflows);
				$$invalidate(27, isDeletingWorkflow = false);
			});
		}
	}

	function onWorkflowInputEnter() {
		if (workflowInputValue.length == 0) {
			return;
		}

		if (workflowInputState == "new") {
			set_store_value(
				workflows,
				$workflows[workflowInputValue] = {
					name: workflowInputValue,
					description: "",
					steps: []
				},
				$workflows
			);
		} else if (workflowInputState == "rename") {
			const workflow = $workflows[currentWorkflowName];
			set_store_value(workflows, $workflows[workflowInputValue] = workflow, $workflows);
			set_store_value(workflows, $workflows = delete $workflows[currentWorkflowName] && $workflows, $workflows);
		}

		set_store_value(projectMetadata, $projectMetadata[$currentProjectPath].workflow = workflowInputValue, $projectMetadata);
		$$invalidate(8, workflowInputValue = "");
		$$invalidate(7, workflowInputState = "hidden");
	}

	// VALIDATION
	const openCompileStepMenu = getContext("openCompileStepMenu");

	function addStep() {
		openCompileStepMenu();
	}

	var WorkflowError;

	(function (WorkflowError) {
		WorkflowError["Valid"] = "";
		WorkflowError["BadFirstStep"] = "The first step must be of Scene or Join type; compilation begins with all scenes as input.";
		WorkflowError["MissingJoinStep"] = "A Manuscript step must occur after a Join step; Manuscript steps run on a single file, not all scenes.";
		WorkflowError["ScenesStepPostJoin"] = "A Scene or Join step cannot occur after a Join step; at this point in the workflow, steps must operate on a single file.";
		WorkflowError["UnloadedStep"] = "This workflow contains a step that could not be loaded. Please delete or replace it.";
	})(WorkflowError || (WorkflowError = {}));

	function calculateWorkflow(workflow) {
		if (!workflow) {
			return;
		}

		let currentKind = null;
		let calculatedKinds = [];

		for (let stepPosition = 0; stepPosition < workflow.steps.length; stepPosition++) {
			const step = workflow.steps[stepPosition];
			const kinds = step.description.availableKinds;
			const hasSceneKind = kinds.includes(CompileStepKind.Scene);
			const hasJoinKind = kinds.includes(CompileStepKind.Join);

			if (step.description.canonicalID === PLACEHOLDER_MISSING_STEP.description.canonicalID) {
				return [
					{
						error: WorkflowError.UnloadedStep,
						stepPosition
					},
					calculatedKinds
				];
			}

			// Calculate the next step kind
			if (!currentKind) {
				// First step calculation
				if (hasJoinKind) {
					currentKind = CompileStepKind.Join;
				} else if (hasSceneKind) {
					currentKind = CompileStepKind.Scene;
				} else {
					return [
						{
							error: WorkflowError.BadFirstStep,
							stepPosition
						},
						calculatedKinds
					];
				}
			} else {
				// Subsequent step calculations
				if (!calculatedKinds.includes(CompileStepKind.Join)) {
					// We're pre-join, all kinds must be scene or join
					if (hasJoinKind) {
						currentKind = CompileStepKind.Join;
					} else if (hasSceneKind) {
						currentKind = CompileStepKind.Scene;
					} else {
						return [
							{
								error: WorkflowError.MissingJoinStep,
								stepPosition
							},
							calculatedKinds
						];
					}
				} else {
					// We're post-join, all kinds must be of type manuscript
					if (kinds.includes(CompileStepKind.Manuscript)) {
						currentKind = CompileStepKind.Manuscript;
					} else {
						return [
							{
								error: WorkflowError.ScenesStepPostJoin,
								stepPosition
							},
							calculatedKinds
						];
					}
				}
			}

			calculatedKinds.push(currentKind);
		}

		return [
			{
				error: WorkflowError.Valid,
				stepPosition: 0
			},
			calculatedKinds
		];
	}

	const VALID = {
		error: WorkflowError.Valid,
		stepPosition: 0
	};

	let validation = VALID;
	let calculatedKinds = [];

	function kindAtIndex(index) {
		return index < calculatedKinds.length
		? calculatedKinds[index]
		: null;
	}

	function errorAtIndex(index) {
		if (validation.error !== WorkflowError.Valid && validation.stepPosition === index) {
			return validation.error;
		}

		return null;
	}

	let items;

	const sortableOptions = {
		animation: 150,
		ghostClass: "step-ghost",
		dragClass: "step-drag"
	};

	// Called when sorting ends an the item order has been updated.
	function itemOrderChanged(event) {
		const newWorkflow = Object.assign(Object.assign({}, $currentWorkflow), {
			steps: event.detail.map(({ index }) => $currentWorkflow.steps[index])
		});

		set_store_value(workflows, $workflows[currentWorkflowName] = newWorkflow, $workflows);
	}

	function onCompileStatusChange(status) {
		if (status.kind == "CompileStatusError") {
			$$invalidate(10, compileStatus.innerText = `${status.error}. See dev console for more details.`, compileStatus);
			compileStatus.classList.add("compile-status-error");
			restoreDefaultStatusAfter(10000);
		} else if (status.kind == "CompileStatusStep") {
			$$invalidate(10, compileStatus.innerText = `Step ${status.stepIndex + 1}/${status.totalSteps} (${formatStepKind(status.stepKind)})`, compileStatus);
		} else if (status.kind == "CompileStatusSuccess") {
			$$invalidate(10, compileStatus.innerText = "Compiled manuscript.", compileStatus);
			compileStatus.classList.add("compile-status-success");
			restoreDefaultStatusAfter();
		} else {
			$$invalidate(10, compileStatus.innerText = "default??", compileStatus);
		}
	}

	function restoreDefaultStatusAfter(ms = 3000) {
		setTimeout(
			() => {
				$$invalidate(10, compileStatus.innerText = defaultCompileStatus, compileStatus);
				compileStatus.classList.remove("compile-status-error");
				compileStatus.classList.remove("compile-status-success");
			},
			ms
		);
	}

	const compile = getContext("compile");

	function doCompile() {
		compile($currentProjectPath, $currentDraftPath, $currentWorkflow, calculatedKinds, onCompileStatusChange);
	}

	function input_input_handler() {
		workflowInputValue = this.value;
		$$invalidate(8, workflowInputValue);
	}

	function input_binding($$value) {
		binding_callbacks[$$value ? 'unshift' : 'push'](() => {
			workflowInput = $$value;
			$$invalidate(9, workflowInput);
		});
	}

	const keydown_handler = e => {
		if (e.key === "Enter" && workflowInputValue.length > 0) {
			onWorkflowInputEnter();
		} else if (e.key === "Escape") {
			$$invalidate(8, workflowInputValue = "");
			workflowInput.blur();
			$$invalidate(7, workflowInputState = "hidden");
		}
	};

	function select_change_handler() {
		$projectMetadata[$currentProjectPath].workflow = select_value(this);
		projectMetadata.set($projectMetadata);
		(($$invalidate(0, allWorkflowNames), $$invalidate(4, $workflows)), $$invalidate(26, _a));
	}

	function button_binding($$value) {
		binding_callbacks[$$value ? 'unshift' : 'push'](() => {
			workflowContextButton = $$value;
			$$invalidate(6, workflowContextButton);
		});
	}

	const click_handler = () => {
		const rect = workflowContextButton.getBoundingClientRect();
		showCompileActionsMenu(rect.x, rect.y, currentWorkflowName, workflowAction);
	};

	function autotextarea_value_binding(value) {
		if ($$self.$$.not_equal($workflows[currentWorkflowName].description, value)) {
			$workflows[currentWorkflowName].description = value;
			workflows.set($workflows);
		}
	}

	function compilestepview_step_binding(value, item) {
		if ($$self.$$.not_equal($workflows[currentWorkflowName].steps[item.index], value)) {
			$workflows[currentWorkflowName].steps[item.index] = value;
			workflows.set($workflows);
		}
	}

	const removeStep_handler = item => {
		const newWorkflow = {
			...$currentWorkflow,
			steps: $currentWorkflow.steps.filter((_e, index) => item.index !== index)
		};

		set_store_value(workflows, $workflows[currentWorkflowName] = newWorkflow, $workflows);
	};

	function sortablelist_items_binding(value) {
		items = value;
		($$invalidate(14, items), $$invalidate(2, $currentWorkflow));
	}

	function span_binding($$value) {
		binding_callbacks[$$value ? 'unshift' : 'push'](() => {
			compileStatus = $$value;
			$$invalidate(10, compileStatus);
		});
	}

	$$self.$$.update = () => {
		if ($$self.$$.dirty[0] & /*$workflows, _a*/ 67108880) {
			// WORKFLOW MANAGEMENT
			$$invalidate(0, allWorkflowNames = $$invalidate(26, _a = Object.keys($workflows).sort()) !== null && _a !== void 0
			? _a
			: []);
		}

		if ($$self.$$.dirty[0] & /*$projectMetadata, $currentProjectPath, isDeletingWorkflow, currentWorkflowName, allWorkflowNames*/ 134217771) {
			{
				const metadata = $projectMetadata[$currentProjectPath];

				$$invalidate(1, currentWorkflowName = metadata === null || metadata === void 0
				? void 0
				: metadata.workflow);

				if (!isDeletingWorkflow && metadata && !currentWorkflowName && allWorkflowNames.length > 0) {
					set_store_value(projectMetadata, $projectMetadata[$currentProjectPath].workflow = allWorkflowNames[0], $projectMetadata);
				}
			}
		}

		if ($$self.$$.dirty[0] & /*$currentWorkflow*/ 4) {
			{
				if ($currentWorkflow) {
					$$invalidate(13, [validation, calculatedKinds] = calculateWorkflow($currentWorkflow), validation);
				} else {
					$$invalidate(13, validation = VALID);
					calculatedKinds = [];
				}
			}
		}

		if ($$self.$$.dirty[0] & /*$currentWorkflow*/ 4) {
			{
				$$invalidate(14, items = $currentWorkflow
				? $currentWorkflow.steps.map((step, index) => ({ id: step.id, index }))
				: []);
			}
		}

		if ($$self.$$.dirty[0] & /*$currentWorkflow*/ 4) {
			// COMPILATION
			$$invalidate(11, defaultCompileStatus = `Will run ${$currentWorkflow ? $currentWorkflow.steps.length : 0} steps.`);
		}
	};

	return [
		allWorkflowNames,
		currentWorkflowName,
		$currentWorkflow,
		$currentProjectPath,
		$workflows,
		$projectMetadata,
		workflowContextButton,
		workflowInputState,
		workflowInputValue,
		workflowInput,
		compileStatus,
		defaultCompileStatus,
		WorkflowError,
		validation,
		items,
		$currentProject,
		$currentDraft,
		showCompileActionsMenu,
		workflowAction,
		onWorkflowInputEnter,
		addStep,
		kindAtIndex,
		errorAtIndex,
		sortableOptions,
		itemOrderChanged,
		doCompile,
		_a,
		isDeletingWorkflow,
		input_input_handler,
		input_binding,
		keydown_handler,
		select_change_handler,
		button_binding,
		click_handler,
		autotextarea_value_binding,
		compilestepview_step_binding,
		removeStep_handler,
		sortablelist_items_binding,
		span_binding
	];
}

class CompileView extends SvelteComponent {
	constructor(options) {
		super();
		init(this, options, instance$a, create_fragment$a, safe_not_equal, {}, add_css$8, [-1, -1]);
	}
}

/* src/view/tabs/Tabs.svelte generated by Svelte v3.43.1 */

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", "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_base(
						default_slot,
						default_slot_template,
						ctx,
						/*$$scope*/ ctx[0],
						!current
						? get_all_dirty_from_scope(/*$$scope*/ ctx[0])
						: get_slot_changes(default_slot_template, /*$$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$9($$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$9, create_fragment$9, safe_not_equal, {});
	}
}

/* src/view/tabs/TabList.svelte generated by Svelte v3.43.1 */

function add_css$7(target) {
	append_styles(target, "svelte-1bo97vk", ".tab-list.svelte-1bo97vk{margin:4px 8px;border-bottom:1px solid var(--text-muted)}");
}

function create_fragment$8(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_base(
						default_slot,
						default_slot_template,
						ctx,
						/*$$scope*/ ctx[0],
						!current
						? get_all_dirty_from_scope(/*$$scope*/ ctx[0])
						: get_slot_changes(default_slot_template, /*$$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$8($$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();
		init(this, options, instance$8, create_fragment$8, safe_not_equal, {}, add_css$7);
	}
}

/* src/view/tabs/TabPanel.svelte generated by Svelte v3.43.1 */

function add_css$6(target) {
	append_styles(target, "svelte-11pvpwl", ".tab-panel-container.svelte-11pvpwl{padding:0 8px}");
}

// (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_base(
						default_slot,
						default_slot_template,
						ctx,
						/*$$scope*/ ctx[3],
						!current
						? get_all_dirty_from_scope(/*$$scope*/ ctx[3])
						: get_slot_changes(default_slot_template, /*$$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$7(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$7($$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();
		init(this, options, instance$7, create_fragment$7, safe_not_equal, {}, add_css$6);
	}
}

/* src/view/tabs/Tab.svelte generated by Svelte v3.43.1 */

function add_css$5(target) {
	append_styles(target, "svelte-htpziy", "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)}");
}

function create_fragment$6(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_base(
						default_slot,
						default_slot_template,
						ctx,
						/*$$scope*/ ctx[4],
						!current
						? get_all_dirty_from_scope(/*$$scope*/ ctx[4])
						: get_slot_changes(default_slot_template, /*$$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$6($$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();
		init(this, options, instance$6, create_fragment$6, safe_not_equal, {}, add_css$5);
	}
}

/* src/view/explorer/DraftList.svelte generated by Svelte v3.43.1 */

function add_css$4(target) {
	append_styles(target, "svelte-1jmafs", "#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)}");
}

// (88: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 $currentDraftPath;
	let $currentProjectPath;
	let $projectMetadata;
	let $currentProject;
	component_subscribe($$self, currentDraftPath, $$value => $$invalidate(3, $currentDraftPath = $$value));
	component_subscribe($$self, currentProjectPath, $$value => $$invalidate(13, $currentProjectPath = $$value));
	component_subscribe($$self, projectMetadata, $$value => $$invalidate(14, $projectMetadata = $$value));
	component_subscribe($$self, currentProject, $$value => $$invalidate(10, $currentProject = $$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();
		init(this, options, instance$5, create_fragment$5, safe_not_equal, {}, add_css$4);
	}
}

/* src/view/explorer/NewDraftField.svelte generated by Svelte v3.43.1 */

function add_css$3(target) {
	append_styles(target, "svelte-1wkli4h", ".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)}");
}

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 option_value_value;
	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 = option_value_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 $currentProjectPath;
	let $projectMetadata;
	let $currentDraftPath;
	let $currentProject;
	component_subscribe($$self, currentProjectPath, $$value => $$invalidate(10, $currentProjectPath = $$value));
	component_subscribe($$self, projectMetadata, $$value => $$invalidate(11, $projectMetadata = $$value));
	component_subscribe($$self, currentDraftPath, $$value => $$invalidate(12, $currentDraftPath = $$value));
	component_subscribe($$self, currentProject, $$value => $$invalidate(1, $currentProject = $$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();
		init(this, options, instance$4, create_fragment$4, safe_not_equal, {}, add_css$3);
	}
}

/* src/view/explorer/NewSceneField.svelte generated by Svelte v3.43.1 */

function add_css$2(target) {
	append_styles(target, "svelte-1lq63fp", ".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}");
}

// (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();
		init(this, options, instance$3, create_fragment$3, safe_not_equal, {}, add_css$2);
	}
}

/* src/view/explorer/ProjectPicker.svelte generated by Svelte v3.43.1 */

function add_css$1(target) {
	append_styles(target, "svelte-23avsr", "#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}");
}

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[0] && /*$currentProject*/ ctx[1] && /*$currentProject*/ ctx[1].drafts && create_if_block_3(ctx);
	let if_block1 = /*$currentDraftPath*/ ctx[0] && 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[0] && /*$currentProject*/ ctx[1] && /*$currentProject*/ ctx[1].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[0]) {
				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[1].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[0] === 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[0]);

			if (!mounted) {
				dispose = listen(select, "change", /*select_change_handler_1*/ ctx[7]);
				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(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[0]);
			}
		},
		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*/ 2 && t_value !== (t_value = /*draftOption*/ ctx[8].name + "")) set_data(t, t_value);

			if (dirty & /*$currentProject*/ 2 && 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[0]}`) + "";
	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*/ 9 && t_value !== (t_value = obsidian.normalizePath(`${/*$currentProjectPath*/ ctx[3]}/${/*$currentDraftPath*/ ctx[0]}`) + "")) 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[1].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*/ 2 && t_value !== (t_value = /*$currentProject*/ ctx[1].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[1] && /*$currentProject*/ ctx[1].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[1] && /*$currentProject*/ ctx[1].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 $currentDraftPath;
	let $currentProject;
	let $initialized;
	let $projects;
	let $currentProjectPath;
	component_subscribe($$self, currentDraftPath, $$value => $$invalidate(0, $currentDraftPath = $$value));
	component_subscribe($$self, currentProject, $$value => $$invalidate(1, $currentProject = $$value));
	component_subscribe($$self, initialized, $$value => $$invalidate(4, $initialized = $$value));
	component_subscribe($$self, projects, $$value => $$invalidate(5, $projects = $$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(5, $projects));
	}

	function select_change_handler_1() {
		$currentDraftPath = select_value(this);
		currentDraftPath.set($currentDraftPath);
	}

	$$self.$$.update = () => {
		if ($$self.$$.dirty & /*$projects*/ 32) {
			{
				$$invalidate(2, projectOptions = Object.keys($projects).map(path => ({ name: path.split("/").slice(-1)[0], path })));
			}
		}

		if ($$self.$$.dirty & /*$initialized, $currentProject, $currentDraftPath*/ 19) {
			// 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 [
		$currentDraftPath,
		$currentProject,
		projectOptions,
		$currentProjectPath,
		$initialized,
		$projects,
		select_change_handler,
		select_change_handler_1
	];
}

class ProjectPicker extends SvelteComponent {
	constructor(options) {
		super();
		init(this, options, instance$2, create_fragment$2, safe_not_equal, {}, add_css$1);
	}
}

/* src/view/explorer/SceneList.svelte generated by Svelte v3.43.1 */

function add_css(target) {
	append_styles(target, "svelte-1wlkmbt", "#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)}");
}

// (56: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 $currentProjectPath;
	let $projectMetadata;
	let $currentDraftPath;
	let $currentDraft;
	let $activeFile;
	component_subscribe($$self, currentProjectPath, $$value => $$invalidate(10, $currentProjectPath = $$value));
	component_subscribe($$self, projectMetadata, $$value => $$invalidate(11, $projectMetadata = $$value));
	component_subscribe($$self, currentDraftPath, $$value => $$invalidate(12, $currentDraftPath = $$value));
	component_subscribe($$self, currentDraft, $$value => $$invalidate(7, $currentDraft = $$value));
	component_subscribe($$self, activeFile, $$value => $$invalidate(2, $activeFile = $$value));
	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();
		init(this, options, instance$1, create_fragment$1, safe_not_equal, {}, add_css);
	}
}

/* src/view/explorer/ExplorerView.svelte generated by Svelte v3.43.1 */

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 $currentDraftPath;
	let $currentProjectPath;
	let $pluginSettings;
	let $currentDraft;
	let $currentProject;
	component_subscribe($$self, currentDraftPath, $$value => $$invalidate(2, $currentDraftPath = $$value));
	component_subscribe($$self, currentProjectPath, $$value => $$invalidate(3, $currentProjectPath = $$value));
	component_subscribe($$self, pluginSettings, $$value => $$invalidate(4, $pluginSettings = $$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 showing a generic confirmation modal
            context.set("showConfirmModal", (title, description, yesText, yesAction, noText = undefined, noAction = undefined) => {
                new ConfirmActionModal(this.app, title, description, yesText, yesAction, noText, noAction).open();
            });
            // 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("compile", (projectPath, draftName, workflow, kinds, statusCallback) => {
                compile(this.app, projectPath, draftName, workflow, kinds, statusCallback);
            });
            context.set("openCompileStepMenu", () => new AddStepModalContainer(this.app).open());
            context.set("showCompileActionsMenu", (x, y, currentWorkflowName, action) => {
                const menu = new obsidian.Menu(this.app);
                menu.addItem((item) => {
                    item.setTitle("Add new workflow");
                    item.setIcon("plus-with-circle");
                    item.onClick(() => action("new"));
                });
                if (currentWorkflowName) {
                    menu.addItem((item) => {
                        item.setTitle(`Rename "${currentWorkflowName}"`);
                        item.setIcon("pencil");
                        item.onClick(() => action("rename"));
                    });
                    menu.addItem((item) => {
                        item.setTitle(`Delete "${currentWorkflowName}"`);
                        item.setIcon("trash");
                        item.onClick(() => action("delete"));
                    });
                }
                menu.showAtPosition({ x, y });
            });
            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 project’s index file acts as storage for all the metadata necessary to make a Longform project work. You can edit it (it’s 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 you’d 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;
    }
}

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 && !!settings.projects[path];
}
function isInLongformProject(path, settings) {
    return (settings && !!Object.keys(settings.projects).find((p) => path.startsWith(p)));
}
function indexFilePath(project) {
    return obsidian.normalizePath(`${project.path}/${project.indexFile}.md`);
}

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 plugin’s README.
`;
const EmptyIndexFileMetadata = {
    version: LONGFORM_CURRENT_INDEX_VERSION,
    workflow: null,
    drafts: [
        {
            name: "Draft 1",
            folder: "Draft 1",
            scenes: [],
        },
    ],
};
function indexBodyFor(state) {
    if (!state) {
        return null;
    }
    const body = obsidian.stringifyYaml(state);
    if (!body || body === "undefined") {
        return null;
    }
    return `---\n${body}---\n\n${WARNING}\n`;
}
function buildDraftsLookup(drafts) {
    return drafts.reduce((agg, d) => {
        agg[d.folder] = d;
        return agg;
    }, {});
}

/** 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;

/**
 * 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 = '[object Boolean]',
    dateTag = '[object Date]',
    errorTag = '[object Error]',
    mapTag = '[object Map]',
    numberTag = '[object Number]',
    regexpTag = '[object RegExp]',
    setTag = '[object Set]',
    stringTag = '[object String]',
    symbolTag = '[object Symbol]';

var arrayBufferTag = '[object ArrayBuffer]',
    dataViewTag = '[object DataView]';

/** Used to convert symbols to primitives and strings. */
var symbolProto = _Symbol ? _Symbol.prototype : undefined,
    symbolValueOf = symbolProto ? symbolProto.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:
      if ((object.byteLength != other.byteLength) ||
          (object.byteOffset != other.byteOffset)) {
        return false;
      }
      object = object.buffer;
      other = other.buffer;

    case arrayBufferTag:
      if ((object.byteLength != other.byteLength) ||
          !equalFunc(new _Uint8Array(object), new _Uint8Array(other))) {
        return false;
      }
      return true;

    case boolTag:
    case dateTag:
    case numberTag:
      // Coerce booleans to `1` or `0` and dates to milliseconds.
      // Invalid dates are coerced to `NaN`.
      return eq_1(+object, +other);

    case errorTag:
      return object.name == other.name && object.message == other.message;

    case regexpTag:
    case stringTag:
      // 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:
      var convert = _mapToArray;

    case setTag:
      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:
      if (symbolValueOf) {
        return symbolValueOf.call(object) == symbolValueOf.call(other);
      }
  }
  return false;
}

var _equalByTag = equalByTag;

/** Used to compose bitmasks for value comparisons. */
var COMPARE_PARTIAL_FLAG$1 = 1;

/** Used for built-in method references. */
var objectProto$1 = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty$1 = objectProto$1.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$1.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;

/** Used to compose bitmasks for value comparisons. */
var COMPARE_PARTIAL_FLAG = 1;

/** `Object#toString` result references. */
var argsTag = '[object Arguments]',
    arrayTag = '[object Array]',
    objectTag = '[object Object]';

/** Used for built-in method references. */
var objectProto = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.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 : _getTag(object),
      othTag = othIsArr ? arrayTag : _getTag(other);

  objTag = objTag == argsTag ? objectTag : objTag;
  othTag = othTag == argsTag ? objectTag : othTag;

  var objIsObj = objTag == objectTag,
      othIsObj = othTag == objectTag,
      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.call(object, '__wrapped__'),
        othIsWrapped = othIsObj && hasOwnProperty.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;

/** 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);
                if (contents) {
                    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,
        workflow: metadata.workflow,
        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;
    }
}

var top = 'top';
var bottom = 'bottom';
var right = 'right';
var left = 'left';
var auto = 'auto';
var basePlacements = [top, bottom, right, left];
var start = 'start';
var end = 'end';
var clippingParents = 'clippingParents';
var viewport = 'viewport';
var popper = 'popper';
var reference = 'reference';
var variationPlacements = /*#__PURE__*/basePlacements.reduce(function (acc, placement) {
  return acc.concat([placement + "-" + start, placement + "-" + end]);
}, []);
var placements = /*#__PURE__*/[].concat(basePlacements, [auto]).reduce(function (acc, placement) {
  return acc.concat([placement, placement + "-" + start, placement + "-" + end]);
}, []); // modifiers that need to read the DOM

var beforeRead = 'beforeRead';
var read = 'read';
var afterRead = 'afterRead'; // pure-logic modifiers

var beforeMain = 'beforeMain';
var main = 'main';
var afterMain = 'afterMain'; // modifier with the purpose to write to the DOM (or write into a framework state)

var beforeWrite = 'beforeWrite';
var write = 'write';
var afterWrite = 'afterWrite';
var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite];

function getNodeName(element) {
  return element ? (element.nodeName || '').toLowerCase() : null;
}

function getWindow(node) {
  if (node == null) {
    return window;
  }

  if (node.toString() !== '[object Window]') {
    var ownerDocument = node.ownerDocument;
    return ownerDocument ? ownerDocument.defaultView || window : window;
  }

  return node;
}

function isElement(node) {
  var OwnElement = getWindow(node).Element;
  return node instanceof OwnElement || node instanceof Element;
}

function isHTMLElement(node) {
  var OwnElement = getWindow(node).HTMLElement;
  return node instanceof OwnElement || node instanceof HTMLElement;
}

function isShadowRoot(node) {
  // IE 11 has no ShadowRoot
  if (typeof ShadowRoot === 'undefined') {
    return false;
  }

  var OwnElement = getWindow(node).ShadowRoot;
  return node instanceof OwnElement || node instanceof ShadowRoot;
}

// and applies them to the HTMLElements such as popper and arrow

function applyStyles(_ref) {
  var state = _ref.state;
  Object.keys(state.elements).forEach(function (name) {
    var style = state.styles[name] || {};
    var attributes = state.attributes[name] || {};
    var element = state.elements[name]; // arrow is optional + virtual elements

    if (!isHTMLElement(element) || !getNodeName(element)) {
      return;
    } // Flow doesn't support to extend this property, but it's the most
    // effective way to apply styles to an HTMLElement
    // $FlowFixMe[cannot-write]


    Object.assign(element.style, style);
    Object.keys(attributes).forEach(function (name) {
      var value = attributes[name];

      if (value === false) {
        element.removeAttribute(name);
      } else {
        element.setAttribute(name, value === true ? '' : value);
      }
    });
  });
}

function effect$2(_ref2) {
  var state = _ref2.state;
  var initialStyles = {
    popper: {
      position: state.options.strategy,
      left: '0',
      top: '0',
      margin: '0'
    },
    arrow: {
      position: 'absolute'
    },
    reference: {}
  };
  Object.assign(state.elements.popper.style, initialStyles.popper);
  state.styles = initialStyles;

  if (state.elements.arrow) {
    Object.assign(state.elements.arrow.style, initialStyles.arrow);
  }

  return function () {
    Object.keys(state.elements).forEach(function (name) {
      var element = state.elements[name];
      var attributes = state.attributes[name] || {};
      var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]); // Set all values to an empty string to unset them

      var style = styleProperties.reduce(function (style, property) {
        style[property] = '';
        return style;
      }, {}); // arrow is optional + virtual elements

      if (!isHTMLElement(element) || !getNodeName(element)) {
        return;
      }

      Object.assign(element.style, style);
      Object.keys(attributes).forEach(function (attribute) {
        element.removeAttribute(attribute);
      });
    });
  };
} // eslint-disable-next-line import/no-unused-modules


var applyStyles$1 = {
  name: 'applyStyles',
  enabled: true,
  phase: 'write',
  fn: applyStyles,
  effect: effect$2,
  requires: ['computeStyles']
};

function getBasePlacement(placement) {
  return placement.split('-')[0];
}

var max = Math.max;
var min = Math.min;
var round = Math.round;

function getBoundingClientRect(element, includeScale) {
  if (includeScale === void 0) {
    includeScale = false;
  }

  var rect = element.getBoundingClientRect();
  var scaleX = 1;
  var scaleY = 1;

  if (isHTMLElement(element) && includeScale) {
    var offsetHeight = element.offsetHeight;
    var offsetWidth = element.offsetWidth; // Do not attempt to divide by 0, otherwise we get `Infinity` as scale
    // Fallback to 1 in case both values are `0`

    if (offsetWidth > 0) {
      scaleX = round(rect.width) / offsetWidth || 1;
    }

    if (offsetHeight > 0) {
      scaleY = round(rect.height) / offsetHeight || 1;
    }
  }

  return {
    width: rect.width / scaleX,
    height: rect.height / scaleY,
    top: rect.top / scaleY,
    right: rect.right / scaleX,
    bottom: rect.bottom / scaleY,
    left: rect.left / scaleX,
    x: rect.left / scaleX,
    y: rect.top / scaleY
  };
}

// means it doesn't take into account transforms.

function getLayoutRect(element) {
  var clientRect = getBoundingClientRect(element); // Use the clientRect sizes if it's not been transformed.
  // Fixes https://github.com/popperjs/popper-core/issues/1223

  var width = element.offsetWidth;
  var height = element.offsetHeight;

  if (Math.abs(clientRect.width - width) <= 1) {
    width = clientRect.width;
  }

  if (Math.abs(clientRect.height - height) <= 1) {
    height = clientRect.height;
  }

  return {
    x: element.offsetLeft,
    y: element.offsetTop,
    width: width,
    height: height
  };
}

function contains(parent, child) {
  var rootNode = child.getRootNode && child.getRootNode(); // First, attempt with faster native method

  if (parent.contains(child)) {
    return true;
  } // then fallback to custom implementation with Shadow DOM support
  else if (rootNode && isShadowRoot(rootNode)) {
      var next = child;

      do {
        if (next && parent.isSameNode(next)) {
          return true;
        } // $FlowFixMe[prop-missing]: need a better way to handle this...


        next = next.parentNode || next.host;
      } while (next);
    } // Give up, the result is false


  return false;
}

function getComputedStyle(element) {
  return getWindow(element).getComputedStyle(element);
}

function isTableElement(element) {
  return ['table', 'td', 'th'].indexOf(getNodeName(element)) >= 0;
}

function getDocumentElement(element) {
  // $FlowFixMe[incompatible-return]: assume body is always available
  return ((isElement(element) ? element.ownerDocument : // $FlowFixMe[prop-missing]
  element.document) || window.document).documentElement;
}

function getParentNode(element) {
  if (getNodeName(element) === 'html') {
    return element;
  }

  return (// this is a quicker (but less type safe) way to save quite some bytes from the bundle
    // $FlowFixMe[incompatible-return]
    // $FlowFixMe[prop-missing]
    element.assignedSlot || // step into the shadow DOM of the parent of a slotted node
    element.parentNode || ( // DOM Element detected
    isShadowRoot(element) ? element.host : null) || // ShadowRoot detected
    // $FlowFixMe[incompatible-call]: HTMLElement is a Node
    getDocumentElement(element) // fallback

  );
}

function getTrueOffsetParent(element) {
  if (!isHTMLElement(element) || // https://github.com/popperjs/popper-core/issues/837
  getComputedStyle(element).position === 'fixed') {
    return null;
  }

  return element.offsetParent;
} // `.offsetParent` reports `null` for fixed elements, while absolute elements
// return the containing block


function getContainingBlock(element) {
  var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') !== -1;
  var isIE = navigator.userAgent.indexOf('Trident') !== -1;

  if (isIE && isHTMLElement(element)) {
    // In IE 9, 10 and 11 fixed elements containing block is always established by the viewport
    var elementCss = getComputedStyle(element);

    if (elementCss.position === 'fixed') {
      return null;
    }
  }

  var currentNode = getParentNode(element);

  while (isHTMLElement(currentNode) && ['html', 'body'].indexOf(getNodeName(currentNode)) < 0) {
    var css = getComputedStyle(currentNode); // This is non-exhaustive but covers the most common CSS properties that
    // create a containing block.
    // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block

    if (css.transform !== 'none' || css.perspective !== 'none' || css.contain === 'paint' || ['transform', 'perspective'].indexOf(css.willChange) !== -1 || isFirefox && css.willChange === 'filter' || isFirefox && css.filter && css.filter !== 'none') {
      return currentNode;
    } else {
      currentNode = currentNode.parentNode;
    }
  }

  return null;
} // Gets the closest ancestor positioned element. Handles some edge cases,
// such as table ancestors and cross browser bugs.


function getOffsetParent(element) {
  var window = getWindow(element);
  var offsetParent = getTrueOffsetParent(element);

  while (offsetParent && isTableElement(offsetParent) && getComputedStyle(offsetParent).position === 'static') {
    offsetParent = getTrueOffsetParent(offsetParent);
  }

  if (offsetParent && (getNodeName(offsetParent) === 'html' || getNodeName(offsetParent) === 'body' && getComputedStyle(offsetParent).position === 'static')) {
    return window;
  }

  return offsetParent || getContainingBlock(element) || window;
}

function getMainAxisFromPlacement(placement) {
  return ['top', 'bottom'].indexOf(placement) >= 0 ? 'x' : 'y';
}

function within(min$1, value, max$1) {
  return max(min$1, min(value, max$1));
}
function withinMaxClamp(min, value, max) {
  var v = within(min, value, max);
  return v > max ? max : v;
}

function getFreshSideObject() {
  return {
    top: 0,
    right: 0,
    bottom: 0,
    left: 0
  };
}

function mergePaddingObject(paddingObject) {
  return Object.assign({}, getFreshSideObject(), paddingObject);
}

function expandToHashMap(value, keys) {
  return keys.reduce(function (hashMap, key) {
    hashMap[key] = value;
    return hashMap;
  }, {});
}

var toPaddingObject = function toPaddingObject(padding, state) {
  padding = typeof padding === 'function' ? padding(Object.assign({}, state.rects, {
    placement: state.placement
  })) : padding;
  return mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements));
};

function arrow(_ref) {
  var _state$modifiersData$;

  var state = _ref.state,
      name = _ref.name,
      options = _ref.options;
  var arrowElement = state.elements.arrow;
  var popperOffsets = state.modifiersData.popperOffsets;
  var basePlacement = getBasePlacement(state.placement);
  var axis = getMainAxisFromPlacement(basePlacement);
  var isVertical = [left, right].indexOf(basePlacement) >= 0;
  var len = isVertical ? 'height' : 'width';

  if (!arrowElement || !popperOffsets) {
    return;
  }

  var paddingObject = toPaddingObject(options.padding, state);
  var arrowRect = getLayoutRect(arrowElement);
  var minProp = axis === 'y' ? top : left;
  var maxProp = axis === 'y' ? bottom : right;
  var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets[axis] - state.rects.popper[len];
  var startDiff = popperOffsets[axis] - state.rects.reference[axis];
  var arrowOffsetParent = getOffsetParent(arrowElement);
  var clientSize = arrowOffsetParent ? axis === 'y' ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0;
  var centerToReference = endDiff / 2 - startDiff / 2; // Make sure the arrow doesn't overflow the popper if the center point is
  // outside of the popper bounds

  var min = paddingObject[minProp];
  var max = clientSize - arrowRect[len] - paddingObject[maxProp];
  var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference;
  var offset = within(min, center, max); // Prevents breaking syntax highlighting...

  var axisProp = axis;
  state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset, _state$modifiersData$.centerOffset = offset - center, _state$modifiersData$);
}

function effect$1(_ref2) {
  var state = _ref2.state,
      options = _ref2.options;
  var _options$element = options.element,
      arrowElement = _options$element === void 0 ? '[data-popper-arrow]' : _options$element;

  if (arrowElement == null) {
    return;
  } // CSS selector


  if (typeof arrowElement === 'string') {
    arrowElement = state.elements.popper.querySelector(arrowElement);

    if (!arrowElement) {
      return;
    }
  }

  if (process.env.NODE_ENV !== "production") {
    if (!isHTMLElement(arrowElement)) {
      console.error(['Popper: "arrow" element must be an HTMLElement (not an SVGElement).', 'To use an SVG arrow, wrap it in an HTMLElement that will be used as', 'the arrow.'].join(' '));
    }
  }

  if (!contains(state.elements.popper, arrowElement)) {
    if (process.env.NODE_ENV !== "production") {
      console.error(['Popper: "arrow" modifier\'s `element` must be a child of the popper', 'element.'].join(' '));
    }

    return;
  }

  state.elements.arrow = arrowElement;
} // eslint-disable-next-line import/no-unused-modules


var arrow$1 = {
  name: 'arrow',
  enabled: true,
  phase: 'main',
  fn: arrow,
  effect: effect$1,
  requires: ['popperOffsets'],
  requiresIfExists: ['preventOverflow']
};

function getVariation(placement) {
  return placement.split('-')[1];
}

var unsetSides = {
  top: 'auto',
  right: 'auto',
  bottom: 'auto',
  left: 'auto'
}; // Round the offsets to the nearest suitable subpixel based on the DPR.
// Zooming can change the DPR, but it seems to report a value that will
// cleanly divide the values into the appropriate subpixels.

function roundOffsetsByDPR(_ref) {
  var x = _ref.x,
      y = _ref.y;
  var win = window;
  var dpr = win.devicePixelRatio || 1;
  return {
    x: round(x * dpr) / dpr || 0,
    y: round(y * dpr) / dpr || 0
  };
}

function mapToStyles(_ref2) {
  var _Object$assign2;

  var popper = _ref2.popper,
      popperRect = _ref2.popperRect,
      placement = _ref2.placement,
      variation = _ref2.variation,
      offsets = _ref2.offsets,
      position = _ref2.position,
      gpuAcceleration = _ref2.gpuAcceleration,
      adaptive = _ref2.adaptive,
      roundOffsets = _ref2.roundOffsets,
      isFixed = _ref2.isFixed;
  var _offsets$x = offsets.x,
      x = _offsets$x === void 0 ? 0 : _offsets$x,
      _offsets$y = offsets.y,
      y = _offsets$y === void 0 ? 0 : _offsets$y;

  var _ref3 = typeof roundOffsets === 'function' ? roundOffsets({
    x: x,
    y: y
  }) : {
    x: x,
    y: y
  };

  x = _ref3.x;
  y = _ref3.y;
  var hasX = offsets.hasOwnProperty('x');
  var hasY = offsets.hasOwnProperty('y');
  var sideX = left;
  var sideY = top;
  var win = window;

  if (adaptive) {
    var offsetParent = getOffsetParent(popper);
    var heightProp = 'clientHeight';
    var widthProp = 'clientWidth';

    if (offsetParent === getWindow(popper)) {
      offsetParent = getDocumentElement(popper);

      if (getComputedStyle(offsetParent).position !== 'static' && position === 'absolute') {
        heightProp = 'scrollHeight';
        widthProp = 'scrollWidth';
      }
    } // $FlowFixMe[incompatible-cast]: force type refinement, we compare offsetParent with window above, but Flow doesn't detect it


    offsetParent = offsetParent;

    if (placement === top || (placement === left || placement === right) && variation === end) {
      sideY = bottom;
      var offsetY = isFixed && win.visualViewport ? win.visualViewport.height : // $FlowFixMe[prop-missing]
      offsetParent[heightProp];
      y -= offsetY - popperRect.height;
      y *= gpuAcceleration ? 1 : -1;
    }

    if (placement === left || (placement === top || placement === bottom) && variation === end) {
      sideX = right;
      var offsetX = isFixed && win.visualViewport ? win.visualViewport.width : // $FlowFixMe[prop-missing]
      offsetParent[widthProp];
      x -= offsetX - popperRect.width;
      x *= gpuAcceleration ? 1 : -1;
    }
  }

  var commonStyles = Object.assign({
    position: position
  }, adaptive && unsetSides);

  var _ref4 = roundOffsets === true ? roundOffsetsByDPR({
    x: x,
    y: y
  }) : {
    x: x,
    y: y
  };

  x = _ref4.x;
  y = _ref4.y;

  if (gpuAcceleration) {
    var _Object$assign;

    return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? '0' : '', _Object$assign[sideX] = hasX ? '0' : '', _Object$assign.transform = (win.devicePixelRatio || 1) <= 1 ? "translate(" + x + "px, " + y + "px)" : "translate3d(" + x + "px, " + y + "px, 0)", _Object$assign));
  }

  return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + "px" : '', _Object$assign2[sideX] = hasX ? x + "px" : '', _Object$assign2.transform = '', _Object$assign2));
}

function computeStyles(_ref5) {
  var state = _ref5.state,
      options = _ref5.options;
  var _options$gpuAccelerat = options.gpuAcceleration,
      gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat,
      _options$adaptive = options.adaptive,
      adaptive = _options$adaptive === void 0 ? true : _options$adaptive,
      _options$roundOffsets = options.roundOffsets,
      roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets;

  if (process.env.NODE_ENV !== "production") {
    var transitionProperty = getComputedStyle(state.elements.popper).transitionProperty || '';

    if (adaptive && ['transform', 'top', 'right', 'bottom', 'left'].some(function (property) {
      return transitionProperty.indexOf(property) >= 0;
    })) {
      console.warn(['Popper: Detected CSS transitions on at least one of the following', 'CSS properties: "transform", "top", "right", "bottom", "left".', '\n\n', 'Disable the "computeStyles" modifier\'s `adaptive` option to allow', 'for smooth transitions, or remove these properties from the CSS', 'transition declaration on the popper element if only transitioning', 'opacity or background-color for example.', '\n\n', 'We recommend using the popper element as a wrapper around an inner', 'element that can have any CSS property transitioned for animations.'].join(' '));
    }
  }

  var commonStyles = {
    placement: getBasePlacement(state.placement),
    variation: getVariation(state.placement),
    popper: state.elements.popper,
    popperRect: state.rects.popper,
    gpuAcceleration: gpuAcceleration,
    isFixed: state.options.strategy === 'fixed'
  };

  if (state.modifiersData.popperOffsets != null) {
    state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, {
      offsets: state.modifiersData.popperOffsets,
      position: state.options.strategy,
      adaptive: adaptive,
      roundOffsets: roundOffsets
    })));
  }

  if (state.modifiersData.arrow != null) {
    state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, {
      offsets: state.modifiersData.arrow,
      position: 'absolute',
      adaptive: false,
      roundOffsets: roundOffsets
    })));
  }

  state.attributes.popper = Object.assign({}, state.attributes.popper, {
    'data-popper-placement': state.placement
  });
} // eslint-disable-next-line import/no-unused-modules


var computeStyles$1 = {
  name: 'computeStyles',
  enabled: true,
  phase: 'beforeWrite',
  fn: computeStyles,
  data: {}
};

var passive = {
  passive: true
};

function effect(_ref) {
  var state = _ref.state,
      instance = _ref.instance,
      options = _ref.options;
  var _options$scroll = options.scroll,
      scroll = _options$scroll === void 0 ? true : _options$scroll,
      _options$resize = options.resize,
      resize = _options$resize === void 0 ? true : _options$resize;
  var window = getWindow(state.elements.popper);
  var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper);

  if (scroll) {
    scrollParents.forEach(function (scrollParent) {
      scrollParent.addEventListener('scroll', instance.update, passive);
    });
  }

  if (resize) {
    window.addEventListener('resize', instance.update, passive);
  }

  return function () {
    if (scroll) {
      scrollParents.forEach(function (scrollParent) {
        scrollParent.removeEventListener('scroll', instance.update, passive);
      });
    }

    if (resize) {
      window.removeEventListener('resize', instance.update, passive);
    }
  };
} // eslint-disable-next-line import/no-unused-modules


var eventListeners = {
  name: 'eventListeners',
  enabled: true,
  phase: 'write',
  fn: function fn() {},
  effect: effect,
  data: {}
};

var hash$1 = {
  left: 'right',
  right: 'left',
  bottom: 'top',
  top: 'bottom'
};
function getOppositePlacement(placement) {
  return placement.replace(/left|right|bottom|top/g, function (matched) {
    return hash$1[matched];
  });
}

var hash = {
  start: 'end',
  end: 'start'
};
function getOppositeVariationPlacement(placement) {
  return placement.replace(/start|end/g, function (matched) {
    return hash[matched];
  });
}

function getWindowScroll(node) {
  var win = getWindow(node);
  var scrollLeft = win.pageXOffset;
  var scrollTop = win.pageYOffset;
  return {
    scrollLeft: scrollLeft,
    scrollTop: scrollTop
  };
}

function getWindowScrollBarX(element) {
  // If <html> has a CSS width greater than the viewport, then this will be
  // incorrect for RTL.
  // Popper 1 is broken in this case and never had a bug report so let's assume
  // it's not an issue. I don't think anyone ever specifies width on <html>
  // anyway.
  // Browsers where the left scrollbar doesn't cause an issue report `0` for
  // this (e.g. Edge 2019, IE11, Safari)
  return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft;
}

function getViewportRect(element) {
  var win = getWindow(element);
  var html = getDocumentElement(element);
  var visualViewport = win.visualViewport;
  var width = html.clientWidth;
  var height = html.clientHeight;
  var x = 0;
  var y = 0; // NB: This isn't supported on iOS <= 12. If the keyboard is open, the popper
  // can be obscured underneath it.
  // Also, `html.clientHeight` adds the bottom bar height in Safari iOS, even
  // if it isn't open, so if this isn't available, the popper will be detected
  // to overflow the bottom of the screen too early.

  if (visualViewport) {
    width = visualViewport.width;
    height = visualViewport.height; // Uses Layout Viewport (like Chrome; Safari does not currently)
    // In Chrome, it returns a value very close to 0 (+/-) but contains rounding
    // errors due to floating point numbers, so we need to check precision.
    // Safari returns a number <= 0, usually < -1 when pinch-zoomed
    // Feature detection fails in mobile emulation mode in Chrome.
    // Math.abs(win.innerWidth / visualViewport.scale - visualViewport.width) <
    // 0.001
    // Fallback here: "Not Safari" userAgent

    if (!/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) {
      x = visualViewport.offsetLeft;
      y = visualViewport.offsetTop;
    }
  }

  return {
    width: width,
    height: height,
    x: x + getWindowScrollBarX(element),
    y: y
  };
}

// of the `<html>` and `<body>` rect bounds if horizontally scrollable

function getDocumentRect(element) {
  var _element$ownerDocumen;

  var html = getDocumentElement(element);
  var winScroll = getWindowScroll(element);
  var body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body;
  var width = max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0);
  var height = max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0);
  var x = -winScroll.scrollLeft + getWindowScrollBarX(element);
  var y = -winScroll.scrollTop;

  if (getComputedStyle(body || html).direction === 'rtl') {
    x += max(html.clientWidth, body ? body.clientWidth : 0) - width;
  }

  return {
    width: width,
    height: height,
    x: x,
    y: y
  };
}

function isScrollParent(element) {
  // Firefox wants us to check `-x` and `-y` variations as well
  var _getComputedStyle = getComputedStyle(element),
      overflow = _getComputedStyle.overflow,
      overflowX = _getComputedStyle.overflowX,
      overflowY = _getComputedStyle.overflowY;

  return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX);
}

function getScrollParent(node) {
  if (['html', 'body', '#document'].indexOf(getNodeName(node)) >= 0) {
    // $FlowFixMe[incompatible-return]: assume body is always available
    return node.ownerDocument.body;
  }

  if (isHTMLElement(node) && isScrollParent(node)) {
    return node;
  }

  return getScrollParent(getParentNode(node));
}

/*
given a DOM element, return the list of all scroll parents, up the list of ancesors
until we get to the top window object. This list is what we attach scroll listeners
to, because if any of these parent elements scroll, we'll need to re-calculate the
reference element's position.
*/

function listScrollParents(element, list) {
  var _element$ownerDocumen;

  if (list === void 0) {
    list = [];
  }

  var scrollParent = getScrollParent(element);
  var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body);
  var win = getWindow(scrollParent);
  var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent;
  var updatedList = list.concat(target);
  return isBody ? updatedList : // $FlowFixMe[incompatible-call]: isBody tells us target will be an HTMLElement here
  updatedList.concat(listScrollParents(getParentNode(target)));
}

function rectToClientRect(rect) {
  return Object.assign({}, rect, {
    left: rect.x,
    top: rect.y,
    right: rect.x + rect.width,
    bottom: rect.y + rect.height
  });
}

function getInnerBoundingClientRect(element) {
  var rect = getBoundingClientRect(element);
  rect.top = rect.top + element.clientTop;
  rect.left = rect.left + element.clientLeft;
  rect.bottom = rect.top + element.clientHeight;
  rect.right = rect.left + element.clientWidth;
  rect.width = element.clientWidth;
  rect.height = element.clientHeight;
  rect.x = rect.left;
  rect.y = rect.top;
  return rect;
}

function getClientRectFromMixedType(element, clippingParent) {
  return clippingParent === viewport ? rectToClientRect(getViewportRect(element)) : isElement(clippingParent) ? getInnerBoundingClientRect(clippingParent) : rectToClientRect(getDocumentRect(getDocumentElement(element)));
} // A "clipping parent" is an overflowable container with the characteristic of
// clipping (or hiding) overflowing elements with a position different from
// `initial`


function getClippingParents(element) {
  var clippingParents = listScrollParents(getParentNode(element));
  var canEscapeClipping = ['absolute', 'fixed'].indexOf(getComputedStyle(element).position) >= 0;
  var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element;

  if (!isElement(clipperElement)) {
    return [];
  } // $FlowFixMe[incompatible-return]: https://github.com/facebook/flow/issues/1414


  return clippingParents.filter(function (clippingParent) {
    return isElement(clippingParent) && contains(clippingParent, clipperElement) && getNodeName(clippingParent) !== 'body';
  });
} // Gets the maximum area that the element is visible in due to any number of
// clipping parents


function getClippingRect(element, boundary, rootBoundary) {
  var mainClippingParents = boundary === 'clippingParents' ? getClippingParents(element) : [].concat(boundary);
  var clippingParents = [].concat(mainClippingParents, [rootBoundary]);
  var firstClippingParent = clippingParents[0];
  var clippingRect = clippingParents.reduce(function (accRect, clippingParent) {
    var rect = getClientRectFromMixedType(element, clippingParent);
    accRect.top = max(rect.top, accRect.top);
    accRect.right = min(rect.right, accRect.right);
    accRect.bottom = min(rect.bottom, accRect.bottom);
    accRect.left = max(rect.left, accRect.left);
    return accRect;
  }, getClientRectFromMixedType(element, firstClippingParent));
  clippingRect.width = clippingRect.right - clippingRect.left;
  clippingRect.height = clippingRect.bottom - clippingRect.top;
  clippingRect.x = clippingRect.left;
  clippingRect.y = clippingRect.top;
  return clippingRect;
}

function computeOffsets(_ref) {
  var reference = _ref.reference,
      element = _ref.element,
      placement = _ref.placement;
  var basePlacement = placement ? getBasePlacement(placement) : null;
  var variation = placement ? getVariation(placement) : null;
  var commonX = reference.x + reference.width / 2 - element.width / 2;
  var commonY = reference.y + reference.height / 2 - element.height / 2;
  var offsets;

  switch (basePlacement) {
    case top:
      offsets = {
        x: commonX,
        y: reference.y - element.height
      };
      break;

    case bottom:
      offsets = {
        x: commonX,
        y: reference.y + reference.height
      };
      break;

    case right:
      offsets = {
        x: reference.x + reference.width,
        y: commonY
      };
      break;

    case left:
      offsets = {
        x: reference.x - element.width,
        y: commonY
      };
      break;

    default:
      offsets = {
        x: reference.x,
        y: reference.y
      };
  }

  var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null;

  if (mainAxis != null) {
    var len = mainAxis === 'y' ? 'height' : 'width';

    switch (variation) {
      case start:
        offsets[mainAxis] = offsets[mainAxis] - (reference[len] / 2 - element[len] / 2);
        break;

      case end:
        offsets[mainAxis] = offsets[mainAxis] + (reference[len] / 2 - element[len] / 2);
        break;
    }
  }

  return offsets;
}

function detectOverflow(state, options) {
  if (options === void 0) {
    options = {};
  }

  var _options = options,
      _options$placement = _options.placement,
      placement = _options$placement === void 0 ? state.placement : _options$placement,
      _options$boundary = _options.boundary,
      boundary = _options$boundary === void 0 ? clippingParents : _options$boundary,
      _options$rootBoundary = _options.rootBoundary,
      rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary,
      _options$elementConte = _options.elementContext,
      elementContext = _options$elementConte === void 0 ? popper : _options$elementConte,
      _options$altBoundary = _options.altBoundary,
      altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary,
      _options$padding = _options.padding,
      padding = _options$padding === void 0 ? 0 : _options$padding;
  var paddingObject = mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements));
  var altContext = elementContext === popper ? reference : popper;
  var popperRect = state.rects.popper;
  var element = state.elements[altBoundary ? altContext : elementContext];
  var clippingClientRect = getClippingRect(isElement(element) ? element : element.contextElement || getDocumentElement(state.elements.popper), boundary, rootBoundary);
  var referenceClientRect = getBoundingClientRect(state.elements.reference);
  var popperOffsets = computeOffsets({
    reference: referenceClientRect,
    element: popperRect,
    strategy: 'absolute',
    placement: placement
  });
  var popperClientRect = rectToClientRect(Object.assign({}, popperRect, popperOffsets));
  var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect; // positive = overflowing the clipping rect
  // 0 or negative = within the clipping rect

  var overflowOffsets = {
    top: clippingClientRect.top - elementClientRect.top + paddingObject.top,
    bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom,
    left: clippingClientRect.left - elementClientRect.left + paddingObject.left,
    right: elementClientRect.right - clippingClientRect.right + paddingObject.right
  };
  var offsetData = state.modifiersData.offset; // Offsets can be applied only to the popper element

  if (elementContext === popper && offsetData) {
    var offset = offsetData[placement];
    Object.keys(overflowOffsets).forEach(function (key) {
      var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1;
      var axis = [top, bottom].indexOf(key) >= 0 ? 'y' : 'x';
      overflowOffsets[key] += offset[axis] * multiply;
    });
  }

  return overflowOffsets;
}

function computeAutoPlacement(state, options) {
  if (options === void 0) {
    options = {};
  }

  var _options = options,
      placement = _options.placement,
      boundary = _options.boundary,
      rootBoundary = _options.rootBoundary,
      padding = _options.padding,
      flipVariations = _options.flipVariations,
      _options$allowedAutoP = _options.allowedAutoPlacements,
      allowedAutoPlacements = _options$allowedAutoP === void 0 ? placements : _options$allowedAutoP;
  var variation = getVariation(placement);
  var placements$1 = variation ? flipVariations ? variationPlacements : variationPlacements.filter(function (placement) {
    return getVariation(placement) === variation;
  }) : basePlacements;
  var allowedPlacements = placements$1.filter(function (placement) {
    return allowedAutoPlacements.indexOf(placement) >= 0;
  });

  if (allowedPlacements.length === 0) {
    allowedPlacements = placements$1;

    if (process.env.NODE_ENV !== "production") {
      console.error(['Popper: The `allowedAutoPlacements` option did not allow any', 'placements. Ensure the `placement` option matches the variation', 'of the allowed placements.', 'For example, "auto" cannot be used to allow "bottom-start".', 'Use "auto-start" instead.'].join(' '));
    }
  } // $FlowFixMe[incompatible-type]: Flow seems to have problems with two array unions...


  var overflows = allowedPlacements.reduce(function (acc, placement) {
    acc[placement] = detectOverflow(state, {
      placement: placement,
      boundary: boundary,
      rootBoundary: rootBoundary,
      padding: padding
    })[getBasePlacement(placement)];
    return acc;
  }, {});
  return Object.keys(overflows).sort(function (a, b) {
    return overflows[a] - overflows[b];
  });
}

function getExpandedFallbackPlacements(placement) {
  if (getBasePlacement(placement) === auto) {
    return [];
  }

  var oppositePlacement = getOppositePlacement(placement);
  return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)];
}

function flip(_ref) {
  var state = _ref.state,
      options = _ref.options,
      name = _ref.name;

  if (state.modifiersData[name]._skip) {
    return;
  }

  var _options$mainAxis = options.mainAxis,
      checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,
      _options$altAxis = options.altAxis,
      checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis,
      specifiedFallbackPlacements = options.fallbackPlacements,
      padding = options.padding,
      boundary = options.boundary,
      rootBoundary = options.rootBoundary,
      altBoundary = options.altBoundary,
      _options$flipVariatio = options.flipVariations,
      flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio,
      allowedAutoPlacements = options.allowedAutoPlacements;
  var preferredPlacement = state.options.placement;
  var basePlacement = getBasePlacement(preferredPlacement);
  var isBasePlacement = basePlacement === preferredPlacement;
  var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement));
  var placements = [preferredPlacement].concat(fallbackPlacements).reduce(function (acc, placement) {
    return acc.concat(getBasePlacement(placement) === auto ? computeAutoPlacement(state, {
      placement: placement,
      boundary: boundary,
      rootBoundary: rootBoundary,
      padding: padding,
      flipVariations: flipVariations,
      allowedAutoPlacements: allowedAutoPlacements
    }) : placement);
  }, []);
  var referenceRect = state.rects.reference;
  var popperRect = state.rects.popper;
  var checksMap = new Map();
  var makeFallbackChecks = true;
  var firstFittingPlacement = placements[0];

  for (var i = 0; i < placements.length; i++) {
    var placement = placements[i];

    var _basePlacement = getBasePlacement(placement);

    var isStartVariation = getVariation(placement) === start;
    var isVertical = [top, bottom].indexOf(_basePlacement) >= 0;
    var len = isVertical ? 'width' : 'height';
    var overflow = detectOverflow(state, {
      placement: placement,
      boundary: boundary,
      rootBoundary: rootBoundary,
      altBoundary: altBoundary,
      padding: padding
    });
    var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top;

    if (referenceRect[len] > popperRect[len]) {
      mainVariationSide = getOppositePlacement(mainVariationSide);
    }

    var altVariationSide = getOppositePlacement(mainVariationSide);
    var checks = [];

    if (checkMainAxis) {
      checks.push(overflow[_basePlacement] <= 0);
    }

    if (checkAltAxis) {
      checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0);
    }

    if (checks.every(function (check) {
      return check;
    })) {
      firstFittingPlacement = placement;
      makeFallbackChecks = false;
      break;
    }

    checksMap.set(placement, checks);
  }

  if (makeFallbackChecks) {
    // `2` may be desired in some cases – research later
    var numberOfChecks = flipVariations ? 3 : 1;

    var _loop = function _loop(_i) {
      var fittingPlacement = placements.find(function (placement) {
        var checks = checksMap.get(placement);

        if (checks) {
          return checks.slice(0, _i).every(function (check) {
            return check;
          });
        }
      });

      if (fittingPlacement) {
        firstFittingPlacement = fittingPlacement;
        return "break";
      }
    };

    for (var _i = numberOfChecks; _i > 0; _i--) {
      var _ret = _loop(_i);

      if (_ret === "break") break;
    }
  }

  if (state.placement !== firstFittingPlacement) {
    state.modifiersData[name]._skip = true;
    state.placement = firstFittingPlacement;
    state.reset = true;
  }
} // eslint-disable-next-line import/no-unused-modules


var flip$1 = {
  name: 'flip',
  enabled: true,
  phase: 'main',
  fn: flip,
  requiresIfExists: ['offset'],
  data: {
    _skip: false
  }
};

function getSideOffsets(overflow, rect, preventedOffsets) {
  if (preventedOffsets === void 0) {
    preventedOffsets = {
      x: 0,
      y: 0
    };
  }

  return {
    top: overflow.top - rect.height - preventedOffsets.y,
    right: overflow.right - rect.width + preventedOffsets.x,
    bottom: overflow.bottom - rect.height + preventedOffsets.y,
    left: overflow.left - rect.width - preventedOffsets.x
  };
}

function isAnySideFullyClipped(overflow) {
  return [top, right, bottom, left].some(function (side) {
    return overflow[side] >= 0;
  });
}

function hide(_ref) {
  var state = _ref.state,
      name = _ref.name;
  var referenceRect = state.rects.reference;
  var popperRect = state.rects.popper;
  var preventedOffsets = state.modifiersData.preventOverflow;
  var referenceOverflow = detectOverflow(state, {
    elementContext: 'reference'
  });
  var popperAltOverflow = detectOverflow(state, {
    altBoundary: true
  });
  var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect);
  var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets);
  var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets);
  var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets);
  state.modifiersData[name] = {
    referenceClippingOffsets: referenceClippingOffsets,
    popperEscapeOffsets: popperEscapeOffsets,
    isReferenceHidden: isReferenceHidden,
    hasPopperEscaped: hasPopperEscaped
  };
  state.attributes.popper = Object.assign({}, state.attributes.popper, {
    'data-popper-reference-hidden': isReferenceHidden,
    'data-popper-escaped': hasPopperEscaped
  });
} // eslint-disable-next-line import/no-unused-modules


var hide$1 = {
  name: 'hide',
  enabled: true,
  phase: 'main',
  requiresIfExists: ['preventOverflow'],
  fn: hide
};

function distanceAndSkiddingToXY(placement, rects, offset) {
  var basePlacement = getBasePlacement(placement);
  var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1;

  var _ref = typeof offset === 'function' ? offset(Object.assign({}, rects, {
    placement: placement
  })) : offset,
      skidding = _ref[0],
      distance = _ref[1];

  skidding = skidding || 0;
  distance = (distance || 0) * invertDistance;
  return [left, right].indexOf(basePlacement) >= 0 ? {
    x: distance,
    y: skidding
  } : {
    x: skidding,
    y: distance
  };
}

function offset(_ref2) {
  var state = _ref2.state,
      options = _ref2.options,
      name = _ref2.name;
  var _options$offset = options.offset,
      offset = _options$offset === void 0 ? [0, 0] : _options$offset;
  var data = placements.reduce(function (acc, placement) {
    acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset);
    return acc;
  }, {});
  var _data$state$placement = data[state.placement],
      x = _data$state$placement.x,
      y = _data$state$placement.y;

  if (state.modifiersData.popperOffsets != null) {
    state.modifiersData.popperOffsets.x += x;
    state.modifiersData.popperOffsets.y += y;
  }

  state.modifiersData[name] = data;
} // eslint-disable-next-line import/no-unused-modules


var offset$1 = {
  name: 'offset',
  enabled: true,
  phase: 'main',
  requires: ['popperOffsets'],
  fn: offset
};

function popperOffsets(_ref) {
  var state = _ref.state,
      name = _ref.name;
  // Offsets are the actual position the popper needs to have to be
  // properly positioned near its reference element
  // This is the most basic placement, and will be adjusted by
  // the modifiers in the next step
  state.modifiersData[name] = computeOffsets({
    reference: state.rects.reference,
    element: state.rects.popper,
    strategy: 'absolute',
    placement: state.placement
  });
} // eslint-disable-next-line import/no-unused-modules


var popperOffsets$1 = {
  name: 'popperOffsets',
  enabled: true,
  phase: 'read',
  fn: popperOffsets,
  data: {}
};

function getAltAxis(axis) {
  return axis === 'x' ? 'y' : 'x';
}

function preventOverflow(_ref) {
  var state = _ref.state,
      options = _ref.options,
      name = _ref.name;
  var _options$mainAxis = options.mainAxis,
      checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,
      _options$altAxis = options.altAxis,
      checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis,
      boundary = options.boundary,
      rootBoundary = options.rootBoundary,
      altBoundary = options.altBoundary,
      padding = options.padding,
      _options$tether = options.tether,
      tether = _options$tether === void 0 ? true : _options$tether,
      _options$tetherOffset = options.tetherOffset,
      tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset;
  var overflow = detectOverflow(state, {
    boundary: boundary,
    rootBoundary: rootBoundary,
    padding: padding,
    altBoundary: altBoundary
  });
  var basePlacement = getBasePlacement(state.placement);
  var variation = getVariation(state.placement);
  var isBasePlacement = !variation;
  var mainAxis = getMainAxisFromPlacement(basePlacement);
  var altAxis = getAltAxis(mainAxis);
  var popperOffsets = state.modifiersData.popperOffsets;
  var referenceRect = state.rects.reference;
  var popperRect = state.rects.popper;
  var tetherOffsetValue = typeof tetherOffset === 'function' ? tetherOffset(Object.assign({}, state.rects, {
    placement: state.placement
  })) : tetherOffset;
  var normalizedTetherOffsetValue = typeof tetherOffsetValue === 'number' ? {
    mainAxis: tetherOffsetValue,
    altAxis: tetherOffsetValue
  } : Object.assign({
    mainAxis: 0,
    altAxis: 0
  }, tetherOffsetValue);
  var offsetModifierState = state.modifiersData.offset ? state.modifiersData.offset[state.placement] : null;
  var data = {
    x: 0,
    y: 0
  };

  if (!popperOffsets) {
    return;
  }

  if (checkMainAxis) {
    var _offsetModifierState$;

    var mainSide = mainAxis === 'y' ? top : left;
    var altSide = mainAxis === 'y' ? bottom : right;
    var len = mainAxis === 'y' ? 'height' : 'width';
    var offset = popperOffsets[mainAxis];
    var min$1 = offset + overflow[mainSide];
    var max$1 = offset - overflow[altSide];
    var additive = tether ? -popperRect[len] / 2 : 0;
    var minLen = variation === start ? referenceRect[len] : popperRect[len];
    var maxLen = variation === start ? -popperRect[len] : -referenceRect[len]; // We need to include the arrow in the calculation so the arrow doesn't go
    // outside the reference bounds

    var arrowElement = state.elements.arrow;
    var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : {
      width: 0,
      height: 0
    };
    var arrowPaddingObject = state.modifiersData['arrow#persistent'] ? state.modifiersData['arrow#persistent'].padding : getFreshSideObject();
    var arrowPaddingMin = arrowPaddingObject[mainSide];
    var arrowPaddingMax = arrowPaddingObject[altSide]; // If the reference length is smaller than the arrow length, we don't want
    // to include its full size in the calculation. If the reference is small
    // and near the edge of a boundary, the popper can overflow even if the
    // reference is not overflowing as well (e.g. virtual elements with no
    // width or height)

    var arrowLen = within(0, referenceRect[len], arrowRect[len]);
    var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis : minLen - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis;
    var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis : maxLen + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis;
    var arrowOffsetParent = state.elements.arrow && getOffsetParent(state.elements.arrow);
    var clientOffset = arrowOffsetParent ? mainAxis === 'y' ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0;
    var offsetModifierValue = (_offsetModifierState$ = offsetModifierState == null ? void 0 : offsetModifierState[mainAxis]) != null ? _offsetModifierState$ : 0;
    var tetherMin = offset + minOffset - offsetModifierValue - clientOffset;
    var tetherMax = offset + maxOffset - offsetModifierValue;
    var preventedOffset = within(tether ? min(min$1, tetherMin) : min$1, offset, tether ? max(max$1, tetherMax) : max$1);
    popperOffsets[mainAxis] = preventedOffset;
    data[mainAxis] = preventedOffset - offset;
  }

  if (checkAltAxis) {
    var _offsetModifierState$2;

    var _mainSide = mainAxis === 'x' ? top : left;

    var _altSide = mainAxis === 'x' ? bottom : right;

    var _offset = popperOffsets[altAxis];

    var _len = altAxis === 'y' ? 'height' : 'width';

    var _min = _offset + overflow[_mainSide];

    var _max = _offset - overflow[_altSide];

    var isOriginSide = [top, left].indexOf(basePlacement) !== -1;

    var _offsetModifierValue = (_offsetModifierState$2 = offsetModifierState == null ? void 0 : offsetModifierState[altAxis]) != null ? _offsetModifierState$2 : 0;

    var _tetherMin = isOriginSide ? _min : _offset - referenceRect[_len] - popperRect[_len] - _offsetModifierValue + normalizedTetherOffsetValue.altAxis;

    var _tetherMax = isOriginSide ? _offset + referenceRect[_len] + popperRect[_len] - _offsetModifierValue - normalizedTetherOffsetValue.altAxis : _max;

    var _preventedOffset = tether && isOriginSide ? withinMaxClamp(_tetherMin, _offset, _tetherMax) : within(tether ? _tetherMin : _min, _offset, tether ? _tetherMax : _max);

    popperOffsets[altAxis] = _preventedOffset;
    data[altAxis] = _preventedOffset - _offset;
  }

  state.modifiersData[name] = data;
} // eslint-disable-next-line import/no-unused-modules


var preventOverflow$1 = {
  name: 'preventOverflow',
  enabled: true,
  phase: 'main',
  fn: preventOverflow,
  requiresIfExists: ['offset']
};

function getHTMLElementScroll(element) {
  return {
    scrollLeft: element.scrollLeft,
    scrollTop: element.scrollTop
  };
}

function getNodeScroll(node) {
  if (node === getWindow(node) || !isHTMLElement(node)) {
    return getWindowScroll(node);
  } else {
    return getHTMLElementScroll(node);
  }
}

function isElementScaled(element) {
  var rect = element.getBoundingClientRect();
  var scaleX = round(rect.width) / element.offsetWidth || 1;
  var scaleY = round(rect.height) / element.offsetHeight || 1;
  return scaleX !== 1 || scaleY !== 1;
} // Returns the composite rect of an element relative to its offsetParent.
// Composite means it takes into account transforms as well as layout.


function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) {
  if (isFixed === void 0) {
    isFixed = false;
  }

  var isOffsetParentAnElement = isHTMLElement(offsetParent);
  var offsetParentIsScaled = isHTMLElement(offsetParent) && isElementScaled(offsetParent);
  var documentElement = getDocumentElement(offsetParent);
  var rect = getBoundingClientRect(elementOrVirtualElement, offsetParentIsScaled);
  var scroll = {
    scrollLeft: 0,
    scrollTop: 0
  };
  var offsets = {
    x: 0,
    y: 0
  };

  if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
    if (getNodeName(offsetParent) !== 'body' || // https://github.com/popperjs/popper-core/issues/1078
    isScrollParent(documentElement)) {
      scroll = getNodeScroll(offsetParent);
    }

    if (isHTMLElement(offsetParent)) {
      offsets = getBoundingClientRect(offsetParent, true);
      offsets.x += offsetParent.clientLeft;
      offsets.y += offsetParent.clientTop;
    } else if (documentElement) {
      offsets.x = getWindowScrollBarX(documentElement);
    }
  }

  return {
    x: rect.left + scroll.scrollLeft - offsets.x,
    y: rect.top + scroll.scrollTop - offsets.y,
    width: rect.width,
    height: rect.height
  };
}

function order(modifiers) {
  var map = new Map();
  var visited = new Set();
  var result = [];
  modifiers.forEach(function (modifier) {
    map.set(modifier.name, modifier);
  }); // On visiting object, check for its dependencies and visit them recursively

  function sort(modifier) {
    visited.add(modifier.name);
    var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []);
    requires.forEach(function (dep) {
      if (!visited.has(dep)) {
        var depModifier = map.get(dep);

        if (depModifier) {
          sort(depModifier);
        }
      }
    });
    result.push(modifier);
  }

  modifiers.forEach(function (modifier) {
    if (!visited.has(modifier.name)) {
      // check for visited object
      sort(modifier);
    }
  });
  return result;
}

function orderModifiers(modifiers) {
  // order based on dependencies
  var orderedModifiers = order(modifiers); // order based on phase

  return modifierPhases.reduce(function (acc, phase) {
    return acc.concat(orderedModifiers.filter(function (modifier) {
      return modifier.phase === phase;
    }));
  }, []);
}

function debounce(fn) {
  var pending;
  return function () {
    if (!pending) {
      pending = new Promise(function (resolve) {
        Promise.resolve().then(function () {
          pending = undefined;
          resolve(fn());
        });
      });
    }

    return pending;
  };
}

function format(str) {
  for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
    args[_key - 1] = arguments[_key];
  }

  return [].concat(args).reduce(function (p, c) {
    return p.replace(/%s/, c);
  }, str);
}

var INVALID_MODIFIER_ERROR = 'Popper: modifier "%s" provided an invalid %s property, expected %s but got %s';
var MISSING_DEPENDENCY_ERROR = 'Popper: modifier "%s" requires "%s", but "%s" modifier is not available';
var VALID_PROPERTIES = ['name', 'enabled', 'phase', 'fn', 'effect', 'requires', 'options'];
function validateModifiers(modifiers) {
  modifiers.forEach(function (modifier) {
    [].concat(Object.keys(modifier), VALID_PROPERTIES) // IE11-compatible replacement for `new Set(iterable)`
    .filter(function (value, index, self) {
      return self.indexOf(value) === index;
    }).forEach(function (key) {
      switch (key) {
        case 'name':
          if (typeof modifier.name !== 'string') {
            console.error(format(INVALID_MODIFIER_ERROR, String(modifier.name), '"name"', '"string"', "\"" + String(modifier.name) + "\""));
          }

          break;

        case 'enabled':
          if (typeof modifier.enabled !== 'boolean') {
            console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"enabled"', '"boolean"', "\"" + String(modifier.enabled) + "\""));
          }

          break;

        case 'phase':
          if (modifierPhases.indexOf(modifier.phase) < 0) {
            console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"phase"', "either " + modifierPhases.join(', '), "\"" + String(modifier.phase) + "\""));
          }

          break;

        case 'fn':
          if (typeof modifier.fn !== 'function') {
            console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"fn"', '"function"', "\"" + String(modifier.fn) + "\""));
          }

          break;

        case 'effect':
          if (modifier.effect != null && typeof modifier.effect !== 'function') {
            console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"effect"', '"function"', "\"" + String(modifier.fn) + "\""));
          }

          break;

        case 'requires':
          if (modifier.requires != null && !Array.isArray(modifier.requires)) {
            console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"requires"', '"array"', "\"" + String(modifier.requires) + "\""));
          }

          break;

        case 'requiresIfExists':
          if (!Array.isArray(modifier.requiresIfExists)) {
            console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"requiresIfExists"', '"array"', "\"" + String(modifier.requiresIfExists) + "\""));
          }

          break;

        case 'options':
        case 'data':
          break;

        default:
          console.error("PopperJS: an invalid property has been provided to the \"" + modifier.name + "\" modifier, valid properties are " + VALID_PROPERTIES.map(function (s) {
            return "\"" + s + "\"";
          }).join(', ') + "; but \"" + key + "\" was provided.");
      }

      modifier.requires && modifier.requires.forEach(function (requirement) {
        if (modifiers.find(function (mod) {
          return mod.name === requirement;
        }) == null) {
          console.error(format(MISSING_DEPENDENCY_ERROR, String(modifier.name), requirement, requirement));
        }
      });
    });
  });
}

function uniqueBy(arr, fn) {
  var identifiers = new Set();
  return arr.filter(function (item) {
    var identifier = fn(item);

    if (!identifiers.has(identifier)) {
      identifiers.add(identifier);
      return true;
    }
  });
}

function mergeByName(modifiers) {
  var merged = modifiers.reduce(function (merged, current) {
    var existing = merged[current.name];
    merged[current.name] = existing ? Object.assign({}, existing, current, {
      options: Object.assign({}, existing.options, current.options),
      data: Object.assign({}, existing.data, current.data)
    }) : current;
    return merged;
  }, {}); // IE11 does not support Object.values

  return Object.keys(merged).map(function (key) {
    return merged[key];
  });
}

var INVALID_ELEMENT_ERROR = 'Popper: Invalid reference or popper argument provided. They must be either a DOM element or virtual element.';
var INFINITE_LOOP_ERROR = 'Popper: An infinite loop in the modifiers cycle has been detected! The cycle has been interrupted to prevent a browser crash.';
var DEFAULT_OPTIONS = {
  placement: 'bottom',
  modifiers: [],
  strategy: 'absolute'
};

function areValidElements() {
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
    args[_key] = arguments[_key];
  }

  return !args.some(function (element) {
    return !(element && typeof element.getBoundingClientRect === 'function');
  });
}

function popperGenerator(generatorOptions) {
  if (generatorOptions === void 0) {
    generatorOptions = {};
  }

  var _generatorOptions = generatorOptions,
      _generatorOptions$def = _generatorOptions.defaultModifiers,
      defaultModifiers = _generatorOptions$def === void 0 ? [] : _generatorOptions$def,
      _generatorOptions$def2 = _generatorOptions.defaultOptions,
      defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2;
  return function createPopper(reference, popper, options) {
    if (options === void 0) {
      options = defaultOptions;
    }

    var state = {
      placement: 'bottom',
      orderedModifiers: [],
      options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions),
      modifiersData: {},
      elements: {
        reference: reference,
        popper: popper
      },
      attributes: {},
      styles: {}
    };
    var effectCleanupFns = [];
    var isDestroyed = false;
    var instance = {
      state: state,
      setOptions: function setOptions(setOptionsAction) {
        var options = typeof setOptionsAction === 'function' ? setOptionsAction(state.options) : setOptionsAction;
        cleanupModifierEffects();
        state.options = Object.assign({}, defaultOptions, state.options, options);
        state.scrollParents = {
          reference: isElement(reference) ? listScrollParents(reference) : reference.contextElement ? listScrollParents(reference.contextElement) : [],
          popper: listScrollParents(popper)
        }; // Orders the modifiers based on their dependencies and `phase`
        // properties

        var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers, state.options.modifiers))); // Strip out disabled modifiers

        state.orderedModifiers = orderedModifiers.filter(function (m) {
          return m.enabled;
        }); // Validate the provided modifiers so that the consumer will get warned
        // if one of the modifiers is invalid for any reason

        if (process.env.NODE_ENV !== "production") {
          var modifiers = uniqueBy([].concat(orderedModifiers, state.options.modifiers), function (_ref) {
            var name = _ref.name;
            return name;
          });
          validateModifiers(modifiers);

          if (getBasePlacement(state.options.placement) === auto) {
            var flipModifier = state.orderedModifiers.find(function (_ref2) {
              var name = _ref2.name;
              return name === 'flip';
            });

            if (!flipModifier) {
              console.error(['Popper: "auto" placements require the "flip" modifier be', 'present and enabled to work.'].join(' '));
            }
          }

          var _getComputedStyle = getComputedStyle(popper),
              marginTop = _getComputedStyle.marginTop,
              marginRight = _getComputedStyle.marginRight,
              marginBottom = _getComputedStyle.marginBottom,
              marginLeft = _getComputedStyle.marginLeft; // We no longer take into account `margins` on the popper, and it can
          // cause bugs with positioning, so we'll warn the consumer


          if ([marginTop, marginRight, marginBottom, marginLeft].some(function (margin) {
            return parseFloat(margin);
          })) {
            console.warn(['Popper: CSS "margin" styles cannot be used to apply padding', 'between the popper and its reference element or boundary.', 'To replicate margin, use the `offset` modifier, as well as', 'the `padding` option in the `preventOverflow` and `flip`', 'modifiers.'].join(' '));
          }
        }

        runModifierEffects();
        return instance.update();
      },
      // Sync update – it will always be executed, even if not necessary. This
      // is useful for low frequency updates where sync behavior simplifies the
      // logic.
      // For high frequency updates (e.g. `resize` and `scroll` events), always
      // prefer the async Popper#update method
      forceUpdate: function forceUpdate() {
        if (isDestroyed) {
          return;
        }

        var _state$elements = state.elements,
            reference = _state$elements.reference,
            popper = _state$elements.popper; // Don't proceed if `reference` or `popper` are not valid elements
        // anymore

        if (!areValidElements(reference, popper)) {
          if (process.env.NODE_ENV !== "production") {
            console.error(INVALID_ELEMENT_ERROR);
          }

          return;
        } // Store the reference and popper rects to be read by modifiers


        state.rects = {
          reference: getCompositeRect(reference, getOffsetParent(popper), state.options.strategy === 'fixed'),
          popper: getLayoutRect(popper)
        }; // Modifiers have the ability to reset the current update cycle. The
        // most common use case for this is the `flip` modifier changing the
        // placement, which then needs to re-run all the modifiers, because the
        // logic was previously ran for the previous placement and is therefore
        // stale/incorrect

        state.reset = false;
        state.placement = state.options.placement; // On each update cycle, the `modifiersData` property for each modifier
        // is filled with the initial data specified by the modifier. This means
        // it doesn't persist and is fresh on each update.
        // To ensure persistent data, use `${name}#persistent`

        state.orderedModifiers.forEach(function (modifier) {
          return state.modifiersData[modifier.name] = Object.assign({}, modifier.data);
        });
        var __debug_loops__ = 0;

        for (var index = 0; index < state.orderedModifiers.length; index++) {
          if (process.env.NODE_ENV !== "production") {
            __debug_loops__ += 1;

            if (__debug_loops__ > 100) {
              console.error(INFINITE_LOOP_ERROR);
              break;
            }
          }

          if (state.reset === true) {
            state.reset = false;
            index = -1;
            continue;
          }

          var _state$orderedModifie = state.orderedModifiers[index],
              fn = _state$orderedModifie.fn,
              _state$orderedModifie2 = _state$orderedModifie.options,
              _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2,
              name = _state$orderedModifie.name;

          if (typeof fn === 'function') {
            state = fn({
              state: state,
              options: _options,
              name: name,
              instance: instance
            }) || state;
          }
        }
      },
      // Async and optimistically optimized update – it will not be executed if
      // not necessary (debounced to run at most once-per-tick)
      update: debounce(function () {
        return new Promise(function (resolve) {
          instance.forceUpdate();
          resolve(state);
        });
      }),
      destroy: function destroy() {
        cleanupModifierEffects();
        isDestroyed = true;
      }
    };

    if (!areValidElements(reference, popper)) {
      if (process.env.NODE_ENV !== "production") {
        console.error(INVALID_ELEMENT_ERROR);
      }

      return instance;
    }

    instance.setOptions(options).then(function (state) {
      if (!isDestroyed && options.onFirstUpdate) {
        options.onFirstUpdate(state);
      }
    }); // Modifiers have the ability to execute arbitrary code before the first
    // update cycle runs. They will be executed in the same order as the update
    // cycle. This is useful when a modifier adds some persistent data that
    // other modifiers need to use, but the modifier is run after the dependent
    // one.

    function runModifierEffects() {
      state.orderedModifiers.forEach(function (_ref3) {
        var name = _ref3.name,
            _ref3$options = _ref3.options,
            options = _ref3$options === void 0 ? {} : _ref3$options,
            effect = _ref3.effect;

        if (typeof effect === 'function') {
          var cleanupFn = effect({
            state: state,
            name: name,
            instance: instance,
            options: options
          });

          var noopFn = function noopFn() {};

          effectCleanupFns.push(cleanupFn || noopFn);
        }
      });
    }

    function cleanupModifierEffects() {
      effectCleanupFns.forEach(function (fn) {
        return fn();
      });
      effectCleanupFns = [];
    }

    return instance;
  };
}

var defaultModifiers = [eventListeners, popperOffsets$1, computeStyles$1, applyStyles$1, offset$1, flip$1, preventOverflow$1, arrow$1, hide$1];
var createPopper = /*#__PURE__*/popperGenerator({
  defaultModifiers: defaultModifiers
}); // eslint-disable-next-line import/no-unused-modules

// Credits go to Liam's Periodic Notes Plugin: https://github.com/liamcain/obsidian-periodic-notes
const wrapAround = (value, size) => {
    return ((value % size) + size) % size;
};
class Suggest {
    constructor(owner, containerEl, scope) {
        this.owner = owner;
        this.containerEl = containerEl;
        containerEl.on("click", ".suggestion-item", this.onSuggestionClick.bind(this));
        containerEl.on("mousemove", ".suggestion-item", this.onSuggestionMouseover.bind(this));
        scope.register([], "ArrowUp", (event) => {
            if (!event.isComposing) {
                this.setSelectedItem(this.selectedItem - 1, true);
                return false;
            }
        });
        scope.register([], "ArrowDown", (event) => {
            if (!event.isComposing) {
                this.setSelectedItem(this.selectedItem + 1, true);
                return false;
            }
        });
        scope.register([], "Enter", (event) => {
            if (!event.isComposing) {
                this.useSelectedItem(event);
                return false;
            }
        });
    }
    onSuggestionClick(event, el) {
        event.preventDefault();
        const item = this.suggestions.indexOf(el);
        this.setSelectedItem(item, false);
        this.useSelectedItem(event);
    }
    onSuggestionMouseover(_event, el) {
        const item = this.suggestions.indexOf(el);
        this.setSelectedItem(item, false);
    }
    setSuggestions(values) {
        this.containerEl.empty();
        const suggestionEls = [];
        values.forEach((value) => {
            const suggestionEl = this.containerEl.createDiv("suggestion-item");
            this.owner.renderSuggestion(value, suggestionEl);
            suggestionEls.push(suggestionEl);
        });
        this.values = values;
        this.suggestions = suggestionEls;
        this.setSelectedItem(0, false);
    }
    useSelectedItem(event) {
        const currentValue = this.values[this.selectedItem];
        if (currentValue) {
            this.owner.selectSuggestion(currentValue, event);
        }
    }
    setSelectedItem(selectedIndex, scrollIntoView) {
        const normalizedIndex = wrapAround(selectedIndex, this.suggestions.length);
        const prevSelectedSuggestion = this.suggestions[this.selectedItem];
        const selectedSuggestion = this.suggestions[normalizedIndex];
        prevSelectedSuggestion === null || prevSelectedSuggestion === void 0 ? void 0 : prevSelectedSuggestion.removeClass("is-selected");
        selectedSuggestion === null || selectedSuggestion === void 0 ? void 0 : selectedSuggestion.addClass("is-selected");
        this.selectedItem = normalizedIndex;
        if (scrollIntoView) {
            selectedSuggestion.scrollIntoView(false);
        }
    }
}
class TextInputSuggest {
    constructor(app, inputEl) {
        this.app = app;
        this.inputEl = inputEl;
        this.scope = new obsidian.Scope();
        this.suggestEl = createDiv("suggestion-container");
        const suggestion = this.suggestEl.createDiv("suggestion");
        this.suggest = new Suggest(this, suggestion, this.scope);
        this.scope.register([], "Escape", this.close.bind(this));
        this.inputEl.addEventListener("input", this.onInputChanged.bind(this));
        this.inputEl.addEventListener("focus", this.onInputChanged.bind(this));
        this.inputEl.addEventListener("blur", this.close.bind(this));
        this.suggestEl.on("mousedown", ".suggestion-container", (event) => {
            event.preventDefault();
        });
    }
    onInputChanged() {
        const inputStr = this.inputEl.value;
        const suggestions = this.getSuggestions(inputStr);
        if (!suggestions) {
            this.close();
            return;
        }
        if (suggestions.length > 0) {
            this.suggest.setSuggestions(suggestions);
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            this.open(this.app.dom.appContainerEl, this.inputEl);
        }
        else {
            this.close();
        }
    }
    open(container, inputEl) {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        this.app.keymap.pushScope(this.scope);
        container.appendChild(this.suggestEl);
        this.popper = createPopper(inputEl, this.suggestEl, {
            placement: "bottom-start",
            modifiers: [
                {
                    name: "sameWidth",
                    enabled: true,
                    fn: ({ state, instance }) => {
                        // Note: positioning needs to be calculated twice -
                        // first pass - positioning it according to the width of the popper
                        // second pass - position it with the width bound to the reference element
                        // we need to early exit to avoid an infinite loop
                        const targetWidth = `${state.rects.reference.width}px`;
                        if (state.styles.popper.width === targetWidth) {
                            return;
                        }
                        state.styles.popper.width = targetWidth;
                        instance.update();
                    },
                    phase: "beforeWrite",
                    requires: ["computeStyles"],
                },
            ],
        });
    }
    close() {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        this.app.keymap.popScope(this.scope);
        this.suggest.setSuggestions([]);
        if (this.popper)
            this.popper.destroy();
        this.suggestEl.detach();
    }
}

// Credits go to Liam's Periodic Notes Plugin: https://github.com/liamcain/obsidian-periodic-notes
class FolderSuggest extends TextInputSuggest {
    getSuggestions(inputStr) {
        const abstractFiles = this.app.vault.getAllLoadedFiles();
        const folders = [];
        const lowerCaseInputStr = inputStr.toLowerCase();
        abstractFiles.forEach((folder) => {
            if (folder instanceof obsidian.TFolder &&
                folder.path.toLowerCase().contains(lowerCaseInputStr)) {
                folders.push(folder);
            }
        });
        return folders;
    }
    renderSuggestion(file, el) {
        el.setText(file.path);
    }
    selectSuggestion(file) {
        this.inputEl.value = file.path;
        this.inputEl.trigger("input");
        this.close();
    }
}

class LongformSettingsTab extends obsidian.PluginSettingTab {
    constructor(app, plugin) {
        super(app, plugin);
        this.plugin = plugin;
    }
    display() {
        const { containerEl } = this;
        containerEl.empty();
        new obsidian.Setting(containerEl).setName("User Script Steps").setHeading();
        new obsidian.Setting(containerEl)
            .setName("User Script Step Folder")
            .setDesc(".js files in this folder will be available as User Script Steps in the Compile panel.")
            .addSearch((cb) => {
            new FolderSuggest(this.app, cb.inputEl);
            cb.setPlaceholder("my/script/steps/")
                .setValue(get_store_value(pluginSettings).userScriptFolder)
                .onChange((v) => {
                pluginSettings.update((s) => (Object.assign(Object.assign({}, s), { userScriptFolder: v })));
            });
        });
        this.stepsSummary = containerEl.createSpan();
        this.stepsList = containerEl.createEl("ul", {
            cls: "longform-settings-user-steps",
        });
        this.unsubscribeUserScripts = userScriptSteps.subscribe((steps) => {
            if (steps && steps.length > 0) {
                this.stepsSummary.innerText = `Loaded ${steps.length} step${steps.length !== 1 ? "s" : ""}:`;
            }
            else {
                this.stepsSummary.innerText = "No steps loaded.";
            }
            if (this.stepsList) {
                this.stepsList.empty();
                if (steps) {
                    steps.forEach((s) => {
                        const stepEl = this.stepsList.createEl("li");
                        stepEl.createSpan({
                            text: s.description.name,
                            cls: "longform-settings-user-step-name",
                        });
                        stepEl.createSpan({
                            text: `(${s.description.canonicalID})`,
                            cls: "longform-settings-user-step-id",
                        });
                    });
                }
            }
        });
        containerEl.createEl("p", { cls: "setting-item-description" }, (el) => {
            el.innerHTML =
                "User Script Steps are automatically loaded from this folder. Changes to .js files in this folder are synced with Longform after a slight delay. If your script does not appear here or in the Compile tab, you may have an error in your script—check the dev console for it.";
        });
        new obsidian.Setting(containerEl).setName("Debugging").setHeading();
        new obsidian.Setting(containerEl)
            .setDesc("Removes all projects from Longform. Useful for debugging issues. No notes will be lost.")
            .addButton((cb) => {
            cb.setButtonText("Untrack All Projects")
                .setWarning()
                .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();
            }));
        });
        new obsidian.Setting(containerEl).setName("Credits").setHeading();
        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>.';
        });
    }
    hide() {
        this.unsubscribeUserScripts();
    }
}

/**
 * Prepare a workflow for storage as json.
 * @param workflow The workflow to serialize.
 * @requires serialized An array of `SerializedStep`s that can be safely saved as json.
 */
function serializeWorkflow(workflow) {
    const serialized = workflow.steps.map((step) => ({
        id: step.description.canonicalID,
        optionValues: step.optionValues,
    }));
    return {
        name: workflow.name,
        description: workflow.description,
        steps: serialized,
    };
}
function lookupStep(id, userSteps = []) {
    const builtIn = BUILTIN_STEPS.find((s) => s.id === id);
    if (builtIn) {
        return builtIn;
    }
    const userStep = userSteps.find((s) => s.id === id);
    if (userStep) {
        return userStep;
    }
    return PLACEHOLDER_MISSING_STEP;
}
/**
 * Deserializes an array of JSON-compatible steps into one that can be run as a workflow.
 * @param steps The JSON-compatible steps to deserialize.
 * @returns deserialized Array of `CompileStep`s to use as a workflow.
 */
function deserializeWorkflow(w) {
    var _a;
    const userSteps = (_a = get_store_value(userScriptSteps)) !== null && _a !== void 0 ? _a : [];
    const deserialized = Object.assign(Object.assign({}, w), { steps: w.steps.map((s) => {
            const step = lookupStep(s.id, userSteps);
            return Object.assign(Object.assign({}, step), { optionValues: s.optionValues });
        }) });
    return deserialized;
}

const DEBOUNCE_SCRIPT_LOAD_DELAY_MS = 10000;
/**
 * Watches the user's script folder and loads the scripts it finds there.
 */
class UserScriptObserver {
    constructor(vault, userScriptFolder) {
        this.initializedSteps = false;
        this.vault = vault;
        this.userScriptFolder = userScriptFolder;
        this.onScriptModify = debounce_1(() => {
            console.log(`[Longform] File in user script folder modified, reloading scripts…`);
            this.loadUserSteps();
        }, DEBOUNCE_SCRIPT_LOAD_DELAY_MS);
    }
    destroy() {
        this.unsubscribeScriptFolder();
    }
    beginObserving() {
        if (this.unsubscribeScriptFolder) {
            this.unsubscribeScriptFolder();
        }
        this.unsubscribeScriptFolder = pluginSettings.subscribe((s) => __awaiter(this, void 0, void 0, function* () {
            if (this.initializedSteps &&
                s.userScriptFolder === this.userScriptFolder) {
                return;
            }
            const valid = yield this.vault.adapter.exists(s.userScriptFolder);
            if (!valid) {
                return;
            }
            this.userScriptFolder = s.userScriptFolder;
            if (this.userScriptFolder) {
                yield this.loadUserSteps();
            }
            else {
                userScriptSteps.set(null);
                console.log("[Longform] Cleared user script steps.");
            }
        }));
    }
    loadUserSteps() {
        return __awaiter(this, void 0, void 0, function* () {
            if (!this.userScriptFolder) {
                return;
            }
            const valid = yield this.vault.adapter.exists(this.userScriptFolder);
            if (!valid) {
                return;
            }
            // Get all .js files in folder
            const { files } = yield this.vault.adapter.list(this.userScriptFolder);
            const scripts = files.filter((f) => f.endsWith("js"));
            const userSteps = [];
            for (const file of scripts) {
                try {
                    const step = yield this.loadScript(file);
                    userSteps.push(step);
                }
                catch (e) {
                    console.error(`[Longform] skipping user script ${file} due to error:`, e);
                }
            }
            console.log(`[Longform] Loaded ${userSteps.length} user script steps.`);
            userScriptSteps.set(userSteps);
            this.initializedSteps = true;
            // if workflows have loaded, merge in user steps to get updated values
            const _workflows = get_store_value(workflows);
            const workflowNames = Object.keys(_workflows);
            const mergedWorkflows = {};
            workflowNames.forEach((name) => {
                const workflow = _workflows[name];
                const workflowSteps = workflow.steps.map((step) => {
                    const userStep = userSteps.find((u) => step.description.canonicalID === u.description.canonicalID);
                    if (userStep) {
                        let mergedStep = Object.assign(Object.assign({}, userStep), { id: step.id, optionValues: userStep.optionValues });
                        // Copy existing step's option values into the merged step
                        for (const key of Object.keys(step.optionValues)) {
                            if (mergedStep.optionValues[key]) {
                                mergedStep = Object.assign(Object.assign({}, mergedStep), { optionValues: Object.assign(Object.assign({}, mergedStep.optionValues), { [key]: step.optionValues[key] }) });
                            }
                        }
                        return mergedStep;
                    }
                    else {
                        return step;
                    }
                });
                mergedWorkflows[name] = Object.assign(Object.assign({}, workflow), { steps: workflowSteps });
            });
            workflows.set(mergedWorkflows);
            return userSteps;
        });
    }
    loadScript(path) {
        return __awaiter(this, void 0, void 0, function* () {
            const js = yield this.vault.adapter.read(path);
            // eslint-disable-next-line prefer-const
            let _require = (s) => {
                return window.require && window.require(s);
            };
            // eslint-disable-next-line prefer-const
            let exports = {};
            // eslint-disable-next-line prefer-const
            let module = {
                exports,
            };
            const evaluateScript = window.eval("(function anonymous(require, module, exports){" + js + "\n})");
            evaluateScript(_require, module, exports);
            const loadedStep = exports["default"] || module.exports;
            if (!loadedStep) {
                console.error(`[Longform] Failed to load user script ${path}. No exports detected.`);
                throw new Error(`Failed to load user script ${path}. No exports detected.`);
            }
            const step = makeBuiltinStep(Object.assign(Object.assign({}, loadedStep), { id: path, description: Object.assign(Object.assign({}, loadedStep.description), { availableKinds: loadedStep.description.availableKinds.map((v) => CompileStepKind[v]), options: loadedStep.description.options.map((o) => (Object.assign(Object.assign({}, o), { type: CompileStepOptionType[o.type] }))) }) }), true);
            return Object.assign(Object.assign({}, step), { id: path, description: Object.assign(Object.assign({}, step.description), { canonicalID: path, isScript: true }) });
        });
    }
    fileEventCallback(file) {
        if (this.userScriptFolder &&
            file.path.endsWith("js") &&
            ((file.parent && file.parent.path == this.userScriptFolder) ||
                (file.parent === null && file.path.startsWith(this.userScriptFolder)))) {
            this.onScriptModify();
        }
    }
}

const LONGFORM_LEAF_CLASS = "longform-leaf";
// TODO: Try and abstract away more logic from actual plugin hooks here
class LongformPlugin extends obsidian.Plugin {
    constructor() {
        super(...arguments);
        // Local mirror of the pluginSettings store
        // since this class does a lot of ad-hoc settings fetching.
        // More efficient than a lot of get() calls.
        this.cachedSettings = null;
    }
    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) => __awaiter(this, void 0, void 0, function* () {
                let shouldSave = false;
                if (this.cachedSettings &&
                    this.cachedSettings.userScriptFolder !== value.userScriptFolder) {
                    shouldSave = true;
                }
                this.cachedSettings = value;
                if (shouldSave) {
                    yield this.saveSettings();
                }
            }));
            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.userScriptObserver.destroy();
        this.unsubscribeSettings();
        this.unsubscribeCurrentProjectPath();
        this.unsubscribeCurrentDraftPath();
        this.unsubscribeWorkflows();
        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());
            const _pluginSettings = pick_1(settings, TRACKED_SETTINGS_PATHS);
            pluginSettings.set(_pluginSettings);
            currentDraftPath.set(_pluginSettings.selectedDraft);
            currentProjectPath.set(_pluginSettings.selectedProject);
            // We load user scripts imperatively first to cover cases where we need to deserialize
            // workflows that may contain them.
            const userScriptFolder = settings["userScriptFolder"];
            this.userScriptObserver = new UserScriptObserver(this.app.vault, userScriptFolder);
            yield this.userScriptObserver.loadUserSteps();
            let _workflows = settings["workflows"];
            if (!_workflows) {
                console.log("[Longform] No workflows found; adding default workflow.");
                _workflows = DEFAULT_WORKFLOWS;
            }
            const deserializedWorkflows = {};
            Object.entries(_workflows).forEach(([key, value]) => {
                deserializedWorkflows[key] = deserializeWorkflow(value);
            });
            workflows.set(deserializedWorkflows);
        });
    }
    saveSettings() {
        return __awaiter(this, void 0, void 0, function* () {
            if (!this.cachedSettings) {
                return;
            }
            const _workflows = get_store_value(workflows);
            const serializedWorkflows = {};
            Object.entries(_workflows).forEach(([key, value]) => {
                serializedWorkflows[key] = serializeWorkflow(value);
            });
            yield this.saveData(Object.assign(Object.assign({}, this.cachedSettings), { workflows: serializedWorkflows }));
        });
    }
    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) {
                let contents = indexBodyFor(EmptyIndexFileMetadata);
                if (!contents) {
                    console.error("[Longform] Unable to initialize index file.");
                    contents = "";
                }
                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.userScriptObserver.beginObserving();
        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
            this.cachedSettings = get_store_value(pluginSettings);
            yield this.saveSettings();
        }));
        // Workflows
        const saveWorkflows = debounce_1(() => {
            this.saveSettings();
        }, 3000);
        this.unsubscribeWorkflows = workflows.subscribe(() => {
            if (!get_store_value(initialized)) {
                return;
            }
            saveWorkflows();
        });
        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("modify", this.userScriptObserver.fileEventCallback.bind(this.userScriptObserver)));
        this.registerEvent(this.app.vault.on("create", (file) => {
            this.foldersObserver.fileCreated.bind(this.foldersObserver)(file);
            this.userScriptObserver.fileEventCallback.bind(this.userScriptObserver)(file);
        }));
        this.registerEvent(this.app.vault.on("delete", (file) => {
            this.foldersObserver.fileDeleted.bind(this.foldersObserver)(file);
            this.userScriptObserver.fileEventCallback.bind(this.userScriptObserver)(file);
        }));
        this.registerEvent(this.app.vault.on("rename", (file, oldPath) => {
            this.foldersObserver.fileRenamed.bind(this.foldersObserver)(file, oldPath);
            this.userScriptObserver.fileEventCallback.bind(this.userScriptObserver)(file);
        }));
        this.registerEvent(this.app.metadataCache.on("changed", this.metadataObserver.metadataCacheChanged.bind(this.metadataObserver)));
        console.log(`[Longform] Loaded and watching projects.`);
    }
}

module.exports = LongformPlugin;
