UNPKG

html-dir-content

Version:

(recursively) iterate directory entries in the browser (html5 File System API)

191 lines (161 loc) 21.8 kB
/* html-dir-content v0.3.2 (c) 2020, Yoav Niran, https://github.com/yoavniran/html-dir-content.git/blob/master/LICENSE */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = global || self, factory(global.htmlDirContent = {})); }(this, (function (exports) { 'use strict'; function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } var OPTS_SYM = "opts_init", //not using Symbol to avoid polyfill BAIL_LEVEL = 1000, arrayConcat = Array.prototype.concat; var initOptions = function initOptions(options) { var _ref; return options[OPTS_SYM] === true ? options : (_ref = {}, _defineProperty(_ref, OPTS_SYM, true), _defineProperty(_ref, "recursive", options === true || !!options.recursive), _defineProperty(_ref, "withFullPath", !!options.withFullPath), _defineProperty(_ref, "bail", options.bail && options.bail > 0 ? options.bail : BAIL_LEVEL), _ref); }; var getFileWithFullPath = function getFileWithFullPath(file, fullPath) { var newFile = new File([file], fullPath, { type: file.type, lastModified: file.lastModified }); //we add "hdcFullPath" prop because firefox converts the path "/" delimiter into ":" newFile.hdcFullPath = fullPath; return newFile; }; var getFile = function getFile(file, fullPath) { var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; return options.withFullPath ? getFileWithFullPath(file, fullPath) : file; }; var getFileFromFileEntry = function getFileFromFileEntry(entry, options) { return new Promise(function (resolve, reject) { if (entry.file) { entry.file(function (file) { return resolve(getFile(file, entry.fullPath, options)); }, reject); } else { resolve(null); } })["catch"](function () { //swallow errors return null; }); }; var isItemFileEntry = function isItemFileEntry(item) { return item.kind === "file"; }; var getAsEntry = function getAsEntry(item) { return item.getAsEntry ? item.getAsEntry() : item.webkitGetAsEntry ? item.webkitGetAsEntry() : null; }; var getListAsArray = function getListAsArray(list) { return (//returns a flat array arrayConcat.apply([], list) ); }; var getEntryData = function getEntryData(entry, options, level) { var promise; if (entry.isDirectory) { promise = options.recursive ? getFileList(entry, options, level + 1) : Promise.resolve([]); } else { promise = getFileFromFileEntry(entry, options).then(function (file) { return file ? [file] : []; }); } return promise; }; /** * returns a flat list of files for root dir item * if recursive is true will get all files from sub folders */ var getFileList = function getFileList(root, options) { var level = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; return root && level < options.bail && root.isDirectory && root.createReader ? new Promise(function (resolve) { var allEntries = []; var reader = root.createReader(); var createResults = function createResults() { Promise.all(allEntries.map(function (entry) { return getEntryData(entry, options, level); })).then(function (results) { return resolve(getListAsArray(results)); }); //flatten the results }; var readEntries = function readEntries() { reader.readEntries(function (entries) { if (entries.length) { allEntries = allEntries.concat(entries); readEntries(); } else { createResults(); } }, createResults); //fail silently }; readEntries(); }) : Promise.resolve([]); }; /** * returns a Promise<Array<File>> of File objects for the provided item if it represents a directory * will attempt to retrieve all of its children files (optionally recursively) * @param item: DataTransferItem * @param options (optional) * {options.recursive} (default: false) - whether to recursively follow the dir structure * {options.withFullPath} (default: false) - whether to include the full path in the file entry * {options.bail} (default: 1000) - how many levels to follow recursively before bailing */ var getFiles = function getFiles(item) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; return getFileList(getAsEntry(item), initOptions(options)); }; var getDataTransferItemFiles = function getDataTransferItemFiles(item, options) { return getFiles(item, options).then(function (files) { if (!files.length) { //perhaps its a regular file var file = item.getAsFile(); files = file ? [file] : files; } return files; }); }; /** * returns a Promise<Array<File>> for the File objects found in the dataTransfer data of a drag&drop event * In case a directory is found, will attempt to retrieve all of its children files (optionally recursively) * * @param evt: DragEvent - containing dataTransfer * @param options (optional) * {options.recursive} (default: false) - whether to recursively follow the dir structure * {options.withFullPath} (default: false) - whether to include the full path in the file entry * {options.bail} (default: 1000) - how many levels to follow recursively before bailing */ var getFilesFromDragEvent = function getFilesFromDragEvent(evt) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; options = initOptions(options); return new Promise(function (resolve) { if (evt.dataTransfer.items) { Promise.all(getListAsArray(evt.dataTransfer.items).filter(function (item) { return isItemFileEntry(item); }).map(function (item) { return getDataTransferItemFiles(item, options); })).then(function (files) { return resolve(getListAsArray(files)); }); } else if (evt.dataTransfer.files) { resolve(getListAsArray(evt.dataTransfer.files)); //turn into regular array (instead of FileList) } else { resolve([]); } }); }; exports.getFiles = getFiles; exports.getFilesFromDragEvent = getFilesFromDragEvent; Object.defineProperty(exports, '__esModule', { value: true }); }))); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHRtbC1kaXItY29udGVudC5qcyIsInNvdXJjZXMiOlsiLi4vbGliL3V0aWxzLmpzIiwiLi4vbGliL2ZpbGVMaXN0LmpzIiwiLi4vbGliL2luZGV4LmpzIl0sInNvdXJjZXNDb250ZW50IjpbImNvbnN0IE9QVFNfU1lNID0gXCJvcHRzX2luaXRcIiwgLy9ub3QgdXNpbmcgU3ltYm9sIHRvIGF2b2lkIHBvbHlmaWxsXG4gICAgQkFJTF9MRVZFTCA9IDEwMDAsXG4gICAgYXJyYXlDb25jYXQgPSBBcnJheS5wcm90b3R5cGUuY29uY2F0O1xuXG5jb25zdCBpbml0T3B0aW9ucyA9IChvcHRpb25zKSA9PiBvcHRpb25zW09QVFNfU1lNXSA9PT0gdHJ1ZSA/XG4gICAgb3B0aW9ucyA6IHtcbiAgICAgICAgW09QVFNfU1lNXTogdHJ1ZSxcbiAgICAgICAgcmVjdXJzaXZlOiBvcHRpb25zID09PSB0cnVlIHx8ICEhb3B0aW9ucy5yZWN1cnNpdmUsXG4gICAgICAgIHdpdGhGdWxsUGF0aDogISFvcHRpb25zLndpdGhGdWxsUGF0aCxcbiAgICAgICAgYmFpbDogKG9wdGlvbnMuYmFpbCAmJiBvcHRpb25zLmJhaWwgPiAwKSA/IG9wdGlvbnMuYmFpbCA6IEJBSUxfTEVWRUxcbiAgICB9O1xuXG5jb25zdCBnZXRGaWxlV2l0aEZ1bGxQYXRoID0gKGZpbGUsIGZ1bGxQYXRoKSA9PiB7XG4gICAgY29uc3QgbmV3RmlsZSA9IG5ldyBGaWxlKFtmaWxlXSwgZnVsbFBhdGgseyB0eXBlOiBmaWxlLnR5cGUsIGxhc3RNb2RpZmllZDogZmlsZS5sYXN0TW9kaWZpZWQgfSk7XG4gICAgLy93ZSBhZGQgXCJoZGNGdWxsUGF0aFwiIHByb3AgYmVjYXVzZSBmaXJlZm94IGNvbnZlcnRzIHRoZSBwYXRoIFwiL1wiIGRlbGltaXRlciBpbnRvIFwiOlwiXG4gICAgbmV3RmlsZS5oZGNGdWxsUGF0aCA9IGZ1bGxQYXRoO1xuICAgIHJldHVybiBuZXdGaWxlO1xufTtcblxuY29uc3QgZ2V0RmlsZSA9IChmaWxlLCBmdWxsUGF0aCwgb3B0aW9ucyA9IHt9KSA9PlxuICAgIG9wdGlvbnMud2l0aEZ1bGxQYXRoID9cbiAgICAgICAgZ2V0RmlsZVdpdGhGdWxsUGF0aChmaWxlLCBmdWxsUGF0aCwgb3B0aW9ucykgOlxuICAgICAgICBmaWxlO1xuXG5jb25zdCBnZXRGaWxlRnJvbUZpbGVFbnRyeSA9IChlbnRyeSwgb3B0aW9ucykgPT5cbiAgICBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIGlmIChlbnRyeS5maWxlKSB7XG4gICAgICAgICAgICBlbnRyeS5maWxlKChmaWxlKSA9PlxuICAgICAgICAgICAgICAgIHJlc29sdmUoZ2V0RmlsZShmaWxlLCBlbnRyeS5mdWxsUGF0aCwgb3B0aW9ucykpLCByZWplY3QpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmVzb2x2ZShudWxsKTtcbiAgICAgICAgfVxuICAgIH0pXG4gICAgICAgIC5jYXRjaCgoKSA9PiB7IC8vc3dhbGxvdyBlcnJvcnNcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9KTtcblxuY29uc3QgaXNJdGVtRmlsZUVudHJ5ID0gKGl0ZW0pID0+IChpdGVtLmtpbmQgPT09IFwiZmlsZVwiKTtcblxuY29uc3QgZ2V0QXNFbnRyeSA9IChpdGVtKSA9PiBpdGVtLmdldEFzRW50cnkgP1xuICAgIGl0ZW0uZ2V0QXNFbnRyeSgpIDpcbiAgICBpdGVtLndlYmtpdEdldEFzRW50cnkgP1xuICAgICAgICBpdGVtLndlYmtpdEdldEFzRW50cnkoKSA6XG4gICAgICAgIG51bGw7XG5cbmNvbnN0IGdldExpc3RBc0FycmF5ID0gKGxpc3QpID0+IC8vcmV0dXJucyBhIGZsYXQgYXJyYXlcbiAgICBhcnJheUNvbmNhdC5hcHBseShbXSwgbGlzdCk7XG5cbmV4cG9ydCB7XG4gICAgaW5pdE9wdGlvbnMsXG4gICAgZ2V0RmlsZUZyb21GaWxlRW50cnksXG4gICAgaXNJdGVtRmlsZUVudHJ5LFxuICAgIGdldEFzRW50cnksXG4gICAgZ2V0TGlzdEFzQXJyYXksXG59O1xuIiwiaW1wb3J0IHsgZ2V0RmlsZUZyb21GaWxlRW50cnksIGdldExpc3RBc0FycmF5IH0gZnJvbSBcIi4vdXRpbHNcIjtcblxuY29uc3QgZ2V0RW50cnlEYXRhID0gKGVudHJ5LCBvcHRpb25zLCBsZXZlbCkgPT4ge1xuICAgIGxldCBwcm9taXNlO1xuXG4gICAgaWYgKGVudHJ5LmlzRGlyZWN0b3J5KSB7XG4gICAgICAgIHByb21pc2UgPSBvcHRpb25zLnJlY3Vyc2l2ZSA/XG4gICAgICAgICAgICBnZXRGaWxlTGlzdChlbnRyeSwgb3B0aW9ucywgKGxldmVsICsgMSkpIDpcbiAgICAgICAgICAgIFByb21pc2UucmVzb2x2ZShbXSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcHJvbWlzZSA9IGdldEZpbGVGcm9tRmlsZUVudHJ5KGVudHJ5LCBvcHRpb25zKVxuICAgICAgICAgICAgLnRoZW4oKGZpbGUpID0+IChmaWxlID8gW2ZpbGVdIDogW10pKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcHJvbWlzZTtcbn07XG5cbi8qKlxuICogcmV0dXJucyBhIGZsYXQgbGlzdCBvZiBmaWxlcyBmb3Igcm9vdCBkaXIgaXRlbVxuICogaWYgcmVjdXJzaXZlIGlzIHRydWUgd2lsbCBnZXQgYWxsIGZpbGVzIGZyb20gc3ViIGZvbGRlcnNcbiAqL1xuY29uc3QgZ2V0RmlsZUxpc3QgPSAocm9vdCwgb3B0aW9ucywgbGV2ZWwgPSAwKSA9PlxuICAgIChyb290ICYmIGxldmVsIDwgb3B0aW9ucy5iYWlsICYmIHJvb3QuaXNEaXJlY3RvcnkgJiYgcm9vdC5jcmVhdGVSZWFkZXIpID9cbiAgICAgICAgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgICAgIGxldCBhbGxFbnRyaWVzID0gW107XG4gICAgICAgICAgICBjb25zdCByZWFkZXIgPSByb290LmNyZWF0ZVJlYWRlcigpO1xuXG4gICAgICAgICAgICBjb25zdCBjcmVhdGVSZXN1bHRzID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIFByb21pc2UuYWxsKGFsbEVudHJpZXMubWFwKChlbnRyeSkgPT5cbiAgICAgICAgICAgICAgICAgICAgZ2V0RW50cnlEYXRhKGVudHJ5LCBvcHRpb25zLCBsZXZlbCkpKVxuICAgICAgICAgICAgICAgICAgICAudGhlbigocmVzdWx0cykgPT5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoZ2V0TGlzdEFzQXJyYXkocmVzdWx0cykpKSAvL2ZsYXR0ZW4gdGhlIHJlc3VsdHNcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHJlYWRFbnRyaWVzID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJlYWRlci5yZWFkRW50cmllcyhcbiAgICAgICAgICAgICAgICAgICAgKGVudHJpZXMpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbnRyaWVzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsbEVudHJpZXMgPSBhbGxFbnRyaWVzLmNvbmNhdChlbnRyaWVzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFkRW50cmllcygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVSZXN1bHRzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGNyZWF0ZVJlc3VsdHMpOyAvL2ZhaWwgc2lsZW50bHlcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHJlYWRFbnRyaWVzKCk7XG4gICAgICAgIH0pIDpcbiAgICAgICAgUHJvbWlzZS5yZXNvbHZlKFtdKTtcblxuZXhwb3J0IHtcbiAgICBnZXRGaWxlTGlzdFxufTtcbiIsImltcG9ydCB7IGdldEZpbGVMaXN0IH0gZnJvbSBcIi4vZmlsZUxpc3RcIjtcbmltcG9ydCB7XG4gICAgaXNJdGVtRmlsZUVudHJ5LFxuICAgIGdldExpc3RBc0FycmF5LFxuICAgIGdldEFzRW50cnksXG4gICAgaW5pdE9wdGlvbnMsXG59IGZyb20gXCIuL3V0aWxzXCI7XG5cbi8qKlxuICogcmV0dXJucyBhIFByb21pc2U8QXJyYXk8RmlsZT4+IG9mIEZpbGUgb2JqZWN0cyBmb3IgdGhlIHByb3ZpZGVkIGl0ZW0gaWYgaXQgcmVwcmVzZW50cyBhIGRpcmVjdG9yeVxuICogd2lsbCBhdHRlbXB0IHRvIHJldHJpZXZlIGFsbCBvZiBpdHMgY2hpbGRyZW4gZmlsZXMgKG9wdGlvbmFsbHkgcmVjdXJzaXZlbHkpXG4gKiBAcGFyYW0gaXRlbTogRGF0YVRyYW5zZmVySXRlbVxuICogQHBhcmFtIG9wdGlvbnMgKG9wdGlvbmFsKVxuICogIHtvcHRpb25zLnJlY3Vyc2l2ZX0gKGRlZmF1bHQ6IGZhbHNlKSAtIHdoZXRoZXIgdG8gcmVjdXJzaXZlbHkgZm9sbG93IHRoZSBkaXIgc3RydWN0dXJlXG4gKiAge29wdGlvbnMud2l0aEZ1bGxQYXRofSAoZGVmYXVsdDogZmFsc2UpIC0gd2hldGhlciB0byBpbmNsdWRlIHRoZSBmdWxsIHBhdGggaW4gdGhlIGZpbGUgZW50cnlcbiAqICB7b3B0aW9ucy5iYWlsfSAoZGVmYXVsdDogMTAwMCkgLSBob3cgbWFueSBsZXZlbHMgdG8gZm9sbG93IHJlY3Vyc2l2ZWx5IGJlZm9yZSBiYWlsaW5nXG4gKi9cbmNvbnN0IGdldEZpbGVzID0gKGl0ZW0sIG9wdGlvbnMgPSB7fSkgPT5cbiAgICBnZXRGaWxlTGlzdChnZXRBc0VudHJ5KGl0ZW0pLCBpbml0T3B0aW9ucyhvcHRpb25zKSk7XG5cbmNvbnN0IGdldERhdGFUcmFuc2Zlckl0ZW1GaWxlcyA9IChpdGVtLCBvcHRpb25zKSA9PlxuICAgIGdldEZpbGVzKGl0ZW0sIG9wdGlvbnMpXG4gICAgICAgIC50aGVuKChmaWxlcykgPT4ge1xuICAgICAgICAgICAgaWYgKCFmaWxlcy5sZW5ndGgpIHsgLy9wZXJoYXBzIGl0cyBhIHJlZ3VsYXIgZmlsZVxuICAgICAgICAgICAgICAgIGNvbnN0IGZpbGUgPSBpdGVtLmdldEFzRmlsZSgpO1xuICAgICAgICAgICAgICAgIGZpbGVzID0gZmlsZSA/IFtmaWxlXSA6IGZpbGVzO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gZmlsZXM7XG4gICAgICAgIH0pO1xuXG4vKipcbiAqIHJldHVybnMgYSBQcm9taXNlPEFycmF5PEZpbGU+PiBmb3IgdGhlIEZpbGUgb2JqZWN0cyBmb3VuZCBpbiB0aGUgZGF0YVRyYW5zZmVyIGRhdGEgb2YgYSBkcmFnJmRyb3AgZXZlbnRcbiAqIEluIGNhc2UgYSBkaXJlY3RvcnkgaXMgZm91bmQsIHdpbGwgYXR0ZW1wdCB0byByZXRyaWV2ZSBhbGwgb2YgaXRzIGNoaWxkcmVuIGZpbGVzIChvcHRpb25hbGx5IHJlY3Vyc2l2ZWx5KVxuICpcbiAqIEBwYXJhbSBldnQ6IERyYWdFdmVudCAtIGNvbnRhaW5pbmcgZGF0YVRyYW5zZmVyXG4gKiBAcGFyYW0gb3B0aW9ucyAob3B0aW9uYWwpXG4gKiAge29wdGlvbnMucmVjdXJzaXZlfSAoZGVmYXVsdDogZmFsc2UpIC0gd2hldGhlciB0byByZWN1cnNpdmVseSBmb2xsb3cgdGhlIGRpciBzdHJ1Y3R1cmVcbiAqICB7b3B0aW9ucy53aXRoRnVsbFBhdGh9IChkZWZhdWx0OiBmYWxzZSkgLSB3aGV0aGVyIHRvIGluY2x1ZGUgdGhlIGZ1bGwgcGF0aCBpbiB0aGUgZmlsZSBlbnRyeVxuICogIHtvcHRpb25zLmJhaWx9IChkZWZhdWx0OiAxMDAwKSAtIGhvdyBtYW55IGxldmVscyB0byBmb2xsb3cgcmVjdXJzaXZlbHkgYmVmb3JlIGJhaWxpbmdcbiAqL1xuY29uc3QgZ2V0RmlsZXNGcm9tRHJhZ0V2ZW50ID0gKGV2dCwgb3B0aW9ucyA9IHt9KSA9PiB7XG4gICAgb3B0aW9ucyA9IGluaXRPcHRpb25zKG9wdGlvbnMpO1xuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgIGlmIChldnQuZGF0YVRyYW5zZmVyLml0ZW1zKSB7XG4gICAgICAgICAgICBQcm9taXNlLmFsbChcbiAgICAgICAgICAgICAgICBnZXRMaXN0QXNBcnJheShldnQuZGF0YVRyYW5zZmVyLml0ZW1zKVxuICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKChpdGVtKSA9PiBpc0l0ZW1GaWxlRW50cnkoaXRlbSkpXG4gICAgICAgICAgICAgICAgICAgIC5tYXAoKGl0ZW0pID0+IGdldERhdGFUcmFuc2Zlckl0ZW1GaWxlcyhpdGVtLCBvcHRpb25zKSlcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAudGhlbigoZmlsZXMpID0+IHJlc29sdmUoZ2V0TGlzdEFzQXJyYXkoZmlsZXMpKSk7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZ0LmRhdGFUcmFuc2Zlci5maWxlcykge1xuICAgICAgICAgICAgcmVzb2x2ZShnZXRMaXN0QXNBcnJheShldnQuZGF0YVRyYW5zZmVyLmZpbGVzKSk7IC8vdHVybiBpbnRvIHJlZ3VsYXIgYXJyYXkgKGluc3RlYWQgb2YgRmlsZUxpc3QpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXNvbHZlKFtdKTtcbiAgICAgICAgfVxuICAgIH0pO1xufTtcblxuZXhwb3J0IHtcbiAgICBnZXRGaWxlcyxcbiAgICBnZXRGaWxlc0Zyb21EcmFnRXZlbnRcbn07XG4iXSwibmFtZXMiOlsiT1BUU19TWU0iLCJCQUlMX0xFVkVMIiwiYXJyYXlDb25jYXQiLCJBcnJheSIsInByb3RvdHlwZSIsImNvbmNhdCIsImluaXRPcHRpb25zIiwib3B0aW9ucyIsInJlY3Vyc2l2ZSIsIndpdGhGdWxsUGF0aCIsImJhaWwiLCJnZXRGaWxlV2l0aEZ1bGxQYXRoIiwiZmlsZSIsImZ1bGxQYXRoIiwibmV3RmlsZSIsIkZpbGUiLCJ0eXBlIiwibGFzdE1vZGlmaWVkIiwiaGRjRnVsbFBhdGgiLCJnZXRGaWxlIiwiZ2V0RmlsZUZyb21GaWxlRW50cnkiLCJlbnRyeSIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwiaXNJdGVtRmlsZUVudHJ5IiwiaXRlbSIsImtpbmQiLCJnZXRBc0VudHJ5Iiwid2Via2l0R2V0QXNFbnRyeSIsImdldExpc3RBc0FycmF5IiwibGlzdCIsImFwcGx5IiwiZ2V0RW50cnlEYXRhIiwibGV2ZWwiLCJwcm9taXNlIiwiaXNEaXJlY3RvcnkiLCJnZXRGaWxlTGlzdCIsInRoZW4iLCJyb290IiwiY3JlYXRlUmVhZGVyIiwiYWxsRW50cmllcyIsInJlYWRlciIsImNyZWF0ZVJlc3VsdHMiLCJhbGwiLCJtYXAiLCJyZXN1bHRzIiwicmVhZEVudHJpZXMiLCJlbnRyaWVzIiwibGVuZ3RoIiwiZ2V0RmlsZXMiLCJnZXREYXRhVHJhbnNmZXJJdGVtRmlsZXMiLCJmaWxlcyIsImdldEFzRmlsZSIsImdldEZpbGVzRnJvbURyYWdFdmVudCIsImV2dCIsImRhdGFUcmFuc2ZlciIsIml0ZW1zIiwiZmlsdGVyIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0VBQUEsSUFBTUEsUUFBUSxHQUFHLFdBQWpCO0VBQUE7RUFDSUMsVUFBVSxHQUFHLElBRGpCO0VBQUEsSUFFSUMsV0FBVyxHQUFHQyxLQUFLLENBQUNDLFNBQU4sQ0FBZ0JDLE1BRmxDOztFQUlBLElBQU1DLFdBQVcsR0FBRyxTQUFkQSxXQUFjLENBQUNDLE9BQUQ7RUFBQTs7RUFBQSxTQUFhQSxPQUFPLENBQUNQLFFBQUQsQ0FBUCxLQUFzQixJQUF0QixHQUM3Qk8sT0FENkIscUNBRXhCUCxRQUZ3QixFQUViLElBRmEsc0NBR2RPLE9BQU8sS0FBSyxJQUFaLElBQW9CLENBQUMsQ0FBQ0EsT0FBTyxDQUFDQyxTQUhoQix5Q0FJWCxDQUFDLENBQUNELE9BQU8sQ0FBQ0UsWUFKQyxpQ0FLbEJGLE9BQU8sQ0FBQ0csSUFBUixJQUFnQkgsT0FBTyxDQUFDRyxJQUFSLEdBQWUsQ0FBaEMsR0FBcUNILE9BQU8sQ0FBQ0csSUFBN0MsR0FBb0RULFVBTGpDLFFBQWI7RUFB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