+ groups[name];\n })\n );\n } else if (typeof substitution === 'function') {\n var _this = this;\n\n return _super[Symbol.replace].call(this, str, function() {\n var args = [];\n args.push.apply(args, arguments);\n\n if (typeof args[args.length - 1] !== 'object') {\n args.push(buildGroups(args, _this));\n }\n\n return substitution.apply(this, args);\n });\n } else {\n return _super[Symbol.replace].call(this, str, substitution);\n }\n };\n\n function buildGroups(result, re) {\n var g = _groups.get(re);\n\n return Object.keys(g).reduce(function(groups, name) {\n groups[name] = result[g[name]];\n return groups;\n }, Object.create(null));\n }\n\n return _wrapRegExp.apply(this, arguments);\n }\n\n var arrayRemove = function arrayRemove(arr, index) {\n return arr.splice(index, 1);\n };\n\n var run = function run(cb, sync) {\n if (sync) {\n cb();\n } else if (document.hidden) {\n Promise.resolve(1).then(cb);\n } else {\n setTimeout(cb, 0);\n }\n };\n\n var on = function on() {\n var listeners = [];\n var off = function off(event, cb) {\n arrayRemove(\n listeners,\n listeners.findIndex(function(listener) {\n return listener.event === event && (listener.cb === cb || !cb);\n })\n );\n };\n var _fire = function fire(event, args, sync) {\n listeners\n .filter(function(listener) {\n return listener.event === event;\n })\n .map(function(listener) {\n return listener.cb;\n })\n .forEach(function(cb) {\n return run(function() {\n return cb.apply(void 0, _toConsumableArray(args));\n }, sync);\n });\n };\n return {\n fireSync: function fireSync(event) {\n for (\n var _len = arguments.length,\n args = new Array(_len \u003E 1 ? _len - 1 : 0),\n _key = 1;\n _key \u003C _len;\n _key++\n ) {\n args[_key - 1] = arguments[_key];\n }\n _fire(event, args, true);\n },\n fire: function fire(event) {\n for (\n var _len2 = arguments.length,\n args = new Array(_len2 \u003E 1 ? _len2 - 1 : 0),\n _key2 = 1;\n _key2 \u003C _len2;\n _key2++\n ) {\n args[_key2 - 1] = arguments[_key2];\n }\n _fire(event, args, false);\n },\n on: function on(event, cb) {\n listeners.push({ event: event, cb: cb });\n },\n onOnce: function onOnce(event, _cb) {\n listeners.push({\n event: event,\n cb: function cb() {\n off(event, _cb);\n _cb.apply(void 0, arguments);\n },\n });\n },\n off: off,\n };\n };\n\n var copyObjectPropertiesToObject = function copyObjectPropertiesToObject(\n src,\n target,\n excluded\n ) {\n Object.getOwnPropertyNames(src)\n .filter(function(property) {\n return !excluded.includes(property);\n })\n .forEach(function(key) {\n return Object.defineProperty(\n target,\n key,\n Object.getOwnPropertyDescriptor(src, key)\n );\n });\n };\n\n var PRIVATE = [\n 'fire',\n 'process',\n 'revert',\n 'load',\n 'on',\n 'off',\n 'onOnce',\n 'retryLoad',\n 'extend',\n 'archive',\n 'archived',\n 'release',\n 'released',\n 'requestProcessing',\n 'freeze',\n ];\n\n var createItemAPI = function createItemAPI(item) {\n var api = {};\n copyObjectPropertiesToObject(item, api, PRIVATE);\n return api;\n };\n\n var removeReleasedItems = function removeReleasedItems(items) {\n items.forEach(function(item, index) {\n if (item.released) {\n arrayRemove(items, index);\n }\n });\n };\n\n var ItemStatus = {\n INIT: 1,\n IDLE: 2,\n PROCESSING_QUEUED: 9,\n PROCESSING: 3,\n PROCESSING_COMPLETE: 5,\n PROCESSING_ERROR: 6,\n PROCESSING_REVERT_ERROR: 10,\n LOADING: 7,\n LOAD_ERROR: 8,\n };\n\n var FileOrigin = {\n INPUT: 1,\n LIMBO: 2,\n LOCAL: 3,\n };\n\n var getNonNumeric = function getNonNumeric(str) {\n return \u002F[^0-9]+\u002F.exec(str);\n };\n\n var getDecimalSeparator = function getDecimalSeparator() {\n return getNonNumeric((1.1).toLocaleString())[0];\n };\n\n var getThousandsSeparator = function getThousandsSeparator() {\n \u002F\u002F Added for browsers that do not return the thousands separator (happend on native browser Android 4.4.4)\n \u002F\u002F We check against the normal toString output and if they're the same return a comma when decimal separator is a dot\n var decimalSeparator = getDecimalSeparator();\n var thousandsStringWithSeparator = (1000.0).toLocaleString();\n var thousandsStringWithoutSeparator = (1000.0).toString();\n if (thousandsStringWithSeparator !== thousandsStringWithoutSeparator) {\n return getNonNumeric(thousandsStringWithSeparator)[0];\n }\n return decimalSeparator === '.' ? ',' : '.';\n };\n\n var Type = {\n BOOLEAN: 'boolean',\n INT: 'int',\n NUMBER: 'number',\n STRING: 'string',\n ARRAY: 'array',\n OBJECT: 'object',\n FUNCTION: 'function',\n ACTION: 'action',\n SERVER_API: 'serverapi',\n REGEX: 'regex',\n };\n\n \u002F\u002F all registered filters\n var filters = [];\n\n \u002F\u002F loops over matching filters and passes options to each filter, returning the mapped results\n var applyFilterChain = function applyFilterChain(key, value, utils) {\n return new Promise(function(resolve, reject) {\n \u002F\u002F find matching filters for this key\n var matchingFilters = filters\n .filter(function(f) {\n return f.key === key;\n })\n .map(function(f) {\n return f.cb;\n });\n\n \u002F\u002F resolve now\n if (matchingFilters.length === 0) {\n resolve(value);\n return;\n }\n\n \u002F\u002F first filter to kick things of\n var initialFilter = matchingFilters.shift();\n\n \u002F\u002F chain filters\n matchingFilters\n .reduce(\n \u002F\u002F loop over promises passing value to next promise\n function(current, next) {\n return current.then(function(value) {\n return next(value, utils);\n });\n },\n\n \u002F\u002F call initial filter, will return a promise\n initialFilter(value, utils)\n\n \u002F\u002F all executed\n )\n .then(function(value) {\n return resolve(value);\n })\n .catch(function(error) {\n return reject(error);\n });\n });\n };\n\n var applyFilters = function applyFilters(key, value, utils) {\n return filters\n .filter(function(f) {\n return f.key === key;\n })\n .map(function(f) {\n return f.cb(value, utils);\n });\n };\n\n \u002F\u002F adds a new filter to the list\n var addFilter = function addFilter(key, cb) {\n return filters.push({ key: key, cb: cb });\n };\n\n var extendDefaultOptions = function extendDefaultOptions(additionalOptions) {\n return Object.assign(defaultOptions, additionalOptions);\n };\n\n var getOptions = function getOptions() {\n return Object.assign({}, defaultOptions);\n };\n\n var setOptions = function setOptions(opts) {\n forin(opts, function(key, value) {\n \u002F\u002F key does not exist, so this option cannot be set\n if (!defaultOptions[key]) {\n return;\n }\n defaultOptions[key][0] = getValueByType(\n value,\n defaultOptions[key][0],\n defaultOptions[key][1]\n );\n });\n };\n\n \u002F\u002F default options on app\n var defaultOptions = {\n \u002F\u002F the id to add to the root element\n id: [null, Type.STRING],\n\n \u002F\u002F input field name to use\n name: ['filepond', Type.STRING],\n\n \u002F\u002F disable the field\n disabled: [false, Type.BOOLEAN],\n\n \u002F\u002F classname to put on wrapper\n className: [null, Type.STRING],\n\n \u002F\u002F is the field required\n required: [false, Type.BOOLEAN],\n\n \u002F\u002F Allow media capture when value is set\n captureMethod: [null, Type.STRING],\n \u002F\u002F - \"camera\", \"microphone\" or \"camcorder\",\n \u002F\u002F - Does not work with multiple on apple devices\n \u002F\u002F - If set, acceptedFileTypes must be made to match with media wildcard \"image\u002F*\", \"audio\u002F*\" or \"video\u002F*\"\n\n \u002F\u002F sync `acceptedFileTypes` property with `accept` attribute\n allowSyncAcceptAttribute: [true, Type.BOOLEAN],\n\n \u002F\u002F Feature toggles\n allowDrop: [true, Type.BOOLEAN], \u002F\u002F Allow dropping of files\n allowBrowse: [true, Type.BOOLEAN], \u002F\u002F Allow browsing the file system\n allowPaste: [true, Type.BOOLEAN], \u002F\u002F Allow pasting files\n allowMultiple: [false, Type.BOOLEAN], \u002F\u002F Allow multiple files (disabled by default, as multiple attribute is also required on input to allow multiple)\n allowReplace: [true, Type.BOOLEAN], \u002F\u002F Allow dropping a file on other file to replace it (only works when multiple is set to false)\n allowRevert: [true, Type.BOOLEAN], \u002F\u002F Allows user to revert file upload\n allowRemove: [true, Type.BOOLEAN], \u002F\u002F Allow user to remove a file\n allowProcess: [true, Type.BOOLEAN], \u002F\u002F Allows user to process a file, when set to false, this removes the file upload button\n allowReorder: [false, Type.BOOLEAN], \u002F\u002F Allow reordering of files\n allowDirectoriesOnly: [false, Type.BOOLEAN], \u002F\u002F Allow only selecting directories with browse (no support for filtering dnd at this point)\n\n \u002F\u002F Try store file if `server` not set\n storeAsFile: [false, Type.BOOLEAN],\n\n \u002F\u002F Revert mode\n forceRevert: [false, Type.BOOLEAN], \u002F\u002F Set to 'force' to require the file to be reverted before removal\n\n \u002F\u002F Input requirements\n maxFiles: [null, Type.INT], \u002F\u002F Max number of files\n checkValidity: [false, Type.BOOLEAN], \u002F\u002F Enables custom validity messages\n\n \u002F\u002F Where to put file\n itemInsertLocationFreedom: [true, Type.BOOLEAN], \u002F\u002F Set to false to always add items to begin or end of list\n itemInsertLocation: ['before', Type.STRING], \u002F\u002F Default index in list to add items that have been dropped at the top of the list\n itemInsertInterval: [75, Type.INT],\n\n \u002F\u002F Drag 'n Drop related\n dropOnPage: [false, Type.BOOLEAN], \u002F\u002F Allow dropping of files anywhere on page (prevents browser from opening file if dropped outside of Up)\n dropOnElement: [true, Type.BOOLEAN], \u002F\u002F Drop needs to happen on element (set to false to also load drops outside of Up)\n dropValidation: [false, Type.BOOLEAN], \u002F\u002F Enable or disable validating files on drop\n ignoredFiles: [['.ds_store', 'thumbs.db', 'desktop.ini'], Type.ARRAY],\n\n \u002F\u002F Upload related\n instantUpload: [true, Type.BOOLEAN], \u002F\u002F Should upload files immediately on drop\n maxParallelUploads: [2, Type.INT], \u002F\u002F Maximum files to upload in parallel\n allowMinimumUploadDuration: [true, Type.BOOLEAN], \u002F\u002F if true uploads take at least 750 ms, this ensures the user sees the upload progress giving trust the upload actually happened\n\n \u002F\u002F Chunks\n chunkUploads: [false, Type.BOOLEAN], \u002F\u002F Enable chunked uploads\n chunkForce: [false, Type.BOOLEAN], \u002F\u002F Force use of chunk uploads even for files smaller than chunk size\n chunkSize: [5000000, Type.INT], \u002F\u002F Size of chunks (5MB default)\n chunkRetryDelays: [[500, 1000, 3000], Type.ARRAY], \u002F\u002F Amount of times to retry upload of a chunk when it fails\n\n \u002F\u002F The server api end points to use for uploading (see docs)\n server: [null, Type.SERVER_API],\n\n \u002F\u002F File size calculations, can set to 1024, this is only used for display, properties use file size base 1000\n fileSizeBase: [1000, Type.INT],\n\n \u002F\u002F Labels and status messages\n labelDecimalSeparator: [getDecimalSeparator(), Type.STRING], \u002F\u002F Default is locale separator\n labelThousandsSeparator: [getThousandsSeparator(), Type.STRING], \u002F\u002F Default is locale separator\n\n labelIdle: [\n 'Drag & Drop your files or \u003Cspan class=\"filepond--label-action\"\u003EBrowse\u003C\u002Fspan\u003E',\n Type.STRING,\n ],\n\n labelInvalidField: ['Field contains invalid files', Type.STRING],\n labelFileWaitingForSize: ['Waiting for size', Type.STRING],\n labelFileSizeNotAvailable: ['Size not available', Type.STRING],\n labelFileCountSingular: ['file in list', Type.STRING],\n labelFileCountPlural: ['files in list', Type.STRING],\n labelFileLoading: ['Loading', Type.STRING],\n labelFileAdded: ['Added', Type.STRING], \u002F\u002F assistive only\n labelFileLoadError: ['Error during load', Type.STRING],\n labelFileRemoved: ['Removed', Type.STRING], \u002F\u002F assistive only\n labelFileRemoveError: ['Error during remove', Type.STRING],\n labelFileProcessing: ['Uploading', Type.STRING],\n labelFileProcessingComplete: ['Upload complete', Type.STRING],\n labelFileProcessingAborted: ['Upload cancelled', Type.STRING],\n labelFileProcessingError: ['Error during upload', Type.STRING],\n labelFileProcessingRevertError: ['Error during revert', Type.STRING],\n\n labelTapToCancel: ['tap to cancel', Type.STRING],\n labelTapToRetry: ['tap to retry', Type.STRING],\n labelTapToUndo: ['tap to undo', Type.STRING],\n\n labelButtonRemoveItem: ['Remove', Type.STRING],\n labelButtonAbortItemLoad: ['Abort', Type.STRING],\n labelButtonRetryItemLoad: ['Retry', Type.STRING],\n labelButtonAbortItemProcessing: ['Cancel', Type.STRING],\n labelButtonUndoItemProcessing: ['Undo', Type.STRING],\n labelButtonRetryItemProcessing: ['Retry', Type.STRING],\n labelButtonProcessItem: ['Upload', Type.STRING],\n\n \u002F\u002F make sure width and height plus viewpox are even numbers so icons are nicely centered\n iconRemove: [\n '\u003Csvg width=\"26\" height=\"26\" viewBox=\"0 0 26 26\" xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\"\u003E\u003Cpath d=\"M11.586 13l-2.293 2.293a1 1 0 0 0 1.414 1.414L13 14.414l2.293 2.293a1 1 0 0 0 1.414-1.414L14.414 13l2.293-2.293a1 1 0 0 0-1.414-1.414L13 11.586l-2.293-2.293a1 1 0 0 0-1.414 1.414L11.586 13z\" fill=\"currentColor\" fill-rule=\"nonzero\"\u002F\u003E\u003C\u002Fsvg\u003E',\n Type.STRING,\n ],\n\n iconProcess: [\n '\u003Csvg width=\"26\" height=\"26\" viewBox=\"0 0 26 26\" xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\"\u003E\u003Cpath d=\"M14 10.414v3.585a1 1 0 0 1-2 0v-3.585l-1.293 1.293a1 1 0 0 1-1.414-1.415l3-3a1 1 0 0 1 1.414 0l3 3a1 1 0 0 1-1.414 1.415L14 10.414zM9 18a1 1 0 0 1 0-2h8a1 1 0 0 1 0 2H9z\" fill=\"currentColor\" fill-rule=\"evenodd\"\u002F\u003E\u003C\u002Fsvg\u003E',\n Type.STRING,\n ],\n\n iconRetry: [\n '\u003Csvg width=\"26\" height=\"26\" viewBox=\"0 0 26 26\" xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\"\u003E\u003Cpath d=\"M10.81 9.185l-.038.02A4.997 4.997 0 0 0 8 13.683a5 5 0 0 0 5 5 5 5 0 0 0 5-5 1 1 0 0 1 2 0A7 7 0 1 1 9.722 7.496l-.842-.21a.999.999 0 1 1 .484-1.94l3.23.806c.535.133.86.675.73 1.21l-.804 3.233a.997.997 0 0 1-1.21.73.997.997 0 0 1-.73-1.21l.23-.928v-.002z\" fill=\"currentColor\" fill-rule=\"nonzero\"\u002F\u003E\u003C\u002Fsvg\u003E',\n Type.STRING,\n ],\n\n iconUndo: [\n '\u003Csvg width=\"26\" height=\"26\" viewBox=\"0 0 26 26\" xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\"\u003E\u003Cpath d=\"M9.185 10.81l.02-.038A4.997 4.997 0 0 1 13.683 8a5 5 0 0 1 5 5 5 5 0 0 1-5 5 1 1 0 0 0 0 2A7 7 0 1 0 7.496 9.722l-.21-.842a.999.999 0 1 0-1.94.484l.806 3.23c.133.535.675.86 1.21.73l3.233-.803a.997.997 0 0 0 .73-1.21.997.997 0 0 0-1.21-.73l-.928.23-.002-.001z\" fill=\"currentColor\" fill-rule=\"nonzero\"\u002F\u003E\u003C\u002Fsvg\u003E',\n Type.STRING,\n ],\n\n iconDone: [\n '\u003Csvg width=\"26\" height=\"26\" viewBox=\"0 0 26 26\" xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\"\u003E\u003Cpath d=\"M18.293 9.293a1 1 0 0 1 1.414 1.414l-7.002 7a1 1 0 0 1-1.414 0l-3.998-4a1 1 0 1 1 1.414-1.414L12 15.586l6.294-6.293z\" fill=\"currentColor\" fill-rule=\"nonzero\"\u002F\u003E\u003C\u002Fsvg\u003E',\n Type.STRING,\n ],\n\n \u002F\u002F event handlers\n oninit: [null, Type.FUNCTION],\n onwarning: [null, Type.FUNCTION],\n onerror: [null, Type.FUNCTION],\n onactivatefile: [null, Type.FUNCTION],\n oninitfile: [null, Type.FUNCTION],\n onaddfilestart: [null, Type.FUNCTION],\n onaddfileprogress: [null, Type.FUNCTION],\n onaddfile: [null, Type.FUNCTION],\n onprocessfilestart: [null, Type.FUNCTION],\n onprocessfileprogress: [null, Type.FUNCTION],\n onprocessfileabort: [null, Type.FUNCTION],\n onprocessfilerevert: [null, Type.FUNCTION],\n onprocessfile: [null, Type.FUNCTION],\n onprocessfiles: [null, Type.FUNCTION],\n onremovefile: [null, Type.FUNCTION],\n onpreparefile: [null, Type.FUNCTION],\n onupdatefiles: [null, Type.FUNCTION],\n onreorderfiles: [null, Type.FUNCTION],\n\n \u002F\u002F hooks\n beforeDropFile: [null, Type.FUNCTION],\n beforeAddFile: [null, Type.FUNCTION],\n beforeRemoveFile: [null, Type.FUNCTION],\n beforePrepareFile: [null, Type.FUNCTION],\n\n \u002F\u002F styles\n stylePanelLayout: [null, Type.STRING], \u002F\u002F null 'integrated', 'compact', 'circle'\n stylePanelAspectRatio: [null, Type.STRING], \u002F\u002F null or '3:2' or 1\n styleItemPanelAspectRatio: [null, Type.STRING],\n styleButtonRemoveItemPosition: ['left', Type.STRING],\n styleButtonProcessItemPosition: ['right', Type.STRING],\n styleLoadIndicatorPosition: ['right', Type.STRING],\n styleProgressIndicatorPosition: ['right', Type.STRING],\n styleButtonRemoveItemAlign: [false, Type.BOOLEAN],\n\n \u002F\u002F custom initial files array\n files: [[], Type.ARRAY],\n\n \u002F\u002F show support by displaying credits\n credits: [['https:\u002F\u002Fpqina.nl\u002F', 'Powered by PQINA'], Type.ARRAY],\n };\n\n var getItemByQuery = function getItemByQuery(items, query) {\n \u002F\u002F just return first index\n if (isEmpty(query)) {\n return items[0] || null;\n }\n\n \u002F\u002F query is index\n if (isInt(query)) {\n return items[query] || null;\n }\n\n \u002F\u002F if query is item, get the id\n if (typeof query === 'object') {\n query = query.id;\n }\n\n \u002F\u002F assume query is a string and return item by id\n return (\n items.find(function(item) {\n return item.id === query;\n }) || null\n );\n };\n\n var getNumericAspectRatioFromString = function getNumericAspectRatioFromString(aspectRatio) {\n if (isEmpty(aspectRatio)) {\n return aspectRatio;\n }\n if (\u002F:\u002F.test(aspectRatio)) {\n var parts = aspectRatio.split(':');\n return parts[1] \u002F parts[0];\n }\n return parseFloat(aspectRatio);\n };\n\n var getActiveItems = function getActiveItems(items) {\n return items.filter(function(item) {\n return !item.archived;\n });\n };\n\n var Status = {\n EMPTY: 0,\n IDLE: 1, \u002F\u002F waiting\n ERROR: 2, \u002F\u002F a file is in error state\n BUSY: 3, \u002F\u002F busy processing or loading\n READY: 4, \u002F\u002F all files uploaded\n };\n\n var res = null;\n var canUpdateFileInput = function canUpdateFileInput() {\n if (res === null) {\n try {\n var dataTransfer = new DataTransfer();\n dataTransfer.items.add(new File(['hello world'], 'This_Works.txt'));\n var el = document.createElement('input');\n el.setAttribute('type', 'file');\n el.files = dataTransfer.files;\n res = el.files.length === 1;\n } catch (err) {\n res = false;\n }\n }\n return res;\n };\n\n var ITEM_ERROR = [\n ItemStatus.LOAD_ERROR,\n ItemStatus.PROCESSING_ERROR,\n ItemStatus.PROCESSING_REVERT_ERROR,\n ];\n\n var ITEM_BUSY = [\n ItemStatus.LOADING,\n ItemStatus.PROCESSING,\n ItemStatus.PROCESSING_QUEUED,\n ItemStatus.INIT,\n ];\n\n var ITEM_READY = [ItemStatus.PROCESSING_COMPLETE];\n\n var isItemInErrorState = function isItemInErrorState(item) {\n return ITEM_ERROR.includes(item.status);\n };\n var isItemInBusyState = function isItemInBusyState(item) {\n return ITEM_BUSY.includes(item.status);\n };\n var isItemInReadyState = function isItemInReadyState(item) {\n return ITEM_READY.includes(item.status);\n };\n\n var isAsync = function isAsync(state) {\n return (\n isObject(state.options.server) &&\n (isObject(state.options.server.process) || isFunction(state.options.server.process))\n );\n };\n\n var queries = function queries(state) {\n return {\n GET_STATUS: function GET_STATUS() {\n var items = getActiveItems(state.items);\n var EMPTY = Status.EMPTY,\n ERROR = Status.ERROR,\n BUSY = Status.BUSY,\n IDLE = Status.IDLE,\n READY = Status.READY;\n\n if (items.length === 0) return EMPTY;\n\n if (items.some(isItemInErrorState)) return ERROR;\n\n if (items.some(isItemInBusyState)) return BUSY;\n\n if (items.some(isItemInReadyState)) return READY;\n\n return IDLE;\n },\n\n GET_ITEM: function GET_ITEM(query) {\n return getItemByQuery(state.items, query);\n },\n\n GET_ACTIVE_ITEM: function GET_ACTIVE_ITEM(query) {\n return getItemByQuery(getActiveItems(state.items), query);\n },\n\n GET_ACTIVE_ITEMS: function GET_ACTIVE_ITEMS() {\n return getActiveItems(state.items);\n },\n\n GET_ITEMS: function GET_ITEMS() {\n return state.items;\n },\n\n GET_ITEM_NAME: function GET_ITEM_NAME(query) {\n var item = getItemByQuery(state.items, query);\n return item ? item.filename : null;\n },\n\n GET_ITEM_SIZE: function GET_ITEM_SIZE(query) {\n var item = getItemByQuery(state.items, query);\n return item ? item.fileSize : null;\n },\n\n GET_STYLES: function GET_STYLES() {\n return Object.keys(state.options)\n .filter(function(key) {\n return \u002F^style\u002F.test(key);\n })\n .map(function(option) {\n return {\n name: option,\n value: state.options[option],\n };\n });\n },\n\n GET_PANEL_ASPECT_RATIO: function GET_PANEL_ASPECT_RATIO() {\n var isShapeCircle = \u002Fcircle\u002F.test(state.options.stylePanelLayout);\n var aspectRatio = isShapeCircle\n ? 1\n : getNumericAspectRatioFromString(state.options.stylePanelAspectRatio);\n return aspectRatio;\n },\n\n GET_ITEM_PANEL_ASPECT_RATIO: function GET_ITEM_PANEL_ASPECT_RATIO() {\n return state.options.styleItemPanelAspectRatio;\n },\n\n GET_ITEMS_BY_STATUS: function GET_ITEMS_BY_STATUS(status) {\n return getActiveItems(state.items).filter(function(item) {\n return item.status === status;\n });\n },\n\n GET_TOTAL_ITEMS: function GET_TOTAL_ITEMS() {\n return getActiveItems(state.items).length;\n },\n\n SHOULD_UPDATE_FILE_INPUT: function SHOULD_UPDATE_FILE_INPUT() {\n return state.options.storeAsFile && canUpdateFileInput() && !isAsync(state);\n },\n\n IS_ASYNC: function IS_ASYNC() {\n return isAsync(state);\n },\n };\n };\n\n var hasRoomForItem = function hasRoomForItem(state) {\n var count = getActiveItems(state.items).length;\n\n \u002F\u002F if cannot have multiple items, to add one item it should currently not contain items\n if (!state.options.allowMultiple) {\n return count === 0;\n }\n\n \u002F\u002F if allows multiple items, we check if a max item count has been set, if not, there's no limit\n var maxFileCount = state.options.maxFiles;\n if (maxFileCount === null) {\n return true;\n }\n\n \u002F\u002F we check if the current count is smaller than the max count, if so, another file can still be added\n if (count \u003C maxFileCount) {\n return true;\n }\n\n \u002F\u002F no more room for another file\n return false;\n };\n\n var limit = function limit(value, min, max) {\n return Math.max(Math.min(max, value), min);\n };\n\n var arrayInsert = function arrayInsert(arr, index, item) {\n return arr.splice(index, 0, item);\n };\n\n var insertItem = function insertItem(items, item, index) {\n if (isEmpty(item)) {\n return null;\n }\n\n \u002F\u002F if index is undefined, append\n if (typeof index === 'undefined') {\n items.push(item);\n return item;\n }\n\n \u002F\u002F limit the index to the size of the items array\n index = limit(index, 0, items.length);\n\n \u002F\u002F add item to array\n arrayInsert(items, index, item);\n\n \u002F\u002F expose\n return item;\n };\n\n var isBase64DataURI = function isBase64DataURI(str) {\n return \u002F^\\s*data:([a-z]+\\\u002F[a-z0-9-+.]+(;[a-z-]+=[a-z0-9-]+)?)?(;base64)?,([a-z0-9!',()*+;=\\-._~:@\\\u002F?%\\s]*)\\s*$\u002Fi.test(\n str\n );\n };\n\n var getFilenameFromURL = function getFilenameFromURL(url) {\n return url\n .split('\u002F')\n .pop()\n .split('?')\n .shift();\n };\n\n var getExtensionFromFilename = function getExtensionFromFilename(name) {\n return name.split('.').pop();\n };\n\n var guesstimateExtension = function guesstimateExtension(type) {\n \u002F\u002F if no extension supplied, exit here\n if (typeof type !== 'string') {\n return '';\n }\n\n \u002F\u002F get subtype\n var subtype = type.split('\u002F').pop();\n\n \u002F\u002F is svg subtype\n if (\u002Fsvg\u002F.test(subtype)) {\n return 'svg';\n }\n\n if (\u002Fzip|compressed\u002F.test(subtype)) {\n return 'zip';\n }\n\n if (\u002Fplain\u002F.test(subtype)) {\n return 'txt';\n }\n\n if (\u002Fmsword\u002F.test(subtype)) {\n return 'doc';\n }\n\n \u002F\u002F if is valid subtype\n if (\u002F[a-z]+\u002F.test(subtype)) {\n \u002F\u002F always use jpg extension\n if (subtype === 'jpeg') {\n return 'jpg';\n }\n\n \u002F\u002F return subtype\n return subtype;\n }\n\n return '';\n };\n\n var leftPad = function leftPad(value) {\n var padding = arguments.length \u003E 1 && arguments[1] !== undefined ? arguments[1] : '';\n return (padding + value).slice(-padding.length);\n };\n\n var getDateString = function getDateString() {\n var date = arguments.length \u003E 0 && arguments[0] !== undefined ? arguments[0] : new Date();\n return (\n date.getFullYear() +\n '-' +\n leftPad(date.getMonth() + 1, '00') +\n '-' +\n leftPad(date.getDate(), '00') +\n '_' +\n leftPad(date.getHours(), '00') +\n '-' +\n leftPad(date.getMinutes(), '00') +\n '-' +\n leftPad(date.getSeconds(), '00')\n );\n };\n\n var getFileFromBlob = function getFileFromBlob(blob, filename) {\n var type = arguments.length \u003E 2 && arguments[2] !== undefined ? arguments[2] : null;\n var extension = arguments.length \u003E 3 && arguments[3] !== undefined ? arguments[3] : null;\n var file =\n typeof type === 'string'\n ? blob.slice(0, blob.size, type)\n : blob.slice(0, blob.size, blob.type);\n file.lastModifiedDate = new Date();\n\n \u002F\u002F copy relative path\n if (blob._relativePath) file._relativePath = blob._relativePath;\n\n \u002F\u002F if blob has name property, use as filename if no filename supplied\n if (!isString(filename)) {\n filename = getDateString();\n }\n\n \u002F\u002F if filename supplied but no extension and filename has extension\n if (filename && extension === null && getExtensionFromFilename(filename)) {\n file.name = filename;\n } else {\n extension = extension || guesstimateExtension(file.type);\n file.name = filename + (extension ? '.' + extension : '');\n }\n\n return file;\n };\n\n var getBlobBuilder = function getBlobBuilder() {\n return (window.BlobBuilder =\n window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder);\n };\n\n var createBlob = function createBlob(arrayBuffer, mimeType) {\n var BB = getBlobBuilder();\n\n if (BB) {\n var bb = new BB();\n bb.append(arrayBuffer);\n return bb.getBlob(mimeType);\n }\n\n return new Blob([arrayBuffer], {\n type: mimeType,\n });\n };\n\n var getBlobFromByteStringWithMimeType = function getBlobFromByteStringWithMimeType(\n byteString,\n mimeType\n ) {\n var ab = new ArrayBuffer(byteString.length);\n var ia = new Uint8Array(ab);\n\n for (var i = 0; i \u003C byteString.length; i++) {\n ia[i] = byteString.charCodeAt(i);\n }\n\n return createBlob(ab, mimeType);\n };\n\n var getMimeTypeFromBase64DataURI = function getMimeTypeFromBase64DataURI(dataURI) {\n return (\u002F^data:(.+);\u002F.exec(dataURI) || [])[1] || null;\n };\n\n var getBase64DataFromBase64DataURI = function getBase64DataFromBase64DataURI(dataURI) {\n \u002F\u002F get data part of string (remove data:image\u002Fjpeg...,)\n var data = dataURI.split(',')[1];\n\n \u002F\u002F remove any whitespace as that causes InvalidCharacterError in IE\n return data.replace(\u002F\\s\u002Fg, '');\n };\n\n var getByteStringFromBase64DataURI = function getByteStringFromBase64DataURI(dataURI) {\n return atob(getBase64DataFromBase64DataURI(dataURI));\n };\n\n var getBlobFromBase64DataURI = function getBlobFromBase64DataURI(dataURI) {\n var mimeType = getMimeTypeFromBase64DataURI(dataURI);\n var byteString = getByteStringFromBase64DataURI(dataURI);\n\n return getBlobFromByteStringWithMimeType(byteString, mimeType);\n };\n\n var getFileFromBase64DataURI = function getFileFromBase64DataURI(dataURI, filename, extension) {\n return getFileFromBlob(getBlobFromBase64DataURI(dataURI), filename, null, extension);\n };\n\n var getFileNameFromHeader = function getFileNameFromHeader(header) {\n \u002F\u002F test if is content disposition header, if not exit\n if (!\u002F^content-disposition:\u002Fi.test(header)) return null;\n\n \u002F\u002F get filename parts\n var matches = header\n .split(\u002Ffilename=|filename\\*=.+''\u002F)\n .splice(1)\n .map(function(name) {\n return name.trim().replace(\u002F^[\"']|[;\"']{0,2}$\u002Fg, '');\n })\n .filter(function(name) {\n return name.length;\n });\n\n return matches.length ? decodeURI(matches[matches.length - 1]) : null;\n };\n\n var getFileSizeFromHeader = function getFileSizeFromHeader(header) {\n if (\u002Fcontent-length:\u002Fi.test(header)) {\n var size = header.match(\u002F[0-9]+\u002F)[0];\n return size ? parseInt(size, 10) : null;\n }\n return null;\n };\n\n var getTranfserIdFromHeader = function getTranfserIdFromHeader(header) {\n if (\u002Fx-content-transfer-id:\u002Fi.test(header)) {\n var id = (header.split(':')[1] || '').trim();\n return id || null;\n }\n return null;\n };\n\n var getFileInfoFromHeaders = function getFileInfoFromHeaders(headers) {\n var info = {\n source: null,\n name: null,\n size: null,\n };\n\n var rows = headers.split('\\n');\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n try {\n for (\n var _iterator = rows[Symbol.iterator](), _step;\n !(_iteratorNormalCompletion = (_step = _iterator.next()).done);\n _iteratorNormalCompletion = true\n ) {\n var header = _step.value;\n\n var name = getFileNameFromHeader(header);\n if (name) {\n info.name = name;\n continue;\n }\n\n var size = getFileSizeFromHeader(header);\n if (size) {\n info.size = size;\n continue;\n }\n\n var source = getTranfserIdFromHeader(header);\n if (source) {\n info.source = source;\n continue;\n }\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return != null) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n return info;\n };\n\n var createFileLoader = function createFileLoader(fetchFn) {\n var state = {\n source: null,\n complete: false,\n progress: 0,\n size: null,\n timestamp: null,\n duration: 0,\n request: null,\n };\n\n var getProgress = function getProgress() {\n return state.progress;\n };\n var abort = function abort() {\n if (state.request && state.request.abort) {\n state.request.abort();\n }\n };\n\n \u002F\u002F load source\n var load = function load() {\n \u002F\u002F get quick reference\n var source = state.source;\n\n api.fire('init', source);\n\n \u002F\u002F Load Files\n if (source instanceof File) {\n api.fire('load', source);\n } else if (source instanceof Blob) {\n \u002F\u002F Load blobs, set default name to current date\n api.fire('load', getFileFromBlob(source, source.name));\n } else if (isBase64DataURI(source)) {\n \u002F\u002F Load base 64, set default name to current date\n api.fire('load', getFileFromBase64DataURI(source));\n } else {\n \u002F\u002F Deal as if is external URL, let's load it!\n loadURL(source);\n }\n };\n\n \u002F\u002F loads a url\n var loadURL = function loadURL(url) {\n \u002F\u002F is remote url and no fetch method supplied\n if (!fetchFn) {\n api.fire('error', {\n type: 'error',\n body: \"Can't load URL\",\n code: 400,\n });\n\n return;\n }\n\n \u002F\u002F set request start\n state.timestamp = Date.now();\n\n \u002F\u002F load file\n state.request = fetchFn(\n url,\n function(response) {\n \u002F\u002F update duration\n state.duration = Date.now() - state.timestamp;\n\n \u002F\u002F done!\n state.complete = true;\n\n \u002F\u002F turn blob response into a file\n if (response instanceof Blob) {\n response = getFileFromBlob(\n response,\n response.name || getFilenameFromURL(url)\n );\n }\n\n api.fire(\n 'load',\n \u002F\u002F if has received blob, we go with blob, if no response, we return null\n response instanceof Blob ? response : response ? response.body : null\n );\n },\n function(error) {\n api.fire(\n 'error',\n typeof error === 'string'\n ? {\n type: 'error',\n code: 0,\n body: error,\n }\n : error\n );\n },\n function(computable, current, total) {\n \u002F\u002F collected some meta data already\n if (total) {\n state.size = total;\n }\n\n \u002F\u002F update duration\n state.duration = Date.now() - state.timestamp;\n\n \u002F\u002F if we can't compute progress, we're not going to fire progress events\n if (!computable) {\n state.progress = null;\n return;\n }\n\n \u002F\u002F update progress percentage\n state.progress = current \u002F total;\n\n \u002F\u002F expose\n api.fire('progress', state.progress);\n },\n function() {\n api.fire('abort');\n },\n function(response) {\n var fileinfo = getFileInfoFromHeaders(\n typeof response === 'string' ? response : response.headers\n );\n api.fire('meta', {\n size: state.size || fileinfo.size,\n filename: fileinfo.name,\n source: fileinfo.source,\n });\n }\n );\n };\n\n var api = Object.assign({}, on(), {\n setSource: function setSource(source) {\n return (state.source = source);\n },\n getProgress: getProgress, \u002F\u002F file load progress\n abort: abort, \u002F\u002F abort file load\n load: load, \u002F\u002F start load\n });\n\n return api;\n };\n\n var isGet = function isGet(method) {\n return \u002FGET|HEAD\u002F.test(method);\n };\n\n var sendRequest = function sendRequest(data, url, options) {\n var api = {\n onheaders: function onheaders() {},\n onprogress: function onprogress() {},\n onload: function onload() {},\n ontimeout: function ontimeout() {},\n onerror: function onerror() {},\n onabort: function onabort() {},\n abort: function abort() {\n aborted = true;\n xhr.abort();\n },\n };\n\n \u002F\u002F timeout identifier, only used when timeout is defined\n var aborted = false;\n var headersReceived = false;\n\n \u002F\u002F set default options\n options = Object.assign(\n {\n method: 'POST',\n headers: {},\n withCredentials: false,\n },\n options\n );\n\n \u002F\u002F encode url\n url = encodeURI(url);\n\n \u002F\u002F if method is GET, add any received data to url\n\n if (isGet(options.method) && data) {\n url =\n '' +\n url +\n encodeURIComponent(typeof data === 'string' ? data : JSON.stringify(data));\n }\n\n \u002F\u002F create request\n var xhr = new XMLHttpRequest();\n\n \u002F\u002F progress of load\n var process = isGet(options.method) ? xhr : xhr.upload;\n process.onprogress = function(e) {\n \u002F\u002F no progress event when aborted ( onprogress is called once after abort() )\n if (aborted) {\n return;\n }\n\n api.onprogress(e.lengthComputable, e.loaded, e.total);\n };\n\n \u002F\u002F tries to get header info to the app as fast as possible\n xhr.onreadystatechange = function() {\n \u002F\u002F not interesting in these states ('unsent' and 'openend' as they don't give us any additional info)\n if (xhr.readyState \u003C 2) {\n return;\n }\n\n \u002F\u002F no server response\n if (xhr.readyState === 4 && xhr.status === 0) {\n return;\n }\n\n if (headersReceived) {\n return;\n }\n\n headersReceived = true;\n\n \u002F\u002F we've probably received some useful data in response headers\n api.onheaders(xhr);\n };\n\n \u002F\u002F load successful\n xhr.onload = function() {\n \u002F\u002F is classified as valid response\n if (xhr.status \u003E= 200 && xhr.status \u003C 300) {\n api.onload(xhr);\n } else {\n api.onerror(xhr);\n }\n };\n\n \u002F\u002F error during load\n xhr.onerror = function() {\n return api.onerror(xhr);\n };\n\n \u002F\u002F request aborted\n xhr.onabort = function() {\n aborted = true;\n api.onabort();\n };\n\n \u002F\u002F request timeout\n xhr.ontimeout = function() {\n return api.ontimeout(xhr);\n };\n\n \u002F\u002F open up open up!\n xhr.open(options.method, url, true);\n\n \u002F\u002F set timeout if defined (do it after open so IE11 plays ball)\n if (isInt(options.timeout)) {\n xhr.timeout = options.timeout;\n }\n\n \u002F\u002F add headers\n Object.keys(options.headers).forEach(function(key) {\n var value = unescape(encodeURIComponent(options.headers[key]));\n xhr.setRequestHeader(key, value);\n });\n\n \u002F\u002F set type of response\n if (options.responseType) {\n xhr.responseType = options.responseType;\n }\n\n \u002F\u002F set credentials\n if (options.withCredentials) {\n xhr.withCredentials = true;\n }\n\n \u002F\u002F let's send our data\n xhr.send(data);\n\n return api;\n };\n\n var createResponse = function createResponse(type, code, body, headers) {\n return {\n type: type,\n code: code,\n body: body,\n headers: headers,\n };\n };\n\n var createTimeoutResponse = function createTimeoutResponse(cb) {\n return function(xhr) {\n cb(createResponse('error', 0, 'Timeout', xhr.getAllResponseHeaders()));\n };\n };\n\n var hasQS = function hasQS(str) {\n return \u002F\\?\u002F.test(str);\n };\n var buildURL = function buildURL() {\n var url = '';\n for (var _len = arguments.length, parts = new Array(_len), _key = 0; _key \u003C _len; _key++) {\n parts[_key] = arguments[_key];\n }\n parts.forEach(function(part) {\n url += hasQS(url) && hasQS(part) ? part.replace(\u002F\\?\u002F, '&') : part;\n });\n return url;\n };\n\n var createFetchFunction = function createFetchFunction() {\n var apiUrl = arguments.length \u003E 0 && arguments[0] !== undefined ? arguments[0] : '';\n var action = arguments.length \u003E 1 ? arguments[1] : undefined;\n \u002F\u002F custom handler (should also handle file, load, error, progress and abort)\n if (typeof action === 'function') {\n return action;\n }\n\n \u002F\u002F no action supplied\n if (!action || !isString(action.url)) {\n return null;\n }\n\n \u002F\u002F set onload hanlder\n var onload =\n action.onload ||\n function(res) {\n return res;\n };\n var onerror =\n action.onerror ||\n function(res) {\n return null;\n };\n\n \u002F\u002F internal handler\n return function(url, load, error, progress, abort, headers) {\n \u002F\u002F do local or remote request based on if the url is external\n var request = sendRequest(\n url,\n buildURL(apiUrl, action.url),\n Object.assign({}, action, {\n responseType: 'blob',\n })\n );\n\n request.onload = function(xhr) {\n \u002F\u002F get headers\n var headers = xhr.getAllResponseHeaders();\n\n \u002F\u002F get filename\n var filename = getFileInfoFromHeaders(headers).name || getFilenameFromURL(url);\n\n \u002F\u002F create response\n load(\n createResponse(\n 'load',\n xhr.status,\n action.method === 'HEAD'\n ? null\n : getFileFromBlob(onload(xhr.response), filename),\n headers\n )\n );\n };\n\n request.onerror = function(xhr) {\n error(\n createResponse(\n 'error',\n xhr.status,\n onerror(xhr.response) || xhr.statusText,\n xhr.getAllResponseHeaders()\n )\n );\n };\n\n request.onheaders = function(xhr) {\n headers(createResponse('headers', xhr.status, null, xhr.getAllResponseHeaders()));\n };\n\n request.ontimeout = createTimeoutResponse(error);\n request.onprogress = progress;\n request.onabort = abort;\n\n \u002F\u002F should return request\n return request;\n };\n };\n\n var ChunkStatus = {\n QUEUED: 0,\n COMPLETE: 1,\n PROCESSING: 2,\n ERROR: 3,\n WAITING: 4,\n };\n\n \u002F*\n function signature:\n (file, metadata, load, error, progress, abort, transfer, options) =\u003E {\n return {\n abort:() =\u003E {}\n }\n }\n *\u002F\n\n \u002F\u002F apiUrl, action, name, file, metadata, load, error, progress, abort, transfer, options\n var processFileChunked = function processFileChunked(\n apiUrl,\n action,\n name,\n file,\n metadata,\n load,\n error,\n progress,\n abort,\n transfer,\n options\n ) {\n \u002F\u002F all chunks\n var chunks = [];\n var chunkTransferId = options.chunkTransferId,\n chunkServer = options.chunkServer,\n chunkSize = options.chunkSize,\n chunkRetryDelays = options.chunkRetryDelays;\n\n \u002F\u002F default state\n var state = {\n serverId: chunkTransferId,\n aborted: false,\n };\n\n \u002F\u002F set onload handlers\n var ondata =\n action.ondata ||\n function(fd) {\n return fd;\n };\n var onload =\n action.onload ||\n function(xhr, method) {\n return method === 'HEAD' ? xhr.getResponseHeader('Upload-Offset') : xhr.response;\n };\n var onerror =\n action.onerror ||\n function(res) {\n return null;\n };\n\n \u002F\u002F create server hook\n var requestTransferId = function requestTransferId(cb) {\n var formData = new FormData();\n\n \u002F\u002F add metadata under same name\n if (isObject(metadata)) formData.append(name, JSON.stringify(metadata));\n\n var headers =\n typeof action.headers === 'function'\n ? action.headers(file, metadata)\n : Object.assign({}, action.headers, {\n 'Upload-Length': file.size,\n });\n\n var requestParams = Object.assign({}, action, {\n headers: headers,\n });\n\n \u002F\u002F send request object\n var request = sendRequest(\n ondata(formData),\n buildURL(apiUrl, action.url),\n requestParams\n );\n\n request.onload = function(xhr) {\n return cb(onload(xhr, requestParams.method));\n };\n\n request.onerror = function(xhr) {\n return error(\n createResponse(\n 'error',\n xhr.status,\n onerror(xhr.response) || xhr.statusText,\n xhr.getAllResponseHeaders()\n )\n );\n };\n\n request.ontimeout = createTimeoutResponse(error);\n };\n\n var requestTransferOffset = function requestTransferOffset(cb) {\n var requestUrl = buildURL(apiUrl, chunkServer.url, state.serverId);\n\n var headers =\n typeof action.headers === 'function'\n ? action.headers(state.serverId)\n : Object.assign({}, action.headers);\n\n var requestParams = {\n headers: headers,\n method: 'HEAD',\n };\n\n var request = sendRequest(null, requestUrl, requestParams);\n\n request.onload = function(xhr) {\n return cb(onload(xhr, requestParams.method));\n };\n\n request.onerror = function(xhr) {\n return error(\n createResponse(\n 'error',\n xhr.status,\n onerror(xhr.response) || xhr.statusText,\n xhr.getAllResponseHeaders()\n )\n );\n };\n\n request.ontimeout = createTimeoutResponse(error);\n };\n\n \u002F\u002F create chunks\n var lastChunkIndex = Math.floor(file.size \u002F chunkSize);\n for (var i = 0; i \u003C= lastChunkIndex; i++) {\n var offset = i * chunkSize;\n var data = file.slice(offset, offset + chunkSize, 'application\u002Foffset+octet-stream');\n chunks[i] = {\n index: i,\n size: data.size,\n offset: offset,\n data: data,\n file: file,\n progress: 0,\n retries: _toConsumableArray(chunkRetryDelays),\n status: ChunkStatus.QUEUED,\n error: null,\n request: null,\n timeout: null,\n };\n }\n\n var completeProcessingChunks = function completeProcessingChunks() {\n return load(state.serverId);\n };\n\n var canProcessChunk = function canProcessChunk(chunk) {\n return chunk.status === ChunkStatus.QUEUED || chunk.status === ChunkStatus.ERROR;\n };\n\n var processChunk = function processChunk(chunk) {\n \u002F\u002F processing is paused, wait here\n if (state.aborted) return;\n\n \u002F\u002F get next chunk to process\n chunk = chunk || chunks.find(canProcessChunk);\n\n \u002F\u002F no more chunks to process\n if (!chunk) {\n \u002F\u002F all done?\n if (\n chunks.every(function(chunk) {\n return chunk.status === ChunkStatus.COMPLETE;\n })\n ) {\n completeProcessingChunks();\n }\n\n \u002F\u002F no chunk to handle\n return;\n }\n\n \u002F\u002F now processing this chunk\n chunk.status = ChunkStatus.PROCESSING;\n chunk.progress = null;\n\n \u002F\u002F allow parsing of formdata\n var ondata =\n chunkServer.ondata ||\n function(fd) {\n return fd;\n };\n var onerror =\n chunkServer.onerror ||\n function(res) {\n return null;\n };\n\n \u002F\u002F send request object\n var requestUrl = buildURL(apiUrl, chunkServer.url, state.serverId);\n\n var headers =\n typeof chunkServer.headers === 'function'\n ? chunkServer.headers(chunk)\n : Object.assign({}, chunkServer.headers, {\n 'Content-Type': 'application\u002Foffset+octet-stream',\n 'Upload-Offset': chunk.offset,\n 'Upload-Length': file.size,\n 'Upload-Name': file.name,\n });\n\n var request = (chunk.request = sendRequest(\n ondata(chunk.data),\n requestUrl,\n Object.assign({}, chunkServer, {\n headers: headers,\n })\n ));\n\n request.onload = function() {\n \u002F\u002F done!\n chunk.status = ChunkStatus.COMPLETE;\n\n \u002F\u002F remove request reference\n chunk.request = null;\n\n \u002F\u002F start processing more chunks\n processChunks();\n };\n\n request.onprogress = function(lengthComputable, loaded, total) {\n chunk.progress = lengthComputable ? loaded : null;\n updateTotalProgress();\n };\n\n request.onerror = function(xhr) {\n chunk.status = ChunkStatus.ERROR;\n chunk.request = null;\n chunk.error = onerror(xhr.response) || xhr.statusText;\n if (!retryProcessChunk(chunk)) {\n error(\n createResponse(\n 'error',\n xhr.status,\n onerror(xhr.response) || xhr.statusText,\n xhr.getAllResponseHeaders()\n )\n );\n }\n };\n\n request.ontimeout = function(xhr) {\n chunk.status = ChunkStatus.ERROR;\n chunk.request = null;\n if (!retryProcessChunk(chunk)) {\n createTimeoutResponse(error)(xhr);\n }\n };\n\n request.onabort = function() {\n chunk.status = ChunkStatus.QUEUED;\n chunk.request = null;\n abort();\n };\n };\n\n var retryProcessChunk = function retryProcessChunk(chunk) {\n \u002F\u002F no more retries left\n if (chunk.retries.length === 0) return false;\n\n \u002F\u002F new retry\n chunk.status = ChunkStatus.WAITING;\n clearTimeout(chunk.timeout);\n chunk.timeout = setTimeout(function() {\n processChunk(chunk);\n }, chunk.retries.shift());\n\n \u002F\u002F we're going to retry\n return true;\n };\n\n var updateTotalProgress = function updateTotalProgress() {\n \u002F\u002F calculate total progress fraction\n var totalBytesTransfered = chunks.reduce(function(p, chunk) {\n if (p === null || chunk.progress === null) return null;\n return p + chunk.progress;\n }, 0);\n\n \u002F\u002F can't compute progress\n if (totalBytesTransfered === null) return progress(false, 0, 0);\n\n \u002F\u002F calculate progress values\n var totalSize = chunks.reduce(function(total, chunk) {\n return total + chunk.size;\n }, 0);\n\n \u002F\u002F can update progress indicator\n progress(true, totalBytesTransfered, totalSize);\n };\n\n \u002F\u002F process new chunks\n var processChunks = function processChunks() {\n var totalProcessing = chunks.filter(function(chunk) {\n return chunk.status === ChunkStatus.PROCESSING;\n }).length;\n if (totalProcessing \u003E= 1) return;\n processChunk();\n };\n\n var abortChunks = function abortChunks() {\n chunks.forEach(function(chunk) {\n clearTimeout(chunk.timeout);\n if (chunk.request) {\n chunk.request.abort();\n }\n });\n };\n\n \u002F\u002F let's go!\n if (!state.serverId) {\n requestTransferId(function(serverId) {\n \u002F\u002F stop here if aborted, might have happened in between request and callback\n if (state.aborted) return;\n\n \u002F\u002F pass back to item so we can use it if something goes wrong\n transfer(serverId);\n\n \u002F\u002F store internally\n state.serverId = serverId;\n processChunks();\n });\n } else {\n requestTransferOffset(function(offset) {\n \u002F\u002F stop here if aborted, might have happened in between request and callback\n if (state.aborted) return;\n\n \u002F\u002F mark chunks with lower offset as complete\n chunks\n .filter(function(chunk) {\n return chunk.offset \u003C offset;\n })\n .forEach(function(chunk) {\n chunk.status = ChunkStatus.COMPLETE;\n chunk.progress = chunk.size;\n });\n\n \u002F\u002F continue processing\n processChunks();\n });\n }\n\n return {\n abort: function abort() {\n state.aborted = true;\n abortChunks();\n },\n };\n };\n\n \u002F*\n function signature:\n (file, metadata, load, error, progress, abort) =\u003E {\n return {\n abort:() =\u003E {}\n }\n }\n *\u002F\n var createFileProcessorFunction = function createFileProcessorFunction(\n apiUrl,\n action,\n name,\n options\n ) {\n return function(file, metadata, load, error, progress, abort, transfer) {\n \u002F\u002F no file received\n if (!file) return;\n\n \u002F\u002F if was passed a file, and we can chunk it, exit here\n var canChunkUpload = options.chunkUploads;\n var shouldChunkUpload = canChunkUpload && file.size \u003E options.chunkSize;\n var willChunkUpload = canChunkUpload && (shouldChunkUpload || options.chunkForce);\n if (file instanceof Blob && willChunkUpload)\n return processFileChunked(\n apiUrl,\n action,\n name,\n file,\n metadata,\n load,\n error,\n progress,\n abort,\n transfer,\n options\n );\n\n \u002F\u002F set handlers\n var ondata =\n action.ondata ||\n function(fd) {\n return fd;\n };\n var onload =\n action.onload ||\n function(res) {\n return res;\n };\n var onerror =\n action.onerror ||\n function(res) {\n return null;\n };\n\n var headers =\n typeof action.headers === 'function'\n ? action.headers(file, metadata) || {}\n : Object.assign(\n {},\n\n action.headers\n );\n\n var requestParams = Object.assign({}, action, {\n headers: headers,\n });\n\n \u002F\u002F create formdata object\n var formData = new FormData();\n\n \u002F\u002F add metadata under same name\n if (isObject(metadata)) {\n formData.append(name, JSON.stringify(metadata));\n }\n\n \u002F\u002F Turn into an array of objects so no matter what the input, we can handle it the same way\n (file instanceof Blob ? [{ name: null, file: file }] : file).forEach(function(item) {\n formData.append(\n name,\n item.file,\n item.name === null ? item.file.name : '' + item.name + item.file.name\n );\n });\n\n \u002F\u002F send request object\n var request = sendRequest(\n ondata(formData),\n buildURL(apiUrl, action.url),\n requestParams\n );\n request.onload = function(xhr) {\n load(\n createResponse(\n 'load',\n xhr.status,\n onload(xhr.response),\n xhr.getAllResponseHeaders()\n )\n );\n };\n\n request.onerror = function(xhr) {\n error(\n createResponse(\n 'error',\n xhr.status,\n onerror(xhr.response) || xhr.statusText,\n xhr.getAllResponseHeaders()\n )\n );\n };\n\n request.ontimeout = createTimeoutResponse(error);\n request.onprogress = progress;\n request.onabort = abort;\n\n \u002F\u002F should return request\n return request;\n };\n };\n\n var createProcessorFunction = function createProcessorFunction() {\n var apiUrl = arguments.length \u003E 0 && arguments[0] !== undefined ? arguments[0] : '';\n var action = arguments.length \u003E 1 ? arguments[1] : undefined;\n var name = arguments.length \u003E 2 ? arguments[2] : undefined;\n var options = arguments.length \u003E 3 ? arguments[3] : undefined;\n\n \u002F\u002F custom handler (should also handle file, load, error, progress and abort)\n if (typeof action === 'function')\n return function() {\n for (\n var _len = arguments.length, params = new Array(_len), _key = 0;\n _key \u003C _len;\n _key++\n ) {\n params[_key] = arguments[_key];\n }\n return action.apply(void 0, [name].concat(params, [options]));\n };\n\n \u002F\u002F no action supplied\n if (!action || !isString(action.url)) return null;\n\n \u002F\u002F internal handler\n return createFileProcessorFunction(apiUrl, action, name, options);\n };\n\n \u002F*\n function signature:\n (uniqueFileId, load, error) =\u003E { }\n *\u002F\n var createRevertFunction = function createRevertFunction() {\n var apiUrl = arguments.length \u003E 0 && arguments[0] !== undefined ? arguments[0] : '';\n var action = arguments.length \u003E 1 ? arguments[1] : undefined;\n \u002F\u002F is custom implementation\n if (typeof action === 'function') {\n return action;\n }\n\n \u002F\u002F no action supplied, return stub function, interface will work, but file won't be removed\n if (!action || !isString(action.url)) {\n return function(uniqueFileId, load) {\n return load();\n };\n }\n\n \u002F\u002F set onload hanlder\n var onload =\n action.onload ||\n function(res) {\n return res;\n };\n var onerror =\n action.onerror ||\n function(res) {\n return null;\n };\n\n \u002F\u002F internal implementation\n return function(uniqueFileId, load, error) {\n var request = sendRequest(\n uniqueFileId,\n apiUrl + action.url,\n action \u002F\u002F contains method, headers and withCredentials properties\n );\n request.onload = function(xhr) {\n load(\n createResponse(\n 'load',\n xhr.status,\n onload(xhr.response),\n xhr.getAllResponseHeaders()\n )\n );\n };\n\n request.onerror = function(xhr) {\n error(\n createResponse(\n 'error',\n xhr.status,\n onerror(xhr.response) || xhr.statusText,\n xhr.getAllResponseHeaders()\n )\n );\n };\n\n request.ontimeout = createTimeoutResponse(error);\n\n return request;\n };\n };\n\n var getRandomNumber = function getRandomNumber() {\n var min = arguments.length \u003E 0 && arguments[0] !== undefined ? arguments[0] : 0;\n var max = arguments.length \u003E 1 && arguments[1] !== undefined ? arguments[1] : 1;\n return min + Math.random() * (max - min);\n };\n\n var createPerceivedPerformanceUpdater = function createPerceivedPerformanceUpdater(cb) {\n var duration = arguments.length \u003E 1 && arguments[1] !== undefined ? arguments[1] : 1000;\n var offset = arguments.length \u003E 2 && arguments[2] !== undefined ? arguments[2] : 0;\n var tickMin = arguments.length \u003E 3 && arguments[3] !== undefined ? arguments[3] : 25;\n var tickMax = arguments.length \u003E 4 && arguments[4] !== undefined ? arguments[4] : 250;\n var timeout = null;\n var start = Date.now();\n\n var tick = function tick() {\n var runtime = Date.now() - start;\n var delay = getRandomNumber(tickMin, tickMax);\n\n if (runtime + delay \u003E duration) {\n delay = runtime + delay - duration;\n }\n\n var progress = runtime \u002F duration;\n if (progress \u003E= 1 || document.hidden) {\n cb(1);\n return;\n }\n\n cb(progress);\n\n timeout = setTimeout(tick, delay);\n };\n\n if (duration \u003E 0) tick();\n\n return {\n clear: function clear() {\n clearTimeout(timeout);\n },\n };\n };\n\n var createFileProcessor = function createFileProcessor(processFn, options) {\n var state = {\n complete: false,\n perceivedProgress: 0,\n perceivedPerformanceUpdater: null,\n progress: null,\n timestamp: null,\n perceivedDuration: 0,\n duration: 0,\n request: null,\n response: null,\n };\n var allowMinimumUploadDuration = options.allowMinimumUploadDuration;\n\n var process = function process(file, metadata) {\n var progressFn = function progressFn() {\n \u002F\u002F we've not yet started the real download, stop here\n \u002F\u002F the request might not go through, for instance, there might be some server trouble\n \u002F\u002F if state.progress is null, the server does not allow computing progress and we show the spinner instead\n if (state.duration === 0 || state.progress === null) return;\n\n \u002F\u002F as we're now processing, fire the progress event\n api.fire('progress', api.getProgress());\n };\n\n var completeFn = function completeFn() {\n state.complete = true;\n api.fire('load-perceived', state.response.body);\n };\n\n \u002F\u002F let's start processing\n api.fire('start');\n\n \u002F\u002F set request start\n state.timestamp = Date.now();\n\n \u002F\u002F create perceived performance progress indicator\n state.perceivedPerformanceUpdater = createPerceivedPerformanceUpdater(\n function(progress) {\n state.perceivedProgress = progress;\n state.perceivedDuration = Date.now() - state.timestamp;\n\n progressFn();\n\n \u002F\u002F if fake progress is done, and a response has been received,\n \u002F\u002F and we've not yet called the complete method\n if (state.response && state.perceivedProgress === 1 && !state.complete) {\n \u002F\u002F we done!\n completeFn();\n }\n },\n \u002F\u002F random delay as in a list of files you start noticing\n \u002F\u002F files uploading at the exact same speed\n allowMinimumUploadDuration ? getRandomNumber(750, 1500) : 0\n );\n\n \u002F\u002F remember request so we can abort it later\n state.request = processFn(\n \u002F\u002F the file to process\n file,\n\n \u002F\u002F the metadata to send along\n metadata,\n\n \u002F\u002F callbacks (load, error, progress, abort, transfer)\n \u002F\u002F load expects the body to be a server id if\n \u002F\u002F you want to make use of revert\n function(response) {\n \u002F\u002F we put the response in state so we can access\n \u002F\u002F it outside of this method\n state.response = isObject(response)\n ? response\n : {\n type: 'load',\n code: 200,\n body: '' + response,\n headers: {},\n };\n\n \u002F\u002F update duration\n state.duration = Date.now() - state.timestamp;\n\n \u002F\u002F force progress to 1 as we're now done\n state.progress = 1;\n\n \u002F\u002F actual load is done let's share results\n api.fire('load', state.response.body);\n\n \u002F\u002F we are really done\n \u002F\u002F if perceived progress is 1 ( wait for perceived progress to complete )\n \u002F\u002F or if server does not support progress ( null )\n if (\n !allowMinimumUploadDuration ||\n (allowMinimumUploadDuration && state.perceivedProgress === 1)\n ) {\n completeFn();\n }\n },\n\n \u002F\u002F error is expected to be an object with type, code, body\n function(error) {\n \u002F\u002F cancel updater\n state.perceivedPerformanceUpdater.clear();\n\n \u002F\u002F update others about this error\n api.fire(\n 'error',\n isObject(error)\n ? error\n : {\n type: 'error',\n code: 0,\n body: '' + error,\n }\n );\n },\n\n \u002F\u002F actual processing progress\n function(computable, current, total) {\n \u002F\u002F update actual duration\n state.duration = Date.now() - state.timestamp;\n\n \u002F\u002F update actual progress\n state.progress = computable ? current \u002F total : null;\n\n progressFn();\n },\n\n \u002F\u002F abort does not expect a value\n function() {\n \u002F\u002F stop updater\n state.perceivedPerformanceUpdater.clear();\n\n \u002F\u002F fire the abort event so we can switch visuals\n api.fire('abort', state.response ? state.response.body : null);\n },\n\n \u002F\u002F register the id for this transfer\n function(transferId) {\n api.fire('transfer', transferId);\n }\n );\n };\n\n var abort = function abort() {\n \u002F\u002F no request running, can't abort\n if (!state.request) return;\n\n \u002F\u002F stop updater\n state.perceivedPerformanceUpdater.clear();\n\n \u002F\u002F abort actual request\n if (state.request.abort) state.request.abort();\n\n \u002F\u002F if has response object, we've completed the request\n state.complete = true;\n };\n\n var reset = function reset() {\n abort();\n state.complete = false;\n state.perceivedProgress = 0;\n state.progress = 0;\n state.timestamp = null;\n state.perceivedDuration = 0;\n state.duration = 0;\n state.request = null;\n state.response = null;\n };\n\n var getProgress = allowMinimumUploadDuration\n ? function() {\n return state.progress ? Math.min(state.progress, state.perceivedProgress) : null;\n }\n : function() {\n return state.progress || null;\n };\n\n var getDuration = allowMinimumUploadDuration\n ? function() {\n return Math.min(state.duration, state.perceivedDuration);\n }\n : function() {\n return state.duration;\n };\n\n var api = Object.assign({}, on(), {\n process: process, \u002F\u002F start processing file\n abort: abort, \u002F\u002F abort active process request\n getProgress: getProgress,\n getDuration: getDuration,\n reset: reset,\n });\n\n return api;\n };\n\n var getFilenameWithoutExtension = function getFilenameWithoutExtension(name) {\n return name.substr(0, name.lastIndexOf('.')) || name;\n };\n\n var createFileStub = function createFileStub(source) {\n var data = [source.name, source.size, source.type];\n\n \u002F\u002F is blob or base64, then we need to set the name\n if (source instanceof Blob || isBase64DataURI(source)) {\n data[0] = source.name || getDateString();\n } else if (isBase64DataURI(source)) {\n \u002F\u002F if is base64 data uri we need to determine the average size and type\n data[1] = source.length;\n data[2] = getMimeTypeFromBase64DataURI(source);\n } else if (isString(source)) {\n \u002F\u002F url\n data[0] = getFilenameFromURL(source);\n data[1] = 0;\n data[2] = 'application\u002Foctet-stream';\n }\n\n return {\n name: data[0],\n size: data[1],\n type: data[2],\n };\n };\n\n var isFile = function isFile(value) {\n return !!(value instanceof File || (value instanceof Blob && value.name));\n };\n\n var deepCloneObject = function deepCloneObject(src) {\n if (!isObject(src)) return src;\n var target = isArray(src) ? [] : {};\n for (var key in src) {\n if (!src.hasOwnProperty(key)) continue;\n var v = src[key];\n target[key] = v && isObject(v) ? deepCloneObject(v) : v;\n }\n return target;\n };\n\n var createItem = function createItem() {\n var origin = arguments.length \u003E 0 && arguments[0] !== undefined ? arguments[0] : null;\n var serverFileReference =\n arguments.length \u003E 1 && arguments[1] !== undefined ? arguments[1] : null;\n var file = arguments.length \u003E 2 && arguments[2] !== undefined ? arguments[2] : null;\n \u002F\u002F unique id for this item, is used to identify the item across views\n var id = getUniqueId();\n\n \u002F**\n * Internal item state\n *\u002F\n var state = {\n \u002F\u002F is archived\n archived: false,\n\n \u002F\u002F if is frozen, no longer fires events\n frozen: false,\n\n \u002F\u002F removed from view\n released: false,\n\n \u002F\u002F original source\n source: null,\n\n \u002F\u002F file model reference\n file: file,\n\n \u002F\u002F id of file on server\n serverFileReference: serverFileReference,\n\n \u002F\u002F id of file transfer on server\n transferId: null,\n\n \u002F\u002F is aborted\n processingAborted: false,\n\n \u002F\u002F current item status\n status: serverFileReference ? ItemStatus.PROCESSING_COMPLETE : ItemStatus.INIT,\n\n \u002F\u002F active processes\n activeLoader: null,\n activeProcessor: null,\n };\n\n \u002F\u002F callback used when abort processing is called to link back to the resolve method\n var abortProcessingRequestComplete = null;\n\n \u002F**\n * Externally added item metadata\n *\u002F\n var metadata = {};\n\n \u002F\u002F item data\n var setStatus = function setStatus(status) {\n return (state.status = status);\n };\n\n \u002F\u002F fire event unless the item has been archived\n var fire = function fire(event) {\n if (state.released || state.frozen) return;\n for (\n var _len = arguments.length, params = new Array(_len \u003E 1 ? _len - 1 : 0), _key = 1;\n _key \u003C _len;\n _key++\n ) {\n params[_key - 1] = arguments[_key];\n }\n api.fire.apply(api, [event].concat(params));\n };\n\n \u002F\u002F file data\n var getFileExtension = function getFileExtension() {\n return getExtensionFromFilename(state.file.name);\n };\n var getFileType = function getFileType() {\n return state.file.type;\n };\n var getFileSize = function getFileSize() {\n return state.file.size;\n };\n var getFile = function getFile() {\n return state.file;\n };\n\n \u002F\u002F\n \u002F\u002F logic to load a file\n \u002F\u002F\n var load = function load(source, loader, onload) {\n \u002F\u002F remember the original item source\n state.source = source;\n\n \u002F\u002F source is known\n api.fireSync('init');\n\n \u002F\u002F file stub is already there\n if (state.file) {\n api.fireSync('load-skip');\n return;\n }\n\n \u002F\u002F set a stub file object while loading the actual data\n state.file = createFileStub(source);\n\n \u002F\u002F starts loading\n loader.on('init', function() {\n fire('load-init');\n });\n\n \u002F\u002F we'eve received a size indication, let's update the stub\n loader.on('meta', function(meta) {\n \u002F\u002F set size of file stub\n state.file.size = meta.size;\n\n \u002F\u002F set name of file stub\n state.file.filename = meta.filename;\n\n \u002F\u002F if has received source, we done\n if (meta.source) {\n origin = FileOrigin.LIMBO;\n state.serverFileReference = meta.source;\n state.status = ItemStatus.PROCESSING_COMPLETE;\n }\n\n \u002F\u002F size has been updated\n fire('load-meta');\n });\n\n \u002F\u002F the file is now loading we need to update the progress indicators\n loader.on('progress', function(progress) {\n setStatus(ItemStatus.LOADING);\n\n fire('load-progress', progress);\n });\n\n \u002F\u002F an error was thrown while loading the file, we need to switch to error state\n loader.on('error', function(error) {\n setStatus(ItemStatus.LOAD_ERROR);\n\n fire('load-request-error', error);\n });\n\n \u002F\u002F user or another process aborted the file load (cannot retry)\n loader.on('abort', function() {\n setStatus(ItemStatus.INIT);\n fire('load-abort');\n });\n\n \u002F\u002F done loading\n loader.on('load', function(file) {\n \u002F\u002F as we've now loaded the file the loader is no longer required\n state.activeLoader = null;\n\n \u002F\u002F called when file has loaded succesfully\n var success = function success(result) {\n \u002F\u002F set (possibly) transformed file\n state.file = isFile(result) ? result : state.file;\n\n \u002F\u002F file received\n if (origin === FileOrigin.LIMBO && state.serverFileReference) {\n setStatus(ItemStatus.PROCESSING_COMPLETE);\n } else {\n setStatus(ItemStatus.IDLE);\n }\n\n fire('load');\n };\n\n var error = function error(result) {\n \u002F\u002F set original file\n state.file = file;\n fire('load-meta');\n\n setStatus(ItemStatus.LOAD_ERROR);\n fire('load-file-error', result);\n };\n\n \u002F\u002F if we already have a server file reference, we don't need to call the onload method\n if (state.serverFileReference) {\n success(file);\n return;\n }\n\n \u002F\u002F no server id, let's give this file the full treatment\n onload(file, success, error);\n });\n\n \u002F\u002F set loader source data\n loader.setSource(source);\n\n \u002F\u002F set as active loader\n state.activeLoader = loader;\n\n \u002F\u002F load the source data\n loader.load();\n };\n\n var retryLoad = function retryLoad() {\n if (!state.activeLoader) {\n return;\n }\n state.activeLoader.load();\n };\n\n var abortLoad = function abortLoad() {\n if (state.activeLoader) {\n state.activeLoader.abort();\n return;\n }\n setStatus(ItemStatus.INIT);\n fire('load-abort');\n };\n\n \u002F\u002F\n \u002F\u002F logic to process a file\n \u002F\u002F\n var process = function process(processor, onprocess) {\n \u002F\u002F processing was aborted\n if (state.processingAborted) {\n state.processingAborted = false;\n return;\n }\n\n \u002F\u002F now processing\n setStatus(ItemStatus.PROCESSING);\n\n \u002F\u002F reset abort callback\n abortProcessingRequestComplete = null;\n\n \u002F\u002F if no file loaded we'll wait for the load event\n if (!(state.file instanceof Blob)) {\n api.on('load', function() {\n process(processor, onprocess);\n });\n return;\n }\n\n \u002F\u002F setup processor\n processor.on('load', function(serverFileReference) {\n \u002F\u002F need this id to be able to revert the upload\n state.transferId = null;\n state.serverFileReference = serverFileReference;\n });\n\n \u002F\u002F register transfer id\n processor.on('transfer', function(transferId) {\n \u002F\u002F need this id to be able to revert the upload\n state.transferId = transferId;\n });\n\n processor.on('load-perceived', function(serverFileReference) {\n \u002F\u002F no longer required\n state.activeProcessor = null;\n\n \u002F\u002F need this id to be able to rever the upload\n state.transferId = null;\n state.serverFileReference = serverFileReference;\n\n setStatus(ItemStatus.PROCESSING_COMPLETE);\n fire('process-complete', serverFileReference);\n });\n\n processor.on('start', function() {\n fire('process-start');\n });\n\n processor.on('error', function(error) {\n state.activeProcessor = null;\n setStatus(ItemStatus.PROCESSING_ERROR);\n fire('process-error', error);\n });\n\n processor.on('abort', function(serverFileReference) {\n state.activeProcessor = null;\n\n \u002F\u002F if file was uploaded but processing was cancelled during perceived processor time store file reference\n state.transferId = null;\n state.serverFileReference = serverFileReference;\n\n setStatus(ItemStatus.IDLE);\n fire('process-abort');\n\n \u002F\u002F has timeout so doesn't interfere with remove action\n if (abortProcessingRequestComplete) {\n abortProcessingRequestComplete();\n }\n });\n\n processor.on('progress', function(progress) {\n fire('process-progress', progress);\n });\n\n \u002F\u002F when successfully transformed\n var success = function success(file) {\n \u002F\u002F if was archived in the mean time, don't process\n if (state.archived) return;\n\n \u002F\u002F process file!\n processor.process(file, Object.assign({}, metadata));\n };\n\n \u002F\u002F something went wrong during transform phase\n var error = console.error;\n\n \u002F\u002F start processing the file\n onprocess(state.file, success, error);\n\n \u002F\u002F set as active processor\n state.activeProcessor = processor;\n };\n\n var requestProcessing = function requestProcessing() {\n state.processingAborted = false;\n setStatus(ItemStatus.PROCESSING_QUEUED);\n };\n\n var abortProcessing = function abortProcessing() {\n return new Promise(function(resolve) {\n if (!state.activeProcessor) {\n state.processingAborted = true;\n\n setStatus(ItemStatus.IDLE);\n fire('process-abort');\n\n resolve();\n return;\n }\n\n abortProcessingRequestComplete = function abortProcessingRequestComplete() {\n resolve();\n };\n\n state.activeProcessor.abort();\n });\n };\n\n \u002F\u002F\n \u002F\u002F logic to revert a processed file\n \u002F\u002F\n var revert = function revert(revertFileUpload, forceRevert) {\n return new Promise(function(resolve, reject) {\n \u002F\u002F cannot revert without a server id for this process\n if (state.serverFileReference === null) {\n resolve();\n return;\n }\n\n \u002F\u002F revert the upload (fire and forget)\n revertFileUpload(\n state.serverFileReference,\n function() {\n \u002F\u002F reset file server id as now it's no available on the server\n state.serverFileReference = null;\n resolve();\n },\n function(error) {\n \u002F\u002F don't set error state when reverting is optional, it will always resolve\n if (!forceRevert) {\n resolve();\n return;\n }\n\n \u002F\u002F oh no errors\n setStatus(ItemStatus.PROCESSING_REVERT_ERROR);\n fire('process-revert-error');\n reject(error);\n }\n );\n\n \u002F\u002F fire event\n setStatus(ItemStatus.IDLE);\n fire('process-revert');\n });\n };\n\n \u002F\u002F exposed methods\n var _setMetadata = function setMetadata(key, value, silent) {\n var keys = key.split('.');\n var root = keys[0];\n var last = keys.pop();\n var data = metadata;\n keys.forEach(function(key) {\n return (data = data[key]);\n });\n\n \u002F\u002F compare old value against new value, if they're the same, we're not updating\n if (JSON.stringify(data[last]) === JSON.stringify(value)) return;\n\n \u002F\u002F update value\n data[last] = value;\n\n \u002F\u002F fire update\n fire('metadata-update', {\n key: root,\n value: metadata[root],\n silent: silent,\n });\n };\n\n var getMetadata = function getMetadata(key) {\n return deepCloneObject(key ? metadata[key] : metadata);\n };\n\n var api = Object.assign(\n {\n id: {\n get: function get() {\n return id;\n },\n },\n origin: {\n get: function get() {\n return origin;\n },\n set: function set(value) {\n return (origin = value);\n },\n },\n serverId: {\n get: function get() {\n return state.serverFileReference;\n },\n },\n transferId: {\n get: function get() {\n return state.transferId;\n },\n },\n status: {\n get: function get() {\n return state.status;\n },\n },\n filename: {\n get: function get() {\n return state.file.name;\n },\n },\n filenameWithoutExtension: {\n get: function get() {\n return getFilenameWithoutExtension(state.file.name);\n },\n },\n fileExtension: { get: getFileExtension },\n fileType: { get: getFileType },\n fileSize: { get: getFileSize },\n file: { get: getFile },\n relativePath: {\n get: function get() {\n return state.file._relativePath;\n },\n },\n\n source: {\n get: function get() {\n return state.source;\n },\n },\n\n getMetadata: getMetadata,\n setMetadata: function setMetadata(key, value, silent) {\n if (isObject(key)) {\n var data = key;\n Object.keys(data).forEach(function(key) {\n _setMetadata(key, data[key], value);\n });\n return key;\n }\n _setMetadata(key, value, silent);\n return value;\n },\n\n extend: function extend(name, handler) {\n return (itemAPI[name] = handler);\n },\n\n abortLoad: abortLoad,\n retryLoad: retryLoad,\n requestProcessing: requestProcessing,\n abortProcessing: abortProcessing,\n\n load: load,\n process: process,\n revert: revert,\n },\n\n on(),\n {\n freeze: function freeze() {\n return (state.frozen = true);\n },\n\n release: function release() {\n return (state.released = true);\n },\n released: {\n get: function get() {\n return state.released;\n },\n },\n\n archive: function archive() {\n return (state.archived = true);\n },\n archived: {\n get: function get() {\n return state.archived;\n },\n },\n }\n );\n\n \u002F\u002F create it here instead of returning it instantly so we can extend it later\n var itemAPI = createObject(api);\n\n return itemAPI;\n };\n\n var getItemIndexByQuery = function getItemIndexByQuery(items, query) {\n \u002F\u002F just return first index\n if (isEmpty(query)) {\n return 0;\n }\n\n \u002F\u002F invalid queries\n if (!isString(query)) {\n return -1;\n }\n\n \u002F\u002F return item by id (or -1 if not found)\n return items.findIndex(function(item) {\n return item.id === query;\n });\n };\n\n var getItemById = function getItemById(items, itemId) {\n var index = getItemIndexByQuery(items, itemId);\n if (index \u003C 0) {\n return;\n }\n return items[index] || null;\n };\n\n var fetchBlob = function fetchBlob(url, load, error, progress, abort, headers) {\n var request = sendRequest(null, url, {\n method: 'GET',\n responseType: 'blob',\n });\n\n request.onload = function(xhr) {\n \u002F\u002F get headers\n var headers = xhr.getAllResponseHeaders();\n\n \u002F\u002F get filename\n var filename = getFileInfoFromHeaders(headers).name || getFilenameFromURL(url);\n\n \u002F\u002F create response\n load(\n createResponse('load', xhr.status, getFileFromBlob(xhr.response, filename), headers)\n );\n };\n\n request.onerror = function(xhr) {\n error(createResponse('error', xhr.status, xhr.statusText, xhr.getAllResponseHeaders()));\n };\n\n request.onheaders = function(xhr) {\n headers(createResponse('headers', xhr.status, null, xhr.getAllResponseHeaders()));\n };\n\n request.ontimeout = createTimeoutResponse(error);\n request.onprogress = progress;\n request.onabort = abort;\n\n \u002F\u002F should return request\n return request;\n };\n\n var getDomainFromURL = function getDomainFromURL(url) {\n if (url.indexOf('\u002F\u002F') === 0) {\n url = location.protocol + url;\n }\n return url\n .toLowerCase()\n .replace('blob:', '')\n .replace(\u002F([a-z])?:\\\u002F\\\u002F\u002F, '$1')\n .split('\u002F')[0];\n };\n\n var isExternalURL = function isExternalURL(url) {\n return (\n (url.indexOf(':') \u003E -1 || url.indexOf('\u002F\u002F') \u003E -1) &&\n getDomainFromURL(location.href) !== getDomainFromURL(url)\n );\n };\n\n var dynamicLabel = function dynamicLabel(label) {\n return function() {\n return isFunction(label) ? label.apply(void 0, arguments) : label;\n };\n };\n\n var isMockItem = function isMockItem(item) {\n return !isFile(item.file);\n };\n\n var listUpdated = function listUpdated(dispatch, state) {\n clearTimeout(state.listUpdateTimeout);\n state.listUpdateTimeout = setTimeout(function() {\n dispatch('DID_UPDATE_ITEMS', { items: getActiveItems(state.items) });\n }, 0);\n };\n\n var optionalPromise = function optionalPromise(fn) {\n for (\n var _len = arguments.length, params = new Array(_len \u003E 1 ? _len - 1 : 0), _key = 1;\n _key \u003C _len;\n _key++\n ) {\n params[_key - 1] = arguments[_key];\n }\n return new Promise(function(resolve) {\n if (!fn) {\n return resolve(true);\n }\n\n var result = fn.apply(void 0, params);\n\n if (result == null) {\n return resolve(true);\n }\n\n if (typeof result === 'boolean') {\n return resolve(result);\n }\n\n if (typeof result.then === 'function') {\n result.then(resolve);\n }\n });\n };\n\n var sortItems = function sortItems(state, compare) {\n state.items.sort(function(a, b) {\n return compare(createItemAPI(a), createItemAPI(b));\n });\n };\n\n \u002F\u002F returns item based on state\n var getItemByQueryFromState = function getItemByQueryFromState(state, itemHandler) {\n return function() {\n var _ref = arguments.length \u003E 0 && arguments[0] !== undefined ? arguments[0] : {};\n var query = _ref.query,\n _ref$success = _ref.success,\n success = _ref$success === void 0 ? function() {} : _ref$success,\n _ref$failure = _ref.failure,\n failure = _ref$failure === void 0 ? function() {} : _ref$failure,\n options = _objectWithoutProperties(_ref, ['query', 'success', 'failure']);\n var item = getItemByQuery(state.items, query);\n if (!item) {\n failure({\n error: createResponse('error', 0, 'Item not found'),\n file: null,\n });\n\n return;\n }\n itemHandler(item, success, failure, options || {});\n };\n };\n\n var actions = function actions(dispatch, query, state) {\n return {\n \u002F**\n * Aborts all ongoing processes\n *\u002F\n ABORT_ALL: function ABORT_ALL() {\n getActiveItems(state.items).forEach(function(item) {\n item.freeze();\n item.abortLoad();\n item.abortProcessing();\n });\n },\n\n \u002F**\n * Sets initial files\n *\u002F\n DID_SET_FILES: function DID_SET_FILES(_ref2) {\n var _ref2$value = _ref2.value,\n value = _ref2$value === void 0 ? [] : _ref2$value;\n \u002F\u002F map values to file objects\n var files = value.map(function(file) {\n return {\n source: file.source ? file.source : file,\n options: file.options,\n };\n });\n\n \u002F\u002F loop over files, if file is in list, leave it be, if not, remove\n \u002F\u002F test if items should be moved\n var activeItems = getActiveItems(state.items);\n\n activeItems.forEach(function(item) {\n \u002F\u002F if item not is in new value, remove\n if (\n !files.find(function(file) {\n return file.source === item.source || file.source === item.file;\n })\n ) {\n dispatch('REMOVE_ITEM', { query: item, remove: false });\n }\n });\n\n \u002F\u002F add new files\n activeItems = getActiveItems(state.items);\n files.forEach(function(file, index) {\n \u002F\u002F if file is already in list\n if (\n activeItems.find(function(item) {\n return item.source === file.source || item.file === file.source;\n })\n )\n return;\n\n \u002F\u002F not in list, add\n dispatch(\n 'ADD_ITEM',\n Object.assign({}, file, {\n interactionMethod: InteractionMethod.NONE,\n index: index,\n })\n );\n });\n },\n\n DID_UPDATE_ITEM_METADATA: function DID_UPDATE_ITEM_METADATA(_ref3) {\n var id = _ref3.id,\n action = _ref3.action,\n change = _ref3.change;\n \u002F\u002F don't do anything\n if (change.silent) return;\n\n \u002F\u002F if is called multiple times in close succession we combined all calls together to save resources\n clearTimeout(state.itemUpdateTimeout);\n state.itemUpdateTimeout = setTimeout(function() {\n var item = getItemById(state.items, id);\n\n \u002F\u002F only revert and attempt to upload when we're uploading to a server\n if (!query('IS_ASYNC')) {\n \u002F\u002F should we update the output data\n applyFilterChain('SHOULD_PREPARE_OUTPUT', false, {\n item: item,\n query: query,\n action: action,\n change: change,\n }).then(function(shouldPrepareOutput) {\n \u002F\u002F plugins determined the output data should be prepared (or not), can be adjusted with beforePrepareOutput hook\n var beforePrepareFile = query('GET_BEFORE_PREPARE_FILE');\n if (beforePrepareFile)\n shouldPrepareOutput = beforePrepareFile(item, shouldPrepareOutput);\n\n if (!shouldPrepareOutput) return;\n\n dispatch(\n 'REQUEST_PREPARE_OUTPUT',\n {\n query: id,\n item: item,\n success: function success(file) {\n dispatch('DID_PREPARE_OUTPUT', { id: id, file: file });\n },\n },\n\n true\n );\n });\n\n return;\n }\n\n \u002F\u002F if is local item we need to enable upload button so change can be propagated to server\n if (item.origin === FileOrigin.LOCAL) {\n dispatch('DID_LOAD_ITEM', {\n id: item.id,\n error: null,\n serverFileReference: item.source,\n });\n }\n\n \u002F\u002F for async scenarios\n var upload = function upload() {\n \u002F\u002F we push this forward a bit so the interface is updated correctly\n setTimeout(function() {\n dispatch('REQUEST_ITEM_PROCESSING', { query: id });\n }, 32);\n };\n\n var revert = function revert(doUpload) {\n item.revert(\n createRevertFunction(\n state.options.server.url,\n state.options.server.revert\n ),\n query('GET_FORCE_REVERT')\n )\n .then(doUpload ? upload : function() {})\n .catch(function() {});\n };\n\n var abort = function abort(doUpload) {\n item.abortProcessing().then(doUpload ? upload : function() {});\n };\n\n \u002F\u002F if we should re-upload the file immediately\n if (item.status === ItemStatus.PROCESSING_COMPLETE) {\n return revert(state.options.instantUpload);\n }\n\n \u002F\u002F if currently uploading, cancel upload\n if (item.status === ItemStatus.PROCESSING) {\n return abort(state.options.instantUpload);\n }\n\n if (state.options.instantUpload) {\n upload();\n }\n }, 0);\n },\n\n MOVE_ITEM: function MOVE_ITEM(_ref4) {\n var query = _ref4.query,\n index = _ref4.index;\n var item = getItemByQuery(state.items, query);\n if (!item) return;\n var currentIndex = state.items.indexOf(item);\n index = limit(index, 0, state.items.length - 1);\n if (currentIndex === index) return;\n state.items.splice(index, 0, state.items.splice(currentIndex, 1)[0]);\n },\n\n SORT: function SORT(_ref5) {\n var compare = _ref5.compare;\n sortItems(state, compare);\n dispatch('DID_SORT_ITEMS', {\n items: query('GET_ACTIVE_ITEMS'),\n });\n },\n\n ADD_ITEMS: function ADD_ITEMS(_ref6) {\n var items = _ref6.items,\n index = _ref6.index,\n interactionMethod = _ref6.interactionMethod,\n _ref6$success = _ref6.success,\n success = _ref6$success === void 0 ? function() {} : _ref6$success,\n _ref6$failure = _ref6.failure,\n failure = _ref6$failure === void 0 ? function() {} : _ref6$failure;\n var currentIndex = index;\n\n if (index === -1 || typeof index === 'undefined') {\n var insertLocation = query('GET_ITEM_INSERT_LOCATION');\n var totalItems = query('GET_TOTAL_ITEMS');\n currentIndex = insertLocation === 'before' ? 0 : totalItems;\n }\n\n var ignoredFiles = query('GET_IGNORED_FILES');\n var isValidFile = function isValidFile(source) {\n return isFile(source)\n ? !ignoredFiles.includes(source.name.toLowerCase())\n : !isEmpty(source);\n };\n var validItems = items.filter(isValidFile);\n\n var promises = validItems.map(function(source) {\n return new Promise(function(resolve, reject) {\n dispatch('ADD_ITEM', {\n interactionMethod: interactionMethod,\n source: source.source || source,\n success: resolve,\n failure: reject,\n index: currentIndex++,\n options: source.options || {},\n });\n });\n });\n\n Promise.all(promises)\n .then(success)\n .catch(failure);\n },\n\n \u002F**\n * @param source\n * @param index\n * @param interactionMethod\n *\u002F\n ADD_ITEM: function ADD_ITEM(_ref7) {\n var source = _ref7.source,\n _ref7$index = _ref7.index,\n index = _ref7$index === void 0 ? -1 : _ref7$index,\n interactionMethod = _ref7.interactionMethod,\n _ref7$success = _ref7.success,\n success = _ref7$success === void 0 ? function() {} : _ref7$success,\n _ref7$failure = _ref7.failure,\n failure = _ref7$failure === void 0 ? function() {} : _ref7$failure,\n _ref7$options = _ref7.options,\n options = _ref7$options === void 0 ? {} : _ref7$options;\n \u002F\u002F if no source supplied\n if (isEmpty(source)) {\n failure({\n error: createResponse('error', 0, 'No source'),\n file: null,\n });\n\n return;\n }\n\n \u002F\u002F filter out invalid file items, used to filter dropped directory contents\n if (\n isFile(source) &&\n state.options.ignoredFiles.includes(source.name.toLowerCase())\n ) {\n \u002F\u002F fail silently\n return;\n }\n\n \u002F\u002F test if there's still room in the list of files\n if (!hasRoomForItem(state)) {\n \u002F\u002F if multiple allowed, we can't replace\n \u002F\u002F or if only a single item is allowed but we're not allowed to replace it we exit\n if (\n state.options.allowMultiple ||\n (!state.options.allowMultiple && !state.options.allowReplace)\n ) {\n var error = createResponse('warning', 0, 'Max files');\n\n dispatch('DID_THROW_MAX_FILES', {\n source: source,\n error: error,\n });\n\n failure({ error: error, file: null });\n\n return;\n }\n\n \u002F\u002F let's replace the item\n \u002F\u002F id of first item we're about to remove\n var _item = getActiveItems(state.items)[0];\n\n \u002F\u002F if has been processed remove it from the server as well\n if (\n _item.status === ItemStatus.PROCESSING_COMPLETE ||\n _item.status === ItemStatus.PROCESSING_REVERT_ERROR\n ) {\n var forceRevert = query('GET_FORCE_REVERT');\n _item\n .revert(\n createRevertFunction(\n state.options.server.url,\n state.options.server.revert\n ),\n forceRevert\n )\n .then(function() {\n if (!forceRevert) return;\n\n \u002F\u002F try to add now\n dispatch('ADD_ITEM', {\n source: source,\n index: index,\n interactionMethod: interactionMethod,\n success: success,\n failure: failure,\n options: options,\n });\n })\n .catch(function() {}); \u002F\u002F no need to handle this catch state for now\n\n if (forceRevert) return;\n }\n\n \u002F\u002F remove first item as it will be replaced by this item\n dispatch('REMOVE_ITEM', { query: _item.id });\n }\n\n \u002F\u002F where did the file originate\n var origin =\n options.type === 'local'\n ? FileOrigin.LOCAL\n : options.type === 'limbo'\n ? FileOrigin.LIMBO\n : FileOrigin.INPUT;\n\n \u002F\u002F create a new blank item\n var item = createItem(\n \u002F\u002F where did this file come from\n origin,\n\n \u002F\u002F an input file never has a server file reference\n origin === FileOrigin.INPUT ? null : source,\n\n \u002F\u002F file mock data, if defined\n options.file\n );\n\n \u002F\u002F set initial meta data\n Object.keys(options.metadata || {}).forEach(function(key) {\n item.setMetadata(key, options.metadata[key]);\n });\n\n \u002F\u002F created the item, let plugins add methods\n applyFilters('DID_CREATE_ITEM', item, { query: query, dispatch: dispatch });\n\n \u002F\u002F where to insert new items\n var itemInsertLocation = query('GET_ITEM_INSERT_LOCATION');\n\n \u002F\u002F adjust index if is not allowed to pick location\n if (!state.options.itemInsertLocationFreedom) {\n index = itemInsertLocation === 'before' ? -1 : state.items.length;\n }\n\n \u002F\u002F add item to list\n insertItem(state.items, item, index);\n\n \u002F\u002F sort items in list\n if (isFunction(itemInsertLocation) && source) {\n sortItems(state, itemInsertLocation);\n }\n\n \u002F\u002F get a quick reference to the item id\n var id = item.id;\n\n \u002F\u002F observe item events\n item.on('init', function() {\n dispatch('DID_INIT_ITEM', { id: id });\n });\n\n item.on('load-init', function() {\n dispatch('DID_START_ITEM_LOAD', { id: id });\n });\n\n item.on('load-meta', function() {\n dispatch('DID_UPDATE_ITEM_META', { id: id });\n });\n\n item.on('load-progress', function(progress) {\n dispatch('DID_UPDATE_ITEM_LOAD_PROGRESS', { id: id, progress: progress });\n });\n\n item.on('load-request-error', function(error) {\n var mainStatus = dynamicLabel(state.options.labelFileLoadError)(error);\n\n \u002F\u002F is client error, no way to recover\n if (error.code \u003E= 400 && error.code \u003C 500) {\n dispatch('DID_THROW_ITEM_INVALID', {\n id: id,\n error: error,\n status: {\n main: mainStatus,\n sub: error.code + ' (' + error.body + ')',\n },\n });\n\n \u002F\u002F reject the file so can be dealt with through API\n failure({ error: error, file: createItemAPI(item) });\n return;\n }\n\n \u002F\u002F is possible server error, so might be possible to retry\n dispatch('DID_THROW_ITEM_LOAD_ERROR', {\n id: id,\n error: error,\n status: {\n main: mainStatus,\n sub: state.options.labelTapToRetry,\n },\n });\n });\n\n item.on('load-file-error', function(error) {\n dispatch('DID_THROW_ITEM_INVALID', {\n id: id,\n error: error.status,\n status: error.status,\n });\n\n failure({ error: error.status, file: createItemAPI(item) });\n });\n\n item.on('load-abort', function() {\n dispatch('REMOVE_ITEM', { query: id });\n });\n\n item.on('load-skip', function() {\n dispatch('COMPLETE_LOAD_ITEM', {\n query: id,\n item: item,\n data: {\n source: source,\n success: success,\n },\n });\n });\n\n item.on('load', function() {\n var handleAdd = function handleAdd(shouldAdd) {\n \u002F\u002F no should not add this file\n if (!shouldAdd) {\n dispatch('REMOVE_ITEM', {\n query: id,\n });\n\n return;\n }\n\n \u002F\u002F now interested in metadata updates\n item.on('metadata-update', function(change) {\n dispatch('DID_UPDATE_ITEM_METADATA', { id: id, change: change });\n });\n\n \u002F\u002F let plugins decide if the output data should be prepared at this point\n \u002F\u002F means we'll do this and wait for idle state\n applyFilterChain('SHOULD_PREPARE_OUTPUT', false, {\n item: item,\n query: query,\n }).then(function(shouldPrepareOutput) {\n \u002F\u002F plugins determined the output data should be prepared (or not), can be adjusted with beforePrepareOutput hook\n var beforePrepareFile = query('GET_BEFORE_PREPARE_FILE');\n if (beforePrepareFile)\n shouldPrepareOutput = beforePrepareFile(item, shouldPrepareOutput);\n\n var loadComplete = function loadComplete() {\n dispatch('COMPLETE_LOAD_ITEM', {\n query: id,\n item: item,\n data: {\n source: source,\n success: success,\n },\n });\n\n listUpdated(dispatch, state);\n };\n\n \u002F\u002F exit\n if (shouldPrepareOutput) {\n \u002F\u002F wait for idle state and then run PREPARE_OUTPUT\n dispatch(\n 'REQUEST_PREPARE_OUTPUT',\n {\n query: id,\n item: item,\n success: function success(file) {\n dispatch('DID_PREPARE_OUTPUT', { id: id, file: file });\n loadComplete();\n },\n },\n\n true\n );\n\n return;\n }\n\n loadComplete();\n });\n };\n\n \u002F\u002F item loaded, allow plugins to\n \u002F\u002F - read data (quickly)\n \u002F\u002F - add metadata\n applyFilterChain('DID_LOAD_ITEM', item, { query: query, dispatch: dispatch })\n .then(function() {\n optionalPromise(query('GET_BEFORE_ADD_FILE'), createItemAPI(item)).then(\n handleAdd\n );\n })\n .catch(function() {\n handleAdd(false);\n });\n });\n\n item.on('process-start', function() {\n dispatch('DID_START_ITEM_PROCESSING', { id: id });\n });\n\n item.on('process-progress', function(progress) {\n dispatch('DID_UPDATE_ITEM_PROCESS_PROGRESS', { id: id, progress: progress });\n });\n\n item.on('process-error', function(error) {\n dispatch('DID_THROW_ITEM_PROCESSING_ERROR', {\n id: id,\n error: error,\n status: {\n main: dynamicLabel(state.options.labelFileProcessingError)(error),\n sub: state.options.labelTapToRetry,\n },\n });\n });\n\n item.on('process-revert-error', function(error) {\n dispatch('DID_THROW_ITEM_PROCESSING_REVERT_ERROR', {\n id: id,\n error: error,\n status: {\n main: dynamicLabel(state.options.labelFileProcessingRevertError)(error),\n sub: state.options.labelTapToRetry,\n },\n });\n });\n\n item.on('process-complete', function(serverFileReference) {\n dispatch('DID_COMPLETE_ITEM_PROCESSING', {\n id: id,\n error: null,\n serverFileReference: serverFileReference,\n });\n\n dispatch('DID_DEFINE_VALUE', { id: id, value: serverFileReference });\n });\n\n item.on('process-abort', function() {\n dispatch('DID_ABORT_ITEM_PROCESSING', { id: id });\n });\n\n item.on('process-revert', function() {\n dispatch('DID_REVERT_ITEM_PROCESSING', { id: id });\n dispatch('DID_DEFINE_VALUE', { id: id, value: null });\n });\n\n \u002F\u002F let view know the item has been inserted\n dispatch('DID_ADD_ITEM', {\n id: id,\n index: index,\n interactionMethod: interactionMethod,\n });\n\n listUpdated(dispatch, state);\n\n \u002F\u002F start loading the source\n var _ref8 = state.options.server || {},\n url = _ref8.url,\n load = _ref8.load,\n restore = _ref8.restore,\n fetch = _ref8.fetch;\n\n item.load(\n source,\n\n \u002F\u002F this creates a function that loads the file based on the type of file (string, base64, blob, file) and location of file (local, remote, limbo)\n createFileLoader(\n origin === FileOrigin.INPUT\n ? \u002F\u002F input, if is remote, see if should use custom fetch, else use default fetchBlob\n isString(source) && isExternalURL(source)\n ? fetch\n ? createFetchFunction(url, fetch)\n : fetchBlob \u002F\u002F remote url\n : fetchBlob \u002F\u002F try to fetch url\n : \u002F\u002F limbo or local\n origin === FileOrigin.LIMBO\n ? createFetchFunction(url, restore) \u002F\u002F limbo\n : createFetchFunction(url, load) \u002F\u002F local\n ),\n\n \u002F\u002F called when the file is loaded so it can be piped through the filters\n function(file, success, error) {\n \u002F\u002F let's process the file\n applyFilterChain('LOAD_FILE', file, { query: query })\n .then(success)\n .catch(error);\n }\n );\n },\n\n REQUEST_PREPARE_OUTPUT: function REQUEST_PREPARE_OUTPUT(_ref9) {\n var item = _ref9.item,\n success = _ref9.success,\n _ref9$failure = _ref9.failure,\n failure = _ref9$failure === void 0 ? function() {} : _ref9$failure;\n \u002F\u002F error response if item archived\n var err = {\n error: createResponse('error', 0, 'Item not found'),\n file: null,\n };\n\n \u002F\u002F don't handle archived items, an item could have been archived (load aborted) while waiting to be prepared\n if (item.archived) return failure(err);\n\n \u002F\u002F allow plugins to alter the file data\n applyFilterChain('PREPARE_OUTPUT', item.file, { query: query, item: item }).then(\n function(result) {\n applyFilterChain('COMPLETE_PREPARE_OUTPUT', result, {\n query: query,\n item: item,\n }).then(function(result) {\n \u002F\u002F don't handle archived items, an item could have been archived (load aborted) while being prepared\n if (item.archived) return failure(err);\n\n \u002F\u002F we done!\n success(result);\n });\n }\n );\n },\n\n COMPLETE_LOAD_ITEM: function COMPLETE_LOAD_ITEM(_ref10) {\n var item = _ref10.item,\n data = _ref10.data;\n var success = data.success,\n source = data.source;\n\n \u002F\u002F sort items in list\n var itemInsertLocation = query('GET_ITEM_INSERT_LOCATION');\n if (isFunction(itemInsertLocation) && source) {\n sortItems(state, itemInsertLocation);\n }\n\n \u002F\u002F let interface know the item has loaded\n dispatch('DID_LOAD_ITEM', {\n id: item.id,\n error: null,\n serverFileReference: item.origin === FileOrigin.INPUT ? null : source,\n });\n\n \u002F\u002F item has been successfully loaded and added to the\n \u002F\u002F list of items so can now be safely returned for use\n success(createItemAPI(item));\n\n \u002F\u002F if this is a local server file we need to show a different state\n if (item.origin === FileOrigin.LOCAL) {\n dispatch('DID_LOAD_LOCAL_ITEM', { id: item.id });\n return;\n }\n\n \u002F\u002F if is a temp server file we prevent async upload call here (as the file is already on the server)\n if (item.origin === FileOrigin.LIMBO) {\n dispatch('DID_COMPLETE_ITEM_PROCESSING', {\n id: item.id,\n error: null,\n serverFileReference: source,\n });\n\n dispatch('DID_DEFINE_VALUE', {\n id: item.id,\n value: item.serverId || source,\n });\n\n return;\n }\n\n \u002F\u002F id we are allowed to upload the file immediately, lets do it\n if (query('IS_ASYNC') && state.options.instantUpload) {\n dispatch('REQUEST_ITEM_PROCESSING', { query: item.id });\n }\n },\n\n RETRY_ITEM_LOAD: getItemByQueryFromState(state, function(item) {\n \u002F\u002F try loading the source one more time\n item.retryLoad();\n }),\n\n REQUEST_ITEM_PREPARE: getItemByQueryFromState(state, function(item, _success, failure) {\n dispatch(\n 'REQUEST_PREPARE_OUTPUT',\n {\n query: item.id,\n item: item,\n success: function success(file) {\n dispatch('DID_PREPARE_OUTPUT', { id: item.id, file: file });\n _success({\n file: item,\n output: file,\n });\n },\n failure: failure,\n },\n\n true\n );\n }),\n\n REQUEST_ITEM_PROCESSING: getItemByQueryFromState(state, function(\n item,\n success,\n failure\n ) {\n \u002F\u002F cannot be queued (or is already queued)\n var itemCanBeQueuedForProcessing =\n \u002F\u002F waiting for something\n item.status === ItemStatus.IDLE ||\n \u002F\u002F processing went wrong earlier\n item.status === ItemStatus.PROCESSING_ERROR;\n\n \u002F\u002F not ready to be processed\n if (!itemCanBeQueuedForProcessing) {\n var processNow = function processNow() {\n return dispatch('REQUEST_ITEM_PROCESSING', {\n query: item,\n success: success,\n failure: failure,\n });\n };\n\n var process = function process() {\n return document.hidden ? processNow() : setTimeout(processNow, 32);\n };\n\n \u002F\u002F if already done processing or tried to revert but didn't work, try again\n if (\n item.status === ItemStatus.PROCESSING_COMPLETE ||\n item.status === ItemStatus.PROCESSING_REVERT_ERROR\n ) {\n item.revert(\n createRevertFunction(\n state.options.server.url,\n state.options.server.revert\n ),\n query('GET_FORCE_REVERT')\n )\n .then(process)\n .catch(function() {}); \u002F\u002F don't continue with processing if something went wrong\n } else if (item.status === ItemStatus.PROCESSING) {\n item.abortProcessing().then(process);\n }\n\n return;\n }\n\n \u002F\u002F already queued for processing\n if (item.status === ItemStatus.PROCESSING_QUEUED) return;\n\n item.requestProcessing();\n\n dispatch('DID_REQUEST_ITEM_PROCESSING', { id: item.id });\n\n dispatch('PROCESS_ITEM', { query: item, success: success, failure: failure }, true);\n }),\n\n PROCESS_ITEM: getItemByQueryFromState(state, function(item, success, failure) {\n var maxParallelUploads = query('GET_MAX_PARALLEL_UPLOADS');\n var totalCurrentUploads = query('GET_ITEMS_BY_STATUS', ItemStatus.PROCESSING)\n .length;\n\n \u002F\u002F queue and wait till queue is freed up\n if (totalCurrentUploads === maxParallelUploads) {\n \u002F\u002F queue for later processing\n state.processingQueue.push({\n id: item.id,\n success: success,\n failure: failure,\n });\n\n \u002F\u002F stop it!\n return;\n }\n\n \u002F\u002F if was not queued or is already processing exit here\n if (item.status === ItemStatus.PROCESSING) return;\n\n var processNext = function processNext() {\n \u002F\u002F process queueud items\n var queueEntry = state.processingQueue.shift();\n\n \u002F\u002F no items left\n if (!queueEntry) return;\n\n \u002F\u002F get item reference\n var id = queueEntry.id,\n success = queueEntry.success,\n failure = queueEntry.failure;\n var itemReference = getItemByQuery(state.items, id);\n\n \u002F\u002F if item was archived while in queue, jump to next\n if (!itemReference || itemReference.archived) {\n processNext();\n return;\n }\n\n \u002F\u002F process queued item\n dispatch(\n 'PROCESS_ITEM',\n { query: id, success: success, failure: failure },\n true\n );\n };\n\n \u002F\u002F we done function\n item.onOnce('process-complete', function() {\n success(createItemAPI(item));\n processNext();\n\n \u002F\u002F if origin is local, and we're instant uploading, trigger remove of original\n \u002F\u002F as revert will remove file from list\n var server = state.options.server;\n var instantUpload = state.options.instantUpload;\n if (\n instantUpload &&\n item.origin === FileOrigin.LOCAL &&\n isFunction(server.remove)\n ) {\n var noop = function noop() {};\n item.origin = FileOrigin.LIMBO;\n state.options.server.remove(item.source, noop, noop);\n }\n\n \u002F\u002F All items processed? No errors?\n var allItemsProcessed =\n query('GET_ITEMS_BY_STATUS', ItemStatus.PROCESSING_COMPLETE).length ===\n state.items.length;\n if (allItemsProcessed) {\n dispatch('DID_COMPLETE_ITEM_PROCESSING_ALL');\n }\n });\n\n \u002F\u002F we error function\n item.onOnce('process-error', function(error) {\n failure({ error: error, file: createItemAPI(item) });\n processNext();\n });\n\n \u002F\u002F start file processing\n var options = state.options;\n item.process(\n createFileProcessor(\n createProcessorFunction(\n options.server.url,\n options.server.process,\n options.name,\n {\n chunkTransferId: item.transferId,\n chunkServer: options.server.patch,\n chunkUploads: options.chunkUploads,\n chunkForce: options.chunkForce,\n chunkSize: options.chunkSize,\n chunkRetryDelays: options.chunkRetryDelays,\n }\n ),\n\n {\n allowMinimumUploadDuration: query('GET_ALLOW_MINIMUM_UPLOAD_DURATION'),\n }\n ),\n\n \u002F\u002F called when the file is about to be processed so it can be piped through the transform filters\n function(file, success, error) {\n \u002F\u002F allow plugins to alter the file data\n applyFilterChain('PREPARE_OUTPUT', file, { query: query, item: item })\n .then(function(file) {\n dispatch('DID_PREPARE_OUTPUT', { id: item.id, file: file });\n\n success(file);\n })\n .catch(error);\n }\n );\n }),\n\n RETRY_ITEM_PROCESSING: getItemByQueryFromState(state, function(item) {\n dispatch('REQUEST_ITEM_PROCESSING', { query: item });\n }),\n\n REQUEST_REMOVE_ITEM: getItemByQueryFromState(state, function(item) {\n optionalPromise(query('GET_BEFORE_REMOVE_FILE'), createItemAPI(item)).then(function(\n shouldRemove\n ) {\n if (!shouldRemove) {\n return;\n }\n dispatch('REMOVE_ITEM', { query: item });\n });\n }),\n\n RELEASE_ITEM: getItemByQueryFromState(state, function(item) {\n item.release();\n }),\n\n REMOVE_ITEM: getItemByQueryFromState(state, function(item, success, failure, options) {\n var removeFromView = function removeFromView() {\n \u002F\u002F get id reference\n var id = item.id;\n\n \u002F\u002F archive the item, this does not remove it from the list\n getItemById(state.items, id).archive();\n\n \u002F\u002F tell the view the item has been removed\n dispatch('DID_REMOVE_ITEM', { error: null, id: id, item: item });\n\n \u002F\u002F now the list has been modified\n listUpdated(dispatch, state);\n\n \u002F\u002F correctly removed\n success(createItemAPI(item));\n };\n\n \u002F\u002F if this is a local file and the `server.remove` function has been configured,\n \u002F\u002F send source there so dev can remove file from server\n var server = state.options.server;\n if (\n item.origin === FileOrigin.LOCAL &&\n server &&\n isFunction(server.remove) &&\n options.remove !== false\n ) {\n dispatch('DID_START_ITEM_REMOVE', { id: item.id });\n\n server.remove(\n item.source,\n function() {\n return removeFromView();\n },\n function(status) {\n dispatch('DID_THROW_ITEM_REMOVE_ERROR', {\n id: item.id,\n error: createResponse('error', 0, status, null),\n status: {\n main: dynamicLabel(state.options.labelFileRemoveError)(status),\n sub: state.options.labelTapToRetry,\n },\n });\n }\n );\n } else {\n \u002F\u002F if is requesting revert and can revert need to call revert handler (not calling request_ because that would also trigger beforeRemoveHook)\n if (\n options.revert &&\n item.origin !== FileOrigin.LOCAL &&\n item.serverId !== null\n ) {\n item.revert(\n createRevertFunction(\n state.options.server.url,\n state.options.server.revert\n ),\n query('GET_FORCE_REVERT')\n );\n }\n\n \u002F\u002F can now safely remove from view\n removeFromView();\n }\n }),\n\n ABORT_ITEM_LOAD: getItemByQueryFromState(state, function(item) {\n item.abortLoad();\n }),\n\n ABORT_ITEM_PROCESSING: getItemByQueryFromState(state, function(item) {\n \u002F\u002F test if is already processed\n if (item.serverId) {\n dispatch('REVERT_ITEM_PROCESSING', { id: item.id });\n return;\n }\n\n \u002F\u002F abort\n item.abortProcessing().then(function() {\n var shouldRemove = state.options.instantUpload;\n if (shouldRemove) {\n dispatch('REMOVE_ITEM', { query: item.id });\n }\n });\n }),\n\n REQUEST_REVERT_ITEM_PROCESSING: getItemByQueryFromState(state, function(item) {\n \u002F\u002F not instant uploading, revert immediately\n if (!state.options.instantUpload) {\n dispatch('REVERT_ITEM_PROCESSING', { query: item });\n return;\n }\n\n \u002F\u002F if we're instant uploading the file will also be removed if we revert,\n \u002F\u002F so if a before remove file hook is defined we need to run it now\n var handleRevert = function handleRevert(shouldRevert) {\n if (!shouldRevert) return;\n dispatch('REVERT_ITEM_PROCESSING', { query: item });\n };\n\n var fn = query('GET_BEFORE_REMOVE_FILE');\n if (!fn) {\n return handleRevert(true);\n }\n\n var requestRemoveResult = fn(createItemAPI(item));\n if (requestRemoveResult == null) {\n \u002F\u002F undefined or null\n return handleRevert(true);\n }\n\n if (typeof requestRemoveResult === 'boolean') {\n return handleRevert(requestRemoveResult);\n }\n\n if (typeof requestRemoveResult.then === 'function') {\n requestRemoveResult.then(handleRevert);\n }\n }),\n\n REVERT_ITEM_PROCESSING: getItemByQueryFromState(state, function(item) {\n item.revert(\n createRevertFunction(state.options.server.url, state.options.server.revert),\n query('GET_FORCE_REVERT')\n )\n .then(function() {\n var shouldRemove = state.options.instantUpload || isMockItem(item);\n if (shouldRemove) {\n dispatch('REMOVE_ITEM', { query: item.id });\n }\n })\n .catch(function() {});\n }),\n\n SET_OPTIONS: function SET_OPTIONS(_ref11) {\n var options = _ref11.options;\n forin(options, function(key, value) {\n dispatch('SET_' + fromCamels(key, '_').toUpperCase(), { value: value });\n });\n },\n };\n };\n\n var formatFilename = function formatFilename(name) {\n return name;\n };\n\n var createElement$1 = function createElement(tagName) {\n return document.createElement(tagName);\n };\n\n var text = function text(node, value) {\n var textNode = node.childNodes[0];\n if (!textNode) {\n textNode = document.createTextNode(value);\n node.appendChild(textNode);\n } else if (value !== textNode.nodeValue) {\n textNode.nodeValue = value;\n }\n };\n\n var polarToCartesian = function polarToCartesian(centerX, centerY, radius, angleInDegrees) {\n var angleInRadians = (((angleInDegrees % 360) - 90) * Math.PI) \u002F 180.0;\n return {\n x: centerX + radius * Math.cos(angleInRadians),\n y: centerY + radius * Math.sin(angleInRadians),\n };\n };\n\n var describeArc = function describeArc(x, y, radius, startAngle, endAngle, arcSweep) {\n var start = polarToCartesian(x, y, radius, endAngle);\n var end = polarToCartesian(x, y, radius, startAngle);\n return ['M', start.x, start.y, 'A', radius, radius, 0, arcSweep, 0, end.x, end.y].join(' ');\n };\n\n var percentageArc = function percentageArc(x, y, radius, from, to) {\n var arcSweep = 1;\n if (to \u003E from && to - from \u003C= 0.5) {\n arcSweep = 0;\n }\n if (from \u003E to && from - to \u003E= 0.5) {\n arcSweep = 0;\n }\n return describeArc(\n x,\n y,\n radius,\n Math.min(0.9999, from) * 360,\n Math.min(0.9999, to) * 360,\n arcSweep\n );\n };\n\n var create = function create(_ref) {\n var root = _ref.root,\n props = _ref.props;\n \u002F\u002F start at 0\n props.spin = false;\n props.progress = 0;\n props.opacity = 0;\n\n \u002F\u002F svg\n var svg = createElement('svg');\n root.ref.path = createElement('path', {\n 'stroke-width': 2,\n 'stroke-linecap': 'round',\n });\n\n svg.appendChild(root.ref.path);\n\n root.ref.svg = svg;\n\n root.appendChild(svg);\n };\n\n var write = function write(_ref2) {\n var root = _ref2.root,\n props = _ref2.props;\n if (props.opacity === 0) {\n return;\n }\n\n if (props.align) {\n root.element.dataset.align = props.align;\n }\n\n \u002F\u002F get width of stroke\n var ringStrokeWidth = parseInt(attr(root.ref.path, 'stroke-width'), 10);\n\n \u002F\u002F calculate size of ring\n var size = root.rect.element.width * 0.5;\n\n \u002F\u002F ring state\n var ringFrom = 0;\n var ringTo = 0;\n\n \u002F\u002F now in busy mode\n if (props.spin) {\n ringFrom = 0;\n ringTo = 0.5;\n } else {\n ringFrom = 0;\n ringTo = props.progress;\n }\n\n \u002F\u002F get arc path\n var coordinates = percentageArc(size, size, size - ringStrokeWidth, ringFrom, ringTo);\n\n \u002F\u002F update progress bar\n attr(root.ref.path, 'd', coordinates);\n\n \u002F\u002F hide while contains 0 value\n attr(root.ref.path, 'stroke-opacity', props.spin || props.progress \u003E 0 ? 1 : 0);\n };\n\n var progressIndicator = createView({\n tag: 'div',\n name: 'progress-indicator',\n ignoreRectUpdate: true,\n ignoreRect: true,\n create: create,\n write: write,\n mixins: {\n apis: ['progress', 'spin', 'align'],\n styles: ['opacity'],\n animations: {\n opacity: { type: 'tween', duration: 500 },\n progress: {\n type: 'spring',\n stiffness: 0.95,\n damping: 0.65,\n mass: 10,\n },\n },\n },\n });\n\n var create$1 = function create(_ref) {\n var root = _ref.root,\n props = _ref.props;\n root.element.innerHTML = (props.icon || '') + ('\u003Cspan\u003E' + props.label + '\u003C\u002Fspan\u003E');\n\n props.isDisabled = false;\n };\n\n var write$1 = function write(_ref2) {\n var root = _ref2.root,\n props = _ref2.props;\n var isDisabled = props.isDisabled;\n var shouldDisable = root.query('GET_DISABLED') || props.opacity === 0;\n\n if (shouldDisable && !isDisabled) {\n props.isDisabled = true;\n attr(root.element, 'disabled', 'disabled');\n } else if (!shouldDisable && isDisabled) {\n props.isDisabled = false;\n root.element.removeAttribute('disabled');\n }\n };\n\n var fileActionButton = createView({\n tag: 'button',\n attributes: {\n type: 'button',\n },\n\n ignoreRect: true,\n ignoreRectUpdate: true,\n name: 'file-action-button',\n mixins: {\n apis: ['label'],\n styles: ['translateX', 'translateY', 'scaleX', 'scaleY', 'opacity'],\n animations: {\n scaleX: 'spring',\n scaleY: 'spring',\n translateX: 'spring',\n translateY: 'spring',\n opacity: { type: 'tween', duration: 250 },\n },\n\n listeners: true,\n },\n\n create: create$1,\n write: write$1,\n });\n\n var toNaturalFileSize = function toNaturalFileSize(bytes) {\n var decimalSeparator =\n arguments.length \u003E 1 && arguments[1] !== undefined ? arguments[1] : '.';\n var base = arguments.length \u003E 2 && arguments[2] !== undefined ? arguments[2] : 1000;\n \u002F\u002F no negative byte sizes\n bytes = Math.round(Math.abs(bytes));\n\n var KB = base;\n var MB = base * base;\n var GB = base * base * base;\n\n \u002F\u002F just bytes\n if (bytes \u003C KB) {\n return bytes + ' bytes';\n }\n\n \u002F\u002F kilobytes\n if (bytes \u003C MB) {\n return Math.floor(bytes \u002F KB) + ' KB';\n }\n\n \u002F\u002F megabytes\n if (bytes \u003C GB) {\n return removeDecimalsWhenZero(bytes \u002F MB, 1, decimalSeparator) + ' MB';\n }\n\n \u002F\u002F gigabytes\n return removeDecimalsWhenZero(bytes \u002F GB, 2, decimalSeparator) + ' GB';\n };\n\n var removeDecimalsWhenZero = function removeDecimalsWhenZero(value, decimalCount, separator) {\n return value\n .toFixed(decimalCount)\n .split('.')\n .filter(function(part) {\n return part !== '0';\n })\n .join(separator);\n };\n\n var create$2 = function create(_ref) {\n var root = _ref.root,\n props = _ref.props;\n \u002F\u002F filename\n var fileName = createElement$1('span');\n fileName.className = 'filepond--file-info-main';\n \u002F\u002F hide for screenreaders\n \u002F\u002F the file is contained in a fieldset with legend that contains the filename\n \u002F\u002F no need to read it twice\n attr(fileName, 'aria-hidden', 'true');\n root.appendChild(fileName);\n root.ref.fileName = fileName;\n\n \u002F\u002F filesize\n var fileSize = createElement$1('span');\n fileSize.className = 'filepond--file-info-sub';\n root.appendChild(fileSize);\n root.ref.fileSize = fileSize;\n\n \u002F\u002F set initial values\n text(fileSize, root.query('GET_LABEL_FILE_WAITING_FOR_SIZE'));\n text(fileName, formatFilename(root.query('GET_ITEM_NAME', props.id)));\n };\n\n var updateFile = function updateFile(_ref2) {\n var root = _ref2.root,\n props = _ref2.props;\n text(\n root.ref.fileSize,\n toNaturalFileSize(\n root.query('GET_ITEM_SIZE', props.id),\n '.',\n root.query('GET_FILE_SIZE_BASE')\n )\n );\n\n text(root.ref.fileName, formatFilename(root.query('GET_ITEM_NAME', props.id)));\n };\n\n var updateFileSizeOnError = function updateFileSizeOnError(_ref3) {\n var root = _ref3.root,\n props = _ref3.props;\n \u002F\u002F if size is available don't fallback to unknown size message\n if (isInt(root.query('GET_ITEM_SIZE', props.id))) {\n return;\n }\n\n text(root.ref.fileSize, root.query('GET_LABEL_FILE_SIZE_NOT_AVAILABLE'));\n };\n\n var fileInfo = createView({\n name: 'file-info',\n ignoreRect: true,\n ignoreRectUpdate: true,\n write: createRoute({\n DID_LOAD_ITEM: updateFile,\n DID_UPDATE_ITEM_META: updateFile,\n DID_THROW_ITEM_LOAD_ERROR: updateFileSizeOnError,\n DID_THROW_ITEM_INVALID: updateFileSizeOnError,\n }),\n\n didCreateView: function didCreateView(root) {\n applyFilters('CREATE_VIEW', Object.assign({}, root, { view: root }));\n },\n create: create$2,\n mixins: {\n styles: ['translateX', 'translateY'],\n animations: {\n translateX: 'spring',\n translateY: 'spring',\n },\n },\n });\n\n var toPercentage = function toPercentage(value) {\n return Math.round(value * 100);\n };\n\n var create$3 = function create(_ref) {\n var root = _ref.root;\n\n \u002F\u002F main status\n var main = createElement$1('span');\n main.className = 'filepond--file-status-main';\n root.appendChild(main);\n root.ref.main = main;\n\n \u002F\u002F sub status\n var sub = createElement$1('span');\n sub.className = 'filepond--file-status-sub';\n root.appendChild(sub);\n root.ref.sub = sub;\n\n didSetItemLoadProgress({ root: root, action: { progress: null } });\n };\n\n var didSetItemLoadProgress = function didSetItemLoadProgress(_ref2) {\n var root = _ref2.root,\n action = _ref2.action;\n var title =\n action.progress === null\n ? root.query('GET_LABEL_FILE_LOADING')\n : root.query('GET_LABEL_FILE_LOADING') + ' ' + toPercentage(action.progress) + '%';\n\n text(root.ref.main, title);\n text(root.ref.sub, root.query('GET_LABEL_TAP_TO_CANCEL'));\n };\n\n var didSetItemProcessProgress = function didSetItemProcessProgress(_ref3) {\n var root = _ref3.root,\n action = _ref3.action;\n var title =\n action.progress === null\n ? root.query('GET_LABEL_FILE_PROCESSING')\n : root.query('GET_LABEL_FILE_PROCESSING') +\n ' ' +\n toPercentage(action.progress) +\n '%';\n\n text(root.ref.main, title);\n text(root.ref.sub, root.query('GET_LABEL_TAP_TO_CANCEL'));\n };\n\n var didRequestItemProcessing = function didRequestItemProcessing(_ref4) {\n var root = _ref4.root;\n text(root.ref.main, root.query('GET_LABEL_FILE_PROCESSING'));\n text(root.ref.sub, root.query('GET_LABEL_TAP_TO_CANCEL'));\n };\n\n var didAbortItemProcessing = function didAbortItemProcessing(_ref5) {\n var root = _ref5.root;\n text(root.ref.main, root.query('GET_LABEL_FILE_PROCESSING_ABORTED'));\n text(root.ref.sub, root.query('GET_LABEL_TAP_TO_RETRY'));\n };\n\n var didCompleteItemProcessing = function didCompleteItemProcessing(_ref6) {\n var root = _ref6.root;\n text(root.ref.main, root.query('GET_LABEL_FILE_PROCESSING_COMPLETE'));\n text(root.ref.sub, root.query('GET_LABEL_TAP_TO_UNDO'));\n };\n\n var clear = function clear(_ref7) {\n var root = _ref7.root;\n text(root.ref.main, '');\n text(root.ref.sub, '');\n };\n\n var error = function error(_ref8) {\n var root = _ref8.root,\n action = _ref8.action;\n text(root.ref.main, action.status.main);\n text(root.ref.sub, action.status.sub);\n };\n\n var fileStatus = createView({\n name: 'file-status',\n ignoreRect: true,\n ignoreRectUpdate: true,\n write: createRoute({\n DID_LOAD_ITEM: clear,\n DID_REVERT_ITEM_PROCESSING: clear,\n DID_REQUEST_ITEM_PROCESSING: didRequestItemProcessing,\n DID_ABORT_ITEM_PROCESSING: didAbortItemProcessing,\n DID_COMPLETE_ITEM_PROCESSING: didCompleteItemProcessing,\n DID_UPDATE_ITEM_PROCESS_PROGRESS: didSetItemProcessProgress,\n DID_UPDATE_ITEM_LOAD_PROGRESS: didSetItemLoadProgress,\n DID_THROW_ITEM_LOAD_ERROR: error,\n DID_THROW_ITEM_INVALID: error,\n DID_THROW_ITEM_PROCESSING_ERROR: error,\n DID_THROW_ITEM_PROCESSING_REVERT_ERROR: error,\n DID_THROW_ITEM_REMOVE_ERROR: error,\n }),\n\n didCreateView: function didCreateView(root) {\n applyFilters('CREATE_VIEW', Object.assign({}, root, { view: root }));\n },\n create: create$3,\n mixins: {\n styles: ['translateX', 'translateY', 'opacity'],\n animations: {\n opacity: { type: 'tween', duration: 250 },\n translateX: 'spring',\n translateY: 'spring',\n },\n },\n });\n\n \u002F**\n * Button definitions for the file view\n *\u002F\n\n var Buttons = {\n AbortItemLoad: {\n label: 'GET_LABEL_BUTTON_ABORT_ITEM_LOAD',\n action: 'ABORT_ITEM_LOAD',\n className: 'filepond--action-abort-item-load',\n align: 'LOAD_INDICATOR_POSITION', \u002F\u002F right\n },\n RetryItemLoad: {\n label: 'GET_LABEL_BUTTON_RETRY_ITEM_LOAD',\n action: 'RETRY_ITEM_LOAD',\n icon: 'GET_ICON_RETRY',\n className: 'filepond--action-retry-item-load',\n align: 'BUTTON_PROCESS_ITEM_POSITION', \u002F\u002F right\n },\n RemoveItem: {\n label: 'GET_LABEL_BUTTON_REMOVE_ITEM',\n action: 'REQUEST_REMOVE_ITEM',\n icon: 'GET_ICON_REMOVE',\n className: 'filepond--action-remove-item',\n align: 'BUTTON_REMOVE_ITEM_POSITION', \u002F\u002F left\n },\n ProcessItem: {\n label: 'GET_LABEL_BUTTON_PROCESS_ITEM',\n action: 'REQUEST_ITEM_PROCESSING',\n icon: 'GET_ICON_PROCESS',\n className: 'filepond--action-process-item',\n align: 'BUTTON_PROCESS_ITEM_POSITION', \u002F\u002F right\n },\n AbortItemProcessing: {\n label: 'GET_LABEL_BUTTON_ABORT_ITEM_PROCESSING',\n action: 'ABORT_ITEM_PROCESSING',\n className: 'filepond--action-abort-item-processing',\n align: 'BUTTON_PROCESS_ITEM_POSITION', \u002F\u002F right\n },\n RetryItemProcessing: {\n label: 'GET_LABEL_BUTTON_RETRY_ITEM_PROCESSING',\n action: 'RETRY_ITEM_PROCESSING',\n icon: 'GET_ICON_RETRY',\n className: 'filepond--action-retry-item-processing',\n align: 'BUTTON_PROCESS_ITEM_POSITION', \u002F\u002F right\n },\n RevertItemProcessing: {\n label: 'GET_LABEL_BUTTON_UNDO_ITEM_PROCESSING',\n action: 'REQUEST_REVERT_ITEM_PROCESSING',\n icon: 'GET_ICON_UNDO',\n className: 'filepond--action-revert-item-processing',\n align: 'BUTTON_PROCESS_ITEM_POSITION', \u002F\u002F right\n },\n };\n\n \u002F\u002F make a list of buttons, we can then remove buttons from this list if they're disabled\n var ButtonKeys = [];\n forin(Buttons, function(key) {\n ButtonKeys.push(key);\n });\n\n var calculateFileInfoOffset = function calculateFileInfoOffset(root) {\n if (getRemoveIndicatorAligment(root) === 'right') return 0;\n var buttonRect = root.ref.buttonRemoveItem.rect.element;\n return buttonRect.hidden ? null : buttonRect.width + buttonRect.left;\n };\n\n var calculateButtonWidth = function calculateButtonWidth(root) {\n var buttonRect = root.ref.buttonAbortItemLoad.rect.element;\n return buttonRect.width;\n };\n\n \u002F\u002F Force on full pixels so text stays crips\n var calculateFileVerticalCenterOffset = function calculateFileVerticalCenterOffset(root) {\n return Math.floor(root.ref.buttonRemoveItem.rect.element.height \u002F 4);\n };\n var calculateFileHorizontalCenterOffset = function calculateFileHorizontalCenterOffset(root) {\n return Math.floor(root.ref.buttonRemoveItem.rect.element.left \u002F 2);\n };\n\n var getLoadIndicatorAlignment = function getLoadIndicatorAlignment(root) {\n return root.query('GET_STYLE_LOAD_INDICATOR_POSITION');\n };\n var getProcessIndicatorAlignment = function getProcessIndicatorAlignment(root) {\n return root.query('GET_STYLE_PROGRESS_INDICATOR_POSITION');\n };\n var getRemoveIndicatorAligment = function getRemoveIndicatorAligment(root) {\n return root.query('GET_STYLE_BUTTON_REMOVE_ITEM_POSITION');\n };\n\n var DefaultStyle = {\n buttonAbortItemLoad: { opacity: 0 },\n buttonRetryItemLoad: { opacity: 0 },\n buttonRemoveItem: { opacity: 0 },\n buttonProcessItem: { opacity: 0 },\n buttonAbortItemProcessing: { opacity: 0 },\n buttonRetryItemProcessing: { opacity: 0 },\n buttonRevertItemProcessing: { opacity: 0 },\n loadProgressIndicator: { opacity: 0, align: getLoadIndicatorAlignment },\n processProgressIndicator: { opacity: 0, align: getProcessIndicatorAlignment },\n processingCompleteIndicator: { opacity: 0, scaleX: 0.75, scaleY: 0.75 },\n info: { translateX: 0, translateY: 0, opacity: 0 },\n status: { translateX: 0, translateY: 0, opacity: 0 },\n };\n\n var IdleStyle = {\n buttonRemoveItem: { opacity: 1 },\n buttonProcessItem: { opacity: 1 },\n info: { translateX: calculateFileInfoOffset },\n status: { translateX: calculateFileInfoOffset },\n };\n\n var ProcessingStyle = {\n buttonAbortItemProcessing: { opacity: 1 },\n processProgressIndicator: { opacity: 1 },\n status: { opacity: 1 },\n };\n\n var StyleMap = {\n DID_THROW_ITEM_INVALID: {\n buttonRemoveItem: { opacity: 1 },\n info: { translateX: calculateFileInfoOffset },\n status: { translateX: calculateFileInfoOffset, opacity: 1 },\n },\n\n DID_START_ITEM_LOAD: {\n buttonAbortItemLoad: { opacity: 1 },\n loadProgressIndicator: { opacity: 1 },\n status: { opacity: 1 },\n },\n\n DID_THROW_ITEM_LOAD_ERROR: {\n buttonRetryItemLoad: { opacity: 1 },\n buttonRemoveItem: { opacity: 1 },\n info: { translateX: calculateFileInfoOffset },\n status: { opacity: 1 },\n },\n\n DID_START_ITEM_REMOVE: {\n processProgressIndicator: { opacity: 1, align: getRemoveIndicatorAligment },\n info: { translateX: calculateFileInfoOffset },\n status: { opacity: 0 },\n },\n\n DID_THROW_ITEM_REMOVE_ERROR: {\n processProgressIndicator: { opacity: 0, align: getRemoveIndicatorAligment },\n buttonRemoveItem: { opacity: 1 },\n info: { translateX: calculateFileInfoOffset },\n status: { opacity: 1, translateX: calculateFileInfoOffset },\n },\n\n DID_LOAD_ITEM: IdleStyle,\n DID_LOAD_LOCAL_ITEM: {\n buttonRemoveItem: { opacity: 1 },\n info: { translateX: calculateFileInfoOffset },\n status: { translateX: calculateFileInfoOffset },\n },\n\n DID_START_ITEM_PROCESSING: ProcessingStyle,\n DID_REQUEST_ITEM_PROCESSING: ProcessingStyle,\n DID_UPDATE_ITEM_PROCESS_PROGRESS: ProcessingStyle,\n DID_COMPLETE_ITEM_PROCESSING: {\n buttonRevertItemProcessing: { opacity: 1 },\n info: { opacity: 1 },\n status: { opacity: 1 },\n },\n\n DID_THROW_ITEM_PROCESSING_ERROR: {\n buttonRemoveItem: { opacity: 1 },\n buttonRetryItemProcessing: { opacity: 1 },\n status: { opacity: 1 },\n info: { translateX: calculateFileInfoOffset },\n },\n\n DID_THROW_ITEM_PROCESSING_REVERT_ERROR: {\n buttonRevertItemProcessing: { opacity: 1 },\n status: { opacity: 1 },\n info: { opacity: 1 },\n },\n\n DID_ABORT_ITEM_PROCESSING: {\n buttonRemoveItem: { opacity: 1 },\n buttonProcessItem: { opacity: 1 },\n info: { translateX: calculateFileInfoOffset },\n status: { opacity: 1 },\n },\n\n DID_REVERT_ITEM_PROCESSING: IdleStyle,\n };\n\n \u002F\u002F complete indicator view\n var processingCompleteIndicatorView = createView({\n create: function create(_ref) {\n var root = _ref.root;\n root.element.innerHTML = root.query('GET_ICON_DONE');\n },\n name: 'processing-complete-indicator',\n ignoreRect: true,\n mixins: {\n styles: ['scaleX', 'scaleY', 'opacity'],\n animations: {\n scaleX: 'spring',\n scaleY: 'spring',\n opacity: { type: 'tween', duration: 250 },\n },\n },\n });\n\n \u002F**\n * Creates the file view\n *\u002F\n var create$4 = function create(_ref2) {\n var root = _ref2.root,\n props = _ref2.props;\n \u002F\u002F copy Buttons object\n var LocalButtons = Object.keys(Buttons).reduce(function(prev, curr) {\n prev[curr] = Object.assign({}, Buttons[curr]);\n return prev;\n }, {});\n var id = props.id;\n\n \u002F\u002F allow reverting upload\n var allowRevert = root.query('GET_ALLOW_REVERT');\n\n \u002F\u002F allow remove file\n var allowRemove = root.query('GET_ALLOW_REMOVE');\n\n \u002F\u002F allow processing upload\n var allowProcess = root.query('GET_ALLOW_PROCESS');\n\n \u002F\u002F is instant uploading, need this to determine the icon of the undo button\n var instantUpload = root.query('GET_INSTANT_UPLOAD');\n\n \u002F\u002F is async set up\n var isAsync = root.query('IS_ASYNC');\n\n \u002F\u002F should align remove item buttons\n var alignRemoveItemButton = root.query('GET_STYLE_BUTTON_REMOVE_ITEM_ALIGN');\n\n \u002F\u002F enabled buttons array\n var buttonFilter;\n if (isAsync) {\n if (allowProcess && !allowRevert) {\n \u002F\u002F only remove revert button\n buttonFilter = function buttonFilter(key) {\n return !\u002FRevertItemProcessing\u002F.test(key);\n };\n } else if (!allowProcess && allowRevert) {\n \u002F\u002F only remove process button\n buttonFilter = function buttonFilter(key) {\n return !\u002FProcessItem|RetryItemProcessing|AbortItemProcessing\u002F.test(key);\n };\n } else if (!allowProcess && !allowRevert) {\n \u002F\u002F remove all process buttons\n buttonFilter = function buttonFilter(key) {\n return !\u002FProcess\u002F.test(key);\n };\n }\n } else {\n \u002F\u002F no process controls available\n buttonFilter = function buttonFilter(key) {\n return !\u002FProcess\u002F.test(key);\n };\n }\n\n var enabledButtons = buttonFilter ? ButtonKeys.filter(buttonFilter) : ButtonKeys.concat();\n\n \u002F\u002F update icon and label for revert button when instant uploading\n if (instantUpload && allowRevert) {\n LocalButtons['RevertItemProcessing'].label = 'GET_LABEL_BUTTON_REMOVE_ITEM';\n LocalButtons['RevertItemProcessing'].icon = 'GET_ICON_REMOVE';\n }\n\n \u002F\u002F remove last button (revert) if not allowed\n if (isAsync && !allowRevert) {\n var map = StyleMap['DID_COMPLETE_ITEM_PROCESSING'];\n map.info.translateX = calculateFileHorizontalCenterOffset;\n map.info.translateY = calculateFileVerticalCenterOffset;\n map.status.translateY = calculateFileVerticalCenterOffset;\n map.processingCompleteIndicator = { opacity: 1, scaleX: 1, scaleY: 1 };\n }\n\n \u002F\u002F should align center\n if (isAsync && !allowProcess) {\n [\n 'DID_START_ITEM_PROCESSING',\n 'DID_REQUEST_ITEM_PROCESSING',\n 'DID_UPDATE_ITEM_PROCESS_PROGRESS',\n 'DID_THROW_ITEM_PROCESSING_ERROR',\n ].forEach(function(key) {\n StyleMap[key].status.translateY = calculateFileVerticalCenterOffset;\n });\n StyleMap['DID_THROW_ITEM_PROCESSING_ERROR'].status.translateX = calculateButtonWidth;\n }\n\n \u002F\u002F move remove button to right\n if (alignRemoveItemButton && allowRevert) {\n LocalButtons['RevertItemProcessing'].align = 'BUTTON_REMOVE_ITEM_POSITION';\n var _map = StyleMap['DID_COMPLETE_ITEM_PROCESSING'];\n _map.info.translateX = calculateFileInfoOffset;\n _map.status.translateY = calculateFileVerticalCenterOffset;\n _map.processingCompleteIndicator = { opacity: 1, scaleX: 1, scaleY: 1 };\n }\n\n \u002F\u002F show\u002Fhide RemoveItem button\n if (!allowRemove) {\n LocalButtons['RemoveItem'].disabled = true;\n }\n\n \u002F\u002F create the button views\n forin(LocalButtons, function(key, definition) {\n \u002F\u002F create button\n var buttonView = root.createChildView(fileActionButton, {\n label: root.query(definition.label),\n icon: root.query(definition.icon),\n opacity: 0,\n });\n\n \u002F\u002F should be appended?\n if (enabledButtons.includes(key)) {\n root.appendChildView(buttonView);\n }\n\n \u002F\u002F toggle\n if (definition.disabled) {\n buttonView.element.setAttribute('disabled', 'disabled');\n buttonView.element.setAttribute('hidden', 'hidden');\n }\n\n \u002F\u002F add position attribute\n buttonView.element.dataset.align = root.query('GET_STYLE_' + definition.align);\n\n \u002F\u002F add class\n buttonView.element.classList.add(definition.className);\n\n \u002F\u002F handle interactions\n buttonView.on('click', function(e) {\n e.stopPropagation();\n if (definition.disabled) return;\n root.dispatch(definition.action, { query: id });\n });\n\n \u002F\u002F set reference\n root.ref['button' + key] = buttonView;\n });\n\n \u002F\u002F checkmark\n root.ref.processingCompleteIndicator = root.appendChildView(\n root.createChildView(processingCompleteIndicatorView)\n );\n\n root.ref.processingCompleteIndicator.element.dataset.align = root.query(\n 'GET_STYLE_BUTTON_PROCESS_ITEM_POSITION'\n );\n\n \u002F\u002F create file info view\n root.ref.info = root.appendChildView(root.createChildView(fileInfo, { id: id }));\n\n \u002F\u002F create file status view\n root.ref.status = root.appendChildView(root.createChildView(fileStatus, { id: id }));\n\n \u002F\u002F add progress indicators\n var loadIndicatorView = root.appendChildView(\n root.createChildView(progressIndicator, {\n opacity: 0,\n align: root.query('GET_STYLE_LOAD_INDICATOR_POSITION'),\n })\n );\n\n loadIndicatorView.element.classList.add('filepond--load-indicator');\n root.ref.loadProgressIndicator = loadIndicatorView;\n\n var progressIndicatorView = root.appendChildView(\n root.createChildView(progressIndicator, {\n opacity: 0,\n align: root.query('GET_STYLE_PROGRESS_INDICATOR_POSITION'),\n })\n );\n\n progressIndicatorView.element.classList.add('filepond--process-indicator');\n root.ref.processProgressIndicator = progressIndicatorView;\n\n \u002F\u002F current active styles\n root.ref.activeStyles = [];\n };\n\n var write$2 = function write(_ref3) {\n var root = _ref3.root,\n actions = _ref3.actions,\n props = _ref3.props;\n \u002F\u002F route actions\n route({ root: root, actions: actions, props: props });\n\n \u002F\u002F select last state change action\n var action = actions\n .concat()\n .filter(function(action) {\n return \u002F^DID_\u002F.test(action.type);\n })\n .reverse()\n .find(function(action) {\n return StyleMap[action.type];\n });\n\n \u002F\u002F a new action happened, let's get the matching styles\n if (action) {\n \u002F\u002F define new active styles\n root.ref.activeStyles = [];\n\n var stylesToApply = StyleMap[action.type];\n forin(DefaultStyle, function(name, defaultStyles) {\n \u002F\u002F get reference to control\n var control = root.ref[name];\n\n \u002F\u002F loop over all styles for this control\n forin(defaultStyles, function(key, defaultValue) {\n var value =\n stylesToApply[name] && typeof stylesToApply[name][key] !== 'undefined'\n ? stylesToApply[name][key]\n : defaultValue;\n root.ref.activeStyles.push({ control: control, key: key, value: value });\n });\n });\n }\n\n \u002F\u002F apply active styles to element\n root.ref.activeStyles.forEach(function(_ref4) {\n var control = _ref4.control,\n key = _ref4.key,\n value = _ref4.value;\n control[key] = typeof value === 'function' ? value(root) : value;\n });\n };\n\n var route = createRoute({\n DID_SET_LABEL_BUTTON_ABORT_ITEM_PROCESSING: function DID_SET_LABEL_BUTTON_ABORT_ITEM_PROCESSING(\n _ref5\n ) {\n var root = _ref5.root,\n action = _ref5.action;\n root.ref.buttonAbortItemProcessing.label = action.value;\n },\n DID_SET_LABEL_BUTTON_ABORT_ITEM_LOAD: function DID_SET_LABEL_BUTTON_ABORT_ITEM_LOAD(_ref6) {\n var root = _ref6.root,\n action = _ref6.action;\n root.ref.buttonAbortItemLoad.label = action.value;\n },\n DID_SET_LABEL_BUTTON_ABORT_ITEM_REMOVAL: function DID_SET_LABEL_BUTTON_ABORT_ITEM_REMOVAL(\n _ref7\n ) {\n var root = _ref7.root,\n action = _ref7.action;\n root.ref.buttonAbortItemRemoval.label = action.value;\n },\n DID_REQUEST_ITEM_PROCESSING: function DID_REQUEST_ITEM_PROCESSING(_ref8) {\n var root = _ref8.root;\n root.ref.processProgressIndicator.spin = true;\n root.ref.processProgressIndicator.progress = 0;\n },\n DID_START_ITEM_LOAD: function DID_START_ITEM_LOAD(_ref9) {\n var root = _ref9.root;\n root.ref.loadProgressIndicator.spin = true;\n root.ref.loadProgressIndicator.progress = 0;\n },\n DID_START_ITEM_REMOVE: function DID_START_ITEM_REMOVE(_ref10) {\n var root = _ref10.root;\n root.ref.processProgressIndicator.spin = true;\n root.ref.processProgressIndicator.progress = 0;\n },\n DID_UPDATE_ITEM_LOAD_PROGRESS: function DID_UPDATE_ITEM_LOAD_PROGRESS(_ref11) {\n var root = _ref11.root,\n action = _ref11.action;\n root.ref.loadProgressIndicator.spin = false;\n root.ref.loadProgressIndicator.progress = action.progress;\n },\n DID_UPDATE_ITEM_PROCESS_PROGRESS: function DID_UPDATE_ITEM_PROCESS_PROGRESS(_ref12) {\n var root = _ref12.root,\n action = _ref12.action;\n root.ref.processProgressIndicator.spin = false;\n root.ref.processProgressIndicator.progress = action.progress;\n },\n });\n\n var file = createView({\n create: create$4,\n write: write$2,\n didCreateView: function didCreateView(root) {\n applyFilters('CREATE_VIEW', Object.assign({}, root, { view: root }));\n },\n name: 'file',\n });\n\n \u002F**\n * Creates the file view\n *\u002F\n var create$5 = function create(_ref) {\n var root = _ref.root,\n props = _ref.props;\n\n \u002F\u002F filename\n root.ref.fileName = createElement$1('legend');\n root.appendChild(root.ref.fileName);\n\n \u002F\u002F file appended\n root.ref.file = root.appendChildView(root.createChildView(file, { id: props.id }));\n\n \u002F\u002F data has moved to data.js\n root.ref.data = false;\n };\n\n \u002F**\n * Data storage\n *\u002F\n var didLoadItem = function didLoadItem(_ref2) {\n var root = _ref2.root,\n props = _ref2.props;\n \u002F\u002F updates the legend of the fieldset so screenreaders can better group buttons\n text(root.ref.fileName, formatFilename(root.query('GET_ITEM_NAME', props.id)));\n };\n\n var fileWrapper = createView({\n create: create$5,\n ignoreRect: true,\n write: createRoute({\n DID_LOAD_ITEM: didLoadItem,\n }),\n\n didCreateView: function didCreateView(root) {\n applyFilters('CREATE_VIEW', Object.assign({}, root, { view: root }));\n },\n tag: 'fieldset',\n name: 'file-wrapper',\n });\n\n var PANEL_SPRING_PROPS = { type: 'spring', damping: 0.6, mass: 7 };\n\n var create$6 = function create(_ref) {\n var root = _ref.root,\n props = _ref.props;\n [\n {\n name: 'top',\n },\n\n {\n name: 'center',\n props: {\n translateY: null,\n scaleY: null,\n },\n\n mixins: {\n animations: {\n scaleY: PANEL_SPRING_PROPS,\n },\n\n styles: ['translateY', 'scaleY'],\n },\n },\n\n {\n name: 'bottom',\n props: {\n translateY: null,\n },\n\n mixins: {\n animations: {\n translateY: PANEL_SPRING_PROPS,\n },\n\n styles: ['translateY'],\n },\n },\n ].forEach(function(section) {\n createSection(root, section, props.name);\n });\n\n root.element.classList.add('filepond--' + props.name);\n\n root.ref.scalable = null;\n };\n\n var createSection = function createSection(root, section, className) {\n var viewConstructor = createView({\n name: 'panel-' + section.name + ' filepond--' + className,\n mixins: section.mixins,\n ignoreRectUpdate: true,\n });\n\n var view = root.createChildView(viewConstructor, section.props);\n\n root.ref[section.name] = root.appendChildView(view);\n };\n\n var write$3 = function write(_ref2) {\n var root = _ref2.root,\n props = _ref2.props;\n\n \u002F\u002F update scalable state\n if (root.ref.scalable === null || props.scalable !== root.ref.scalable) {\n root.ref.scalable = isBoolean(props.scalable) ? props.scalable : true;\n root.element.dataset.scalable = root.ref.scalable;\n }\n\n \u002F\u002F no height, can't set\n if (!props.height) return;\n\n \u002F\u002F get child rects\n var topRect = root.ref.top.rect.element;\n var bottomRect = root.ref.bottom.rect.element;\n\n \u002F\u002F make sure height never is smaller than bottom and top seciton heights combined (will probably never happen, but who knows)\n var height = Math.max(topRect.height + bottomRect.height, props.height);\n\n \u002F\u002F offset center part\n root.ref.center.translateY = topRect.height;\n\n \u002F\u002F scale center part\n \u002F\u002F use math ceil to prevent transparent lines because of rounding errors\n root.ref.center.scaleY = (height - topRect.height - bottomRect.height) \u002F 100;\n\n \u002F\u002F offset bottom part\n root.ref.bottom.translateY = height - bottomRect.height;\n };\n\n var panel = createView({\n name: 'panel',\n read: function read(_ref3) {\n var root = _ref3.root,\n props = _ref3.props;\n return (props.heightCurrent = root.ref.bottom.translateY);\n },\n write: write$3,\n create: create$6,\n ignoreRect: true,\n mixins: {\n apis: ['height', 'heightCurrent', 'scalable'],\n },\n });\n\n var createDragHelper = function createDragHelper(items) {\n var itemIds = items.map(function(item) {\n return item.id;\n });\n var prevIndex = undefined;\n return {\n setIndex: function setIndex(index) {\n prevIndex = index;\n },\n getIndex: function getIndex() {\n return prevIndex;\n },\n getItemIndex: function getItemIndex(item) {\n return itemIds.indexOf(item.id);\n },\n };\n };\n\n var ITEM_TRANSLATE_SPRING = {\n type: 'spring',\n stiffness: 0.75,\n damping: 0.45,\n mass: 10,\n };\n\n var ITEM_SCALE_SPRING = 'spring';\n\n var StateMap = {\n DID_START_ITEM_LOAD: 'busy',\n DID_UPDATE_ITEM_LOAD_PROGRESS: 'loading',\n DID_THROW_ITEM_INVALID: 'load-invalid',\n DID_THROW_ITEM_LOAD_ERROR: 'load-error',\n DID_LOAD_ITEM: 'idle',\n DID_THROW_ITEM_REMOVE_ERROR: 'remove-error',\n DID_START_ITEM_REMOVE: 'busy',\n DID_START_ITEM_PROCESSING: 'busy processing',\n DID_REQUEST_ITEM_PROCESSING: 'busy processing',\n DID_UPDATE_ITEM_PROCESS_PROGRESS: 'processing',\n DID_COMPLETE_ITEM_PROCESSING: 'processing-complete',\n DID_THROW_ITEM_PROCESSING_ERROR: 'processing-error',\n DID_THROW_ITEM_PROCESSING_REVERT_ERROR: 'processing-revert-error',\n DID_ABORT_ITEM_PROCESSING: 'cancelled',\n DID_REVERT_ITEM_PROCESSING: 'idle',\n };\n\n \u002F**\n * Creates the file view\n *\u002F\n var create$7 = function create(_ref) {\n var root = _ref.root,\n props = _ref.props;\n\n \u002F\u002F select\n root.ref.handleClick = function(e) {\n return root.dispatch('DID_ACTIVATE_ITEM', { id: props.id });\n };\n\n \u002F\u002F set id\n root.element.id = 'filepond--item-' + props.id;\n root.element.addEventListener('click', root.ref.handleClick);\n\n \u002F\u002F file view\n root.ref.container = root.appendChildView(\n root.createChildView(fileWrapper, { id: props.id })\n );\n\n \u002F\u002F file panel\n root.ref.panel = root.appendChildView(root.createChildView(panel, { name: 'item-panel' }));\n\n \u002F\u002F default start height\n root.ref.panel.height = null;\n\n \u002F\u002F by default not marked for removal\n props.markedForRemoval = false;\n\n \u002F\u002F if not allowed to reorder file items, exit here\n if (!root.query('GET_ALLOW_REORDER')) return;\n\n \u002F\u002F set to idle so shows grab cursor\n root.element.dataset.dragState = 'idle';\n\n var grab = function grab(e) {\n if (!e.isPrimary) return;\n\n var removedActivateListener = false;\n\n var origin = {\n x: e.pageX,\n y: e.pageY,\n };\n\n props.dragOrigin = {\n x: root.translateX,\n y: root.translateY,\n };\n\n props.dragCenter = {\n x: e.offsetX,\n y: e.offsetY,\n };\n\n var dragState = createDragHelper(root.query('GET_ACTIVE_ITEMS'));\n\n root.dispatch('DID_GRAB_ITEM', { id: props.id, dragState: dragState });\n\n var drag = function drag(e) {\n if (!e.isPrimary) return;\n\n e.stopPropagation();\n e.preventDefault();\n\n props.dragOffset = {\n x: e.pageX - origin.x,\n y: e.pageY - origin.y,\n };\n\n \u002F\u002F if dragged stop listening to clicks, will re-add when done dragging\n var dist =\n props.dragOffset.x * props.dragOffset.x +\n props.dragOffset.y * props.dragOffset.y;\n if (dist \u003E 16 && !removedActivateListener) {\n removedActivateListener = true;\n root.element.removeEventListener('click', root.ref.handleClick);\n }\n\n root.dispatch('DID_DRAG_ITEM', { id: props.id, dragState: dragState });\n };\n\n var drop = function drop(e) {\n if (!e.isPrimary) return;\n\n document.removeEventListener('pointermove', drag);\n document.removeEventListener('pointerup', drop);\n\n props.dragOffset = {\n x: e.pageX - origin.x,\n y: e.pageY - origin.y,\n };\n\n root.dispatch('DID_DROP_ITEM', { id: props.id, dragState: dragState });\n\n \u002F\u002F start listening to clicks again\n if (removedActivateListener) {\n setTimeout(function() {\n return root.element.addEventListener('click', root.ref.handleClick);\n }, 0);\n }\n };\n\n document.addEventListener('pointermove', drag);\n document.addEventListener('pointerup', drop);\n };\n\n root.element.addEventListener('pointerdown', grab);\n };\n\n var route$1 = createRoute({\n DID_UPDATE_PANEL_HEIGHT: function DID_UPDATE_PANEL_HEIGHT(_ref2) {\n var root = _ref2.root,\n action = _ref2.action;\n root.height = action.height;\n },\n });\n\n var write$4 = createRoute(\n {\n DID_GRAB_ITEM: function DID_GRAB_ITEM(_ref3) {\n var root = _ref3.root,\n props = _ref3.props;\n props.dragOrigin = {\n x: root.translateX,\n y: root.translateY,\n };\n },\n DID_DRAG_ITEM: function DID_DRAG_ITEM(_ref4) {\n var root = _ref4.root;\n root.element.dataset.dragState = 'drag';\n },\n DID_DROP_ITEM: function DID_DROP_ITEM(_ref5) {\n var root = _ref5.root,\n props = _ref5.props;\n props.dragOffset = null;\n props.dragOrigin = null;\n root.element.dataset.dragState = 'drop';\n },\n },\n function(_ref6) {\n var root = _ref6.root,\n actions = _ref6.actions,\n props = _ref6.props,\n shouldOptimize = _ref6.shouldOptimize;\n\n if (root.element.dataset.dragState === 'drop') {\n if (root.scaleX \u003C= 1) {\n root.element.dataset.dragState = 'idle';\n }\n }\n\n \u002F\u002F select last state change action\n var action = actions\n .concat()\n .filter(function(action) {\n return \u002F^DID_\u002F.test(action.type);\n })\n .reverse()\n .find(function(action) {\n return StateMap[action.type];\n });\n\n \u002F\u002F no need to set same state twice\n if (action && action.type !== props.currentState) {\n \u002F\u002F set current state\n props.currentState = action.type;\n\n \u002F\u002F set state\n root.element.dataset.filepondItemState = StateMap[props.currentState] || '';\n }\n\n \u002F\u002F route actions\n var aspectRatio =\n root.query('GET_ITEM_PANEL_ASPECT_RATIO') || root.query('GET_PANEL_ASPECT_RATIO');\n if (!aspectRatio) {\n route$1({ root: root, actions: actions, props: props });\n if (!root.height && root.ref.container.rect.element.height \u003E 0) {\n root.height = root.ref.container.rect.element.height;\n }\n } else if (!shouldOptimize) {\n root.height = root.rect.element.width * aspectRatio;\n }\n\n \u002F\u002F sync panel height with item height\n if (shouldOptimize) {\n root.ref.panel.height = null;\n }\n\n root.ref.panel.height = root.height;\n }\n );\n\n var item = createView({\n create: create$7,\n write: write$4,\n destroy: function destroy(_ref7) {\n var root = _ref7.root,\n props = _ref7.props;\n root.element.removeEventListener('click', root.ref.handleClick);\n root.dispatch('RELEASE_ITEM', { query: props.id });\n },\n tag: 'li',\n name: 'item',\n mixins: {\n apis: [\n 'id',\n 'interactionMethod',\n 'markedForRemoval',\n 'spawnDate',\n 'dragCenter',\n 'dragOrigin',\n 'dragOffset',\n ],\n styles: ['translateX', 'translateY', 'scaleX', 'scaleY', 'opacity', 'height'],\n\n animations: {\n scaleX: ITEM_SCALE_SPRING,\n scaleY: ITEM_SCALE_SPRING,\n translateX: ITEM_TRANSLATE_SPRING,\n translateY: ITEM_TRANSLATE_SPRING,\n opacity: { type: 'tween', duration: 150 },\n },\n },\n });\n\n var getItemsPerRow = function(horizontalSpace, itemWidth) {\n \u002F\u002F add one pixel leeway, when using percentages for item width total items can be 1.99 per row\n\n return Math.max(1, Math.floor((horizontalSpace + 1) \u002F itemWidth));\n };\n\n var getItemIndexByPosition = function getItemIndexByPosition(view, children, positionInView) {\n if (!positionInView) return;\n\n var horizontalSpace = view.rect.element.width;\n \u002F\u002F const children = view.childViews;\n var l = children.length;\n var last = null;\n\n \u002F\u002F -1, don't move items to accomodate (either add to top or bottom)\n if (l === 0 || positionInView.top \u003C children[0].rect.element.top) return -1;\n\n \u002F\u002F let's get the item width\n var item = children[0];\n var itemRect = item.rect.element;\n var itemHorizontalMargin = itemRect.marginLeft + itemRect.marginRight;\n var itemWidth = itemRect.width + itemHorizontalMargin;\n var itemsPerRow = getItemsPerRow(horizontalSpace, itemWidth);\n\n \u002F\u002F stack\n if (itemsPerRow === 1) {\n for (var index = 0; index \u003C l; index++) {\n var child = children[index];\n var childMid = child.rect.outer.top + child.rect.element.height * 0.5;\n if (positionInView.top \u003C childMid) {\n return index;\n }\n }\n return l;\n }\n\n \u002F\u002F grid\n var itemVerticalMargin = itemRect.marginTop + itemRect.marginBottom;\n var itemHeight = itemRect.height + itemVerticalMargin;\n for (var _index = 0; _index \u003C l; _index++) {\n var indexX = _index % itemsPerRow;\n var indexY = Math.floor(_index \u002F itemsPerRow);\n\n var offsetX = indexX * itemWidth;\n var offsetY = indexY * itemHeight;\n\n var itemTop = offsetY - itemRect.marginTop;\n var itemRight = offsetX + itemWidth;\n var itemBottom = offsetY + itemHeight + itemRect.marginBottom;\n\n if (positionInView.top \u003C itemBottom && positionInView.top \u003E itemTop) {\n if (positionInView.left \u003C itemRight) {\n return _index;\n } else if (_index !== l - 1) {\n last = _index;\n } else {\n last = null;\n }\n }\n }\n\n if (last !== null) {\n return last;\n }\n\n return l;\n };\n\n var dropAreaDimensions = {\n height: 0,\n width: 0,\n get getHeight() {\n return this.height;\n },\n set setHeight(val) {\n if (this.height === 0 || val === 0) this.height = val;\n },\n get getWidth() {\n return this.width;\n },\n set setWidth(val) {\n if (this.width === 0 || val === 0) this.width = val;\n },\n setDimensions: function setDimensions(height, width) {\n if (this.height === 0 || height === 0) this.height = height;\n if (this.width === 0 || width === 0) this.width = width;\n },\n };\n\n var create$8 = function create(_ref) {\n var root = _ref.root;\n \u002F\u002F need to set role to list as otherwise it won't be read as a list by VoiceOver\n attr(root.element, 'role', 'list');\n\n root.ref.lastItemSpanwDate = Date.now();\n };\n\n \u002F**\n * Inserts a new item\n * @param root\n * @param action\n *\u002F\n var addItemView = function addItemView(_ref2) {\n var root = _ref2.root,\n action = _ref2.action;\n var id = action.id,\n index = action.index,\n interactionMethod = action.interactionMethod;\n\n root.ref.addIndex = index;\n\n var now = Date.now();\n var spawnDate = now;\n var opacity = 1;\n\n if (interactionMethod !== InteractionMethod.NONE) {\n opacity = 0;\n var cooldown = root.query('GET_ITEM_INSERT_INTERVAL');\n var dist = now - root.ref.lastItemSpanwDate;\n spawnDate = dist \u003C cooldown ? now + (cooldown - dist) : now;\n }\n\n root.ref.lastItemSpanwDate = spawnDate;\n\n root.appendChildView(\n root.createChildView(\n \u002F\u002F view type\n item,\n\n \u002F\u002F props\n {\n spawnDate: spawnDate,\n id: id,\n opacity: opacity,\n interactionMethod: interactionMethod,\n }\n ),\n\n index\n );\n };\n\n var moveItem = function moveItem(item, x, y) {\n var vx = arguments.length \u003E 3 && arguments[3] !== undefined ? arguments[3] : 0;\n var vy = arguments.length \u003E 4 && arguments[4] !== undefined ? arguments[4] : 1;\n \u002F\u002F set to null to remove animation while dragging\n if (item.dragOffset) {\n item.translateX = null;\n item.translateY = null;\n item.translateX = item.dragOrigin.x + item.dragOffset.x;\n item.translateY = item.dragOrigin.y + item.dragOffset.y;\n item.scaleX = 1.025;\n item.scaleY = 1.025;\n } else {\n item.translateX = x;\n item.translateY = y;\n\n if (Date.now() \u003E item.spawnDate) {\n \u002F\u002F reveal element\n if (item.opacity === 0) {\n introItemView(item, x, y, vx, vy);\n }\n\n \u002F\u002F make sure is default scale every frame\n item.scaleX = 1;\n item.scaleY = 1;\n item.opacity = 1;\n }\n }\n };\n\n var introItemView = function introItemView(item, x, y, vx, vy) {\n if (item.interactionMethod === InteractionMethod.NONE) {\n item.translateX = null;\n item.translateX = x;\n item.translateY = null;\n item.translateY = y;\n } else if (item.interactionMethod === InteractionMethod.DROP) {\n item.translateX = null;\n item.translateX = x - vx * 20;\n\n item.translateY = null;\n item.translateY = y - vy * 10;\n\n item.scaleX = 0.8;\n item.scaleY = 0.8;\n } else if (item.interactionMethod === InteractionMethod.BROWSE) {\n item.translateY = null;\n item.translateY = y - 30;\n } else if (item.interactionMethod === InteractionMethod.API) {\n item.translateX = null;\n item.translateX = x - 30;\n item.translateY = null;\n }\n };\n\n \u002F**\n * Removes an existing item\n * @param root\n * @param action\n *\u002F\n var removeItemView = function removeItemView(_ref3) {\n var root = _ref3.root,\n action = _ref3.action;\n var id = action.id;\n\n \u002F\u002F get the view matching the given id\n var view = root.childViews.find(function(child) {\n return child.id === id;\n });\n\n \u002F\u002F if no view found, exit\n if (!view) {\n return;\n }\n\n \u002F\u002F animate view out of view\n view.scaleX = 0.9;\n view.scaleY = 0.9;\n view.opacity = 0;\n\n \u002F\u002F mark for removal\n view.markedForRemoval = true;\n };\n\n var getItemHeight = function getItemHeight(child) {\n return (\n child.rect.element.height +\n child.rect.element.marginBottom * 0.5 +\n child.rect.element.marginTop * 0.5\n );\n };\n var getItemWidth = function getItemWidth(child) {\n return (\n child.rect.element.width +\n child.rect.element.marginLeft * 0.5 +\n child.rect.element.marginRight * 0.5\n );\n };\n\n var dragItem = function dragItem(_ref4) {\n var root = _ref4.root,\n action = _ref4.action;\n var id = action.id,\n dragState = action.dragState;\n\n \u002F\u002F reference to item\n var item = root.query('GET_ITEM', { id: id });\n\n \u002F\u002F get the view matching the given id\n var view = root.childViews.find(function(child) {\n return child.id === id;\n });\n\n var numItems = root.childViews.length;\n var oldIndex = dragState.getItemIndex(item);\n\n \u002F\u002F if no view found, exit\n if (!view) return;\n\n var dragPosition = {\n x: view.dragOrigin.x + view.dragOffset.x + view.dragCenter.x,\n y: view.dragOrigin.y + view.dragOffset.y + view.dragCenter.y,\n };\n\n \u002F\u002F get drag area dimensions\n var dragHeight = getItemHeight(view);\n var dragWidth = getItemWidth(view);\n\n \u002F\u002F get rows and columns (There will always be at least one row and one column if a file is present)\n var cols = Math.floor(root.rect.outer.width \u002F dragWidth);\n if (cols \u003E numItems) cols = numItems;\n\n \u002F\u002F rows are used to find when we have left the preview area bounding box\n var rows = Math.floor(numItems \u002F cols + 1);\n\n dropAreaDimensions.setHeight = dragHeight * rows;\n dropAreaDimensions.setWidth = dragWidth * cols;\n\n \u002F\u002F get new index of dragged item\n var location = {\n y: Math.floor(dragPosition.y \u002F dragHeight),\n x: Math.floor(dragPosition.x \u002F dragWidth),\n getGridIndex: function getGridIndex() {\n if (\n dragPosition.y \u003E dropAreaDimensions.getHeight ||\n dragPosition.y \u003C 0 ||\n dragPosition.x \u003E dropAreaDimensions.getWidth ||\n dragPosition.x \u003C 0\n )\n return oldIndex;\n return this.y * cols + this.x;\n },\n getColIndex: function getColIndex() {\n var items = root.query('GET_ACTIVE_ITEMS');\n var visibleChildren = root.childViews.filter(function(child) {\n return child.rect.element.height;\n });\n var children = items.map(function(item) {\n return visibleChildren.find(function(childView) {\n return childView.id === item.id;\n });\n });\n\n var currentIndex = children.findIndex(function(child) {\n return child === view;\n });\n var dragHeight = getItemHeight(view);\n var l = children.length;\n var idx = l;\n var childHeight = 0;\n var childBottom = 0;\n var childTop = 0;\n for (var i = 0; i \u003C l; i++) {\n childHeight = getItemHeight(children[i]);\n childTop = childBottom;\n childBottom = childTop + childHeight;\n if (dragPosition.y \u003C childBottom) {\n if (currentIndex \u003E i) {\n if (dragPosition.y \u003C childTop + dragHeight) {\n idx = i;\n break;\n }\n continue;\n }\n idx = i;\n break;\n }\n }\n return idx;\n },\n };\n\n \u002F\u002F get new index\n var index = cols \u003E 1 ? location.getGridIndex() : location.getColIndex();\n root.dispatch('MOVE_ITEM', { query: view, index: index });\n\n \u002F\u002F if the index of the item changed, dispatch reorder action\n var currentIndex = dragState.getIndex();\n\n if (currentIndex === undefined || currentIndex !== index) {\n dragState.setIndex(index);\n\n if (currentIndex === undefined) return;\n\n root.dispatch('DID_REORDER_ITEMS', {\n items: root.query('GET_ACTIVE_ITEMS'),\n origin: oldIndex,\n target: index,\n });\n }\n };\n\n \u002F**\n * Setup action routes\n *\u002F\n var route$2 = createRoute({\n DID_ADD_ITEM: addItemView,\n DID_REMOVE_ITEM: removeItemView,\n DID_DRAG_ITEM: dragItem,\n });\n\n \u002F**\n * Write to view\n * @param root\n * @param actions\n * @param props\n *\u002F\n var write$5 = function write(_ref5) {\n var root = _ref5.root,\n props = _ref5.props,\n actions = _ref5.actions,\n shouldOptimize = _ref5.shouldOptimize;\n \u002F\u002F route actions\n route$2({ root: root, props: props, actions: actions });\n var dragCoordinates = props.dragCoordinates;\n\n \u002F\u002F available space on horizontal axis\n var horizontalSpace = root.rect.element.width;\n\n \u002F\u002F only draw children that have dimensions\n var visibleChildren = root.childViews.filter(function(child) {\n return child.rect.element.height;\n });\n\n \u002F\u002F sort based on current active items\n var children = root\n .query('GET_ACTIVE_ITEMS')\n .map(function(item) {\n return visibleChildren.find(function(child) {\n return child.id === item.id;\n });\n })\n .filter(function(item) {\n return item;\n });\n\n \u002F\u002F get index\n var dragIndex = dragCoordinates\n ? getItemIndexByPosition(root, children, dragCoordinates)\n : null;\n\n \u002F\u002F add index is used to reserve the dropped\u002Fadded item index till the actual item is rendered\n var addIndex = root.ref.addIndex || null;\n\n \u002F\u002F add index no longer needed till possibly next draw\n root.ref.addIndex = null;\n\n var dragIndexOffset = 0;\n var removeIndexOffset = 0;\n var addIndexOffset = 0;\n\n if (children.length === 0) return;\n\n var childRect = children[0].rect.element;\n var itemVerticalMargin = childRect.marginTop + childRect.marginBottom;\n var itemHorizontalMargin = childRect.marginLeft + childRect.marginRight;\n var itemWidth = childRect.width + itemHorizontalMargin;\n var itemHeight = childRect.height + itemVerticalMargin;\n var itemsPerRow = getItemsPerRow(horizontalSpace, itemWidth);\n\n \u002F\u002F stack\n if (itemsPerRow === 1) {\n var offsetY = 0;\n var dragOffset = 0;\n\n children.forEach(function(child, index) {\n if (dragIndex) {\n var dist = index - dragIndex;\n if (dist === -2) {\n dragOffset = -itemVerticalMargin * 0.25;\n } else if (dist === -1) {\n dragOffset = -itemVerticalMargin * 0.75;\n } else if (dist === 0) {\n dragOffset = itemVerticalMargin * 0.75;\n } else if (dist === 1) {\n dragOffset = itemVerticalMargin * 0.25;\n } else {\n dragOffset = 0;\n }\n }\n\n if (shouldOptimize) {\n child.translateX = null;\n child.translateY = null;\n }\n\n if (!child.markedForRemoval) {\n moveItem(child, 0, offsetY + dragOffset);\n }\n\n var itemHeight = child.rect.element.height + itemVerticalMargin;\n\n var visualHeight = itemHeight * (child.markedForRemoval ? child.opacity : 1);\n\n offsetY += visualHeight;\n });\n }\n \u002F\u002F grid\n else {\n var prevX = 0;\n var prevY = 0;\n\n children.forEach(function(child, index) {\n if (index === dragIndex) {\n dragIndexOffset = 1;\n }\n\n if (index === addIndex) {\n addIndexOffset += 1;\n }\n\n if (child.markedForRemoval && child.opacity \u003C 0.5) {\n removeIndexOffset -= 1;\n }\n\n var visualIndex = index + addIndexOffset + dragIndexOffset + removeIndexOffset;\n\n var indexX = visualIndex % itemsPerRow;\n var indexY = Math.floor(visualIndex \u002F itemsPerRow);\n\n var offsetX = indexX * itemWidth;\n var offsetY = indexY * itemHeight;\n\n var vectorX = Math.sign(offsetX - prevX);\n var vectorY = Math.sign(offsetY - prevY);\n\n prevX = offsetX;\n prevY = offsetY;\n\n if (child.markedForRemoval) return;\n\n if (shouldOptimize) {\n child.translateX = null;\n child.translateY = null;\n }\n\n moveItem(child, offsetX, offsetY, vectorX, vectorY);\n });\n }\n };\n\n \u002F**\n * Filters actions that are meant specifically for a certain child of the list\n * @param child\n * @param actions\n *\u002F\n var filterSetItemActions = function filterSetItemActions(child, actions) {\n return actions.filter(function(action) {\n \u002F\u002F if action has an id, filter out actions that don't have this child id\n if (action.data && action.data.id) {\n return child.id === action.data.id;\n }\n\n \u002F\u002F allow all other actions\n return true;\n });\n };\n\n var list = createView({\n create: create$8,\n write: write$5,\n tag: 'ul',\n name: 'list',\n didWriteView: function didWriteView(_ref6) {\n var root = _ref6.root;\n root.childViews\n .filter(function(view) {\n return view.markedForRemoval && view.opacity === 0 && view.resting;\n })\n .forEach(function(view) {\n view._destroy();\n root.removeChildView(view);\n });\n },\n filterFrameActionsForChild: filterSetItemActions,\n mixins: {\n apis: ['dragCoordinates'],\n },\n });\n\n var create$9 = function create(_ref) {\n var root = _ref.root,\n props = _ref.props;\n root.ref.list = root.appendChildView(root.createChildView(list));\n props.dragCoordinates = null;\n props.overflowing = false;\n };\n\n var storeDragCoordinates = function storeDragCoordinates(_ref2) {\n var root = _ref2.root,\n props = _ref2.props,\n action = _ref2.action;\n if (!root.query('GET_ITEM_INSERT_LOCATION_FREEDOM')) return;\n props.dragCoordinates = {\n left: action.position.scopeLeft - root.ref.list.rect.element.left,\n top:\n action.position.scopeTop -\n (root.rect.outer.top + root.rect.element.marginTop + root.rect.element.scrollTop),\n };\n };\n\n var clearDragCoordinates = function clearDragCoordinates(_ref3) {\n var props = _ref3.props;\n props.dragCoordinates = null;\n };\n\n var route$3 = createRoute({\n DID_DRAG: storeDragCoordinates,\n DID_END_DRAG: clearDragCoordinates,\n });\n\n var write$6 = function write(_ref4) {\n var root = _ref4.root,\n props = _ref4.props,\n actions = _ref4.actions;\n\n \u002F\u002F route actions\n route$3({ root: root, props: props, actions: actions });\n\n \u002F\u002F current drag position\n root.ref.list.dragCoordinates = props.dragCoordinates;\n\n \u002F\u002F if currently overflowing but no longer received overflow\n if (props.overflowing && !props.overflow) {\n props.overflowing = false;\n\n \u002F\u002F reset overflow state\n root.element.dataset.state = '';\n root.height = null;\n }\n\n \u002F\u002F if is not overflowing currently but does receive overflow value\n if (props.overflow) {\n var newHeight = Math.round(props.overflow);\n if (newHeight !== root.height) {\n props.overflowing = true;\n root.element.dataset.state = 'overflow';\n root.height = newHeight;\n }\n }\n };\n\n var listScroller = createView({\n create: create$9,\n write: write$6,\n name: 'list-scroller',\n mixins: {\n apis: ['overflow', 'dragCoordinates'],\n styles: ['height', 'translateY'],\n animations: {\n translateY: 'spring',\n },\n },\n });\n\n var attrToggle = function attrToggle(element, name, state) {\n var enabledValue = arguments.length \u003E 3 && arguments[3] !== undefined ? arguments[3] : '';\n if (state) {\n attr(element, name, enabledValue);\n } else {\n element.removeAttribute(name);\n }\n };\n\n var resetFileInput = function resetFileInput(input) {\n \u002F\u002F no value, no need to reset\n if (!input || input.value === '') {\n return;\n }\n\n try {\n \u002F\u002F for modern browsers\n input.value = '';\n } catch (err) {}\n\n \u002F\u002F for IE10\n if (input.value) {\n \u002F\u002F quickly append input to temp form and reset form\n var form = createElement$1('form');\n var parentNode = input.parentNode;\n var ref = input.nextSibling;\n form.appendChild(input);\n form.reset();\n\n \u002F\u002F re-inject input where it originally was\n if (ref) {\n parentNode.insertBefore(input, ref);\n } else {\n parentNode.appendChild(input);\n }\n }\n };\n\n var create$a = function create(_ref) {\n var root = _ref.root,\n props = _ref.props;\n\n \u002F\u002F set id so can be referenced from outside labels\n root.element.id = 'filepond--browser-' + props.id;\n\n \u002F\u002F set name of element (is removed when a value is set)\n attr(root.element, 'name', root.query('GET_NAME'));\n\n \u002F\u002F we have to link this element to the status element\n attr(root.element, 'aria-controls', 'filepond--assistant-' + props.id);\n\n \u002F\u002F set label, we use labelled by as otherwise the screenreader does not read the \"browse\" text in the label (as it has tabindex: 0)\n attr(root.element, 'aria-labelledby', 'filepond--drop-label-' + props.id);\n\n \u002F\u002F set configurable props\n setAcceptedFileTypes({\n root: root,\n action: { value: root.query('GET_ACCEPTED_FILE_TYPES') },\n });\n toggleAllowMultiple({ root: root, action: { value: root.query('GET_ALLOW_MULTIPLE') } });\n toggleDirectoryFilter({\n root: root,\n action: { value: root.query('GET_ALLOW_DIRECTORIES_ONLY') },\n });\n toggleDisabled({ root: root });\n toggleRequired({ root: root, action: { value: root.query('GET_REQUIRED') } });\n setCaptureMethod({ root: root, action: { value: root.query('GET_CAPTURE_METHOD') } });\n\n \u002F\u002F handle changes to the input field\n root.ref.handleChange = function(e) {\n if (!root.element.value) {\n return;\n }\n\n \u002F\u002F extract files and move value of webkitRelativePath path to _relativePath\n var files = Array.from(root.element.files).map(function(file) {\n file._relativePath = file.webkitRelativePath;\n return file;\n });\n\n \u002F\u002F we add a little delay so the OS file select window can move out of the way before we add our file\n setTimeout(function() {\n \u002F\u002F load files\n props.onload(files);\n\n \u002F\u002F reset input, it's just for exposing a method to drop files, should not retain any state\n resetFileInput(root.element);\n }, 250);\n };\n\n root.element.addEventListener('change', root.ref.handleChange);\n };\n\n var setAcceptedFileTypes = function setAcceptedFileTypes(_ref2) {\n var root = _ref2.root,\n action = _ref2.action;\n if (!root.query('GET_ALLOW_SYNC_ACCEPT_ATTRIBUTE')) return;\n attrToggle(\n root.element,\n 'accept',\n !!action.value,\n action.value ? action.value.join(',') : ''\n );\n };\n\n var toggleAllowMultiple = function toggleAllowMultiple(_ref3) {\n var root = _ref3.root,\n action = _ref3.action;\n attrToggle(root.element, 'multiple', action.value);\n };\n\n var toggleDirectoryFilter = function toggleDirectoryFilter(_ref4) {\n var root = _ref4.root,\n action = _ref4.action;\n attrToggle(root.element, 'webkitdirectory', action.value);\n };\n\n var toggleDisabled = function toggleDisabled(_ref5) {\n var root = _ref5.root;\n var isDisabled = root.query('GET_DISABLED');\n var doesAllowBrowse = root.query('GET_ALLOW_BROWSE');\n var disableField = isDisabled || !doesAllowBrowse;\n attrToggle(root.element, 'disabled', disableField);\n };\n\n var toggleRequired = function toggleRequired(_ref6) {\n var root = _ref6.root,\n action = _ref6.action;\n \u002F\u002F want to remove required, always possible\n if (!action.value) {\n attrToggle(root.element, 'required', false);\n }\n \u002F\u002F if want to make required, only possible when zero items\n else if (root.query('GET_TOTAL_ITEMS') === 0) {\n attrToggle(root.element, 'required', true);\n }\n };\n\n var setCaptureMethod = function setCaptureMethod(_ref7) {\n var root = _ref7.root,\n action = _ref7.action;\n attrToggle(\n root.element,\n 'capture',\n !!action.value,\n action.value === true ? '' : action.value\n );\n };\n\n var updateRequiredStatus = function updateRequiredStatus(_ref8) {\n var root = _ref8.root;\n var element = root.element;\n \u002F\u002F always remove the required attribute when more than zero items\n if (root.query('GET_TOTAL_ITEMS') \u003E 0) {\n attrToggle(element, 'required', false);\n attrToggle(element, 'name', false);\n } else {\n \u002F\u002F add name attribute\n attrToggle(element, 'name', true, root.query('GET_NAME'));\n\n \u002F\u002F remove any validation messages\n var shouldCheckValidity = root.query('GET_CHECK_VALIDITY');\n if (shouldCheckValidity) {\n element.setCustomValidity('');\n }\n\n \u002F\u002F we only add required if the field has been deemed required\n if (root.query('GET_REQUIRED')) {\n attrToggle(element, 'required', true);\n }\n }\n };\n\n var updateFieldValidityStatus = function updateFieldValidityStatus(_ref9) {\n var root = _ref9.root;\n var shouldCheckValidity = root.query('GET_CHECK_VALIDITY');\n if (!shouldCheckValidity) return;\n root.element.setCustomValidity(root.query('GET_LABEL_INVALID_FIELD'));\n };\n\n var browser = createView({\n tag: 'input',\n name: 'browser',\n ignoreRect: true,\n ignoreRectUpdate: true,\n attributes: {\n type: 'file',\n },\n\n create: create$a,\n destroy: function destroy(_ref10) {\n var root = _ref10.root;\n root.element.removeEventListener('change', root.ref.handleChange);\n },\n write: createRoute({\n DID_LOAD_ITEM: updateRequiredStatus,\n DID_REMOVE_ITEM: updateRequiredStatus,\n DID_THROW_ITEM_INVALID: updateFieldValidityStatus,\n\n DID_SET_DISABLED: toggleDisabled,\n DID_SET_ALLOW_BROWSE: toggleDisabled,\n DID_SET_ALLOW_DIRECTORIES_ONLY: toggleDirectoryFilter,\n DID_SET_ALLOW_MULTIPLE: toggleAllowMultiple,\n DID_SET_ACCEPTED_FILE_TYPES: setAcceptedFileTypes,\n DID_SET_CAPTURE_METHOD: setCaptureMethod,\n DID_SET_REQUIRED: toggleRequired,\n }),\n });\n\n var Key = {\n ENTER: 13,\n SPACE: 32,\n };\n\n var create$b = function create(_ref) {\n var root = _ref.root,\n props = _ref.props;\n\n \u002F\u002F create the label and link it to the file browser\n var label = createElement$1('label');\n attr(label, 'for', 'filepond--browser-' + props.id);\n\n \u002F\u002F use for labeling file input (aria-labelledby on file input)\n attr(label, 'id', 'filepond--drop-label-' + props.id);\n\n \u002F\u002F hide the label for screenreaders, the input element will read the contents of the label when it's focussed. If we don't set aria-hidden the screenreader will also navigate the contents of the label separately from the input.\n attr(label, 'aria-hidden', 'true');\n\n \u002F\u002F handle keys\n root.ref.handleKeyDown = function(e) {\n var isActivationKey = e.keyCode === Key.ENTER || e.keyCode === Key.SPACE;\n if (!isActivationKey) return;\n \u002F\u002F stops from triggering the element a second time\n e.preventDefault();\n\n \u002F\u002F click link (will then in turn activate file input)\n root.ref.label.click();\n };\n\n root.ref.handleClick = function(e) {\n var isLabelClick = e.target === label || label.contains(e.target);\n\n \u002F\u002F don't want to click twice\n if (isLabelClick) return;\n\n \u002F\u002F click link (will then in turn activate file input)\n root.ref.label.click();\n };\n\n \u002F\u002F attach events\n label.addEventListener('keydown', root.ref.handleKeyDown);\n root.element.addEventListener('click', root.ref.handleClick);\n\n \u002F\u002F update\n updateLabelValue(label, props.caption);\n\n \u002F\u002F add!\n root.appendChild(label);\n root.ref.label = label;\n };\n\n var updateLabelValue = function updateLabelValue(label, value) {\n label.innerHTML = value;\n var clickable = label.querySelector('.filepond--label-action');\n if (clickable) {\n attr(clickable, 'tabindex', '0');\n }\n return value;\n };\n\n var dropLabel = createView({\n name: 'drop-label',\n ignoreRect: true,\n create: create$b,\n destroy: function destroy(_ref2) {\n var root = _ref2.root;\n root.ref.label.addEventListener('keydown', root.ref.handleKeyDown);\n root.element.removeEventListener('click', root.ref.handleClick);\n },\n write: createRoute({\n DID_SET_LABEL_IDLE: function DID_SET_LABEL_IDLE(_ref3) {\n var root = _ref3.root,\n action = _ref3.action;\n updateLabelValue(root.ref.label, action.value);\n },\n }),\n\n mixins: {\n styles: ['opacity', 'translateX', 'translateY'],\n animations: {\n opacity: { type: 'tween', duration: 150 },\n translateX: 'spring',\n translateY: 'spring',\n },\n },\n });\n\n var blob = createView({\n name: 'drip-blob',\n ignoreRect: true,\n mixins: {\n styles: ['translateX', 'translateY', 'scaleX', 'scaleY', 'opacity'],\n animations: {\n scaleX: 'spring',\n scaleY: 'spring',\n translateX: 'spring',\n translateY: 'spring',\n opacity: { type: 'tween', duration: 250 },\n },\n },\n });\n\n var addBlob = function addBlob(_ref) {\n var root = _ref.root;\n var centerX = root.rect.element.width * 0.5;\n var centerY = root.rect.element.height * 0.5;\n\n root.ref.blob = root.appendChildView(\n root.createChildView(blob, {\n opacity: 0,\n scaleX: 2.5,\n scaleY: 2.5,\n translateX: centerX,\n translateY: centerY,\n })\n );\n };\n\n var moveBlob = function moveBlob(_ref2) {\n var root = _ref2.root,\n action = _ref2.action;\n if (!root.ref.blob) {\n addBlob({ root: root });\n return;\n }\n\n root.ref.blob.translateX = action.position.scopeLeft;\n root.ref.blob.translateY = action.position.scopeTop;\n root.ref.blob.scaleX = 1;\n root.ref.blob.scaleY = 1;\n root.ref.blob.opacity = 1;\n };\n\n var hideBlob = function hideBlob(_ref3) {\n var root = _ref3.root;\n if (!root.ref.blob) {\n return;\n }\n root.ref.blob.opacity = 0;\n };\n\n var explodeBlob = function explodeBlob(_ref4) {\n var root = _ref4.root;\n if (!root.ref.blob) {\n return;\n }\n root.ref.blob.scaleX = 2.5;\n root.ref.blob.scaleY = 2.5;\n root.ref.blob.opacity = 0;\n };\n\n var write$7 = function write(_ref5) {\n var root = _ref5.root,\n props = _ref5.props,\n actions = _ref5.actions;\n route$4({ root: root, props: props, actions: actions });\n var blob = root.ref.blob;\n\n if (actions.length === 0 && blob && blob.opacity === 0) {\n root.removeChildView(blob);\n root.ref.blob = null;\n }\n };\n\n var route$4 = createRoute({\n DID_DRAG: moveBlob,\n DID_DROP: explodeBlob,\n DID_END_DRAG: hideBlob,\n });\n\n var drip = createView({\n ignoreRect: true,\n ignoreRectUpdate: true,\n name: 'drip',\n write: write$7,\n });\n\n var setInputFiles = function setInputFiles(element, files) {\n try {\n \u002F\u002F Create a DataTransfer instance and add a newly created file\n var dataTransfer = new DataTransfer();\n files.forEach(function(file) {\n if (file instanceof File) {\n dataTransfer.items.add(file);\n } else {\n dataTransfer.items.add(\n new File([file], file.name, {\n type: file.type,\n })\n );\n }\n });\n\n \u002F\u002F Assign the DataTransfer files list to the file input\n element.files = dataTransfer.files;\n } catch (err) {\n return false;\n }\n return true;\n };\n\n var create$c = function create(_ref) {\n var root = _ref.root;\n return (root.ref.fields = {});\n };\n\n var getField = function getField(root, id) {\n return root.ref.fields[id];\n };\n\n var syncFieldPositionsWithItems = function syncFieldPositionsWithItems(root) {\n root.query('GET_ACTIVE_ITEMS').forEach(function(item) {\n if (!root.ref.fields[item.id]) return;\n root.element.appendChild(root.ref.fields[item.id]);\n });\n };\n\n var didReorderItems = function didReorderItems(_ref2) {\n var root = _ref2.root;\n return syncFieldPositionsWithItems(root);\n };\n\n var didAddItem = function didAddItem(_ref3) {\n var root = _ref3.root,\n action = _ref3.action;\n var fileItem = root.query('GET_ITEM', action.id);\n var isLocalFile = fileItem.origin === FileOrigin.LOCAL;\n var shouldUseFileInput = !isLocalFile && root.query('SHOULD_UPDATE_FILE_INPUT');\n var dataContainer = createElement$1('input');\n dataContainer.type = shouldUseFileInput ? 'file' : 'hidden';\n dataContainer.name = root.query('GET_NAME');\n dataContainer.disabled = root.query('GET_DISABLED');\n root.ref.fields[action.id] = dataContainer;\n syncFieldPositionsWithItems(root);\n };\n\n var didLoadItem$1 = function didLoadItem(_ref4) {\n var root = _ref4.root,\n action = _ref4.action;\n var field = getField(root, action.id);\n if (!field) return;\n\n \u002F\u002F store server ref in hidden input\n if (action.serverFileReference !== null) field.value = action.serverFileReference;\n\n \u002F\u002F store file item in file input\n if (!root.query('SHOULD_UPDATE_FILE_INPUT')) return;\n\n var fileItem = root.query('GET_ITEM', action.id);\n setInputFiles(field, [fileItem.file]);\n };\n\n var didPrepareOutput = function didPrepareOutput(_ref5) {\n var root = _ref5.root,\n action = _ref5.action;\n \u002F\u002F this timeout pushes the handler after 'load'\n if (!root.query('SHOULD_UPDATE_FILE_INPUT')) return;\n setTimeout(function() {\n var field = getField(root, action.id);\n if (!field) return;\n setInputFiles(field, [action.file]);\n }, 0);\n };\n\n var didSetDisabled = function didSetDisabled(_ref6) {\n var root = _ref6.root;\n root.element.disabled = root.query('GET_DISABLED');\n };\n\n var didRemoveItem = function didRemoveItem(_ref7) {\n var root = _ref7.root,\n action = _ref7.action;\n var field = getField(root, action.id);\n if (!field) return;\n if (field.parentNode) field.parentNode.removeChild(field);\n delete root.ref.fields[action.id];\n };\n\n \u002F\u002F only runs for server files (so doesn't deal with file input)\n var didDefineValue = function didDefineValue(_ref8) {\n var root = _ref8.root,\n action = _ref8.action;\n var field = getField(root, action.id);\n if (!field) return;\n if (action.value === null) {\n \u002F\u002F clear field value\n field.removeAttribute('value');\n } else {\n \u002F\u002F set field value\n field.value = action.value;\n }\n syncFieldPositionsWithItems(root);\n };\n\n var write$8 = createRoute({\n DID_SET_DISABLED: didSetDisabled,\n DID_ADD_ITEM: didAddItem,\n DID_LOAD_ITEM: didLoadItem$1,\n DID_REMOVE_ITEM: didRemoveItem,\n DID_DEFINE_VALUE: didDefineValue,\n DID_PREPARE_OUTPUT: didPrepareOutput,\n DID_REORDER_ITEMS: didReorderItems,\n DID_SORT_ITEMS: didReorderItems,\n });\n\n var data = createView({\n tag: 'fieldset',\n name: 'data',\n create: create$c,\n write: write$8,\n ignoreRect: true,\n });\n\n var getRootNode = function getRootNode(element) {\n return 'getRootNode' in element ? element.getRootNode() : document;\n };\n\n var images = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg', 'tiff'];\n var text$1 = ['css', 'csv', 'html', 'txt'];\n var map = {\n zip: 'zip|compressed',\n epub: 'application\u002Fepub+zip',\n };\n\n var guesstimateMimeType = function guesstimateMimeType() {\n var extension = arguments.length \u003E 0 && arguments[0] !== undefined ? arguments[0] : '';\n extension = extension.toLowerCase();\n if (images.includes(extension)) {\n return (\n 'image\u002F' +\n (extension === 'jpg' ? 'jpeg' : extension === 'svg' ? 'svg+xml' : extension)\n );\n }\n if (text$1.includes(extension)) {\n return 'text\u002F' + extension;\n }\n\n return map[extension] || '';\n };\n\n var requestDataTransferItems = function requestDataTransferItems(dataTransfer) {\n return new Promise(function(resolve, reject) {\n \u002F\u002F try to get links from transfer, if found we'll exit immediately (unless a file is in the dataTransfer as well, this is because Firefox could represent the file as a URL and a file object at the same time)\n var links = getLinks(dataTransfer);\n if (links.length && !hasFiles(dataTransfer)) {\n return resolve(links);\n }\n \u002F\u002F try to get files from the transfer\n getFiles(dataTransfer).then(resolve);\n });\n };\n\n \u002F**\n * Test if datatransfer has files\n *\u002F\n var hasFiles = function hasFiles(dataTransfer) {\n if (dataTransfer.files) return dataTransfer.files.length \u003E 0;\n return false;\n };\n\n \u002F**\n * Extracts files from a DataTransfer object\n *\u002F\n var getFiles = function getFiles(dataTransfer) {\n return new Promise(function(resolve, reject) {\n \u002F\u002F get the transfer items as promises\n var promisedFiles = (dataTransfer.items ? Array.from(dataTransfer.items) : [])\n \u002F\u002F only keep file system items (files and directories)\n .filter(function(item) {\n return isFileSystemItem(item);\n })\n\n \u002F\u002F map each item to promise\n .map(function(item) {\n return getFilesFromItem(item);\n });\n\n \u002F\u002F if is empty, see if we can extract some info from the files property as a fallback\n if (!promisedFiles.length) {\n \u002F\u002F TODO: test for directories (should not be allowed)\n \u002F\u002F Use FileReader, problem is that the files property gets lost in the process\n resolve(dataTransfer.files ? Array.from(dataTransfer.files) : []);\n return;\n }\n\n \u002F\u002F done!\n Promise.all(promisedFiles)\n .then(function(returnedFileGroups) {\n \u002F\u002F flatten groups\n var files = [];\n returnedFileGroups.forEach(function(group) {\n files.push.apply(files, group);\n });\n\n \u002F\u002F done (filter out empty files)!\n resolve(\n files\n .filter(function(file) {\n return file;\n })\n .map(function(file) {\n if (!file._relativePath)\n file._relativePath = file.webkitRelativePath;\n return file;\n })\n );\n })\n .catch(console.error);\n });\n };\n\n var isFileSystemItem = function isFileSystemItem(item) {\n if (isEntry(item)) {\n var entry = getAsEntry(item);\n if (entry) {\n return entry.isFile || entry.isDirectory;\n }\n }\n return item.kind === 'file';\n };\n\n var getFilesFromItem = function getFilesFromItem(item) {\n return new Promise(function(resolve, reject) {\n if (isDirectoryEntry(item)) {\n getFilesInDirectory(getAsEntry(item))\n .then(resolve)\n .catch(reject);\n return;\n }\n\n resolve([item.getAsFile()]);\n });\n };\n\n var getFilesInDirectory = function getFilesInDirectory(entry) {\n return new Promise(function(resolve, reject) {\n var files = [];\n\n \u002F\u002F the total entries to read\n var dirCounter = 0;\n var fileCounter = 0;\n\n var resolveIfDone = function resolveIfDone() {\n if (fileCounter === 0 && dirCounter === 0) {\n resolve(files);\n }\n };\n\n \u002F\u002F the recursive function\n var readEntries = function readEntries(dirEntry) {\n dirCounter++;\n\n var directoryReader = dirEntry.createReader();\n\n \u002F\u002F directories are returned in batches, we need to process all batches before we're done\n var readBatch = function readBatch() {\n directoryReader.readEntries(function(entries) {\n if (entries.length === 0) {\n dirCounter--;\n resolveIfDone();\n return;\n }\n\n entries.forEach(function(entry) {\n \u002F\u002F recursively read more directories\n if (entry.isDirectory) {\n readEntries(entry);\n } else {\n \u002F\u002F read as file\n fileCounter++;\n\n entry.file(function(file) {\n var correctedFile = correctMissingFileType(file);\n if (entry.fullPath)\n correctedFile._relativePath = entry.fullPath;\n files.push(correctedFile);\n fileCounter--;\n resolveIfDone();\n });\n }\n });\n\n \u002F\u002F try to get next batch of files\n readBatch();\n }, reject);\n };\n\n \u002F\u002F read first batch of files\n readBatch();\n };\n\n \u002F\u002F go!\n readEntries(entry);\n });\n };\n\n var correctMissingFileType = function correctMissingFileType(file) {\n if (file.type.length) return file;\n var date = file.lastModifiedDate;\n var name = file.name;\n var type = guesstimateMimeType(getExtensionFromFilename(file.name));\n if (!type.length) return file;\n file = file.slice(0, file.size, type);\n file.name = name;\n file.lastModifiedDate = date;\n return file;\n };\n\n var isDirectoryEntry = function isDirectoryEntry(item) {\n return isEntry(item) && (getAsEntry(item) || {}).isDirectory;\n };\n\n var isEntry = function isEntry(item) {\n return 'webkitGetAsEntry' in item;\n };\n\n var getAsEntry = function getAsEntry(item) {\n return item.webkitGetAsEntry();\n };\n\n \u002F**\n * Extracts links from a DataTransfer object\n *\u002F\n var getLinks = function getLinks(dataTransfer) {\n var links = [];\n try {\n \u002F\u002F look in meta data property\n links = getLinksFromTransferMetaData(dataTransfer);\n if (links.length) {\n return links;\n }\n links = getLinksFromTransferURLData(dataTransfer);\n } catch (e) {\n \u002F\u002F nope nope nope (probably IE trouble)\n }\n return links;\n };\n\n var getLinksFromTransferURLData = function getLinksFromTransferURLData(dataTransfer) {\n var data = dataTransfer.getData('url');\n if (typeof data === 'string' && data.length) {\n return [data];\n }\n return [];\n };\n\n var getLinksFromTransferMetaData = function getLinksFromTransferMetaData(dataTransfer) {\n var data = dataTransfer.getData('text\u002Fhtml');\n if (typeof data === 'string' && data.length) {\n var matches = data.match(\u002Fsrc\\s*=\\s*\"(.+?)\"\u002F);\n if (matches) {\n return [matches[1]];\n }\n }\n return [];\n };\n\n var dragNDropObservers = [];\n\n var eventPosition = function eventPosition(e) {\n return {\n pageLeft: e.pageX,\n pageTop: e.pageY,\n scopeLeft: e.offsetX || e.layerX,\n scopeTop: e.offsetY || e.layerY,\n };\n };\n\n var createDragNDropClient = function createDragNDropClient(\n element,\n scopeToObserve,\n filterElement\n ) {\n var observer = getDragNDropObserver(scopeToObserve);\n\n var client = {\n element: element,\n filterElement: filterElement,\n state: null,\n ondrop: function ondrop() {},\n onenter: function onenter() {},\n ondrag: function ondrag() {},\n onexit: function onexit() {},\n onload: function onload() {},\n allowdrop: function allowdrop() {},\n };\n\n client.destroy = observer.addListener(client);\n\n return client;\n };\n\n var getDragNDropObserver = function getDragNDropObserver(element) {\n \u002F\u002F see if already exists, if so, return\n var observer = dragNDropObservers.find(function(item) {\n return item.element === element;\n });\n if (observer) {\n return observer;\n }\n\n \u002F\u002F create new observer, does not yet exist for this element\n var newObserver = createDragNDropObserver(element);\n dragNDropObservers.push(newObserver);\n return newObserver;\n };\n\n var createDragNDropObserver = function createDragNDropObserver(element) {\n var clients = [];\n\n var routes = {\n dragenter: dragenter,\n dragover: dragover,\n dragleave: dragleave,\n drop: drop,\n };\n\n var handlers = {};\n\n forin(routes, function(event, createHandler) {\n handlers[event] = createHandler(element, clients);\n element.addEventListener(event, handlers[event], false);\n });\n\n var observer = {\n element: element,\n addListener: function addListener(client) {\n \u002F\u002F add as client\n clients.push(client);\n\n \u002F\u002F return removeListener function\n return function() {\n \u002F\u002F remove client\n clients.splice(clients.indexOf(client), 1);\n\n \u002F\u002F if no more clients, clean up observer\n if (clients.length === 0) {\n dragNDropObservers.splice(dragNDropObservers.indexOf(observer), 1);\n\n forin(routes, function(event) {\n element.removeEventListener(event, handlers[event], false);\n });\n }\n };\n },\n };\n\n return observer;\n };\n\n var elementFromPoint = function elementFromPoint(root, point) {\n if (!('elementFromPoint' in root)) {\n root = document;\n }\n return root.elementFromPoint(point.x, point.y);\n };\n\n var isEventTarget = function isEventTarget(e, target) {\n \u002F\u002F get root\n var root = getRootNode(target);\n\n \u002F\u002F get element at position\n \u002F\u002F if root is not actual shadow DOM and does not have elementFromPoint method, use the one on document\n var elementAtPosition = elementFromPoint(root, {\n x: e.pageX - window.pageXOffset,\n y: e.pageY - window.pageYOffset,\n });\n\n \u002F\u002F test if target is the element or if one of its children is\n return elementAtPosition === target || target.contains(elementAtPosition);\n };\n\n var initialTarget = null;\n\n var setDropEffect = function setDropEffect(dataTransfer, effect) {\n \u002F\u002F is in try catch as IE11 will throw error if not\n try {\n dataTransfer.dropEffect = effect;\n } catch (e) {}\n };\n\n var dragenter = function dragenter(root, clients) {\n return function(e) {\n e.preventDefault();\n\n initialTarget = e.target;\n\n clients.forEach(function(client) {\n var element = client.element,\n onenter = client.onenter;\n\n if (isEventTarget(e, element)) {\n client.state = 'enter';\n\n \u002F\u002F fire enter event\n onenter(eventPosition(e));\n }\n });\n };\n };\n\n var dragover = function dragover(root, clients) {\n return function(e) {\n e.preventDefault();\n\n var dataTransfer = e.dataTransfer;\n\n requestDataTransferItems(dataTransfer).then(function(items) {\n var overDropTarget = false;\n\n clients.some(function(client) {\n var filterElement = client.filterElement,\n element = client.element,\n onenter = client.onenter,\n onexit = client.onexit,\n ondrag = client.ondrag,\n allowdrop = client.allowdrop;\n\n \u002F\u002F by default we can drop\n setDropEffect(dataTransfer, 'copy');\n\n \u002F\u002F allow transfer of these items\n var allowsTransfer = allowdrop(items);\n\n \u002F\u002F only used when can be dropped on page\n if (!allowsTransfer) {\n setDropEffect(dataTransfer, 'none');\n return;\n }\n\n \u002F\u002F targetting this client\n if (isEventTarget(e, element)) {\n overDropTarget = true;\n\n \u002F\u002F had no previous state, means we are entering this client\n if (client.state === null) {\n client.state = 'enter';\n onenter(eventPosition(e));\n return;\n }\n\n \u002F\u002F now over element (no matter if it allows the drop or not)\n client.state = 'over';\n\n \u002F\u002F needs to allow transfer\n if (filterElement && !allowsTransfer) {\n setDropEffect(dataTransfer, 'none');\n return;\n }\n\n \u002F\u002F dragging\n ondrag(eventPosition(e));\n } else {\n \u002F\u002F should be over an element to drop\n if (filterElement && !overDropTarget) {\n setDropEffect(dataTransfer, 'none');\n }\n\n \u002F\u002F might have just left this client?\n if (client.state) {\n client.state = null;\n onexit(eventPosition(e));\n }\n }\n });\n });\n };\n };\n\n var drop = function drop(root, clients) {\n return function(e) {\n e.preventDefault();\n\n var dataTransfer = e.dataTransfer;\n\n requestDataTransferItems(dataTransfer).then(function(items) {\n clients.forEach(function(client) {\n var filterElement = client.filterElement,\n element = client.element,\n ondrop = client.ondrop,\n onexit = client.onexit,\n allowdrop = client.allowdrop;\n\n client.state = null;\n\n \u002F\u002F if we're filtering on element we need to be over the element to drop\n if (filterElement && !isEventTarget(e, element)) return;\n\n \u002F\u002F no transfer for this client\n if (!allowdrop(items)) return onexit(eventPosition(e));\n\n \u002F\u002F we can drop these items on this client\n ondrop(eventPosition(e), items);\n });\n });\n };\n };\n\n var dragleave = function dragleave(root, clients) {\n return function(e) {\n if (initialTarget !== e.target) {\n return;\n }\n\n clients.forEach(function(client) {\n var onexit = client.onexit;\n\n client.state = null;\n\n onexit(eventPosition(e));\n });\n };\n };\n\n var createHopper = function createHopper(scope, validateItems, options) {\n \u002F\u002F is now hopper scope\n scope.classList.add('filepond--hopper');\n\n \u002F\u002F shortcuts\n var catchesDropsOnPage = options.catchesDropsOnPage,\n requiresDropOnElement = options.requiresDropOnElement,\n _options$filterItems = options.filterItems,\n filterItems =\n _options$filterItems === void 0\n ? function(items) {\n return items;\n }\n : _options$filterItems;\n\n \u002F\u002F create a dnd client\n var client = createDragNDropClient(\n scope,\n catchesDropsOnPage ? document.documentElement : scope,\n requiresDropOnElement\n );\n\n \u002F\u002F current client state\n var lastState = '';\n var currentState = '';\n\n \u002F\u002F determines if a file may be dropped\n client.allowdrop = function(items) {\n \u002F\u002F TODO: if we can, throw error to indicate the items cannot by dropped\n\n return validateItems(filterItems(items));\n };\n\n client.ondrop = function(position, items) {\n var filteredItems = filterItems(items);\n\n if (!validateItems(filteredItems)) {\n api.ondragend(position);\n return;\n }\n\n currentState = 'drag-drop';\n\n api.onload(filteredItems, position);\n };\n\n client.ondrag = function(position) {\n api.ondrag(position);\n };\n\n client.onenter = function(position) {\n currentState = 'drag-over';\n\n api.ondragstart(position);\n };\n\n client.onexit = function(position) {\n currentState = 'drag-exit';\n\n api.ondragend(position);\n };\n\n var api = {\n updateHopperState: function updateHopperState() {\n if (lastState !== currentState) {\n scope.dataset.hopperState = currentState;\n lastState = currentState;\n }\n },\n onload: function onload() {},\n ondragstart: function ondragstart() {},\n ondrag: function ondrag() {},\n ondragend: function ondragend() {},\n destroy: function destroy() {\n \u002F\u002F destroy client\n client.destroy();\n },\n };\n\n return api;\n };\n\n var listening = false;\n var listeners$1 = [];\n\n var handlePaste = function handlePaste(e) {\n \u002F\u002F if is pasting in input or textarea and the target is outside of a filepond scope, ignore\n var activeEl = document.activeElement;\n if (activeEl && \u002Ftextarea|input\u002Fi.test(activeEl.nodeName)) {\n \u002F\u002F test textarea or input is contained in filepond root\n var inScope = false;\n var element = activeEl;\n while (element !== document.body) {\n if (element.classList.contains('filepond--root')) {\n inScope = true;\n break;\n }\n element = element.parentNode;\n }\n\n if (!inScope) return;\n }\n\n requestDataTransferItems(e.clipboardData).then(function(files) {\n \u002F\u002F no files received\n if (!files.length) {\n return;\n }\n\n \u002F\u002F notify listeners of received files\n listeners$1.forEach(function(listener) {\n return listener(files);\n });\n });\n };\n\n var listen = function listen(cb) {\n \u002F\u002F can't add twice\n if (listeners$1.includes(cb)) {\n return;\n }\n\n \u002F\u002F add initial listener\n listeners$1.push(cb);\n\n \u002F\u002F setup paste listener for entire page\n if (listening) {\n return;\n }\n\n listening = true;\n document.addEventListener('paste', handlePaste);\n };\n\n var unlisten = function unlisten(listener) {\n arrayRemove(listeners$1, listeners$1.indexOf(listener));\n\n \u002F\u002F clean up\n if (listeners$1.length === 0) {\n document.removeEventListener('paste', handlePaste);\n listening = false;\n }\n };\n\n var createPaster = function createPaster() {\n var cb = function cb(files) {\n api.onload(files);\n };\n\n var api = {\n destroy: function destroy() {\n unlisten(cb);\n },\n onload: function onload() {},\n };\n\n listen(cb);\n\n return api;\n };\n\n \u002F**\n * Creates the file view\n *\u002F\n var create$d = function create(_ref) {\n var root = _ref.root,\n props = _ref.props;\n root.element.id = 'filepond--assistant-' + props.id;\n attr(root.element, 'role', 'status');\n attr(root.element, 'aria-live', 'polite');\n attr(root.element, 'aria-relevant', 'additions');\n };\n\n var addFilesNotificationTimeout = null;\n var notificationClearTimeout = null;\n\n var filenames = [];\n\n var assist = function assist(root, message) {\n root.element.textContent = message;\n };\n\n var clear$1 = function clear(root) {\n root.element.textContent = '';\n };\n\n var listModified = function listModified(root, filename, label) {\n var total = root.query('GET_TOTAL_ITEMS');\n assist(\n root,\n label +\n ' ' +\n filename +\n ', ' +\n total +\n ' ' +\n (total === 1\n ? root.query('GET_LABEL_FILE_COUNT_SINGULAR')\n : root.query('GET_LABEL_FILE_COUNT_PLURAL'))\n );\n\n \u002F\u002F clear group after set amount of time so the status is not read twice\n clearTimeout(notificationClearTimeout);\n notificationClearTimeout = setTimeout(function() {\n clear$1(root);\n }, 1500);\n };\n\n var isUsingFilePond = function isUsingFilePond(root) {\n return root.element.parentNode.contains(document.activeElement);\n };\n\n var itemAdded = function itemAdded(_ref2) {\n var root = _ref2.root,\n action = _ref2.action;\n if (!isUsingFilePond(root)) {\n return;\n }\n\n root.element.textContent = '';\n var item = root.query('GET_ITEM', action.id);\n filenames.push(item.filename);\n\n clearTimeout(addFilesNotificationTimeout);\n addFilesNotificationTimeout = setTimeout(function() {\n listModified(root, filenames.join(', '), root.query('GET_LABEL_FILE_ADDED'));\n\n filenames.length = 0;\n }, 750);\n };\n\n var itemRemoved = function itemRemoved(_ref3) {\n var root = _ref3.root,\n action = _ref3.action;\n if (!isUsingFilePond(root)) {\n return;\n }\n\n var item = action.item;\n listModified(root, item.filename, root.query('GET_LABEL_FILE_REMOVED'));\n };\n\n var itemProcessed = function itemProcessed(_ref4) {\n var root = _ref4.root,\n action = _ref4.action;\n \u002F\u002F will also notify the user when FilePond is not being used, as the user might be occupied with other activities while uploading a file\n\n var item = root.query('GET_ITEM', action.id);\n var filename = item.filename;\n var label = root.query('GET_LABEL_FILE_PROCESSING_COMPLETE');\n\n assist(root, filename + ' ' + label);\n };\n\n var itemProcessedUndo = function itemProcessedUndo(_ref5) {\n var root = _ref5.root,\n action = _ref5.action;\n var item = root.query('GET_ITEM', action.id);\n var filename = item.filename;\n var label = root.query('GET_LABEL_FILE_PROCESSING_ABORTED');\n\n assist(root, filename + ' ' + label);\n };\n\n var itemError = function itemError(_ref6) {\n var root = _ref6.root,\n action = _ref6.action;\n var item = root.query('GET_ITEM', action.id);\n var filename = item.filename;\n\n \u002F\u002F will also notify the user when FilePond is not being used, as the user might be occupied with other activities while uploading a file\n\n assist(root, action.status.main + ' ' + filename + ' ' + action.status.sub);\n };\n\n var assistant = createView({\n create: create$d,\n ignoreRect: true,\n ignoreRectUpdate: true,\n write: createRoute({\n DID_LOAD_ITEM: itemAdded,\n DID_REMOVE_ITEM: itemRemoved,\n DID_COMPLETE_ITEM_PROCESSING: itemProcessed,\n\n DID_ABORT_ITEM_PROCESSING: itemProcessedUndo,\n DID_REVERT_ITEM_PROCESSING: itemProcessedUndo,\n\n DID_THROW_ITEM_REMOVE_ERROR: itemError,\n DID_THROW_ITEM_LOAD_ERROR: itemError,\n DID_THROW_ITEM_INVALID: itemError,\n DID_THROW_ITEM_PROCESSING_ERROR: itemError,\n }),\n\n tag: 'span',\n name: 'assistant',\n });\n\n var toCamels = function toCamels(string) {\n var separator = arguments.length \u003E 1 && arguments[1] !== undefined ? arguments[1] : '-';\n return string.replace(new RegExp(separator + '.', 'g'), function(sub) {\n return sub.charAt(1).toUpperCase();\n });\n };\n\n var debounce = function debounce(func) {\n var interval = arguments.length \u003E 1 && arguments[1] !== undefined ? arguments[1] : 16;\n var immidiateOnly =\n arguments.length \u003E 2 && arguments[2] !== undefined ? arguments[2] : true;\n var last = Date.now();\n var timeout = null;\n\n return function() {\n for (\n var _len = arguments.length, args = new Array(_len), _key = 0;\n _key \u003C _len;\n _key++\n ) {\n args[_key] = arguments[_key];\n }\n clearTimeout(timeout);\n\n var dist = Date.now() - last;\n\n var fn = function fn() {\n last = Date.now();\n func.apply(void 0, args);\n };\n\n if (dist \u003C interval) {\n \u002F\u002F we need to delay by the difference between interval and dist\n \u002F\u002F for example: if distance is 10 ms and interval is 16 ms,\n \u002F\u002F we need to wait an additional 6ms before calling the function)\n if (!immidiateOnly) {\n timeout = setTimeout(fn, interval - dist);\n }\n } else {\n \u002F\u002F go!\n fn();\n }\n };\n };\n\n var MAX_FILES_LIMIT = 1000000;\n\n var prevent = function prevent(e) {\n return e.preventDefault();\n };\n\n var create$e = function create(_ref) {\n var root = _ref.root,\n props = _ref.props;\n \u002F\u002F Add id\n var id = root.query('GET_ID');\n if (id) {\n root.element.id = id;\n }\n\n \u002F\u002F Add className\n var className = root.query('GET_CLASS_NAME');\n if (className) {\n className\n .split(' ')\n .filter(function(name) {\n return name.length;\n })\n .forEach(function(name) {\n root.element.classList.add(name);\n });\n }\n\n \u002F\u002F Field label\n root.ref.label = root.appendChildView(\n root.createChildView(\n dropLabel,\n Object.assign({}, props, {\n translateY: null,\n caption: root.query('GET_LABEL_IDLE'),\n })\n )\n );\n\n \u002F\u002F List of items\n root.ref.list = root.appendChildView(\n root.createChildView(listScroller, { translateY: null })\n );\n\n \u002F\u002F Background panel\n root.ref.panel = root.appendChildView(root.createChildView(panel, { name: 'panel-root' }));\n\n \u002F\u002F Assistant notifies assistive tech when content changes\n root.ref.assistant = root.appendChildView(\n root.createChildView(assistant, Object.assign({}, props))\n );\n\n \u002F\u002F Data\n root.ref.data = root.appendChildView(root.createChildView(data, Object.assign({}, props)));\n\n \u002F\u002F Measure (tests if fixed height was set)\n \u002F\u002F DOCTYPE needs to be set for this to work\n root.ref.measure = createElement$1('div');\n root.ref.measure.style.height = '100%';\n root.element.appendChild(root.ref.measure);\n\n \u002F\u002F information on the root height or fixed height status\n root.ref.bounds = null;\n\n \u002F\u002F apply initial style properties\n root.query('GET_STYLES')\n .filter(function(style) {\n return !isEmpty(style.value);\n })\n .map(function(_ref2) {\n var name = _ref2.name,\n value = _ref2.value;\n root.element.dataset[name] = value;\n });\n\n \u002F\u002F determine if width changed\n root.ref.widthPrevious = null;\n root.ref.widthUpdated = debounce(function() {\n root.ref.updateHistory = [];\n root.dispatch('DID_RESIZE_ROOT');\n }, 250);\n\n \u002F\u002F history of updates\n root.ref.previousAspectRatio = null;\n root.ref.updateHistory = [];\n\n \u002F\u002F prevent scrolling and zooming on iOS (only if supports pointer events, for then we can enable reorder)\n var canHover = window.matchMedia('(pointer: fine) and (hover: hover)').matches;\n var hasPointerEvents = 'PointerEvent' in window;\n if (root.query('GET_ALLOW_REORDER') && hasPointerEvents && !canHover) {\n root.element.addEventListener('touchmove', prevent, { passive: false });\n root.element.addEventListener('gesturestart', prevent);\n }\n\n \u002F\u002F add credits\n var credits = root.query('GET_CREDITS');\n var hasCredits = credits.length === 2;\n if (hasCredits) {\n var frag = document.createElement('a');\n frag.className = 'filepond--credits';\n frag.setAttribute('aria-hidden', 'true');\n frag.href = credits[0];\n frag.tabindex = -1;\n frag.target = '_blank';\n frag.rel = 'noopener noreferrer';\n frag.textContent = credits[1];\n root.element.appendChild(frag);\n root.ref.credits = frag;\n }\n };\n\n var write$9 = function write(_ref3) {\n var root = _ref3.root,\n props = _ref3.props,\n actions = _ref3.actions;\n \u002F\u002F route actions\n route$5({ root: root, props: props, actions: actions });\n\n \u002F\u002F apply style properties\n actions\n .filter(function(action) {\n return \u002F^DID_SET_STYLE_\u002F.test(action.type);\n })\n .filter(function(action) {\n return !isEmpty(action.data.value);\n })\n .map(function(_ref4) {\n var type = _ref4.type,\n data = _ref4.data;\n var name = toCamels(type.substr(8).toLowerCase(), '_');\n root.element.dataset[name] = data.value;\n root.invalidateLayout();\n });\n\n if (root.rect.element.hidden) return;\n\n if (root.rect.element.width !== root.ref.widthPrevious) {\n root.ref.widthPrevious = root.rect.element.width;\n root.ref.widthUpdated();\n }\n\n \u002F\u002F get box bounds, we do this only once\n var bounds = root.ref.bounds;\n if (!bounds) {\n bounds = root.ref.bounds = calculateRootBoundingBoxHeight(root);\n\n \u002F\u002F destroy measure element\n root.element.removeChild(root.ref.measure);\n root.ref.measure = null;\n }\n\n \u002F\u002F get quick references to various high level parts of the upload tool\n var _root$ref = root.ref,\n hopper = _root$ref.hopper,\n label = _root$ref.label,\n list = _root$ref.list,\n panel = _root$ref.panel;\n\n \u002F\u002F sets correct state to hopper scope\n if (hopper) {\n hopper.updateHopperState();\n }\n\n \u002F\u002F bool to indicate if we're full or not\n var aspectRatio = root.query('GET_PANEL_ASPECT_RATIO');\n var isMultiItem = root.query('GET_ALLOW_MULTIPLE');\n var totalItems = root.query('GET_TOTAL_ITEMS');\n var maxItems = isMultiItem ? root.query('GET_MAX_FILES') || MAX_FILES_LIMIT : 1;\n var atMaxCapacity = totalItems === maxItems;\n\n \u002F\u002F action used to add item\n var addAction = actions.find(function(action) {\n return action.type === 'DID_ADD_ITEM';\n });\n\n \u002F\u002F if reached max capacity and we've just reached it\n if (atMaxCapacity && addAction) {\n \u002F\u002F get interaction type\n var interactionMethod = addAction.data.interactionMethod;\n\n \u002F\u002F hide label\n label.opacity = 0;\n\n if (isMultiItem) {\n label.translateY = -40;\n } else {\n if (interactionMethod === InteractionMethod.API) {\n label.translateX = 40;\n } else if (interactionMethod === InteractionMethod.BROWSE) {\n label.translateY = 40;\n } else {\n label.translateY = 30;\n }\n }\n } else if (!atMaxCapacity) {\n label.opacity = 1;\n label.translateX = 0;\n label.translateY = 0;\n }\n\n var listItemMargin = calculateListItemMargin(root);\n\n var listHeight = calculateListHeight(root);\n\n var labelHeight = label.rect.element.height;\n var currentLabelHeight = !isMultiItem || atMaxCapacity ? 0 : labelHeight;\n\n var listMarginTop = atMaxCapacity ? list.rect.element.marginTop : 0;\n var listMarginBottom = totalItems === 0 ? 0 : list.rect.element.marginBottom;\n\n var visualHeight =\n currentLabelHeight + listMarginTop + listHeight.visual + listMarginBottom;\n var boundsHeight =\n currentLabelHeight + listMarginTop + listHeight.bounds + listMarginBottom;\n\n \u002F\u002F link list to label bottom position\n list.translateY =\n Math.max(0, currentLabelHeight - list.rect.element.marginTop) - listItemMargin.top;\n\n if (aspectRatio) {\n \u002F\u002F fixed aspect ratio\n\n \u002F\u002F calculate height based on width\n var width = root.rect.element.width;\n var height = width * aspectRatio;\n\n \u002F\u002F clear history if aspect ratio has changed\n if (aspectRatio !== root.ref.previousAspectRatio) {\n root.ref.previousAspectRatio = aspectRatio;\n root.ref.updateHistory = [];\n }\n\n \u002F\u002F remember this width\n var history = root.ref.updateHistory;\n history.push(width);\n\n var MAX_BOUNCES = 2;\n if (history.length \u003E MAX_BOUNCES * 2) {\n var l = history.length;\n var bottom = l - 10;\n var bounces = 0;\n for (var i = l; i \u003E= bottom; i--) {\n if (history[i] === history[i - 2]) {\n bounces++;\n }\n\n if (bounces \u003E= MAX_BOUNCES) {\n \u002F\u002F dont adjust height\n return;\n }\n }\n }\n\n \u002F\u002F fix height of panel so it adheres to aspect ratio\n panel.scalable = false;\n panel.height = height;\n\n \u002F\u002F available height for list\n var listAvailableHeight =\n \u002F\u002F the height of the panel minus the label height\n height -\n currentLabelHeight -\n \u002F\u002F the room we leave open between the end of the list and the panel bottom\n (listMarginBottom - listItemMargin.bottom) -\n \u002F\u002F if we're full we need to leave some room between the top of the panel and the list\n (atMaxCapacity ? listMarginTop : 0);\n\n if (listHeight.visual \u003E listAvailableHeight) {\n list.overflow = listAvailableHeight;\n } else {\n list.overflow = null;\n }\n\n \u002F\u002F set container bounds (so pushes siblings downwards)\n root.height = height;\n } else if (bounds.fixedHeight) {\n \u002F\u002F fixed height\n\n \u002F\u002F fix height of panel\n panel.scalable = false;\n\n \u002F\u002F available height for list\n var _listAvailableHeight =\n \u002F\u002F the height of the panel minus the label height\n bounds.fixedHeight -\n currentLabelHeight -\n \u002F\u002F the room we leave open between the end of the list and the panel bottom\n (listMarginBottom - listItemMargin.bottom) -\n \u002F\u002F if we're full we need to leave some room between the top of the panel and the list\n (atMaxCapacity ? listMarginTop : 0);\n\n \u002F\u002F set list height\n if (listHeight.visual \u003E _listAvailableHeight) {\n list.overflow = _listAvailableHeight;\n } else {\n list.overflow = null;\n }\n\n \u002F\u002F no need to set container bounds as these are handles by CSS fixed height\n } else if (bounds.cappedHeight) {\n \u002F\u002F max-height\n\n \u002F\u002F not a fixed height panel\n var isCappedHeight = visualHeight \u003E= bounds.cappedHeight;\n var panelHeight = Math.min(bounds.cappedHeight, visualHeight);\n panel.scalable = true;\n panel.height = isCappedHeight\n ? panelHeight\n : panelHeight - listItemMargin.top - listItemMargin.bottom;\n\n \u002F\u002F available height for list\n var _listAvailableHeight2 =\n \u002F\u002F the height of the panel minus the label height\n panelHeight -\n currentLabelHeight -\n \u002F\u002F the room we leave open between the end of the list and the panel bottom\n (listMarginBottom - listItemMargin.bottom) -\n \u002F\u002F if we're full we need to leave some room between the top of the panel and the list\n (atMaxCapacity ? listMarginTop : 0);\n\n \u002F\u002F set list height (if is overflowing)\n if (visualHeight \u003E bounds.cappedHeight && listHeight.visual \u003E _listAvailableHeight2) {\n list.overflow = _listAvailableHeight2;\n } else {\n list.overflow = null;\n }\n\n \u002F\u002F set container bounds (so pushes siblings downwards)\n root.height = Math.min(\n bounds.cappedHeight,\n boundsHeight - listItemMargin.top - listItemMargin.bottom\n );\n } else {\n \u002F\u002F flexible height\n\n \u002F\u002F not a fixed height panel\n var itemMargin = totalItems \u003E 0 ? listItemMargin.top + listItemMargin.bottom : 0;\n panel.scalable = true;\n panel.height = Math.max(labelHeight, visualHeight - itemMargin);\n\n \u002F\u002F set container bounds (so pushes siblings downwards)\n root.height = Math.max(labelHeight, boundsHeight - itemMargin);\n }\n\n \u002F\u002F move credits to bottom\n if (root.ref.credits && panel.heightCurrent)\n root.ref.credits.style.transform = 'translateY(' + panel.heightCurrent + 'px)';\n };\n\n var calculateListItemMargin = function calculateListItemMargin(root) {\n var item = root.ref.list.childViews[0].childViews[0];\n return item\n ? {\n top: item.rect.element.marginTop,\n bottom: item.rect.element.marginBottom,\n }\n : {\n top: 0,\n bottom: 0,\n };\n };\n\n var calculateListHeight = function calculateListHeight(root) {\n var visual = 0;\n var bounds = 0;\n\n \u002F\u002F get file list reference\n var scrollList = root.ref.list;\n var itemList = scrollList.childViews[0];\n var visibleChildren = itemList.childViews.filter(function(child) {\n return child.rect.element.height;\n });\n var children = root\n .query('GET_ACTIVE_ITEMS')\n .map(function(item) {\n return visibleChildren.find(function(child) {\n return child.id === item.id;\n });\n })\n .filter(function(item) {\n return item;\n });\n\n \u002F\u002F no children, done!\n if (children.length === 0) return { visual: visual, bounds: bounds };\n\n var horizontalSpace = itemList.rect.element.width;\n var dragIndex = getItemIndexByPosition(itemList, children, scrollList.dragCoordinates);\n\n var childRect = children[0].rect.element;\n\n var itemVerticalMargin = childRect.marginTop + childRect.marginBottom;\n var itemHorizontalMargin = childRect.marginLeft + childRect.marginRight;\n\n var itemWidth = childRect.width + itemHorizontalMargin;\n var itemHeight = childRect.height + itemVerticalMargin;\n\n var newItem = typeof dragIndex !== 'undefined' && dragIndex \u003E= 0 ? 1 : 0;\n var removedItem = children.find(function(child) {\n return child.markedForRemoval && child.opacity \u003C 0.45;\n })\n ? -1\n : 0;\n var verticalItemCount = children.length + newItem + removedItem;\n var itemsPerRow = getItemsPerRow(horizontalSpace, itemWidth);\n\n \u002F\u002F stack\n if (itemsPerRow === 1) {\n children.forEach(function(item) {\n var height = item.rect.element.height + itemVerticalMargin;\n bounds += height;\n visual += height * item.opacity;\n });\n }\n \u002F\u002F grid\n else {\n bounds = Math.ceil(verticalItemCount \u002F itemsPerRow) * itemHeight;\n visual = bounds;\n }\n\n return { visual: visual, bounds: bounds };\n };\n\n var calculateRootBoundingBoxHeight = function calculateRootBoundingBoxHeight(root) {\n var height = root.ref.measureHeight || null;\n var cappedHeight = parseInt(root.style.maxHeight, 10) || null;\n var fixedHeight = height === 0 ? null : height;\n\n return {\n cappedHeight: cappedHeight,\n fixedHeight: fixedHeight,\n };\n };\n\n var exceedsMaxFiles = function exceedsMaxFiles(root, items) {\n var allowReplace = root.query('GET_ALLOW_REPLACE');\n var allowMultiple = root.query('GET_ALLOW_MULTIPLE');\n var totalItems = root.query('GET_TOTAL_ITEMS');\n var maxItems = root.query('GET_MAX_FILES');\n\n \u002F\u002F total amount of items being dragged\n var totalBrowseItems = items.length;\n\n \u002F\u002F if does not allow multiple items and dragging more than one item\n if (!allowMultiple && totalBrowseItems \u003E 1) {\n return true;\n }\n\n \u002F\u002F limit max items to one if not allowed to drop multiple items\n maxItems = allowMultiple ? maxItems : allowReplace ? maxItems : 1;\n\n \u002F\u002F no more room?\n var hasMaxItems = isInt(maxItems);\n if (hasMaxItems && totalItems + totalBrowseItems \u003E maxItems) {\n root.dispatch('DID_THROW_MAX_FILES', {\n source: items,\n error: createResponse('warning', 0, 'Max files'),\n });\n\n return true;\n }\n\n return false;\n };\n\n var getDragIndex = function getDragIndex(list, children, position) {\n var itemList = list.childViews[0];\n return getItemIndexByPosition(itemList, children, {\n left: position.scopeLeft - itemList.rect.element.left,\n top:\n position.scopeTop -\n (list.rect.outer.top + list.rect.element.marginTop + list.rect.element.scrollTop),\n });\n };\n\n \u002F**\n * Enable or disable file drop functionality\n *\u002F\n var toggleDrop = function toggleDrop(root) {\n var isAllowed = root.query('GET_ALLOW_DROP');\n var isDisabled = root.query('GET_DISABLED');\n var enabled = isAllowed && !isDisabled;\n if (enabled && !root.ref.hopper) {\n var hopper = createHopper(\n root.element,\n function(items) {\n \u002F\u002F allow quick validation of dropped items\n var beforeDropFile =\n root.query('GET_BEFORE_DROP_FILE') ||\n function() {\n return true;\n };\n\n \u002F\u002F all items should be validated by all filters as valid\n var dropValidation = root.query('GET_DROP_VALIDATION');\n return dropValidation\n ? items.every(function(item) {\n return (\n applyFilters('ALLOW_HOPPER_ITEM', item, {\n query: root.query,\n }).every(function(result) {\n return result === true;\n }) && beforeDropFile(item)\n );\n })\n : true;\n },\n {\n filterItems: function filterItems(items) {\n var ignoredFiles = root.query('GET_IGNORED_FILES');\n return items.filter(function(item) {\n if (isFile(item)) {\n return !ignoredFiles.includes(item.name.toLowerCase());\n }\n return true;\n });\n },\n catchesDropsOnPage: root.query('GET_DROP_ON_PAGE'),\n requiresDropOnElement: root.query('GET_DROP_ON_ELEMENT'),\n }\n );\n\n hopper.onload = function(items, position) {\n \u002F\u002F get item children elements and sort based on list sort\n var list = root.ref.list.childViews[0];\n var visibleChildren = list.childViews.filter(function(child) {\n return child.rect.element.height;\n });\n var children = root\n .query('GET_ACTIVE_ITEMS')\n .map(function(item) {\n return visibleChildren.find(function(child) {\n return child.id === item.id;\n });\n })\n .filter(function(item) {\n return item;\n });\n\n applyFilterChain('ADD_ITEMS', items, { dispatch: root.dispatch }).then(function(\n queue\n ) {\n \u002F\u002F these files don't fit so stop here\n if (exceedsMaxFiles(root, queue)) return false;\n\n \u002F\u002F go\n root.dispatch('ADD_ITEMS', {\n items: queue,\n index: getDragIndex(root.ref.list, children, position),\n interactionMethod: InteractionMethod.DROP,\n });\n });\n\n root.dispatch('DID_DROP', { position: position });\n\n root.dispatch('DID_END_DRAG', { position: position });\n };\n\n hopper.ondragstart = function(position) {\n root.dispatch('DID_START_DRAG', { position: position });\n };\n\n hopper.ondrag = debounce(function(position) {\n root.dispatch('DID_DRAG', { position: position });\n });\n\n hopper.ondragend = function(position) {\n root.dispatch('DID_END_DRAG', { position: position });\n };\n\n root.ref.hopper = hopper;\n\n root.ref.drip = root.appendChildView(root.createChildView(drip));\n } else if (!enabled && root.ref.hopper) {\n root.ref.hopper.destroy();\n root.ref.hopper = null;\n root.removeChildView(root.ref.drip);\n }\n };\n\n \u002F**\n * Enable or disable browse functionality\n *\u002F\n var toggleBrowse = function toggleBrowse(root, props) {\n var isAllowed = root.query('GET_ALLOW_BROWSE');\n var isDisabled = root.query('GET_DISABLED');\n var enabled = isAllowed && !isDisabled;\n if (enabled && !root.ref.browser) {\n root.ref.browser = root.appendChildView(\n root.createChildView(\n browser,\n Object.assign({}, props, {\n onload: function onload(items) {\n applyFilterChain('ADD_ITEMS', items, {\n dispatch: root.dispatch,\n }).then(function(queue) {\n \u002F\u002F these files don't fit so stop here\n if (exceedsMaxFiles(root, queue)) return false;\n\n \u002F\u002F add items!\n root.dispatch('ADD_ITEMS', {\n items: queue,\n index: -1,\n interactionMethod: InteractionMethod.BROWSE,\n });\n });\n },\n })\n ),\n\n 0\n );\n } else if (!enabled && root.ref.browser) {\n root.removeChildView(root.ref.browser);\n root.ref.browser = null;\n }\n };\n\n \u002F**\n * Enable or disable paste functionality\n *\u002F\n var togglePaste = function togglePaste(root) {\n var isAllowed = root.query('GET_ALLOW_PASTE');\n var isDisabled = root.query('GET_DISABLED');\n var enabled = isAllowed && !isDisabled;\n if (enabled && !root.ref.paster) {\n root.ref.paster = createPaster();\n root.ref.paster.onload = function(items) {\n applyFilterChain('ADD_ITEMS', items, { dispatch: root.dispatch }).then(function(\n queue\n ) {\n \u002F\u002F these files don't fit so stop here\n if (exceedsMaxFiles(root, queue)) return false;\n\n \u002F\u002F add items!\n root.dispatch('ADD_ITEMS', {\n items: queue,\n index: -1,\n interactionMethod: InteractionMethod.PASTE,\n });\n });\n };\n } else if (!enabled && root.ref.paster) {\n root.ref.paster.destroy();\n root.ref.paster = null;\n }\n };\n\n \u002F**\n * Route actions\n *\u002F\n var route$5 = createRoute({\n DID_SET_ALLOW_BROWSE: function DID_SET_ALLOW_BROWSE(_ref5) {\n var root = _ref5.root,\n props = _ref5.props;\n toggleBrowse(root, props);\n },\n DID_SET_ALLOW_DROP: function DID_SET_ALLOW_DROP(_ref6) {\n var root = _ref6.root;\n toggleDrop(root);\n },\n DID_SET_ALLOW_PASTE: function DID_SET_ALLOW_PASTE(_ref7) {\n var root = _ref7.root;\n togglePaste(root);\n },\n DID_SET_DISABLED: function DID_SET_DISABLED(_ref8) {\n var root = _ref8.root,\n props = _ref8.props;\n toggleDrop(root);\n togglePaste(root);\n toggleBrowse(root, props);\n var isDisabled = root.query('GET_DISABLED');\n if (isDisabled) {\n root.element.dataset.disabled = 'disabled';\n } else {\n \u002F\u002F delete root.element.dataset.disabled; \u003C= this does not work on iOS 10\n root.element.removeAttribute('data-disabled');\n }\n },\n });\n\n var root = createView({\n name: 'root',\n read: function read(_ref9) {\n var root = _ref9.root;\n if (root.ref.measure) {\n root.ref.measureHeight = root.ref.measure.offsetHeight;\n }\n },\n create: create$e,\n write: write$9,\n destroy: function destroy(_ref10) {\n var root = _ref10.root;\n if (root.ref.paster) {\n root.ref.paster.destroy();\n }\n if (root.ref.hopper) {\n root.ref.hopper.destroy();\n }\n root.element.removeEventListener('touchmove', prevent);\n root.element.removeEventListener('gesturestart', prevent);\n },\n mixins: {\n styles: ['height'],\n },\n });\n\n \u002F\u002F creates the app\n var createApp = function createApp() {\n var initialOptions = arguments.length \u003E 0 && arguments[0] !== undefined ? arguments[0] : {};\n \u002F\u002F let element\n var originalElement = null;\n\n \u002F\u002F get default options\n var defaultOptions = getOptions();\n\n \u002F\u002F create the data store, this will contain all our app info\n var store = createStore(\n \u002F\u002F initial state (should be serializable)\n createInitialState(defaultOptions),\n\n \u002F\u002F queries\n [queries, createOptionQueries(defaultOptions)],\n\n \u002F\u002F action handlers\n [actions, createOptionActions(defaultOptions)]\n );\n\n \u002F\u002F set initial options\n store.dispatch('SET_OPTIONS', { options: initialOptions });\n\n \u002F\u002F kick thread if visibility changes\n var visibilityHandler = function visibilityHandler() {\n if (document.hidden) return;\n store.dispatch('KICK');\n };\n document.addEventListener('visibilitychange', visibilityHandler);\n\n \u002F\u002F re-render on window resize start and finish\n var resizeDoneTimer = null;\n var isResizing = false;\n var isResizingHorizontally = false;\n var initialWindowWidth = null;\n var currentWindowWidth = null;\n var resizeHandler = function resizeHandler() {\n if (!isResizing) {\n isResizing = true;\n }\n clearTimeout(resizeDoneTimer);\n resizeDoneTimer = setTimeout(function() {\n isResizing = false;\n initialWindowWidth = null;\n currentWindowWidth = null;\n if (isResizingHorizontally) {\n isResizingHorizontally = false;\n store.dispatch('DID_STOP_RESIZE');\n }\n }, 500);\n };\n window.addEventListener('resize', resizeHandler);\n\n \u002F\u002F render initial view\n var view = root(store, { id: getUniqueId() });\n\n \u002F\u002F\n \u002F\u002F PRIVATE API -------------------------------------------------------------------------------------\n \u002F\u002F\n var isResting = false;\n var isHidden = false;\n\n var readWriteApi = {\n \u002F\u002F necessary for update loop\n\n \u002F**\n * Reads from dom (never call manually)\n * @private\n *\u002F\n _read: function _read() {\n \u002F\u002F test if we're resizing horizontally\n \u002F\u002F TODO: see if we can optimize this by measuring root rect\n if (isResizing) {\n currentWindowWidth = window.innerWidth;\n if (!initialWindowWidth) {\n initialWindowWidth = currentWindowWidth;\n }\n\n if (!isResizingHorizontally && currentWindowWidth !== initialWindowWidth) {\n store.dispatch('DID_START_RESIZE');\n isResizingHorizontally = true;\n }\n }\n\n if (isHidden && isResting) {\n \u002F\u002F test if is no longer hidden\n isResting = view.element.offsetParent === null;\n }\n\n \u002F\u002F if resting, no need to read as numbers will still all be correct\n if (isResting) return;\n\n \u002F\u002F read view data\n view._read();\n\n \u002F\u002F if is hidden we need to know so we exit rest mode when revealed\n isHidden = view.rect.element.hidden;\n },\n\n \u002F**\n * Writes to dom (never call manually)\n * @private\n *\u002F\n _write: function _write(ts) {\n \u002F\u002F get all actions from store\n var actions = store\n .processActionQueue()\n\n \u002F\u002F filter out set actions (these will automatically trigger DID_SET)\n .filter(function(action) {\n return !\u002F^SET_\u002F.test(action.type);\n });\n\n \u002F\u002F if was idling and no actions stop here\n if (isResting && !actions.length) return;\n\n \u002F\u002F some actions might trigger events\n routeActionsToEvents(actions);\n\n \u002F\u002F update the view\n isResting = view._write(ts, actions, isResizingHorizontally);\n\n \u002F\u002F will clean up all archived items\n removeReleasedItems(store.query('GET_ITEMS'));\n\n \u002F\u002F now idling\n if (isResting) {\n store.processDispatchQueue();\n }\n },\n };\n\n \u002F\u002F\n \u002F\u002F EXPOSE EVENTS -------------------------------------------------------------------------------------\n \u002F\u002F\n var createEvent = function createEvent(name) {\n return function(data) {\n \u002F\u002F create default event\n var event = {\n type: name,\n };\n\n \u002F\u002F no data to add\n if (!data) {\n return event;\n }\n\n \u002F\u002F copy relevant props\n if (data.hasOwnProperty('error')) {\n event.error = data.error ? Object.assign({}, data.error) : null;\n }\n\n if (data.status) {\n event.status = Object.assign({}, data.status);\n }\n\n if (data.file) {\n event.output = data.file;\n }\n\n \u002F\u002F only source is available, else add item if possible\n if (data.source) {\n event.file = data.source;\n } else if (data.item || data.id) {\n var item = data.item ? data.item : store.query('GET_ITEM', data.id);\n event.file = item ? createItemAPI(item) : null;\n }\n\n \u002F\u002F map all items in a possible items array\n if (data.items) {\n event.items = data.items.map(createItemAPI);\n }\n\n \u002F\u002F if this is a progress event add the progress amount\n if (\u002Fprogress\u002F.test(name)) {\n event.progress = data.progress;\n }\n\n \u002F\u002F copy relevant props\n if (data.hasOwnProperty('origin') && data.hasOwnProperty('target')) {\n event.origin = data.origin;\n event.target = data.target;\n }\n\n return event;\n };\n };\n\n var eventRoutes = {\n DID_DESTROY: createEvent('destroy'),\n\n DID_INIT: createEvent('init'),\n\n DID_THROW_MAX_FILES: createEvent('warning'),\n\n DID_INIT_ITEM: createEvent('initfile'),\n DID_START_ITEM_LOAD: createEvent('addfilestart'),\n DID_UPDATE_ITEM_LOAD_PROGRESS: createEvent('addfileprogress'),\n DID_LOAD_ITEM: createEvent('addfile'),\n\n DID_THROW_ITEM_INVALID: [createEvent('error'), createEvent('addfile')],\n\n DID_THROW_ITEM_LOAD_ERROR: [createEvent('error'), createEvent('addfile')],\n\n DID_THROW_ITEM_REMOVE_ERROR: [createEvent('error'), createEvent('removefile')],\n\n DID_PREPARE_OUTPUT: createEvent('preparefile'),\n\n DID_START_ITEM_PROCESSING: createEvent('processfilestart'),\n DID_UPDATE_ITEM_PROCESS_PROGRESS: createEvent('processfileprogress'),\n DID_ABORT_ITEM_PROCESSING: createEvent('processfileabort'),\n DID_COMPLETE_ITEM_PROCESSING: createEvent('processfile'),\n DID_COMPLETE_ITEM_PROCESSING_ALL: createEvent('processfiles'),\n DID_REVERT_ITEM_PROCESSING: createEvent('processfilerevert'),\n\n DID_THROW_ITEM_PROCESSING_ERROR: [createEvent('error'), createEvent('processfile')],\n\n DID_REMOVE_ITEM: createEvent('removefile'),\n\n DID_UPDATE_ITEMS: createEvent('updatefiles'),\n\n DID_ACTIVATE_ITEM: createEvent('activatefile'),\n\n DID_REORDER_ITEMS: createEvent('reorderfiles'),\n };\n\n var exposeEvent = function exposeEvent(event) {\n \u002F\u002F create event object to be dispatched\n var detail = Object.assign({ pond: exports }, event);\n delete detail.type;\n view.element.dispatchEvent(\n new CustomEvent('FilePond:' + event.type, {\n \u002F\u002F event info\n detail: detail,\n\n \u002F\u002F event behaviour\n bubbles: true,\n cancelable: true,\n composed: true, \u002F\u002F triggers listeners outside of shadow root\n })\n );\n\n \u002F\u002F event object to params used for `on()` event handlers and callbacks `oninit()`\n var params = [];\n\n \u002F\u002F if is possible error event, make it the first param\n if (event.hasOwnProperty('error')) {\n params.push(event.error);\n }\n\n \u002F\u002F file is always section\n if (event.hasOwnProperty('file')) {\n params.push(event.file);\n }\n\n \u002F\u002F append other props\n var filtered = ['type', 'error', 'file'];\n Object.keys(event)\n .filter(function(key) {\n return !filtered.includes(key);\n })\n .forEach(function(key) {\n return params.push(event[key]);\n });\n\n \u002F\u002F on(type, () =\u003E { })\n exports.fire.apply(exports, [event.type].concat(params));\n\n \u002F\u002F oninit = () =\u003E {}\n var handler = store.query('GET_ON' + event.type.toUpperCase());\n if (handler) {\n handler.apply(void 0, params);\n }\n };\n\n var routeActionsToEvents = function routeActionsToEvents(actions) {\n if (!actions.length) return;\n actions\n .filter(function(action) {\n return eventRoutes[action.type];\n })\n .forEach(function(action) {\n var routes = eventRoutes[action.type];\n (Array.isArray(routes) ? routes : [routes]).forEach(function(route) {\n \u002F\u002F this isn't fantastic, but because of the stacking of settimeouts plugins can handle the did_load before the did_init\n if (action.type === 'DID_INIT_ITEM') {\n exposeEvent(route(action.data));\n } else {\n setTimeout(function() {\n exposeEvent(route(action.data));\n }, 0);\n }\n });\n });\n };\n\n \u002F\u002F\n \u002F\u002F PUBLIC API -------------------------------------------------------------------------------------\n \u002F\u002F\n var setOptions = function setOptions(options) {\n return store.dispatch('SET_OPTIONS', { options: options });\n };\n\n var getFile = function getFile(query) {\n return store.query('GET_ACTIVE_ITEM', query);\n };\n\n var prepareFile = function prepareFile(query) {\n return new Promise(function(resolve, reject) {\n store.dispatch('REQUEST_ITEM_PREPARE', {\n query: query,\n success: function success(item) {\n resolve(item);\n },\n failure: function failure(error) {\n reject(error);\n },\n });\n });\n };\n\n var addFile = function addFile(source) {\n var options = arguments.length \u003E 1 && arguments[1] !== undefined ? arguments[1] : {};\n return new Promise(function(resolve, reject) {\n addFiles([{ source: source, options: options }], { index: options.index })\n .then(function(items) {\n return resolve(items && items[0]);\n })\n .catch(reject);\n });\n };\n\n var isFilePondFile = function isFilePondFile(obj) {\n return obj.file && obj.id;\n };\n\n var removeFile = function removeFile(query, options) {\n \u002F\u002F if only passed options\n if (typeof query === 'object' && !isFilePondFile(query) && !options) {\n options = query;\n query = undefined;\n }\n\n \u002F\u002F request item removal\n store.dispatch('REMOVE_ITEM', Object.assign({}, options, { query: query }));\n\n \u002F\u002F see if item has been removed\n return store.query('GET_ACTIVE_ITEM', query) === null;\n };\n\n var addFiles = function addFiles() {\n for (\n var _len = arguments.length, args = new Array(_len), _key = 0;\n _key \u003C _len;\n _key++\n ) {\n args[_key] = arguments[_key];\n }\n return new Promise(function(resolve, reject) {\n var sources = [];\n var options = {};\n\n \u002F\u002F user passed a sources array\n if (isArray(args[0])) {\n sources.push.apply(sources, args[0]);\n Object.assign(options, args[1] || {});\n } else {\n \u002F\u002F user passed sources as arguments, last one might be options object\n var lastArgument = args[args.length - 1];\n if (typeof lastArgument === 'object' && !(lastArgument instanceof Blob)) {\n Object.assign(options, args.pop());\n }\n\n \u002F\u002F add rest to sources\n sources.push.apply(sources, args);\n }\n\n store.dispatch('ADD_ITEMS', {\n items: sources,\n index: options.index,\n interactionMethod: InteractionMethod.API,\n success: resolve,\n failure: reject,\n });\n });\n };\n\n var getFiles = function getFiles() {\n return store.query('GET_ACTIVE_ITEMS');\n };\n\n var processFile = function processFile(query) {\n return new Promise(function(resolve, reject) {\n store.dispatch('REQUEST_ITEM_PROCESSING', {\n query: query,\n success: function success(item) {\n resolve(item);\n },\n failure: function failure(error) {\n reject(error);\n },\n });\n });\n };\n\n var prepareFiles = function prepareFiles() {\n for (\n var _len2 = arguments.length, args = new Array(_len2), _key2 = 0;\n _key2 \u003C _len2;\n _key2++\n ) {\n args[_key2] = arguments[_key2];\n }\n var queries = Array.isArray(args[0]) ? args[0] : args;\n var items = queries.length ? queries : getFiles();\n return Promise.all(items.map(prepareFile));\n };\n\n var processFiles = function processFiles() {\n for (\n var _len3 = arguments.length, args = new Array(_len3), _key3 = 0;\n _key3 \u003C _len3;\n _key3++\n ) {\n args[_key3] = arguments[_key3];\n }\n var queries = Array.isArray(args[0]) ? args[0] : args;\n if (!queries.length) {\n var files = getFiles().filter(function(item) {\n return (\n !(item.status === ItemStatus.IDLE && item.origin === FileOrigin.LOCAL) &&\n item.status !== ItemStatus.PROCESSING &&\n item.status !== ItemStatus.PROCESSING_COMPLETE &&\n item.status !== ItemStatus.PROCESSING_REVERT_ERROR\n );\n });\n\n return Promise.all(files.map(processFile));\n }\n return Promise.all(queries.map(processFile));\n };\n\n var removeFiles = function removeFiles() {\n for (\n var _len4 = arguments.length, args = new Array(_len4), _key4 = 0;\n _key4 \u003C _len4;\n _key4++\n ) {\n args[_key4] = arguments[_key4];\n }\n\n var queries = Array.isArray(args[0]) ? args[0] : args;\n\n var options;\n if (typeof queries[queries.length - 1] === 'object') {\n options = queries.pop();\n } else if (Array.isArray(args[0])) {\n options = args[1];\n }\n\n var files = getFiles();\n\n if (!queries.length)\n return Promise.all(\n files.map(function(file) {\n return removeFile(file, options);\n })\n );\n\n \u002F\u002F when removing by index the indexes shift after each file removal so we need to convert indexes to ids\n var mappedQueries = queries\n .map(function(query) {\n return isNumber(query) ? (files[query] ? files[query].id : null) : query;\n })\n .filter(function(query) {\n return query;\n });\n\n return mappedQueries.map(function(q) {\n return removeFile(q, options);\n });\n };\n\n var exports = Object.assign(\n {},\n\n on(),\n {},\n\n readWriteApi,\n {},\n\n createOptionAPI(store, defaultOptions),\n {\n \u002F**\n * Override options defined in options object\n * @param options\n *\u002F\n setOptions: setOptions,\n\n \u002F**\n * Load the given file\n * @param source - the source of the file (either a File, base64 data uri or url)\n * @param options - object, { index: 0 }\n *\u002F\n addFile: addFile,\n\n \u002F**\n * Load the given files\n * @param sources - the sources of the files to load\n * @param options - object, { index: 0 }\n *\u002F\n addFiles: addFiles,\n\n \u002F**\n * Returns the file objects matching the given query\n * @param query { string, number, null }\n *\u002F\n getFile: getFile,\n\n \u002F**\n * Upload file with given name\n * @param query { string, number, null }\n *\u002F\n processFile: processFile,\n\n \u002F**\n * Request prepare output for file with given name\n * @param query { string, number, null }\n *\u002F\n prepareFile: prepareFile,\n\n \u002F**\n * Removes a file by its name\n * @param query { string, number, null }\n *\u002F\n removeFile: removeFile,\n\n \u002F**\n * Moves a file to a new location in the files list\n *\u002F\n moveFile: function moveFile(query, index) {\n return store.dispatch('MOVE_ITEM', { query: query, index: index });\n },\n\n \u002F**\n * Returns all files (wrapped in public api)\n *\u002F\n getFiles: getFiles,\n\n \u002F**\n * Starts uploading all files\n *\u002F\n processFiles: processFiles,\n\n \u002F**\n * Clears all files from the files list\n *\u002F\n removeFiles: removeFiles,\n\n \u002F**\n * Starts preparing output of all files\n *\u002F\n prepareFiles: prepareFiles,\n\n \u002F**\n * Sort list of files\n *\u002F\n sort: function sort(compare) {\n return store.dispatch('SORT', { compare: compare });\n },\n\n \u002F**\n * Browse the file system for a file\n *\u002F\n browse: function browse() {\n \u002F\u002F needs to be trigger directly as user action needs to be traceable (is not traceable in requestAnimationFrame)\n var input = view.element.querySelector('input[type=file]');\n if (input) {\n input.click();\n }\n },\n\n \u002F**\n * Destroys the app\n *\u002F\n destroy: function destroy() {\n \u002F\u002F request destruction\n exports.fire('destroy', view.element);\n\n \u002F\u002F stop active processes (file uploads, fetches, stuff like that)\n \u002F\u002F loop over items and depending on states call abort for ongoing processes\n store.dispatch('ABORT_ALL');\n\n \u002F\u002F destroy view\n view._destroy();\n\n \u002F\u002F stop listening to resize\n window.removeEventListener('resize', resizeHandler);\n\n \u002F\u002F stop listening to the visiblitychange event\n document.removeEventListener('visibilitychange', visibilityHandler);\n\n \u002F\u002F dispatch destroy\n store.dispatch('DID_DESTROY');\n },\n\n \u002F**\n * Inserts the plugin before the target element\n *\u002F\n insertBefore: function insertBefore$1(element) {\n return insertBefore(view.element, element);\n },\n\n \u002F**\n * Inserts the plugin after the target element\n *\u002F\n insertAfter: function insertAfter$1(element) {\n return insertAfter(view.element, element);\n },\n\n \u002F**\n * Appends the plugin to the target element\n *\u002F\n appendTo: function appendTo(element) {\n return element.appendChild(view.element);\n },\n\n \u002F**\n * Replaces an element with the app\n *\u002F\n replaceElement: function replaceElement(element) {\n \u002F\u002F insert the app before the element\n insertBefore(view.element, element);\n\n \u002F\u002F remove the original element\n element.parentNode.removeChild(element);\n\n \u002F\u002F remember original element\n originalElement = element;\n },\n\n \u002F**\n * Restores the original element\n *\u002F\n restoreElement: function restoreElement() {\n if (!originalElement) {\n return; \u002F\u002F no element to restore\n }\n\n \u002F\u002F restore original element\n insertAfter(originalElement, view.element);\n\n \u002F\u002F remove our element\n view.element.parentNode.removeChild(view.element);\n\n \u002F\u002F remove reference\n originalElement = null;\n },\n\n \u002F**\n * Returns true if the app root is attached to given element\n * @param element\n *\u002F\n isAttachedTo: function isAttachedTo(element) {\n return view.element === element || originalElement === element;\n },\n\n \u002F**\n * Returns the root element\n *\u002F\n element: {\n get: function get() {\n return view.element;\n },\n },\n\n \u002F**\n * Returns the current pond status\n *\u002F\n status: {\n get: function get() {\n return store.query('GET_STATUS');\n },\n },\n }\n );\n\n \u002F\u002F Done!\n store.dispatch('DID_INIT');\n\n \u002F\u002F create actual api object\n return createObject(exports);\n };\n\n var createAppObject = function createAppObject() {\n var customOptions = arguments.length \u003E 0 && arguments[0] !== undefined ? arguments[0] : {};\n \u002F\u002F default options\n var defaultOptions = {};\n forin(getOptions(), function(key, value) {\n defaultOptions[key] = value[0];\n });\n\n \u002F\u002F set app options\n var app = createApp(\n Object.assign(\n {},\n\n defaultOptions,\n {},\n\n customOptions\n )\n );\n\n \u002F\u002F return the plugin instance\n return app;\n };\n\n var lowerCaseFirstLetter = function lowerCaseFirstLetter(string) {\n return string.charAt(0).toLowerCase() + string.slice(1);\n };\n\n var attributeNameToPropertyName = function attributeNameToPropertyName(attributeName) {\n return toCamels(attributeName.replace(\u002F^data-\u002F, ''));\n };\n\n var mapObject = function mapObject(object, propertyMap) {\n \u002F\u002F remove unwanted\n forin(propertyMap, function(selector, mapping) {\n forin(object, function(property, value) {\n \u002F\u002F create regexp shortcut\n var selectorRegExp = new RegExp(selector);\n\n \u002F\u002F tests if\n var matches = selectorRegExp.test(property);\n\n \u002F\u002F no match, skip\n if (!matches) {\n return;\n }\n\n \u002F\u002F if there's a mapping, the original property is always removed\n delete object[property];\n\n \u002F\u002F should only remove, we done!\n if (mapping === false) {\n return;\n }\n\n \u002F\u002F move value to new property\n if (isString(mapping)) {\n object[mapping] = value;\n return;\n }\n\n \u002F\u002F move to group\n var group = mapping.group;\n if (isObject(mapping) && !object[group]) {\n object[group] = {};\n }\n\n object[group][lowerCaseFirstLetter(property.replace(selectorRegExp, ''))] = value;\n });\n\n \u002F\u002F do submapping\n if (mapping.mapping) {\n mapObject(object[mapping.group], mapping.mapping);\n }\n });\n };\n\n var getAttributesAsObject = function getAttributesAsObject(node) {\n var attributeMapping =\n arguments.length \u003E 1 && arguments[1] !== undefined ? arguments[1] : {};\n \u002F\u002F turn attributes into object\n var attributes = [];\n forin(node.attributes, function(index) {\n attributes.push(node.attributes[index]);\n });\n\n var output = attributes\n .filter(function(attribute) {\n return attribute.name;\n })\n .reduce(function(obj, attribute) {\n var value = attr(node, attribute.name);\n\n obj[attributeNameToPropertyName(attribute.name)] =\n value === attribute.name ? true : value;\n return obj;\n }, {});\n\n \u002F\u002F do mapping of object properties\n mapObject(output, attributeMapping);\n\n return output;\n };\n\n var createAppAtElement = function createAppAtElement(element) {\n var options = arguments.length \u003E 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n \u002F\u002F how attributes of the input element are mapped to the options for the plugin\n var attributeMapping = {\n \u002F\u002F translate to other name\n '^class
: 'className',\n '^multiple
: 'allowMultiple',\n '^capture
: 'captureMethod',\n '^webkitdirectory
: 'allowDirectoriesOnly',\n\n \u002F\u002F group under single property\n '^server': {\n group: 'server',\n mapping: {\n '^process': {\n group: 'process',\n },\n\n '^revert': {\n group: 'revert',\n },\n\n '^fetch': {\n group: 'fetch',\n },\n\n '^restore': {\n group: 'restore',\n },\n\n '^load': {\n group: 'load',\n },\n },\n },\n\n \u002F\u002F don't include in object\n '^type
: false,\n '^files
: false,\n };\n\n \u002F\u002F add additional option translators\n applyFilters('SET_ATTRIBUTE_TO_OPTION_MAP', attributeMapping);\n\n \u002F\u002F create final options object by setting options object and then overriding options supplied on element\n var mergedOptions = Object.assign({}, options);\n\n var attributeOptions = getAttributesAsObject(\n element.nodeName === 'FIELDSET' ? element.querySelector('input[type=file]') : element,\n attributeMapping\n );\n\n \u002F\u002F merge with options object\n Object.keys(attributeOptions).forEach(function(key) {\n if (isObject(attributeOptions[key])) {\n if (!isObject(mergedOptions[key])) {\n mergedOptions[key] = {};\n }\n Object.assign(mergedOptions[key], attributeOptions[key]);\n } else {\n mergedOptions[key] = attributeOptions[key];\n }\n });\n\n \u002F\u002F if parent is a fieldset, get files from parent by selecting all input fields that are not file upload fields\n \u002F\u002F these will then be automatically set to the initial files\n mergedOptions.files = (options.files || []).concat(\n Array.from(element.querySelectorAll('input:not([type=file])')).map(function(input) {\n return {\n source: input.value,\n options: {\n type: input.dataset.type,\n },\n };\n })\n );\n\n \u002F\u002F build plugin\n var app = createAppObject(mergedOptions);\n\n \u002F\u002F add already selected files\n if (element.files) {\n Array.from(element.files).forEach(function(file) {\n app.addFile(file);\n });\n }\n\n \u002F\u002F replace the target element\n app.replaceElement(element);\n\n \u002F\u002F expose\n return app;\n };\n\n \u002F\u002F if an element is passed, we create the instance at that element, if not, we just create an up object\n var createApp$1 = function createApp() {\n return isNode(arguments.length \u003C= 0 ? undefined : arguments[0])\n ? createAppAtElement.apply(void 0, arguments)\n : createAppObject.apply(void 0, arguments);\n };\n\n var PRIVATE_METHODS = ['fire', '_read', '_write'];\n\n var createAppAPI = function createAppAPI(app) {\n var api = {};\n\n copyObjectPropertiesToObject(app, api, PRIVATE_METHODS);\n\n return api;\n };\n\n \u002F**\n * Replaces placeholders in given string with replacements\n * @param string - \"Foo {bar}\"\"\n * @param replacements - { \"bar\": 10 }\n *\u002F\n var replaceInString = function replaceInString(string, replacements) {\n return string.replace(\u002F(?:{([a-zA-Z]+)})\u002Fg, function(match, group) {\n return replacements[group];\n });\n };\n\n var createWorker = function createWorker(fn) {\n var workerBlob = new Blob(['(', fn.toString(), ')()'], {\n type: 'application\u002Fjavascript',\n });\n\n var workerURL = URL.createObjectURL(workerBlob);\n var worker = new Worker(workerURL);\n\n return {\n transfer: function transfer(message, cb) {},\n post: function post(message, cb, transferList) {\n var id = getUniqueId();\n\n worker.onmessage = function(e) {\n if (e.data.id === id) {\n cb(e.data.message);\n }\n };\n\n worker.postMessage(\n {\n id: id,\n message: message,\n },\n\n transferList\n );\n },\n terminate: function terminate() {\n worker.terminate();\n URL.revokeObjectURL(workerURL);\n },\n };\n };\n\n var loadImage = function loadImage(url) {\n return new Promise(function(resolve, reject) {\n var img = new Image();\n img.onload = function() {\n resolve(img);\n };\n img.onerror = function(e) {\n reject(e);\n };\n img.src = url;\n });\n };\n\n var renameFile = function renameFile(file, name) {\n var renamedFile = file.slice(0, file.size, file.type);\n renamedFile.lastModifiedDate = file.lastModifiedDate;\n renamedFile.name = name;\n return renamedFile;\n };\n\n var copyFile = function copyFile(file) {\n return renameFile(file, file.name);\n };\n\n \u002F\u002F already registered plugins (can't register twice)\n var registeredPlugins = [];\n\n \u002F\u002F pass utils to plugin\n var createAppPlugin = function createAppPlugin(plugin) {\n \u002F\u002F already registered\n if (registeredPlugins.includes(plugin)) {\n return;\n }\n\n \u002F\u002F remember this plugin\n registeredPlugins.push(plugin);\n\n \u002F\u002F setup!\n var pluginOutline = plugin({\n addFilter: addFilter,\n utils: {\n Type: Type,\n forin: forin,\n isString: isString,\n isFile: isFile,\n toNaturalFileSize: toNaturalFileSize,\n replaceInString: replaceInString,\n getExtensionFromFilename: getExtensionFromFilename,\n getFilenameWithoutExtension: getFilenameWithoutExtension,\n guesstimateMimeType: guesstimateMimeType,\n getFileFromBlob: getFileFromBlob,\n getFilenameFromURL: getFilenameFromURL,\n createRoute: createRoute,\n createWorker: createWorker,\n createView: createView,\n createItemAPI: createItemAPI,\n loadImage: loadImage,\n copyFile: copyFile,\n renameFile: renameFile,\n createBlob: createBlob,\n applyFilterChain: applyFilterChain,\n text: text,\n getNumericAspectRatioFromString: getNumericAspectRatioFromString,\n },\n\n views: {\n fileActionButton: fileActionButton,\n },\n });\n\n \u002F\u002F add plugin options to default options\n extendDefaultOptions(pluginOutline.options);\n };\n\n \u002F\u002F feature detection used by supported() method\n var isOperaMini = function isOperaMini() {\n return Object.prototype.toString.call(window.operamini) === '[object OperaMini]';\n };\n var hasPromises = function hasPromises() {\n return 'Promise' in window;\n };\n var hasBlobSlice = function hasBlobSlice() {\n return 'slice' in Blob.prototype;\n };\n var hasCreateObjectURL = function hasCreateObjectURL() {\n return 'URL' in window && 'createObjectURL' in window.URL;\n };\n var hasVisibility = function hasVisibility() {\n return 'visibilityState' in document;\n };\n var hasTiming = function hasTiming() {\n return 'performance' in window;\n }; \u002F\u002F iOS 8.x\n var hasCSSSupports = function hasCSSSupports() {\n return 'supports' in (window.CSS || {});\n }; \u002F\u002F use to detect Safari 9+\n var isIE11 = function isIE11() {\n return \u002FMSIE|Trident\u002F.test(window.navigator.userAgent);\n };\n\n var supported = (function() {\n \u002F\u002F Runs immediately and then remembers result for subsequent calls\n var isSupported =\n \u002F\u002F Has to be a browser\n isBrowser() &&\n \u002F\u002F Can't run on Opera Mini due to lack of everything\n !isOperaMini() &&\n \u002F\u002F Require these APIs to feature detect a modern browser\n hasVisibility() &&\n hasPromises() &&\n hasBlobSlice() &&\n hasCreateObjectURL() &&\n hasTiming() &&\n \u002F\u002F doesn't need CSSSupports but is a good way to detect Safari 9+ (we do want to support IE11 though)\n (hasCSSSupports() || isIE11());\n\n return function() {\n return isSupported;\n };\n })();\n\n \u002F**\n * Plugin internal state (over all instances)\n *\u002F\n var state = {\n \u002F\u002F active app instances, used to redraw the apps and to find the later\n apps: [],\n };\n\n \u002F\u002F plugin name\n var name = 'filepond';\n\n \u002F**\n * Public Plugin methods\n *\u002F\n var fn = function fn() {};\n exports.Status = {};\n exports.FileStatus = {};\n exports.FileOrigin = {};\n exports.OptionTypes = {};\n exports.create = fn;\n exports.destroy = fn;\n exports.parse = fn;\n exports.find = fn;\n exports.registerPlugin = fn;\n exports.getOptions = fn;\n exports.setOptions = fn;\n\n \u002F\u002F if not supported, no API\n if (supported()) {\n \u002F\u002F start painter and fire load event\n createPainter(\n function() {\n state.apps.forEach(function(app) {\n return app._read();\n });\n },\n function(ts) {\n state.apps.forEach(function(app) {\n return app._write(ts);\n });\n }\n );\n\n \u002F\u002F fire loaded event so we know when FilePond is available\n var dispatch = function dispatch() {\n \u002F\u002F let others know we have area ready\n document.dispatchEvent(\n new CustomEvent('FilePond:loaded', {\n detail: {\n supported: supported,\n create: exports.create,\n destroy: exports.destroy,\n parse: exports.parse,\n find: exports.find,\n registerPlugin: exports.registerPlugin,\n setOptions: exports.setOptions,\n },\n })\n );\n\n \u002F\u002F clean up event\n document.removeEventListener('DOMContentLoaded', dispatch);\n };\n\n if (document.readyState !== 'loading') {\n \u002F\u002F move to back of execution queue, FilePond should have been exported by then\n setTimeout(function() {\n return dispatch();\n }, 0);\n } else {\n document.addEventListener('DOMContentLoaded', dispatch);\n }\n\n \u002F\u002F updates the OptionTypes object based on the current options\n var updateOptionTypes = function updateOptionTypes() {\n return forin(getOptions(), function(key, value) {\n exports.OptionTypes[key] = value[1];\n });\n };\n\n exports.Status = Object.assign({}, Status);\n exports.FileOrigin = Object.assign({}, FileOrigin);\n exports.FileStatus = Object.assign({}, ItemStatus);\n\n exports.OptionTypes = {};\n updateOptionTypes();\n\n \u002F\u002F create method, creates apps and adds them to the app array\n exports.create = function create() {\n var app = createApp$1.apply(void 0, arguments);\n app.on('destroy', exports.destroy);\n state.apps.push(app);\n return createAppAPI(app);\n };\n\n \u002F\u002F destroys apps and removes them from the app array\n exports.destroy = function destroy(hook) {\n \u002F\u002F returns true if the app was destroyed successfully\n var indexToRemove = state.apps.findIndex(function(app) {\n return app.isAttachedTo(hook);\n });\n if (indexToRemove \u003E= 0) {\n \u002F\u002F remove from apps\n var app = state.apps.splice(indexToRemove, 1)[0];\n\n \u002F\u002F restore original dom element\n app.restoreElement();\n\n return true;\n }\n\n return false;\n };\n\n \u002F\u002F parses the given context for plugins (does not include the context element itself)\n exports.parse = function parse(context) {\n \u002F\u002F get all possible hooks\n var matchedHooks = Array.from(context.querySelectorAll('.' + name));\n\n \u002F\u002F filter out already active hooks\n var newHooks = matchedHooks.filter(function(newHook) {\n return !state.apps.find(function(app) {\n return app.isAttachedTo(newHook);\n });\n });\n\n \u002F\u002F create new instance for each hook\n return newHooks.map(function(hook) {\n return exports.create(hook);\n });\n };\n\n \u002F\u002F returns an app based on the given element hook\n exports.find = function find(hook) {\n var app = state.apps.find(function(app) {\n return app.isAttachedTo(hook);\n });\n if (!app) {\n return null;\n }\n return createAppAPI(app);\n };\n\n \u002F\u002F adds a plugin extension\n exports.registerPlugin = function registerPlugin() {\n for (\n var _len = arguments.length, plugins = new Array(_len), _key = 0;\n _key \u003C _len;\n _key++\n ) {\n plugins[_key] = arguments[_key];\n }\n\n \u002F\u002F register plugins\n plugins.forEach(createAppPlugin);\n\n \u002F\u002F update OptionTypes, each plugin might have extended the default options\n updateOptionTypes();\n };\n\n exports.getOptions = function getOptions$1() {\n var opts = {};\n forin(getOptions(), function(key, value) {\n opts[key] = value[0];\n });\n return opts;\n };\n\n exports.setOptions = function setOptions$1(opts) {\n if (isObject(opts)) {\n \u002F\u002F update existing plugins\n state.apps.forEach(function(app) {\n app.setOptions(opts);\n });\n\n \u002F\u002F override defaults\n setOptions(opts);\n }\n\n \u002F\u002F return new options\n return exports.getOptions();\n };\n }\n\n exports.supported = supported;\n\n Object.defineProperty(exports, '__esModule', { value: true });\n});\n","id":"cee41f1b-12c1-4b5c-a909-c70721bfdcb0","is_binary":false,"title":"filepond.js","sha":null,"inserted_at":"2021-07-05T16:41:13","updated_at":"2021-07-05T16:41:13","upload_id":null,"shortid":"H1ZNL3gaO","source_id":"50161fbc-cae5-478e-b223-783e0c89506e","directory_shortid":null},{"code":"\u002F*!\n * FilePond 4.28.2\n * Licensed under MIT, https:\u002F\u002Fopensource.org\u002Flicenses\u002FMIT\u002F\n * Please visit https:\u002F\u002Fpqina.nl\u002Ffilepond\u002F for details.\n *\u002F\n\n\u002F* eslint-disable *\u002F\n.filepond--assistant {\n position: absolute;\n overflow: hidden;\n height: 1px;\n width: 1px;\n padding: 0;\n border: 0;\n clip: rect(1px, 1px, 1px, 1px);\n -webkit-clip-path: inset(50%);\n clip-path: inset(50%);\n white-space: nowrap;\n}\n\u002F* Hard to override styles *\u002F\n.filepond--browser.filepond--browser {\n \u002F* is positioned absolute so it is focusable for form validation errors *\u002F\n position: absolute;\n margin: 0;\n padding: 0;\n\n \u002F* is positioned ~behind drop label *\u002F\n left: 1em;\n top: 1.75em;\n width: calc(100% - 2em);\n\n \u002F* hide visually *\u002F\n opacity: 0;\n font-size: 0; \u002F* removes text cursor in Internet Explorer 11 *\u002F\n}\n.filepond--data {\n position: absolute;\n width: 0;\n height: 0;\n padding: 0;\n margin: 0;\n border: none;\n visibility: hidden;\n pointer-events: none;\n contain: strict;\n}\n.filepond--drip {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n overflow: hidden;\n opacity: 0.1;\n\n \u002F* can't interact with this element *\u002F\n pointer-events: none;\n\n \u002F* inherit border radius from parent (needed for drip-blob cut of) *\u002F\n border-radius: 0.5em;\n\n \u002F* this seems to prevent Chrome from redrawing this layer constantly *\u002F\n background: rgba(0, 0, 0, 0.01);\n}\n.filepond--drip-blob {\n position: absolute;\n -webkit-transform-origin: center center;\n transform-origin: center center;\n top: 0;\n left: 0;\n width: 8em;\n height: 8em;\n margin-left: -4em;\n margin-top: -4em;\n background: #292625;\n border-radius: 50%;\n\n \u002F* will be animated *\u002F\n will-change: transform, opacity;\n}\n.filepond--drop-label {\n position: absolute;\n left: 0;\n right: 0;\n top: 0;\n margin: 0;\n color: #4f4f4f;\n\n \u002F* center contents *\u002F\n display: flex;\n justify-content: center;\n align-items: center;\n\n \u002F* fixes IE11 centering problems (is overruled by label min-height) *\u002F\n height: 0px;\n\n \u002F* dont allow selection *\u002F\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n\n \u002F* will be animated *\u002F\n will-change: transform, opacity;\n}\n\u002F* Hard to override styles on purpose *\u002F\n.filepond--drop-label.filepond--drop-label label {\n display: block;\n margin: 0;\n padding: 0.5em; \u002F* use padding instead of margin so click area is not impacted *\u002F\n}\n.filepond--drop-label label {\n cursor: default;\n font-size: 0.875em;\n font-weight: normal;\n text-align: center;\n line-height: 1.5;\n}\n.filepond--label-action {\n text-decoration: underline;\n -webkit-text-decoration-skip: ink;\n text-decoration-skip-ink: auto;\n -webkit-text-decoration-color: #a7a4a4;\n text-decoration-color: #a7a4a4;\n cursor: pointer;\n}\n.filepond--root[data-disabled] .filepond--drop-label label {\n opacity: 0.5;\n}\n\u002F* Hard to override styles *\u002F\n.filepond--file-action-button.filepond--file-action-button {\n font-size: 1em;\n width: 1.625em;\n height: 1.625em;\n\n font-family: inherit;\n line-height: inherit;\n\n margin: 0;\n padding: 0;\n border: none;\n outline: none;\n\n will-change: transform, opacity;\n\n \u002F* hidden label *\u002F\n}\n.filepond--file-action-button.filepond--file-action-button span {\n position: absolute;\n overflow: hidden;\n height: 1px;\n width: 1px;\n padding: 0;\n border: 0;\n clip: rect(1px, 1px, 1px, 1px);\n -webkit-clip-path: inset(50%);\n clip-path: inset(50%);\n white-space: nowrap;\n}\n.filepond--file-action-button.filepond--file-action-button {\n \u002F* scale SVG to fill button *\u002F\n}\n.filepond--file-action-button.filepond--file-action-button svg {\n width: 100%;\n height: 100%;\n}\n.filepond--file-action-button.filepond--file-action-button {\n \u002F* bigger touch area *\u002F\n}\n.filepond--file-action-button.filepond--file-action-button::after {\n position: absolute;\n left: -0.75em;\n right: -0.75em;\n top: -0.75em;\n bottom: -0.75em;\n content: '';\n}\n\u002F* Soft styles *\u002F\n.filepond--file-action-button {\n \u002F* use default arrow cursor *\u002F\n cursor: auto;\n\n \u002F* reset default button styles *\u002F\n color: #fff;\n\n \u002F* set default look n feel *\u002F\n border-radius: 50%;\n background-color: rgba(0, 0, 0, 0.5);\n background-image: none;\n\n \u002F* we animate box shadow on focus *\u002F\n \u002F* it's only slightly slower than animating *\u002F\n \u002F* a pseudo-element with transforms and renders *\u002F\n \u002F* a lot better on chrome *\u002F\n box-shadow: 0 0 0 0 rgba(255, 255, 255, 0);\n transition: box-shadow 0.25s ease-in;\n}\n.filepond--file-action-button:hover,\n.filepond--file-action-button:focus {\n box-shadow: 0 0 0 0.125em rgba(255, 255, 255, 0.9);\n}\n.filepond--file-action-button[disabled] {\n color: rgba(255, 255, 255, 0.5);\n background-color: rgba(0, 0, 0, 0.25);\n}\n.filepond--file-action-button[hidden] {\n display: none;\n}\n\u002F* edit button *\u002F\n.filepond--action-edit-item.filepond--action-edit-item {\n width: 2em;\n height: 2em;\n padding: 0.1875em;\n}\n.filepond--action-edit-item.filepond--action-edit-item[data-align*='center'] {\n margin-left: -0.1875em;\n}\n.filepond--action-edit-item.filepond--action-edit-item[data-align*='bottom'] {\n margin-bottom: -0.1875em;\n}\n.filepond--action-edit-item-alt {\n border: none;\n line-height: inherit;\n background: transparent;\n font-family: inherit;\n color: inherit;\n outline: none;\n padding: 0;\n margin: 0 0 0 0.25em;\n pointer-events: all;\n position: absolute;\n}\n.filepond--action-edit-item-alt svg {\n width: 1.3125em;\n height: 1.3125em;\n}\n.filepond--action-edit-item-alt span {\n font-size: 0;\n opacity: 0;\n}\n.filepond--file-info {\n position: static;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n flex: 1;\n margin: 0 0.5em 0 0;\n min-width: 0;\n\n \u002F* will be animated *\u002F\n will-change: transform, opacity;\n\n \u002F* can't do anything with this info *\u002F\n pointer-events: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n\n \u002F* no margins on children *\u002F\n}\n.filepond--file-info * {\n margin: 0;\n}\n.filepond--file-info {\n \u002F* we don't want to have these overrules so these selectors are a bit more specific *\u002F\n}\n.filepond--file-info .filepond--file-info-main {\n font-size: 0.75em;\n line-height: 1.2;\n\n \u002F* we want ellipsis if this bar gets too wide *\u002F\n text-overflow: ellipsis;\n overflow: hidden;\n white-space: nowrap;\n width: 100%;\n}\n.filepond--file-info .filepond--file-info-sub {\n font-size: 0.625em;\n opacity: 0.5;\n transition: opacity 0.25s ease-in-out;\n white-space: nowrap;\n}\n.filepond--file-info .filepond--file-info-sub:empty {\n display: none;\n}\n.filepond--file-status {\n position: static;\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n flex-grow: 0;\n flex-shrink: 0;\n\n margin: 0;\n min-width: 2.25em;\n text-align: right;\n\n \u002F* will be animated *\u002F\n will-change: transform, opacity;\n\n \u002F* can't do anything with this info *\u002F\n pointer-events: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n\n \u002F* no margins on children *\u002F\n}\n.filepond--file-status * {\n margin: 0;\n white-space: nowrap;\n}\n.filepond--file-status {\n \u002F* font sizes *\u002F\n}\n.filepond--file-status .filepond--file-status-main {\n font-size: 0.75em;\n line-height: 1.2;\n}\n.filepond--file-status .filepond--file-status-sub {\n font-size: 0.625em;\n opacity: 0.5;\n transition: opacity 0.25s ease-in-out;\n}\n\u002F* Hard to override styles *\u002F\n.filepond--file-wrapper.filepond--file-wrapper {\n border: none;\n margin: 0;\n padding: 0;\n min-width: 0;\n height: 100%;\n\n \u002F* hide legend for visual users *\u002F\n}\n.filepond--file-wrapper.filepond--file-wrapper \u003E legend {\n position: absolute;\n overflow: hidden;\n height: 1px;\n width: 1px;\n padding: 0;\n border: 0;\n clip: rect(1px, 1px, 1px, 1px);\n -webkit-clip-path: inset(50%);\n clip-path: inset(50%);\n white-space: nowrap;\n}\n.filepond--file {\n position: static;\n display: flex;\n height: 100%;\n align-items: flex-start;\n\n padding: 0.5625em 0.5625em;\n\n color: #fff;\n border-radius: 0.5em;\n\n \u002F* control positions *\u002F\n}\n.filepond--file .filepond--file-status {\n margin-left: auto;\n margin-right: 2.25em;\n}\n.filepond--file .filepond--processing-complete-indicator {\n pointer-events: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n z-index: 3;\n}\n.filepond--file .filepond--processing-complete-indicator,\n.filepond--file .filepond--progress-indicator,\n.filepond--file .filepond--file-action-button {\n position: absolute;\n}\n.filepond--file {\n \u002F* .filepond--file-action-button *\u002F\n}\n.filepond--file [data-align*='left'] {\n left: 0.5625em;\n}\n.filepond--file [data-align*='right'] {\n right: 0.5625em;\n}\n.filepond--file [data-align*='center'] {\n left: calc(50% - 0.8125em); \u002F* .8125 is half of button width *\u002F\n}\n.filepond--file [data-align*='bottom'] {\n bottom: 1.125em;\n}\n.filepond--file [data-align='center'] {\n top: calc(50% - 0.8125em);\n}\n.filepond--file .filepond--progress-indicator {\n margin-top: 0.1875em;\n}\n.filepond--file .filepond--progress-indicator[data-align*='right'] {\n margin-right: 0.1875em;\n}\n.filepond--file .filepond--progress-indicator[data-align*='left'] {\n margin-left: 0.1875em;\n}\n\u002F* make sure text does not overlap *\u002F\n[data-filepond-item-state='cancelled'] .filepond--file-info,\n[data-filepond-item-state*='invalid'] .filepond--file-info,\n[data-filepond-item-state*='error'] .filepond--file-info {\n margin-right: 2.25em;\n}\n[data-filepond-item-state~='processing'] .filepond--file-status-sub {\n opacity: 0;\n}\n[data-filepond-item-state~='processing']\n .filepond--action-abort-item-processing\n ~ .filepond--file-status\n .filepond--file-status-sub {\n opacity: 0.5;\n}\n[data-filepond-item-state='processing-error'] .filepond--file-status-sub {\n opacity: 0;\n}\n[data-filepond-item-state='processing-error']\n .filepond--action-retry-item-processing\n ~ .filepond--file-status\n .filepond--file-status-sub {\n opacity: 0.5;\n}\n[data-filepond-item-state='processing-complete'] {\n \u002F* busy state *\u002F\n}\n[data-filepond-item-state='processing-complete'] .filepond--action-revert-item-processing svg {\n -webkit-animation: fall 0.5s 0.125s linear both;\n animation: fall 0.5s 0.125s linear both;\n}\n[data-filepond-item-state='processing-complete'] {\n \u002F* hide details by default, only show when can revert *\u002F\n}\n[data-filepond-item-state='processing-complete'] .filepond--file-status-sub {\n opacity: 0.5;\n}\n[data-filepond-item-state='processing-complete']\n .filepond--processing-complete-indicator:not([style*='hidden'])\n ~ .filepond--file-status\n .filepond--file-status-sub {\n opacity: 0;\n}\n[data-filepond-item-state='processing-complete'] .filepond--file-info-sub {\n opacity: 0;\n}\n[data-filepond-item-state='processing-complete']\n .filepond--action-revert-item-processing\n ~ .filepond--file-info\n .filepond--file-info-sub {\n opacity: 0.5;\n}\n\u002F* file state can be invalid or error, both are visually similar but *\u002F\n\u002F* having them as separate states might be useful *\u002F\n[data-filepond-item-state*='invalid'] .filepond--panel,\n[data-filepond-item-state*='invalid'] .filepond--file-wrapper,\n[data-filepond-item-state*='error'] .filepond--panel,\n[data-filepond-item-state*='error'] .filepond--file-wrapper {\n -webkit-animation: shake 0.65s linear both;\n animation: shake 0.65s linear both;\n}\n\u002F* spins progress indicator when file is marked as busy *\u002F\n[data-filepond-item-state*='busy'] .filepond--progress-indicator svg {\n -webkit-animation: spin 1s linear infinite;\n animation: spin 1s linear infinite;\n}\n\u002F**\n * States\n *\u002F\n@-webkit-keyframes spin {\n 0% {\n -webkit-transform: rotateZ(0deg);\n transform: rotateZ(0deg);\n }\n\n 100% {\n -webkit-transform: rotateZ(360deg);\n transform: rotateZ(360deg);\n }\n}\n@keyframes spin {\n 0% {\n -webkit-transform: rotateZ(0deg);\n transform: rotateZ(0deg);\n }\n\n 100% {\n -webkit-transform: rotateZ(360deg);\n transform: rotateZ(360deg);\n }\n}\n@-webkit-keyframes shake {\n 10%,\n 90% {\n -webkit-transform: translateX(-0.0625em);\n transform: translateX(-0.0625em);\n }\n\n 20%,\n 80% {\n -webkit-transform: translateX(0.125em);\n transform: translateX(0.125em);\n }\n\n 30%,\n 50%,\n 70% {\n -webkit-transform: translateX(-0.25em);\n transform: translateX(-0.25em);\n }\n\n 40%,\n 60% {\n -webkit-transform: translateX(0.25em);\n transform: translateX(0.25em);\n }\n}\n@keyframes shake {\n 10%,\n 90% {\n -webkit-transform: translateX(-0.0625em);\n transform: translateX(-0.0625em);\n }\n\n 20%,\n 80% {\n -webkit-transform: translateX(0.125em);\n transform: translateX(0.125em);\n }\n\n 30%,\n 50%,\n 70% {\n -webkit-transform: translateX(-0.25em);\n transform: translateX(-0.25em);\n }\n\n 40%,\n 60% {\n -webkit-transform: translateX(0.25em);\n transform: translateX(0.25em);\n }\n}\n@-webkit-keyframes fall {\n 0% {\n opacity: 0;\n -webkit-transform: scale(0.5);\n transform: scale(0.5);\n -webkit-animation-timing-function: ease-out;\n animation-timing-function: ease-out;\n }\n\n 70% {\n opacity: 1;\n -webkit-transform: scale(1.1);\n transform: scale(1.1);\n -webkit-animation-timing-function: ease-in-out;\n animation-timing-function: ease-in-out;\n }\n\n 100% {\n -webkit-transform: scale(1);\n transform: scale(1);\n -webkit-animation-timing-function: ease-out;\n animation-timing-function: ease-out;\n }\n}\n@keyframes fall {\n 0% {\n opacity: 0;\n -webkit-transform: scale(0.5);\n transform: scale(0.5);\n -webkit-animation-timing-function: ease-out;\n animation-timing-function: ease-out;\n }\n\n 70% {\n opacity: 1;\n -webkit-transform: scale(1.1);\n transform: scale(1.1);\n -webkit-animation-timing-function: ease-in-out;\n animation-timing-function: ease-in-out;\n }\n\n 100% {\n -webkit-transform: scale(1);\n transform: scale(1);\n -webkit-animation-timing-function: ease-out;\n animation-timing-function: ease-out;\n }\n}\n\u002F* ignore all other interaction elements while dragging a file *\u002F\n.filepond--hopper[data-hopper-state='drag-over'] \u003E * {\n pointer-events: none;\n}\n\u002F* capture all hit tests using a hidden layer, this speeds up the event flow *\u002F\n.filepond--hopper[data-hopper-state='drag-over']::after {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n right: 0;\n bottom: 0;\n z-index: 100;\n}\n.filepond--progress-indicator {\n z-index: 103;\n}\n.filepond--file-action-button {\n z-index: 102;\n}\n.filepond--file-status {\n z-index: 101;\n}\n.filepond--file-info {\n z-index: 100;\n}\n.filepond--item {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n z-index: 1;\n\n padding: 0;\n margin: 0.25em;\n\n will-change: transform, opacity;\n\n \u002F* item children order *\u002F\n}\n.filepond--item \u003E .filepond--panel {\n z-index: -1;\n}\n\u002F* has a slight shadow *\u002F\n.filepond--item \u003E .filepond--panel .filepond--panel-bottom {\n box-shadow: 0 0.0625em 0.125em -0.0625em rgba(0, 0, 0, 0.25);\n}\n.filepond--item {\n \u002F* drag related *\u002F\n}\n.filepond--item \u003E .filepond--file-wrapper,\n.filepond--item \u003E .filepond--panel {\n transition: opacity 0.15s ease-out;\n}\n.filepond--item[data-drag-state] {\n cursor: -webkit-grab;\n cursor: grab;\n}\n.filepond--item[data-drag-state] \u003E .filepond--panel {\n transition: box-shadow 0.125s ease-in-out;\n box-shadow: 0 0 0 rgba(0, 0, 0, 0);\n}\n.filepond--item[data-drag-state='drag'] {\n cursor: -webkit-grabbing;\n cursor: grabbing;\n}\n.filepond--item[data-drag-state='drag'] \u003E .filepond--panel {\n box-shadow: 0 0.125em 0.3125em rgba(0, 0, 0, 0.325);\n}\n.filepond--item[data-drag-state]:not([data-drag-state='idle']) {\n z-index: 2;\n}\n\u002F* states *\u002F\n.filepond--item-panel {\n background-color: #64605e;\n}\n[data-filepond-item-state='processing-complete'] .filepond--item-panel {\n background-color: #369763;\n}\n[data-filepond-item-state*='invalid'] .filepond--item-panel,\n[data-filepond-item-state*='error'] .filepond--item-panel {\n background-color: #c44e47;\n}\n\u002F* style of item panel *\u002F\n.filepond--item-panel {\n border-radius: 0.5em;\n transition: background-color 0.25s;\n}\n\u002F* normal mode *\u002F\n.filepond--list-scroller {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n margin: 0;\n will-change: transform;\n}\n\u002F* scroll mode *\u002F\n.filepond--list-scroller[data-state='overflow'] .filepond--list {\n bottom: 0;\n right: 0;\n}\n.filepond--list-scroller[data-state='overflow'] {\n overflow-y: scroll;\n overflow-x: hidden;\n -webkit-overflow-scrolling: touch;\n -webkit-mask: linear-gradient(to bottom, #000 calc(100% - 0.5em), transparent 100%);\n mask: linear-gradient(to bottom, #000 calc(100% - 0.5em), transparent 100%);\n}\n\u002F* style scrollbar *\u002F\n.filepond--list-scroller::-webkit-scrollbar {\n background: transparent;\n}\n.filepond--list-scroller::-webkit-scrollbar:vertical {\n width: 1em;\n}\n.filepond--list-scroller::-webkit-scrollbar:horizontal {\n height: 0;\n}\n.filepond--list-scroller::-webkit-scrollbar-thumb {\n background-color: rgba(0, 0, 0, 0.3);\n border-radius: 99999px;\n border: 0.3125em solid transparent;\n background-clip: content-box;\n}\n\u002F* hard to overide styles on purpose *\u002F\n.filepond--list.filepond--list {\n position: absolute;\n top: 0;\n margin: 0;\n padding: 0;\n list-style-type: none;\n\n \u002F* prevents endless paint calls on filepond--list-scroller *\u002F\n will-change: transform;\n}\n\u002F* used for padding so allowed to be restyled *\u002F\n.filepond--list {\n left: 0.75em;\n right: 0.75em;\n}\n.filepond--root[data-style-panel-layout~='integrated'] {\n width: 100%;\n height: 100%;\n max-width: none;\n margin: 0;\n}\n.filepond--root[data-style-panel-layout~='circle'] .filepond--panel-root,\n.filepond--root[data-style-panel-layout~='integrated'] .filepond--panel-root {\n border-radius: 0;\n}\n.filepond--root[data-style-panel-layout~='circle'] .filepond--panel-root \u003E *,\n.filepond--root[data-style-panel-layout~='integrated'] .filepond--panel-root \u003E * {\n display: none;\n}\n.filepond--root[data-style-panel-layout~='circle'] .filepond--drop-label,\n.filepond--root[data-style-panel-layout~='integrated'] .filepond--drop-label {\n bottom: 0;\n height: auto;\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 7;\n}\n.filepond--root[data-style-panel-layout~='circle'],\n.filepond--root[data-style-panel-layout~='integrated'] {\n \u002F* we're only loading one item, this makes the intro animation a bit nicer *\u002F\n}\n.filepond--root[data-style-panel-layout~='circle'] .filepond--item-panel,\n.filepond--root[data-style-panel-layout~='integrated'] .filepond--item-panel {\n display: none;\n}\n.filepond--root[data-style-panel-layout~='compact'] .filepond--list-scroller,\n.filepond--root[data-style-panel-layout~='integrated'] .filepond--list-scroller {\n overflow: hidden;\n height: 100%;\n margin-top: 0;\n margin-bottom: 0;\n}\n.filepond--root[data-style-panel-layout~='compact'] .filepond--list,\n.filepond--root[data-style-panel-layout~='integrated'] .filepond--list {\n left: 0;\n right: 0;\n height: 100%;\n}\n.filepond--root[data-style-panel-layout~='compact'] .filepond--item,\n.filepond--root[data-style-panel-layout~='integrated'] .filepond--item {\n margin: 0;\n}\n.filepond--root[data-style-panel-layout~='compact'] .filepond--file-wrapper,\n.filepond--root[data-style-panel-layout~='integrated'] .filepond--file-wrapper {\n height: 100%;\n}\n.filepond--root[data-style-panel-layout~='compact'] .filepond--drop-label,\n.filepond--root[data-style-panel-layout~='integrated'] .filepond--drop-label {\n z-index: 7;\n}\n.filepond--root[data-style-panel-layout~='circle'] {\n border-radius: 99999rem;\n overflow: hidden;\n}\n.filepond--root[data-style-panel-layout~='circle'] \u003E .filepond--panel {\n border-radius: inherit;\n}\n.filepond--root[data-style-panel-layout~='circle'] \u003E .filepond--panel \u003E * {\n display: none;\n}\n.filepond--root[data-style-panel-layout~='circle'] {\n \u002F* circle cuts of this info, so best to hide it *\u002F\n}\n.filepond--root[data-style-panel-layout~='circle'] .filepond--file-info {\n display: none;\n}\n.filepond--root[data-style-panel-layout~='circle'] .filepond--file-status {\n display: none;\n}\n.filepond--root[data-style-panel-layout~='circle'] .filepond--action-edit-item {\n opacity: 1 !important;\n visibility: visible !important;\n}\n\u002F* dirfty way to fix circular overflow issue on safari 11+ *\u002F\n@media not all and (min-resolution: 0.001dpcm) {\n @supports (-webkit-appearance: none) and (stroke-color: transparent) {\n .filepond--root[data-style-panel-layout~='circle'] {\n will-change: transform;\n }\n }\n}\n.filepond--panel-root {\n border-radius: 0.5em;\n background-color: #f1f0ef;\n}\n.filepond--panel {\n position: absolute;\n left: 0;\n top: 0;\n right: 0;\n margin: 0;\n\n \u002F* defaults to 100% height (fixed height mode) this fixes problem with panel height in IE11 *\u002F\n height: 100% !important;\n\n \u002F* no interaction possible with panel *\u002F\n pointer-events: none;\n}\n.filepond-panel:not([data-scalable='false']) {\n height: auto !important;\n}\n.filepond--panel[data-scalable='false'] \u003E div {\n display: none;\n}\n.filepond--panel[data-scalable='true'] {\n \u002F* this seems to fix Chrome performance issues *\u002F\n \u002F* - when box-shadow is enabled *\u002F\n \u002F* - when multiple ponds are active on the same page *\u002F\n -webkit-transform-style: preserve-3d;\n transform-style: preserve-3d;\n\n \u002F* prevent borders and backgrounds *\u002F\n background-color: transparent !important;\n border: none !important;\n}\n.filepond--panel-top,\n.filepond--panel-bottom,\n.filepond--panel-center {\n position: absolute;\n left: 0;\n top: 0;\n right: 0;\n margin: 0;\n padding: 0;\n}\n.filepond--panel-top,\n.filepond--panel-bottom {\n height: 0.5em;\n}\n.filepond--panel-top {\n border-bottom-left-radius: 0 !important;\n border-bottom-right-radius: 0 !important;\n border-bottom: none !important;\n\n \u002F* fixes tiny transparant line between top and center panel *\u002F\n}\n.filepond--panel-top::after {\n content: '';\n position: absolute;\n height: 2px;\n left: 0;\n right: 0;\n bottom: -1px;\n background-color: inherit;\n}\n.filepond--panel-center,\n.filepond--panel-bottom {\n will-change: transform;\n -webkit-backface-visibility: hidden;\n backface-visibility: hidden;\n -webkit-transform-origin: left top;\n transform-origin: left top;\n -webkit-transform: translate3d(0, 0.5em, 0);\n transform: translate3d(0, 0.5em, 0);\n}\n.filepond--panel-bottom {\n border-top-left-radius: 0 !important;\n border-top-right-radius: 0 !important;\n border-top: none !important;\n\n \u002F* fixes tiny transparant line between bottom and center of panel *\u002F\n}\n.filepond--panel-bottom::before {\n content: '';\n position: absolute;\n height: 2px;\n left: 0;\n right: 0;\n top: -1px;\n background-color: inherit;\n}\n.filepond--panel-center {\n \u002F* the center panel is scaled using scale3d to fit the correct height *\u002F\n \u002F* we use 100px instead of 1px as scaling 1px to a huge height is really laggy on chrome *\u002F\n height: 100px !important;\n border-top: none !important;\n border-bottom: none !important;\n border-radius: 0 !important;\n\n \u002F* hide if not transformed, prevents a little flash when the panel is at 100px height while attached for first time *\u002F\n}\n.filepond--panel-center:not([style]) {\n visibility: hidden;\n}\n.filepond--progress-indicator {\n position: static;\n width: 1.25em;\n height: 1.25em;\n\n color: #fff;\n\n \u002F* can't have margins *\u002F\n margin: 0;\n\n \u002F* no interaction possible with progress indicator *\u002F\n pointer-events: none;\n\n \u002F* will be animated *\u002F\n will-change: transform, opacity;\n}\n.filepond--progress-indicator svg {\n width: 100%;\n height: 100%;\n vertical-align: top;\n transform-box: fill-box; \u002F* should center the animation correctly when zoomed in *\u002F\n}\n.filepond--progress-indicator path {\n fill: none;\n stroke: currentColor;\n}\n.filepond--list-scroller {\n z-index: 6;\n}\n.filepond--drop-label {\n z-index: 5;\n}\n.filepond--drip {\n z-index: 3;\n}\n.filepond--root \u003E .filepond--panel {\n z-index: 2;\n}\n.filepond--browser {\n z-index: 1;\n}\n.filepond--root {\n \u002F* layout*\u002F\n box-sizing: border-box;\n position: relative;\n margin-bottom: 1em;\n\n \u002F* base font size for whole component *\u002F\n font-size: 1rem;\n\n \u002F* base line height *\u002F\n line-height: normal;\n\n \u002F* up uses default system font family *\u002F\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif,\n 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';\n\n \u002F* will increase font weight a bit on Safari *\u002F\n font-weight: 450;\n\n \u002F* default text alignment *\u002F\n text-align: left;\n\n \u002F* better text rendering on Safari *\u002F\n text-rendering: optimizeLegibility;\n\n \u002F* text direction is ltr for now *\u002F\n direction: ltr;\n\n \u002F* optimize rendering *\u002F\n \u002F* https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FCSS\u002Fcontain *\u002F\n contain: layout style size;\n\n \u002F* correct box sizing, line-height and positioning on child elements *\u002F\n}\n.filepond--root * {\n box-sizing: inherit;\n line-height: inherit;\n}\n.filepond--root *:not(text) {\n font-size: inherit;\n}\n.filepond--root {\n \u002F* block everything *\u002F\n}\n.filepond--root[data-disabled] {\n pointer-events: none;\n}\n.filepond--root[data-disabled] .filepond--list-scroller {\n pointer-events: all;\n}\n.filepond--root[data-disabled] .filepond--list {\n pointer-events: none;\n}\n\u002F**\n * Root element children layout\n *\u002F\n.filepond--root .filepond--drop-label {\n min-height: 4.75em;\n}\n.filepond--root .filepond--list-scroller {\n margin-top: 1em;\n margin-bottom: 1em;\n}\n.filepond--root .filepond--credits {\n position: absolute;\n right: 0;\n opacity: 0.175;\n line-height: 0.85;\n font-size: 11px;\n color: inherit;\n text-decoration: none;\n z-index: 3;\n bottom: -14px;\n}\n.filepond--root .filepond--credits[style] {\n top: 0;\n bottom: auto;\n margin-top: 14px;\n}\n","id":"729d50f1-f6c9-4eca-969f-8b3038c702d2","is_binary":false,"title":"filepond.css","sha":null,"inserted_at":"2021-07-05T16:41:13","updated_at":"2021-07-05T16:41:13","upload_id":null,"shortid":"r1ebV83xad","source_id":"50161fbc-cae5-478e-b223-783e0c89506e","directory_shortid":null},{"code":"{\n \"name\": \"static\",\n \"version\": \"1.0.0\",\n \"description\": \"This is a static template with no bundling\",\n \"main\": \"index.html\",\n \"scripts\": {\n \"start\": \"serve\",\n \"build\": \"echo This is a static template, there is no bundler or bundling involved!\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https:\u002F\u002Fgithub.com\u002Fcodesandbox-app\u002Fstatic-template.git\"\n },\n \"keywords\": [\n \"static\",\n \"template\",\n \"codesandbox\"\n ],\n \"author\": \"Ives van Hoorne\",\n \"license\": \"MIT\",\n \"bugs\": {\n \"url\": \"https:\u002F\u002Fgithub.com\u002Fcodesandbox-app\u002Fstatic-template\u002Fissues\"\n },\n \"homepage\": \"https:\u002F\u002Fgithub.com\u002Fcodesandbox-app\u002Fstatic-template#readme\",\n \"devDependencies\": {\n \"serve\": \"^11.2.0\"\n }\n}\n","id":"87f4af13-6efd-458f-afdb-7278d9dc18e0","is_binary":false,"title":"package.json","sha":null,"inserted_at":"2021-07-05T15:28:39","updated_at":"2020-05-20T15:22:27","upload_id":null,"shortid":"rJe2NopMjU","source_id":"50161fbc-cae5-478e-b223-783e0c89506e","directory_shortid":null},{"code":"{\n \"template\": \"static\"\n}\n","id":"6ad091e1-f5c5-4ca1-8737-2135390215e9","is_binary":false,"title":"sandbox.config.json","sha":null,"inserted_at":"2021-07-05T15:28:39","updated_at":"2020-05-20T15:22:27","upload_id":null,"shortid":"BJZ3VsaMi8","source_id":"50161fbc-cae5-478e-b223-783e0c89506e","directory_shortid":null},{"code":"\u003C!DOCTYPE html\u003E\n\u003Chtml\u003E\n \u003Chead\u003E\n \u003Cmeta charset=\"utf-8\" \u002F\u003E\n \u003Clink href=\"filepond.css\" rel=\"stylesheet\" \u002F\u003E\n \u003Clink href=\"filepond-plugin-image-preview.css\" rel=\"stylesheet\" \u002F\u003E\n \u003C\u002Fhead\u003E\n \u003Cbody\u003E\n \u003Cform\u003E\n \u003Cinput type=\"file\" \u002F\u003E\n \u003C\u002Fform\u003E\n \u003Cscript src=\"filepond-plugin-image-preview.js\"\u003E\u003C\u002Fscript\u003E\n \u003Cscript src=\"filepond.js\"\u003E\u003C\u002Fscript\u003E\n \u003Cscript\u003E\n FilePond.registerPlugin(FilePondPluginImagePreview);\n const inputElement = document.querySelector(\"input\");\n const pond = FilePond.create(inputElement);\n \u003C\u002Fscript\u003E\n \u003C\u002Fbody\u003E\n\u003C\u002Fhtml\u003E\n","id":"8bcb5545-71ee-4693-84ec-ec666c656bcd","is_binary":false,"title":"index.html","sha":null,"inserted_at":"2021-07-05T15:29:05","updated_at":"2021-07-05T16:43:40","upload_id":null,"shortid":"HJKHHola_","source_id":"50161fbc-cae5-478e-b223-783e0c89506e","directory_shortid":null},{"code":"\u002F*!\n * FilePondPluginImagePreview 4.6.6\n * Licensed under MIT, https:\u002F\u002Fopensource.org\u002Flicenses\u002FMIT\u002F\n * Please visit https:\u002F\u002Fpqina.nl\u002Ffilepond\u002F for details.\n *\u002F\n\n\u002F* eslint-disable *\u002F\n\n(function(global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined'\n ? (module.exports = factory())\n : typeof define === 'function' && define.amd\n ? define(factory)\n : ((global = global || self),\n (global.FilePondPluginImagePreview = factory()));\n})(this, function() {\n 'use strict';\n\n \u002F\u002F test if file is of type image and can be viewed in canvas\n var isPreviewableImage = function isPreviewableImage(file) {\n return \u002F^image\u002F.test(file.type);\n };\n\n function _typeof(obj) {\n if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {\n _typeof = function(obj) {\n return typeof obj;\n };\n } else {\n _typeof = function(obj) {\n return obj &&\n typeof Symbol === 'function' &&\n obj.constructor === Symbol &&\n obj !== Symbol.prototype\n ? 'symbol'\n : typeof obj;\n };\n }\n\n return _typeof(obj);\n }\n\n var REACT_ELEMENT_TYPE;\n\n function _jsx(type, props, key, children) {\n if (!REACT_ELEMENT_TYPE) {\n REACT_ELEMENT_TYPE =\n (typeof Symbol === 'function' &&\n Symbol.for &&\n Symbol.for('react.element')) ||\n 0xeac7;\n }\n\n var defaultProps = type && type.defaultProps;\n var childrenLength = arguments.length - 3;\n\n if (!props && childrenLength !== 0) {\n props = {\n children: void 0\n };\n }\n\n if (props && defaultProps) {\n for (var propName in defaultProps) {\n if (props[propName] === void 0) {\n props[propName] = defaultProps[propName];\n }\n }\n } else if (!props) {\n props = defaultProps || {};\n }\n\n if (childrenLength === 1) {\n props.children = children;\n } else if (childrenLength \u003E 1) {\n var childArray = new Array(childrenLength);\n\n for (var i = 0; i \u003C childrenLength; i++) {\n childArray[i] = arguments[i + 3];\n }\n\n props.children = childArray;\n }\n\n return {\n $typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key === undefined ? null : '' + key,\n ref: null,\n props: props,\n _owner: null\n };\n }\n\n function _asyncIterator(iterable) {\n var method;\n\n if (typeof Symbol === 'function') {\n if (Symbol.asyncIterator) {\n method = iterable[Symbol.asyncIterator];\n if (method != null) return method.call(iterable);\n }\n\n if (Symbol.iterator) {\n method = iterable[Symbol.iterator];\n if (method != null) return method.call(iterable);\n }\n }\n\n throw new TypeError('Object is not async iterable');\n }\n\n function _AwaitValue(value) {\n this.wrapped = value;\n }\n\n function _AsyncGenerator(gen) {\n var front, back;\n\n function send(key, arg) {\n return new Promise(function(resolve, reject) {\n var request = {\n key: key,\n arg: arg,\n resolve: resolve,\n reject: reject,\n next: null\n };\n\n if (back) {\n back = back.next = request;\n } else {\n front = back = request;\n resume(key, arg);\n }\n });\n }\n\n function resume(key, arg) {\n try {\n var result = gen[key](arg);\n var value = result.value;\n var wrappedAwait = value instanceof _AwaitValue;\n Promise.resolve(wrappedAwait ? value.wrapped : value).then(\n function(arg) {\n if (wrappedAwait) {\n resume('next', arg);\n return;\n }\n\n settle(result.done ? 'return' : 'normal', arg);\n },\n function(err) {\n resume('throw', err);\n }\n );\n } catch (err) {\n settle('throw', err);\n }\n }\n\n function settle(type, value) {\n switch (type) {\n case 'return':\n front.resolve({\n value: value,\n done: true\n });\n break;\n\n case 'throw':\n front.reject(value);\n break;\n\n default:\n front.resolve({\n value: value,\n done: false\n });\n break;\n }\n\n front = front.next;\n\n if (front) {\n resume(front.key, front.arg);\n } else {\n back = null;\n }\n }\n\n this._invoke = send;\n\n if (typeof gen.return !== 'function') {\n this.return = undefined;\n }\n }\n\n if (typeof Symbol === 'function' && Symbol.asyncIterator) {\n _AsyncGenerator.prototype[Symbol.asyncIterator] = function() {\n return this;\n };\n }\n\n _AsyncGenerator.prototype.next = function(arg) {\n return this._invoke('next', arg);\n };\n\n _AsyncGenerator.prototype.throw = function(arg) {\n return this._invoke('throw', arg);\n };\n\n _AsyncGenerator.prototype.return = function(arg) {\n return this._invoke('return', arg);\n };\n\n function _wrapAsyncGenerator(fn) {\n return function() {\n return new _AsyncGenerator(fn.apply(this, arguments));\n };\n }\n\n function _awaitAsyncGenerator(value) {\n return new _AwaitValue(value);\n }\n\n function _asyncGeneratorDelegate(inner, awaitWrap) {\n var iter = {},\n waiting = false;\n\n function pump(key, value) {\n waiting = true;\n value = new Promise(function(resolve) {\n resolve(inner[key](value));\n });\n return {\n done: false,\n value: awaitWrap(value)\n };\n }\n\n if (typeof Symbol === 'function' && Symbol.iterator) {\n iter[Symbol.iterator] = function() {\n return this;\n };\n }\n\n iter.next = function(value) {\n if (waiting) {\n waiting = false;\n return value;\n }\n\n return pump('next', value);\n };\n\n if (typeof inner.throw === 'function') {\n iter.throw = function(value) {\n if (waiting) {\n waiting = false;\n throw value;\n }\n\n return pump('throw', value);\n };\n }\n\n if (typeof inner.return === 'function') {\n iter.return = function(value) {\n return pump('return', value);\n };\n }\n\n return iter;\n }\n\n function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {\n try {\n var info = gen[key](arg);\n var value = info.value;\n } catch (error) {\n reject(error);\n return;\n }\n\n if (info.done) {\n resolve(value);\n } else {\n Promise.resolve(value).then(_next, _throw);\n }\n }\n\n function _asyncToGenerator(fn) {\n return function() {\n var self = this,\n args = arguments;\n return new Promise(function(resolve, reject) {\n var gen = fn.apply(self, args);\n\n function _next(value) {\n asyncGeneratorStep(\n gen,\n resolve,\n reject,\n _next,\n _throw,\n 'next',\n value\n );\n }\n\n function _throw(err) {\n asyncGeneratorStep(gen, resolve, reject, _next, _throw, 'throw', err);\n }\n\n _next(undefined);\n });\n };\n }\n\n function _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError('Cannot call a class as a function');\n }\n }\n\n function _defineProperties(target, props) {\n for (var i = 0; i \u003C props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if ('value' in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n }\n\n function _createClass(Constructor, protoProps, staticProps) {\n if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n if (staticProps) _defineProperties(Constructor, staticProps);\n return Constructor;\n }\n\n function _defineEnumerableProperties(obj, descs) {\n for (var key in descs) {\n var desc = descs[key];\n desc.configurable = desc.enumerable = true;\n if ('value' in desc) desc.writable = true;\n Object.defineProperty(obj, key, desc);\n }\n\n if (Object.getOwnPropertySymbols) {\n var objectSymbols = Object.getOwnPropertySymbols(descs);\n\n for (var i = 0; i \u003C objectSymbols.length; i++) {\n var sym = objectSymbols[i];\n var desc = descs[sym];\n desc.configurable = desc.enumerable = true;\n if ('value' in desc) desc.writable = true;\n Object.defineProperty(obj, sym, desc);\n }\n }\n\n return obj;\n }\n\n function _defaults(obj, defaults) {\n var keys = Object.getOwnPropertyNames(defaults);\n\n for (var i = 0; i \u003C keys.length; i++) {\n var key = keys[i];\n var value = Object.getOwnPropertyDescriptor(defaults, key);\n\n if (value && value.configurable && obj[key] === undefined) {\n Object.defineProperty(obj, key, value);\n }\n }\n\n return obj;\n }\n\n function _defineProperty(obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n }\n\n function _extends() {\n _extends =\n Object.assign ||\n function(target) {\n for (var i = 1; i \u003C arguments.length; i++) {\n var source = arguments[i];\n\n for (var key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n\n return target;\n };\n\n return _extends.apply(this, arguments);\n }\n\n function _objectSpread(target) {\n for (var i = 1; i \u003C arguments.length; i++) {\n var source = arguments[i] != null ? arguments[i] : {};\n var ownKeys = Object.keys(source);\n\n if (typeof Object.getOwnPropertySymbols === 'function') {\n ownKeys = ownKeys.concat(\n Object.getOwnPropertySymbols(source).filter(function(sym) {\n return Object.getOwnPropertyDescriptor(source, sym).enumerable;\n })\n );\n }\n\n ownKeys.forEach(function(key) {\n _defineProperty(target, key, source[key]);\n });\n }\n\n return target;\n }\n\n function _inherits(subClass, superClass) {\n if (typeof superClass !== 'function' && superClass !== null) {\n throw new TypeError('Super expression must either be null or a function');\n }\n\n subClass.prototype = Object.create(superClass && superClass.prototype, {\n constructor: {\n value: subClass,\n writable: true,\n configurable: true\n }\n });\n if (superClass) _setPrototypeOf(subClass, superClass);\n }\n\n function _inheritsLoose(subClass, superClass) {\n subClass.prototype = Object.create(superClass.prototype);\n subClass.prototype.constructor = subClass;\n subClass.__proto__ = superClass;\n }\n\n function _getPrototypeOf(o) {\n _getPrototypeOf = Object.setPrototypeOf\n ? Object.getPrototypeOf\n : function _getPrototypeOf(o) {\n return o.__proto__ || Object.getPrototypeOf(o);\n };\n return _getPrototypeOf(o);\n }\n\n function _setPrototypeOf(o, p) {\n _setPrototypeOf =\n Object.setPrototypeOf ||\n function _setPrototypeOf(o, p) {\n o.__proto__ = p;\n return o;\n };\n\n return _setPrototypeOf(o, p);\n }\n\n function isNativeReflectConstruct() {\n if (typeof Reflect === 'undefined' || !Reflect.construct) return false;\n if (Reflect.construct.sham) return false;\n if (typeof Proxy === 'function') return true;\n\n try {\n Date.prototype.toString.call(Reflect.construct(Date, [], function() {}));\n return true;\n } catch (e) {\n return false;\n }\n }\n\n function _construct(Parent, args, Class) {\n if (isNativeReflectConstruct()) {\n _construct = Reflect.construct;\n } else {\n _construct = function _construct(Parent, args, Class) {\n var a = [null];\n a.push.apply(a, args);\n var Constructor = Function.bind.apply(Parent, a);\n var instance = new Constructor();\n if (Class) _setPrototypeOf(instance, Class.prototype);\n return instance;\n };\n }\n\n return _construct.apply(null, arguments);\n }\n\n function _isNativeFunction(fn) {\n return Function.toString.call(fn).indexOf('[native code]') !== -1;\n }\n\n function _wrapNativeSuper(Class) {\n var _cache = typeof Map === 'function' ? new Map() : undefined;\n\n _wrapNativeSuper = function _wrapNativeSuper(Class) {\n if (Class === null || !_isNativeFunction(Class)) return Class;\n\n if (typeof Class !== 'function') {\n throw new TypeError(\n 'Super expression must either be null or a function'\n );\n }\n\n if (typeof _cache !== 'undefined') {\n if (_cache.has(Class)) return _cache.get(Class);\n\n _cache.set(Class, Wrapper);\n }\n\n function Wrapper() {\n return _construct(Class, arguments, _getPrototypeOf(this).constructor);\n }\n\n Wrapper.prototype = Object.create(Class.prototype, {\n constructor: {\n value: Wrapper,\n enumerable: false,\n writable: true,\n configurable: true\n }\n });\n return _setPrototypeOf(Wrapper, Class);\n };\n\n return _wrapNativeSuper(Class);\n }\n\n function _instanceof(left, right) {\n if (\n right != null &&\n typeof Symbol !== 'undefined' &&\n right[Symbol.hasInstance]\n ) {\n return right[Symbol.hasInstance](left);\n } else {\n return left instanceof right;\n }\n }\n\n function _interopRequireDefault(obj) {\n return obj && obj.__esModule\n ? obj\n : {\n default: obj\n };\n }\n\n function _interopRequireWildcard(obj) {\n if (obj && obj.__esModule) {\n return obj;\n } else {\n var newObj = {};\n\n if (obj != null) {\n for (var key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n var desc =\n Object.defineProperty && Object.getOwnPropertyDescriptor\n ? Object.getOwnPropertyDescriptor(obj, key)\n : {};\n\n if (desc.get || desc.set) {\n Object.defineProperty(newObj, key, desc);\n } else {\n newObj[key] = obj[key];\n }\n }\n }\n }\n\n newObj.default = obj;\n return newObj;\n }\n }\n\n function _newArrowCheck(innerThis, boundThis) {\n if (innerThis !== boundThis) {\n throw new TypeError('Cannot instantiate an arrow function');\n }\n }\n\n function _objectDestructuringEmpty(obj) {\n if (obj == null) throw new TypeError('Cannot destructure undefined');\n }\n\n function _objectWithoutPropertiesLoose(source, excluded) {\n if (source == null) return {};\n var target = {};\n var sourceKeys = Object.keys(source);\n var key, i;\n\n for (i = 0; i \u003C sourceKeys.length; i++) {\n key = sourceKeys[i];\n if (excluded.indexOf(key) \u003E= 0) continue;\n target[key] = source[key];\n }\n\n return target;\n }\n\n function _objectWithoutProperties(source, excluded) {\n if (source == null) return {};\n\n var target = _objectWithoutPropertiesLoose(source, excluded);\n\n var key, i;\n\n if (Object.getOwnPropertySymbols) {\n var sourceSymbolKeys = Object.getOwnPropertySymbols(source);\n\n for (i = 0; i \u003C sourceSymbolKeys.length; i++) {\n key = sourceSymbolKeys[i];\n if (excluded.indexOf(key) \u003E= 0) continue;\n if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;\n target[key] = source[key];\n }\n }\n\n return target;\n }\n\n function _assertThisInitialized(self) {\n if (self === void 0) {\n throw new ReferenceError(\n \"this hasn't been initialised - super() hasn't been called\"\n );\n }\n\n return self;\n }\n\n function _possibleConstructorReturn(self, call) {\n if (call && (typeof call === 'object' || typeof call === 'function')) {\n return call;\n }\n\n return _assertThisInitialized(self);\n }\n\n function _superPropBase(object, property) {\n while (!Object.prototype.hasOwnProperty.call(object, property)) {\n object = _getPrototypeOf(object);\n if (object === null) break;\n }\n\n return object;\n }\n\n function _get(target, property, receiver) {\n if (typeof Reflect !== 'undefined' && Reflect.get) {\n _get = Reflect.get;\n } else {\n _get = function _get(target, property, receiver) {\n var base = _superPropBase(target, property);\n\n if (!base) return;\n var desc = Object.getOwnPropertyDescriptor(base, property);\n\n if (desc.get) {\n return desc.get.call(receiver);\n }\n\n return desc.value;\n };\n }\n\n return _get(target, property, receiver || target);\n }\n\n function set(target, property, value, receiver) {\n if (typeof Reflect !== 'undefined' && Reflect.set) {\n set = Reflect.set;\n } else {\n set = function set(target, property, value, receiver) {\n var base = _superPropBase(target, property);\n\n var desc;\n\n if (base) {\n desc = Object.getOwnPropertyDescriptor(base, property);\n\n if (desc.set) {\n desc.set.call(receiver, value);\n return true;\n } else if (!desc.writable) {\n return false;\n }\n }\n\n desc = Object.getOwnPropertyDescriptor(receiver, property);\n\n if (desc) {\n if (!desc.writable) {\n return false;\n }\n\n desc.value = value;\n Object.defineProperty(receiver, property, desc);\n } else {\n _defineProperty(receiver, property, value);\n }\n\n return true;\n };\n }\n\n return set(target, property, value, receiver);\n }\n\n function _set(target, property, value, receiver, isStrict) {\n var s = set(target, property, value, receiver || target);\n\n if (!s && isStrict) {\n throw new Error('failed to set property');\n }\n\n return value;\n }\n\n function _taggedTemplateLiteral(strings, raw) {\n if (!raw) {\n raw = strings.slice(0);\n }\n\n return Object.freeze(\n Object.defineProperties(strings, {\n raw: {\n value: Object.freeze(raw)\n }\n })\n );\n }\n\n function _taggedTemplateLiteralLoose(strings, raw) {\n if (!raw) {\n raw = strings.slice(0);\n }\n\n strings.raw = raw;\n return strings;\n }\n\n function _temporalRef(val, name) {\n if (val === _temporalUndefined) {\n throw new ReferenceError(name + ' is not defined - temporal dead zone');\n } else {\n return val;\n }\n }\n\n function _readOnlyError(name) {\n throw new Error('\"' + name + '\" is read-only');\n }\n\n function _classNameTDZError(name) {\n throw new Error(\n 'Class \"' + name + '\" cannot be referenced in computed property keys.'\n );\n }\n\n var _temporalUndefined = {};\n\n function _slicedToArray(arr, i) {\n return (\n _arrayWithHoles(arr) ||\n _iterableToArrayLimit(arr, i) ||\n _nonIterableRest()\n );\n }\n\n function _slicedToArrayLoose(arr, i) {\n return (\n _arrayWithHoles(arr) ||\n _iterableToArrayLimitLoose(arr, i) ||\n _nonIterableRest()\n );\n }\n\n function _toArray(arr) {\n return _arrayWithHoles(arr) || _iterableToArray(arr) || _nonIterableRest();\n }\n\n function _toConsumableArray(arr) {\n return (\n _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread()\n );\n }\n\n function _arrayWithoutHoles(arr) {\n if (Array.isArray(arr)) {\n for (var i = 0, arr2 = new Array(arr.length); i \u003C arr.length; i++)\n arr2[i] = arr[i];\n\n return arr2;\n }\n }\n\n function _arrayWithHoles(arr) {\n if (Array.isArray(arr)) return arr;\n }\n\n function _iterableToArray(iter) {\n if (\n Symbol.iterator in Object(iter) ||\n Object.prototype.toString.call(iter) === '[object Arguments]'\n )\n return Array.from(iter);\n }\n\n function _iterableToArrayLimit(arr, i) {\n var _arr = [];\n var _n = true;\n var _d = false;\n var _e = undefined;\n\n try {\n for (\n var _i = arr[Symbol.iterator](), _s;\n !(_n = (_s = _i.next()).done);\n _n = true\n ) {\n _arr.push(_s.value);\n\n if (i && _arr.length === i) break;\n }\n } catch (err) {\n _d = true;\n _e = err;\n } finally {\n try {\n if (!_n && _i['return'] != null) _i['return']();\n } finally {\n if (_d) throw _e;\n }\n }\n\n return _arr;\n }\n\n function _iterableToArrayLimitLoose(arr, i) {\n var _arr = [];\n\n for (\n var _iterator = arr[Symbol.iterator](), _step;\n !(_step = _iterator.next()).done;\n\n ) {\n _arr.push(_step.value);\n\n if (i && _arr.length === i) break;\n }\n\n return _arr;\n }\n\n function _nonIterableSpread() {\n throw new TypeError('Invalid attempt to spread non-iterable instance');\n }\n\n function _nonIterableRest() {\n throw new TypeError('Invalid attempt to destructure non-iterable instance');\n }\n\n function _skipFirstGeneratorNext(fn) {\n return function() {\n var it = fn.apply(this, arguments);\n it.next();\n return it;\n };\n }\n\n function _toPrimitive(input, hint) {\n if (typeof input !== 'object' || input === null) return input;\n var prim = input[Symbol.toPrimitive];\n\n if (prim !== undefined) {\n var res = prim.call(input, hint || 'default');\n if (typeof res !== 'object') return res;\n throw new TypeError('@@toPrimitive must return a primitive value.');\n }\n\n return (hint === 'string' ? String : Number)(input);\n }\n\n function _toPropertyKey(arg) {\n var key = _toPrimitive(arg, 'string');\n\n return typeof key === 'symbol' ? key : String(key);\n }\n\n function _initializerWarningHelper(descriptor, context) {\n throw new Error(\n 'Decorating class property failed. Please ensure that ' +\n 'proposal-class-properties is enabled and set to use loose mode. ' +\n 'To use proposal-class-properties in spec mode with decorators, wait for ' +\n 'the next major version of decorators in stage 2.'\n );\n }\n\n function _initializerDefineProperty(target, property, descriptor, context) {\n if (!descriptor) return;\n Object.defineProperty(target, property, {\n enumerable: descriptor.enumerable,\n configurable: descriptor.configurable,\n writable: descriptor.writable,\n value: descriptor.initializer\n ? descriptor.initializer.call(context)\n : void 0\n });\n }\n\n function _applyDecoratedDescriptor(\n target,\n property,\n decorators,\n descriptor,\n context\n ) {\n var desc = {};\n Object.keys(descriptor).forEach(function(key) {\n desc[key] = descriptor[key];\n });\n desc.enumerable = !!desc.enumerable;\n desc.configurable = !!desc.configurable;\n\n if ('value' in desc || desc.initializer) {\n desc.writable = true;\n }\n\n desc = decorators\n .slice()\n .reverse()\n .reduce(function(desc, decorator) {\n return decorator(target, property, desc) || desc;\n }, desc);\n\n if (context && desc.initializer !== void 0) {\n desc.value = desc.initializer ? desc.initializer.call(context) : void 0;\n desc.initializer = undefined;\n }\n\n if (desc.initializer === void 0) {\n Object.defineProperty(target, property, desc);\n desc = null;\n }\n\n return desc;\n }\n\n var id = 0;\n\n function _classPrivateFieldLooseKey(name) {\n return '__private_' + id++ + '_' + name;\n }\n\n function _classPrivateFieldLooseBase(receiver, privateKey) {\n if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) {\n throw new TypeError('attempted to use private field on non-instance');\n }\n\n return receiver;\n }\n\n function _classPrivateFieldGet(receiver, privateMap) {\n if (!privateMap.has(receiver)) {\n throw new TypeError('attempted to get private field on non-instance');\n }\n\n var descriptor = privateMap.get(receiver);\n\n if (descriptor.get) {\n return descriptor.get.call(receiver);\n }\n\n return descriptor.value;\n }\n\n function _classPrivateFieldSet(receiver, privateMap, value) {\n if (!privateMap.has(receiver)) {\n throw new TypeError('attempted to set private field on non-instance');\n }\n\n var descriptor = privateMap.get(receiver);\n\n if (descriptor.set) {\n descriptor.set.call(receiver, value);\n } else {\n if (!descriptor.writable) {\n throw new TypeError('attempted to set read only private field');\n }\n\n descriptor.value = value;\n }\n\n return value;\n }\n\n function _classStaticPrivateFieldSpecGet(\n receiver,\n classConstructor,\n descriptor\n ) {\n if (receiver !== classConstructor) {\n throw new TypeError('Private static access of wrong provenance');\n }\n\n return descriptor.value;\n }\n\n function _classStaticPrivateFieldSpecSet(\n receiver,\n classConstructor,\n descriptor,\n value\n ) {\n if (receiver !== classConstructor) {\n throw new TypeError('Private static access of wrong provenance');\n }\n\n if (!descriptor.writable) {\n throw new TypeError('attempted to set read only private field');\n }\n\n descriptor.value = value;\n return value;\n }\n\n function _classStaticPrivateMethodGet(receiver, classConstructor, method) {\n if (receiver !== classConstructor) {\n throw new TypeError('Private static access of wrong provenance');\n }\n\n return method;\n }\n\n function _classStaticPrivateMethodSet() {\n throw new TypeError('attempted to set read only static private field');\n }\n\n function _decorate(decorators, factory, superClass, mixins) {\n var api = _getDecoratorsApi();\n\n if (mixins) {\n for (var i = 0; i \u003C mixins.length; i++) {\n api = mixins[i](api);\n }\n }\n\n var r = factory(function initialize(O) {\n api.initializeInstanceElements(O, decorated.elements);\n }, superClass);\n var decorated = api.decorateClass(\n _coalesceClassElements(r.d.map(_createElementDescriptor)),\n decorators\n );\n api.initializeClassElements(r.F, decorated.elements);\n return api.runClassFinishers(r.F, decorated.finishers);\n }\n\n function _getDecoratorsApi() {\n _getDecoratorsApi = function() {\n return api;\n };\n\n var api = {\n elementsDefinitionOrder: [['method'], ['field']],\n initializeInstanceElements: function(O, elements) {\n ['method', 'field'].forEach(function(kind) {\n elements.forEach(function(element) {\n if (element.kind === kind && element.placement === 'own') {\n this.defineClassElement(O, element);\n }\n }, this);\n }, this);\n },\n initializeClassElements: function(F, elements) {\n var proto = F.prototype;\n ['method', 'field'].forEach(function(kind) {\n elements.forEach(function(element) {\n var placement = element.placement;\n\n if (\n element.kind === kind &&\n (placement === 'static' || placement === 'prototype')\n ) {\n var receiver = placement === 'static' ? F : proto;\n this.defineClassElement(receiver, element);\n }\n }, this);\n }, this);\n },\n defineClassElement: function(receiver, element) {\n var descriptor = element.descriptor;\n\n if (element.kind === 'field') {\n var initializer = element.initializer;\n descriptor = {\n enumerable: descriptor.enumerable,\n writable: descriptor.writable,\n configurable: descriptor.configurable,\n value: initializer === void 0 ? void 0 : initializer.call(receiver)\n };\n }\n\n Object.defineProperty(receiver, element.key, descriptor);\n },\n decorateClass: function(elements, decorators) {\n var newElements = [];\n var finishers = [];\n var placements = {\n static: [],\n prototype: [],\n own: []\n };\n elements.forEach(function(element) {\n this.addElementPlacement(element, placements);\n }, this);\n elements.forEach(function(element) {\n if (!_hasDecorators(element)) return newElements.push(element);\n var elementFinishersExtras = this.decorateElement(\n element,\n placements\n );\n newElements.push(elementFinishersExtras.element);\n newElements.push.apply(newElements, elementFinishersExtras.extras);\n finishers.push.apply(finishers, elementFinishersExtras.finishers);\n }, this);\n\n if (!decorators) {\n return {\n elements: newElements,\n finishers: finishers\n };\n }\n\n var result = this.decorateConstructor(newElements, decorators);\n finishers.push.apply(finishers, result.finishers);\n result.finishers = finishers;\n return result;\n },\n addElementPlacement: function(element, placements, silent) {\n var keys = placements[element.placement];\n\n if (!silent && keys.indexOf(element.key) !== -1) {\n throw new TypeError('Duplicated element (' + element.key + ')');\n }\n\n keys.push(element.key);\n },\n decorateElement: function(element, placements) {\n var extras = [];\n var finishers = [];\n\n for (\n var decorators = element.decorators, i = decorators.length - 1;\n i \u003E= 0;\n i--\n ) {\n var keys = placements[element.placement];\n keys.splice(keys.indexOf(element.key), 1);\n var elementObject = this.fromElementDescriptor(element);\n var elementFinisherExtras = this.toElementFinisherExtras(\n (0, decorators[i])(elementObject) || elementObject\n );\n element = elementFinisherExtras.element;\n this.addElementPlacement(element, placements);\n\n if (elementFinisherExtras.finisher) {\n finishers.push(elementFinisherExtras.finisher);\n }\n\n var newExtras = elementFinisherExtras.extras;\n\n if (newExtras) {\n for (var j = 0; j \u003C newExtras.length; j++) {\n this.addElementPlacement(newExtras[j], placements);\n }\n\n extras.push.apply(extras, newExtras);\n }\n }\n\n return {\n element: element,\n finishers: finishers,\n extras: extras\n };\n },\n decorateConstructor: function(elements, decorators) {\n var finishers = [];\n\n for (var i = decorators.length - 1; i \u003E= 0; i--) {\n var obj = this.fromClassDescriptor(elements);\n var elementsAndFinisher = this.toClassDescriptor(\n (0, decorators[i])(obj) || obj\n );\n\n if (elementsAndFinisher.finisher !== undefined) {\n finishers.push(elementsAndFinisher.finisher);\n }\n\n if (elementsAndFinisher.elements !== undefined) {\n elements = elementsAndFinisher.elements;\n\n for (var j = 0; j \u003C elements.length - 1; j++) {\n for (var k = j + 1; k \u003C elements.length; k++) {\n if (\n elements[j].key === elements[k].key &&\n elements[j].placement === elements[k].placement\n ) {\n throw new TypeError(\n 'Duplicated element (' + elements[j].key + ')'\n );\n }\n }\n }\n }\n }\n\n return {\n elements: elements,\n finishers: finishers\n };\n },\n fromElementDescriptor: function(element) {\n var obj = {\n kind: element.kind,\n key: element.key,\n placement: element.placement,\n descriptor: element.descriptor\n };\n var desc = {\n value: 'Descriptor',\n configurable: true\n };\n Object.defineProperty(obj, Symbol.toStringTag, desc);\n if (element.kind === 'field') obj.initializer = element.initializer;\n return obj;\n },\n toElementDescriptors: function(elementObjects) {\n if (elementObjects === undefined) return;\n return _toArray(elementObjects).map(function(elementObject) {\n var element = this.toElementDescriptor(elementObject);\n this.disallowProperty(\n elementObject,\n 'finisher',\n 'An element descriptor'\n );\n this.disallowProperty(\n elementObject,\n 'extras',\n 'An element descriptor'\n );\n return element;\n }, this);\n },\n toElementDescriptor: function(elementObject) {\n var kind = String(elementObject.kind);\n\n if (kind !== 'method' && kind !== 'field') {\n throw new TypeError(\n 'An element descriptor\\'s .kind property must be either \"method\" or' +\n ' \"field\", but a decorator created an element descriptor with' +\n ' .kind \"' +\n kind +\n '\"'\n );\n }\n\n var key = _toPropertyKey(elementObject.key);\n\n var placement = String(elementObject.placement);\n\n if (\n placement !== 'static' &&\n placement !== 'prototype' &&\n placement !== 'own'\n ) {\n throw new TypeError(\n 'An element descriptor\\'s .placement property must be one of \"static\",' +\n ' \"prototype\" or \"own\", but a decorator created an element descriptor' +\n ' with .placement \"' +\n placement +\n '\"'\n );\n }\n\n var descriptor = elementObject.descriptor;\n this.disallowProperty(\n elementObject,\n 'elements',\n 'An element descriptor'\n );\n var element = {\n kind: kind,\n key: key,\n placement: placement,\n descriptor: Object.assign({}, descriptor)\n };\n\n if (kind !== 'field') {\n this.disallowProperty(\n elementObject,\n 'initializer',\n 'A method descriptor'\n );\n } else {\n this.disallowProperty(\n descriptor,\n 'get',\n 'The property descriptor of a field descriptor'\n );\n this.disallowProperty(\n descriptor,\n 'set',\n 'The property descriptor of a field descriptor'\n );\n this.disallowProperty(\n descriptor,\n 'value',\n 'The property descriptor of a field descriptor'\n );\n element.initializer = elementObject.initializer;\n }\n\n return element;\n },\n toElementFinisherExtras: function(elementObject) {\n var element = this.toElementDescriptor(elementObject);\n\n var finisher = _optionalCallableProperty(elementObject, 'finisher');\n\n var extras = this.toElementDescriptors(elementObject.extras);\n return {\n element: element,\n finisher: finisher,\n extras: extras\n };\n },\n fromClassDescriptor: function(elements) {\n var obj = {\n kind: 'class',\n elements: elements.map(this.fromElementDescriptor, this)\n };\n var desc = {\n value: 'Descriptor',\n configurable: true\n };\n Object.defineProperty(obj, Symbol.toStringTag, desc);\n return obj;\n },\n toClassDescriptor: function(obj) {\n var kind = String(obj.kind);\n\n if (kind !== 'class') {\n throw new TypeError(\n 'A class descriptor\\'s .kind property must be \"class\", but a decorator' +\n ' created a class descriptor with .kind \"' +\n kind +\n '\"'\n );\n }\n\n this.disallowProperty(obj, 'key', 'A class descriptor');\n this.disallowProperty(obj, 'placement', 'A class descriptor');\n this.disallowProperty(obj, 'descriptor', 'A class descriptor');\n this.disallowProperty(obj, 'initializer', 'A class descriptor');\n this.disallowProperty(obj, 'extras', 'A class descriptor');\n\n var finisher = _optionalCallableProperty(obj, 'finisher');\n\n var elements = this.toElementDescriptors(obj.elements);\n return {\n elements: elements,\n finisher: finisher\n };\n },\n runClassFinishers: function(constructor, finishers) {\n for (var i = 0; i \u003C finishers.length; i++) {\n var newConstructor = (0, finishers[i])(constructor);\n\n if (newConstructor !== undefined) {\n if (typeof newConstructor !== 'function') {\n throw new TypeError('Finishers must return a constructor.');\n }\n\n constructor = newConstructor;\n }\n }\n\n return constructor;\n },\n disallowProperty: function(obj, name, objectType) {\n if (obj[name] !== undefined) {\n throw new TypeError(\n objectType + \" can't have a .\" + name + ' property.'\n );\n }\n }\n };\n return api;\n }\n\n function _createElementDescriptor(def) {\n var key = _toPropertyKey(def.key);\n\n var descriptor;\n\n if (def.kind === 'method') {\n descriptor = {\n value: def.value,\n writable: true,\n configurable: true,\n enumerable: false\n };\n } else if (def.kind === 'get') {\n descriptor = {\n get: def.value,\n configurable: true,\n enumerable: false\n };\n } else if (def.kind === 'set') {\n descriptor = {\n set: def.value,\n configurable: true,\n enumerable: false\n };\n } else if (def.kind === 'field') {\n descriptor = {\n configurable: true,\n writable: true,\n enumerable: true\n };\n }\n\n var element = {\n kind: def.kind === 'field' ? 'field' : 'method',\n key: key,\n placement: def.static\n ? 'static'\n : def.kind === 'field'\n ? 'own'\n : 'prototype',\n descriptor: descriptor\n };\n if (def.decorators) element.decorators = def.decorators;\n if (def.kind === 'field') element.initializer = def.value;\n return element;\n }\n\n function _coalesceGetterSetter(element, other) {\n if (element.descriptor.get !== undefined) {\n other.descriptor.get = element.descriptor.get;\n } else {\n other.descriptor.set = element.descriptor.set;\n }\n }\n\n function _coalesceClassElements(elements) {\n var newElements = [];\n\n var isSameElement = function(other) {\n return (\n other.kind === 'method' &&\n other.key === element.key &&\n other.placement === element.placement\n );\n };\n\n for (var i = 0; i \u003C elements.length; i++) {\n var element = elements[i];\n var other;\n\n if (\n element.kind === 'method' &&\n (other = newElements.find(isSameElement))\n ) {\n if (\n _isDataDescriptor(element.descriptor) ||\n _isDataDescriptor(other.descriptor)\n ) {\n if (_hasDecorators(element) || _hasDecorators(other)) {\n throw new ReferenceError(\n 'Duplicated methods (' + element.key + \") can't be decorated.\"\n );\n }\n\n other.descriptor = element.descriptor;\n } else {\n if (_hasDecorators(element)) {\n if (_hasDecorators(other)) {\n throw new ReferenceError(\n \"Decorators can't be placed on different accessors with for \" +\n 'the same property (' +\n element.key +\n ').'\n );\n }\n\n other.decorators = element.decorators;\n }\n\n _coalesceGetterSetter(element, other);\n }\n } else {\n newElements.push(element);\n }\n }\n\n return newElements;\n }\n\n function _hasDecorators(element) {\n return element.decorators && element.decorators.length;\n }\n\n function _isDataDescriptor(desc) {\n return (\n desc !== undefined &&\n !(desc.value === undefined && desc.writable === undefined)\n );\n }\n\n function _optionalCallableProperty(obj, name) {\n var value = obj[name];\n\n if (value !== undefined && typeof value !== 'function') {\n throw new TypeError(\"Expected '\" + name + \"' to be a function\");\n }\n\n return value;\n }\n\n function _classPrivateMethodGet(receiver, privateSet, fn) {\n if (!privateSet.has(receiver)) {\n throw new TypeError('attempted to get private field on non-instance');\n }\n\n return fn;\n }\n\n function _classPrivateMethodSet() {\n throw new TypeError('attempted to reassign private method');\n }\n\n function _wrapRegExp(re, groups) {\n _wrapRegExp = function(re, groups) {\n return new BabelRegExp(re, groups);\n };\n\n var _RegExp = _wrapNativeSuper(RegExp);\n\n var _super = RegExp.prototype;\n\n var _groups = new WeakMap();\n\n function BabelRegExp(re, groups) {\n var _this = _RegExp.call(this, re);\n\n _groups.set(_this, groups);\n\n return _this;\n }\n\n _inherits(BabelRegExp, _RegExp);\n\n BabelRegExp.prototype.exec = function(str) {\n var result = _super.exec.call(this, str);\n\n if (result) result.groups = buildGroups(result, this);\n return result;\n };\n\n BabelRegExp.prototype[Symbol.replace] = function(str, substitution) {\n if (typeof substitution === 'string') {\n var groups = _groups.get(this);\n\n return _super[Symbol.replace].call(\n this,\n str,\n substitution.replace(\u002F\\$\u003C([^\u003E]+)\u003E\u002Fg, function(_, name) {\n return '
+ groups[name];\n })\n );\n } else if (typeof substitution === 'function') {\n var _this = this;\n\n return _super[Symbol.replace].call(this, str, function() {\n var args = [];\n args.push.apply(args, arguments);\n\n if (typeof args[args.length - 1] !== 'object') {\n args.push(buildGroups(args, _this));\n }\n\n return substitution.apply(this, args);\n });\n } else {\n return _super[Symbol.replace].call(this, str, substitution);\n }\n };\n\n function buildGroups(result, re) {\n var g = _groups.get(re);\n\n return Object.keys(g).reduce(function(groups, name) {\n groups[name] = result[g[name]];\n return groups;\n }, Object.create(null));\n }\n\n return _wrapRegExp.apply(this, arguments);\n }\n\n var vectorMultiply = function vectorMultiply(v, amount) {\n return createVector(v.x * amount, v.y * amount);\n };\n\n var vectorAdd = function vectorAdd(a, b) {\n return createVector(a.x + b.x, a.y + b.y);\n };\n\n var vectorNormalize = function vectorNormalize(v) {\n var l = Math.sqrt(v.x * v.x + v.y * v.y);\n if (l === 0) {\n return {\n x: 0,\n y: 0\n };\n }\n return createVector(v.x \u002F l, v.y \u002F l);\n };\n\n var vectorRotate = function vectorRotate(v, radians, origin) {\n var cos = Math.cos(radians);\n var sin = Math.sin(radians);\n var t = createVector(v.x - origin.x, v.y - origin.y);\n return createVector(\n origin.x + cos * t.x - sin * t.y,\n origin.y + sin * t.x + cos * t.y\n );\n };\n\n var createVector = function createVector() {\n var x =\n arguments.length \u003E 0 && arguments[0] !== undefined ? arguments[0] : 0;\n var y =\n arguments.length \u003E 1 && arguments[1] !== undefined ? arguments[1] : 0;\n return { x: x, y: y };\n };\n\n var getMarkupValue = function getMarkupValue(value, size) {\n var scalar =\n arguments.length \u003E 2 && arguments[2] !== undefined ? arguments[2] : 1;\n var axis = arguments.length \u003E 3 ? arguments[3] : undefined;\n if (typeof value === 'string') {\n return parseFloat(value) * scalar;\n }\n if (typeof value === 'number') {\n return value * (axis ? size[axis] : Math.min(size.width, size.height));\n }\n return;\n };\n\n var getMarkupStyles = function getMarkupStyles(markup, size, scale) {\n var lineStyle = markup.borderStyle || markup.lineStyle || 'solid';\n var fill = markup.backgroundColor || markup.fontColor || 'transparent';\n var stroke = markup.borderColor || markup.lineColor || 'transparent';\n var strokeWidth = getMarkupValue(\n markup.borderWidth || markup.lineWidth,\n size,\n scale\n );\n var lineCap = markup.lineCap || 'round';\n var lineJoin = markup.lineJoin || 'round';\n var dashes =\n typeof lineStyle === 'string'\n ? ''\n : lineStyle\n .map(function(v) {\n return getMarkupValue(v, size, scale);\n })\n .join(',');\n var opacity = markup.opacity || 1;\n return {\n 'stroke-linecap': lineCap,\n 'stroke-linejoin': lineJoin,\n 'stroke-width': strokeWidth || 0,\n 'stroke-dasharray': dashes,\n stroke: stroke,\n fill: fill,\n opacity: opacity\n };\n };\n\n var isDefined = function isDefined(value) {\n return value != null;\n };\n\n var getMarkupRect = function getMarkupRect(rect, size) {\n var scalar =\n arguments.length \u003E 2 && arguments[2] !== undefined ? arguments[2] : 1;\n\n var left =\n getMarkupValue(rect.x, size, scalar, 'width') ||\n getMarkupValue(rect.left, size, scalar, 'width');\n var top =\n getMarkupValue(rect.y, size, scalar, 'height') ||\n getMarkupValue(rect.top, size, scalar, 'height');\n var width = getMarkupValue(rect.width, size, scalar, 'width');\n var height = getMarkupValue(rect.height, size, scalar, 'height');\n var right = getMarkupValue(rect.right, size, scalar, 'width');\n var bottom = getMarkupValue(rect.bottom, size, scalar, 'height');\n\n if (!isDefined(top)) {\n if (isDefined(height) && isDefined(bottom)) {\n top = size.height - height - bottom;\n } else {\n top = bottom;\n }\n }\n\n if (!isDefined(left)) {\n if (isDefined(width) && isDefined(right)) {\n left = size.width - width - right;\n } else {\n left = right;\n }\n }\n\n if (!isDefined(width)) {\n if (isDefined(left) && isDefined(right)) {\n width = size.width - left - right;\n } else {\n width = 0;\n }\n }\n\n if (!isDefined(height)) {\n if (isDefined(top) && isDefined(bottom)) {\n height = size.height - top - bottom;\n } else {\n height = 0;\n }\n }\n\n return {\n x: left || 0,\n y: top || 0,\n width: width || 0,\n height: height || 0\n };\n };\n\n var pointsToPathShape = function pointsToPathShape(points) {\n return points\n .map(function(point, index) {\n return ''\n .concat(index === 0 ? 'M' : 'L', ' ')\n .concat(point.x, ' ')\n .concat(point.y);\n })\n .join(' ');\n };\n\n var setAttributes = function setAttributes(element, attr) {\n return Object.keys(attr).forEach(function(key) {\n return element.setAttribute(key, attr[key]);\n });\n };\n\n var ns = 'http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg';\n var svg = function svg(tag, attr) {\n var element = document.createElementNS(ns, tag);\n if (attr) {\n setAttributes(element, attr);\n }\n return element;\n };\n\n var updateRect = function updateRect(element) {\n return setAttributes(\n element,\n Object.assign({}, element.rect, element.styles)\n );\n };\n\n var updateEllipse = function updateEllipse(element) {\n var cx = element.rect.x + element.rect.width * 0.5;\n var cy = element.rect.y + element.rect.height * 0.5;\n var rx = element.rect.width * 0.5;\n var ry = element.rect.height * 0.5;\n return setAttributes(\n element,\n Object.assign(\n {\n cx: cx,\n cy: cy,\n rx: rx,\n ry: ry\n },\n element.styles\n )\n );\n };\n\n var IMAGE_FIT_STYLE = {\n contain: 'xMidYMid meet',\n cover: 'xMidYMid slice'\n };\n\n var updateImage = function updateImage(element, markup) {\n setAttributes(\n element,\n Object.assign({}, element.rect, element.styles, {\n preserveAspectRatio: IMAGE_FIT_STYLE[markup.fit] || 'none'\n })\n );\n };\n\n var TEXT_ANCHOR = {\n left: 'start',\n center: 'middle',\n right: 'end'\n };\n\n var updateText = function updateText(element, markup, size, scale) {\n var fontSize = getMarkupValue(markup.fontSize, size, scale);\n var fontFamily = markup.fontFamily || 'sans-serif';\n var fontWeight = markup.fontWeight || 'normal';\n var textAlign = TEXT_ANCHOR[markup.textAlign] || 'start';\n\n setAttributes(\n element,\n Object.assign({}, element.rect, element.styles, {\n 'stroke-width': 0,\n 'font-weight': fontWeight,\n 'font-size': fontSize,\n 'font-family': fontFamily,\n 'text-anchor': textAlign\n })\n );\n\n \u002F\u002F update text\n if (element.text !== markup.text) {\n element.text = markup.text;\n element.textContent = markup.text.length ? markup.text : ' ';\n }\n };\n\n var updateLine = function updateLine(element, markup, size, scale) {\n setAttributes(\n element,\n Object.assign({}, element.rect, element.styles, {\n fill: 'none'\n })\n );\n\n var line = element.childNodes[0];\n var begin = element.childNodes[1];\n var end = element.childNodes[2];\n\n var origin = element.rect;\n\n var target = {\n x: element.rect.x + element.rect.width,\n y: element.rect.y + element.rect.height\n };\n\n setAttributes(line, {\n x1: origin.x,\n y1: origin.y,\n x2: target.x,\n y2: target.y\n });\n\n if (!markup.lineDecoration) return;\n\n begin.style.display = 'none';\n end.style.display = 'none';\n\n var v = vectorNormalize({\n x: target.x - origin.x,\n y: target.y - origin.y\n });\n\n var l = getMarkupValue(0.05, size, scale);\n\n if (markup.lineDecoration.indexOf('arrow-begin') !== -1) {\n var arrowBeginRotationPoint = vectorMultiply(v, l);\n var arrowBeginCenter = vectorAdd(origin, arrowBeginRotationPoint);\n var arrowBeginA = vectorRotate(origin, 2, arrowBeginCenter);\n var arrowBeginB = vectorRotate(origin, -2, arrowBeginCenter);\n\n setAttributes(begin, {\n style: 'display:block;',\n d: 'M'\n .concat(arrowBeginA.x, ',')\n .concat(arrowBeginA.y, ' L')\n .concat(origin.x, ',')\n .concat(origin.y, ' L')\n .concat(arrowBeginB.x, ',')\n .concat(arrowBeginB.y)\n });\n }\n\n if (markup.lineDecoration.indexOf('arrow-end') !== -1) {\n var arrowEndRotationPoint = vectorMultiply(v, -l);\n var arrowEndCenter = vectorAdd(target, arrowEndRotationPoint);\n var arrowEndA = vectorRotate(target, 2, arrowEndCenter);\n var arrowEndB = vectorRotate(target, -2, arrowEndCenter);\n\n setAttributes(end, {\n style: 'display:block;',\n d: 'M'\n .concat(arrowEndA.x, ',')\n .concat(arrowEndA.y, ' L')\n .concat(target.x, ',')\n .concat(target.y, ' L')\n .concat(arrowEndB.x, ',')\n .concat(arrowEndB.y)\n });\n }\n };\n\n var updatePath = function updatePath(element, markup, size, scale) {\n setAttributes(\n element,\n Object.assign({}, element.styles, {\n fill: 'none',\n d: pointsToPathShape(\n markup.points.map(function(point) {\n return {\n x: getMarkupValue(point.x, size, scale, 'width'),\n y: getMarkupValue(point.y, size, scale, 'height')\n };\n })\n )\n })\n );\n };\n\n var createShape = function createShape(node) {\n return function(markup) {\n return svg(node, { id: markup.id });\n };\n };\n\n var createImage = function createImage(markup) {\n var shape = svg('image', {\n id: markup.id,\n 'stroke-linecap': 'round',\n 'stroke-linejoin': 'round',\n opacity: '0'\n });\n\n shape.onload = function() {\n shape.setAttribute('opacity', markup.opacity || 1);\n };\n shape.setAttributeNS(\n 'http:\u002F\u002Fwww.w3.org\u002F1999\u002Fxlink',\n 'xlink:href',\n markup.src\n );\n return shape;\n };\n\n var createLine = function createLine(markup) {\n var shape = svg('g', {\n id: markup.id,\n 'stroke-linecap': 'round',\n 'stroke-linejoin': 'round'\n });\n\n var line = svg('line');\n shape.appendChild(line);\n\n var begin = svg('path');\n shape.appendChild(begin);\n\n var end = svg('path');\n shape.appendChild(end);\n\n return shape;\n };\n\n var CREATE_TYPE_ROUTES = {\n image: createImage,\n rect: createShape('rect'),\n ellipse: createShape('ellipse'),\n text: createShape('text'),\n path: createShape('path'),\n line: createLine\n };\n\n var UPDATE_TYPE_ROUTES = {\n rect: updateRect,\n ellipse: updateEllipse,\n image: updateImage,\n text: updateText,\n path: updatePath,\n line: updateLine\n };\n\n var createMarkupByType = function createMarkupByType(type, markup) {\n return CREATE_TYPE_ROUTES[type](markup);\n };\n\n var updateMarkupByType = function updateMarkupByType(\n element,\n type,\n markup,\n size,\n scale\n ) {\n if (type !== 'path') {\n element.rect = getMarkupRect(markup, size, scale);\n }\n element.styles = getMarkupStyles(markup, size, scale);\n UPDATE_TYPE_ROUTES[type](element, markup, size, scale);\n };\n\n var MARKUP_RECT = [\n 'x',\n 'y',\n 'left',\n 'top',\n 'right',\n 'bottom',\n 'width',\n 'height'\n ];\n\n var toOptionalFraction = function toOptionalFraction(value) {\n return typeof value === 'string' && \u002F%\u002F.test(value)\n ? parseFloat(value) \u002F 100\n : value;\n };\n\n \u002F\u002F adds default markup properties, clones markup\n var prepareMarkup = function prepareMarkup(markup) {\n var _markup = _slicedToArray(markup, 2),\n type = _markup[0],\n props = _markup[1];\n\n var rect = props.points\n ? {}\n : MARKUP_RECT.reduce(function(prev, curr) {\n prev[curr] = toOptionalFraction(props[curr]);\n return prev;\n }, {});\n\n return [\n type,\n Object.assign(\n {\n zIndex: 0\n },\n props,\n rect\n )\n ];\n };\n\n var sortMarkupByZIndex = function sortMarkupByZIndex(a, b) {\n if (a[1].zIndex \u003E b[1].zIndex) {\n return 1;\n }\n if (a[1].zIndex \u003C b[1].zIndex) {\n return -1;\n }\n return 0;\n };\n\n var createMarkupView = function createMarkupView(_) {\n return _.utils.createView({\n name: 'image-preview-markup',\n tag: 'svg',\n ignoreRect: true,\n mixins: {\n apis: ['width', 'height', 'crop', 'markup', 'resize', 'dirty']\n },\n\n write: function write(_ref) {\n var root = _ref.root,\n props = _ref.props;\n\n if (!props.dirty) return;\n var crop = props.crop,\n resize = props.resize,\n markup = props.markup;\n\n var viewWidth = props.width;\n var viewHeight = props.height;\n\n var cropWidth = crop.width;\n var cropHeight = crop.height;\n\n if (resize) {\n var _size = resize.size;\n\n var outputWidth = _size && _size.width;\n var outputHeight = _size && _size.height;\n var outputFit = resize.mode;\n var outputUpscale = resize.upscale;\n\n if (outputWidth && !outputHeight) outputHeight = outputWidth;\n if (outputHeight && !outputWidth) outputWidth = outputHeight;\n\n var shouldUpscale =\n cropWidth \u003C outputWidth && cropHeight \u003C outputHeight;\n\n if (!shouldUpscale || (shouldUpscale && outputUpscale)) {\n var scalarWidth = outputWidth \u002F cropWidth;\n var scalarHeight = outputHeight \u002F cropHeight;\n\n if (outputFit === 'force') {\n cropWidth = outputWidth;\n cropHeight = outputHeight;\n } else {\n var scalar;\n if (outputFit === 'cover') {\n scalar = Math.max(scalarWidth, scalarHeight);\n } else if (outputFit === 'contain') {\n scalar = Math.min(scalarWidth, scalarHeight);\n }\n cropWidth = cropWidth * scalar;\n cropHeight = cropHeight * scalar;\n }\n }\n }\n\n var size = {\n width: viewWidth,\n height: viewHeight\n };\n\n root.element.setAttribute('width', size.width);\n root.element.setAttribute('height', size.height);\n\n var scale = Math.min(viewWidth \u002F cropWidth, viewHeight \u002F cropHeight);\n\n \u002F\u002F clear\n root.element.innerHTML = '';\n\n \u002F\u002F get filter\n var markupFilter = root.query('GET_IMAGE_PREVIEW_MARKUP_FILTER');\n\n \u002F\u002F draw new\n markup\n .filter(markupFilter)\n .map(prepareMarkup)\n .sort(sortMarkupByZIndex)\n .forEach(function(markup) {\n var _markup = _slicedToArray(markup, 2),\n type = _markup[0],\n settings = _markup[1];\n\n \u002F\u002F create\n var element = createMarkupByType(type, settings);\n\n \u002F\u002F update\n updateMarkupByType(element, type, settings, size, scale);\n\n \u002F\u002F add\n root.element.appendChild(element);\n });\n }\n });\n };\n\n var createVector$1 = function createVector(x, y) {\n return { x: x, y: y };\n };\n\n var vectorDot = function vectorDot(a, b) {\n return a.x * b.x + a.y * b.y;\n };\n\n var vectorSubtract = function vectorSubtract(a, b) {\n return createVector$1(a.x - b.x, a.y - b.y);\n };\n\n var vectorDistanceSquared = function vectorDistanceSquared(a, b) {\n return vectorDot(vectorSubtract(a, b), vectorSubtract(a, b));\n };\n\n var vectorDistance = function vectorDistance(a, b) {\n return Math.sqrt(vectorDistanceSquared(a, b));\n };\n\n var getOffsetPointOnEdge = function getOffsetPointOnEdge(length, rotation) {\n var a = length;\n\n var A = 1.5707963267948966;\n var B = rotation;\n var C = 1.5707963267948966 - rotation;\n\n var sinA = Math.sin(A);\n var sinB = Math.sin(B);\n var sinC = Math.sin(C);\n var cosC = Math.cos(C);\n var ratio = a \u002F sinA;\n var b = ratio * sinB;\n var c = ratio * sinC;\n\n return createVector$1(cosC * b, cosC * c);\n };\n\n var getRotatedRectSize = function getRotatedRectSize(rect, rotation) {\n var w = rect.width;\n var h = rect.height;\n\n var hor = getOffsetPointOnEdge(w, rotation);\n var ver = getOffsetPointOnEdge(h, rotation);\n\n var tl = createVector$1(rect.x + Math.abs(hor.x), rect.y - Math.abs(hor.y));\n\n var tr = createVector$1(\n rect.x + rect.width + Math.abs(ver.y),\n rect.y + Math.abs(ver.x)\n );\n\n var bl = createVector$1(\n rect.x - Math.abs(ver.y),\n rect.y + rect.height - Math.abs(ver.x)\n );\n\n return {\n width: vectorDistance(tl, tr),\n height: vectorDistance(tl, bl)\n };\n };\n\n var calculateCanvasSize = function calculateCanvasSize(\n image,\n canvasAspectRatio\n ) {\n var zoom =\n arguments.length \u003E 2 && arguments[2] !== undefined ? arguments[2] : 1;\n\n var imageAspectRatio = image.height \u002F image.width;\n\n \u002F\u002F determine actual pixels on x and y axis\n var canvasWidth = 1;\n var canvasHeight = canvasAspectRatio;\n var imgWidth = 1;\n var imgHeight = imageAspectRatio;\n if (imgHeight \u003E canvasHeight) {\n imgHeight = canvasHeight;\n imgWidth = imgHeight \u002F imageAspectRatio;\n }\n\n var scalar = Math.max(canvasWidth \u002F imgWidth, canvasHeight \u002F imgHeight);\n var width = image.width \u002F (zoom * scalar * imgWidth);\n var height = width * canvasAspectRatio;\n\n return {\n width: width,\n height: height\n };\n };\n\n var getImageRectZoomFactor = function getImageRectZoomFactor(\n imageRect,\n cropRect,\n rotation,\n center\n ) {\n \u002F\u002F calculate available space round image center position\n var cx = center.x \u003E 0.5 ? 1 - center.x : center.x;\n var cy = center.y \u003E 0.5 ? 1 - center.y : center.y;\n var imageWidth = cx * 2 * imageRect.width;\n var imageHeight = cy * 2 * imageRect.height;\n\n \u002F\u002F calculate rotated crop rectangle size\n var rotatedCropSize = getRotatedRectSize(cropRect, rotation);\n\n \u002F\u002F calculate scalar required to fit image\n return Math.max(\n rotatedCropSize.width \u002F imageWidth,\n rotatedCropSize.height \u002F imageHeight\n );\n };\n\n var getCenteredCropRect = function getCenteredCropRect(\n container,\n aspectRatio\n ) {\n var width = container.width;\n var height = width * aspectRatio;\n if (height \u003E container.height) {\n height = container.height;\n width = height \u002F aspectRatio;\n }\n var x = (container.width - width) * 0.5;\n var y = (container.height - height) * 0.5;\n\n return {\n x: x,\n y: y,\n width: width,\n height: height\n };\n };\n\n var getCurrentCropSize = function getCurrentCropSize(imageSize) {\n var crop =\n arguments.length \u003E 1 && arguments[1] !== undefined ? arguments[1] : {};\n var zoom = crop.zoom,\n rotation = crop.rotation,\n center = crop.center,\n aspectRatio = crop.aspectRatio;\n\n if (!aspectRatio) aspectRatio = imageSize.height \u002F imageSize.width;\n\n var canvasSize = calculateCanvasSize(imageSize, aspectRatio, zoom);\n\n var canvasCenter = {\n x: canvasSize.width * 0.5,\n y: canvasSize.height * 0.5\n };\n\n var stage = {\n x: 0,\n y: 0,\n width: canvasSize.width,\n height: canvasSize.height,\n center: canvasCenter\n };\n\n var shouldLimit = typeof crop.scaleToFit === 'undefined' || crop.scaleToFit;\n\n var stageZoomFactor = getImageRectZoomFactor(\n imageSize,\n getCenteredCropRect(stage, aspectRatio),\n rotation,\n shouldLimit ? center : { x: 0.5, y: 0.5 }\n );\n\n var scale = zoom * stageZoomFactor;\n\n \u002F\u002F start drawing\n return {\n widthFloat: canvasSize.width \u002F scale,\n heightFloat: canvasSize.height \u002F scale,\n width: Math.round(canvasSize.width \u002F scale),\n height: Math.round(canvasSize.height \u002F scale)\n };\n };\n\n var IMAGE_SCALE_SPRING_PROPS = {\n type: 'spring',\n stiffness: 0.5,\n damping: 0.45,\n mass: 10\n };\n\n \u002F\u002F does horizontal and vertical flipping\n var createBitmapView = function createBitmapView(_) {\n return _.utils.createView({\n name: 'image-bitmap',\n ignoreRect: true,\n mixins: { styles: ['scaleX', 'scaleY'] },\n create: function create(_ref) {\n var root = _ref.root,\n props = _ref.props;\n root.appendChild(props.image);\n }\n });\n };\n\n \u002F\u002F shifts and rotates image\n var createImageCanvasWrapper = function createImageCanvasWrapper(_) {\n return _.utils.createView({\n name: 'image-canvas-wrapper',\n tag: 'div',\n ignoreRect: true,\n mixins: {\n apis: ['crop', 'width', 'height'],\n\n styles: [\n 'originX',\n 'originY',\n 'translateX',\n 'translateY',\n 'scaleX',\n 'scaleY',\n 'rotateZ'\n ],\n\n animations: {\n originX: IMAGE_SCALE_SPRING_PROPS,\n originY: IMAGE_SCALE_SPRING_PROPS,\n scaleX: IMAGE_SCALE_SPRING_PROPS,\n scaleY: IMAGE_SCALE_SPRING_PROPS,\n translateX: IMAGE_SCALE_SPRING_PROPS,\n translateY: IMAGE_SCALE_SPRING_PROPS,\n rotateZ: IMAGE_SCALE_SPRING_PROPS\n }\n },\n\n create: function create(_ref2) {\n var root = _ref2.root,\n props = _ref2.props;\n props.width = props.image.width;\n props.height = props.image.height;\n root.ref.bitmap = root.appendChildView(\n root.createChildView(createBitmapView(_), { image: props.image })\n );\n },\n write: function write(_ref3) {\n var root = _ref3.root,\n props = _ref3.props;\n var flip = props.crop.flip;\n var bitmap = root.ref.bitmap;\n bitmap.scaleX = flip.horizontal ? -1 : 1;\n bitmap.scaleY = flip.vertical ? -1 : 1;\n }\n });\n };\n\n \u002F\u002F clips canvas to correct aspect ratio\n var createClipView = function createClipView(_) {\n return _.utils.createView({\n name: 'image-clip',\n tag: 'div',\n ignoreRect: true,\n mixins: {\n apis: [\n 'crop',\n 'markup',\n 'resize',\n 'width',\n 'height',\n 'dirty',\n 'background'\n ],\n\n styles: ['width', 'height', 'opacity'],\n animations: {\n opacity: { type: 'tween', duration: 250 }\n }\n },\n\n didWriteView: function didWriteView(_ref4) {\n var root = _ref4.root,\n props = _ref4.props;\n if (!props.background) return;\n root.element.style.backgroundColor = props.background;\n },\n create: function create(_ref5) {\n var root = _ref5.root,\n props = _ref5.props;\n\n root.ref.image = root.appendChildView(\n root.createChildView(\n createImageCanvasWrapper(_),\n Object.assign({}, props)\n )\n );\n\n root.ref.createMarkup = function() {\n if (root.ref.markup) return;\n root.ref.markup = root.appendChildView(\n root.createChildView(createMarkupView(_), Object.assign({}, props))\n );\n };\n\n root.ref.destroyMarkup = function() {\n if (!root.ref.markup) return;\n root.removeChildView(root.ref.markup);\n root.ref.markup = null;\n };\n\n \u002F\u002F set up transparency grid\n var transparencyIndicator = root.query(\n 'GET_IMAGE_PREVIEW_TRANSPARENCY_INDICATOR'\n );\n if (transparencyIndicator === null) return;\n\n \u002F\u002F grid pattern\n if (transparencyIndicator === 'grid') {\n root.element.dataset.transparencyIndicator = transparencyIndicator;\n }\n \u002F\u002F basic color\n else {\n root.element.dataset.transparencyIndicator = 'color';\n }\n },\n write: function write(_ref6) {\n var root = _ref6.root,\n props = _ref6.props,\n shouldOptimize = _ref6.shouldOptimize;\n var crop = props.crop,\n markup = props.markup,\n resize = props.resize,\n dirty = props.dirty,\n width = props.width,\n height = props.height;\n\n root.ref.image.crop = crop;\n\n var stage = {\n x: 0,\n y: 0,\n width: width,\n height: height,\n center: {\n x: width * 0.5,\n y: height * 0.5\n }\n };\n\n var image = {\n width: root.ref.image.width,\n height: root.ref.image.height\n };\n\n var origin = {\n x: crop.center.x * image.width,\n y: crop.center.y * image.height\n };\n\n var translation = {\n x: stage.center.x - image.width * crop.center.x,\n y: stage.center.y - image.height * crop.center.y\n };\n\n var rotation = Math.PI * 2 + (crop.rotation % (Math.PI * 2));\n\n var cropAspectRatio = crop.aspectRatio || image.height \u002F image.width;\n\n var shouldLimit =\n typeof crop.scaleToFit === 'undefined' || crop.scaleToFit;\n\n var stageZoomFactor = getImageRectZoomFactor(\n image,\n getCenteredCropRect(stage, cropAspectRatio),\n\n rotation,\n shouldLimit ? crop.center : { x: 0.5, y: 0.5 }\n );\n\n var scale = crop.zoom * stageZoomFactor;\n\n \u002F\u002F update markup view\n if (markup && markup.length) {\n root.ref.createMarkup();\n root.ref.markup.width = width;\n root.ref.markup.height = height;\n root.ref.markup.resize = resize;\n root.ref.markup.dirty = dirty;\n root.ref.markup.markup = markup;\n root.ref.markup.crop = getCurrentCropSize(image, crop);\n } else if (root.ref.markup) {\n root.ref.destroyMarkup();\n }\n\n \u002F\u002F update image view\n var imageView = root.ref.image;\n\n \u002F\u002F don't update clip layout\n if (shouldOptimize) {\n imageView.originX = null;\n imageView.originY = null;\n imageView.translateX = null;\n imageView.translateY = null;\n imageView.rotateZ = null;\n imageView.scaleX = null;\n imageView.scaleY = null;\n return;\n }\n\n imageView.originX = origin.x;\n imageView.originY = origin.y;\n imageView.translateX = translation.x;\n imageView.translateY = translation.y;\n imageView.rotateZ = rotation;\n imageView.scaleX = scale;\n imageView.scaleY = scale;\n }\n });\n };\n\n var createImageView = function createImageView(_) {\n return _.utils.createView({\n name: 'image-preview',\n tag: 'div',\n ignoreRect: true,\n mixins: {\n apis: ['image', 'crop', 'markup', 'resize', 'dirty', 'background'],\n\n styles: ['translateY', 'scaleX', 'scaleY', 'opacity'],\n\n animations: {\n scaleX: IMAGE_SCALE_SPRING_PROPS,\n scaleY: IMAGE_SCALE_SPRING_PROPS,\n translateY: IMAGE_SCALE_SPRING_PROPS,\n opacity: { type: 'tween', duration: 400 }\n }\n },\n\n create: function create(_ref7) {\n var root = _ref7.root,\n props = _ref7.props;\n root.ref.clip = root.appendChildView(\n root.createChildView(createClipView(_), {\n id: props.id,\n image: props.image,\n crop: props.crop,\n markup: props.markup,\n resize: props.resize,\n dirty: props.dirty,\n background: props.background\n })\n );\n },\n write: function write(_ref8) {\n var root = _ref8.root,\n props = _ref8.props,\n shouldOptimize = _ref8.shouldOptimize;\n var clip = root.ref.clip;\n var image = props.image,\n crop = props.crop,\n markup = props.markup,\n resize = props.resize,\n dirty = props.dirty;\n\n clip.crop = crop;\n clip.markup = markup;\n clip.resize = resize;\n clip.dirty = dirty;\n\n \u002F\u002F don't update clip layout\n clip.opacity = shouldOptimize ? 0 : 1;\n\n \u002F\u002F don't re-render if optimizing or hidden (width will be zero resulting in weird animations)\n if (shouldOptimize || root.rect.element.hidden) return;\n\n \u002F\u002F calculate scaled preview image size\n var imageAspectRatio = image.height \u002F image.width;\n var aspectRatio = crop.aspectRatio || imageAspectRatio;\n\n \u002F\u002F calculate container size\n var containerWidth = root.rect.inner.width;\n var containerHeight = root.rect.inner.height;\n\n var fixedPreviewHeight = root.query('GET_IMAGE_PREVIEW_HEIGHT');\n var minPreviewHeight = root.query('GET_IMAGE_PREVIEW_MIN_HEIGHT');\n var maxPreviewHeight = root.query('GET_IMAGE_PREVIEW_MAX_HEIGHT');\n\n var panelAspectRatio = root.query('GET_PANEL_ASPECT_RATIO');\n var allowMultiple = root.query('GET_ALLOW_MULTIPLE');\n\n if (panelAspectRatio && !allowMultiple) {\n fixedPreviewHeight = containerWidth * panelAspectRatio;\n aspectRatio = panelAspectRatio;\n }\n\n \u002F\u002F determine clip width and height\n var clipHeight =\n fixedPreviewHeight !== null\n ? fixedPreviewHeight\n : Math.max(\n minPreviewHeight,\n Math.min(containerWidth * aspectRatio, maxPreviewHeight)\n );\n\n var clipWidth = clipHeight \u002F aspectRatio;\n if (clipWidth \u003E containerWidth) {\n clipWidth = containerWidth;\n clipHeight = clipWidth * aspectRatio;\n }\n\n if (clipHeight \u003E containerHeight) {\n clipHeight = containerHeight;\n clipWidth = containerHeight \u002F aspectRatio;\n }\n\n clip.width = clipWidth;\n clip.height = clipHeight;\n }\n });\n };\n\n var SVG_MASK =\n '\u003Csvg width=\"500\" height=\"200\" viewBox=\"0 0 500 200\" preserveAspectRatio=\"none\"\u003E\\n \u003Cdefs\u003E\\n \u003CradialGradient id=\"gradient-__UID__\" cx=\".5\" cy=\"1.25\" r=\"1.15\"\u003E\\n \u003Cstop offset=\\'50%\\' stop-color=\\'#000000\\'\u002F\u003E\\n \u003Cstop offset=\\'56%\\' stop-color=\\'#0a0a0a\\'\u002F\u003E\\n \u003Cstop offset=\\'63%\\' stop-color=\\'#262626\\'\u002F\u003E\\n \u003Cstop offset=\\'69%\\' stop-color=\\'#4f4f4f\\'\u002F\u003E\\n \u003Cstop offset=\\'75%\\' stop-color=\\'#808080\\'\u002F\u003E\\n \u003Cstop offset=\\'81%\\' stop-color=\\'#b1b1b1\\'\u002F\u003E\\n \u003Cstop offset=\\'88%\\' stop-color=\\'#dadada\\'\u002F\u003E\\n \u003Cstop offset=\\'94%\\' stop-color=\\'#f6f6f6\\'\u002F\u003E\\n \u003Cstop offset=\\'100%\\' stop-color=\\'#ffffff\\'\u002F\u003E\\n \u003C\u002FradialGradient\u003E\\n \u003Cmask id=\"mask-__UID__\"\u003E\\n \u003Crect x=\"0\" y=\"0\" width=\"500\" height=\"200\" fill=\"url(#gradient-__UID__)\"\u003E\u003C\u002Frect\u003E\\n \u003C\u002Fmask\u003E\\n \u003C\u002Fdefs\u003E\\n \u003Crect x=\"0\" width=\"500\" height=\"200\" fill=\"currentColor\" mask=\"url(#mask-__UID__)\"\u003E\u003C\u002Frect\u003E\\n\u003C\u002Fsvg\u003E';\n\n var checkedMyBases = false;\n var SVGMaskUniqueId = 0;\n\n var createImageOverlayView = function createImageOverlayView(fpAPI) {\n return fpAPI.utils.createView({\n name: 'image-preview-overlay',\n tag: 'div',\n ignoreRect: true,\n create: function create(_ref) {\n var root = _ref.root,\n props = _ref.props;\n\n if (!checkedMyBases && document.querySelector('base')) {\n SVG_MASK = SVG_MASK.replace(\n \u002Furl\\(\\#\u002Fg,\n 'url(' +\n window.location.href.replace(window.location.hash, '') +\n '#'\n );\n checkedMyBases = true;\n }\n\n SVGMaskUniqueId++;\n root.element.classList.add(\n 'filepond--image-preview-overlay-'.concat(props.status)\n );\n root.element.innerHTML = SVG_MASK.replace(\u002F__UID__\u002Fg, SVGMaskUniqueId);\n },\n mixins: {\n styles: ['opacity'],\n animations: {\n opacity: { type: 'spring', mass: 25 }\n }\n }\n });\n };\n\n \u002F**\n * Bitmap Worker\n *\u002F\n var BitmapWorker = function BitmapWorker() {\n self.onmessage = function(e) {\n createImageBitmap(e.data.message.file).then(function(bitmap) {\n self.postMessage({ id: e.data.id, message: bitmap }, [bitmap]);\n });\n };\n };\n\n \u002F**\n * ColorMatrix Worker\n *\u002F\n var ColorMatrixWorker = function ColorMatrixWorker() {\n self.onmessage = function(e) {\n var imageData = e.data.message.imageData;\n var matrix = e.data.message.colorMatrix;\n\n var data = imageData.data;\n var l = data.length;\n\n var m11 = matrix[0];\n var m12 = matrix[1];\n var m13 = matrix[2];\n var m14 = matrix[3];\n var m15 = matrix[4];\n\n var m21 = matrix[5];\n var m22 = matrix[6];\n var m23 = matrix[7];\n var m24 = matrix[8];\n var m25 = matrix[9];\n\n var m31 = matrix[10];\n var m32 = matrix[11];\n var m33 = matrix[12];\n var m34 = matrix[13];\n var m35 = matrix[14];\n\n var m41 = matrix[15];\n var m42 = matrix[16];\n var m43 = matrix[17];\n var m44 = matrix[18];\n var m45 = matrix[19];\n\n var index = 0,\n r = 0.0,\n g = 0.0,\n b = 0.0,\n a = 0.0;\n\n for (; index \u003C l; index += 4) {\n r = data[index] \u002F 255;\n g = data[index + 1] \u002F 255;\n b = data[index + 2] \u002F 255;\n a = data[index + 3] \u002F 255;\n data[index] = Math.max(\n 0,\n Math.min((r * m11 + g * m12 + b * m13 + a * m14 + m15) * 255, 255)\n );\n data[index + 1] = Math.max(\n 0,\n Math.min((r * m21 + g * m22 + b * m23 + a * m24 + m25) * 255, 255)\n );\n data[index + 2] = Math.max(\n 0,\n Math.min((r * m31 + g * m32 + b * m33 + a * m34 + m35) * 255, 255)\n );\n data[index + 3] = Math.max(\n 0,\n Math.min((r * m41 + g * m42 + b * m43 + a * m44 + m45) * 255, 255)\n );\n }\n\n self.postMessage({ id: e.data.id, message: imageData }, [\n imageData.data.buffer\n ]);\n };\n };\n\n var getImageSize = function getImageSize(url, cb) {\n var image = new Image();\n image.onload = function() {\n var width = image.naturalWidth;\n var height = image.naturalHeight;\n image = null;\n cb(width, height);\n };\n image.src = url;\n };\n\n var transforms = {\n 1: function _() {\n return [1, 0, 0, 1, 0, 0];\n },\n 2: function _(width) {\n return [-1, 0, 0, 1, width, 0];\n },\n 3: function _(width, height) {\n return [-1, 0, 0, -1, width, height];\n },\n 4: function _(width, height) {\n return [1, 0, 0, -1, 0, height];\n },\n 5: function _() {\n return [0, 1, 1, 0, 0, 0];\n },\n 6: function _(width, height) {\n return [0, 1, -1, 0, height, 0];\n },\n 7: function _(width, height) {\n return [0, -1, -1, 0, height, width];\n },\n 8: function _(width) {\n return [0, -1, 1, 0, 0, width];\n }\n };\n\n var fixImageOrientation = function fixImageOrientation(\n ctx,\n width,\n height,\n orientation\n ) {\n \u002F\u002F no orientation supplied\n if (orientation === -1) {\n return;\n }\n\n ctx.transform.apply(ctx, transforms[orientation](width, height));\n };\n\n \u002F\u002F draws the preview image to canvas\n var createPreviewImage = function createPreviewImage(\n data,\n width,\n height,\n orientation\n ) {\n \u002F\u002F can't draw on half pixels\n width = Math.round(width);\n height = Math.round(height);\n\n \u002F\u002F draw image\n var canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n var ctx = canvas.getContext('2d');\n\n \u002F\u002F if is rotated incorrectly swap width and height\n if (orientation \u003E= 5 && orientation \u003C= 8) {\n var _ref = [height, width];\n width = _ref[0];\n height = _ref[1];\n }\n\n \u002F\u002F correct image orientation\n fixImageOrientation(ctx, width, height, orientation);\n\n \u002F\u002F draw the image\n ctx.drawImage(data, 0, 0, width, height);\n\n return canvas;\n };\n\n var isBitmap = function isBitmap(file) {\n return \u002F^image\u002F.test(file.type) && !\u002Fsvg\u002F.test(file.type);\n };\n\n var MAX_WIDTH = 10;\n var MAX_HEIGHT = 10;\n\n var calculateAverageColor = function calculateAverageColor(image) {\n var scalar = Math.min(MAX_WIDTH \u002F image.width, MAX_HEIGHT \u002F image.height);\n\n var canvas = document.createElement('canvas');\n var ctx = canvas.getContext('2d');\n var width = (canvas.width = Math.ceil(image.width * scalar));\n var height = (canvas.height = Math.ceil(image.height * scalar));\n ctx.drawImage(image, 0, 0, width, height);\n var data = null;\n try {\n data = ctx.getImageData(0, 0, width, height).data;\n } catch (e) {\n return null;\n }\n var l = data.length;\n\n var r = 0;\n var g = 0;\n var b = 0;\n var i = 0;\n\n for (; i \u003C l; i += 4) {\n r += data[i] * data[i];\n g += data[i + 1] * data[i + 1];\n b += data[i + 2] * data[i + 2];\n }\n\n r = averageColor(r, l);\n g = averageColor(g, l);\n b = averageColor(b, l);\n\n return { r: r, g: g, b: b };\n };\n\n var averageColor = function averageColor(c, l) {\n return Math.floor(Math.sqrt(c \u002F (l \u002F 4)));\n };\n\n var cloneCanvas = function cloneCanvas(origin, target) {\n target = target || document.createElement('canvas');\n target.width = origin.width;\n target.height = origin.height;\n var ctx = target.getContext('2d');\n ctx.drawImage(origin, 0, 0);\n return target;\n };\n\n var cloneImageData = function cloneImageData(imageData) {\n var id;\n try {\n id = new ImageData(imageData.width, imageData.height);\n } catch (e) {\n var canvas = document.createElement('canvas');\n var ctx = canvas.getContext('2d');\n id = ctx.createImageData(imageData.width, imageData.height);\n }\n id.data.set(new Uint8ClampedArray(imageData.data));\n return id;\n };\n\n var loadImage = function loadImage(url) {\n return new Promise(function(resolve, reject) {\n var img = new Image();\n img.crossOrigin = 'Anonymous';\n img.onload = function() {\n resolve(img);\n };\n img.onerror = function(e) {\n reject(e);\n };\n img.src = url;\n });\n };\n\n var createImageWrapperView = function createImageWrapperView(_) {\n \u002F\u002F create overlay view\n var OverlayView = createImageOverlayView(_);\n\n var ImageView = createImageView(_);\n var createWorker = _.utils.createWorker;\n\n var applyFilter = function applyFilter(root, filter, target) {\n return new Promise(function(resolve) {\n \u002F\u002F will store image data for future filter updates\n if (!root.ref.imageData) {\n root.ref.imageData = target\n .getContext('2d')\n .getImageData(0, 0, target.width, target.height);\n }\n\n \u002F\u002F get image data reference\n var imageData = cloneImageData(root.ref.imageData);\n\n if (!filter || filter.length !== 20) {\n target.getContext('2d').putImageData(imageData, 0, 0);\n return resolve();\n }\n\n var worker = createWorker(ColorMatrixWorker);\n worker.post(\n {\n imageData: imageData,\n colorMatrix: filter\n },\n\n function(response) {\n \u002F\u002F apply filtered colors\n target.getContext('2d').putImageData(response, 0, 0);\n\n \u002F\u002F stop worker\n worker.terminate();\n\n \u002F\u002F done!\n resolve();\n },\n [imageData.data.buffer]\n );\n });\n };\n\n var removeImageView = function removeImageView(root, imageView) {\n root.removeChildView(imageView);\n imageView.image.width = 1;\n imageView.image.height = 1;\n imageView._destroy();\n };\n\n \u002F\u002F remove an image\n var shiftImage = function shiftImage(_ref) {\n var root = _ref.root;\n var imageView = root.ref.images.shift();\n imageView.opacity = 0;\n imageView.translateY = -15;\n root.ref.imageViewBin.push(imageView);\n return imageView;\n };\n\n \u002F\u002F add new image\n var pushImage = function pushImage(_ref2) {\n var root = _ref2.root,\n props = _ref2.props,\n image = _ref2.image;\n\n var id = props.id;\n var item = root.query('GET_ITEM', { id: id });\n if (!item) return;\n\n var crop = item.getMetadata('crop') || {\n center: {\n x: 0.5,\n y: 0.5\n },\n\n flip: {\n horizontal: false,\n vertical: false\n },\n\n zoom: 1,\n rotation: 0,\n aspectRatio: null\n };\n\n var background = root.query(\n 'GET_IMAGE_TRANSFORM_CANVAS_BACKGROUND_COLOR'\n );\n\n var markup;\n var resize;\n var dirty = false;\n if (root.query('GET_IMAGE_PREVIEW_MARKUP_SHOW')) {\n markup = item.getMetadata('markup') || [];\n resize = item.getMetadata('resize');\n dirty = true;\n }\n\n \u002F\u002F append image presenter\n var imageView = root.appendChildView(\n root.createChildView(ImageView, {\n id: id,\n image: image,\n crop: crop,\n resize: resize,\n markup: markup,\n dirty: dirty,\n background: background,\n opacity: 0,\n scaleX: 1.15,\n scaleY: 1.15,\n translateY: 15\n }),\n\n root.childViews.length\n );\n\n root.ref.images.push(imageView);\n\n \u002F\u002F reveal the preview image\n imageView.opacity = 1;\n imageView.scaleX = 1;\n imageView.scaleY = 1;\n imageView.translateY = 0;\n\n \u002F\u002F the preview is now ready to be drawn\n setTimeout(function() {\n root.dispatch('DID_IMAGE_PREVIEW_SHOW', { id: id });\n }, 250);\n };\n\n var updateImage = function updateImage(_ref3) {\n var root = _ref3.root,\n props = _ref3.props;\n var item = root.query('GET_ITEM', { id: props.id });\n if (!item) return;\n var imageView = root.ref.images[root.ref.images.length - 1];\n imageView.crop = item.getMetadata('crop');\n imageView.background = root.query(\n 'GET_IMAGE_TRANSFORM_CANVAS_BACKGROUND_COLOR'\n );\n if (root.query('GET_IMAGE_PREVIEW_MARKUP_SHOW')) {\n imageView.dirty = true;\n imageView.resize = item.getMetadata('resize');\n imageView.markup = item.getMetadata('markup');\n }\n };\n\n \u002F\u002F replace image preview\n var didUpdateItemMetadata = function didUpdateItemMetadata(_ref4) {\n var root = _ref4.root,\n props = _ref4.props,\n action = _ref4.action;\n\n \u002F\u002F only filter and crop trigger redraw\n if (!\u002Fcrop|filter|markup|resize\u002F.test(action.change.key)) return;\n\n \u002F\u002F no images to update, exit\n if (!root.ref.images.length) return;\n\n \u002F\u002F no item found, exit\n var item = root.query('GET_ITEM', { id: props.id });\n if (!item) return;\n\n \u002F\u002F for now, update existing image when filtering\n if (\u002Ffilter\u002F.test(action.change.key)) {\n var imageView = root.ref.images[root.ref.images.length - 1];\n applyFilter(root, action.change.value, imageView.image);\n return;\n }\n\n if (\u002Fcrop|markup|resize\u002F.test(action.change.key)) {\n var crop = item.getMetadata('crop');\n var image = root.ref.images[root.ref.images.length - 1];\n\n \u002F\u002F if aspect ratio has changed, we need to create a new image\n if (Math.abs(crop.aspectRatio - image.crop.aspectRatio) \u003E 0.00001) {\n var _imageView = shiftImage({ root: root });\n pushImage({\n root: root,\n props: props,\n image: cloneCanvas(_imageView.image)\n });\n }\n \u002F\u002F if not, we can update the current image\n else {\n updateImage({ root: root, props: props });\n }\n }\n };\n\n var canCreateImageBitmap = function canCreateImageBitmap(file) {\n \u002F\u002F Firefox versions before 58 will freeze when running createImageBitmap\n \u002F\u002F in a Web Worker so we detect those versions and return false for support\n var userAgent = window.navigator.userAgent;\n var isFirefox = userAgent.match(\u002FFirefox\\\u002F([0-9]+)\\.\u002F);\n var firefoxVersion = isFirefox ? parseInt(isFirefox[1]) : null;\n if (firefoxVersion \u003C= 58) return false;\n\n return 'createImageBitmap' in window && isBitmap(file);\n };\n\n \u002F**\n * Write handler for when preview container has been created\n *\u002F\n var didCreatePreviewContainer = function didCreatePreviewContainer(_ref5) {\n var root = _ref5.root,\n props = _ref5.props;\n var id = props.id;\n\n \u002F\u002F we need to get the file data to determine the eventual image size\n var item = root.query('GET_ITEM', id);\n if (!item) return;\n\n \u002F\u002F get url to file (we'll revoke it later on when done)\n var fileURL = URL.createObjectURL(item.file);\n\n \u002F\u002F determine image size of this item\n getImageSize(fileURL, function(width, height) {\n \u002F\u002F we can now scale the panel to the final size\n root.dispatch('DID_IMAGE_PREVIEW_CALCULATE_SIZE', {\n id: id,\n width: width,\n height: height\n });\n });\n };\n\n var drawPreview = function drawPreview(_ref6) {\n var root = _ref6.root,\n props = _ref6.props;\n var id = props.id;\n\n \u002F\u002F we need to get the file data to determine the eventual image size\n var item = root.query('GET_ITEM', id);\n if (!item) return;\n\n \u002F\u002F get url to file (we'll revoke it later on when done)\n var fileURL = URL.createObjectURL(item.file);\n\n \u002F\u002F fallback\n var loadPreviewFallback = function loadPreviewFallback() {\n \u002F\u002F let's scale the image in the main thread :(\n loadImage(fileURL).then(previewImageLoaded);\n };\n\n \u002F\u002F image is now ready\n var previewImageLoaded = function previewImageLoaded(imageData) {\n \u002F\u002F the file url is no longer needed\n URL.revokeObjectURL(fileURL);\n\n \u002F\u002F draw the scaled down version here and use that as source so bitmapdata can be closed\n \u002F\u002F orientation info\n var exif = item.getMetadata('exif') || {};\n var orientation = exif.orientation || -1;\n\n \u002F\u002F get width and height from action, and swap if orientation is incorrect\n var width = imageData.width,\n height = imageData.height;\n\n \u002F\u002F if no width or height, just return early.\n if (!width || !height) return;\n\n if (orientation \u003E= 5 && orientation \u003C= 8) {\n var _ref7 = [height, width];\n width = _ref7[0];\n height = _ref7[1];\n }\n\n \u002F\u002F scale canvas based on pixel density\n \u002F\u002F we multiply by .75 as that creates smaller but still clear images on screens with high res displays\n var pixelDensityFactor = Math.max(1, window.devicePixelRatio * 0.75);\n\n \u002F\u002F we want as much pixels to work with as possible,\n \u002F\u002F this multiplies the minimum image resolution,\n \u002F\u002F so when zooming in it doesn't get too blurry\n var zoomFactor = root.query('GET_IMAGE_PREVIEW_ZOOM_FACTOR');\n\n \u002F\u002F imaeg scale factor\n var scaleFactor = zoomFactor * pixelDensityFactor;\n\n \u002F\u002F calculate scaled preview image size\n var previewImageRatio = height \u002F width;\n\n \u002F\u002F calculate image preview height and width\n var previewContainerWidth = root.rect.element.width;\n var previewContainerHeight = root.rect.element.height;\n\n var imageWidth = previewContainerWidth;\n var imageHeight = imageWidth * previewImageRatio;\n\n if (previewImageRatio \u003E 1) {\n imageWidth = Math.min(width, previewContainerWidth * scaleFactor);\n imageHeight = imageWidth * previewImageRatio;\n } else {\n imageHeight = Math.min(height, previewContainerHeight * scaleFactor);\n imageWidth = imageHeight \u002F previewImageRatio;\n }\n\n \u002F\u002F transfer to image tag so no canvas memory wasted on iOS\n var previewImage = createPreviewImage(\n imageData,\n imageWidth,\n imageHeight,\n orientation\n );\n\n \u002F\u002F done\n var done = function done() {\n \u002F\u002F calculate average image color, disabled for now\n var averageColor = root.query(\n 'GET_IMAGE_PREVIEW_CALCULATE_AVERAGE_IMAGE_COLOR'\n )\n ? calculateAverageColor(data)\n : null;\n item.setMetadata('color', averageColor, true);\n\n \u002F\u002F data has been transferred to canvas ( if was ImageBitmap )\n if ('close' in imageData) {\n imageData.close();\n }\n\n \u002F\u002F show the overlay\n root.ref.overlayShadow.opacity = 1;\n\n \u002F\u002F create the first image\n pushImage({ root: root, props: props, image: previewImage });\n };\n\n \u002F\u002F apply filter\n var filter = item.getMetadata('filter');\n if (filter) {\n applyFilter(root, filter, previewImage).then(done);\n } else {\n done();\n }\n };\n\n \u002F\u002F if we support scaling using createImageBitmap we use a worker\n if (canCreateImageBitmap(item.file)) {\n \u002F\u002F let's scale the image in a worker\n var worker = createWorker(BitmapWorker);\n\n worker.post(\n {\n file: item.file\n },\n\n function(imageBitmap) {\n \u002F\u002F destroy worker\n worker.terminate();\n\n \u002F\u002F no bitmap returned, must be something wrong,\n \u002F\u002F try the oldschool way\n if (!imageBitmap) {\n loadPreviewFallback();\n return;\n }\n\n \u002F\u002F yay we got our bitmap, let's continue showing the preview\n previewImageLoaded(imageBitmap);\n }\n );\n } else {\n \u002F\u002F create fallback preview\n loadPreviewFallback();\n }\n };\n\n \u002F**\n * Write handler for when the preview image is ready to be animated\n *\u002F\n var didDrawPreview = function didDrawPreview(_ref8) {\n var root = _ref8.root;\n \u002F\u002F get last added image\n var image = root.ref.images[root.ref.images.length - 1];\n image.translateY = 0;\n image.scaleX = 1.0;\n image.scaleY = 1.0;\n image.opacity = 1;\n };\n\n \u002F**\n * Write handler for when the preview has been loaded\n *\u002F\n var restoreOverlay = function restoreOverlay(_ref9) {\n var root = _ref9.root;\n root.ref.overlayShadow.opacity = 1;\n root.ref.overlayError.opacity = 0;\n root.ref.overlaySuccess.opacity = 0;\n };\n\n var didThrowError = function didThrowError(_ref10) {\n var root = _ref10.root;\n root.ref.overlayShadow.opacity = 0.25;\n root.ref.overlayError.opacity = 1;\n };\n\n var didCompleteProcessing = function didCompleteProcessing(_ref11) {\n var root = _ref11.root;\n root.ref.overlayShadow.opacity = 0.25;\n root.ref.overlaySuccess.opacity = 1;\n };\n\n \u002F**\n * Constructor\n *\u002F\n var create = function create(_ref12) {\n var root = _ref12.root;\n\n \u002F\u002F image view\n root.ref.images = [];\n\n \u002F\u002F the preview image data (we need this to filter the image)\n root.ref.imageData = null;\n\n \u002F\u002F image bin\n root.ref.imageViewBin = [];\n\n \u002F\u002F image overlays\n root.ref.overlayShadow = root.appendChildView(\n root.createChildView(OverlayView, {\n opacity: 0,\n status: 'idle'\n })\n );\n\n root.ref.overlaySuccess = root.appendChildView(\n root.createChildView(OverlayView, {\n opacity: 0,\n status: 'success'\n })\n );\n\n root.ref.overlayError = root.appendChildView(\n root.createChildView(OverlayView, {\n opacity: 0,\n status: 'failure'\n })\n );\n };\n\n return _.utils.createView({\n name: 'image-preview-wrapper',\n create: create,\n styles: ['height'],\n\n apis: ['height'],\n\n destroy: function destroy(_ref13) {\n var root = _ref13.root;\n \u002F\u002F we resize the image so memory on iOS 12 is released more quickly (it seems)\n root.ref.images.forEach(function(imageView) {\n imageView.image.width = 1;\n imageView.image.height = 1;\n });\n },\n didWriteView: function didWriteView(_ref14) {\n var root = _ref14.root;\n root.ref.images.forEach(function(imageView) {\n imageView.dirty = false;\n });\n },\n write: _.utils.createRoute(\n {\n \u002F\u002F image preview stated\n DID_IMAGE_PREVIEW_DRAW: didDrawPreview,\n DID_IMAGE_PREVIEW_CONTAINER_CREATE: didCreatePreviewContainer,\n DID_FINISH_CALCULATE_PREVIEWSIZE: drawPreview,\n DID_UPDATE_ITEM_METADATA: didUpdateItemMetadata,\n\n \u002F\u002F file states\n DID_THROW_ITEM_LOAD_ERROR: didThrowError,\n DID_THROW_ITEM_PROCESSING_ERROR: didThrowError,\n DID_THROW_ITEM_INVALID: didThrowError,\n DID_COMPLETE_ITEM_PROCESSING: didCompleteProcessing,\n DID_START_ITEM_PROCESSING: restoreOverlay,\n DID_REVERT_ITEM_PROCESSING: restoreOverlay\n },\n function(_ref15) {\n var root = _ref15.root;\n\n \u002F\u002F views on death row\n var viewsToRemove = root.ref.imageViewBin.filter(function(imageView) {\n return imageView.opacity === 0;\n });\n\n \u002F\u002F views to retain\n root.ref.imageViewBin = root.ref.imageViewBin.filter(function(\n imageView\n ) {\n return imageView.opacity \u003E 0;\n });\n\n \u002F\u002F remove these views\n viewsToRemove.forEach(function(imageView) {\n return removeImageView(root, imageView);\n });\n viewsToRemove.length = 0;\n }\n )\n });\n };\n\n \u002F**\n * Image Preview Plugin\n *\u002F\n var plugin = function plugin(fpAPI) {\n var addFilter = fpAPI.addFilter,\n utils = fpAPI.utils;\n var Type = utils.Type,\n createRoute = utils.createRoute,\n isFile = utils.isFile;\n\n \u002F\u002F imagePreviewView\n var imagePreviewView = createImageWrapperView(fpAPI);\n\n \u002F\u002F called for each view that is created right after the 'create' method\n addFilter('CREATE_VIEW', function(viewAPI) {\n \u002F\u002F get reference to created view\n var is = viewAPI.is,\n view = viewAPI.view,\n query = viewAPI.query;\n\n \u002F\u002F only hook up to item view and only if is enabled for this cropper\n if (!is('file') || !query('GET_ALLOW_IMAGE_PREVIEW')) return;\n\n \u002F\u002F create the image preview plugin, but only do so if the item is an image\n var didLoadItem = function didLoadItem(_ref) {\n var root = _ref.root,\n props = _ref.props;\n var id = props.id;\n var item = query('GET_ITEM', id);\n\n \u002F\u002F item could theoretically have been removed in the mean time\n if (!item || !isFile(item.file) || item.archived) return;\n\n \u002F\u002F get the file object\n var file = item.file;\n\n \u002F\u002F exit if this is not an image\n if (!isPreviewableImage(file)) return;\n\n \u002F\u002F test if is filtered\n if (!query('GET_IMAGE_PREVIEW_FILTER_ITEM')(item)) return;\n\n \u002F\u002F exit if image size is too high and no createImageBitmap support\n \u002F\u002F this would simply bring the browser to its knees and that is not what we want\n var supportsCreateImageBitmap = 'createImageBitmap' in (window || {});\n var maxPreviewFileSize = query('GET_IMAGE_PREVIEW_MAX_FILE_SIZE');\n if (\n !supportsCreateImageBitmap &&\n maxPreviewFileSize &&\n file.size \u003E maxPreviewFileSize\n )\n return;\n\n \u002F\u002F set preview view\n root.ref.imagePreview = view.appendChildView(\n view.createChildView(imagePreviewView, { id: id })\n );\n\n \u002F\u002F update height if is fixed\n var fixedPreviewHeight = root.query('GET_IMAGE_PREVIEW_HEIGHT');\n if (fixedPreviewHeight) {\n root.dispatch('DID_UPDATE_PANEL_HEIGHT', {\n id: item.id,\n height: fixedPreviewHeight\n });\n }\n\n \u002F\u002F now ready\n var queue =\n !supportsCreateImageBitmap &&\n file.size \u003E query('GET_IMAGE_PREVIEW_MAX_INSTANT_PREVIEW_FILE_SIZE');\n root.dispatch('DID_IMAGE_PREVIEW_CONTAINER_CREATE', { id: id }, queue);\n };\n\n var rescaleItem = function rescaleItem(root, props) {\n if (!root.ref.imagePreview) return;\n var id = props.id;\n\n \u002F\u002F get item\n var item = root.query('GET_ITEM', { id: id });\n if (!item) return;\n\n \u002F\u002F if is fixed height or panel has aspect ratio, exit here, height has already been defined\n var panelAspectRatio = root.query('GET_PANEL_ASPECT_RATIO');\n var itemPanelAspectRatio = root.query('GET_ITEM_PANEL_ASPECT_RATIO');\n var fixedHeight = root.query('GET_IMAGE_PREVIEW_HEIGHT');\n if (panelAspectRatio || itemPanelAspectRatio || fixedHeight) return;\n\n \u002F\u002F no data!\n var _root$ref = root.ref,\n imageWidth = _root$ref.imageWidth,\n imageHeight = _root$ref.imageHeight;\n if (!imageWidth || !imageHeight) return;\n\n \u002F\u002F get height min and max\n var minPreviewHeight = root.query('GET_IMAGE_PREVIEW_MIN_HEIGHT');\n var maxPreviewHeight = root.query('GET_IMAGE_PREVIEW_MAX_HEIGHT');\n\n \u002F\u002F orientation info\n var exif = item.getMetadata('exif') || {};\n var orientation = exif.orientation || -1;\n\n \u002F\u002F get width and height from action, and swap of orientation is incorrect\n if (orientation \u003E= 5 && orientation \u003C= 8) {\n var _ref2 = [imageHeight, imageWidth];\n imageWidth = _ref2[0];\n imageHeight = _ref2[1];\n }\n\n \u002F\u002F scale up width and height when we're dealing with an SVG\n if (!isBitmap(item.file) || root.query('GET_IMAGE_PREVIEW_UPSCALE')) {\n var scalar = 2048 \u002F imageWidth;\n imageWidth *= scalar;\n imageHeight *= scalar;\n }\n\n \u002F\u002F image aspect ratio\n var imageAspectRatio = imageHeight \u002F imageWidth;\n\n \u002F\u002F we need the item to get to the crop size\n var previewAspectRatio =\n (item.getMetadata('crop') || {}).aspectRatio || imageAspectRatio;\n\n \u002F\u002F preview height range\n var previewHeightMax = Math.max(\n minPreviewHeight,\n Math.min(imageHeight, maxPreviewHeight)\n );\n var itemWidth = root.rect.element.width;\n var previewHeight = Math.min(\n itemWidth * previewAspectRatio,\n previewHeightMax\n );\n\n \u002F\u002F request update to panel height\n root.dispatch('DID_UPDATE_PANEL_HEIGHT', {\n id: item.id,\n height: previewHeight\n });\n };\n\n var didResizeView = function didResizeView(_ref3) {\n var root = _ref3.root;\n \u002F\u002F actions in next write operation\n root.ref.shouldRescale = true;\n };\n\n var didUpdateItemMetadata = function didUpdateItemMetadata(_ref4) {\n var root = _ref4.root,\n action = _ref4.action;\n\n if (action.change.key !== 'crop') return;\n\n \u002F\u002F actions in next write operation\n root.ref.shouldRescale = true;\n };\n\n var didCalculatePreviewSize = function didCalculatePreviewSize(_ref5) {\n var root = _ref5.root,\n action = _ref5.action;\n\n \u002F\u002F remember dimensions\n root.ref.imageWidth = action.width;\n root.ref.imageHeight = action.height;\n\n \u002F\u002F actions in next write operation\n root.ref.shouldRescale = true;\n root.ref.shouldDrawPreview = true;\n\n \u002F\u002F as image load could take a while and fire when draw loop is resting we need to give it a kick\n root.dispatch('KICK');\n };\n\n \u002F\u002F start writing\n view.registerWriter(\n createRoute(\n {\n DID_RESIZE_ROOT: didResizeView,\n DID_STOP_RESIZE: didResizeView,\n DID_LOAD_ITEM: didLoadItem,\n DID_IMAGE_PREVIEW_CALCULATE_SIZE: didCalculatePreviewSize,\n DID_UPDATE_ITEM_METADATA: didUpdateItemMetadata\n },\n function(_ref6) {\n var root = _ref6.root,\n props = _ref6.props;\n\n \u002F\u002F no preview view attached\n if (!root.ref.imagePreview) return;\n\n \u002F\u002F don't do anything while hidden\n if (root.rect.element.hidden) return;\n\n \u002F\u002F resize the item panel\n if (root.ref.shouldRescale) {\n rescaleItem(root, props);\n root.ref.shouldRescale = false;\n }\n\n if (root.ref.shouldDrawPreview) {\n \u002F\u002F queue till next frame so we're sure the height has been applied this forces the draw image call inside the wrapper view to use the correct height\n requestAnimationFrame(function() {\n root.dispatch('DID_FINISH_CALCULATE_PREVIEWSIZE', {\n id: props.id\n });\n });\n root.ref.shouldDrawPreview = false;\n }\n }\n )\n );\n });\n\n \u002F\u002F expose plugin\n return {\n options: {\n \u002F\u002F Enable or disable image preview\n allowImagePreview: [true, Type.BOOLEAN],\n\n \u002F\u002F filters file items to determine which are shown as preview\n imagePreviewFilterItem: [\n function() {\n return true;\n },\n Type.FUNCTION\n ],\n\n \u002F\u002F Fixed preview height\n imagePreviewHeight: [null, Type.INT],\n\n \u002F\u002F Min image height\n imagePreviewMinHeight: [44, Type.INT],\n\n \u002F\u002F Max image height\n imagePreviewMaxHeight: [256, Type.INT],\n\n \u002F\u002F Max size of preview file for when createImageBitmap is not supported\n imagePreviewMaxFileSize: [null, Type.INT],\n\n \u002F\u002F The amount of extra pixels added to the image preview to allow comfortable zooming\n imagePreviewZoomFactor: [2, Type.INT],\n\n \u002F\u002F Should we upscale small images to fit the max bounding box of the preview area\n imagePreviewUpscale: [false, Type.BOOLEAN],\n\n \u002F\u002F Max size of preview file that we allow to try to instant preview if createImageBitmap is not supported, else image is queued for loading\n imagePreviewMaxInstantPreviewFileSize: [1000000, Type.INT],\n\n \u002F\u002F Style of the transparancy indicator used behind images\n imagePreviewTransparencyIndicator: [null, Type.STRING],\n\n \u002F\u002F Enables or disables reading average image color\n imagePreviewCalculateAverageImageColor: [false, Type.BOOLEAN],\n\n \u002F\u002F Enables or disables the previewing of markup\n imagePreviewMarkupShow: [true, Type.BOOLEAN],\n\n \u002F\u002F Allows filtering of markup to only show certain shapes\n imagePreviewMarkupFilter: [\n function() {\n return true;\n },\n Type.FUNCTION\n ]\n }\n };\n };\n\n \u002F\u002F fire pluginloaded event if running in browser, this allows registering the plugin when using async script tags\n var isBrowser =\n typeof window !== 'undefined' && typeof window.document !== 'undefined';\n if (isBrowser) {\n document.dispatchEvent(\n new CustomEvent('FilePond:pluginloaded', { detail: plugin })\n );\n }\n\n return plugin;\n});\n","id":"ff0b1f99-c6ea-4a4d-aedc-2dedc0911686","is_binary":false,"title":"filepond-plugin-image-preview.js","sha":null,"inserted_at":"2021-07-05T16:41:09","updated_at":"2021-07-05T16:41:09","upload_id":null,"shortid":"HyTmUnxTu","source_id":"50161fbc-cae5-478e-b223-783e0c89506e","directory_shortid":null},{"code":"\u002F*!\n * FilePondPluginImagePreview 4.6.6\n * Licensed under MIT, https:\u002F\u002Fopensource.org\u002Flicenses\u002FMIT\u002F\n * Please visit https:\u002F\u002Fpqina.nl\u002Ffilepond\u002F for details.\n *\u002F\n\n\u002F* eslint-disable *\u002F\n.filepond--image-preview-markup {\n position: absolute;\n left: 0;\n top: 0;\n}\n.filepond--image-preview-wrapper {\n z-index: 2;\n}\n.filepond--image-preview-overlay {\n display: block;\n position: absolute;\n left: 0;\n top: 0;\n width: 100%;\n min-height: 5rem;\n max-height: 7rem;\n margin: 0;\n opacity: 0;\n z-index: 2;\n pointer-events: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n.filepond--image-preview-overlay svg {\n width: 100%;\n height: auto;\n color: inherit;\n max-height: inherit;\n}\n.filepond--image-preview-overlay-idle {\n mix-blend-mode: multiply;\n color: rgba(40, 40, 40, 0.85);\n}\n.filepond--image-preview-overlay-success {\n mix-blend-mode: normal;\n color: rgba(54, 151, 99, 1);\n}\n.filepond--image-preview-overlay-failure {\n mix-blend-mode: normal;\n color: rgba(196, 78, 71, 1);\n}\n\u002F* disable for Safari as mix-blend-mode causes the overflow:hidden of the parent container to not work *\u002F\n@supports (-webkit-marquee-repetition: infinite) and\n ((-o-object-fit: fill) or (object-fit: fill)) {\n .filepond--image-preview-overlay-idle {\n mix-blend-mode: normal;\n }\n}\n.filepond--image-preview-wrapper {\n \u002F* no interaction *\u002F\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n\n \u002F* have preview fill up all available space *\u002F\n position: absolute;\n left: 0;\n top: 0;\n right: 0;\n height: 100%;\n margin: 0;\n\n \u002F* radius is .05em less to prevent the panel background color from shining through *\u002F\n border-radius: 0.45em;\n overflow: hidden;\n\n \u002F* this seems to prevent Chrome from redrawing this layer constantly *\u002F\n background: rgba(0, 0, 0, 0.01);\n}\n.filepond--image-preview {\n position: absolute;\n left: 0;\n top: 0;\n z-index: 1;\n display: flex; \u002F* this aligns the graphic vertically if the panel is higher than the image *\u002F\n align-items: center;\n height: 100%;\n width: 100%;\n pointer-events: none;\n background: #222;\n\n \u002F* will be animated *\u002F\n will-change: transform, opacity;\n}\n.filepond--image-clip {\n position: relative;\n overflow: hidden;\n margin: 0 auto;\n\n \u002F* transparency indicator (currently only supports grid or basic color) *\u002F\n}\n.filepond--image-clip[data-transparency-indicator='grid'] img,\n.filepond--image-clip[data-transparency-indicator='grid'] canvas {\n background-color: #fff;\n background-image: url(\"data:image\u002Fsvg+xml,%3Csvg viewBox='0 0 100 100' xmlns='http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg' fill='%23eee'%3E%3Cpath d='M0 0 H50 V50 H0'\u002F%3E%3Cpath d='M50 50 H100 V100 H50'\u002F%3E%3C\u002Fsvg%3E\");\n background-size: 1.25em 1.25em;\n}\n.filepond--image-bitmap,\n.filepond--image-vector {\n position: absolute;\n left: 0;\n top: 0;\n will-change: transform;\n}\n.filepond--root[data-style-panel-layout~='integrated']\n .filepond--image-preview-wrapper {\n border-radius: 0;\n}\n.filepond--root[data-style-panel-layout~='integrated']\n .filepond--image-preview {\n height: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n}\n.filepond--root[data-style-panel-layout~='circle']\n .filepond--image-preview-wrapper {\n border-radius: 99999rem;\n}\n.filepond--root[data-style-panel-layout~='circle']\n .filepond--image-preview-overlay {\n top: auto;\n bottom: 0;\n -webkit-transform: scaleY(-1);\n transform: scaleY(-1);\n}\n.filepond--root[data-style-panel-layout~='circle']\n .filepond--file\n .filepond--file-action-button[data-align*='bottom']:not([data-align*='center']) {\n margin-bottom: 0.325em;\n}\n.filepond--root[data-style-panel-layout~='circle']\n .filepond--file\n [data-align*='left'] {\n left: calc(50% - 3em);\n}\n.filepond--root[data-style-panel-layout~='circle']\n .filepond--file\n [data-align*='right'] {\n right: calc(50% - 3em);\n}\n.filepond--root[data-style-panel-layout~='circle']\n .filepond--progress-indicator[data-align*='bottom'][data-align*='left'],\n.filepond--root[data-style-panel-layout~='circle']\n .filepond--progress-indicator[data-align*='bottom'][data-align*='right'] {\n margin-bottom: calc(0.325em + 0.1875em);\n}\n.filepond--root[data-style-panel-layout~='circle']\n .filepond--progress-indicator[data-align*='bottom'][data-align*='center'] {\n margin-top: 0;\n margin-bottom: 0.1875em;\n margin-left: 0.1875em;\n}\n","id":"552d1408-91a6-4f89-8ba5-6d31f0d8bddd","is_binary":false,"title":"filepond-plugin-image-preview.css","sha":null,"inserted_at":"2021-07-05T16:41:09","updated_at":"2021-07-05T16:41:09","upload_id":null,"shortid":"B1gp7Uhlp_","source_id":"50161fbc-cae5-478e-b223-783e0c89506e","directory_shortid":null}],"id":"xkr0e","forked_from_sandbox":null,"owned":false,"user_liked":false,"privacy":0,"preview_secret":null,"restrictions":{"free_plan_editing_restricted":false,"live_sessions_restricted":true},"entry":"index.html","team":{"id":"c4f564ae-a296-4f83-92eb-533446d74ce4","name":"xknght","settings":{"ai_consent":{"public_sandboxes":false,"private_sandboxes":false}},"subscription_type":null,"avatar_url":"https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F78901197?v=4"},"settings":{"ai_consent":null},"authorization":"read","room_id":null,"permissions":{"prevent_sandbox_export":false,"prevent_sandbox_leaving":false},"author":{"id":"e88ef300-f2cf-4b0e-b77f-c7418d234e18","name":"foo","username":"xknght","avatar_url":"https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F78901197?v=4","personal_workspace_id":"c4f564ae-a296-4f83-92eb-533446d74ce4","subscription_plan":null,"subscription_since":null},"picks":[],"screenshot_url":"https:\u002F\u002Fscreenshots.codesandbox.io\u002Fxkr0e\u002F30.png"};