figma-page-clone
Version:
One-click tool to clone a page
904 lines (794 loc) • 88.9 kB
HTML
<body>
<div id="lds" class="lds-container">
<div class="lds-dual-ring"></div>
</div>
<div class="row">
<div class="column third">
<h4>Current Page: </h4>
</div>
<div class="column two-thirds">
<p id="selected-page-name">---</p>
</div>
</div>
<div id="frames" class="scrollable-container"></div>
<div class="row" id="checked-frame-warnings">
<p id="okay" class="okay show"> </p>
<p id="too-much" class="warning">If your frames are complex, consider cloning 5 frames each run.</p>
</div>
<div class="row">
<div class="column third">
<h4>Clone to: </h4>
</div>
<div class="column two-thirds">
<select id="pages-in-document"></select>
</div>
</div>
<div class="row">
<div class="column third">
<p> Name: </p>
</div>
<div class="column two-thirds">
<input type="text" id="clone-name" />
</div>
</div>
<div id="line-break" class="row">
<div class="column"> </div>
</div>
<div class="row">
<div class="column eighty">
<h4>Options</h4>
</div>
<div class="column twenty">
<h4>Apply?</h4>
</div>
</div>
<div id="detach-instances-checkbox" class="row">
<div class="column eighty-five">
<p>Detach instances </p>
</div>
<div class="column fifteen">
<div class="column" style="width: 15%;">
<label class="container">
<input id="detach-instances" type="checkbox" checked />
<span class="figma-checkbox"></span>
</label>
</div>
</div>
</div>
<div id="overwrite-checkbox" class="row">
<div class="column eighty-five">
<p>Overwrite existing frames </p>
</div>
<div class="column fifteen">
<div class="column" style="width: 15%;">
<label class="container">
<input id="overwrite" type="checkbox" disabled />
<span class="figma-checkbox"></span>
</label>
</div>
</div>
</div>
<div id="sanitize-checkbox" class="row">
<div class="column eighty-five">
<p>Remove hidden layers </p>
</div>
<div class="column fifteen">
<div class="column" style="width: 15%;">
<label class="container">
<input id="sanitize" type="checkbox" checked />
<span class="figma-checkbox"></span>
</label>
</div>
</div>
</div>
<div id="locked-checkbox" class="row">
<div class="column eighty-five">
<p>Lock all frames </p>
</div>
<div class="column fifteen">
<div class="column" style="width: 15%;">
<label class="container">
<input id="locked" type="checkbox" checked />
<span class="figma-checkbox"></span>
</label>
</div>
</div>
</div>
<div id="line-break" class="row">
<div class="column"> </div>
</div>
<div class="row">
<div class="column btn-standalone primary">
<button id="clone">Clone</button>
</div>
</div>
<script type="text/javascript">/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = "./src/ui.ts");
/******/ })
/************************************************************************/
/******/ ({
/***/ "../../node_modules/css-loader/dist/cjs.js!../styles.css":
/*!******************************************************************************************************!*\
!*** /Volumes/DATA/Documents/GitHub/figma-plugins/node_modules/css-loader/dist/cjs.js!../styles.css ***!
\******************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
// Imports
var ___CSS_LOADER_API_IMPORT___ = __webpack_require__(/*! ../node_modules/css-loader/dist/runtime/api.js */ "../../node_modules/css-loader/dist/runtime/api.js");
exports = ___CSS_LOADER_API_IMPORT___(false);
// Module
exports.push([module.i, "body {\n font: 12px sans-serif;\n margin: 10px 15px;\n text-align: center;\n}\n\np {\n margin: 0;\n padding: 5px 0;\n text-align: left;\n}\n\n.validator {\n color: #ef5533;\n display: none;\n}\n\n.validator.show {\n display: block;\n}\n\n.warning {\n color: #dd571c;\n display: none;\n}\n\n.warning.show {\n display: block;\n}\n\n.okay {\n color: #1b8a6b;\n display: none;\n}\n\n.okay.show {\n display: block;\n}\n\nh4 {\n margin: 0;\n padding: 5px 0;\n text-align: left;\n}\n\n/* --- Buttons --- */\n.btn-standalone button {\n cursor: pointer;\n border-radius: 5px;\n background: white;\n color: black;\n border: none;\n margin: 5px 0;\n box-shadow: inset 0 0 0 1px black;\n outline: none;\n}\n\n.btn-standalone.primary button {\n background: #18a0fb;\n color: white;\n box-shadow: inset 0 0 0 1px white;\n}\n\n.btn-standalone button:focus {\n box-shadow: 0 0 0 2px #b9e2fe;\n}\n\n.btn-standalone button:disabled {\n background: #f8f8f8;\n color: #bebebe;\n box-shadow: inset 0 0 0 1px #bebebe;\n}\n\n/* --- Select --- */\nselect {\n width: 95%;\n height: 25px;\n border: none;\n border-radius: 3px;\n outline: none;\n padding: 5px;\n text-align: left;\n font-size: 12px;\n float: left;\n}\n\nselect:hover {\n box-shadow: inset 0 0 0 2px #b9e2fe;\n}\n\nselect:focus {\n border-radius: 3px;\n box-shadow: inset 0 0 0 2px #b9e2fe;\n}\n\nselect::selection {\n background: #c8c8c8;\n}\n\nselect:focus::selection {\n background: #b9e2fe;\n}\n\nselect:disabled {\n color: #bebebe;\n}\n\n/* --- Input --- */\ninput[type=\"text\"] {\n width: 95%;\n border: none;\n border-radius: 3px;\n outline: none;\n padding: 5px;\n text-align: left;\n font-size: 12px;\n float: left;\n}\n\ninput[type=\"checkbox\"] {\n width: 100%;\n border: none;\n border-radius: 3px;\n outline: none;\n padding: 5px;\n text-align: left;\n}\n\ninput[type=\"text\"]:hover {\n box-shadow: inset 0 0 0 2px #b9e2fe;\n}\n\ninput:focus {\n border-radius: 3px;\n box-shadow: inset 0 0 0 2px #b9e2fe;\n}\n\ninput::selection {\n background: #c8c8c8;\n}\n\ninput:focus::selection {\n background: #b9e2fe;\n}\n\ninput:disabled {\n color: #bebebe;\n}\n\n.invalid {\n box-shadow: inset 0 0 0 1px #ef5533;\n}\n\n/* --- Grid --- */\n.row {\n padding: 2px 3px;\n}\n\n.column {\n float: left;\n vertical-align: middle;\n width: 100%;\n}\n\n.column .zero-padding {\n padding: 0 !important;\n}\n\n.half {\n width: 50% !important;\n}\n\n.two-thirds {\n width: 66.7% !important;\n}\n\n.third {\n width: 33.3% !important;\n}\n\n.one-sixth {\n width: 16.7% !important;\n}\n\n.three-fourths {\n width: 75% !important;\n}\n\n.quarter {\n width: 25% !important;\n}\n\n.eighty {\n width: 80% !important;\n}\n\n.eighty-five {\n width: 85% !important;\n}\n\n.twenty {\n width: 20% !important;\n}\n\n.fifteen {\n width: 15% !important;\n}\n\n.label {\n width: 65% !important;\n}\n\n.input-column {\n width: 35% !important;\n}\n\n/* Clear floats after the columns */\n.row::after {\n content: \"\";\n display: table;\n clear: both;\n}\n\n/* --- Checkbox --- */\n\n/* The container */\n.container {\n padding: 3px 0;\n display: block;\n position: relative;\n cursor: pointer;\n width: 10px;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n.container input {\n vertical-align: middle;\n position: absolute;\n cursor: pointer;\n opacity: 0;\n}\n\n.container .figma-checkbox {\n position: absolute;\n top: 6px;\n left: 0;\n height: 10px;\n width: 10px;\n background-color: #fff;\n border-radius: 2px;\n border: 1px solid #000;\n}\n\n.container .figma-checkbox::after {\n position: absolute;\n content: \"\";\n left: 0;\n top: 6px;\n height: 0;\n width: 0;\n border-radius: 2px;\n border: solid #fff;\n border-width: 0 1px 1px 0;\n -webkit-transform: rotate(0deg) scale(0);\n -ms-transform: rotate(0deg) scale(0);\n transform: rotate(0deg) scale(0);\n opacity: 1;\n}\n\n.container input:hover ~ .figma-checkbox {\n border-radius: 2px;\n box-shadow: 0 0 0 2px #b9e2fe;\n}\n\n.container input:focus ~ .figma-checkbox {\n border-radius: 2px;\n box-shadow: 0 0 0 2px #b9e2fe;\n}\n\n.container input:disabled ~ .figma-checkbox {\n height: 10px;\n width: 10px;\n border-radius: 2px;\n background-color: #bebebe;\n border: 1px solid #bebebe;\n}\n\n.container input:checked ~ .figma-checkbox {\n background-color: #18a0fb;\n border-radius: 2px;\n -webkit-transform: rotate(0deg) scale(1);\n -ms-transform: rotate(0deg) scale(1);\n transform: rotate(0deg) scale(1);\n opacity: 1;\n border: 1px solid #18a0fb;\n}\n\n.container input:checked ~ .figma-checkbox::after {\n -webkit-transform: rotate(45deg) scale(1);\n -ms-transform: rotate(45deg) scale(1);\n transform: rotate(45deg) scale(1);\n opacity: 1;\n left: 2.5px;\n top: 0;\n width: 3px;\n height: 6px;\n border: solid #fff;\n border-width: 0 1px 1px 0;\n background-color: transparent;\n border-radius: 0;\n}\n\n.container input ~ .figma-checkbox.partial-checked {\n background-color: #18a0fb;\n border-radius: 2px;\n -webkit-transform: rotate(0deg) scale(1);\n -ms-transform: rotate(0deg) scale(1);\n transform: rotate(0deg) scale(1);\n opacity: 1;\n border: 1px solid #18a0fb;\n}\n\n.container input ~ .figma-checkbox.partial-checked::after {\n -webkit-transform: rotate(0deg) scale(1);\n -ms-transform: rotate(0deg) scale(1);\n transform: rotate(0deg) scale(1);\n opacity: 1;\n left: 2px;\n top: 4px;\n width: 4px;\n height: 0;\n border: solid #fff;\n border-width: 1px;\n background-color: transparent;\n border-radius: 0;\n}\n\n.toggle-display {\n display: none;\n}\n\n.toggle-display.is-visible {\n display: block;\n}\n\n/* --- Animated Loader --- */\n\n/* Based on loading.io */\n.lds-container {\n position: fixed;\n\n /* Sit on top of the page content */\n display: none;\n\n /* Hidden by default */\n width: 100%;\n\n /* Full width (cover the whole page) */\n height: 100%;\n\n /* Full height (cover the whole page) */\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.5);\n\n /* Black background with opacity */\n z-index: 100 !important;\n\n /* Specify a stack order in case you're using a different order for other elements */\n}\n\n.lds-container.is-visible {\n display: block;\n}\n\n.lds-dual-ring {\n display: inline-block;\n width: 80px;\n height: 80px;\n}\n\n.lds-dual-ring::after {\n content: \" \";\n display: block;\n width: 30px;\n height: 30px;\n margin: 21px;\n border-radius: 50%;\n border: 3px solid #fff;\n border-color: #fff transparent #fff transparent;\n animation: lds-dual-ring 1.2s linear infinite;\n}\n\n@keyframes lds-dual-ring {\n 0% {\n transform: rotate(0deg);\n }\n\n 100% {\n transform: rotate(360deg);\n }\n}\n", ""]);
// Exports
module.exports = exports;
/***/ }),
/***/ "../../node_modules/css-loader/dist/cjs.js!./src/ui.css":
/*!*****************************************************************************************************!*\
!*** /Volumes/DATA/Documents/GitHub/figma-plugins/node_modules/css-loader/dist/cjs.js!./src/ui.css ***!
\*****************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
// Imports
var ___CSS_LOADER_API_IMPORT___ = __webpack_require__(/*! ../../../node_modules/css-loader/dist/runtime/api.js */ "../../node_modules/css-loader/dist/runtime/api.js");
var ___CSS_LOADER_AT_RULE_IMPORT_0___ = __webpack_require__(/*! -!../../../node_modules/css-loader/dist/cjs.js!../../styles.css */ "../../node_modules/css-loader/dist/cjs.js!../styles.css");
exports = ___CSS_LOADER_API_IMPORT___(false);
exports.i(___CSS_LOADER_AT_RULE_IMPORT_0___);
// Module
exports.push([module.i, "/* Import helper style from package root */\r\n\r\n/* --- Buttons --- */\r\n.btn-standalone button {\r\n padding: 8px 130px;\r\n}\r\n\r\n/* --- Animated Loader --- */\r\n\r\n/* Based on loading.io */\r\n.lds-dual-ring {\r\n padding: 200px 0;\r\n}\r\n\r\n/* --- Container for Frames --- */\r\n.scrollable-container {\r\n height: 150px;\r\n overflow-y: auto;\r\n border: 1px solid #bebebe;\r\n border-radius: 3px;\r\n}\r\n\r\n.scrollable-container.empty {\r\n border: 1px solid #ef5533;\r\n}\r\n\r\n#okay,\r\n#too-much {\r\n font-size: 11px;\r\n}\r\n", ""]);
// Exports
module.exports = exports;
/***/ }),
/***/ "../../node_modules/css-loader/dist/runtime/api.js":
/*!************************************************************************************************!*\
!*** /Volumes/DATA/Documents/GitHub/figma-plugins/node_modules/css-loader/dist/runtime/api.js ***!
\************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
// css base code, injected by the css-loader
// eslint-disable-next-line func-names
module.exports = function (useSourceMap) {
var list = []; // return the list of modules as css string
list.toString = function toString() {
return this.map(function (item) {
var content = cssWithMappingToString(item, useSourceMap);
if (item[2]) {
return "@media ".concat(item[2], " {").concat(content, "}");
}
return content;
}).join('');
}; // import a list of modules into the list
// eslint-disable-next-line func-names
list.i = function (modules, mediaQuery, dedupe) {
if (typeof modules === 'string') {
// eslint-disable-next-line no-param-reassign
modules = [[null, modules, '']];
}
var alreadyImportedModules = {};
if (dedupe) {
for (var i = 0; i < this.length; i++) {
// eslint-disable-next-line prefer-destructuring
var id = this[i][0];
if (id != null) {
alreadyImportedModules[id] = true;
}
}
}
for (var _i = 0; _i < modules.length; _i++) {
var item = [].concat(modules[_i]);
if (dedupe && alreadyImportedModules[item[0]]) {
// eslint-disable-next-line no-continue
continue;
}
if (mediaQuery) {
if (!item[2]) {
item[2] = mediaQuery;
} else {
item[2] = "".concat(mediaQuery, " and ").concat(item[2]);
}
}
list.push(item);
}
};
return list;
};
function cssWithMappingToString(item, useSourceMap) {
var content = item[1] || ''; // eslint-disable-next-line prefer-destructuring
var cssMapping = item[3];
if (!cssMapping) {
return content;
}
if (useSourceMap && typeof btoa === 'function') {
var sourceMapping = toComment(cssMapping);
var sourceURLs = cssMapping.sources.map(function (source) {
return "/*# sourceURL=".concat(cssMapping.sourceRoot || '').concat(source, " */");
});
return [content].concat(sourceURLs).concat([sourceMapping]).join('\n');
}
return [content].join('\n');
} // Adapted from convert-source-map (MIT)
function toComment(sourceMap) {
// eslint-disable-next-line no-undef
var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))));
var data = "sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(base64);
return "/*# ".concat(data, " */");
}
/***/ }),
/***/ "../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js":
/*!***********************************************************************************************************************!*\
!*** /Volumes/DATA/Documents/GitHub/figma-plugins/node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js ***!
\***********************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var isOldIE = function isOldIE() {
var memo;
return function memorize() {
if (typeof memo === 'undefined') {
// Test for IE <= 9 as proposed by Browserhacks
// @see http://browserhacks.com/#hack-e71d8692f65334173fee715c222cb805
// Tests for existence of standard globals is to allow style-loader
// to operate correctly into non-standard environments
// @see https://github.com/webpack-contrib/style-loader/issues/177
memo = Boolean(window && document && document.all && !window.atob);
}
return memo;
};
}();
var getTarget = function getTarget() {
var memo = {};
return function memorize(target) {
if (typeof memo[target] === 'undefined') {
var styleTarget = document.querySelector(target); // Special case to return head of iframe instead of iframe itself
if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {
try {
// This will throw an exception if access to iframe is blocked
// due to cross-origin restrictions
styleTarget = styleTarget.contentDocument.head;
} catch (e) {
// istanbul ignore next
styleTarget = null;
}
}
memo[target] = styleTarget;
}
return memo[target];
};
}();
var stylesInDom = [];
function getIndexByIdentifier(identifier) {
var result = -1;
for (var i = 0; i < stylesInDom.length; i++) {
if (stylesInDom[i].identifier === identifier) {
result = i;
break;
}
}
return result;
}
function modulesToDom(list, options) {
var idCountMap = {};
var identifiers = [];
for (var i = 0; i < list.length; i++) {
var item = list[i];
var id = options.base ? item[0] + options.base : item[0];
var count = idCountMap[id] || 0;
var identifier = "".concat(id, " ").concat(count);
idCountMap[id] = count + 1;
var index = getIndexByIdentifier(identifier);
var obj = {
css: item[1],
media: item[2],
sourceMap: item[3]
};
if (index !== -1) {
stylesInDom[index].references++;
stylesInDom[index].updater(obj);
} else {
stylesInDom.push({
identifier: identifier,
updater: addStyle(obj, options),
references: 1
});
}
identifiers.push(identifier);
}
return identifiers;
}
function insertStyleElement(options) {
var style = document.createElement('style');
var attributes = options.attributes || {};
if (typeof attributes.nonce === 'undefined') {
var nonce = true ? __webpack_require__.nc : undefined;
if (nonce) {
attributes.nonce = nonce;
}
}
Object.keys(attributes).forEach(function (key) {
style.setAttribute(key, attributes[key]);
});
if (typeof options.insert === 'function') {
options.insert(style);
} else {
var target = getTarget(options.insert || 'head');
if (!target) {
throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");
}
target.appendChild(style);
}
return style;
}
function removeStyleElement(style) {
// istanbul ignore if
if (style.parentNode === null) {
return false;
}
style.parentNode.removeChild(style);
}
/* istanbul ignore next */
var replaceText = function replaceText() {
var textStore = [];
return function replace(index, replacement) {
textStore[index] = replacement;
return textStore.filter(Boolean).join('\n');
};
}();
function applyToSingletonTag(style, index, remove, obj) {
var css = remove ? '' : obj.media ? "@media ".concat(obj.media, " {").concat(obj.css, "}") : obj.css; // For old IE
/* istanbul ignore if */
if (style.styleSheet) {
style.styleSheet.cssText = replaceText(index, css);
} else {
var cssNode = document.createTextNode(css);
var childNodes = style.childNodes;
if (childNodes[index]) {
style.removeChild(childNodes[index]);
}
if (childNodes.length) {
style.insertBefore(cssNode, childNodes[index]);
} else {
style.appendChild(cssNode);
}
}
}
function applyToTag(style, options, obj) {
var css = obj.css;
var media = obj.media;
var sourceMap = obj.sourceMap;
if (media) {
style.setAttribute('media', media);
} else {
style.removeAttribute('media');
}
if (sourceMap && typeof btoa !== 'undefined') {
css += "\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), " */");
} // For old IE
/* istanbul ignore if */
if (style.styleSheet) {
style.styleSheet.cssText = css;
} else {
while (style.firstChild) {
style.removeChild(style.firstChild);
}
style.appendChild(document.createTextNode(css));
}
}
var singleton = null;
var singletonCounter = 0;
function addStyle(obj, options) {
var style;
var update;
var remove;
if (options.singleton) {
var styleIndex = singletonCounter++;
style = singleton || (singleton = insertStyleElement(options));
update = applyToSingletonTag.bind(null, style, styleIndex, false);
remove = applyToSingletonTag.bind(null, style, styleIndex, true);
} else {
style = insertStyleElement(options);
update = applyToTag.bind(null, style, options);
remove = function remove() {
removeStyleElement(style);
};
}
update(obj);
return function updateStyle(newObj) {
if (newObj) {
if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap) {
return;
}
update(obj = newObj);
} else {
remove();
}
};
}
module.exports = function (list, options) {
options = options || {}; // Force single-tag solution on IE6-9, which has a hard limit on the # of <style>
// tags it will allow on a page
if (!options.singleton && typeof options.singleton !== 'boolean') {
options.singleton = isOldIE();
}
list = list || [];
var lastIdentifiers = modulesToDom(list, options);
return function update(newList) {
newList = newList || [];
if (Object.prototype.toString.call(newList) !== '[object Array]') {
return;
}
for (var i = 0; i < lastIdentifiers.length; i++) {
var identifier = lastIdentifiers[i];
var index = getIndexByIdentifier(identifier);
stylesInDom[index].references--;
}
var newLastIdentifiers = modulesToDom(newList, options);
for (var _i = 0; _i < lastIdentifiers.length; _i++) {
var _identifier = lastIdentifiers[_i];
var _index = getIndexByIdentifier(_identifier);
if (stylesInDom[_index].references === 0) {
stylesInDom[_index].updater();
stylesInDom.splice(_index, 1);
}
}
lastIdentifiers = newLastIdentifiers;
};
};
/***/ }),
/***/ "./src/ui.css":
/*!********************!*\
!*** ./src/ui.css ***!
\********************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
var api = __webpack_require__(/*! ../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js */ "../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js");
var content = __webpack_require__(/*! !../../../node_modules/css-loader/dist/cjs.js!./ui.css */ "../../node_modules/css-loader/dist/cjs.js!./src/ui.css");
content = content.__esModule ? content.default : content;
if (typeof content === 'string') {
content = [[module.i, content, '']];
}
var options = {};
options.insert = "head";
options.singleton = false;
var update = api(content, options);
module.exports = content.locals || {};
/***/ }),
/***/ "./src/ui.ts":
/*!*******************!*\
!*** ./src/ui.ts ***!
\*******************/
/*! no exports provided */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _ui_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ui.css */ "./src/ui.css");
/* harmony import */ var _ui_css__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_ui_css__WEBPACK_IMPORTED_MODULE_0__);
let isShiftHeld = false;
let checkedFramesCount = 0;
let boundaryInputId = "";
let possibleFramesToClone = [];
onmessage = (msg) => {
document.getElementById("selected-page-name").innerHTML = msg.data.pluginMessage.name;
const destinationOptions = constructDestinationPageOptions(msg.data.pluginMessage.pages, msg.data.pluginMessage.id);
const availableFrames = constructAvailableFramesList(msg.data.pluginMessage.frames);
document.getElementById("pages-in-document").innerHTML = destinationOptions;
document.getElementById("frames").innerHTML = availableFrames;
checkedFramesCountValidationAndSelectAll();
// UI logic
const selectAllCheckbox = document.getElementById("select-all-checkbox");
selectAllCheckbox.onclick = () => {
// if checkbox is checked, uncheck all frames
if (!selectAllCheckbox.checked) {
possibleFramesToClone.forEach(frame => {
document.getElementById(frame).checked = false;
checkedFramesCount = 0;
checkedFramesCountValidationAndSelectAll();
});
}
else {
possibleFramesToClone.forEach(frame => {
document.getElementById(frame).checked = true;
checkedFramesCount = possibleFramesToClone.length;
checkedFramesCountValidationAndSelectAll();
});
}
};
possibleFramesToClone.forEach(frame => {
document.getElementById(frame).onchange = () => {
document.getElementById(frame).checked ? checkedFramesCount++ : checkedFramesCount--;
checkedFramesCountValidationAndSelectAll();
};
});
document.getElementById("clone-name").value = `Copy of ${msg.data.pluginMessage.name}`;
document.getElementById("clone-name").select();
};
window.onfocus = () => {
parent.postMessage({
pluginMessage: {
type: "focus",
frames: [],
destinationId: "",
name: "",
"detach-instances": false,
overwrite: false,
sanitize: false,
locked: false,
},
}, "*");
};
document.getElementById("pages-in-document").onchange = () => {
if (document.getElementById("pages-in-document").value === "") {
// enable new page name textbox
document.getElementById("clone-name").disabled = false;
// uncheck and disable overwrite
document.getElementById("overwrite").checked = false;
document.getElementById("overwrite").disabled = true;
// focus on new page name textbox
document.getElementById("clone-name").focus();
}
else {
// disable new page name textbox
document.getElementById("clone-name").disabled = true;
// enable overwrite
document.getElementById("overwrite").disabled = false;
document.getElementById("detach-instances").focus();
}
};
document.getElementById("clone").onclick = () => {
document.getElementById("frames").classList.remove("empty");
let framesToClone = [];
possibleFramesToClone.forEach(frame => {
document.getElementById(frame).checked ? framesToClone.push(frame) : null;
});
const destinationId = document.getElementById("pages-in-document").value;
const name = document.getElementById("clone-name").value;
if (framesToClone.length === 0) {
document.getElementById("frames").classList.add("empty");
}
else if (destinationId) {
document.getElementById("lds").classList.add("is-visible");
setTimeout(() => {
parent.postMessage({
pluginMessage: {
type: "cloned",
frames: framesToClone,
destination: destinationId,
name: "",
"detach-instances": document.getElementById("detach-instances").checked,
overwrite: document.getElementById("overwrite").checked,
sanitize: document.getElementById("sanitize").checked,
locked: document.getElementById("locked").checked,
},
}, "*");
}, 50);
}
else if (name.length > 0) {
document.getElementById("lds").classList.add("is-visible");
setTimeout(() => {
parent.postMessage({
pluginMessage: {
type: "cloned",
frames: framesToClone,
destination: "",
name: document.getElementById("clone-name").value,
"detach-instances": document.getElementById("detach-instances").checked,
overwrite: false,
sanitize: document.getElementById("sanitize").checked,
locked: document.getElementById("locked").checked,
},
}, "*");
}, 50);
}
else {
document.getElementById("clone-name").classList.add("invalid");
}
};
document.onkeydown = keyDown => {
if (keyDown.key) {
let activeElement = document.activeElement;
switch (keyDown.key) {
case "Shift":
isShiftHeld = true;
keyDown.preventDefault();
break;
case "Tab":
if (activeElement.id === "clone") {
if (!isShiftHeld) {
document.getElementById(boundaryInputId).focus();
keyDown.preventDefault();
}
}
else if (activeElement.id === boundaryInputId) {
if (isShiftHeld) {
document.getElementById("clone").focus();
keyDown.preventDefault();
}
}
break;
case "Enter":
if (activeElement.type === "checkbox") {
activeElement.checked = !activeElement.checked;
}
break;
default:
break;
}
}
};
document.onkeyup = keyUp => {
if (keyUp.key) {
switch (keyUp.key) {
case "Shift":
isShiftHeld = false;
keyUp.preventDefault();
break;
}
}
};
const checkedFramesCountValidationAndSelectAll = () => {
const selectAllCheckbox = document.getElementById("select-all-checkbox");
const selectAllCheckboxSpan = document.getElementById("select-all-checkbox-span");
if (possibleFramesToClone.length === checkedFramesCount) {
selectAllCheckbox.checked = true;
selectAllCheckboxSpan.classList.remove("partial-checked");
}
else {
selectAllCheckbox.checked = false;
if (checkedFramesCount !== 0) {
selectAllCheckboxSpan.classList.add("partial-checked");
}
else {
selectAllCheckboxSpan.classList.remove("partial-checked");
}
}
checkedFramesCount > 5
? (document.getElementById("too-much").classList.add("show"),
document.getElementById("okay").classList.remove("show"))
: (document.getElementById("too-much").classList.remove("show"),
document.getElementById("okay").classList.add("show"));
};
const constructDestinationPageOptions = (pages, currentPageId) => {
let options = `<option value="" selected>New Page</option>`;
pages.forEach((page) => {
page.id !== currentPageId ? (options += `<option value="${page.id}">${page.name}</option>`) : null;
});
return options;
};
const constructAvailableFramesList = (frames) => {
const preCheckedFramesAvailable = Boolean(frames.find(frame => frame.selected));
let availableFrames = "";
/* Reset UI variables */
boundaryInputId = "";
possibleFramesToClone.length = 0;
checkedFramesCount = 0;
frames.forEach((frame) => {
boundaryInputId === "" ? (boundaryInputId = `${frame.id}`) : null;
possibleFramesToClone.push(frame.id);
const checked = preCheckedFramesAvailable ? (frame.selected ? "checked" : "") : "checked";
checkedFramesCount = preCheckedFramesAvailable
? frame.selected
? (checkedFramesCount += 1)
: checkedFramesCount
: (checkedFramesCount += 1);
availableFrames += `
<div class="checkbox-container row">
<div class="column eighty-five">
<p>${frame.name} </p>
</div>
<div class="column fifteen">
<div class="column" style="width: 15%;">
<label class="container">
<input id="${frame.id}" type="checkbox" ${checked}/>
<span class="figma-checkbox"></span>
</label>
</div>
</div>
</div>
`;
});
const partialCheckedClass = checkedFramesCount !== 0 && possibleFramesToClone.length > checkedFramesCount ? "partial-checked" : "";
const checked = possibleFramesToClone.length === checkedFramesCount ? "checked" : "";
let availableFramesHeader = `
<div class="checkbox-container row">
<div class="column eighty-five">
<h4>Available Frames</h4>
</div>
<div class="column fifteen">
<div class="column" style="width: 15%;">
<label class="container">
<input id="select-all-checkbox" type="checkbox" ${checked}/>
<span id="select-all-checkbox-span" class="figma-checkbox ${partialCheckedClass}"></span>
</label>
</div>
</div>
</div>
`;
return availableFramesHeader + availableFrames;
};
/***/ })
/******/ });
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vLy4uL3N0eWxlcy5jc3MiLCJ3ZWJwYWNrOi8vLy4vc3JjL3VpLmNzcyIsIndlYnBhY2s6Ly8vL1ZvbHVtZXMvREFUQS9Eb2N1bWVudHMvR2l0SHViL2ZpZ21hLXBsdWdpbnMvbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9ydW50aW1lL2FwaS5qcyIsIndlYnBhY2s6Ly8vL1ZvbHVtZXMvREFUQS9Eb2N1bWVudHMvR2l0SHViL2ZpZ21hLXBsdWdpbnMvbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5qZWN0U3R5bGVzSW50b1N0eWxlVGFnLmpzIiwid2VicGFjazovLy8uL3NyYy91aS5jc3M/MmRjNyIsIndlYnBhY2s6Ly8vLi9zcmMvdWkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtRQUFBO1FBQ0E7O1FBRUE7UUFDQTs7UUFFQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTs7UUFFQTtRQUNBOztRQUVBO1FBQ0E7O1FBRUE7UUFDQTtRQUNBOzs7UUFHQTtRQUNBOztRQUVBO1FBQ0E7O1FBRUE7UUFDQTtRQUNBO1FBQ0EsMENBQTBDLGdDQUFnQztRQUMxRTtRQUNBOztRQUVBO1FBQ0E7UUFDQTtRQUNBLHdEQUF3RCxrQkFBa0I7UUFDMUU7UUFDQSxpREFBaUQsY0FBYztRQUMvRDs7UUFFQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0EseUNBQXlDLGlDQUFpQztRQUMxRSxnSEFBZ0gsbUJBQW1CLEVBQUU7UUFDckk7UUFDQTs7UUFFQTtRQUNBO1FBQ0E7UUFDQSwyQkFBMkIsMEJBQTBCLEVBQUU7UUFDdkQsaUNBQWlDLGVBQWU7UUFDaEQ7UUFDQTtRQUNBOztRQUVBO1FBQ0Esc0RBQXNELCtEQUErRDs7UUFFckg7UUFDQTs7O1FBR0E7UUFDQTs7Ozs7Ozs7Ozs7O0FDbEZBO0FBQ0Esa0NBQWtDLG1CQUFPLENBQUMseUdBQWdEO0FBQzFGO0FBQ0E7QUFDQSxjQUFjLFFBQVMsU0FBUywwQkFBMEIsc0JBQXNCLHVCQUF1QixHQUFHLE9BQU8sY0FBYyxtQkFBbUIscUJBQXFCLEdBQUcsZ0JBQWdCLG1CQUFtQixrQkFBa0IsR0FBRyxxQkFBcUIsbUJBQW1CLEdBQUcsY0FBYyxtQkFBbUIsa0JBQWtCLEdBQUcsbUJBQW1CLG1CQUFtQixHQUFHLFdBQVcsbUJBQW1CLGtCQUFrQixHQUFHLGdCQUFnQixtQkFBbUIsR0FBRyxRQUFRLGNBQWMsbUJBQW1CLHFCQUFxQixHQUFHLG1EQUFtRCxvQkFBb0IsdUJBQXVCLHNCQUFzQixpQkFBaUIsaUJBQWlCLGtCQUFrQixzQ0FBc0Msa0JBQWtCLEdBQUcsb0NBQW9DLHdCQUF3QixpQkFBaUIsc0NBQXNDLEdBQUcsa0NBQWtDLGtDQUFrQyxHQUFHLHFDQUFxQyx3QkFBd0IsbUJBQW1CLHdDQUF3QyxHQUFHLGtDQUFrQyxlQUFlLGlCQUFpQixpQkFBaUIsdUJBQXVCLGtCQUFrQixpQkFBaUIscUJBQXFCLG9CQUFvQixnQkFBZ0IsR0FBRyxrQkFBa0Isd0NBQXdDLEdBQUcsa0JBQWtCLHVCQUF1Qix3Q0FBd0MsR0FBRyx1QkFBdUIsd0JBQXdCLEdBQUcsNkJBQTZCLHdCQUF3QixHQUFHLHFCQUFxQixtQkFBbUIsR0FBRywrQ0FBK0MsZUFBZSxpQkFBaUIsdUJBQXVCLGtCQUFrQixpQkFBaUIscUJBQXFCLG9CQUFvQixnQkFBZ0IsR0FBRyw4QkFBOEIsZ0JBQWdCLGlCQUFpQix1QkFBdUIsa0JBQWtCLGlCQUFpQixxQkFBcUIsR0FBRyxnQ0FBZ0Msd0NBQXdDLEdBQUcsaUJBQWlCLHVCQUF1Qix3Q0FBd0MsR0FBRyxzQkFBc0Isd0JBQXdCLEdBQUcsNEJBQTRCLHdCQUF3QixHQUFHLG9CQUFvQixtQkFBbUIsR0FBRyxjQUFjLHdDQUF3QyxHQUFHLDhCQUE4QixxQkFBcUIsR0FBRyxhQUFhLGdCQUFnQiwyQkFBMkIsZ0JBQWdCLEdBQUcsMkJBQTJCLDBCQUEwQixHQUFHLFdBQVcsMEJBQTBCLEdBQUcsaUJBQWlCLDRCQUE0QixHQUFHLFlBQVksNEJBQTRCLEdBQUcsZ0JBQWdCLDRCQUE0QixHQUFHLG9CQUFvQiwwQkFBMEIsR0FBRyxjQUFjLDBCQUEwQixHQUFHLGFBQWEsMEJBQTBCLEdBQUcsa0JBQWtCLDBCQUEwQixHQUFHLGFBQWEsMEJBQTBCLEdBQUcsY0FBYywwQkFBMEIsR0FBRyxZQUFZLDBCQUEwQixHQUFHLG1CQUFtQiwwQkFBMEIsR0FBRyx1REFBdUQsa0JBQWtCLG1CQUFtQixnQkFBZ0IsR0FBRywrREFBK0QsbUJBQW1CLG1CQUFtQix1QkFBdUIsb0JBQW9CLGdCQUFnQiw4QkFBOEIsMkJBQTJCLDBCQUEwQixzQkFBc0IsR0FBRyxzQkFBc0IsMkJBQTJCLHVCQUF1QixvQkFBb0IsZUFBZSxHQUFHLGdDQUFnQyx1QkFBdUIsYUFBYSxZQUFZLGlCQUFpQixnQkFBZ0IsMkJBQTJCLHVCQUF1QiwyQkFBMkIsR0FBRyx1Q0FBdUMsdUJBQXVCLGtCQUFrQixZQUFZLGFBQWEsY0FBYyxhQUFhLHVCQUF1Qix1QkFBdUIsOEJBQThCLDZDQUE2Qyx5Q0FBeUMscUNBQXFDLGVBQWUsR0FBRyw4Q0FBOEMsdUJBQXVCLGtDQUFrQyxHQUFHLDhDQUE4Qyx1QkFBdUIsa0NBQWtDLEdBQUcsaURBQWlELGlCQUFpQixnQkFBZ0IsdUJBQXVCLDhCQUE4Qiw4QkFBOEIsR0FBRyxnREFBZ0QsOEJBQThCLHVCQUF1Qiw2Q0FBNkMseUNBQXlDLHFDQUFxQyxlQUFlLDhCQUE4QixHQUFHLHVEQUF1RCw4Q0FBOEMsMENBQTBDLHNDQUFzQyxlQUFlLGdCQUFnQixXQUFXLGVBQWUsZ0JBQWdCLHVCQUF1Qiw4QkFBOEIsa0NBQWtDLHFCQUFxQixHQUFHLHdEQUF3RCw4QkFBOEIsdUJBQXVCLDZDQUE2Qyx5Q0FBeUMscUNBQXFDLGVBQWUsOEJBQThCLEdBQUcsK0RBQStELDZDQUE2Qyx5Q0FBeUMscUNBQXFDLGVBQWUsY0FBYyxhQUFhLGVBQWUsY0FBYyx1QkFBdUIsc0JBQXNCLGtDQUFrQyxxQkFBcUIsR0FBRyxxQkFBcUIsa0JBQWtCLEdBQUcsZ0NBQWdDLG1CQUFtQixHQUFHLGdGQUFnRixvQkFBb0IsNERBQTRELDZDQUE2Qyw4REFBOEQseURBQXlELFlBQVksYUFBYSxjQUFjLHlDQUF5QyxxRUFBcUUsOEZBQThGLCtCQUErQixtQkFBbUIsR0FBRyxvQkFBb0IsMEJBQTBCLGdCQUFnQixpQkFBaUIsR0FBRywyQkFBMkIsbUJBQW1CLG1CQUFtQixnQkFBZ0IsaUJBQWlCLGlCQUFpQix1QkFBdUIsMkJBQTJCLG9EQUFvRCxrREFBa0QsR0FBRyw4QkFBOEIsUUFBUSw4QkFBOEIsS0FBSyxZQUFZLGdDQUFnQyxLQUFLLEdBQUc7QUFDdHNOO0FBQ0E7Ozs7Ozs7Ozs7OztBQ05BO0FBQ0Esa0NBQWtDLG1CQUFPLENBQUMsK0dBQXNEO0FBQ2hHLHdDQUF3QyxtQkFBTyxDQUFDLGdJQUFpRTtBQUNqSDtBQUNBO0FBQ0E7QUFDQSxjQUFjLFFBQVMsdUdBQXVHLHlCQUF5QixLQUFLLDBGQUEwRix1QkFBdUIsS0FBSyxxRUFBcUUsb0JBQW9CLHVCQUF1QixnQ0FBZ0MseUJBQXlCLEtBQUsscUNBQXFDLGdDQUFnQyxLQUFLLDZCQUE2QixzQkFBc0IsS0FBSztBQUNsa0I7QUFDQTs7Ozs7Ozs7Ozs7OztBQ1JhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCOztBQUVoQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw0Q0FBNEMscUJBQXFCO0FBQ2pFOztBQUVBO0FBQ0EsS0FBSztBQUNMLElBQUk7QUFDSjs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLHFCQUFxQixpQkFBaUI7QUFDdEM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLG9CQUFvQixxQkFBcUI7QUFDekM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLDhCQUE4Qjs7QUFFOUI7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOzs7QUFHRDtBQUNBO0FBQ0E7QUFDQSxxREFBcUQsY0FBYztBQUNuRTtBQUNBLEM7Ozs7Ozs7Ozs7OztBQzdGYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdURBQXVEOztBQUV2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7O0FBRUQ7O0FBRUE7QUFDQTs7QUFFQSxpQkFBaUIsd0JBQXdCO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsaUJBQWlCLGlCQUFpQjtBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZ0JBQWdCLEtBQXdDLEdBQUcsc0JBQWlCLEdBQUcsU0FBSTs7QUFFbkY7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0EscUVBQXFFLHFCQUFxQixhQUFhOztBQUV2Rzs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0EseURBQXlEO0FBQ3pELEdBQUc7O0FBRUg7OztBQUdBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwwQkFBMEI7QUFDMUI7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxtQkFBbUIsNEJBQTRCO0FBQy9DO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLG9CQUFvQiw2QkFBNkI7QUFDakQ7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEU7Ozs7Ozs7Ozs7O0FDNVFBLFVBQVUsbUJBQU8sQ0FBQyw2SkFBOEU7QUFDaEcsMEJBQTBCLG1CQUFPLENBQUMsc0hBQXlEOztBQUUzRjs7QUFFQTtBQUNBLDBCQUEwQixRQUFTO0FBQ25DOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7Ozs7QUFJQSxzQzs7Ozs7Ozs7Ozs7O0FDbEJBO0FBQUE7QUFBQTtBQUFrQjtBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCw2REFBNkQsNEJBQTRCO0FBQ3pGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCLGFBQWE7QUFDYixTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQixhQUFhO0FBQ2IsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtFQUFrRSxRQUFRLElBQUksVUFBVTtBQUN4RixLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1REFBdUQsU0FBUztBQUNoRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWEsV0FBVyxNQUFNO0FBQzlCO0FBQ0E7QUFDQSw4Q0FBOEM7QUFDOUM7QUFDQSx5QkFBeUIsU0FBUyxvQkFBb0IsUUFBUTtBQUM5RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhDQUE4QztBQUM5QztBQUNBLDhEQUE4RCxRQUFRO0FBQ3RFLHdFQUF3RSxvQkFBb0I7QUFDNUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoidWkuanMiLCJzb3VyY2VzQ29udGVudCI6WyIgXHQvLyBUaGUgbW9kdWxlIGNhY2hlXG4gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuXG4gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXG4gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSkge1xuIFx0XHRcdHJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzO1xuIFx0XHR9XG4gXHRcdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG4gXHRcdHZhciBtb2R1bGUgPSBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSA9IHtcbiBcdFx0XHRpOiBtb2R1bGVJZCxcbiBcdFx0XHRsOiBmYWxzZSxcbiBcdFx0XHRleHBvcnRzOiB7fVxuIFx0XHR9O1xuXG4gXHRcdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuIFx0XHRtb2R1bGVzW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuIFx0XHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG4gXHRcdG1vZHVsZS5sID0gdHJ1ZTtcblxuIFx0XHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG4gXHR9XG5cblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBpbnN0YWxsZWRNb2R1bGVzO1xuXG4gXHQvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9uIGZvciBoYXJtb255IGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uZCA9IGZ1bmN0aW9uKGV4cG9ydHMsIG5hbWUsIGdldHRlcikge1xuIFx0XHRpZighX193ZWJwYWNrX3JlcXVpcmVfXy5vKGV4cG9ydHMsIG5hbWUpKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIG5hbWUsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBnZXR0ZXIgfSk7XG4gXHRcdH1cbiBcdH07XG5cbiBcdC8vIGRlZmluZSBfX2VzTW9kdWxlIG9uIGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uciA9IGZ1bmN0aW9uKGV4cG9ydHMpIHtcbiBcdFx0aWYodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFN5bWJvbC50b1N0cmluZ1RhZywgeyB2YWx1ZTogJ01vZHVsZScgfSk7XG4gXHRcdH1cbiBcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcbiBcdH07XG5cbiBcdC8vIGNyZWF0ZSBhIGZha2UgbmFtZXNwYWNlIG9iamVjdFxuIFx0Ly8gbW9kZSAmIDE6IHZhbHVlIGlzIGEgbW9kdWxlIGlkLCByZXF1aXJlIGl0XG4gXHQvLyBtb2RlICYgMjogbWVyZ2UgYWxsIHByb3BlcnRpZXMgb2YgdmFsdWUgaW50byB0aGUgbnNcbiBcdC8vIG1vZGUgJiA0OiByZXR1cm4gdmFsdWUgd2hlbiBhbHJlYWR5IG5zIG9iamVjdFxuIFx0Ly8gbW9kZSAmIDh8MTogYmVoYXZlIGxpa2UgcmVxdWlyZVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy50ID0gZnVuY3Rpb24odmFsdWUsIG1vZGUpIHtcbiBcdFx0aWYobW9kZSAmIDEpIHZhbHVlID0gX193ZWJwYWNrX3JlcXVpcmVfXyh2YWx1ZSk7XG4gXHRcdGlmKG1vZGUgJiA4KSByZXR1cm4gdmFsdWU7XG4gXHRcdGlmKChtb2RlICYgNCkgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAmJiB2YWx1ZS5fX2VzTW9kdWxlKSByZXR1cm4gdmFsdWU7XG4gXHRcdHZhciBucyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gXHRcdF9fd2VicGFja19yZXF1aXJlX18ucihucyk7XG4gXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShucywgJ2RlZmF1bHQnLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2YWx1ZSB9KTtcbiBcdFx0aWYobW9kZSAmIDIgJiYgdHlwZW9mIHZhbHVlICE9ICdzdHJpbmcnKSBmb3IodmFyIGtleSBpbiB2YWx1ZSkgX193ZWJwYWNrX3JlcXVpcmVfXy5kKG5zLCBrZXksIGZ1bmN0aW9uKGtleSkgeyByZXR1cm4gdmFsdWVba2V5XTsgfS5iaW5kKG51bGwsIGtleSkpO1xuIFx0XHRyZXR1cm4gbnM7XG4gXHR9O1xuXG4gXHQvLyBnZXREZWZhdWx0RXhwb3J0IGZ1bmN0aW9uIGZvciBjb21wYXRpYmlsaXR5IHdpdGggbm9uLWhhcm1vbnkgbW9kdWxlc1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5uID0gZnVuY3Rpb24obW9kdWxlKSB7XG4gXHRcdHZhciBnZXR0ZXIgPSBtb2R1bGUgJiYgbW9kdWxlLl9fZXNNb2R1bGUgP1xuIFx0XHRcdGZ1bmN0aW9uIGdldERlZmF1bHQoKSB7IHJldHVybiBtb2R1bGVbJ2RlZmF1bHQnXTsgfSA6XG4gXHRcdFx0ZnVuY3Rpb24gZ2V0TW9kdWxlRXhwb3J0cygpIHsgcmV0dXJuIG1vZHVsZTsgfTtcbiBcdFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kKGdldHRlciwgJ2EnLCBnZXR0ZXIpO1xuIFx0XHRyZXR1cm4gZ2V0dGVyO1xuIFx0fTtcblxuIFx0Ly8gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSBmdW5jdGlvbihvYmplY3QsIHByb3BlcnR5KSB7IHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmN