(self.webpackChunktimetrex=self.webpackChunktimetrex||[]).push([["quick_punch","quick_punch-header-HeaderViewController"],{2237:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval("\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n \"Z\": () => (/* binding */ components_main_ui_router)\n});\n\n// EXTERNAL MODULE: ./node_modules/vue/dist/vue.esm-bundler.js + 6 modules\nvar vue_esm_bundler = __webpack_require__(5166);\n;// CONCATENATED MODULE: ./node_modules/vue-router/dist/vue-router.esm-bundler.js\n/*!\n * vue-router v4.0.12\n * (c) 2021 Eduardo San Martin Morote\n * @license MIT\n */\n\n\n\nconst hasSymbol = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol';\r\nconst PolySymbol = (name) => \r\n// vr = vue router\r\nhasSymbol\r\n ? Symbol(( false) ? 0 : name)\r\n : (( false) ? 0 : '_vr_') + name;\r\n// rvlm = Router View Location Matched\r\n/**\r\n * RouteRecord being rendered by the closest ancestor Router View. Used for\r\n * `onBeforeRouteUpdate` and `onBeforeRouteLeave`. rvlm stands for Router View\r\n * Location Matched\r\n *\r\n * @internal\r\n */\r\nconst matchedRouteKey = /*#__PURE__*/ PolySymbol(( false) ? 0 : 'rvlm');\r\n/**\r\n * Allows overriding the router view depth to control which component in\r\n * `matched` is rendered. rvd stands for Router View Depth\r\n *\r\n * @internal\r\n */\r\nconst viewDepthKey = /*#__PURE__*/ PolySymbol(( false) ? 0 : 'rvd');\r\n/**\r\n * Allows overriding the router instance returned by `useRouter` in tests. r\r\n * stands for router\r\n *\r\n * @internal\r\n */\r\nconst routerKey = /*#__PURE__*/ PolySymbol(( false) ? 0 : 'r');\r\n/**\r\n * Allows overriding the current route returned by `useRoute` in tests. rl\r\n * stands for route location\r\n *\r\n * @internal\r\n */\r\nconst routeLocationKey = /*#__PURE__*/ PolySymbol(( false) ? 0 : 'rl');\r\n/**\r\n * Allows overriding the current route used by router-view. Internally this is\r\n * used when the `route` prop is passed.\r\n *\r\n * @internal\r\n */\r\nconst routerViewLocationKey = /*#__PURE__*/ PolySymbol(( false) ? 0 : 'rvl');\n\nconst isBrowser = typeof window !== 'undefined';\n\nfunction isESModule(obj) {\r\n return obj.__esModule || (hasSymbol && obj[Symbol.toStringTag] === 'Module');\r\n}\r\nconst vue_router_esm_bundler_assign = Object.assign;\r\nfunction applyToParams(fn, params) {\r\n const newParams = {};\r\n for (const key in params) {\r\n const value = params[key];\r\n newParams[key] = Array.isArray(value) ? value.map(fn) : fn(value);\r\n }\r\n return newParams;\r\n}\r\nconst noop = () => { };\n\nfunction warn(msg) {\r\n // avoid using ...args as it breaks in older Edge builds\r\n const args = Array.from(arguments).slice(1);\r\n console.warn.apply(console, ['[Vue Router warn]: ' + msg].concat(args));\r\n}\n\nconst TRAILING_SLASH_RE = /\\/$/;\r\nconst removeTrailingSlash = (path) => path.replace(TRAILING_SLASH_RE, '');\r\n/**\r\n * Transforms an URI into a normalized history location\r\n *\r\n * @param parseQuery\r\n * @param location - URI to normalize\r\n * @param currentLocation - current absolute location. Allows resolving relative\r\n * paths. Must start with `/`. Defaults to `/`\r\n * @returns a normalized history location\r\n */\r\nfunction parseURL(parseQuery, location, currentLocation = '/') {\r\n let path, query = {}, searchString = '', hash = '';\r\n // Could use URL and URLSearchParams but IE 11 doesn't support it\r\n const searchPos = location.indexOf('?');\r\n const hashPos = location.indexOf('#', searchPos > -1 ? searchPos : 0);\r\n if (searchPos > -1) {\r\n path = location.slice(0, searchPos);\r\n searchString = location.slice(searchPos + 1, hashPos > -1 ? hashPos : location.length);\r\n query = parseQuery(searchString);\r\n }\r\n if (hashPos > -1) {\r\n path = path || location.slice(0, hashPos);\r\n // keep the # character\r\n hash = location.slice(hashPos, location.length);\r\n }\r\n // no search and no query\r\n path = resolveRelativePath(path != null ? path : location, currentLocation);\r\n // empty path means a relative query or hash `?foo=f`, `#thing`\r\n return {\r\n fullPath: path + (searchString && '?') + searchString + hash,\r\n path,\r\n query,\r\n hash,\r\n };\r\n}\r\n/**\r\n * Stringifies a URL object\r\n *\r\n * @param stringifyQuery\r\n * @param location\r\n */\r\nfunction stringifyURL(stringifyQuery, location) {\r\n const query = location.query ? stringifyQuery(location.query) : '';\r\n return location.path + (query && '?') + query + (location.hash || '');\r\n}\r\n/**\r\n * Strips off the base from the beginning of a location.pathname in a non\r\n * case-sensitive way.\r\n *\r\n * @param pathname - location.pathname\r\n * @param base - base to strip off\r\n */\r\nfunction stripBase(pathname, base) {\r\n // no base or base is not found at the beginning\r\n if (!base || !pathname.toLowerCase().startsWith(base.toLowerCase()))\r\n return pathname;\r\n return pathname.slice(base.length) || '/';\r\n}\r\n/**\r\n * Checks if two RouteLocation are equal. This means that both locations are\r\n * pointing towards the same {@link RouteRecord} and that all `params`, `query`\r\n * parameters and `hash` are the same\r\n *\r\n * @param a - first {@link RouteLocation}\r\n * @param b - second {@link RouteLocation}\r\n */\r\nfunction isSameRouteLocation(stringifyQuery, a, b) {\r\n const aLastIndex = a.matched.length - 1;\r\n const bLastIndex = b.matched.length - 1;\r\n return (aLastIndex > -1 &&\r\n aLastIndex === bLastIndex &&\r\n isSameRouteRecord(a.matched[aLastIndex], b.matched[bLastIndex]) &&\r\n isSameRouteLocationParams(a.params, b.params) &&\r\n stringifyQuery(a.query) === stringifyQuery(b.query) &&\r\n a.hash === b.hash);\r\n}\r\n/**\r\n * Check if two `RouteRecords` are equal. Takes into account aliases: they are\r\n * considered equal to the `RouteRecord` they are aliasing.\r\n *\r\n * @param a - first {@link RouteRecord}\r\n * @param b - second {@link RouteRecord}\r\n */\r\nfunction isSameRouteRecord(a, b) {\r\n // since the original record has an undefined value for aliasOf\r\n // but all aliases point to the original record, this will always compare\r\n // the original record\r\n return (a.aliasOf || a) === (b.aliasOf || b);\r\n}\r\nfunction isSameRouteLocationParams(a, b) {\r\n if (Object.keys(a).length !== Object.keys(b).length)\r\n return false;\r\n for (const key in a) {\r\n if (!isSameRouteLocationParamsValue(a[key], b[key]))\r\n return false;\r\n }\r\n return true;\r\n}\r\nfunction isSameRouteLocationParamsValue(a, b) {\r\n return Array.isArray(a)\r\n ? isEquivalentArray(a, b)\r\n : Array.isArray(b)\r\n ? isEquivalentArray(b, a)\r\n : a === b;\r\n}\r\n/**\r\n * Check if two arrays are the same or if an array with one single entry is the\r\n * same as another primitive value. Used to check query and parameters\r\n *\r\n * @param a - array of values\r\n * @param b - array of values or a single value\r\n */\r\nfunction isEquivalentArray(a, b) {\r\n return Array.isArray(b)\r\n ? a.length === b.length && a.every((value, i) => value === b[i])\r\n : a.length === 1 && a[0] === b;\r\n}\r\n/**\r\n * Resolves a relative path that starts with `.`.\r\n *\r\n * @param to - path location we are resolving\r\n * @param from - currentLocation.path, should start with `/`\r\n */\r\nfunction resolveRelativePath(to, from) {\r\n if (to.startsWith('/'))\r\n return to;\r\n if (false) {}\r\n if (!to)\r\n return from;\r\n const fromSegments = from.split('/');\r\n const toSegments = to.split('/');\r\n let position = fromSegments.length - 1;\r\n let toPosition;\r\n let segment;\r\n for (toPosition = 0; toPosition < toSegments.length; toPosition++) {\r\n segment = toSegments[toPosition];\r\n // can't go below zero\r\n if (position === 1 || segment === '.')\r\n continue;\r\n if (segment === '..')\r\n position--;\r\n // found something that is not relative path\r\n else\r\n break;\r\n }\r\n return (fromSegments.slice(0, position).join('/') +\r\n '/' +\r\n toSegments\r\n .slice(toPosition - (toPosition === toSegments.length ? 1 : 0))\r\n .join('/'));\r\n}\n\nvar NavigationType;\r\n(function (NavigationType) {\r\n NavigationType[\"pop\"] = \"pop\";\r\n NavigationType[\"push\"] = \"push\";\r\n})(NavigationType || (NavigationType = {}));\r\nvar NavigationDirection;\r\n(function (NavigationDirection) {\r\n NavigationDirection[\"back\"] = \"back\";\r\n NavigationDirection[\"forward\"] = \"forward\";\r\n NavigationDirection[\"unknown\"] = \"\";\r\n})(NavigationDirection || (NavigationDirection = {}));\r\n/**\r\n * Starting location for Histories\r\n */\r\nconst START = '';\r\n// Generic utils\r\n/**\r\n * Normalizes a base by removing any trailing slash and reading the base tag if\r\n * present.\r\n *\r\n * @param base - base to normalize\r\n */\r\nfunction normalizeBase(base) {\r\n if (!base) {\r\n if (isBrowser) {\r\n // respect tag\r\n const baseEl = document.querySelector('base');\r\n base = (baseEl && baseEl.getAttribute('href')) || '/';\r\n // strip full URL origin\r\n base = base.replace(/^\\w+:\\/\\/[^\\/]+/, '');\r\n }\r\n else {\r\n base = '/';\r\n }\r\n }\r\n // ensure leading slash when it was removed by the regex above avoid leading\r\n // slash with hash because the file could be read from the disk like file://\r\n // and the leading slash would cause problems\r\n if (base[0] !== '/' && base[0] !== '#')\r\n base = '/' + base;\r\n // remove the trailing slash so all other method can just do `base + fullPath`\r\n // to build an href\r\n return removeTrailingSlash(base);\r\n}\r\n// remove any character before the hash\r\nconst BEFORE_HASH_RE = /^[^#]+#/;\r\nfunction createHref(base, location) {\r\n return base.replace(BEFORE_HASH_RE, '#') + location;\r\n}\n\nfunction getElementPosition(el, offset) {\r\n const docRect = document.documentElement.getBoundingClientRect();\r\n const elRect = el.getBoundingClientRect();\r\n return {\r\n behavior: offset.behavior,\r\n left: elRect.left - docRect.left - (offset.left || 0),\r\n top: elRect.top - docRect.top - (offset.top || 0),\r\n };\r\n}\r\nconst computeScrollPosition = () => ({\r\n left: window.pageXOffset,\r\n top: window.pageYOffset,\r\n});\r\nfunction scrollToPosition(position) {\r\n let scrollToOptions;\r\n if ('el' in position) {\r\n const positionEl = position.el;\r\n const isIdSelector = typeof positionEl === 'string' && positionEl.startsWith('#');\r\n /**\r\n * `id`s can accept pretty much any characters, including CSS combinators\r\n * like `>` or `~`. It's still possible to retrieve elements using\r\n * `document.getElementById('~')` but it needs to be escaped when using\r\n * `document.querySelector('#\\\\~')` for it to be valid. The only\r\n * requirements for `id`s are them to be unique on the page and to not be\r\n * empty (`id=\"\"`). Because of that, when passing an id selector, it should\r\n * be properly escaped for it to work with `querySelector`. We could check\r\n * for the id selector to be simple (no CSS combinators `+ >~`) but that\r\n * would make things inconsistent since they are valid characters for an\r\n * `id` but would need to be escaped when using `querySelector`, breaking\r\n * their usage and ending up in no selector returned. Selectors need to be\r\n * escaped:\r\n *\r\n * - `#1-thing` becomes `#\\31 -thing`\r\n * - `#with~symbols` becomes `#with\\\\~symbols`\r\n *\r\n * - More information about the topic can be found at\r\n * https://mathiasbynens.be/notes/html5-id-class.\r\n * - Practical example: https://mathiasbynens.be/demo/html5-id\r\n */\r\n if (false) {}\r\n const el = typeof positionEl === 'string'\r\n ? isIdSelector\r\n ? document.getElementById(positionEl.slice(1))\r\n : document.querySelector(positionEl)\r\n : positionEl;\r\n if (!el) {\r\n ( false) &&\r\n 0;\r\n return;\r\n }\r\n scrollToOptions = getElementPosition(el, position);\r\n }\r\n else {\r\n scrollToOptions = position;\r\n }\r\n if ('scrollBehavior' in document.documentElement.style)\r\n window.scrollTo(scrollToOptions);\r\n else {\r\n window.scrollTo(scrollToOptions.left != null ? scrollToOptions.left : window.pageXOffset, scrollToOptions.top != null ? scrollToOptions.top : window.pageYOffset);\r\n }\r\n}\r\nfunction getScrollKey(path, delta) {\r\n const position = history.state ? history.state.position - delta : -1;\r\n return position + path;\r\n}\r\nconst scrollPositions = new Map();\r\nfunction saveScrollPosition(key, scrollPosition) {\r\n scrollPositions.set(key, scrollPosition);\r\n}\r\nfunction getSavedScrollPosition(key) {\r\n const scroll = scrollPositions.get(key);\r\n // consume it so it's not used again\r\n scrollPositions.delete(key);\r\n return scroll;\r\n}\r\n// TODO: RFC about how to save scroll position\r\n/**\r\n * ScrollBehavior instance used by the router to compute and restore the scroll\r\n * position when navigating.\r\n */\r\n// export interface ScrollHandler {\r\n// // returns a scroll position that can be saved in history\r\n// compute(): ScrollPositionEntry\r\n// // can take an extended ScrollPositionEntry\r\n// scroll(position: ScrollPosition): void\r\n// }\r\n// export const scrollHandler: ScrollHandler = {\r\n// compute: computeScroll,\r\n// scroll: scrollToPosition,\r\n// }\n\nlet createBaseLocation = () => location.protocol + '//' + location.host;\r\n/**\r\n * Creates a normalized history location from a window.location object\r\n * @param location -\r\n */\r\nfunction createCurrentLocation(base, location) {\r\n const { pathname, search, hash } = location;\r\n // allows hash bases like #, /#, #/, #!, #!/, /#!/, or even /folder#end\r\n const hashPos = base.indexOf('#');\r\n if (hashPos > -1) {\r\n let slicePos = hash.includes(base.slice(hashPos))\r\n ? base.slice(hashPos).length\r\n : 1;\r\n let pathFromHash = hash.slice(slicePos);\r\n // prepend the starting slash to hash so the url starts with /#\r\n if (pathFromHash[0] !== '/')\r\n pathFromHash = '/' + pathFromHash;\r\n return stripBase(pathFromHash, '');\r\n }\r\n const path = stripBase(pathname, base);\r\n return path + search + hash;\r\n}\r\nfunction useHistoryListeners(base, historyState, currentLocation, replace) {\r\n let listeners = [];\r\n let teardowns = [];\r\n // TODO: should it be a stack? a Dict. Check if the popstate listener\r\n // can trigger twice\r\n let pauseState = null;\r\n const popStateHandler = ({ state, }) => {\r\n const to = createCurrentLocation(base, location);\r\n const from = currentLocation.value;\r\n const fromState = historyState.value;\r\n let delta = 0;\r\n if (state) {\r\n currentLocation.value = to;\r\n historyState.value = state;\r\n // ignore the popstate and reset the pauseState\r\n if (pauseState && pauseState === from) {\r\n pauseState = null;\r\n return;\r\n }\r\n delta = fromState ? state.position - fromState.position : 0;\r\n }\r\n else {\r\n replace(to);\r\n }\r\n // console.log({ deltaFromCurrent })\r\n // Here we could also revert the navigation by calling history.go(-delta)\r\n // this listener will have to be adapted to not trigger again and to wait for the url\r\n // to be updated before triggering the listeners. Some kind of validation function would also\r\n // need to be passed to the listeners so the navigation can be accepted\r\n // call all listeners\r\n listeners.forEach(listener => {\r\n listener(currentLocation.value, from, {\r\n delta,\r\n type: NavigationType.pop,\r\n direction: delta\r\n ? delta > 0\r\n ? NavigationDirection.forward\r\n : NavigationDirection.back\r\n : NavigationDirection.unknown,\r\n });\r\n });\r\n };\r\n function pauseListeners() {\r\n pauseState = currentLocation.value;\r\n }\r\n function listen(callback) {\r\n // setup the listener and prepare teardown callbacks\r\n listeners.push(callback);\r\n const teardown = () => {\r\n const index = listeners.indexOf(callback);\r\n if (index > -1)\r\n listeners.splice(index, 1);\r\n };\r\n teardowns.push(teardown);\r\n return teardown;\r\n }\r\n function beforeUnloadListener() {\r\n const { history } = window;\r\n if (!history.state)\r\n return;\r\n history.replaceState(vue_router_esm_bundler_assign({}, history.state, { scroll: computeScrollPosition() }), '');\r\n }\r\n function destroy() {\r\n for (const teardown of teardowns)\r\n teardown();\r\n teardowns = [];\r\n window.removeEventListener('popstate', popStateHandler);\r\n window.removeEventListener('beforeunload', beforeUnloadListener);\r\n }\r\n // setup the listeners and prepare teardown callbacks\r\n window.addEventListener('popstate', popStateHandler);\r\n window.addEventListener('beforeunload', beforeUnloadListener);\r\n return {\r\n pauseListeners,\r\n listen,\r\n destroy,\r\n };\r\n}\r\n/**\r\n * Creates a state object\r\n */\r\nfunction buildState(back, current, forward, replaced = false, computeScroll = false) {\r\n return {\r\n back,\r\n current,\r\n forward,\r\n replaced,\r\n position: window.history.length,\r\n scroll: computeScroll ? computeScrollPosition() : null,\r\n };\r\n}\r\nfunction useHistoryStateNavigation(base) {\r\n const { history, location } = window;\r\n // private variables\r\n const currentLocation = {\r\n value: createCurrentLocation(base, location),\r\n };\r\n const historyState = { value: history.state };\r\n // build current history entry as this is a fresh navigation\r\n if (!historyState.value) {\r\n changeLocation(currentLocation.value, {\r\n back: null,\r\n current: currentLocation.value,\r\n forward: null,\r\n // the length is off by one, we need to decrease it\r\n position: history.length - 1,\r\n replaced: true,\r\n // don't add a scroll as the user may have an anchor and we want\r\n // scrollBehavior to be triggered without a saved position\r\n scroll: null,\r\n }, true);\r\n }\r\n function changeLocation(to, state, replace) {\r\n /**\r\n * if a base tag is provided and we are on a normal domain, we have to\r\n * respect the provided `base` attribute because pushState() will use it and\r\n * potentially erase anything before the `#` like at\r\n * https://github.com/vuejs/vue-router-next/issues/685 where a base of\r\n * `/folder/#` but a base of `/` would erase the `/folder/` section. If\r\n * there is no host, the `` tag makes no sense and if there isn't a\r\n * base tag we can just use everything after the `#`.\r\n */\r\n const hashIndex = base.indexOf('#');\r\n const url = hashIndex > -1\r\n ? (location.host && document.querySelector('base')\r\n ? base\r\n : base.slice(hashIndex)) + to\r\n : createBaseLocation() + base + to;\r\n try {\r\n // BROWSER QUIRK\r\n // NOTE: Safari throws a SecurityError when calling this function 100 times in 30 seconds\r\n history[replace ? 'replaceState' : 'pushState'](state, '', url);\r\n historyState.value = state;\r\n }\r\n catch (err) {\r\n if ((false)) {}\r\n else {\r\n console.error(err);\r\n }\r\n // Force the navigation, this also resets the call count\r\n location[replace ? 'replace' : 'assign'](url);\r\n }\r\n }\r\n function replace(to, data) {\r\n const state = vue_router_esm_bundler_assign({}, history.state, buildState(historyState.value.back, \r\n // keep back and forward entries but override current position\r\n to, historyState.value.forward, true), data, { position: historyState.value.position });\r\n changeLocation(to, state, true);\r\n currentLocation.value = to;\r\n }\r\n function push(to, data) {\r\n // Add to current entry the information of where we are going\r\n // as well as saving the current position\r\n const currentState = vue_router_esm_bundler_assign({}, \r\n // use current history state to gracefully handle a wrong call to\r\n // history.replaceState\r\n // https://github.com/vuejs/vue-router-next/issues/366\r\n historyState.value, history.state, {\r\n forward: to,\r\n scroll: computeScrollPosition(),\r\n });\r\n if (false) {}\r\n changeLocation(currentState.current, currentState, true);\r\n const state = vue_router_esm_bundler_assign({}, buildState(currentLocation.value, to, null), { position: currentState.position + 1 }, data);\r\n changeLocation(to, state, false);\r\n currentLocation.value = to;\r\n }\r\n return {\r\n location: currentLocation,\r\n state: historyState,\r\n push,\r\n replace,\r\n };\r\n}\r\n/**\r\n * Creates an HTML5 history. Most common history for single page applications.\r\n *\r\n * @param base -\r\n */\r\nfunction createWebHistory(base) {\r\n base = normalizeBase(base);\r\n const historyNavigation = useHistoryStateNavigation(base);\r\n const historyListeners = useHistoryListeners(base, historyNavigation.state, historyNavigation.location, historyNavigation.replace);\r\n function go(delta, triggerListeners = true) {\r\n if (!triggerListeners)\r\n historyListeners.pauseListeners();\r\n history.go(delta);\r\n }\r\n const routerHistory = vue_router_esm_bundler_assign({\r\n // it's overridden right after\r\n location: '',\r\n base,\r\n go,\r\n createHref: createHref.bind(null, base),\r\n }, historyNavigation, historyListeners);\r\n Object.defineProperty(routerHistory, 'location', {\r\n enumerable: true,\r\n get: () => historyNavigation.location.value,\r\n });\r\n Object.defineProperty(routerHistory, 'state', {\r\n enumerable: true,\r\n get: () => historyNavigation.state.value,\r\n });\r\n return routerHistory;\r\n}\n\n/**\r\n * Creates a in-memory based history. The main purpose of this history is to handle SSR. It starts in a special location that is nowhere.\r\n * It's up to the user to replace that location with the starter location by either calling `router.push` or `router.replace`.\r\n *\r\n * @param base - Base applied to all urls, defaults to '/'\r\n * @returns a history object that can be passed to the router constructor\r\n */\r\nfunction createMemoryHistory(base = '') {\r\n let listeners = [];\r\n let queue = [START];\r\n let position = 0;\r\n base = normalizeBase(base);\r\n function setLocation(location) {\r\n position++;\r\n if (position === queue.length) {\r\n // we are at the end, we can simply append a new entry\r\n queue.push(location);\r\n }\r\n else {\r\n // we are in the middle, we remove everything from here in the queue\r\n queue.splice(position);\r\n queue.push(location);\r\n }\r\n }\r\n function triggerListeners(to, from, { direction, delta }) {\r\n const info = {\r\n direction,\r\n delta,\r\n type: NavigationType.pop,\r\n };\r\n for (const callback of listeners) {\r\n callback(to, from, info);\r\n }\r\n }\r\n const routerHistory = {\r\n // rewritten by Object.defineProperty\r\n location: START,\r\n // TODO: should be kept in queue\r\n state: {},\r\n base,\r\n createHref: createHref.bind(null, base),\r\n replace(to) {\r\n // remove current entry and decrement position\r\n queue.splice(position--, 1);\r\n setLocation(to);\r\n },\r\n push(to, data) {\r\n setLocation(to);\r\n },\r\n listen(callback) {\r\n listeners.push(callback);\r\n return () => {\r\n const index = listeners.indexOf(callback);\r\n if (index > -1)\r\n listeners.splice(index, 1);\r\n };\r\n },\r\n destroy() {\r\n listeners = [];\r\n queue = [START];\r\n position = 0;\r\n },\r\n go(delta, shouldTrigger = true) {\r\n const from = this.location;\r\n const direction = \r\n // we are considering delta === 0 going forward, but in abstract mode\r\n // using 0 for the delta doesn't make sense like it does in html5 where\r\n // it reloads the page\r\n delta < 0 ? NavigationDirection.back : NavigationDirection.forward;\r\n position = Math.max(0, Math.min(position + delta, queue.length - 1));\r\n if (shouldTrigger) {\r\n triggerListeners(this.location, from, {\r\n direction,\r\n delta,\r\n });\r\n }\r\n },\r\n };\r\n Object.defineProperty(routerHistory, 'location', {\r\n enumerable: true,\r\n get: () => queue[position],\r\n });\r\n return routerHistory;\r\n}\n\n/**\r\n * Creates a hash history. Useful for web applications with no host (e.g.\r\n * `file://`) or when configuring a server to handle any URL is not possible.\r\n *\r\n * @param base - optional base to provide. Defaults to `location.pathname +\r\n * location.search` If there is a `` tag in the `head`, its value will be\r\n * ignored in favor of this parameter **but note it affects all the\r\n * history.pushState() calls**, meaning that if you use a `` tag, it's\r\n * `href` value **has to match this parameter** (ignoring anything after the\r\n * `#`).\r\n *\r\n * @example\r\n * ```js\r\n * // at https://example.com/folder\r\n * createWebHashHistory() // gives a url of `https://example.com/folder#`\r\n * createWebHashHistory('/folder/') // gives a url of `https://example.com/folder/#`\r\n * // if the `#` is provided in the base, it won't be added by `createWebHashHistory`\r\n * createWebHashHistory('/folder/#/app/') // gives a url of `https://example.com/folder/#/app/`\r\n * // you should avoid doing this because it changes the original url and breaks copying urls\r\n * createWebHashHistory('/other-folder/') // gives a url of `https://example.com/other-folder/#`\r\n *\r\n * // at file:///usr/etc/folder/index.html\r\n * // for locations with no `host`, the base is ignored\r\n * createWebHashHistory('/iAmIgnored') // gives a url of `file:///usr/etc/folder/index.html#`\r\n * ```\r\n */\r\nfunction createWebHashHistory(base) {\r\n // Make sure this implementation is fine in terms of encoding, specially for IE11\r\n // for `file://`, directly use the pathname and ignore the base\r\n // location.pathname contains an initial `/` even at the root: `https://example.com`\r\n base = location.host ? base || location.pathname + location.search : '';\r\n // allow the user to provide a `#` in the middle: `/base/#/app`\r\n if (!base.includes('#'))\r\n base += '#';\r\n if (false) {}\r\n return createWebHistory(base);\r\n}\n\nfunction isRouteLocation(route) {\r\n return typeof route === 'string' || (route && typeof route === 'object');\r\n}\r\nfunction isRouteName(name) {\r\n return typeof name === 'string' || typeof name === 'symbol';\r\n}\n\n/**\r\n * Initial route location where the router is. Can be used in navigation guards\r\n * to differentiate the initial navigation.\r\n *\r\n * @example\r\n * ```js\r\n * import { START_LOCATION } from 'vue-router'\r\n *\r\n * router.beforeEach((to, from) => {\r\n * if (from === START_LOCATION) {\r\n * // initial navigation\r\n * }\r\n * })\r\n * ```\r\n */\r\nconst START_LOCATION_NORMALIZED = {\r\n path: '/',\r\n name: undefined,\r\n params: {},\r\n query: {},\r\n hash: '',\r\n fullPath: '/',\r\n matched: [],\r\n meta: {},\r\n redirectedFrom: undefined,\r\n};\n\nconst NavigationFailureSymbol = /*#__PURE__*/ PolySymbol(( false) ? 0 : 'nf');\r\n/**\r\n * Enumeration with all possible types for navigation failures. Can be passed to\r\n * {@link isNavigationFailure} to check for specific failures.\r\n */\r\nvar NavigationFailureType;\r\n(function (NavigationFailureType) {\r\n /**\r\n * An aborted navigation is a navigation that failed because a navigation\r\n * guard returned `false` or called `next(false)`\r\n */\r\n NavigationFailureType[NavigationFailureType[\"aborted\"] = 4] = \"aborted\";\r\n /**\r\n * A cancelled navigation is a navigation that failed because a more recent\r\n * navigation finished started (not necessarily finished).\r\n */\r\n NavigationFailureType[NavigationFailureType[\"cancelled\"] = 8] = \"cancelled\";\r\n /**\r\n * A duplicated navigation is a navigation that failed because it was\r\n * initiated while already being at the exact same location.\r\n */\r\n NavigationFailureType[NavigationFailureType[\"duplicated\"] = 16] = \"duplicated\";\r\n})(NavigationFailureType || (NavigationFailureType = {}));\r\n// DEV only debug messages\r\nconst ErrorTypeMessages = {\r\n [1 /* MATCHER_NOT_FOUND */]({ location, currentLocation }) {\r\n return `No match for\\n ${JSON.stringify(location)}${currentLocation\r\n ? '\\nwhile being at\\n' + JSON.stringify(currentLocation)\r\n : ''}`;\r\n },\r\n [2 /* NAVIGATION_GUARD_REDIRECT */]({ from, to, }) {\r\n return `Redirected from \"${from.fullPath}\" to \"${stringifyRoute(to)}\" via a navigation guard.`;\r\n },\r\n [4 /* NAVIGATION_ABORTED */]({ from, to }) {\r\n return `Navigation aborted from \"${from.fullPath}\" to \"${to.fullPath}\" via a navigation guard.`;\r\n },\r\n [8 /* NAVIGATION_CANCELLED */]({ from, to }) {\r\n return `Navigation cancelled from \"${from.fullPath}\" to \"${to.fullPath}\" with a new navigation.`;\r\n },\r\n [16 /* NAVIGATION_DUPLICATED */]({ from, to }) {\r\n return `Avoided redundant navigation to current location: \"${from.fullPath}\".`;\r\n },\r\n};\r\nfunction createRouterError(type, params) {\r\n // keep full error messages in cjs versions\r\n if (false) {}\r\n else {\r\n return vue_router_esm_bundler_assign(new Error(), {\r\n type,\r\n [NavigationFailureSymbol]: true,\r\n }, params);\r\n }\r\n}\r\nfunction isNavigationFailure(error, type) {\r\n return (error instanceof Error &&\r\n NavigationFailureSymbol in error &&\r\n (type == null || !!(error.type & type)));\r\n}\r\nconst propertiesToLog = ['params', 'query', 'hash'];\r\nfunction stringifyRoute(to) {\r\n if (typeof to === 'string')\r\n return to;\r\n if ('path' in to)\r\n return to.path;\r\n const location = {};\r\n for (const key of propertiesToLog) {\r\n if (key in to)\r\n location[key] = to[key];\r\n }\r\n return JSON.stringify(location, null, 2);\r\n}\n\n// default pattern for a param: non greedy everything but /\r\nconst BASE_PARAM_PATTERN = '[^/]+?';\r\nconst BASE_PATH_PARSER_OPTIONS = {\r\n sensitive: false,\r\n strict: false,\r\n start: true,\r\n end: true,\r\n};\r\n// Special Regex characters that must be escaped in static tokens\r\nconst REGEX_CHARS_RE = /[.+*?^${}()[\\]/\\\\]/g;\r\n/**\r\n * Creates a path parser from an array of Segments (a segment is an array of Tokens)\r\n *\r\n * @param segments - array of segments returned by tokenizePath\r\n * @param extraOptions - optional options for the regexp\r\n * @returns a PathParser\r\n */\r\nfunction tokensToParser(segments, extraOptions) {\r\n const options = vue_router_esm_bundler_assign({}, BASE_PATH_PARSER_OPTIONS, extraOptions);\r\n // the amount of scores is the same as the length of segments except for the root segment \"/\"\r\n const score = [];\r\n // the regexp as a string\r\n let pattern = options.start ? '^' : '';\r\n // extracted keys\r\n const keys = [];\r\n for (const segment of segments) {\r\n // the root segment needs special treatment\r\n const segmentScores = segment.length ? [] : [90 /* Root */];\r\n // allow trailing slash\r\n if (options.strict && !segment.length)\r\n pattern += '/';\r\n for (let tokenIndex = 0; tokenIndex < segment.length; tokenIndex++) {\r\n const token = segment[tokenIndex];\r\n // resets the score if we are inside a sub segment /:a-other-:b\r\n let subSegmentScore = 40 /* Segment */ +\r\n (options.sensitive ? 0.25 /* BonusCaseSensitive */ : 0);\r\n if (token.type === 0 /* Static */) {\r\n // prepend the slash if we are starting a new segment\r\n if (!tokenIndex)\r\n pattern += '/';\r\n pattern += token.value.replace(REGEX_CHARS_RE, '\\\\$&');\r\n subSegmentScore += 40 /* Static */;\r\n }\r\n else if (token.type === 1 /* Param */) {\r\n const { value, repeatable, optional, regexp } = token;\r\n keys.push({\r\n name: value,\r\n repeatable,\r\n optional,\r\n });\r\n const re = regexp ? regexp : BASE_PARAM_PATTERN;\r\n // the user provided a custom regexp /:id(\\\\d+)\r\n if (re !== BASE_PARAM_PATTERN) {\r\n subSegmentScore += 10 /* BonusCustomRegExp */;\r\n // make sure the regexp is valid before using it\r\n try {\r\n new RegExp(`(${re})`);\r\n }\r\n catch (err) {\r\n throw new Error(`Invalid custom RegExp for param \"${value}\" (${re}): ` +\r\n err.message);\r\n }\r\n }\r\n // when we repeat we must take care of the repeating leading slash\r\n let subPattern = repeatable ? `((?:${re})(?:/(?:${re}))*)` : `(${re})`;\r\n // prepend the slash if we are starting a new segment\r\n if (!tokenIndex)\r\n subPattern =\r\n // avoid an optional / if there are more segments e.g. /:p?-static\r\n // or /:p?-:p2\r\n optional && segment.length < 2\r\n ? `(?:/${subPattern})`\r\n : '/' + subPattern;\r\n if (optional)\r\n subPattern += '?';\r\n pattern += subPattern;\r\n subSegmentScore += 20 /* Dynamic */;\r\n if (optional)\r\n subSegmentScore += -8 /* BonusOptional */;\r\n if (repeatable)\r\n subSegmentScore += -20 /* BonusRepeatable */;\r\n if (re === '.*')\r\n subSegmentScore += -50 /* BonusWildcard */;\r\n }\r\n segmentScores.push(subSegmentScore);\r\n }\r\n // an empty array like /home/ -> [[{home}], []]\r\n // if (!segment.length) pattern += '/'\r\n score.push(segmentScores);\r\n }\r\n // only apply the strict bonus to the last score\r\n if (options.strict && options.end) {\r\n const i = score.length - 1;\r\n score[i][score[i].length - 1] += 0.7000000000000001 /* BonusStrict */;\r\n }\r\n // TODO: dev only warn double trailing slash\r\n if (!options.strict)\r\n pattern += '/?';\r\n if (options.end)\r\n pattern += '$';\r\n // allow paths like /dynamic to only match dynamic or dynamic/... but not dynamic_something_else\r\n else if (options.strict)\r\n pattern += '(?:/|$)';\r\n const re = new RegExp(pattern, options.sensitive ? '' : 'i');\r\n function parse(path) {\r\n const match = path.match(re);\r\n const params = {};\r\n if (!match)\r\n return null;\r\n for (let i = 1; i < match.length; i++) {\r\n const value = match[i] || '';\r\n const key = keys[i - 1];\r\n params[key.name] = value && key.repeatable ? value.split('/') : value;\r\n }\r\n return params;\r\n }\r\n function stringify(params) {\r\n let path = '';\r\n // for optional parameters to allow to be empty\r\n let avoidDuplicatedSlash = false;\r\n for (const segment of segments) {\r\n if (!avoidDuplicatedSlash || !path.endsWith('/'))\r\n path += '/';\r\n avoidDuplicatedSlash = false;\r\n for (const token of segment) {\r\n if (token.type === 0 /* Static */) {\r\n path += token.value;\r\n }\r\n else if (token.type === 1 /* Param */) {\r\n const { value, repeatable, optional } = token;\r\n const param = value in params ? params[value] : '';\r\n if (Array.isArray(param) && !repeatable)\r\n throw new Error(`Provided param \"${value}\" is an array but it is not repeatable (* or + modifiers)`);\r\n const text = Array.isArray(param) ? param.join('/') : param;\r\n if (!text) {\r\n if (optional) {\r\n // if we have more than one optional param like /:a?-static we\r\n // don't need to care about the optional param\r\n if (segment.length < 2) {\r\n // remove the last slash as we could be at the end\r\n if (path.endsWith('/'))\r\n path = path.slice(0, -1);\r\n // do not append a slash on the next iteration\r\n else\r\n avoidDuplicatedSlash = true;\r\n }\r\n }\r\n else\r\n throw new Error(`Missing required param \"${value}\"`);\r\n }\r\n path += text;\r\n }\r\n }\r\n }\r\n return path;\r\n }\r\n return {\r\n re,\r\n score,\r\n keys,\r\n parse,\r\n stringify,\r\n };\r\n}\r\n/**\r\n * Compares an array of numbers as used in PathParser.score and returns a\r\n * number. This function can be used to `sort` an array\r\n *\r\n * @param a - first array of numbers\r\n * @param b - second array of numbers\r\n * @returns 0 if both are equal, < 0 if a should be sorted first, > 0 if b\r\n * should be sorted first\r\n */\r\nfunction compareScoreArray(a, b) {\r\n let i = 0;\r\n while (i < a.length && i < b.length) {\r\n const diff = b[i] - a[i];\r\n // only keep going if diff === 0\r\n if (diff)\r\n return diff;\r\n i++;\r\n }\r\n // if the last subsegment was Static, the shorter segments should be sorted first\r\n // otherwise sort the longest segment first\r\n if (a.length < b.length) {\r\n return a.length === 1 && a[0] === 40 /* Static */ + 40 /* Segment */\r\n ? -1\r\n : 1;\r\n }\r\n else if (a.length > b.length) {\r\n return b.length === 1 && b[0] === 40 /* Static */ + 40 /* Segment */\r\n ? 1\r\n : -1;\r\n }\r\n return 0;\r\n}\r\n/**\r\n * Compare function that can be used with `sort` to sort an array of PathParser\r\n *\r\n * @param a - first PathParser\r\n * @param b - second PathParser\r\n * @returns 0 if both are equal, < 0 if a should be sorted first, > 0 if b\r\n */\r\nfunction comparePathParserScore(a, b) {\r\n let i = 0;\r\n const aScore = a.score;\r\n const bScore = b.score;\r\n while (i < aScore.length && i < bScore.length) {\r\n const comp = compareScoreArray(aScore[i], bScore[i]);\r\n // do not return if both are equal\r\n if (comp)\r\n return comp;\r\n i++;\r\n }\r\n // if a and b share the same score entries but b has more, sort b first\r\n return bScore.length - aScore.length;\r\n // this is the ternary version\r\n // return aScore.length < bScore.length\r\n // ? 1\r\n // : aScore.length > bScore.length\r\n // ? -1\r\n // : 0\r\n}\n\nconst ROOT_TOKEN = {\r\n type: 0 /* Static */,\r\n value: '',\r\n};\r\nconst VALID_PARAM_RE = /[a-zA-Z0-9_]/;\r\n// After some profiling, the cache seems to be unnecessary because tokenizePath\r\n// (the slowest part of adding a route) is very fast\r\n// const tokenCache = new Map()\r\nfunction tokenizePath(path) {\r\n if (!path)\r\n return [[]];\r\n if (path === '/')\r\n return [[ROOT_TOKEN]];\r\n if (!path.startsWith('/')) {\r\n throw new Error(( false)\r\n ? 0\r\n : `Invalid path \"${path}\"`);\r\n }\r\n // if (tokenCache.has(path)) return tokenCache.get(path)!\r\n function crash(message) {\r\n throw new Error(`ERR (${state})/\"${buffer}\": ${message}`);\r\n }\r\n let state = 0 /* Static */;\r\n let previousState = state;\r\n const tokens = [];\r\n // the segment will always be valid because we get into the initial state\r\n // with the leading /\r\n let segment;\r\n function finalizeSegment() {\r\n if (segment)\r\n tokens.push(segment);\r\n segment = [];\r\n }\r\n // index on the path\r\n let i = 0;\r\n // char at index\r\n let char;\r\n // buffer of the value read\r\n let buffer = '';\r\n // custom regexp for a param\r\n let customRe = '';\r\n function consumeBuffer() {\r\n if (!buffer)\r\n return;\r\n if (state === 0 /* Static */) {\r\n segment.push({\r\n type: 0 /* Static */,\r\n value: buffer,\r\n });\r\n }\r\n else if (state === 1 /* Param */ ||\r\n state === 2 /* ParamRegExp */ ||\r\n state === 3 /* ParamRegExpEnd */) {\r\n if (segment.length > 1 && (char === '*' || char === '+'))\r\n crash(`A repeatable param (${buffer}) must be alone in its segment. eg: '/:ids+.`);\r\n segment.push({\r\n type: 1 /* Param */,\r\n value: buffer,\r\n regexp: customRe,\r\n repeatable: char === '*' || char === '+',\r\n optional: char === '*' || char === '?',\r\n });\r\n }\r\n else {\r\n crash('Invalid state to consume buffer');\r\n }\r\n buffer = '';\r\n }\r\n function addCharToBuffer() {\r\n buffer += char;\r\n }\r\n while (i < path.length) {\r\n char = path[i++];\r\n if (char === '\\\\' && state !== 2 /* ParamRegExp */) {\r\n previousState = state;\r\n state = 4 /* EscapeNext */;\r\n continue;\r\n }\r\n switch (state) {\r\n case 0 /* Static */:\r\n if (char === '/') {\r\n if (buffer) {\r\n consumeBuffer();\r\n }\r\n finalizeSegment();\r\n }\r\n else if (char === ':') {\r\n consumeBuffer();\r\n state = 1 /* Param */;\r\n }\r\n else {\r\n addCharToBuffer();\r\n }\r\n break;\r\n case 4 /* EscapeNext */:\r\n addCharToBuffer();\r\n state = previousState;\r\n break;\r\n case 1 /* Param */:\r\n if (char === '(') {\r\n state = 2 /* ParamRegExp */;\r\n }\r\n else if (VALID_PARAM_RE.test(char)) {\r\n addCharToBuffer();\r\n }\r\n else {\r\n consumeBuffer();\r\n state = 0 /* Static */;\r\n // go back one character if we were not modifying\r\n if (char !== '*' && char !== '?' && char !== '+')\r\n i--;\r\n }\r\n break;\r\n case 2 /* ParamRegExp */:\r\n // TODO: is it worth handling nested regexp? like :p(?:prefix_([^/]+)_suffix)\r\n // it already works by escaping the closing )\r\n // https://paths.esm.dev/?p=AAMeJbiAwQEcDKbAoAAkP60PG2R6QAvgNaA6AFACM2ABuQBB#\r\n // is this really something people need since you can also write\r\n // /prefix_:p()_suffix\r\n if (char === ')') {\r\n // handle the escaped )\r\n if (customRe[customRe.length - 1] == '\\\\')\r\n customRe = customRe.slice(0, -1) + char;\r\n else\r\n state = 3 /* ParamRegExpEnd */;\r\n }\r\n else {\r\n customRe += char;\r\n }\r\n break;\r\n case 3 /* ParamRegExpEnd */:\r\n // same as finalizing a param\r\n consumeBuffer();\r\n state = 0 /* Static */;\r\n // go back one character if we were not modifying\r\n if (char !== '*' && char !== '?' && char !== '+')\r\n i--;\r\n customRe = '';\r\n break;\r\n default:\r\n crash('Unknown state');\r\n break;\r\n }\r\n }\r\n if (state === 2 /* ParamRegExp */)\r\n crash(`Unfinished custom RegExp for param \"${buffer}\"`);\r\n consumeBuffer();\r\n finalizeSegment();\r\n // tokenCache.set(path, tokens)\r\n return tokens;\r\n}\n\nfunction createRouteRecordMatcher(record, parent, options) {\r\n const parser = tokensToParser(tokenizePath(record.path), options);\r\n // warn against params with the same name\r\n if ((false)) {}\r\n const matcher = vue_router_esm_bundler_assign(parser, {\r\n record,\r\n parent,\r\n // these needs to be populated by the parent\r\n children: [],\r\n alias: [],\r\n });\r\n if (parent) {\r\n // both are aliases or both are not aliases\r\n // we don't want to mix them because the order is used when\r\n // passing originalRecord in Matcher.addRoute\r\n if (!matcher.record.aliasOf === !parent.record.aliasOf)\r\n parent.children.push(matcher);\r\n }\r\n return matcher;\r\n}\n\n/**\r\n * Creates a Router Matcher.\r\n *\r\n * @internal\r\n * @param routes - array of initial routes\r\n * @param globalOptions - global route options\r\n */\r\nfunction createRouterMatcher(routes, globalOptions) {\r\n // normalized ordered array of matchers\r\n const matchers = [];\r\n const matcherMap = new Map();\r\n globalOptions = mergeOptions({ strict: false, end: true, sensitive: false }, globalOptions);\r\n function getRecordMatcher(name) {\r\n return matcherMap.get(name);\r\n }\r\n function addRoute(record, parent, originalRecord) {\r\n // used later on to remove by name\r\n const isRootAdd = !originalRecord;\r\n const mainNormalizedRecord = normalizeRouteRecord(record);\r\n // we might be the child of an alias\r\n mainNormalizedRecord.aliasOf = originalRecord && originalRecord.record;\r\n const options = mergeOptions(globalOptions, record);\r\n // generate an array of records to correctly handle aliases\r\n const normalizedRecords = [\r\n mainNormalizedRecord,\r\n ];\r\n if ('alias' in record) {\r\n const aliases = typeof record.alias === 'string' ? [record.alias] : record.alias;\r\n for (const alias of aliases) {\r\n normalizedRecords.push(vue_router_esm_bundler_assign({}, mainNormalizedRecord, {\r\n // this allows us to hold a copy of the `components` option\r\n // so that async components cache is hold on the original record\r\n components: originalRecord\r\n ? originalRecord.record.components\r\n : mainNormalizedRecord.components,\r\n path: alias,\r\n // we might be the child of an alias\r\n aliasOf: originalRecord\r\n ? originalRecord.record\r\n : mainNormalizedRecord,\r\n // the aliases are always of the same kind as the original since they\r\n // are defined on the same record\r\n }));\r\n }\r\n }\r\n let matcher;\r\n let originalMatcher;\r\n for (const normalizedRecord of normalizedRecords) {\r\n const { path } = normalizedRecord;\r\n // Build up the path for nested routes if the child isn't an absolute\r\n // route. Only add the / delimiter if the child path isn't empty and if the\r\n // parent path doesn't have a trailing slash\r\n if (parent && path[0] !== '/') {\r\n const parentPath = parent.record.path;\r\n const connectingSlash = parentPath[parentPath.length - 1] === '/' ? '' : '/';\r\n normalizedRecord.path =\r\n parent.record.path + (path && connectingSlash + path);\r\n }\r\n if (false) {}\r\n // create the object before hand so it can be passed to children\r\n matcher = createRouteRecordMatcher(normalizedRecord, parent, options);\r\n if (false)\r\n {}\r\n // if we are an alias we must tell the original record that we exist\r\n // so we can be removed\r\n if (originalRecord) {\r\n originalRecord.alias.push(matcher);\r\n if ((false)) {}\r\n }\r\n else {\r\n // otherwise, the first record is the original and others are aliases\r\n originalMatcher = originalMatcher || matcher;\r\n if (originalMatcher !== matcher)\r\n originalMatcher.alias.push(matcher);\r\n // remove the route if named and only for the top record (avoid in nested calls)\r\n // this works because the original record is the first one\r\n if (isRootAdd && record.name && !isAliasRecord(matcher))\r\n removeRoute(record.name);\r\n }\r\n if ('children' in mainNormalizedRecord) {\r\n const children = mainNormalizedRecord.children;\r\n for (let i = 0; i < children.length; i++) {\r\n addRoute(children[i], matcher, originalRecord && originalRecord.children[i]);\r\n }\r\n }\r\n // if there was no original record, then the first one was not an alias and all\r\n // other alias (if any) need to reference this record when adding children\r\n originalRecord = originalRecord || matcher;\r\n // TODO: add normalized records for more flexibility\r\n // if (parent && isAliasRecord(originalRecord)) {\r\n // parent.children.push(originalRecord)\r\n // }\r\n insertMatcher(matcher);\r\n }\r\n return originalMatcher\r\n ? () => {\r\n // since other matchers are aliases, they should be removed by the original matcher\r\n removeRoute(originalMatcher);\r\n }\r\n : noop;\r\n }\r\n function removeRoute(matcherRef) {\r\n if (isRouteName(matcherRef)) {\r\n const matcher = matcherMap.get(matcherRef);\r\n if (matcher) {\r\n matcherMap.delete(matcherRef);\r\n matchers.splice(matchers.indexOf(matcher), 1);\r\n matcher.children.forEach(removeRoute);\r\n matcher.alias.forEach(removeRoute);\r\n }\r\n }\r\n else {\r\n const index = matchers.indexOf(matcherRef);\r\n if (index > -1) {\r\n matchers.splice(index, 1);\r\n if (matcherRef.record.name)\r\n matcherMap.delete(matcherRef.record.name);\r\n matcherRef.children.forEach(removeRoute);\r\n matcherRef.alias.forEach(removeRoute);\r\n }\r\n }\r\n }\r\n function getRoutes() {\r\n return matchers;\r\n }\r\n function insertMatcher(matcher) {\r\n let i = 0;\r\n // console.log('i is', { i })\r\n while (i < matchers.length &&\r\n comparePathParserScore(matcher, matchers[i]) >= 0)\r\n i++;\r\n // console.log('END i is', { i })\r\n // while (i < matchers.length && matcher.score <= matchers[i].score) i++\r\n matchers.splice(i, 0, matcher);\r\n // only add the original record to the name map\r\n if (matcher.record.name && !isAliasRecord(matcher))\r\n matcherMap.set(matcher.record.name, matcher);\r\n }\r\n function resolve(location, currentLocation) {\r\n let matcher;\r\n let params = {};\r\n let path;\r\n let name;\r\n if ('name' in location && location.name) {\r\n matcher = matcherMap.get(location.name);\r\n if (!matcher)\r\n throw createRouterError(1 /* MATCHER_NOT_FOUND */, {\r\n location,\r\n });\r\n name = matcher.record.name;\r\n params = vue_router_esm_bundler_assign(\r\n // paramsFromLocation is a new object\r\n paramsFromLocation(currentLocation.params, \r\n // only keep params that exist in the resolved location\r\n // TODO: only keep optional params coming from a parent record\r\n matcher.keys.filter(k => !k.optional).map(k => k.name)), location.params);\r\n // throws if cannot be stringified\r\n path = matcher.stringify(params);\r\n }\r\n else if ('path' in location) {\r\n // no need to resolve the path with the matcher as it was provided\r\n // this also allows the user to control the encoding\r\n path = location.path;\r\n if (false) {}\r\n matcher = matchers.find(m => m.re.test(path));\r\n // matcher should have a value after the loop\r\n if (matcher) {\r\n // TODO: dev warning of unused params if provided\r\n // we know the matcher works because we tested the regexp\r\n params = matcher.parse(path);\r\n name = matcher.record.name;\r\n }\r\n // location is a relative path\r\n }\r\n else {\r\n // match by name or path of current route\r\n matcher = currentLocation.name\r\n ? matcherMap.get(currentLocation.name)\r\n : matchers.find(m => m.re.test(currentLocation.path));\r\n if (!matcher)\r\n throw createRouterError(1 /* MATCHER_NOT_FOUND */, {\r\n location,\r\n currentLocation,\r\n });\r\n name = matcher.record.name;\r\n // since we are navigating to the same location, we don't need to pick the\r\n // params like when `name` is provided\r\n params = vue_router_esm_bundler_assign({}, currentLocation.params, location.params);\r\n path = matcher.stringify(params);\r\n }\r\n const matched = [];\r\n let parentMatcher = matcher;\r\n while (parentMatcher) {\r\n // reversed order so parents are at the beginning\r\n matched.unshift(parentMatcher.record);\r\n parentMatcher = parentMatcher.parent;\r\n }\r\n return {\r\n name,\r\n path,\r\n params,\r\n matched,\r\n meta: mergeMetaFields(matched),\r\n };\r\n }\r\n // add initial routes\r\n routes.forEach(route => addRoute(route));\r\n return { addRoute, resolve, removeRoute, getRoutes, getRecordMatcher };\r\n}\r\nfunction paramsFromLocation(params, keys) {\r\n const newParams = {};\r\n for (const key of keys) {\r\n if (key in params)\r\n newParams[key] = params[key];\r\n }\r\n return newParams;\r\n}\r\n/**\r\n * Normalizes a RouteRecordRaw. Creates a copy\r\n *\r\n * @param record\r\n * @returns the normalized version\r\n */\r\nfunction normalizeRouteRecord(record) {\r\n return {\r\n path: record.path,\r\n redirect: record.redirect,\r\n name: record.name,\r\n meta: record.meta || {},\r\n aliasOf: undefined,\r\n beforeEnter: record.beforeEnter,\r\n props: normalizeRecordProps(record),\r\n children: record.children || [],\r\n instances: {},\r\n leaveGuards: new Set(),\r\n updateGuards: new Set(),\r\n enterCallbacks: {},\r\n components: 'components' in record\r\n ? record.components || {}\r\n : { default: record.component },\r\n };\r\n}\r\n/**\r\n * Normalize the optional `props` in a record to always be an object similar to\r\n * components. Also accept a boolean for components.\r\n * @param record\r\n */\r\nfunction normalizeRecordProps(record) {\r\n const propsObject = {};\r\n // props does not exist on redirect records but we can set false directly\r\n const props = record.props || false;\r\n if ('component' in record) {\r\n propsObject.default = props;\r\n }\r\n else {\r\n // NOTE: we could also allow a function to be applied to every component.\r\n // Would need user feedback for use cases\r\n for (const name in record.components)\r\n propsObject[name] = typeof props === 'boolean' ? props : props[name];\r\n }\r\n return propsObject;\r\n}\r\n/**\r\n * Checks if a record or any of its parent is an alias\r\n * @param record\r\n */\r\nfunction isAliasRecord(record) {\r\n while (record) {\r\n if (record.record.aliasOf)\r\n return true;\r\n record = record.parent;\r\n }\r\n return false;\r\n}\r\n/**\r\n * Merge meta fields of an array of records\r\n *\r\n * @param matched - array of matched records\r\n */\r\nfunction mergeMetaFields(matched) {\r\n return matched.reduce((meta, record) => vue_router_esm_bundler_assign(meta, record.meta), {});\r\n}\r\nfunction mergeOptions(defaults, partialOptions) {\r\n const options = {};\r\n for (const key in defaults) {\r\n options[key] = key in partialOptions ? partialOptions[key] : defaults[key];\r\n }\r\n return options;\r\n}\r\nfunction isSameParam(a, b) {\r\n return (a.name === b.name &&\r\n a.optional === b.optional &&\r\n a.repeatable === b.repeatable);\r\n}\r\n/**\r\n * Check if a path and its alias have the same required params\r\n *\r\n * @param a - original record\r\n * @param b - alias record\r\n */\r\nfunction checkSameParams(a, b) {\r\n for (const key of a.keys) {\r\n if (!key.optional && !b.keys.find(isSameParam.bind(null, key)))\r\n return warn(`Alias \"${b.record.path}\" and the original record: \"${a.record.path}\" should have the exact same param named \"${key.name}\"`);\r\n }\r\n for (const key of b.keys) {\r\n if (!key.optional && !a.keys.find(isSameParam.bind(null, key)))\r\n return warn(`Alias \"${b.record.path}\" and the original record: \"${a.record.path}\" should have the exact same param named \"${key.name}\"`);\r\n }\r\n}\r\nfunction checkMissingParamsInAbsolutePath(record, parent) {\r\n for (const key of parent.keys) {\r\n if (!record.keys.find(isSameParam.bind(null, key)))\r\n return warn(`Absolute path \"${record.record.path}\" should have the exact same param named \"${key.name}\" as its parent \"${parent.record.path}\".`);\r\n }\r\n}\n\n/**\r\n * Encoding Rules ␣ = Space Path: ␣ \" < > # ? { } Query: ␣ \" < > # & = Hash: ␣ \"\r\n * < > `\r\n *\r\n * On top of that, the RFC3986 (https://tools.ietf.org/html/rfc3986#section-2.2)\r\n * defines some extra characters to be encoded. Most browsers do not encode them\r\n * in encodeURI https://github.com/whatwg/url/issues/369, so it may be safer to\r\n * also encode `!'()*`. Leaving unencoded only ASCII alphanumeric(`a-zA-Z0-9`)\r\n * plus `-._~`. This extra safety should be applied to query by patching the\r\n * string returned by encodeURIComponent encodeURI also encodes `[\\]^`. `\\`\r\n * should be encoded to avoid ambiguity. Browsers (IE, FF, C) transform a `\\`\r\n * into a `/` if directly typed in. The _backtick_ (`````) should also be\r\n * encoded everywhere because some browsers like FF encode it when directly\r\n * written while others don't. Safari and IE don't encode ``\"<>{}``` in hash.\r\n */\r\n// const EXTRA_RESERVED_RE = /[!'()*]/g\r\n// const encodeReservedReplacer = (c: string) => '%' + c.charCodeAt(0).toString(16)\r\nconst HASH_RE = /#/g; // %23\r\nconst AMPERSAND_RE = /&/g; // %26\r\nconst SLASH_RE = /\\//g; // %2F\r\nconst EQUAL_RE = /=/g; // %3D\r\nconst IM_RE = /\\?/g; // %3F\r\nconst PLUS_RE = /\\+/g; // %2B\r\n/**\r\n * NOTE: It's not clear to me if we should encode the + symbol in queries, it\r\n * seems to be less flexible than not doing so and I can't find out the legacy\r\n * systems requiring this for regular requests like text/html. In the standard,\r\n * the encoding of the plus character is only mentioned for\r\n * application/x-www-form-urlencoded\r\n * (https://url.spec.whatwg.org/#urlencoded-parsing) and most browsers seems lo\r\n * leave the plus character as is in queries. To be more flexible, we allow the\r\n * plus character on the query but it can also be manually encoded by the user.\r\n *\r\n * Resources:\r\n * - https://url.spec.whatwg.org/#urlencoded-parsing\r\n * - https://stackoverflow.com/questions/1634271/url-encoding-the-space-character-or-20\r\n */\r\nconst ENC_BRACKET_OPEN_RE = /%5B/g; // [\r\nconst ENC_BRACKET_CLOSE_RE = /%5D/g; // ]\r\nconst ENC_CARET_RE = /%5E/g; // ^\r\nconst ENC_BACKTICK_RE = /%60/g; // `\r\nconst ENC_CURLY_OPEN_RE = /%7B/g; // {\r\nconst ENC_PIPE_RE = /%7C/g; // |\r\nconst ENC_CURLY_CLOSE_RE = /%7D/g; // }\r\nconst ENC_SPACE_RE = /%20/g; // }\r\n/**\r\n * Encode characters that need to be encoded on the path, search and hash\r\n * sections of the URL.\r\n *\r\n * @internal\r\n * @param text - string to encode\r\n * @returns encoded string\r\n */\r\nfunction commonEncode(text) {\r\n return encodeURI('' + text)\r\n .replace(ENC_PIPE_RE, '|')\r\n .replace(ENC_BRACKET_OPEN_RE, '[')\r\n .replace(ENC_BRACKET_CLOSE_RE, ']');\r\n}\r\n/**\r\n * Encode characters that need to be encoded on the hash section of the URL.\r\n *\r\n * @param text - string to encode\r\n * @returns encoded string\r\n */\r\nfunction encodeHash(text) {\r\n return commonEncode(text)\r\n .replace(ENC_CURLY_OPEN_RE, '{')\r\n .replace(ENC_CURLY_CLOSE_RE, '}')\r\n .replace(ENC_CARET_RE, '^');\r\n}\r\n/**\r\n * Encode characters that need to be encoded query values on the query\r\n * section of the URL.\r\n *\r\n * @param text - string to encode\r\n * @returns encoded string\r\n */\r\nfunction encodeQueryValue(text) {\r\n return (commonEncode(text)\r\n // Encode the space as +, encode the + to differentiate it from the space\r\n .replace(PLUS_RE, '%2B')\r\n .replace(ENC_SPACE_RE, '+')\r\n .replace(HASH_RE, '%23')\r\n .replace(AMPERSAND_RE, '%26')\r\n .replace(ENC_BACKTICK_RE, '`')\r\n .replace(ENC_CURLY_OPEN_RE, '{')\r\n .replace(ENC_CURLY_CLOSE_RE, '}')\r\n .replace(ENC_CARET_RE, '^'));\r\n}\r\n/**\r\n * Like `encodeQueryValue` but also encodes the `=` character.\r\n *\r\n * @param text - string to encode\r\n */\r\nfunction encodeQueryKey(text) {\r\n return encodeQueryValue(text).replace(EQUAL_RE, '%3D');\r\n}\r\n/**\r\n * Encode characters that need to be encoded on the path section of the URL.\r\n *\r\n * @param text - string to encode\r\n * @returns encoded string\r\n */\r\nfunction encodePath(text) {\r\n return commonEncode(text).replace(HASH_RE, '%23').replace(IM_RE, '%3F');\r\n}\r\n/**\r\n * Encode characters that need to be encoded on the path section of the URL as a\r\n * param. This function encodes everything {@link encodePath} does plus the\r\n * slash (`/`) character. If `text` is `null` or `undefined`, returns an empty\r\n * string instead.\r\n *\r\n * @param text - string to encode\r\n * @returns encoded string\r\n */\r\nfunction encodeParam(text) {\r\n return text == null ? '' : encodePath(text).replace(SLASH_RE, '%2F');\r\n}\r\n/**\r\n * Decode text using `decodeURIComponent`. Returns the original text if it\r\n * fails.\r\n *\r\n * @param text - string to decode\r\n * @returns decoded string\r\n */\r\nfunction decode(text) {\r\n try {\r\n return decodeURIComponent('' + text);\r\n }\r\n catch (err) {\r\n ( false) && 0;\r\n }\r\n return '' + text;\r\n}\n\n/**\r\n * Transforms a queryString into a {@link LocationQuery} object. Accept both, a\r\n * version with the leading `?` and without Should work as URLSearchParams\r\n\n * @internal\r\n *\r\n * @param search - search string to parse\r\n * @returns a query object\r\n */\r\nfunction parseQuery(search) {\r\n const query = {};\r\n // avoid creating an object with an empty key and empty value\r\n // because of split('&')\r\n if (search === '' || search === '?')\r\n return query;\r\n const hasLeadingIM = search[0] === '?';\r\n const searchParams = (hasLeadingIM ? search.slice(1) : search).split('&');\r\n for (let i = 0; i < searchParams.length; ++i) {\r\n // pre decode the + into space\r\n const searchParam = searchParams[i].replace(PLUS_RE, ' ');\r\n // allow the = character\r\n const eqPos = searchParam.indexOf('=');\r\n const key = decode(eqPos < 0 ? searchParam : searchParam.slice(0, eqPos));\r\n const value = eqPos < 0 ? null : decode(searchParam.slice(eqPos + 1));\r\n if (key in query) {\r\n // an extra variable for ts types\r\n let currentValue = query[key];\r\n if (!Array.isArray(currentValue)) {\r\n currentValue = query[key] = [currentValue];\r\n }\r\n currentValue.push(value);\r\n }\r\n else {\r\n query[key] = value;\r\n }\r\n }\r\n return query;\r\n}\r\n/**\r\n * Stringifies a {@link LocationQueryRaw} object. Like `URLSearchParams`, it\r\n * doesn't prepend a `?`\r\n *\r\n * @internal\r\n *\r\n * @param query - query object to stringify\r\n * @returns string version of the query without the leading `?`\r\n */\r\nfunction stringifyQuery(query) {\r\n let search = '';\r\n for (let key in query) {\r\n const value = query[key];\r\n key = encodeQueryKey(key);\r\n if (value == null) {\r\n // only null adds the value\r\n if (value !== undefined) {\r\n search += (search.length ? '&' : '') + key;\r\n }\r\n continue;\r\n }\r\n // keep null values\r\n const values = Array.isArray(value)\r\n ? value.map(v => v && encodeQueryValue(v))\r\n : [value && encodeQueryValue(value)];\r\n values.forEach(value => {\r\n // skip undefined values in arrays as if they were not present\r\n // smaller code than using filter\r\n if (value !== undefined) {\r\n // only append & with non-empty search\r\n search += (search.length ? '&' : '') + key;\r\n if (value != null)\r\n search += '=' + value;\r\n }\r\n });\r\n }\r\n return search;\r\n}\r\n/**\r\n * Transforms a {@link LocationQueryRaw} into a {@link LocationQuery} by casting\r\n * numbers into strings, removing keys with an undefined value and replacing\r\n * undefined with null in arrays\r\n *\r\n * @param query - query object to normalize\r\n * @returns a normalized query object\r\n */\r\nfunction normalizeQuery(query) {\r\n const normalizedQuery = {};\r\n for (const key in query) {\r\n const value = query[key];\r\n if (value !== undefined) {\r\n normalizedQuery[key] = Array.isArray(value)\r\n ? value.map(v => (v == null ? null : '' + v))\r\n : value == null\r\n ? value\r\n : '' + value;\r\n }\r\n }\r\n return normalizedQuery;\r\n}\n\n/**\r\n * Create a list of callbacks that can be reset. Used to create before and after navigation guards list\r\n */\r\nfunction useCallbacks() {\r\n let handlers = [];\r\n function add(handler) {\r\n handlers.push(handler);\r\n return () => {\r\n const i = handlers.indexOf(handler);\r\n if (i > -1)\r\n handlers.splice(i, 1);\r\n };\r\n }\r\n function reset() {\r\n handlers = [];\r\n }\r\n return {\r\n add,\r\n list: () => handlers,\r\n reset,\r\n };\r\n}\n\nfunction registerGuard(record, name, guard) {\r\n const removeFromList = () => {\r\n record[name].delete(guard);\r\n };\r\n onUnmounted(removeFromList);\r\n onDeactivated(removeFromList);\r\n onActivated(() => {\r\n record[name].add(guard);\r\n });\r\n record[name].add(guard);\r\n}\r\n/**\r\n * Add a navigation guard that triggers whenever the component for the current\r\n * location is about to be left. Similar to {@link beforeRouteLeave} but can be\r\n * used in any component. The guard is removed when the component is unmounted.\r\n *\r\n * @param leaveGuard - {@link NavigationGuard}\r\n */\r\nfunction onBeforeRouteLeave(leaveGuard) {\r\n if (false) {}\r\n const activeRecord = inject(matchedRouteKey, \r\n // to avoid warning\r\n {}).value;\r\n if (!activeRecord) {\r\n ( false) &&\r\n 0;\r\n return;\r\n }\r\n registerGuard(activeRecord, 'leaveGuards', leaveGuard);\r\n}\r\n/**\r\n * Add a navigation guard that triggers whenever the current location is about\r\n * to be updated. Similar to {@link beforeRouteUpdate} but can be used in any\r\n * component. The guard is removed when the component is unmounted.\r\n *\r\n * @param updateGuard - {@link NavigationGuard}\r\n */\r\nfunction onBeforeRouteUpdate(updateGuard) {\r\n if (false) {}\r\n const activeRecord = inject(matchedRouteKey, \r\n // to avoid warning\r\n {}).value;\r\n if (!activeRecord) {\r\n ( false) &&\r\n 0;\r\n return;\r\n }\r\n registerGuard(activeRecord, 'updateGuards', updateGuard);\r\n}\r\nfunction guardToPromiseFn(guard, to, from, record, name) {\r\n // keep a reference to the enterCallbackArray to prevent pushing callbacks if a new navigation took place\r\n const enterCallbackArray = record &&\r\n // name is defined if record is because of the function overload\r\n (record.enterCallbacks[name] = record.enterCallbacks[name] || []);\r\n return () => new Promise((resolve, reject) => {\r\n const next = (valid) => {\r\n if (valid === false)\r\n reject(createRouterError(4 /* NAVIGATION_ABORTED */, {\r\n from,\r\n to,\r\n }));\r\n else if (valid instanceof Error) {\r\n reject(valid);\r\n }\r\n else if (isRouteLocation(valid)) {\r\n reject(createRouterError(2 /* NAVIGATION_GUARD_REDIRECT */, {\r\n from: to,\r\n to: valid,\r\n }));\r\n }\r\n else {\r\n if (enterCallbackArray &&\r\n // since enterCallbackArray is truthy, both record and name also are\r\n record.enterCallbacks[name] === enterCallbackArray &&\r\n typeof valid === 'function')\r\n enterCallbackArray.push(valid);\r\n resolve();\r\n }\r\n };\r\n // wrapping with Promise.resolve allows it to work with both async and sync guards\r\n const guardReturn = guard.call(record && record.instances[name], to, from, ( false) ? 0 : next);\r\n let guardCall = Promise.resolve(guardReturn);\r\n if (guard.length < 3)\r\n guardCall = guardCall.then(next);\r\n if (false) {}\r\n guardCall.catch(err => reject(err));\r\n });\r\n}\r\nfunction canOnlyBeCalledOnce(next, to, from) {\r\n let called = 0;\r\n return function () {\r\n if (called++ === 1)\r\n warn(`The \"next\" callback was called more than once in one navigation guard when going from \"${from.fullPath}\" to \"${to.fullPath}\". It should be called exactly one time in each navigation guard. This will fail in production.`);\r\n // @ts-expect-error: we put it in the original one because it's easier to check\r\n next._called = true;\r\n if (called === 1)\r\n next.apply(null, arguments);\r\n };\r\n}\r\nfunction extractComponentsGuards(matched, guardType, to, from) {\r\n const guards = [];\r\n for (const record of matched) {\r\n for (const name in record.components) {\r\n let rawComponent = record.components[name];\r\n if ((false)) {}\r\n // skip update and leave guards if the route component is not mounted\r\n if (guardType !== 'beforeRouteEnter' && !record.instances[name])\r\n continue;\r\n if (isRouteComponent(rawComponent)) {\r\n // __vccOpts is added by vue-class-component and contain the regular options\r\n const options = rawComponent.__vccOpts || rawComponent;\r\n const guard = options[guardType];\r\n guard && guards.push(guardToPromiseFn(guard, to, from, record, name));\r\n }\r\n else {\r\n // start requesting the chunk already\r\n let componentPromise = rawComponent();\r\n if (false) {}\r\n guards.push(() => componentPromise.then(resolved => {\r\n if (!resolved)\r\n return Promise.reject(new Error(`Couldn't resolve component \"${name}\" at \"${record.path}\"`));\r\n const resolvedComponent = isESModule(resolved)\r\n ? resolved.default\r\n : resolved;\r\n // replace the function with the resolved component\r\n record.components[name] = resolvedComponent;\r\n // __vccOpts is added by vue-class-component and contain the regular options\r\n const options = resolvedComponent.__vccOpts || resolvedComponent;\r\n const guard = options[guardType];\r\n return guard && guardToPromiseFn(guard, to, from, record, name)();\r\n }));\r\n }\r\n }\r\n }\r\n return guards;\r\n}\r\n/**\r\n * Allows differentiating lazy components from functional components and vue-class-component\r\n *\r\n * @param component\r\n */\r\nfunction isRouteComponent(component) {\r\n return (typeof component === 'object' ||\r\n 'displayName' in component ||\r\n 'props' in component ||\r\n '__vccOpts' in component);\r\n}\n\n// TODO: we could allow currentRoute as a prop to expose `isActive` and\r\n// `isExactActive` behavior should go through an RFC\r\nfunction useLink(props) {\r\n const router = (0,vue_esm_bundler/* inject */.f3)(routerKey);\r\n const currentRoute = (0,vue_esm_bundler/* inject */.f3)(routeLocationKey);\r\n const route = (0,vue_esm_bundler/* computed */.Fl)(() => router.resolve((0,vue_esm_bundler/* unref */.SU)(props.to)));\r\n const activeRecordIndex = (0,vue_esm_bundler/* computed */.Fl)(() => {\r\n const { matched } = route.value;\r\n const { length } = matched;\r\n const routeMatched = matched[length - 1];\r\n const currentMatched = currentRoute.matched;\r\n if (!routeMatched || !currentMatched.length)\r\n return -1;\r\n const index = currentMatched.findIndex(isSameRouteRecord.bind(null, routeMatched));\r\n if (index > -1)\r\n return index;\r\n // possible parent record\r\n const parentRecordPath = getOriginalPath(matched[length - 2]);\r\n return (\r\n // we are dealing with nested routes\r\n length > 1 &&\r\n // if the parent and matched route have the same path, this link is\r\n // referring to the empty child. Or we currently are on a different\r\n // child of the same parent\r\n getOriginalPath(routeMatched) === parentRecordPath &&\r\n // avoid comparing the child with its parent\r\n currentMatched[currentMatched.length - 1].path !== parentRecordPath\r\n ? currentMatched.findIndex(isSameRouteRecord.bind(null, matched[length - 2]))\r\n : index);\r\n });\r\n const isActive = (0,vue_esm_bundler/* computed */.Fl)(() => activeRecordIndex.value > -1 &&\r\n includesParams(currentRoute.params, route.value.params));\r\n const isExactActive = (0,vue_esm_bundler/* computed */.Fl)(() => activeRecordIndex.value > -1 &&\r\n activeRecordIndex.value === currentRoute.matched.length - 1 &&\r\n isSameRouteLocationParams(currentRoute.params, route.value.params));\r\n function navigate(e = {}) {\r\n if (guardEvent(e)) {\r\n return router[(0,vue_esm_bundler/* unref */.SU)(props.replace) ? 'replace' : 'push']((0,vue_esm_bundler/* unref */.SU)(props.to)\r\n // avoid uncaught errors are they are logged anyway\r\n ).catch(noop);\r\n }\r\n return Promise.resolve();\r\n }\r\n // devtools only\r\n if (false) {}\r\n return {\r\n route,\r\n href: (0,vue_esm_bundler/* computed */.Fl)(() => route.value.href),\r\n isActive,\r\n isExactActive,\r\n navigate,\r\n };\r\n}\r\nconst RouterLinkImpl = /*#__PURE__*/ (0,vue_esm_bundler/* defineComponent */.aZ)({\r\n name: 'RouterLink',\r\n props: {\r\n to: {\r\n type: [String, Object],\r\n required: true,\r\n },\r\n replace: Boolean,\r\n activeClass: String,\r\n // inactiveClass: String,\r\n exactActiveClass: String,\r\n custom: Boolean,\r\n ariaCurrentValue: {\r\n type: String,\r\n default: 'page',\r\n },\r\n },\r\n useLink,\r\n setup(props, { slots }) {\r\n const link = (0,vue_esm_bundler/* reactive */.qj)(useLink(props));\r\n const { options } = (0,vue_esm_bundler/* inject */.f3)(routerKey);\r\n const elClass = (0,vue_esm_bundler/* computed */.Fl)(() => ({\r\n [getLinkClass(props.activeClass, options.linkActiveClass, 'router-link-active')]: link.isActive,\r\n // [getLinkClass(\r\n // props.inactiveClass,\r\n // options.linkInactiveClass,\r\n // 'router-link-inactive'\r\n // )]: !link.isExactActive,\r\n [getLinkClass(props.exactActiveClass, options.linkExactActiveClass, 'router-link-exact-active')]: link.isExactActive,\r\n }));\r\n return () => {\r\n const children = slots.default && slots.default(link);\r\n return props.custom\r\n ? children\r\n : (0,vue_esm_bundler.h)('a', {\r\n 'aria-current': link.isExactActive\r\n ? props.ariaCurrentValue\r\n : null,\r\n href: link.href,\r\n // this would override user added attrs but Vue will still add\r\n // the listener so we end up triggering both\r\n onClick: link.navigate,\r\n class: elClass.value,\r\n }, children);\r\n };\r\n },\r\n});\r\n// export the public type for h/tsx inference\r\n// also to avoid inline import() in generated d.ts files\r\n/**\r\n * Component to render a link that triggers a navigation on click.\r\n */\r\nconst RouterLink = RouterLinkImpl;\r\nfunction guardEvent(e) {\r\n // don't redirect with control keys\r\n if (e.metaKey || e.altKey || e.ctrlKey || e.shiftKey)\r\n return;\r\n // don't redirect when preventDefault called\r\n if (e.defaultPrevented)\r\n return;\r\n // don't redirect on right click\r\n if (e.button !== undefined && e.button !== 0)\r\n return;\r\n // don't redirect if `target=\"_blank\"`\r\n // @ts-expect-error getAttribute does exist\r\n if (e.currentTarget && e.currentTarget.getAttribute) {\r\n // @ts-expect-error getAttribute exists\r\n const target = e.currentTarget.getAttribute('target');\r\n if (/\\b_blank\\b/i.test(target))\r\n return;\r\n }\r\n // this may be a Weex event which doesn't have this method\r\n if (e.preventDefault)\r\n e.preventDefault();\r\n return true;\r\n}\r\nfunction includesParams(outer, inner) {\r\n for (const key in inner) {\r\n const innerValue = inner[key];\r\n const outerValue = outer[key];\r\n if (typeof innerValue === 'string') {\r\n if (innerValue !== outerValue)\r\n return false;\r\n }\r\n else {\r\n if (!Array.isArray(outerValue) ||\r\n outerValue.length !== innerValue.length ||\r\n innerValue.some((value, i) => value !== outerValue[i]))\r\n return false;\r\n }\r\n }\r\n return true;\r\n}\r\n/**\r\n * Get the original path value of a record by following its aliasOf\r\n * @param record\r\n */\r\nfunction getOriginalPath(record) {\r\n return record ? (record.aliasOf ? record.aliasOf.path : record.path) : '';\r\n}\r\n/**\r\n * Utility class to get the active class based on defaults.\r\n * @param propClass\r\n * @param globalClass\r\n * @param defaultClass\r\n */\r\nconst getLinkClass = (propClass, globalClass, defaultClass) => propClass != null\r\n ? propClass\r\n : globalClass != null\r\n ? globalClass\r\n : defaultClass;\n\nconst RouterViewImpl = /*#__PURE__*/ (0,vue_esm_bundler/* defineComponent */.aZ)({\r\n name: 'RouterView',\r\n // #674 we manually inherit them\r\n inheritAttrs: false,\r\n props: {\r\n name: {\r\n type: String,\r\n default: 'default',\r\n },\r\n route: Object,\r\n },\r\n setup(props, { attrs, slots }) {\r\n ( false) && 0;\r\n const injectedRoute = (0,vue_esm_bundler/* inject */.f3)(routerViewLocationKey);\r\n const routeToDisplay = (0,vue_esm_bundler/* computed */.Fl)(() => props.route || injectedRoute.value);\r\n const depth = (0,vue_esm_bundler/* inject */.f3)(viewDepthKey, 0);\r\n const matchedRouteRef = (0,vue_esm_bundler/* computed */.Fl)(() => routeToDisplay.value.matched[depth]);\r\n (0,vue_esm_bundler/* provide */.JJ)(viewDepthKey, depth + 1);\r\n (0,vue_esm_bundler/* provide */.JJ)(matchedRouteKey, matchedRouteRef);\r\n (0,vue_esm_bundler/* provide */.JJ)(routerViewLocationKey, routeToDisplay);\r\n const viewRef = (0,vue_esm_bundler/* ref */.iH)();\r\n // watch at the same time the component instance, the route record we are\r\n // rendering, and the name\r\n (0,vue_esm_bundler/* watch */.YP)(() => [viewRef.value, matchedRouteRef.value, props.name], ([instance, to, name], [oldInstance, from, oldName]) => {\r\n // copy reused instances\r\n if (to) {\r\n // this will update the instance for new instances as well as reused\r\n // instances when navigating to a new route\r\n to.instances[name] = instance;\r\n // the component instance is reused for a different route or name so\r\n // we copy any saved update or leave guards. With async setup, the\r\n // mounting component will mount before the matchedRoute changes,\r\n // making instance === oldInstance, so we check if guards have been\r\n // added before. This works because we remove guards when\r\n // unmounting/deactivating components\r\n if (from && from !== to && instance && instance === oldInstance) {\r\n if (!to.leaveGuards.size) {\r\n to.leaveGuards = from.leaveGuards;\r\n }\r\n if (!to.updateGuards.size) {\r\n to.updateGuards = from.updateGuards;\r\n }\r\n }\r\n }\r\n // trigger beforeRouteEnter next callbacks\r\n if (instance &&\r\n to &&\r\n // if there is no instance but to and from are the same this might be\r\n // the first visit\r\n (!from || !isSameRouteRecord(to, from) || !oldInstance)) {\r\n (to.enterCallbacks[name] || []).forEach(callback => callback(instance));\r\n }\r\n }, { flush: 'post' });\r\n return () => {\r\n const route = routeToDisplay.value;\r\n const matchedRoute = matchedRouteRef.value;\r\n const ViewComponent = matchedRoute && matchedRoute.components[props.name];\r\n // we need the value at the time we render because when we unmount, we\r\n // navigated to a different location so the value is different\r\n const currentName = props.name;\r\n if (!ViewComponent) {\r\n return normalizeSlot(slots.default, { Component: ViewComponent, route });\r\n }\r\n // props from route configuration\r\n const routePropsOption = matchedRoute.props[props.name];\r\n const routeProps = routePropsOption\r\n ? routePropsOption === true\r\n ? route.params\r\n : typeof routePropsOption === 'function'\r\n ? routePropsOption(route)\r\n : routePropsOption\r\n : null;\r\n const onVnodeUnmounted = vnode => {\r\n // remove the instance reference to prevent leak\r\n if (vnode.component.isUnmounted) {\r\n matchedRoute.instances[currentName] = null;\r\n }\r\n };\r\n const component = (0,vue_esm_bundler.h)(ViewComponent, vue_router_esm_bundler_assign({}, routeProps, attrs, {\r\n onVnodeUnmounted,\r\n ref: viewRef,\r\n }));\r\n if (false) {}\r\n return (\r\n // pass the vnode to the slot as a prop.\r\n // h and both accept vnodes\r\n normalizeSlot(slots.default, { Component: component, route }) ||\r\n component);\r\n };\r\n },\r\n});\r\nfunction normalizeSlot(slot, data) {\r\n if (!slot)\r\n return null;\r\n const slotContent = slot(data);\r\n return slotContent.length === 1 ? slotContent[0] : slotContent;\r\n}\r\n// export the public type for h/tsx inference\r\n// also to avoid inline import() in generated d.ts files\r\n/**\r\n * Component to display the current route the user is at.\r\n */\r\nconst RouterView = RouterViewImpl;\r\n// warn against deprecated usage with & \r\n// due to functional component being no longer eager in Vue 3\r\nfunction warnDeprecatedUsage() {\r\n const instance = getCurrentInstance();\r\n const parentName = instance.parent && instance.parent.type.name;\r\n if (parentName &&\r\n (parentName === 'KeepAlive' || parentName.includes('Transition'))) {\r\n const comp = parentName === 'KeepAlive' ? 'keep-alive' : 'transition';\r\n warn(` can no longer be used directly inside or .\\n` +\r\n `Use slot props instead:\\n\\n` +\r\n `\\n` +\r\n ` <${comp}>\\n` +\r\n ` \\n` +\r\n ` ${comp}>\\n` +\r\n ``);\r\n }\r\n}\n\nfunction formatRouteLocation(routeLocation, tooltip) {\r\n const copy = vue_router_esm_bundler_assign({}, routeLocation, {\r\n // remove variables that can contain vue instances\r\n matched: routeLocation.matched.map(matched => omit(matched, ['instances', 'children', 'aliasOf'])),\r\n });\r\n return {\r\n _custom: {\r\n type: null,\r\n readOnly: true,\r\n display: routeLocation.fullPath,\r\n tooltip,\r\n value: copy,\r\n },\r\n };\r\n}\r\nfunction formatDisplay(display) {\r\n return {\r\n _custom: {\r\n display,\r\n },\r\n };\r\n}\r\n// to support multiple router instances\r\nlet routerId = 0;\r\nfunction addDevtools(app, router, matcher) {\r\n // Take over router.beforeEach and afterEach\r\n // make sure we are not registering the devtool twice\r\n if (router.__hasDevtools)\r\n return;\r\n router.__hasDevtools = true;\r\n // increment to support multiple router instances\r\n const id = routerId++;\r\n setupDevtoolsPlugin({\r\n id: 'org.vuejs.router' + (id ? '.' + id : ''),\r\n label: 'Vue Router',\r\n packageName: 'vue-router',\r\n homepage: 'https://next.router.vuejs.org/',\r\n logo: 'https://vuejs.org/images/icons/favicon-96x96.png',\r\n componentStateTypes: ['Routing'],\r\n app,\r\n }, api => {\r\n // display state added by the router\r\n api.on.inspectComponent((payload, ctx) => {\r\n if (payload.instanceData) {\r\n payload.instanceData.state.push({\r\n type: 'Routing',\r\n key: '$route',\r\n editable: false,\r\n value: formatRouteLocation(router.currentRoute.value, 'Current Route'),\r\n });\r\n }\r\n });\r\n // mark router-link as active and display tags on router views\r\n api.on.visitComponentTree(({ treeNode: node, componentInstance }) => {\r\n if (componentInstance.__vrv_devtools) {\r\n const info = componentInstance.__vrv_devtools;\r\n node.tags.push({\r\n label: (info.name ? `${info.name.toString()}: ` : '') + info.path,\r\n textColor: 0,\r\n tooltip: 'This component is rendered by <router-view>',\r\n backgroundColor: PINK_500,\r\n });\r\n }\r\n // if multiple useLink are used\r\n if (Array.isArray(componentInstance.__vrl_devtools)) {\r\n componentInstance.__devtoolsApi = api;\r\n componentInstance.__vrl_devtools.forEach(devtoolsData => {\r\n let backgroundColor = ORANGE_400;\r\n let tooltip = '';\r\n if (devtoolsData.isExactActive) {\r\n backgroundColor = LIME_500;\r\n tooltip = 'This is exactly active';\r\n }\r\n else if (devtoolsData.isActive) {\r\n backgroundColor = BLUE_600;\r\n tooltip = 'This link is active';\r\n }\r\n node.tags.push({\r\n label: devtoolsData.route.path,\r\n textColor: 0,\r\n tooltip,\r\n backgroundColor,\r\n });\r\n });\r\n }\r\n });\r\n watch(router.currentRoute, () => {\r\n // refresh active state\r\n refreshRoutesView();\r\n api.notifyComponentUpdate();\r\n api.sendInspectorTree(routerInspectorId);\r\n api.sendInspectorState(routerInspectorId);\r\n });\r\n const navigationsLayerId = 'router:navigations:' + id;\r\n api.addTimelineLayer({\r\n id: navigationsLayerId,\r\n label: `Router${id ? ' ' + id : ''} Navigations`,\r\n color: 0x40a8c4,\r\n });\r\n // const errorsLayerId = 'router:errors'\r\n // api.addTimelineLayer({\r\n // id: errorsLayerId,\r\n // label: 'Router Errors',\r\n // color: 0xea5455,\r\n // })\r\n router.onError((error, to) => {\r\n api.addTimelineEvent({\r\n layerId: navigationsLayerId,\r\n event: {\r\n title: 'Error during Navigation',\r\n subtitle: to.fullPath,\r\n logType: 'error',\r\n time: Date.now(),\r\n data: { error },\r\n groupId: to.meta.__navigationId,\r\n },\r\n });\r\n });\r\n // attached to `meta` and used to group events\r\n let navigationId = 0;\r\n router.beforeEach((to, from) => {\r\n const data = {\r\n guard: formatDisplay('beforeEach'),\r\n from: formatRouteLocation(from, 'Current Location during this navigation'),\r\n to: formatRouteLocation(to, 'Target location'),\r\n };\r\n // Used to group navigations together, hide from devtools\r\n Object.defineProperty(to.meta, '__navigationId', {\r\n value: navigationId++,\r\n });\r\n api.addTimelineEvent({\r\n layerId: navigationsLayerId,\r\n event: {\r\n time: Date.now(),\r\n title: 'Start of navigation',\r\n subtitle: to.fullPath,\r\n data,\r\n groupId: to.meta.__navigationId,\r\n },\r\n });\r\n });\r\n router.afterEach((to, from, failure) => {\r\n const data = {\r\n guard: formatDisplay('afterEach'),\r\n };\r\n if (failure) {\r\n data.failure = {\r\n _custom: {\r\n type: Error,\r\n readOnly: true,\r\n display: failure ? failure.message : '',\r\n tooltip: 'Navigation Failure',\r\n value: failure,\r\n },\r\n };\r\n data.status = formatDisplay('❌');\r\n }\r\n else {\r\n data.status = formatDisplay('✅');\r\n }\r\n // we set here to have the right order\r\n data.from = formatRouteLocation(from, 'Current Location during this navigation');\r\n data.to = formatRouteLocation(to, 'Target location');\r\n api.addTimelineEvent({\r\n layerId: navigationsLayerId,\r\n event: {\r\n title: 'End of navigation',\r\n subtitle: to.fullPath,\r\n time: Date.now(),\r\n data,\r\n logType: failure ? 'warning' : 'default',\r\n groupId: to.meta.__navigationId,\r\n },\r\n });\r\n });\r\n /**\r\n * Inspector of Existing routes\r\n */\r\n const routerInspectorId = 'router-inspector:' + id;\r\n api.addInspector({\r\n id: routerInspectorId,\r\n label: 'Routes' + (id ? ' ' + id : ''),\r\n icon: 'book',\r\n treeFilterPlaceholder: 'Search routes',\r\n });\r\n function refreshRoutesView() {\r\n // the routes view isn't active\r\n if (!activeRoutesPayload)\r\n return;\r\n const payload = activeRoutesPayload;\r\n // children routes will appear as nested\r\n let routes = matcher.getRoutes().filter(route => !route.parent);\r\n // reset match state to false\r\n routes.forEach(resetMatchStateOnRouteRecord);\r\n // apply a match state if there is a payload\r\n if (payload.filter) {\r\n routes = routes.filter(route => \r\n // save matches state based on the payload\r\n isRouteMatching(route, payload.filter.toLowerCase()));\r\n }\r\n // mark active routes\r\n routes.forEach(route => markRouteRecordActive(route, router.currentRoute.value));\r\n payload.rootNodes = routes.map(formatRouteRecordForInspector);\r\n }\r\n let activeRoutesPayload;\r\n api.on.getInspectorTree(payload => {\r\n activeRoutesPayload = payload;\r\n if (payload.app === app && payload.inspectorId === routerInspectorId) {\r\n refreshRoutesView();\r\n }\r\n });\r\n /**\r\n * Display information about the currently selected route record\r\n */\r\n api.on.getInspectorState(payload => {\r\n if (payload.app === app && payload.inspectorId === routerInspectorId) {\r\n const routes = matcher.getRoutes();\r\n const route = routes.find(route => route.record.__vd_id === payload.nodeId);\r\n if (route) {\r\n payload.state = {\r\n options: formatRouteRecordMatcherForStateInspector(route),\r\n };\r\n }\r\n }\r\n });\r\n api.sendInspectorTree(routerInspectorId);\r\n api.sendInspectorState(routerInspectorId);\r\n });\r\n}\r\nfunction modifierForKey(key) {\r\n if (key.optional) {\r\n return key.repeatable ? '*' : '?';\r\n }\r\n else {\r\n return key.repeatable ? '+' : '';\r\n }\r\n}\r\nfunction formatRouteRecordMatcherForStateInspector(route) {\r\n const { record } = route;\r\n const fields = [\r\n { editable: false, key: 'path', value: record.path },\r\n ];\r\n if (record.name != null) {\r\n fields.push({\r\n editable: false,\r\n key: 'name',\r\n value: record.name,\r\n });\r\n }\r\n fields.push({ editable: false, key: 'regexp', value: route.re });\r\n if (route.keys.length) {\r\n fields.push({\r\n editable: false,\r\n key: 'keys',\r\n value: {\r\n _custom: {\r\n type: null,\r\n readOnly: true,\r\n display: route.keys\r\n .map(key => `${key.name}${modifierForKey(key)}`)\r\n .join(' '),\r\n tooltip: 'Param keys',\r\n value: route.keys,\r\n },\r\n },\r\n });\r\n }\r\n if (record.redirect != null) {\r\n fields.push({\r\n editable: false,\r\n key: 'redirect',\r\n value: record.redirect,\r\n });\r\n }\r\n if (route.alias.length) {\r\n fields.push({\r\n editable: false,\r\n key: 'aliases',\r\n value: route.alias.map(alias => alias.record.path),\r\n });\r\n }\r\n fields.push({\r\n key: 'score',\r\n editable: false,\r\n value: {\r\n _custom: {\r\n type: null,\r\n readOnly: true,\r\n display: route.score.map(score => score.join(', ')).join(' | '),\r\n tooltip: 'Score used to sort routes',\r\n value: route.score,\r\n },\r\n },\r\n });\r\n return fields;\r\n}\r\n/**\r\n * Extracted from tailwind palette\r\n */\r\nconst PINK_500 = 0xec4899;\r\nconst BLUE_600 = 0x2563eb;\r\nconst LIME_500 = 0x84cc16;\r\nconst CYAN_400 = 0x22d3ee;\r\nconst ORANGE_400 = 0xfb923c;\r\n// const GRAY_100 = 0xf4f4f5\r\nconst DARK = 0x666666;\r\nfunction formatRouteRecordForInspector(route) {\r\n const tags = [];\r\n const { record } = route;\r\n if (record.name != null) {\r\n tags.push({\r\n label: String(record.name),\r\n textColor: 0,\r\n backgroundColor: CYAN_400,\r\n });\r\n }\r\n if (record.aliasOf) {\r\n tags.push({\r\n label: 'alias',\r\n textColor: 0,\r\n backgroundColor: ORANGE_400,\r\n });\r\n }\r\n if (route.__vd_match) {\r\n tags.push({\r\n label: 'matches',\r\n textColor: 0,\r\n backgroundColor: PINK_500,\r\n });\r\n }\r\n if (route.__vd_exactActive) {\r\n tags.push({\r\n label: 'exact',\r\n textColor: 0,\r\n backgroundColor: LIME_500,\r\n });\r\n }\r\n if (route.__vd_active) {\r\n tags.push({\r\n label: 'active',\r\n textColor: 0,\r\n backgroundColor: BLUE_600,\r\n });\r\n }\r\n if (record.redirect) {\r\n tags.push({\r\n label: 'redirect: ' +\r\n (typeof record.redirect === 'string' ? record.redirect : 'Object'),\r\n textColor: 0xffffff,\r\n backgroundColor: DARK,\r\n });\r\n }\r\n // add an id to be able to select it. Using the `path` is not possible because\r\n // empty path children would collide with their parents\r\n let id = record.__vd_id;\r\n if (id == null) {\r\n id = String(routeRecordId++);\r\n record.__vd_id = id;\r\n }\r\n return {\r\n id,\r\n label: record.path,\r\n tags,\r\n children: route.children.map(formatRouteRecordForInspector),\r\n };\r\n}\r\n// incremental id for route records and inspector state\r\nlet routeRecordId = 0;\r\nconst EXTRACT_REGEXP_RE = /^\\/(.*)\\/([a-z]*)$/;\r\nfunction markRouteRecordActive(route, currentRoute) {\r\n // no route will be active if matched is empty\r\n // reset the matching state\r\n const isExactActive = currentRoute.matched.length &&\r\n isSameRouteRecord(currentRoute.matched[currentRoute.matched.length - 1], route.record);\r\n route.__vd_exactActive = route.__vd_active = isExactActive;\r\n if (!isExactActive) {\r\n route.__vd_active = currentRoute.matched.some(match => isSameRouteRecord(match, route.record));\r\n }\r\n route.children.forEach(childRoute => markRouteRecordActive(childRoute, currentRoute));\r\n}\r\nfunction resetMatchStateOnRouteRecord(route) {\r\n route.__vd_match = false;\r\n route.children.forEach(resetMatchStateOnRouteRecord);\r\n}\r\nfunction isRouteMatching(route, filter) {\r\n const found = String(route.re).match(EXTRACT_REGEXP_RE);\r\n route.__vd_match = false;\r\n if (!found || found.length < 3) {\r\n return false;\r\n }\r\n // use a regexp without $ at the end to match nested routes better\r\n const nonEndingRE = new RegExp(found[1].replace(/\\$$/, ''), found[2]);\r\n if (nonEndingRE.test(filter)) {\r\n // mark children as matches\r\n route.children.forEach(child => isRouteMatching(child, filter));\r\n // exception case: `/`\r\n if (route.record.path !== '/' || filter === '/') {\r\n route.__vd_match = route.re.test(filter);\r\n return true;\r\n }\r\n // hide the / route\r\n return false;\r\n }\r\n const path = route.record.path.toLowerCase();\r\n const decodedPath = decode(path);\r\n // also allow partial matching on the path\r\n if (!filter.startsWith('/') &&\r\n (decodedPath.includes(filter) || path.includes(filter)))\r\n return true;\r\n if (decodedPath.startsWith(filter) || path.startsWith(filter))\r\n return true;\r\n if (route.record.name && String(route.record.name).includes(filter))\r\n return true;\r\n return route.children.some(child => isRouteMatching(child, filter));\r\n}\r\nfunction omit(obj, keys) {\r\n const ret = {};\r\n for (const key in obj) {\r\n if (!keys.includes(key)) {\r\n // @ts-expect-error\r\n ret[key] = obj[key];\r\n }\r\n }\r\n return ret;\r\n}\n\n/**\r\n * Creates a Router instance that can be used by a Vue app.\r\n *\r\n * @param options - {@link RouterOptions}\r\n */\r\nfunction createRouter(options) {\r\n const matcher = createRouterMatcher(options.routes, options);\r\n const parseQuery$1 = options.parseQuery || parseQuery;\r\n const stringifyQuery$1 = options.stringifyQuery || stringifyQuery;\r\n const routerHistory = options.history;\r\n if (false)\r\n {}\r\n const beforeGuards = useCallbacks();\r\n const beforeResolveGuards = useCallbacks();\r\n const afterGuards = useCallbacks();\r\n const currentRoute = (0,vue_esm_bundler/* shallowRef */.XI)(START_LOCATION_NORMALIZED);\r\n let pendingLocation = START_LOCATION_NORMALIZED;\r\n // leave the scrollRestoration if no scrollBehavior is provided\r\n if (isBrowser && options.scrollBehavior && 'scrollRestoration' in history) {\r\n history.scrollRestoration = 'manual';\r\n }\r\n const normalizeParams = applyToParams.bind(null, paramValue => '' + paramValue);\r\n const encodeParams = applyToParams.bind(null, encodeParam);\r\n const decodeParams = \r\n // @ts-expect-error: intentionally avoid the type check\r\n applyToParams.bind(null, decode);\r\n function addRoute(parentOrRoute, route) {\r\n let parent;\r\n let record;\r\n if (isRouteName(parentOrRoute)) {\r\n parent = matcher.getRecordMatcher(parentOrRoute);\r\n record = route;\r\n }\r\n else {\r\n record = parentOrRoute;\r\n }\r\n return matcher.addRoute(record, parent);\r\n }\r\n function removeRoute(name) {\r\n const recordMatcher = matcher.getRecordMatcher(name);\r\n if (recordMatcher) {\r\n matcher.removeRoute(recordMatcher);\r\n }\r\n else if ((false)) {}\r\n }\r\n function getRoutes() {\r\n return matcher.getRoutes().map(routeMatcher => routeMatcher.record);\r\n }\r\n function hasRoute(name) {\r\n return !!matcher.getRecordMatcher(name);\r\n }\r\n function resolve(rawLocation, currentLocation) {\r\n // const objectLocation = routerLocationAsObject(rawLocation)\r\n // we create a copy to modify it later\r\n currentLocation = vue_router_esm_bundler_assign({}, currentLocation || currentRoute.value);\r\n if (typeof rawLocation === 'string') {\r\n const locationNormalized = parseURL(parseQuery$1, rawLocation, currentLocation.path);\r\n const matchedRoute = matcher.resolve({ path: locationNormalized.path }, currentLocation);\r\n const href = routerHistory.createHref(locationNormalized.fullPath);\r\n if ((false)) {}\r\n // locationNormalized is always a new object\r\n return vue_router_esm_bundler_assign(locationNormalized, matchedRoute, {\r\n params: decodeParams(matchedRoute.params),\r\n hash: decode(locationNormalized.hash),\r\n redirectedFrom: undefined,\r\n href,\r\n });\r\n }\r\n let matcherLocation;\r\n // path could be relative in object as well\r\n if ('path' in rawLocation) {\r\n if (false) {}\r\n matcherLocation = vue_router_esm_bundler_assign({}, rawLocation, {\r\n path: parseURL(parseQuery$1, rawLocation.path, currentLocation.path).path,\r\n });\r\n }\r\n else {\r\n // remove any nullish param\r\n const targetParams = vue_router_esm_bundler_assign({}, rawLocation.params);\r\n for (const key in targetParams) {\r\n if (targetParams[key] == null) {\r\n delete targetParams[key];\r\n }\r\n }\r\n // pass encoded values to the matcher so it can produce encoded path and fullPath\r\n matcherLocation = vue_router_esm_bundler_assign({}, rawLocation, {\r\n params: encodeParams(rawLocation.params),\r\n });\r\n // current location params are decoded, we need to encode them in case the\r\n // matcher merges the params\r\n currentLocation.params = encodeParams(currentLocation.params);\r\n }\r\n const matchedRoute = matcher.resolve(matcherLocation, currentLocation);\r\n const hash = rawLocation.hash || '';\r\n if (false) {}\r\n // decoding them) the matcher might have merged current location params so\r\n // we need to run the decoding again\r\n matchedRoute.params = normalizeParams(decodeParams(matchedRoute.params));\r\n const fullPath = stringifyURL(stringifyQuery$1, vue_router_esm_bundler_assign({}, rawLocation, {\r\n hash: encodeHash(hash),\r\n path: matchedRoute.path,\r\n }));\r\n const href = routerHistory.createHref(fullPath);\r\n if ((false)) {}\r\n return vue_router_esm_bundler_assign({\r\n fullPath,\r\n // keep the hash encoded so fullPath is effectively path + encodedQuery +\r\n // hash\r\n hash,\r\n query: \r\n // if the user is using a custom query lib like qs, we might have\r\n // nested objects, so we keep the query as is, meaning it can contain\r\n // numbers at `$route.query`, but at the point, the user will have to\r\n // use their own type anyway.\r\n // https://github.com/vuejs/vue-router-next/issues/328#issuecomment-649481567\r\n stringifyQuery$1 === stringifyQuery\r\n ? normalizeQuery(rawLocation.query)\r\n : (rawLocation.query || {}),\r\n }, matchedRoute, {\r\n redirectedFrom: undefined,\r\n href,\r\n });\r\n }\r\n function locationAsObject(to) {\r\n return typeof to === 'string'\r\n ? parseURL(parseQuery$1, to, currentRoute.value.path)\r\n : vue_router_esm_bundler_assign({}, to);\r\n }\r\n function checkCanceledNavigation(to, from) {\r\n if (pendingLocation !== to) {\r\n return createRouterError(8 /* NAVIGATION_CANCELLED */, {\r\n from,\r\n to,\r\n });\r\n }\r\n }\r\n function push(to) {\r\n return pushWithRedirect(to);\r\n }\r\n function replace(to) {\r\n return push(vue_router_esm_bundler_assign(locationAsObject(to), { replace: true }));\r\n }\r\n function handleRedirectRecord(to) {\r\n const lastMatched = to.matched[to.matched.length - 1];\r\n if (lastMatched && lastMatched.redirect) {\r\n const { redirect } = lastMatched;\r\n let newTargetLocation = typeof redirect === 'function' ? redirect(to) : redirect;\r\n if (typeof newTargetLocation === 'string') {\r\n newTargetLocation =\r\n newTargetLocation.includes('?') || newTargetLocation.includes('#')\r\n ? (newTargetLocation = locationAsObject(newTargetLocation))\r\n : // force empty params\r\n { path: newTargetLocation };\r\n // @ts-expect-error: force empty params when a string is passed to let\r\n // the router parse them again\r\n newTargetLocation.params = {};\r\n }\r\n if (false) {}\r\n return vue_router_esm_bundler_assign({\r\n query: to.query,\r\n hash: to.hash,\r\n params: to.params,\r\n }, newTargetLocation);\r\n }\r\n }\r\n function pushWithRedirect(to, redirectedFrom) {\r\n const targetLocation = (pendingLocation = resolve(to));\r\n const from = currentRoute.value;\r\n const data = to.state;\r\n const force = to.force;\r\n // to could be a string where `replace` is a function\r\n const replace = to.replace === true;\r\n const shouldRedirect = handleRedirectRecord(targetLocation);\r\n if (shouldRedirect)\r\n return pushWithRedirect(vue_router_esm_bundler_assign(locationAsObject(shouldRedirect), {\r\n state: data,\r\n force,\r\n replace,\r\n }), \r\n // keep original redirectedFrom if it exists\r\n redirectedFrom || targetLocation);\r\n // if it was a redirect we already called `pushWithRedirect` above\r\n const toLocation = targetLocation;\r\n toLocation.redirectedFrom = redirectedFrom;\r\n let failure;\r\n if (!force && isSameRouteLocation(stringifyQuery$1, from, targetLocation)) {\r\n failure = createRouterError(16 /* NAVIGATION_DUPLICATED */, { to: toLocation, from });\r\n // trigger scroll to allow scrolling to the same anchor\r\n handleScroll(from, from, \r\n // this is a push, the only way for it to be triggered from a\r\n // history.listen is with a redirect, which makes it become a push\r\n true, \r\n // This cannot be the first navigation because the initial location\r\n // cannot be manually navigated to\r\n false);\r\n }\r\n return (failure ? Promise.resolve(failure) : navigate(toLocation, from))\r\n .catch((error) => isNavigationFailure(error)\r\n ? error\r\n : // reject any unknown error\r\n triggerError(error, toLocation, from))\r\n .then((failure) => {\r\n if (failure) {\r\n if (isNavigationFailure(failure, 2 /* NAVIGATION_GUARD_REDIRECT */)) {\r\n if (false) {}\r\n return pushWithRedirect(\r\n // keep options\r\n vue_router_esm_bundler_assign(locationAsObject(failure.to), {\r\n state: data,\r\n force,\r\n replace,\r\n }), \r\n // preserve the original redirectedFrom if any\r\n redirectedFrom || toLocation);\r\n }\r\n }\r\n else {\r\n // if we fail we don't finalize the navigation\r\n failure = finalizeNavigation(toLocation, from, true, replace, data);\r\n }\r\n triggerAfterEach(toLocation, from, failure);\r\n return failure;\r\n });\r\n }\r\n /**\r\n * Helper to reject and skip all navigation guards if a new navigation happened\r\n * @param to\r\n * @param from\r\n */\r\n function checkCanceledNavigationAndReject(to, from) {\r\n const error = checkCanceledNavigation(to, from);\r\n return error ? Promise.reject(error) : Promise.resolve();\r\n }\r\n // TODO: refactor the whole before guards by internally using router.beforeEach\r\n function navigate(to, from) {\r\n let guards;\r\n const [leavingRecords, updatingRecords, enteringRecords] = extractChangingRecords(to, from);\r\n // all components here have been resolved once because we are leaving\r\n guards = extractComponentsGuards(leavingRecords.reverse(), 'beforeRouteLeave', to, from);\r\n // leavingRecords is already reversed\r\n for (const record of leavingRecords) {\r\n record.leaveGuards.forEach(guard => {\r\n guards.push(guardToPromiseFn(guard, to, from));\r\n });\r\n }\r\n const canceledNavigationCheck = checkCanceledNavigationAndReject.bind(null, to, from);\r\n guards.push(canceledNavigationCheck);\r\n // run the queue of per route beforeRouteLeave guards\r\n return (runGuardQueue(guards)\r\n .then(() => {\r\n // check global guards beforeEach\r\n guards = [];\r\n for (const guard of beforeGuards.list()) {\r\n guards.push(guardToPromiseFn(guard, to, from));\r\n }\r\n guards.push(canceledNavigationCheck);\r\n return runGuardQueue(guards);\r\n })\r\n .then(() => {\r\n // check in components beforeRouteUpdate\r\n guards = extractComponentsGuards(updatingRecords, 'beforeRouteUpdate', to, from);\r\n for (const record of updatingRecords) {\r\n record.updateGuards.forEach(guard => {\r\n guards.push(guardToPromiseFn(guard, to, from));\r\n });\r\n }\r\n guards.push(canceledNavigationCheck);\r\n // run the queue of per route beforeEnter guards\r\n return runGuardQueue(guards);\r\n })\r\n .then(() => {\r\n // check the route beforeEnter\r\n guards = [];\r\n for (const record of to.matched) {\r\n // do not trigger beforeEnter on reused views\r\n if (record.beforeEnter && !from.matched.includes(record)) {\r\n if (Array.isArray(record.beforeEnter)) {\r\n for (const beforeEnter of record.beforeEnter)\r\n guards.push(guardToPromiseFn(beforeEnter, to, from));\r\n }\r\n else {\r\n guards.push(guardToPromiseFn(record.beforeEnter, to, from));\r\n }\r\n }\r\n }\r\n guards.push(canceledNavigationCheck);\r\n // run the queue of per route beforeEnter guards\r\n return runGuardQueue(guards);\r\n })\r\n .then(() => {\r\n // NOTE: at this point to.matched is normalized and does not contain any () => Promise\r\n // clear existing enterCallbacks, these are added by extractComponentsGuards\r\n to.matched.forEach(record => (record.enterCallbacks = {}));\r\n // check in-component beforeRouteEnter\r\n guards = extractComponentsGuards(enteringRecords, 'beforeRouteEnter', to, from);\r\n guards.push(canceledNavigationCheck);\r\n // run the queue of per route beforeEnter guards\r\n return runGuardQueue(guards);\r\n })\r\n .then(() => {\r\n // check global guards beforeResolve\r\n guards = [];\r\n for (const guard of beforeResolveGuards.list()) {\r\n guards.push(guardToPromiseFn(guard, to, from));\r\n }\r\n guards.push(canceledNavigationCheck);\r\n return runGuardQueue(guards);\r\n })\r\n // catch any navigation canceled\r\n .catch(err => isNavigationFailure(err, 8 /* NAVIGATION_CANCELLED */)\r\n ? err\r\n : Promise.reject(err)));\r\n }\r\n function triggerAfterEach(to, from, failure) {\r\n // navigation is confirmed, call afterGuards\r\n // TODO: wrap with error handlers\r\n for (const guard of afterGuards.list())\r\n guard(to, from, failure);\r\n }\r\n /**\r\n * - Cleans up any navigation guards\r\n * - Changes the url if necessary\r\n * - Calls the scrollBehavior\r\n */\r\n function finalizeNavigation(toLocation, from, isPush, replace, data) {\r\n // a more recent navigation took place\r\n const error = checkCanceledNavigation(toLocation, from);\r\n if (error)\r\n return error;\r\n // only consider as push if it's not the first navigation\r\n const isFirstNavigation = from === START_LOCATION_NORMALIZED;\r\n const state = !isBrowser ? {} : history.state;\r\n // change URL only if the user did a push/replace and if it's not the initial navigation because\r\n // it's just reflecting the url\r\n if (isPush) {\r\n // on the initial navigation, we want to reuse the scroll position from\r\n // history state if it exists\r\n if (replace || isFirstNavigation)\r\n routerHistory.replace(toLocation.fullPath, vue_router_esm_bundler_assign({\r\n scroll: isFirstNavigation && state && state.scroll,\r\n }, data));\r\n else\r\n routerHistory.push(toLocation.fullPath, data);\r\n }\r\n // accept current navigation\r\n currentRoute.value = toLocation;\r\n handleScroll(toLocation, from, isPush, isFirstNavigation);\r\n markAsReady();\r\n }\r\n let removeHistoryListener;\r\n // attach listener to history to trigger navigations\r\n function setupListeners() {\r\n removeHistoryListener = routerHistory.listen((to, _from, info) => {\r\n // cannot be a redirect route because it was in history\r\n const toLocation = resolve(to);\r\n // due to dynamic routing, and to hash history with manual navigation\r\n // (manually changing the url or calling history.hash = '#/somewhere'),\r\n // there could be a redirect record in history\r\n const shouldRedirect = handleRedirectRecord(toLocation);\r\n if (shouldRedirect) {\r\n pushWithRedirect(vue_router_esm_bundler_assign(shouldRedirect, { replace: true }), toLocation).catch(noop);\r\n return;\r\n }\r\n pendingLocation = toLocation;\r\n const from = currentRoute.value;\r\n // TODO: should be moved to web history?\r\n if (isBrowser) {\r\n saveScrollPosition(getScrollKey(from.fullPath, info.delta), computeScrollPosition());\r\n }\r\n navigate(toLocation, from)\r\n .catch((error) => {\r\n if (isNavigationFailure(error, 4 /* NAVIGATION_ABORTED */ | 8 /* NAVIGATION_CANCELLED */)) {\r\n return error;\r\n }\r\n if (isNavigationFailure(error, 2 /* NAVIGATION_GUARD_REDIRECT */)) {\r\n // Here we could call if (info.delta) routerHistory.go(-info.delta,\r\n // false) but this is bug prone as we have no way to wait the\r\n // navigation to be finished before calling pushWithRedirect. Using\r\n // a setTimeout of 16ms seems to work but there is not guarantee for\r\n // it to work on every browser. So Instead we do not restore the\r\n // history entry and trigger a new navigation as requested by the\r\n // navigation guard.\r\n // the error is already handled by router.push we just want to avoid\r\n // logging the error\r\n pushWithRedirect(error.to, toLocation\r\n // avoid an uncaught rejection, let push call triggerError\r\n )\r\n .then(failure => {\r\n // manual change in hash history #916 ending up in the URL not\r\n // changing but it was changed by the manual url change, so we\r\n // need to manually change it ourselves\r\n if (isNavigationFailure(failure, 4 /* NAVIGATION_ABORTED */ |\r\n 16 /* NAVIGATION_DUPLICATED */) &&\r\n !info.delta &&\r\n info.type === NavigationType.pop) {\r\n routerHistory.go(-1, false);\r\n }\r\n })\r\n .catch(noop);\r\n // avoid the then branch\r\n return Promise.reject();\r\n }\r\n // do not restore history on unknown direction\r\n if (info.delta)\r\n routerHistory.go(-info.delta, false);\r\n // unrecognized error, transfer to the global handler\r\n return triggerError(error, toLocation, from);\r\n })\r\n .then((failure) => {\r\n failure =\r\n failure ||\r\n finalizeNavigation(\r\n // after navigation, all matched components are resolved\r\n toLocation, from, false);\r\n // revert the navigation\r\n if (failure) {\r\n if (info.delta) {\r\n routerHistory.go(-info.delta, false);\r\n }\r\n else if (info.type === NavigationType.pop &&\r\n isNavigationFailure(failure, 4 /* NAVIGATION_ABORTED */ | 16 /* NAVIGATION_DUPLICATED */)) {\r\n // manual change in hash history #916\r\n // it's like a push but lacks the information of the direction\r\n routerHistory.go(-1, false);\r\n }\r\n }\r\n triggerAfterEach(toLocation, from, failure);\r\n })\r\n .catch(noop);\r\n });\r\n }\r\n // Initialization and Errors\r\n let readyHandlers = useCallbacks();\r\n let errorHandlers = useCallbacks();\r\n let ready;\r\n /**\r\n * Trigger errorHandlers added via onError and throws the error as well\r\n *\r\n * @param error - error to throw\r\n * @param to - location we were navigating to when the error happened\r\n * @param from - location we were navigating from when the error happened\r\n * @returns the error as a rejected promise\r\n */\r\n function triggerError(error, to, from) {\r\n markAsReady(error);\r\n const list = errorHandlers.list();\r\n if (list.length) {\r\n list.forEach(handler => handler(error, to, from));\r\n }\r\n else {\r\n if ((false)) {}\r\n console.error(error);\r\n }\r\n return Promise.reject(error);\r\n }\r\n function isReady() {\r\n if (ready && currentRoute.value !== START_LOCATION_NORMALIZED)\r\n return Promise.resolve();\r\n return new Promise((resolve, reject) => {\r\n readyHandlers.add([resolve, reject]);\r\n });\r\n }\r\n /**\r\n * Mark the router as ready, resolving the promised returned by isReady(). Can\r\n * only be called once, otherwise does nothing.\r\n * @param err - optional error\r\n */\r\n function markAsReady(err) {\r\n if (ready)\r\n return;\r\n ready = true;\r\n setupListeners();\r\n readyHandlers\r\n .list()\r\n .forEach(([resolve, reject]) => (err ? reject(err) : resolve()));\r\n readyHandlers.reset();\r\n }\r\n // Scroll behavior\r\n function handleScroll(to, from, isPush, isFirstNavigation) {\r\n const { scrollBehavior } = options;\r\n if (!isBrowser || !scrollBehavior)\r\n return Promise.resolve();\r\n const scrollPosition = (!isPush && getSavedScrollPosition(getScrollKey(to.fullPath, 0))) ||\r\n ((isFirstNavigation || !isPush) &&\r\n history.state &&\r\n history.state.scroll) ||\r\n null;\r\n return (0,vue_esm_bundler/* nextTick */.Y3)()\r\n .then(() => scrollBehavior(to, from, scrollPosition))\r\n .then(position => position && scrollToPosition(position))\r\n .catch(err => triggerError(err, to, from));\r\n }\r\n const go = (delta) => routerHistory.go(delta);\r\n let started;\r\n const installedApps = new Set();\r\n const router = {\r\n currentRoute,\r\n addRoute,\r\n removeRoute,\r\n hasRoute,\r\n getRoutes,\r\n resolve,\r\n options,\r\n push,\r\n replace,\r\n go,\r\n back: () => go(-1),\r\n forward: () => go(1),\r\n beforeEach: beforeGuards.add,\r\n beforeResolve: beforeResolveGuards.add,\r\n afterEach: afterGuards.add,\r\n onError: errorHandlers.add,\r\n isReady,\r\n install(app) {\r\n const router = this;\r\n app.component('RouterLink', RouterLink);\r\n app.component('RouterView', RouterView);\r\n app.config.globalProperties.$router = router;\r\n Object.defineProperty(app.config.globalProperties, '$route', {\r\n enumerable: true,\r\n get: () => (0,vue_esm_bundler/* unref */.SU)(currentRoute),\r\n });\r\n // this initial navigation is only necessary on client, on server it doesn't\r\n // make sense because it will create an extra unnecessary navigation and could\r\n // lead to problems\r\n if (isBrowser &&\r\n // used for the initial navigation client side to avoid pushing\r\n // multiple times when the router is used in multiple apps\r\n !started &&\r\n currentRoute.value === START_LOCATION_NORMALIZED) {\r\n // see above\r\n started = true;\r\n push(routerHistory.location).catch(err => {\r\n if ((false))\r\n {}\r\n });\r\n }\r\n const reactiveRoute = {};\r\n for (const key in START_LOCATION_NORMALIZED) {\r\n // @ts-expect-error: the key matches\r\n reactiveRoute[key] = (0,vue_esm_bundler/* computed */.Fl)(() => currentRoute.value[key]);\r\n }\r\n app.provide(routerKey, router);\r\n app.provide(routeLocationKey, (0,vue_esm_bundler/* reactive */.qj)(reactiveRoute));\r\n app.provide(routerViewLocationKey, currentRoute);\r\n const unmountApp = app.unmount;\r\n installedApps.add(app);\r\n app.unmount = function () {\r\n installedApps.delete(app);\r\n // the router is not attached to an app anymore\r\n if (installedApps.size < 1) {\r\n // invalidate the current navigation\r\n pendingLocation = START_LOCATION_NORMALIZED;\r\n removeHistoryListener && removeHistoryListener();\r\n currentRoute.value = START_LOCATION_NORMALIZED;\r\n started = false;\r\n ready = false;\r\n }\r\n unmountApp();\r\n };\r\n if (false) {}\r\n },\r\n };\r\n return router;\r\n}\r\nfunction runGuardQueue(guards) {\r\n return guards.reduce((promise, guard) => promise.then(() => guard()), Promise.resolve());\r\n}\r\nfunction extractChangingRecords(to, from) {\r\n const leavingRecords = [];\r\n const updatingRecords = [];\r\n const enteringRecords = [];\r\n const len = Math.max(from.matched.length, to.matched.length);\r\n for (let i = 0; i < len; i++) {\r\n const recordFrom = from.matched[i];\r\n if (recordFrom) {\r\n if (to.matched.find(record => isSameRouteRecord(record, recordFrom)))\r\n updatingRecords.push(recordFrom);\r\n else\r\n leavingRecords.push(recordFrom);\r\n }\r\n const recordTo = to.matched[i];\r\n if (recordTo) {\r\n // the type doesn't matter because we are comparing per reference\r\n if (!from.matched.find(record => isSameRouteRecord(record, recordTo))) {\r\n enteringRecords.push(recordTo);\r\n }\r\n }\r\n }\r\n return [leavingRecords, updatingRecords, enteringRecords];\r\n}\n\n/**\r\n * Returns the router instance. Equivalent to using `$router` inside\r\n * templates.\r\n */\r\nfunction useRouter() {\r\n return inject(routerKey);\r\n}\r\n/**\r\n * Returns the current route location. Equivalent to using `$route` inside\r\n * templates.\r\n */\r\nfunction useRoute() {\r\n return inject(routeLocationKey);\r\n}\n\n\n\n;// CONCATENATED MODULE: ./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[1]!./node_modules/vue-loader/dist/index.js??ruleSet[1].rules[6].use[0]!./interface/html5/components/LegacyView.vue?vue&type=template&id=374ba4a8\n\n\nconst _hoisted_1 = {\n id: \"contentContainer\",\n class: \"content-container\"\n}\nconst _hoisted_2 = /*#__PURE__*/(0,vue_esm_bundler/* createElementVNode */._)(\"div\", { class: \"loading-view\" }, [\n /*#__PURE__*/(0,vue_esm_bundler/* createElementVNode */._)(\"div\", { class: \"progress-bar-div\" }, [\n /*#__PURE__*/(0,vue_esm_bundler/* createElementVNode */._)(\"progress\", {\n class: \"progress-bar\",\n max: \"100\",\n value: \"10\"\n }, [\n /*#__PURE__*/(0,vue_esm_bundler/* createElementVNode */._)(\"strong\", null, \"Progress: 100% Complete.\")\n ]),\n /*#__PURE__*/(0,vue_esm_bundler/* createElementVNode */._)(\"span\", { class: \"progress-label\" }, \"Initializing...\")\n ])\n], -1 /* HOISTED */)\nconst _hoisted_3 = [\n _hoisted_2\n]\n\nfunction render(_ctx, _cache, $props, $setup, $data, $options) {\n return ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"div\", _hoisted_1, _hoisted_3))\n}\n;// CONCATENATED MODULE: ./interface/html5/components/LegacyView.vue?vue&type=template&id=374ba4a8\n\n;// CONCATENATED MODULE: ./node_modules/vue-loader/dist/index.js??ruleSet[1].rules[6].use[0]!./interface/html5/components/LegacyView.vue?vue&type=script&lang=js\n\n\n/* harmony default export */ const LegacyViewvue_type_script_lang_js = ({\n name: \"LegacyView\",\n components: {}\n});\n\n;// CONCATENATED MODULE: ./interface/html5/components/LegacyView.vue?vue&type=script&lang=js\n \n// EXTERNAL MODULE: ./node_modules/vue-loader/dist/exportHelper.js\nvar exportHelper = __webpack_require__(3744);\n;// CONCATENATED MODULE: ./interface/html5/components/LegacyView.vue\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,exportHelper/* default */.Z)(LegacyViewvue_type_script_lang_js, [['render',render]])\n\n/* harmony default export */ const LegacyView = (__exports__);\n;// CONCATENATED MODULE: ./interface/html5/components/main_ui_router.js\n// import { createRouter, createWebHistory } from 'vue-router'\n\n\n\n// import ReportView from '@/components/ReportView';\n\nconst lazy_load_test = () => __webpack_require__.e(/* import() | dynamic-testview */ \"dynamic-testview\").then(__webpack_require__.bind(__webpack_require__, 1136)); // #VUETEST\n\n// Can also import this from another file.\nconst routes = [\n\t{ path: '/test', name: 'test', component: lazy_load_test, props:true }, // #VUETEST Lazy loaded, so not loaded normally. Only when used with `VueRouter.push('test')` or via dev tools.\n\t// { path: '/view/:viewId', name: 'view', component: LegacyView, props:true },\n\t// { path: '/report/:viewId', name: 'report', component: ReportView, props:true },\n\t// { path: '/report/:reportId', name: 'report', component: LegacyView },\n\t// { path: '/wizard/:wizardId', name: 'wizard', component: LegacyView },\n\t{ path: '/:pathMatch(.*)*', name: 'catch-all', component: LegacyView },\n\t// { path: '/#!m=Login', name: 'not-found', component: LegacyView },\n\t// { path: '/#!m=:viewId&*:restOf(.*)', name: 'not-found', component: LegacyView },\n\n];\n\nconst main_ui_router = createRouter({\n\t// history: createWebHistory(),\n\thistory: createMemoryHistory(),\n\troutes,\n});\n\n/* harmony default export */ const components_main_ui_router = (main_ui_router);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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Q0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsS0FBeUQ7QUFDakUsUUFBUSxFQUNvRDtBQUM1RDtBQUNBO0FBQ0E7QUFDQSx5QkFBeUIsc0NBQVU7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLEtBQXFDLEdBQUcsRUFFakQ7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBCQUEwQiw2QkFB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YztlQUNyQiw4Q0FLTSxTQUxELEtBQUssRUFBQyxrQkFBa0I7aUJBQ3pCLDhDQUVXO01BRkQsS0FBSyxFQUFDLGNBQWM7TUFBQyxHQUFHLEVBQUMsS0FBSztNQUFDLEtBQUssRUFBQyxJQUFJOzttQkFDL0MsOENBQXlDLGdCQUFqQywwQkFBd0I7O2lCQUVwQyw4Q0FBbUQsVUFBN0MsS0FBSyxFQUFDLGdCQUFnQixJQUFDLGlCQUFlOzs7O0VBTHBELFVBT007Ozs7bURBUlYsK0NBU00sT0FUTixVQVNNOzs7Ozs7O0FBS1Ysd0VBQWU7SUFDWCxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbEIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7QUFDakIsQ0FBQyxFQUFDOzs7QUVsQjhJLEM7Ozs7QUNBekU7QUFDVjtBQUNMOztBQUV4RCxDQUFxRztBQUNyRyxpQ0FBaUMsK0JBQWUsQ0FBQyxpQ0FBTSxhQUFhLE1BQU07O0FBRTFFLGlEQUFlOztBQ1BmLFlBQVksaUNBQWlDO0FBQ2lCOztBQUViO0FBQ2pEOztBQUVBLDZCQUE2QixxSUFBMkUsRUFBRTs7QUFFMUc7QUFDQTtBQUNBLEdBQUcsb0VBQW9FO0FBQ3ZFLE1BQU0sd0VBQXdFO0FBQzlFLE1BQU0sNEVBQTRFO0FBQ2xGLE1BQU0sa0VBQWtFO0FBQ3hFLE1BQU0sa0VBQWtFO0FBQ3hFLEdBQUcsd0RBQXdELFVBQVUsRUFBRTtBQUN2RSxNQUFNLDhEQUE4RDtBQUNwRSxNQUFNLDZFQUE2RTs7QUFFbkY7O0FBRUEsdUJBQXVCLFlBQVk7QUFDbkM7QUFDQSxVQUFVLG1CQUFtQjtBQUM3QjtBQUNBLENBQUM7O0FBRUQsZ0VBQWUsY0FBYyxFQUFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL3Z1ZS1yb3V0ZXIvZGlzdC92dWUtcm91dGVyLmVzbS1idW5kbGVyLmpzPzZjMDIiLCJ3ZWJwYWNrOi8vLy4vaW50ZXJmYWNlL2h0bWw1L2NvbXBvbmVudHMvTGVnYWN5Vmlldy52dWU/ZjNkOSIsIndlYnBhY2s6Ly8vLi9pbnRlcmZhY2UvaHRtbDUvY29tcG9uZW50cy9MZWdhY3lWaWV3LnZ1ZT80M2M0Iiwid2VicGFjazovLy8uL2ludGVyZmFjZS9odG1sNS9jb21wb25lbnRzL0xlZ2FjeVZpZXcudnVlPzg0NzciLCJ3ZWJwYWNrOi8vLy4vaW50ZXJmYWNlL2h0bWw1L2NvbXBvbmVudHMvTGVnYWN5Vmlldy52dWU/MzgyNSIsIndlYnBhY2s6Ly8vLi9pbnRlcmZhY2UvaHRtbDUvY29tcG9uZW50cy9tYWluX3VpX3JvdXRlci5qcz81MmU0Il0sInNvdXJjZXNDb250ZW50IjpbIi8qIVxuICAqIHZ1ZS1yb3V0ZXIgdjQuMC4xMlxuICAqIChjKSAyMDIxIEVkdWFyZG8gU2FuIE1hcnRpbiBNb3JvdGVcbiAgKiBAbGljZW5zZSBNSVRcbiAgKi9cbmltcG9ydCB7IGdldEN1cnJlbnRJbnN0YW5jZSwgaW5qZWN0LCBvblVubW91bnRlZCwgb25EZWFjdGl2YXRlZCwgb25BY3RpdmF0ZWQsIGNvbXB1dGVkLCB1bnJlZiwgd2F0Y2hFZmZlY3QsIGRlZmluZUNvbXBvbmVudCwgcmVhY3RpdmUsIGgsIHByb3ZpZGUsIHJlZiwgd2F0Y2gsIHNoYWxsb3dSZWYsIG5leHRUaWNrIH0gZnJvbSAndnVlJztcbmltcG9ydCB7IHNldHVwRGV2dG9vbHNQbHVnaW4gfSBmcm9tICdAdnVlL2RldnRvb2xzLWFwaSc7XG5cbmNvbnN0IGhhc1N5bWJvbCA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIFN5bWJvbC50b1N0cmluZ1RhZyA9PT0gJ3N5bWJvbCc7XHJcbmNvbnN0IFBvbHlTeW1ib2wgPSAobmFtZSkgPT4gXHJcbi8vIHZyID0gdnVlIHJvdXRlclxyXG5oYXNTeW1ib2xcclxuICAgID8gU3ltYm9sKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSA/ICdbdnVlLXJvdXRlcl06ICcgKyBuYW1lIDogbmFtZSlcclxuICAgIDogKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSA/ICdbdnVlLXJvdXRlcl06ICcgOiAnX3ZyXycpICsgbmFtZTtcclxuLy8gcnZsbSA9IFJvdXRlciBWaWV3IExvY2F0aW9uIE1hdGNoZWRcclxuLyoqXHJcbiAqIFJvdXRlUmVjb3JkIGJlaW5nIHJlbmRlcmVkIGJ5IHRoZSBjbG9zZXN0IGFuY2VzdG9yIFJvdXRlciBWaWV3LiBVc2VkIGZvclxyXG4gKiBgb25CZWZvcmVSb3V0ZVVwZGF0ZWAgYW5kIGBvbkJlZm9yZVJvdXRlTGVhdmVgLiBydmxtIHN0YW5kcyBmb3IgUm91dGVyIFZpZXdcclxuICogTG9jYXRpb24gTWF0Y2hlZFxyXG4gKlxyXG4gKiBAaW50ZXJuYWxcclxuICovXHJcbmNvbnN0IG1hdGNoZWRSb3V0ZUtleSA9IC8qI19fUFVSRV9fKi8gUG9seVN5bWJvbCgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgPyAncm91dGVyIHZpZXcgbG9jYXRpb24gbWF0Y2hlZCcgOiAncnZsbScpO1xyXG4vKipcclxuICogQWxsb3dzIG92ZXJyaWRpbmcgdGhlIHJvdXRlciB2aWV3IGRlcHRoIHRvIGNvbnRyb2wgd2hpY2ggY29tcG9uZW50IGluXHJcbiAqIGBtYXRjaGVkYCBpcyByZW5kZXJlZC4gcnZkIHN0YW5kcyBmb3IgUm91dGVyIFZpZXcgRGVwdGhcclxuICpcclxuICogQGludGVybmFsXHJcbiAqL1xyXG5jb25zdCB2aWV3RGVwdGhLZXkgPSAvKiNfX1BVUkVfXyovIFBvbHlTeW1ib2woKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpID8gJ3JvdXRlciB2aWV3IGRlcHRoJyA6ICdydmQnKTtcclxuLyoqXHJcbiAqIEFsbG93cyBvdmVycmlkaW5nIHRoZSByb3V0ZXIgaW5zdGFuY2UgcmV0dXJuZWQgYnkgYHVzZVJvdXRlcmAgaW4gdGVzdHMuIHJcclxuICogc3RhbmRzIGZvciByb3V0ZXJcclxuICpcclxuICogQGludGVybmFsXHJcbiAqL1xyXG5jb25zdCByb3V0ZXJLZXkgPSAvKiNfX1BVUkVfXyovIFBvbHlTeW1ib2woKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpID8gJ3JvdXRlcicgOiAncicpO1xyXG4vKipcclxuICogQWxsb3dzIG92ZXJyaWRpbmcgdGhlIGN1cnJlbnQgcm91dGUgcmV0dXJuZWQgYnkgYHVzZVJvdXRlYCBpbiB0ZXN0cy4gcmxcclxuICogc3RhbmRzIGZvciByb3V0ZSBsb2NhdGlvblxyXG4gKlxyXG4gKiBAaW50ZXJuYWxcclxuICovXHJcbmNvbnN0IHJvdXRlTG9jYXRpb25LZXkgPSAvKiNfX1BVUkVfXyovIFBvbHlTeW1ib2woKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpID8gJ3JvdXRlIGxvY2F0aW9uJyA6ICdybCcpO1xyXG4vKipcclxuICogQWxsb3dzIG92ZXJyaWRpbmcgdGhlIGN1cnJlbnQgcm91dGUgdXNlZCBieSByb3V0ZXItdmlldy4gSW50ZXJuYWxseSB0aGlzIGlzXHJcbiAqIHVzZWQgd2hlbiB0aGUgYHJvdXRlYCBwcm9wIGlzIHBhc3NlZC5cclxuICpcclxuICogQGludGVybmFsXHJcbiAqL1xyXG5jb25zdCByb3V0ZXJWaWV3TG9jYXRpb25LZXkgPSAvKiNfX1BVUkVfXyovIFBvbHlTeW1ib2woKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpID8gJ3JvdXRlciB2aWV3IGxvY2F0aW9uJyA6ICdydmwnKTtcblxuY29uc3QgaXNCcm93c2VyID0gdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCc7XG5cbmZ1bmN0aW9uIGlzRVNNb2R1bGUob2JqKSB7XHJcbiAgICByZXR1cm4gb2JqLl9fZXNNb2R1bGUgfHwgKGhhc1N5bWJvbCAmJiBvYmpbU3ltYm9sLnRvU3RyaW5nVGFnXSA9PT0gJ01vZHVsZScpO1xyXG59XHJcbmNvbnN0IGFzc2lnbiA9IE9iamVjdC5hc3NpZ247XHJcbmZ1bmN0aW9uIGFwcGx5VG9QYXJhbXMoZm4sIHBhcmFtcykge1xyXG4gICAgY29uc3QgbmV3UGFyYW1zID0ge307XHJcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBwYXJhbXMpIHtcclxuICAgICAgICBjb25zdCB2YWx1ZSA9IHBhcmFtc1trZXldO1xyXG4gICAgICAgIG5ld1BhcmFtc1trZXldID0gQXJyYXkuaXNBcnJheSh2YWx1ZSkgPyB2YWx1ZS5tYXAoZm4pIDogZm4odmFsdWUpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIG5ld1BhcmFtcztcclxufVxyXG5jb25zdCBub29wID0gKCkgPT4geyB9O1xuXG5mdW5jdGlvbiB3YXJuKG1zZykge1xyXG4gICAgLy8gYXZvaWQgdXNpbmcgLi4uYXJncyBhcyBpdCBicmVha3MgaW4gb2xkZXIgRWRnZSBidWlsZHNcclxuICAgIGNvbnN0IGFyZ3MgPSBBcnJheS5mcm9tKGFyZ3VtZW50cykuc2xpY2UoMSk7XHJcbiAgICBjb25zb2xlLndhcm4uYXBwbHkoY29uc29sZSwgWydbVnVlIFJvdXRlciB3YXJuXTogJyArIG1zZ10uY29uY2F0KGFyZ3MpKTtcclxufVxuXG5jb25zdCBUUkFJTElOR19TTEFTSF9SRSA9IC9cXC8kLztcclxuY29uc3QgcmVtb3ZlVHJhaWxpbmdTbGFzaCA9IChwYXRoKSA9PiBwYXRoLnJlcGxhY2UoVFJBSUxJTkdfU0xBU0hfUkUsICcnKTtcclxuLyoqXHJcbiAqIFRyYW5zZm9ybXMgYW4gVVJJIGludG8gYSBub3JtYWxpemVkIGhpc3RvcnkgbG9jYXRpb25cclxuICpcclxuICogQHBhcmFtIHBhcnNlUXVlcnlcclxuICogQHBhcmFtIGxvY2F0aW9uIC0gVVJJIHRvIG5vcm1hbGl6ZVxyXG4gKiBAcGFyYW0gY3VycmVudExvY2F0aW9uIC0gY3VycmVudCBhYnNvbHV0ZSBsb2NhdGlvbi4gQWxsb3dzIHJlc29sdmluZyByZWxhdGl2ZVxyXG4gKiBwYXRocy4gTXVzdCBzdGFydCB3aXRoIGAvYC4gRGVmYXVsdHMgdG8gYC9gXHJcbiAqIEByZXR1cm5zIGEgbm9ybWFsaXplZCBoaXN0b3J5IGxvY2F0aW9uXHJcbiAqL1xyXG5mdW5jdGlvbiBwYXJzZVVSTChwYXJzZVF1ZXJ5LCBsb2NhdGlvbiwgY3VycmVudExvY2F0aW9uID0gJy8nKSB7XHJcbiAgICBsZXQgcGF0aCwgcXVlcnkgPSB7fSwgc2VhcmNoU3RyaW5nID0gJycsIGhhc2ggPSAnJztcclxuICAgIC8vIENvdWxkIHVzZSBVUkwgYW5kIFVSTFNlYXJjaFBhcmFtcyBidXQgSUUgMTEgZG9lc24ndCBzdXBwb3J0IGl0XHJcbiAgICBjb25zdCBzZWFyY2hQb3MgPSBsb2NhdGlvbi5pbmRleE9mKCc/Jyk7XHJcbiAgICBjb25zdCBoYXNoUG9zID0gbG9jYXRpb24uaW5kZXhPZignIycsIHNlYXJjaFBvcyA+IC0xID8gc2VhcmNoUG9zIDogMCk7XHJcbiAgICBpZiAoc2VhcmNoUG9zID4gLTEpIHtcclxuICAgICAgICBwYXRoID0gbG9jYXRpb24uc2xpY2UoMCwgc2VhcmNoUG9zKTtcclxuICAgICAgICBzZWFyY2hTdHJpbmcgPSBsb2NhdGlvbi5zbGljZShzZWFyY2hQb3MgKyAxLCBoYXNoUG9zID4gLTEgPyBoYXNoUG9zIDogbG9jYXRpb24ubGVuZ3RoKTtcclxuICAgICAgICBxdWVyeSA9IHBhcnNlUXVlcnkoc2VhcmNoU3RyaW5nKTtcclxuICAgIH1cclxuICAgIGlmIChoYXNoUG9zID4gLTEpIHtcclxuICAgICAgICBwYXRoID0gcGF0aCB8fCBsb2NhdGlvbi5zbGljZSgwLCBoYXNoUG9zKTtcclxuICAgICAgICAvLyBrZWVwIHRoZSAjIGNoYXJhY3RlclxyXG4gICAgICAgIGhhc2ggPSBsb2NhdGlvbi5zbGljZShoYXNoUG9zLCBsb2NhdGlvbi5sZW5ndGgpO1xyXG4gICAgfVxyXG4gICAgLy8gbm8gc2VhcmNoIGFuZCBubyBxdWVyeVxyXG4gICAgcGF0aCA9IHJlc29sdmVSZWxhdGl2ZVBhdGgocGF0aCAhPSBudWxsID8gcGF0aCA6IGxvY2F0aW9uLCBjdXJyZW50TG9jYXRpb24pO1xyXG4gICAgLy8gZW1wdHkgcGF0aCBtZWFucyBhIHJlbGF0aXZlIHF1ZXJ5IG9yIGhhc2ggYD9mb289ZmAsIGAjdGhpbmdgXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIGZ1bGxQYXRoOiBwYXRoICsgKHNlYXJjaFN0cmluZyAmJiAnPycpICsgc2VhcmNoU3RyaW5nICsgaGFzaCxcclxuICAgICAgICBwYXRoLFxyXG4gICAgICAgIHF1ZXJ5LFxyXG4gICAgICAgIGhhc2gsXHJcbiAgICB9O1xyXG59XHJcbi8qKlxyXG4gKiBTdHJpbmdpZmllcyBhIFVSTCBvYmplY3RcclxuICpcclxuICogQHBhcmFtIHN0cmluZ2lmeVF1ZXJ5XHJcbiAqIEBwYXJhbSBsb2NhdGlvblxyXG4gKi9cclxuZnVuY3Rpb24gc3RyaW5naWZ5VVJMKHN0cmluZ2lmeVF1ZXJ5LCBsb2NhdGlvbikge1xyXG4gICAgY29uc3QgcXVlcnkgPSBsb2NhdGlvbi5xdWVyeSA/IHN0cmluZ2lmeVF1ZXJ5KGxvY2F0aW9uLnF1ZXJ5KSA6ICcnO1xyXG4gICAgcmV0dXJuIGxvY2F0aW9uLnBhdGggKyAocXVlcnkgJiYgJz8nKSArIHF1ZXJ5ICsgKGxvY2F0aW9uLmhhc2ggfHwgJycpO1xyXG59XHJcbi8qKlxyXG4gKiBTdHJpcHMgb2ZmIHRoZSBiYXNlIGZyb20gdGhlIGJlZ2lubmluZyBvZiBhIGxvY2F0aW9uLnBhdGhuYW1lIGluIGEgbm9uXHJcbiAqIGNhc2Utc2Vuc2l0aXZlIHdheS5cclxuICpcclxuICogQHBhcmFtIHBhdGhuYW1lIC0gbG9jYXRpb24ucGF0aG5hbWVcclxuICogQHBhcmFtIGJhc2UgLSBiYXNlIHRvIHN0cmlwIG9mZlxyXG4gKi9cclxuZnVuY3Rpb24gc3RyaXBCYXNlKHBhdGhuYW1lLCBiYXNlKSB7XHJcbiAgICAvLyBubyBiYXNlIG9yIGJhc2UgaXMgbm90IGZvdW5kIGF0IHRoZSBiZWdpbm5pbmdcclxuICAgIGlmICghYmFzZSB8fCAhcGF0aG5hbWUudG9Mb3dlckNhc2UoKS5zdGFydHNXaXRoKGJhc2UudG9Mb3dlckNhc2UoKSkpXHJcbiAgICAgICAgcmV0dXJuIHBhdGhuYW1lO1xyXG4gICAgcmV0dXJuIHBhdGhuYW1lLnNsaWNlKGJhc2UubGVuZ3RoKSB8fCAnLyc7XHJcbn1cclxuLyoqXHJcbiAqIENoZWNrcyBpZiB0d28gUm91dGVMb2NhdGlvbiBhcmUgZXF1YWwuIFRoaXMgbWVhbnMgdGhhdCBib3RoIGxvY2F0aW9ucyBhcmVcclxuICogcG9pbnRpbmcgdG93YXJkcyB0aGUgc2FtZSB7QGxpbmsgUm91dGVSZWNvcmR9IGFuZCB0aGF0IGFsbCBgcGFyYW1zYCwgYHF1ZXJ5YFxyXG4gKiBwYXJhbWV0ZXJzIGFuZCBgaGFzaGAgYXJlIHRoZSBzYW1lXHJcbiAqXHJcbiAqIEBwYXJhbSBhIC0gZmlyc3Qge0BsaW5rIFJvdXRlTG9jYXRpb259XHJcbiAqIEBwYXJhbSBiIC0gc2Vjb25kIHtAbGluayBSb3V0ZUxvY2F0aW9ufVxyXG4gKi9cclxuZnVuY3Rpb24gaXNTYW1lUm91dGVMb2NhdGlvbihzdHJpbmdpZnlRdWVyeSwgYSwgYikge1xyXG4gICAgY29uc3QgYUxhc3RJbmRleCA9IGEubWF0Y2hlZC5sZW5ndGggLSAxO1xyXG4gICAgY29uc3QgYkxhc3RJbmRleCA9IGIubWF0Y2hlZC5sZW5ndGggLSAxO1xyXG4gICAgcmV0dXJuIChhTGFzdEluZGV4ID4gLTEgJiZcclxuICAgICAgICBhTGFzdEluZGV4ID09PSBiTGFzdEluZGV4ICYmXHJcbiAgICAgICAgaXNTYW1lUm91dGVSZWNvcmQoYS5tYXRjaGVkW2FMYXN0SW5kZXhdLCBiLm1hdGNoZWRbYkxhc3RJbmRleF0pICYmXHJcbiAgICAgICAgaXNTYW1lUm91dGVMb2NhdGlvblBhcmFtcyhhLnBhcmFtcywgYi5wYXJhbXMpICYmXHJcbiAgICAgICAgc3RyaW5naWZ5UXVlcnkoYS5xdWVyeSkgPT09IHN0cmluZ2lmeVF1ZXJ5KGIucXVlcnkpICYmXHJcbiAgICAgICAgYS5oYXNoID09PSBiLmhhc2gpO1xyXG59XHJcbi8qKlxyXG4gKiBDaGVjayBpZiB0d28gYFJvdXRlUmVjb3Jkc2AgYXJlIGVxdWFsLiBUYWtlcyBpbnRvIGFjY291bnQgYWxpYXNlczogdGhleSBhcmVcclxuICogY29uc2lkZXJlZCBlcXVhbCB0byB0aGUgYFJvdXRlUmVjb3JkYCB0aGV5IGFyZSBhbGlhc2luZy5cclxuICpcclxuICogQHBhcmFtIGEgLSBmaXJzdCB7QGxpbmsgUm91dGVSZWNvcmR9XHJcbiAqIEBwYXJhbSBiIC0gc2Vjb25kIHtAbGluayBSb3V0ZVJlY29yZH1cclxuICovXHJcbmZ1bmN0aW9uIGlzU2FtZVJvdXRlUmVjb3JkKGEsIGIpIHtcclxuICAgIC8vIHNpbmNlIHRoZSBvcmlnaW5hbCByZWNvcmQgaGFzIGFuIHVuZGVmaW5lZCB2YWx1ZSBmb3IgYWxpYXNPZlxyXG4gICAgLy8gYnV0IGFsbCBhbGlhc2VzIHBvaW50IHRvIHRoZSBvcmlnaW5hbCByZWNvcmQsIHRoaXMgd2lsbCBhbHdheXMgY29tcGFyZVxyXG4gICAgLy8gdGhlIG9yaWdpbmFsIHJlY29yZFxyXG4gICAgcmV0dXJuIChhLmFsaWFzT2YgfHwgYSkgPT09IChiLmFsaWFzT2YgfHwgYik7XHJcbn1cclxuZnVuY3Rpb24gaXNTYW1lUm91dGVMb2NhdGlvblBhcmFtcyhhLCBiKSB7XHJcbiAgICBpZiAoT2JqZWN0LmtleXMoYSkubGVuZ3RoICE9PSBPYmplY3Qua2V5cyhiKS5sZW5ndGgpXHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgZm9yIChjb25zdCBrZXkgaW4gYSkge1xyXG4gICAgICAgIGlmICghaXNTYW1lUm91dGVMb2NhdGlvblBhcmFtc1ZhbHVlKGFba2V5XSwgYltrZXldKSlcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRydWU7XHJcbn1cclxuZnVuY3Rpb24gaXNTYW1lUm91dGVMb2NhdGlvblBhcmFtc1ZhbHVlKGEsIGIpIHtcclxuICAgIHJldHVybiBBcnJheS5pc0FycmF5KGEpXHJcbiAgICAgICAgPyBpc0VxdWl2YWxlbnRBcnJheShhLCBiKVxyXG4gICAgICAgIDogQXJyYXkuaXNBcnJheShiKVxyXG4gICAgICAgICAgICA/IGlzRXF1aXZhbGVudEFycmF5KGIsIGEpXHJcbiAgICAgICAgICAgIDogYSA9PT0gYjtcclxufVxyXG4vKipcclxuICogQ2hlY2sgaWYgdHdvIGFycmF5cyBhcmUgdGhlIHNhbWUgb3IgaWYgYW4gYXJyYXkgd2l0aCBvbmUgc2luZ2xlIGVudHJ5IGlzIHRoZVxyXG4gKiBzYW1lIGFzIGFub3RoZXIgcHJpbWl0aXZlIHZhbHVlLiBVc2VkIHRvIGNoZWNrIHF1ZXJ5IGFuZCBwYXJhbWV0ZXJzXHJcbiAqXHJcbiAqIEBwYXJhbSBhIC0gYXJyYXkgb2YgdmFsdWVzXHJcbiAqIEBwYXJhbSBiIC0gYXJyYXkgb2YgdmFsdWVzIG9yIGEgc2luZ2xlIHZhbHVlXHJcbiAqL1xyXG5mdW5jdGlvbiBpc0VxdWl2YWxlbnRBcnJheShhLCBiKSB7XHJcbiAgICByZXR1cm4gQXJyYXkuaXNBcnJheShiKVxyXG4gICAgICAgID8gYS5sZW5ndGggPT09IGIubGVuZ3RoICYmIGEuZXZlcnkoKHZhbHVlLCBpKSA9PiB2YWx1ZSA9PT0gYltpXSlcclxuICAgICAgICA6IGEubGVuZ3RoID09PSAxICYmIGFbMF0gPT09IGI7XHJcbn1cclxuLyoqXHJcbiAqIFJlc29sdmVzIGEgcmVsYXRpdmUgcGF0aCB0aGF0IHN0YXJ0cyB3aXRoIGAuYC5cclxuICpcclxuICogQHBhcmFtIHRvIC0gcGF0aCBsb2NhdGlvbiB3ZSBhcmUgcmVzb2x2aW5nXHJcbiAqIEBwYXJhbSBmcm9tIC0gY3VycmVudExvY2F0aW9uLnBhdGgsIHNob3VsZCBzdGFydCB3aXRoIGAvYFxyXG4gKi9cclxuZnVuY3Rpb24gcmVzb2x2ZVJlbGF0aXZlUGF0aCh0bywgZnJvbSkge1xyXG4gICAgaWYgKHRvLnN0YXJ0c1dpdGgoJy8nKSlcclxuICAgICAgICByZXR1cm4gdG87XHJcbiAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmICFmcm9tLnN0YXJ0c1dpdGgoJy8nKSkge1xyXG4gICAgICAgIHdhcm4oYENhbm5vdCByZXNvbHZlIGEgcmVsYXRpdmUgbG9jYXRpb24gd2l0aG91dCBhbiBhYnNvbHV0ZSBwYXRoLiBUcnlpbmcgdG8gcmVzb2x2ZSBcIiR7dG99XCIgZnJvbSBcIiR7ZnJvbX1cIi4gSXQgc2hvdWxkIGxvb2sgbGlrZSBcIi8ke2Zyb219XCIuYCk7XHJcbiAgICAgICAgcmV0dXJuIHRvO1xyXG4gICAgfVxyXG4gICAgaWYgKCF0bylcclxuICAgICAgICByZXR1cm4gZnJvbTtcclxuICAgIGNvbnN0IGZyb21TZWdtZW50cyA9IGZyb20uc3BsaXQoJy8nKTtcclxuICAgIGNvbnN0IHRvU2VnbWVudHMgPSB0by5zcGxpdCgnLycpO1xyXG4gICAgbGV0IHBvc2l0aW9uID0gZnJvbVNlZ21lbnRzLmxlbmd0aCAtIDE7XHJcbiAgICBsZXQgdG9Qb3NpdGlvbjtcclxuICAgIGxldCBzZWdtZW50O1xyXG4gICAgZm9yICh0b1Bvc2l0aW9uID0gMDsgdG9Qb3NpdGlvbiA8IHRvU2VnbWVudHMubGVuZ3RoOyB0b1Bvc2l0aW9uKyspIHtcclxuICAgICAgICBzZWdtZW50ID0gdG9TZWdtZW50c1t0b1Bvc2l0aW9uXTtcclxuICAgICAgICAvLyBjYW4ndCBnbyBiZWxvdyB6ZXJvXHJcbiAgICAgICAgaWYgKHBvc2l0aW9uID09PSAxIHx8IHNlZ21lbnQgPT09ICcuJylcclxuICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgaWYgKHNlZ21lbnQgPT09ICcuLicpXHJcbiAgICAgICAgICAgIHBvc2l0aW9uLS07XHJcbiAgICAgICAgLy8gZm91bmQgc29tZXRoaW5nIHRoYXQgaXMgbm90IHJlbGF0aXZlIHBhdGhcclxuICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIChmcm9tU2VnbWVudHMuc2xpY2UoMCwgcG9zaXRpb24pLmpvaW4oJy8nKSArXHJcbiAgICAgICAgJy8nICtcclxuICAgICAgICB0b1NlZ21lbnRzXHJcbiAgICAgICAgICAgIC5zbGljZSh0b1Bvc2l0aW9uIC0gKHRvUG9zaXRpb24gPT09IHRvU2VnbWVudHMubGVuZ3RoID8gMSA6IDApKVxyXG4gICAgICAgICAgICAuam9pbignLycpKTtcclxufVxuXG52YXIgTmF2aWdhdGlvblR5cGU7XHJcbihmdW5jdGlvbiAoTmF2aWdhdGlvblR5cGUpIHtcclxuICAgIE5hdmlnYXRpb25UeXBlW1wicG9wXCJdID0gXCJwb3BcIjtcclxuICAgIE5hdmlnYXRpb25UeXBlW1wicHVzaFwiXSA9IFwicHVzaFwiO1xyXG59KShOYXZpZ2F0aW9uVHlwZSB8fCAoTmF2aWdhdGlvblR5cGUgPSB7fSkpO1xyXG52YXIgTmF2aWdhdGlvbkRpcmVjdGlvbjtcclxuKGZ1bmN0aW9uIChOYXZpZ2F0aW9uRGlyZWN0aW9uKSB7XHJcbiAgICBOYXZpZ2F0aW9uRGlyZWN0aW9uW1wiYmFja1wiXSA9IFwiYmFja1wiO1xyXG4gICAgTmF2aWdhdGlvbkRpcmVjdGlvbltcImZvcndhcmRcIl0gPSBcImZvcndhcmRcIjtcclxuICAgIE5hdmlnYXRpb25EaXJlY3Rpb25bXCJ1bmtub3duXCJdID0gXCJcIjtcclxufSkoTmF2aWdhdGlvbkRpcmVjdGlvbiB8fCAoTmF2aWdhdGlvbkRpcmVjdGlvbiA9IHt9KSk7XHJcbi8qKlxyXG4gKiBTdGFydGluZyBsb2NhdGlvbiBmb3IgSGlzdG9yaWVzXHJcbiAqL1xyXG5jb25zdCBTVEFSVCA9ICcnO1xyXG4vLyBHZW5lcmljIHV0aWxzXHJcbi8qKlxyXG4gKiBOb3JtYWxpemVzIGEgYmFzZSBieSByZW1vdmluZyBhbnkgdHJhaWxpbmcgc2xhc2ggYW5kIHJlYWRpbmcgdGhlIGJhc2UgdGFnIGlmXHJcbiAqIHByZXNlbnQuXHJcbiAqXHJcbiAqIEBwYXJhbSBiYXNlIC0gYmFzZSB0byBub3JtYWxpemVcclxuICovXHJcbmZ1bmN0aW9uIG5vcm1hbGl6ZUJhc2UoYmFzZSkge1xyXG4gICAgaWYgKCFiYXNlKSB7XHJcbiAgICAgICAgaWYgKGlzQnJvd3Nlcikge1xyXG4gICAgICAgICAgICAvLyByZXNwZWN0IDxiYXNlPiB0YWdcclxuICAgICAgICAgICAgY29uc3QgYmFzZUVsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYmFzZScpO1xyXG4gICAgICAgICAgICBiYXNlID0gKGJhc2VFbCAmJiBiYXNlRWwuZ2V0QXR0cmlidXRlKCdocmVmJykpIHx8ICcvJztcclxuICAgICAgICAgICAgLy8gc3RyaXAgZnVsbCBVUkwgb3JpZ2luXHJcbiAgICAgICAgICAgIGJhc2UgPSBiYXNlLnJlcGxhY2UoL15cXHcrOlxcL1xcL1teXFwvXSsvLCAnJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBiYXNlID0gJy8nO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIC8vIGVuc3VyZSBsZWFkaW5nIHNsYXNoIHdoZW4gaXQgd2FzIHJlbW92ZWQgYnkgdGhlIHJlZ2V4IGFib3ZlIGF2b2lkIGxlYWRpbmdcclxuICAgIC8vIHNsYXNoIHdpdGggaGFzaCBiZWNhdXNlIHRoZSBmaWxlIGNvdWxkIGJlIHJlYWQgZnJvbSB0aGUgZGlzayBsaWtlIGZpbGU6Ly9cclxuICAgIC8vIGFuZCB0aGUgbGVhZGluZyBzbGFzaCB3b3VsZCBjYXVzZSBwcm9ibGVtc1xyXG4gICAgaWYgKGJhc2VbMF0gIT09ICcvJyAmJiBiYXNlWzBdICE9PSAnIycpXHJcbiAgICAgICAgYmFzZSA9ICcvJyArIGJhc2U7XHJcbiAgICAvLyByZW1vdmUgdGhlIHRyYWlsaW5nIHNsYXNoIHNvIGFsbCBvdGhlciBtZXRob2QgY2FuIGp1c3QgZG8gYGJhc2UgKyBmdWxsUGF0aGBcclxuICAgIC8vIHRvIGJ1aWxkIGFuIGhyZWZcclxuICAgIHJldHVybiByZW1vdmVUcmFpbGluZ1NsYXNoKGJhc2UpO1xyXG59XHJcbi8vIHJlbW92ZSBhbnkgY2hhcmFjdGVyIGJlZm9yZSB0aGUgaGFzaFxyXG5jb25zdCBCRUZPUkVfSEFTSF9SRSA9IC9eW14jXSsjLztcclxuZnVuY3Rpb24gY3JlYXRlSHJlZihiYXNlLCBsb2NhdGlvbikge1xyXG4gICAgcmV0dXJuIGJhc2UucmVwbGFjZShCRUZPUkVfSEFTSF9SRSwgJyMnKSArIGxvY2F0aW9uO1xyXG59XG5cbmZ1bmN0aW9uIGdldEVsZW1lbnRQb3NpdGlvbihlbCwgb2Zmc2V0KSB7XHJcbiAgICBjb25zdCBkb2NSZWN0ID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgY29uc3QgZWxSZWN0ID0gZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIGJlaGF2aW9yOiBvZmZzZXQuYmVoYXZpb3IsXHJcbiAgICAgICAgbGVmdDogZWxSZWN0LmxlZnQgLSBkb2NSZWN0LmxlZnQgLSAob2Zmc2V0LmxlZnQgfHwgMCksXHJcbiAgICAgICAgdG9wOiBlbFJlY3QudG9wIC0gZG9jUmVjdC50b3AgLSAob2Zmc2V0LnRvcCB8fCAwKSxcclxuICAgIH07XHJcbn1cclxuY29uc3QgY29tcHV0ZVNjcm9sbFBvc2l0aW9uID0gKCkgPT4gKHtcclxuICAgIGxlZnQ6IHdpbmRvdy5wYWdlWE9mZnNldCxcclxuICAgIHRvcDogd2luZG93LnBhZ2VZT2Zmc2V0LFxyXG59KTtcclxuZnVuY3Rpb24gc2Nyb2xsVG9Qb3NpdGlvbihwb3NpdGlvbikge1xyXG4gICAgbGV0IHNjcm9sbFRvT3B0aW9ucztcclxuICAgIGlmICgnZWwnIGluIHBvc2l0aW9uKSB7XHJcbiAgICAgICAgY29uc3QgcG9zaXRpb25FbCA9IHBvc2l0aW9uLmVsO1xyXG4gICAgICAgIGNvbnN0IGlzSWRTZWxlY3RvciA9IHR5cGVvZiBwb3NpdGlvbkVsID09PSAnc3RyaW5nJyAmJiBwb3NpdGlvbkVsLnN0YXJ0c1dpdGgoJyMnKTtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBgaWRgcyBjYW4gYWNjZXB0IHByZXR0eSBtdWNoIGFueSBjaGFyYWN0ZXJzLCBpbmNsdWRpbmcgQ1NTIGNvbWJpbmF0b3JzXHJcbiAgICAgICAgICogbGlrZSBgPmAgb3IgYH5gLiBJdCdzIHN0aWxsIHBvc3NpYmxlIHRvIHJldHJpZXZlIGVsZW1lbnRzIHVzaW5nXHJcbiAgICAgICAgICogYGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd+JylgIGJ1dCBpdCBuZWVkcyB0byBiZSBlc2NhcGVkIHdoZW4gdXNpbmdcclxuICAgICAgICAgKiBgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI1xcXFx+JylgIGZvciBpdCB0byBiZSB2YWxpZC4gVGhlIG9ubHlcclxuICAgICAgICAgKiByZXF1aXJlbWVudHMgZm9yIGBpZGBzIGFyZSB0aGVtIHRvIGJlIHVuaXF1ZSBvbiB0aGUgcGFnZSBhbmQgdG8gbm90IGJlXHJcbiAgICAgICAgICogZW1wdHkgKGBpZD1cIlwiYCkuIEJlY2F1c2Ugb2YgdGhhdCwgd2hlbiBwYXNzaW5nIGFuIGlkIHNlbGVjdG9yLCBpdCBzaG91bGRcclxuICAgICAgICAgKiBiZSBwcm9wZXJseSBlc2NhcGVkIGZvciBpdCB0byB3b3JrIHdpdGggYHF1ZXJ5U2VsZWN0b3JgLiBXZSBjb3VsZCBjaGVja1xyXG4gICAgICAgICAqIGZvciB0aGUgaWQgc2VsZWN0b3IgdG8gYmUgc2ltcGxlIChubyBDU1MgY29tYmluYXRvcnMgYCsgPn5gKSBidXQgdGhhdFxyXG4gICAgICAgICAqIHdvdWxkIG1ha2UgdGhpbmdzIGluY29uc2lzdGVudCBzaW5jZSB0aGV5IGFyZSB2YWxpZCBjaGFyYWN0ZXJzIGZvciBhblxyXG4gICAgICAgICAqIGBpZGAgYnV0IHdvdWxkIG5lZWQgdG8gYmUgZXNjYXBlZCB3aGVuIHVzaW5nIGBxdWVyeVNlbGVjdG9yYCwgYnJlYWtpbmdcclxuICAgICAgICAgKiB0aGVpciB1c2FnZSBhbmQgZW5kaW5nIHVwIGluIG5vIHNlbGVjdG9yIHJldHVybmVkLiBTZWxlY3RvcnMgbmVlZCB0byBiZVxyXG4gICAgICAgICAqIGVzY2FwZWQ6XHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiAtIGAjMS10aGluZ2AgYmVjb21lcyBgI1xcMzEgLXRoaW5nYFxyXG4gICAgICAgICAqIC0gYCN3aXRofnN5bWJvbHNgIGJlY29tZXMgYCN3aXRoXFxcXH5zeW1ib2xzYFxyXG4gICAgICAgICAqXHJcbiAgICAgICAgICogLSBNb3JlIGluZm9ybWF0aW9uIGFib3V0ICB0aGUgdG9waWMgY2FuIGJlIGZvdW5kIGF0XHJcbiAgICAgICAgICogICBodHRwczovL21hdGhpYXNieW5lbnMuYmUvbm90ZXMvaHRtbDUtaWQtY2xhc3MuXHJcbiAgICAgICAgICogLSBQcmFjdGljYWwgZXhhbXBsZTogaHR0cHM6Ly9tYXRoaWFzYnluZW5zLmJlL2RlbW8vaHRtbDUtaWRcclxuICAgICAgICAgKi9cclxuICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmIHR5cGVvZiBwb3NpdGlvbi5lbCA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgICAgICAgaWYgKCFpc0lkU2VsZWN0b3IgfHwgIWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHBvc2l0aW9uLmVsLnNsaWNlKDEpKSkge1xyXG4gICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBmb3VuZEVsID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcihwb3NpdGlvbi5lbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzSWRTZWxlY3RvciAmJiBmb3VuZEVsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHdhcm4oYFRoZSBzZWxlY3RvciBcIiR7cG9zaXRpb24uZWx9XCIgc2hvdWxkIGJlIHBhc3NlZCBhcyBcImVsOiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcke3Bvc2l0aW9uLmVsfScpXCIgYmVjYXVzZSBpdCBzdGFydHMgd2l0aCBcIiNcIi5gKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmV0dXJuIHRvIGF2b2lkIG90aGVyIHdhcm5pbmdzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgd2FybihgVGhlIHNlbGVjdG9yIFwiJHtwb3NpdGlvbi5lbH1cIiBpcyBpbnZhbGlkLiBJZiB5b3UgYXJlIHVzaW5nIGFuIGlkIHNlbGVjdG9yLCBtYWtlIHN1cmUgdG8gZXNjYXBlIGl0LiBZb3UgY2FuIGZpbmQgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBlc2NhcGluZyBjaGFyYWN0ZXJzIGluIHNlbGVjdG9ycyBhdCBodHRwczovL21hdGhpYXNieW5lbnMuYmUvbm90ZXMvY3NzLWVzY2FwZXMgb3IgdXNlIENTUy5lc2NhcGUgKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9DU1MvZXNjYXBlKS5gKTtcclxuICAgICAgICAgICAgICAgICAgICAvLyByZXR1cm4gdG8gYXZvaWQgb3RoZXIgd2FybmluZ3NcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgZWwgPSB0eXBlb2YgcG9zaXRpb25FbCA9PT0gJ3N0cmluZydcclxuICAgICAgICAgICAgPyBpc0lkU2VsZWN0b3JcclxuICAgICAgICAgICAgICAgID8gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQocG9zaXRpb25FbC5zbGljZSgxKSlcclxuICAgICAgICAgICAgICAgIDogZG9jdW1lbnQucXVlcnlTZWxlY3Rvcihwb3NpdGlvbkVsKVxyXG4gICAgICAgICAgICA6IHBvc2l0aW9uRWw7XHJcbiAgICAgICAgaWYgKCFlbCkge1xyXG4gICAgICAgICAgICAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiZcclxuICAgICAgICAgICAgICAgIHdhcm4oYENvdWxkbid0IGZpbmQgZWxlbWVudCB1c2luZyBzZWxlY3RvciBcIiR7cG9zaXRpb24uZWx9XCIgcmV0dXJuZWQgYnkgc2Nyb2xsQmVoYXZpb3IuYCk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgc2Nyb2xsVG9PcHRpb25zID0gZ2V0RWxlbWVudFBvc2l0aW9uKGVsLCBwb3NpdGlvbik7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICBzY3JvbGxUb09wdGlvbnMgPSBwb3NpdGlvbjtcclxuICAgIH1cclxuICAgIGlmICgnc2Nyb2xsQmVoYXZpb3InIGluIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zdHlsZSlcclxuICAgICAgICB3aW5kb3cuc2Nyb2xsVG8oc2Nyb2xsVG9PcHRpb25zKTtcclxuICAgIGVsc2Uge1xyXG4gICAgICAgIHdpbmRvdy5zY3JvbGxUbyhzY3JvbGxUb09wdGlvbnMubGVmdCAhPSBudWxsID8gc2Nyb2xsVG9PcHRpb25zLmxlZnQgOiB3aW5kb3cucGFnZVhPZmZzZXQsIHNjcm9sbFRvT3B0aW9ucy50b3AgIT0gbnVsbCA/IHNjcm9sbFRvT3B0aW9ucy50b3AgOiB3aW5kb3cucGFnZVlPZmZzZXQpO1xyXG4gICAgfVxyXG59XHJcbmZ1bmN0aW9uIGdldFNjcm9sbEtleShwYXRoLCBkZWx0YSkge1xyXG4gICAgY29uc3QgcG9zaXRpb24gPSBoaXN0b3J5LnN0YXRlID8gaGlzdG9yeS5zdGF0ZS5wb3NpdGlvbiAtIGRlbHRhIDogLTE7XHJcbiAgICByZXR1cm4gcG9zaXRpb24gKyBwYXRoO1xyXG59XHJcbmNvbnN0IHNjcm9sbFBvc2l0aW9ucyA9IG5ldyBNYXAoKTtcclxuZnVuY3Rpb24gc2F2ZVNjcm9sbFBvc2l0aW9uKGtleSwgc2Nyb2xsUG9zaXRpb24pIHtcclxuICAgIHNjcm9sbFBvc2l0aW9ucy5zZXQoa2V5LCBzY3JvbGxQb3NpdGlvbik7XHJcbn1cclxuZnVuY3Rpb24gZ2V0U2F2ZWRTY3JvbGxQb3NpdGlvbihrZXkpIHtcclxuICAgIGNvbnN0IHNjcm9sbCA9IHNjcm9sbFBvc2l0aW9ucy5nZXQoa2V5KTtcclxuICAgIC8vIGNvbnN1bWUgaXQgc28gaXQncyBub3QgdXNlZCBhZ2FpblxyXG4gICAgc2Nyb2xsUG9zaXRpb25zLmRlbGV0ZShrZXkpO1xyXG4gICAgcmV0dXJuIHNjcm9sbDtcclxufVxyXG4vLyBUT0RPOiBSRkMgYWJvdXQgaG93IHRvIHNhdmUgc2Nyb2xsIHBvc2l0aW9uXHJcbi8qKlxyXG4gKiBTY3JvbGxCZWhhdmlvciBpbnN0YW5jZSB1c2VkIGJ5IHRoZSByb3V0ZXIgdG8gY29tcHV0ZSBhbmQgcmVzdG9yZSB0aGUgc2Nyb2xsXHJcbiAqIHBvc2l0aW9uIHdoZW4gbmF2aWdhdGluZy5cclxuICovXHJcbi8vIGV4cG9ydCBpbnRlcmZhY2UgU2Nyb2xsSGFuZGxlcjxTY3JvbGxQb3NpdGlvbkVudHJ5IGV4dGVuZHMgSGlzdG9yeVN0YXRlVmFsdWUsIFNjcm9sbFBvc2l0aW9uIGV4dGVuZHMgU2Nyb2xsUG9zaXRpb25FbnRyeT4ge1xyXG4vLyAgIC8vIHJldHVybnMgYSBzY3JvbGwgcG9zaXRpb24gdGhhdCBjYW4gYmUgc2F2ZWQgaW4gaGlzdG9yeVxyXG4vLyAgIGNvbXB1dGUoKTogU2Nyb2xsUG9zaXRpb25FbnRyeVxyXG4vLyAgIC8vIGNhbiB0YWtlIGFuIGV4dGVuZGVkIFNjcm9sbFBvc2l0aW9uRW50cnlcclxuLy8gICBzY3JvbGwocG9zaXRpb246IFNjcm9sbFBvc2l0aW9uKTogdm9pZFxyXG4vLyB9XHJcbi8vIGV4cG9ydCBjb25zdCBzY3JvbGxIYW5kbGVyOiBTY3JvbGxIYW5kbGVyPFNjcm9sbFBvc2l0aW9uPiA9IHtcclxuLy8gICBjb21wdXRlOiBjb21wdXRlU2Nyb2xsLFxyXG4vLyAgIHNjcm9sbDogc2Nyb2xsVG9Qb3NpdGlvbixcclxuLy8gfVxuXG5sZXQgY3JlYXRlQmFzZUxvY2F0aW9uID0gKCkgPT4gbG9jYXRpb24ucHJvdG9jb2wgKyAnLy8nICsgbG9jYXRpb24uaG9zdDtcclxuLyoqXHJcbiAqIENyZWF0ZXMgYSBub3JtYWxpemVkIGhpc3RvcnkgbG9jYXRpb24gZnJvbSBhIHdpbmRvdy5sb2NhdGlvbiBvYmplY3RcclxuICogQHBhcmFtIGxvY2F0aW9uIC1cclxuICovXHJcbmZ1bmN0aW9uIGNyZWF0ZUN1cnJlbnRMb2NhdGlvbihiYXNlLCBsb2NhdGlvbikge1xyXG4gICAgY29uc3QgeyBwYXRobmFtZSwgc2VhcmNoLCBoYXNoIH0gPSBsb2NhdGlvbjtcclxuICAgIC8vIGFsbG93cyBoYXNoIGJhc2VzIGxpa2UgIywgLyMsICMvLCAjISwgIyEvLCAvIyEvLCBvciBldmVuIC9mb2xkZXIjZW5kXHJcbiAgICBjb25zdCBoYXNoUG9zID0gYmFzZS5pbmRleE9mKCcjJyk7XHJcbiAgICBpZiAoaGFzaFBvcyA+IC0xKSB7XHJcbiAgICAgICAgbGV0IHNsaWNlUG9zID0gaGFzaC5pbmNsdWRlcyhiYXNlLnNsaWNlKGhhc2hQb3MpKVxyXG4gICAgICAgICAgICA/IGJhc2Uuc2xpY2UoaGFzaFBvcykubGVuZ3RoXHJcbiAgICAgICAgICAgIDogMTtcclxuICAgICAgICBsZXQgcGF0aEZyb21IYXNoID0gaGFzaC5zbGljZShzbGljZVBvcyk7XHJcbiAgICAgICAgLy8gcHJlcGVuZCB0aGUgc3RhcnRpbmcgc2xhc2ggdG8gaGFzaCBzbyB0aGUgdXJsIHN0YXJ0cyB3aXRoIC8jXHJcbiAgICAgICAgaWYgKHBhdGhGcm9tSGFzaFswXSAhPT0gJy8nKVxyXG4gICAgICAgICAgICBwYXRoRnJvbUhhc2ggPSAnLycgKyBwYXRoRnJvbUhhc2g7XHJcbiAgICAgICAgcmV0dXJuIHN0cmlwQmFzZShwYXRoRnJvbUhhc2gsICcnKTtcclxuICAgIH1cclxuICAgIGNvbnN0IHBhdGggPSBzdHJpcEJhc2UocGF0aG5hbWUsIGJhc2UpO1xyXG4gICAgcmV0dXJuIHBhdGggKyBzZWFyY2ggKyBoYXNoO1xyXG59XHJcbmZ1bmN0aW9uIHVzZUhpc3RvcnlMaXN0ZW5lcnMoYmFzZSwgaGlzdG9yeVN0YXRlLCBjdXJyZW50TG9jYXRpb24sIHJlcGxhY2UpIHtcclxuICAgIGxldCBsaXN0ZW5lcnMgPSBbXTtcclxuICAgIGxldCB0ZWFyZG93bnMgPSBbXTtcclxuICAgIC8vIFRPRE86IHNob3VsZCBpdCBiZSBhIHN0YWNrPyBhIERpY3QuIENoZWNrIGlmIHRoZSBwb3BzdGF0ZSBsaXN0ZW5lclxyXG4gICAgLy8gY2FuIHRyaWdnZXIgdHdpY2VcclxuICAgIGxldCBwYXVzZVN0YXRlID0gbnVsbDtcclxuICAgIGNvbnN0IHBvcFN0YXRlSGFuZGxlciA9ICh7IHN0YXRlLCB9KSA9PiB7XHJcbiAgICAgICAgY29uc3QgdG8gPSBjcmVhdGVDdXJyZW50TG9jYXRpb24oYmFzZSwgbG9jYXRpb24pO1xyXG4gICAgICAgIGNvbnN0IGZyb20gPSBjdXJyZW50TG9jYXRpb24udmFsdWU7XHJcbiAgICAgICAgY29uc3QgZnJvbVN0YXRlID0gaGlzdG9yeVN0YXRlLnZhbHVlO1xyXG4gICAgICAgIGxldCBkZWx0YSA9IDA7XHJcbiAgICAgICAgaWYgKHN0YXRlKSB7XHJcbiAgICAgICAgICAgIGN1cnJlbnRMb2NhdGlvbi52YWx1ZSA9IHRvO1xyXG4gICAgICAgICAgICBoaXN0b3J5U3RhdGUudmFsdWUgPSBzdGF0ZTtcclxuICAgICAgICAgICAgLy8gaWdub3JlIHRoZSBwb3BzdGF0ZSBhbmQgcmVzZXQgdGhlIHBhdXNlU3RhdGVcclxuICAgICAgICAgICAgaWYgKHBhdXNlU3RhdGUgJiYgcGF1c2VTdGF0ZSA9PT0gZnJvbSkge1xyXG4gICAgICAgICAgICAgICAgcGF1c2VTdGF0ZSA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZGVsdGEgPSBmcm9tU3RhdGUgPyBzdGF0ZS5wb3NpdGlvbiAtIGZyb21TdGF0ZS5wb3NpdGlvbiA6IDA7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICByZXBsYWNlKHRvKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gY29uc29sZS5sb2coeyBkZWx0YUZyb21DdXJyZW50IH0pXHJcbiAgICAgICAgLy8gSGVyZSB3ZSBjb3VsZCBhbHNvIHJldmVydCB0aGUgbmF2aWdhdGlvbiBieSBjYWxsaW5nIGhpc3RvcnkuZ28oLWRlbHRhKVxyXG4gICAgICAgIC8vIHRoaXMgbGlzdGVuZXIgd2lsbCBoYXZlIHRvIGJlIGFkYXB0ZWQgdG8gbm90IHRyaWdnZXIgYWdhaW4gYW5kIHRvIHdhaXQgZm9yIHRoZSB1cmxcclxuICAgICAgICAvLyB0byBiZSB1cGRhdGVkIGJlZm9yZSB0cmlnZ2VyaW5nIHRoZSBsaXN0ZW5lcnMuIFNvbWUga2luZCBvZiB2YWxpZGF0aW9uIGZ1bmN0aW9uIHdvdWxkIGFsc29cclxuICAgICAgICAvLyBuZWVkIHRvIGJlIHBhc3NlZCB0byB0aGUgbGlzdGVuZXJzIHNvIHRoZSBuYXZpZ2F0aW9uIGNhbiBiZSBhY2NlcHRlZFxyXG4gICAgICAgIC8vIGNhbGwgYWxsIGxpc3RlbmVyc1xyXG4gICAgICAgIGxpc3RlbmVycy5mb3JFYWNoKGxpc3RlbmVyID0+IHtcclxuICAgICAgICAgICAgbGlzdGVuZXIoY3VycmVudExvY2F0aW9uLnZhbHVlLCBmcm9tLCB7XHJcbiAgICAgICAgICAgICAgICBkZWx0YSxcclxuICAgICAgICAgICAgICAgIHR5cGU6IE5hdmlnYXRpb25UeXBlLnBvcCxcclxuICAgICAgICAgICAgICAgIGRpcmVjdGlvbjogZGVsdGFcclxuICAgICAgICAgICAgICAgICAgICA/IGRlbHRhID4gMFxyXG4gICAgICAgICAgICAgICAgICAgICAgICA/IE5hdmlnYXRpb25EaXJlY3Rpb24uZm9yd2FyZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICA6IE5hdmlnYXRpb25EaXJlY3Rpb24uYmFja1xyXG4gICAgICAgICAgICAgICAgICAgIDogTmF2aWdhdGlvbkRpcmVjdGlvbi51bmtub3duLFxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcbiAgICBmdW5jdGlvbiBwYXVzZUxpc3RlbmVycygpIHtcclxuICAgICAgICBwYXVzZVN0YXRlID0gY3VycmVudExvY2F0aW9uLnZhbHVlO1xyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gbGlzdGVuKGNhbGxiYWNrKSB7XHJcbiAgICAgICAgLy8gc2V0dXAgdGhlIGxpc3RlbmVyIGFuZCBwcmVwYXJlIHRlYXJkb3duIGNhbGxiYWNrc1xyXG4gICAgICAgIGxpc3RlbmVycy5wdXNoKGNhbGxiYWNrKTtcclxuICAgICAgICBjb25zdCB0ZWFyZG93biA9ICgpID0+IHtcclxuICAgICAgICAgICAgY29uc3QgaW5kZXggPSBsaXN0ZW5lcnMuaW5kZXhPZihjYWxsYmFjayk7XHJcbiAgICAgICAgICAgIGlmIChpbmRleCA+IC0xKVxyXG4gICAgICAgICAgICAgICAgbGlzdGVuZXJzLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICAgICAgfTtcclxuICAgICAgICB0ZWFyZG93bnMucHVzaCh0ZWFyZG93bik7XHJcbiAgICAgICAgcmV0dXJuIHRlYXJkb3duO1xyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gYmVmb3JlVW5sb2FkTGlzdGVuZXIoKSB7XHJcbiAgICAgICAgY29uc3QgeyBoaXN0b3J5IH0gPSB3aW5kb3c7XHJcbiAgICAgICAgaWYgKCFoaXN0b3J5LnN0YXRlKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgaGlzdG9yeS5yZXBsYWNlU3RhdGUoYXNzaWduKHt9LCBoaXN0b3J5LnN0YXRlLCB7IHNjcm9sbDogY29tcHV0ZVNjcm9sbFBvc2l0aW9uKCkgfSksICcnKTtcclxuICAgIH1cclxuICAgIGZ1bmN0aW9uIGRlc3Ryb3koKSB7XHJcbiAgICAgICAgZm9yIChjb25zdCB0ZWFyZG93biBvZiB0ZWFyZG93bnMpXHJcbiAgICAgICAgICAgIHRlYXJkb3duKCk7XHJcbiAgICAgICAgdGVhcmRvd25zID0gW107XHJcbiAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvcHN0YXRlJywgcG9wU3RhdGVIYW5kbGVyKTtcclxuICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignYmVmb3JldW5sb2FkJywgYmVmb3JlVW5sb2FkTGlzdGVuZXIpO1xyXG4gICAgfVxyXG4gICAgLy8gc2V0dXAgdGhlIGxpc3RlbmVycyBhbmQgcHJlcGFyZSB0ZWFyZG93biBjYWxsYmFja3NcclxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdwb3BzdGF0ZScsIHBvcFN0YXRlSGFuZGxlcik7XHJcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignYmVmb3JldW5sb2FkJywgYmVmb3JlVW5sb2FkTGlzdGVuZXIpO1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICBwYXVzZUxpc3RlbmVycyxcclxuICAgICAgICBsaXN0ZW4sXHJcbiAgICAgICAgZGVzdHJveSxcclxuICAgIH07XHJcbn1cclxuLyoqXHJcbiAqIENyZWF0ZXMgYSBzdGF0ZSBvYmplY3RcclxuICovXHJcbmZ1bmN0aW9uIGJ1aWxkU3RhdGUoYmFjaywgY3VycmVudCwgZm9yd2FyZCwgcmVwbGFjZWQgPSBmYWxzZSwgY29tcHV0ZVNjcm9sbCA9IGZhbHNlKSB7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIGJhY2ssXHJcbiAgICAgICAgY3VycmVudCxcclxuICAgICAgICBmb3J3YXJkLFxyXG4gICAgICAgIHJlcGxhY2VkLFxyXG4gICAgICAgIHBvc2l0aW9uOiB3aW5kb3cuaGlzdG9yeS5sZW5ndGgsXHJcbiAgICAgICAgc2Nyb2xsOiBjb21wdXRlU2Nyb2xsID8gY29tcHV0ZVNjcm9sbFBvc2l0aW9uKCkgOiBudWxsLFxyXG4gICAgfTtcclxufVxyXG5mdW5jdGlvbiB1c2VIaXN0b3J5U3RhdGVOYXZpZ2F0aW9uKGJhc2UpIHtcclxuICAgIGNvbnN0IHsgaGlzdG9yeSwgbG9jYXRpb24gfSA9IHdpbmRvdztcclxuICAgIC8vIHByaXZhdGUgdmFyaWFibGVzXHJcbiAgICBjb25zdCBjdXJyZW50TG9jYXRpb24gPSB7XHJcbiAgICAgICAgdmFsdWU6IGNyZWF0ZUN1cnJlbnRMb2NhdGlvbihiYXNlLCBsb2NhdGlvbiksXHJcbiAgICB9O1xyXG4gICAgY29uc3QgaGlzdG9yeVN0YXRlID0geyB2YWx1ZTogaGlzdG9yeS5zdGF0ZSB9O1xyXG4gICAgLy8gYnVpbGQgY3VycmVudCBoaXN0b3J5IGVudHJ5IGFzIHRoaXMgaXMgYSBmcmVzaCBuYXZpZ2F0aW9uXHJcbiAgICBpZiAoIWhpc3RvcnlTdGF0ZS52YWx1ZSkge1xyXG4gICAgICAgIGNoYW5nZUxvY2F0aW9uKGN1cnJlbnRMb2NhdGlvbi52YWx1ZSwge1xyXG4gICAgICAgICAgICBiYWNrOiBudWxsLFxyXG4gICAgICAgICAgICBjdXJyZW50OiBjdXJyZW50TG9jYXRpb24udmFsdWUsXHJcbiAgICAgICAgICAgIGZvcndhcmQ6IG51bGwsXHJcbiAgICAgICAgICAgIC8vIHRoZSBsZW5ndGggaXMgb2ZmIGJ5IG9uZSwgd2UgbmVlZCB0byBkZWNyZWFzZSBpdFxyXG4gICAgICAgICAgICBwb3NpdGlvbjogaGlzdG9yeS5sZW5ndGggLSAxLFxyXG4gICAgICAgICAgICByZXBsYWNlZDogdHJ1ZSxcclxuICAgICAgICAgICAgLy8gZG9uJ3QgYWRkIGEgc2Nyb2xsIGFzIHRoZSB1c2VyIG1heSBoYXZlIGFuIGFuY2hvciBhbmQgd2Ugd2FudFxyXG4gICAgICAgICAgICAvLyBzY3JvbGxCZWhhdmlvciB0byBiZSB0cmlnZ2VyZWQgd2l0aG91dCBhIHNhdmVkIHBvc2l0aW9uXHJcbiAgICAgICAgICAgIHNjcm9sbDogbnVsbCxcclxuICAgICAgICB9LCB0cnVlKTtcclxuICAgIH1cclxuICAgIGZ1bmN0aW9uIGNoYW5nZUxvY2F0aW9uKHRvLCBzdGF0ZSwgcmVwbGFjZSkge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIGlmIGEgYmFzZSB0YWcgaXMgcHJvdmlkZWQgYW5kIHdlIGFyZSBvbiBhIG5vcm1hbCBkb21haW4sIHdlIGhhdmUgdG9cclxuICAgICAgICAgKiByZXNwZWN0IHRoZSBwcm92aWRlZCBgYmFzZWAgYXR0cmlidXRlIGJlY2F1c2UgcHVzaFN0YXRlKCkgd2lsbCB1c2UgaXQgYW5kXHJcbiAgICAgICAgICogcG90ZW50aWFsbHkgZXJhc2UgYW55dGhpbmcgYmVmb3JlIHRoZSBgI2AgbGlrZSBhdFxyXG4gICAgICAgICAqIGh0dHBzOi8vZ2l0aHViLmNvbS92dWVqcy92dWUtcm91dGVyLW5leHQvaXNzdWVzLzY4NSB3aGVyZSBhIGJhc2Ugb2ZcclxuICAgICAgICAgKiBgL2ZvbGRlci8jYCBidXQgYSBiYXNlIG9mIGAvYCB3b3VsZCBlcmFzZSB0aGUgYC9mb2xkZXIvYCBzZWN0aW9uLiBJZlxyXG4gICAgICAgICAqIHRoZXJlIGlzIG5vIGhvc3QsIHRoZSBgPGJhc2U+YCB0YWcgbWFrZXMgbm8gc2Vuc2UgYW5kIGlmIHRoZXJlIGlzbid0IGFcclxuICAgICAgICAgKiBiYXNlIHRhZyB3ZSBjYW4ganVzdCB1c2UgZXZlcnl0aGluZyBhZnRlciB0aGUgYCNgLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGNvbnN0IGhhc2hJbmRleCA9IGJhc2UuaW5kZXhPZignIycpO1xyXG4gICAgICAgIGNvbnN0IHVybCA9IGhhc2hJbmRleCA+IC0xXHJcbiAgICAgICAgICAgID8gKGxvY2F0aW9uLmhvc3QgJiYgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYmFzZScpXHJcbiAgICAgICAgICAgICAgICA/IGJhc2VcclxuICAgICAgICAgICAgICAgIDogYmFzZS5zbGljZShoYXNoSW5kZXgpKSArIHRvXHJcbiAgICAgICAgICAgIDogY3JlYXRlQmFzZUxvY2F0aW9uKCkgKyBiYXNlICsgdG87XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgLy8gQlJPV1NFUiBRVUlSS1xyXG4gICAgICAgICAgICAvLyBOT1RFOiBTYWZhcmkgdGhyb3dzIGEgU2VjdXJpdHlFcnJvciB3aGVuIGNhbGxpbmcgdGhpcyBmdW5jdGlvbiAxMDAgdGltZXMgaW4gMzAgc2Vjb25kc1xyXG4gICAgICAgICAgICBoaXN0b3J5W3JlcGxhY2UgPyAncmVwbGFjZVN0YXRlJyA6ICdwdXNoU3RhdGUnXShzdGF0ZSwgJycsIHVybCk7XHJcbiAgICAgICAgICAgIGhpc3RvcnlTdGF0ZS52YWx1ZSA9IHN0YXRlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICAgICAgICAgIHdhcm4oJ0Vycm9yIHdpdGggcHVzaC9yZXBsYWNlIFN0YXRlJywgZXJyKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBGb3JjZSB0aGUgbmF2aWdhdGlvbiwgdGhpcyBhbHNvIHJlc2V0cyB0aGUgY2FsbCBjb3VudFxyXG4gICAgICAgICAgICBsb2NhdGlvbltyZXBsYWNlID8gJ3JlcGxhY2UnIDogJ2Fzc2lnbiddKHVybCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gcmVwbGFjZSh0bywgZGF0YSkge1xyXG4gICAgICAgIGNvbnN0IHN0YXRlID0gYXNzaWduKHt9LCBoaXN0b3J5LnN0YXRlLCBidWlsZFN0YXRlKGhpc3RvcnlTdGF0ZS52YWx1ZS5iYWNrLCBcclxuICAgICAgICAvLyBrZWVwIGJhY2sgYW5kIGZvcndhcmQgZW50cmllcyBidXQgb3ZlcnJpZGUgY3VycmVudCBwb3NpdGlvblxyXG4gICAgICAgIHRvLCBoaXN0b3J5U3RhdGUudmFsdWUuZm9yd2FyZCwgdHJ1ZSksIGRhdGEsIHsgcG9zaXRpb246IGhpc3RvcnlTdGF0ZS52YWx1ZS5wb3NpdGlvbiB9KTtcclxuICAgICAgICBjaGFuZ2VMb2NhdGlvbih0bywgc3RhdGUsIHRydWUpO1xyXG4gICAgICAgIGN1cnJlbnRMb2NhdGlvbi52YWx1ZSA9IHRvO1xyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gcHVzaCh0bywgZGF0YSkge1xyXG4gICAgICAgIC8vIEFkZCB0byBjdXJyZW50IGVudHJ5IHRoZSBpbmZvcm1hdGlvbiBvZiB3aGVyZSB3ZSBhcmUgZ29pbmdcclxuICAgICAgICAvLyBhcyB3ZWxsIGFzIHNhdmluZyB0aGUgY3VycmVudCBwb3NpdGlvblxyXG4gICAgICAgIGNvbnN0IGN1cnJlbnRTdGF0ZSA9IGFzc2lnbih7fSwgXHJcbiAgICAgICAgLy8gdXNlIGN1cnJlbnQgaGlzdG9yeSBzdGF0ZSB0byBncmFjZWZ1bGx5IGhhbmRsZSBhIHdyb25nIGNhbGwgdG9cclxuICAgICAgICAvLyBoaXN0b3J5LnJlcGxhY2VTdGF0ZVxyXG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS92dWVqcy92dWUtcm91dGVyLW5leHQvaXNzdWVzLzM2NlxyXG4gICAgICAgIGhpc3RvcnlTdGF0ZS52YWx1ZSwgaGlzdG9yeS5zdGF0ZSwge1xyXG4gICAgICAgICAgICBmb3J3YXJkOiB0byxcclxuICAgICAgICAgICAgc2Nyb2xsOiBjb21wdXRlU2Nyb2xsUG9zaXRpb24oKSxcclxuICAgICAgICB9KTtcclxuICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmICFoaXN0b3J5LnN0YXRlKSB7XHJcbiAgICAgICAgICAgIHdhcm4oYGhpc3Rvcnkuc3RhdGUgc2VlbXMgdG8gaGF2ZSBiZWVuIG1hbnVhbGx5IHJlcGxhY2VkIHdpdGhvdXQgcHJlc2VydmluZyB0aGUgbmVjZXNzYXJ5IHZhbHVlcy4gTWFrZSBzdXJlIHRvIHByZXNlcnZlIGV4aXN0aW5nIGhpc3Rvcnkgc3RhdGUgaWYgeW91IGFyZSBtYW51YWxseSBjYWxsaW5nIGhpc3RvcnkucmVwbGFjZVN0YXRlOlxcblxcbmAgK1xyXG4gICAgICAgICAgICAgICAgYGhpc3RvcnkucmVwbGFjZVN0YXRlKGhpc3Rvcnkuc3RhdGUsICcnLCB1cmwpXFxuXFxuYCArXHJcbiAgICAgICAgICAgICAgICBgWW91IGNhbiBmaW5kIG1vcmUgaW5mb3JtYXRpb24gYXQgaHR0cHM6Ly9uZXh0LnJvdXRlci52dWVqcy5vcmcvZ3VpZGUvbWlncmF0aW9uLyN1c2FnZS1vZi1oaXN0b3J5LXN0YXRlLmApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjaGFuZ2VMb2NhdGlvbihjdXJyZW50U3RhdGUuY3VycmVudCwgY3VycmVudFN0YXRlLCB0cnVlKTtcclxuICAgICAgICBjb25zdCBzdGF0ZSA9IGFzc2lnbih7fSwgYnVpbGRTdGF0ZShjdXJyZW50TG9jYXRpb24udmFsdWUsIHRvLCBudWxsKSwgeyBwb3NpdGlvbjogY3VycmVudFN0YXRlLnBvc2l0aW9uICsgMSB9LCBkYXRhKTtcclxuICAgICAgICBjaGFuZ2VMb2NhdGlvbih0bywgc3RhdGUsIGZhbHNlKTtcclxuICAgICAgICBjdXJyZW50TG9jYXRpb24udmFsdWUgPSB0bztcclxuICAgIH1cclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgbG9jYXRpb246IGN1cnJlbnRMb2NhdGlvbixcclxuICAgICAgICBzdGF0ZTogaGlzdG9yeVN0YXRlLFxyXG4gICAgICAgIHB1c2gsXHJcbiAgICAgICAgcmVwbGFjZSxcclxuICAgIH07XHJcbn1cclxuLyoqXHJcbiAqIENyZWF0ZXMgYW4gSFRNTDUgaGlzdG9yeS4gTW9zdCBjb21tb24gaGlzdG9yeSBmb3Igc2luZ2xlIHBhZ2UgYXBwbGljYXRpb25zLlxyXG4gKlxyXG4gKiBAcGFyYW0gYmFzZSAtXHJcbiAqL1xyXG5mdW5jdGlvbiBjcmVhdGVXZWJIaXN0b3J5KGJhc2UpIHtcclxuICAgIGJhc2UgPSBub3JtYWxpemVCYXNlKGJhc2UpO1xyXG4gICAgY29uc3QgaGlzdG9yeU5hdmlnYXRpb24gPSB1c2VIaXN0b3J5U3RhdGVOYXZpZ2F0aW9uKGJhc2UpO1xyXG4gICAgY29uc3QgaGlzdG9yeUxpc3RlbmVycyA9IHVzZUhpc3RvcnlMaXN0ZW5lcnMoYmFzZSwgaGlzdG9yeU5hdmlnYXRpb24uc3RhdGUsIGhpc3RvcnlOYXZpZ2F0aW9uLmxvY2F0aW9uLCBoaXN0b3J5TmF2aWdhdGlvbi5yZXBsYWNlKTtcclxuICAgIGZ1bmN0aW9uIGdvKGRlbHRhLCB0cmlnZ2VyTGlzdGVuZXJzID0gdHJ1ZSkge1xyXG4gICAgICAgIGlmICghdHJpZ2dlckxpc3RlbmVycylcclxuICAgICAgICAgICAgaGlzdG9yeUxpc3RlbmVycy5wYXVzZUxpc3RlbmVycygpO1xyXG4gICAgICAgIGhpc3RvcnkuZ28oZGVsdGEpO1xyXG4gICAgfVxyXG4gICAgY29uc3Qgcm91dGVySGlzdG9yeSA9IGFzc2lnbih7XHJcbiAgICAgICAgLy8gaXQncyBvdmVycmlkZGVuIHJpZ2h0IGFmdGVyXHJcbiAgICAgICAgbG9jYXRpb246ICcnLFxyXG4gICAgICAgIGJhc2UsXHJcbiAgICAgICAgZ28sXHJcbiAgICAgICAgY3JlYXRlSHJlZjogY3JlYXRlSHJlZi5iaW5kKG51bGwsIGJhc2UpLFxyXG4gICAgfSwgaGlzdG9yeU5hdmlnYXRpb24sIGhpc3RvcnlMaXN0ZW5lcnMpO1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHJvdXRlckhpc3RvcnksICdsb2NhdGlvbicsIHtcclxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxyXG4gICAgICAgIGdldDogKCkgPT4gaGlzdG9yeU5hdmlnYXRpb24ubG9jYXRpb24udmFsdWUsXHJcbiAgICB9KTtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShyb3V0ZXJIaXN0b3J5LCAnc3RhdGUnLCB7XHJcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICBnZXQ6ICgpID0+IGhpc3RvcnlOYXZpZ2F0aW9uLnN0YXRlLnZhbHVlLFxyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gcm91dGVySGlzdG9yeTtcclxufVxuXG4vKipcclxuICogQ3JlYXRlcyBhIGluLW1lbW9yeSBiYXNlZCBoaXN0b3J5LiBUaGUgbWFpbiBwdXJwb3NlIG9mIHRoaXMgaGlzdG9yeSBpcyB0byBoYW5kbGUgU1NSLiBJdCBzdGFydHMgaW4gYSBzcGVjaWFsIGxvY2F0aW9uIHRoYXQgaXMgbm93aGVyZS5cclxuICogSXQncyB1cCB0byB0aGUgdXNlciB0byByZXBsYWNlIHRoYXQgbG9jYXRpb24gd2l0aCB0aGUgc3RhcnRlciBsb2NhdGlvbiBieSBlaXRoZXIgY2FsbGluZyBgcm91dGVyLnB1c2hgIG9yIGByb3V0ZXIucmVwbGFjZWAuXHJcbiAqXHJcbiAqIEBwYXJhbSBiYXNlIC0gQmFzZSBhcHBsaWVkIHRvIGFsbCB1cmxzLCBkZWZhdWx0cyB0byAnLydcclxuICogQHJldHVybnMgYSBoaXN0b3J5IG9iamVjdCB0aGF0IGNhbiBiZSBwYXNzZWQgdG8gdGhlIHJvdXRlciBjb25zdHJ1Y3RvclxyXG4gKi9cclxuZnVuY3Rpb24gY3JlYXRlTWVtb3J5SGlzdG9yeShiYXNlID0gJycpIHtcclxuICAgIGxldCBsaXN0ZW5lcnMgPSBbXTtcclxuICAgIGxldCBxdWV1ZSA9IFtTVEFSVF07XHJcbiAgICBsZXQgcG9zaXRpb24gPSAwO1xyXG4gICAgYmFzZSA9IG5vcm1hbGl6ZUJhc2UoYmFzZSk7XHJcbiAgICBmdW5jdGlvbiBzZXRMb2NhdGlvbihsb2NhdGlvbikge1xyXG4gICAgICAgIHBvc2l0aW9uKys7XHJcbiAgICAgICAgaWYgKHBvc2l0aW9uID09PSBxdWV1ZS5sZW5ndGgpIHtcclxuICAgICAgICAgICAgLy8gd2UgYXJlIGF0IHRoZSBlbmQsIHdlIGNhbiBzaW1wbHkgYXBwZW5kIGEgbmV3IGVudHJ5XHJcbiAgICAgICAgICAgIHF1ZXVlLnB1c2gobG9jYXRpb24pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgLy8gd2UgYXJlIGluIHRoZSBtaWRkbGUsIHdlIHJlbW92ZSBldmVyeXRoaW5nIGZyb20gaGVyZSBpbiB0aGUgcXVldWVcclxuICAgICAgICAgICAgcXVldWUuc3BsaWNlKHBvc2l0aW9uKTtcclxuICAgICAgICAgICAgcXVldWUucHVzaChsb2NhdGlvbik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gdHJpZ2dlckxpc3RlbmVycyh0bywgZnJvbSwgeyBkaXJlY3Rpb24sIGRlbHRhIH0pIHtcclxuICAgICAgICBjb25zdCBpbmZvID0ge1xyXG4gICAgICAgICAgICBkaXJlY3Rpb24sXHJcbiAgICAgICAgICAgIGRlbHRhLFxyXG4gICAgICAgICAgICB0eXBlOiBOYXZpZ2F0aW9uVHlwZS5wb3AsXHJcbiAgICAgICAgfTtcclxuICAgICAgICBmb3IgKGNvbnN0IGNhbGxiYWNrIG9mIGxpc3RlbmVycykge1xyXG4gICAgICAgICAgICBjYWxsYmFjayh0bywgZnJvbSwgaW5mbyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgY29uc3Qgcm91dGVySGlzdG9yeSA9IHtcclxuICAgICAgICAvLyByZXdyaXR0ZW4gYnkgT2JqZWN0LmRlZmluZVByb3BlcnR5XHJcbiAgICAgICAgbG9jYXRpb246IFNUQVJULFxyXG4gICAgICAgIC8vIFRPRE86IHNob3VsZCBiZSBrZXB0IGluIHF1ZXVlXHJcbiAgICAgICAgc3RhdGU6IHt9LFxyXG4gICAgICAgIGJhc2UsXHJcbiAgICAgICAgY3JlYXRlSHJlZjogY3JlYXRlSHJlZi5iaW5kKG51bGwsIGJhc2UpLFxyXG4gICAgICAgIHJlcGxhY2UodG8pIHtcclxuICAgICAgICAgICAgLy8gcmVtb3ZlIGN1cnJlbnQgZW50cnkgYW5kIGRlY3JlbWVudCBwb3NpdGlvblxyXG4gICAgICAgICAgICBxdWV1ZS5zcGxpY2UocG9zaXRpb24tLSwgMSk7XHJcbiAgICAgICAgICAgIHNldExvY2F0aW9uKHRvKTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIHB1c2godG8sIGRhdGEpIHtcclxuICAgICAgICAgICAgc2V0TG9jYXRpb24odG8pO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgbGlzdGVuKGNhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgIGxpc3RlbmVycy5wdXNoKGNhbGxiYWNrKTtcclxuICAgICAgICAgICAgcmV0dXJuICgpID0+IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gbGlzdGVuZXJzLmluZGV4T2YoY2FsbGJhY2spO1xyXG4gICAgICAgICAgICAgICAgaWYgKGluZGV4ID4gLTEpXHJcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXJzLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfSxcclxuICAgICAgICBkZXN0cm95KCkge1xyXG4gICAgICAgICAgICBsaXN0ZW5lcnMgPSBbXTtcclxuICAgICAgICAgICAgcXVldWUgPSBbU1RBUlRdO1xyXG4gICAgICAgICAgICBwb3NpdGlvbiA9IDA7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBnbyhkZWx0YSwgc2hvdWxkVHJpZ2dlciA9IHRydWUpIHtcclxuICAgICAgICAgICAgY29uc3QgZnJvbSA9IHRoaXMubG9jYXRpb247XHJcbiAgICAgICAgICAgIGNvbnN0IGRpcmVjdGlvbiA9IFxyXG4gICAgICAgICAgICAvLyB3ZSBhcmUgY29uc2lkZXJpbmcgZGVsdGEgPT09IDAgZ29pbmcgZm9yd2FyZCwgYnV0IGluIGFic3RyYWN0IG1vZGVcclxuICAgICAgICAgICAgLy8gdXNpbmcgMCBmb3IgdGhlIGRlbHRhIGRvZXNuJ3QgbWFrZSBzZW5zZSBsaWtlIGl0IGRvZXMgaW4gaHRtbDUgd2hlcmVcclxuICAgICAgICAgICAgLy8gaXQgcmVsb2FkcyB0aGUgcGFnZVxyXG4gICAgICAgICAgICBkZWx0YSA8IDAgPyBOYXZpZ2F0aW9uRGlyZWN0aW9uLmJhY2sgOiBOYXZpZ2F0aW9uRGlyZWN0aW9uLmZvcndhcmQ7XHJcbiAgICAgICAgICAgIHBvc2l0aW9uID0gTWF0aC5tYXgoMCwgTWF0aC5taW4ocG9zaXRpb24gKyBkZWx0YSwgcXVldWUubGVuZ3RoIC0gMSkpO1xyXG4gICAgICAgICAgICBpZiAoc2hvdWxkVHJpZ2dlcikge1xyXG4gICAgICAgICAgICAgICAgdHJpZ2dlckxpc3RlbmVycyh0aGlzLmxvY2F0aW9uLCBmcm9tLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgZGlyZWN0aW9uLFxyXG4gICAgICAgICAgICAgICAgICAgIGRlbHRhLFxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG4gICAgfTtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShyb3V0ZXJIaXN0b3J5LCAnbG9jYXRpb24nLCB7XHJcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICBnZXQ6ICgpID0+IHF1ZXVlW3Bvc2l0aW9uXSxcclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIHJvdXRlckhpc3Rvcnk7XHJcbn1cblxuLyoqXHJcbiAqIENyZWF0ZXMgYSBoYXNoIGhpc3RvcnkuIFVzZWZ1bCBmb3Igd2ViIGFwcGxpY2F0aW9ucyB3aXRoIG5vIGhvc3QgKGUuZy5cclxuICogYGZpbGU6Ly9gKSBvciB3aGVuIGNvbmZpZ3VyaW5nIGEgc2VydmVyIHRvIGhhbmRsZSBhbnkgVVJMIGlzIG5vdCBwb3NzaWJsZS5cclxuICpcclxuICogQHBhcmFtIGJhc2UgLSBvcHRpb25hbCBiYXNlIHRvIHByb3ZpZGUuIERlZmF1bHRzIHRvIGBsb2NhdGlvbi5wYXRobmFtZSArXHJcbiAqIGxvY2F0aW9uLnNlYXJjaGAgSWYgdGhlcmUgaXMgYSBgPGJhc2U+YCB0YWcgaW4gdGhlIGBoZWFkYCwgaXRzIHZhbHVlIHdpbGwgYmVcclxuICogaWdub3JlZCBpbiBmYXZvciBvZiB0aGlzIHBhcmFtZXRlciAqKmJ1dCBub3RlIGl0IGFmZmVjdHMgYWxsIHRoZVxyXG4gKiBoaXN0b3J5LnB1c2hTdGF0ZSgpIGNhbGxzKiosIG1lYW5pbmcgdGhhdCBpZiB5b3UgdXNlIGEgYDxiYXNlPmAgdGFnLCBpdCdzXHJcbiAqIGBocmVmYCB2YWx1ZSAqKmhhcyB0byBtYXRjaCB0aGlzIHBhcmFtZXRlcioqIChpZ25vcmluZyBhbnl0aGluZyBhZnRlciB0aGVcclxuICogYCNgKS5cclxuICpcclxuICogQGV4YW1wbGVcclxuICogYGBganNcclxuICogLy8gYXQgaHR0cHM6Ly9leGFtcGxlLmNvbS9mb2xkZXJcclxuICogY3JlYXRlV2ViSGFzaEhpc3RvcnkoKSAvLyBnaXZlcyBhIHVybCBvZiBgaHR0cHM6Ly9leGFtcGxlLmNvbS9mb2xkZXIjYFxyXG4gKiBjcmVhdGVXZWJIYXNoSGlzdG9yeSgnL2ZvbGRlci8nKSAvLyBnaXZlcyBhIHVybCBvZiBgaHR0cHM6Ly9leGFtcGxlLmNvbS9mb2xkZXIvI2BcclxuICogLy8gaWYgdGhlIGAjYCBpcyBwcm92aWRlZCBpbiB0aGUgYmFzZSwgaXQgd29uJ3QgYmUgYWRkZWQgYnkgYGNyZWF0ZVdlYkhhc2hIaXN0b3J5YFxyXG4gKiBjcmVhdGVXZWJIYXNoSGlzdG9yeSgnL2ZvbGRlci8jL2FwcC8nKSAvLyBnaXZlcyBhIHVybCBvZiBgaHR0cHM6Ly9leGFtcGxlLmNvbS9mb2xkZXIvIy9hcHAvYFxyXG4gKiAvLyB5b3Ugc2hvdWxkIGF2b2lkIGRvaW5nIHRoaXMgYmVjYXVzZSBpdCBjaGFuZ2VzIHRoZSBvcmlnaW5hbCB1cmwgYW5kIGJyZWFrcyBjb3B5aW5nIHVybHNcclxuICogY3JlYXRlV2ViSGFzaEhpc3RvcnkoJy9vdGhlci1mb2xkZXIvJykgLy8gZ2l2ZXMgYSB1cmwgb2YgYGh0dHBzOi8vZXhhbXBsZS5jb20vb3RoZXItZm9sZGVyLyNgXHJcbiAqXHJcbiAqIC8vIGF0IGZpbGU6Ly8vdXNyL2V0Yy9mb2xkZXIvaW5kZXguaHRtbFxyXG4gKiAvLyBmb3IgbG9jYXRpb25zIHdpdGggbm8gYGhvc3RgLCB0aGUgYmFzZSBpcyBpZ25vcmVkXHJcbiAqIGNyZWF0ZVdlYkhhc2hIaXN0b3J5KCcvaUFtSWdub3JlZCcpIC8vIGdpdmVzIGEgdXJsIG9mIGBmaWxlOi8vL3Vzci9ldGMvZm9sZGVyL2luZGV4Lmh0bWwjYFxyXG4gKiBgYGBcclxuICovXHJcbmZ1bmN0aW9uIGNyZWF0ZVdlYkhhc2hIaXN0b3J5KGJhc2UpIHtcclxuICAgIC8vIE1ha2Ugc3VyZSB0aGlzIGltcGxlbWVudGF0aW9uIGlzIGZpbmUgaW4gdGVybXMgb2YgZW5jb2RpbmcsIHNwZWNpYWxseSBmb3IgSUUxMVxyXG4gICAgLy8gZm9yIGBmaWxlOi8vYCwgZGlyZWN0bHkgdXNlIHRoZSBwYXRobmFtZSBhbmQgaWdub3JlIHRoZSBiYXNlXHJcbiAgICAvLyBsb2NhdGlvbi5wYXRobmFtZSBjb250YWlucyBhbiBpbml0aWFsIGAvYCBldmVuIGF0IHRoZSByb290OiBgaHR0cHM6Ly9leGFtcGxlLmNvbWBcclxuICAgIGJhc2UgPSBsb2NhdGlvbi5ob3N0ID8gYmFzZSB8fCBsb2NhdGlvbi5wYXRobmFtZSArIGxvY2F0aW9uLnNlYXJjaCA6ICcnO1xyXG4gICAgLy8gYWxsb3cgdGhlIHVzZXIgdG8gcHJvdmlkZSBhIGAjYCBpbiB0aGUgbWlkZGxlOiBgL2Jhc2UvIy9hcHBgXHJcbiAgICBpZiAoIWJhc2UuaW5jbHVkZXMoJyMnKSlcclxuICAgICAgICBiYXNlICs9ICcjJztcclxuICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiYgIWJhc2UuZW5kc1dpdGgoJyMvJykgJiYgIWJhc2UuZW5kc1dpdGgoJyMnKSkge1xyXG4gICAgICAgIHdhcm4oYEEgaGFzaCBiYXNlIG11c3QgZW5kIHdpdGggYSBcIiNcIjpcXG5cIiR7YmFzZX1cIiBzaG91bGQgYmUgXCIke2Jhc2UucmVwbGFjZSgvIy4qJC8sICcjJyl9XCIuYCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gY3JlYXRlV2ViSGlzdG9yeShiYXNlKTtcclxufVxuXG5mdW5jdGlvbiBpc1JvdXRlTG9jYXRpb24ocm91dGUpIHtcclxuICAgIHJldHVybiB0eXBlb2Ygcm91dGUgPT09ICdzdHJpbmcnIHx8IChyb3V0ZSAmJiB0eXBlb2Ygcm91dGUgPT09ICdvYmplY3QnKTtcclxufVxyXG5mdW5jdGlvbiBpc1JvdXRlTmFtZShuYW1lKSB7XHJcbiAgICByZXR1cm4gdHlwZW9mIG5hbWUgPT09ICdzdHJpbmcnIHx8IHR5cGVvZiBuYW1lID09PSAnc3ltYm9sJztcclxufVxuXG4vKipcclxuICogSW5pdGlhbCByb3V0ZSBsb2NhdGlvbiB3aGVyZSB0aGUgcm91dGVyIGlzLiBDYW4gYmUgdXNlZCBpbiBuYXZpZ2F0aW9uIGd1YXJkc1xyXG4gKiB0byBkaWZmZXJlbnRpYXRlIHRoZSBpbml0aWFsIG5hdmlnYXRpb24uXHJcbiAqXHJcbiAqIEBleGFtcGxlXHJcbiAqIGBgYGpzXHJcbiAqIGltcG9ydCB7IFNUQVJUX0xPQ0FUSU9OIH0gZnJvbSAndnVlLXJvdXRlcidcclxuICpcclxuICogcm91dGVyLmJlZm9yZUVhY2goKHRvLCBmcm9tKSA9PiB7XHJcbiAqICAgaWYgKGZyb20gPT09IFNUQVJUX0xPQ0FUSU9OKSB7XHJcbiAqICAgICAvLyBpbml0aWFsIG5hdmlnYXRpb25cclxuICogICB9XHJcbiAqIH0pXHJcbiAqIGBgYFxyXG4gKi9cclxuY29uc3QgU1RBUlRfTE9DQVRJT05fTk9STUFMSVpFRCA9IHtcclxuICAgIHBhdGg6ICcvJyxcclxuICAgIG5hbWU6IHVuZGVmaW5lZCxcclxuICAgIHBhcmFtczoge30sXHJcbiAgICBxdWVyeToge30sXHJcbiAgICBoYXNoOiAnJyxcclxuICAgIGZ1bGxQYXRoOiAnLycsXHJcbiAgICBtYXRjaGVkOiBbXSxcclxuICAgIG1ldGE6IHt9LFxyXG4gICAgcmVkaXJlY3RlZEZyb206IHVuZGVmaW5lZCxcclxufTtcblxuY29uc3QgTmF2aWdhdGlvbkZhaWx1cmVTeW1ib2wgPSAvKiNfX1BVUkVfXyovIFBvbHlTeW1ib2woKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpID8gJ25hdmlnYXRpb24gZmFpbHVyZScgOiAnbmYnKTtcclxuLyoqXHJcbiAqIEVudW1lcmF0aW9uIHdpdGggYWxsIHBvc3NpYmxlIHR5cGVzIGZvciBuYXZpZ2F0aW9uIGZhaWx1cmVzLiBDYW4gYmUgcGFzc2VkIHRvXHJcbiAqIHtAbGluayBpc05hdmlnYXRpb25GYWlsdXJlfSB0byBjaGVjayBmb3Igc3BlY2lmaWMgZmFpbHVyZXMuXHJcbiAqL1xyXG52YXIgTmF2aWdhdGlvbkZhaWx1cmVUeXBlO1xyXG4oZnVuY3Rpb24gKE5hdmlnYXRpb25GYWlsdXJlVHlwZSkge1xyXG4gICAgLyoqXHJcbiAgICAgKiBBbiBhYm9ydGVkIG5hdmlnYXRpb24gaXMgYSBuYXZpZ2F0aW9uIHRoYXQgZmFpbGVkIGJlY2F1c2UgYSBuYXZpZ2F0aW9uXHJcbiAgICAgKiBndWFyZCByZXR1cm5lZCBgZmFsc2VgIG9yIGNhbGxlZCBgbmV4dChmYWxzZSlgXHJcbiAgICAgKi9cclxuICAgIE5hdmlnYXRpb25GYWlsdXJlVHlwZVtOYXZpZ2F0aW9uRmFpbHVyZVR5cGVbXCJhYm9ydGVkXCJdID0gNF0gPSBcImFib3J0ZWRcIjtcclxuICAgIC8qKlxyXG4gICAgICogQSBjYW5jZWxsZWQgbmF2aWdhdGlvbiBpcyBhIG5hdmlnYXRpb24gdGhhdCBmYWlsZWQgYmVjYXVzZSBhIG1vcmUgcmVjZW50XHJcbiAgICAgKiBuYXZpZ2F0aW9uIGZpbmlzaGVkIHN0YXJ0ZWQgKG5vdCBuZWNlc3NhcmlseSBmaW5pc2hlZCkuXHJcbiAgICAgKi9cclxuICAgIE5hdmlnYXRpb25GYWlsdXJlVHlwZVtOYXZpZ2F0aW9uRmFpbHVyZVR5cGVbXCJjYW5jZWxsZWRcIl0gPSA4XSA9IFwiY2FuY2VsbGVkXCI7XHJcbiAgICAvKipcclxuICAgICAqIEEgZHVwbGljYXRlZCBuYXZpZ2F0aW9uIGlzIGEgbmF2aWdhdGlvbiB0aGF0IGZhaWxlZCBiZWNhdXNlIGl0IHdhc1xyXG4gICAgICogaW5pdGlhdGVkIHdoaWxlIGFscmVhZHkgYmVpbmcgYXQgdGhlIGV4YWN0IHNhbWUgbG9jYXRpb24uXHJcbiAgICAgKi9cclxuICAgIE5hdmlnYXRpb25GYWlsdXJlVHlwZVtOYXZpZ2F0aW9uRmFpbHVyZVR5cGVbXCJkdXBsaWNhdGVkXCJdID0gMTZdID0gXCJkdXBsaWNhdGVkXCI7XHJcbn0pKE5hdmlnYXRpb25GYWlsdXJlVHlwZSB8fCAoTmF2aWdhdGlvbkZhaWx1cmVUeXBlID0ge30pKTtcclxuLy8gREVWIG9ubHkgZGVidWcgbWVzc2FnZXNcclxuY29uc3QgRXJyb3JUeXBlTWVzc2FnZXMgPSB7XHJcbiAgICBbMSAvKiBNQVRDSEVSX05PVF9GT1VORCAqL10oeyBsb2NhdGlvbiwgY3VycmVudExvY2F0aW9uIH0pIHtcclxuICAgICAgICByZXR1cm4gYE5vIG1hdGNoIGZvclxcbiAke0pTT04uc3RyaW5naWZ5KGxvY2F0aW9uKX0ke2N1cnJlbnRMb2NhdGlvblxyXG4gICAgICAgICAgICA/ICdcXG53aGlsZSBiZWluZyBhdFxcbicgKyBKU09OLnN0cmluZ2lmeShjdXJyZW50TG9jYXRpb24pXHJcbiAgICAgICAgICAgIDogJyd9YDtcclxuICAgIH0sXHJcbiAgICBbMiAvKiBOQVZJR0FUSU9OX0dVQVJEX1JFRElSRUNUICovXSh7IGZyb20sIHRvLCB9KSB7XHJcbiAgICAgICAgcmV0dXJuIGBSZWRpcmVjdGVkIGZyb20gXCIke2Zyb20uZnVsbFBhdGh9XCIgdG8gXCIke3N0cmluZ2lmeVJvdXRlKHRvKX1cIiB2aWEgYSBuYXZpZ2F0aW9uIGd1YXJkLmA7XHJcbiAgICB9LFxyXG4gICAgWzQgLyogTkFWSUdBVElPTl9BQk9SVEVEICovXSh7IGZyb20sIHRvIH0pIHtcclxuICAgICAgICByZXR1cm4gYE5hdmlnYXRpb24gYWJvcnRlZCBmcm9tIFwiJHtmcm9tLmZ1bGxQYXRofVwiIHRvIFwiJHt0by5mdWxsUGF0aH1cIiB2aWEgYSBuYXZpZ2F0aW9uIGd1YXJkLmA7XHJcbiAgICB9LFxyXG4gICAgWzggLyogTkFWSUdBVElPTl9DQU5DRUxMRUQgKi9dKHsgZnJvbSwgdG8gfSkge1xyXG4gICAgICAgIHJldHVybiBgTmF2aWdhdGlvbiBjYW5jZWxsZWQgZnJvbSBcIiR7ZnJvbS5mdWxsUGF0aH1cIiB0byBcIiR7dG8uZnVsbFBhdGh9XCIgd2l0aCBhIG5ldyBuYXZpZ2F0aW9uLmA7XHJcbiAgICB9LFxyXG4gICAgWzE2IC8qIE5BVklHQVRJT05fRFVQTElDQVRFRCAqL10oeyBmcm9tLCB0byB9KSB7XHJcbiAgICAgICAgcmV0dXJuIGBBdm9pZGVkIHJlZHVuZGFudCBuYXZpZ2F0aW9uIHRvIGN1cnJlbnQgbG9jYXRpb246IFwiJHtmcm9tLmZ1bGxQYXRofVwiLmA7XHJcbiAgICB9LFxyXG59O1xyXG5mdW5jdGlvbiBjcmVhdGVSb3V0ZXJFcnJvcih0eXBlLCBwYXJhbXMpIHtcclxuICAgIC8vIGtlZXAgZnVsbCBlcnJvciBtZXNzYWdlcyBpbiBjanMgdmVyc2lvbnNcclxuICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgfHwgIXRydWUpIHtcclxuICAgICAgICByZXR1cm4gYXNzaWduKG5ldyBFcnJvcihFcnJvclR5cGVNZXNzYWdlc1t0eXBlXShwYXJhbXMpKSwge1xyXG4gICAgICAgICAgICB0eXBlLFxyXG4gICAgICAgICAgICBbTmF2aWdhdGlvbkZhaWx1cmVTeW1ib2xdOiB0cnVlLFxyXG4gICAgICAgIH0sIHBhcmFtcyk7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICByZXR1cm4gYXNzaWduKG5ldyBFcnJvcigpLCB7XHJcbiAgICAgICAgICAgIHR5cGUsXHJcbiAgICAgICAgICAgIFtOYXZpZ2F0aW9uRmFpbHVyZVN5bWJvbF06IHRydWUsXHJcbiAgICAgICAgfSwgcGFyYW1zKTtcclxuICAgIH1cclxufVxyXG5mdW5jdGlvbiBpc05hdmlnYXRpb25GYWlsdXJlKGVycm9yLCB0eXBlKSB7XHJcbiAgICByZXR1cm4gKGVycm9yIGluc3RhbmNlb2YgRXJyb3IgJiZcclxuICAgICAgICBOYXZpZ2F0aW9uRmFpbHVyZVN5bWJvbCBpbiBlcnJvciAmJlxyXG4gICAgICAgICh0eXBlID09IG51bGwgfHwgISEoZXJyb3IudHlwZSAmIHR5cGUpKSk7XHJcbn1cclxuY29uc3QgcHJvcGVydGllc1RvTG9nID0gWydwYXJhbXMnLCAncXVlcnknLCAnaGFzaCddO1xyXG5mdW5jdGlvbiBzdHJpbmdpZnlSb3V0ZSh0bykge1xyXG4gICAgaWYgKHR5cGVvZiB0byA9PT0gJ3N0cmluZycpXHJcbiAgICAgICAgcmV0dXJuIHRvO1xyXG4gICAgaWYgKCdwYXRoJyBpbiB0bylcclxuICAgICAgICByZXR1cm4gdG8ucGF0aDtcclxuICAgIGNvbnN0IGxvY2F0aW9uID0ge307XHJcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBwcm9wZXJ0aWVzVG9Mb2cpIHtcclxuICAgICAgICBpZiAoa2V5IGluIHRvKVxyXG4gICAgICAgICAgICBsb2NhdGlvbltrZXldID0gdG9ba2V5XTtcclxuICAgIH1cclxuICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShsb2NhdGlvbiwgbnVsbCwgMik7XHJcbn1cblxuLy8gZGVmYXVsdCBwYXR0ZXJuIGZvciBhIHBhcmFtOiBub24gZ3JlZWR5IGV2ZXJ5dGhpbmcgYnV0IC9cclxuY29uc3QgQkFTRV9QQVJBTV9QQVRURVJOID0gJ1teL10rPyc7XHJcbmNvbnN0IEJBU0VfUEFUSF9QQVJTRVJfT1BUSU9OUyA9IHtcclxuICAgIHNlbnNpdGl2ZTogZmFsc2UsXHJcbiAgICBzdHJpY3Q6IGZhbHNlLFxyXG4gICAgc3RhcnQ6IHRydWUsXHJcbiAgICBlbmQ6IHRydWUsXHJcbn07XHJcbi8vIFNwZWNpYWwgUmVnZXggY2hhcmFjdGVycyB0aGF0IG11c3QgYmUgZXNjYXBlZCBpbiBzdGF0aWMgdG9rZW5zXHJcbmNvbnN0IFJFR0VYX0NIQVJTX1JFID0gL1suKyo/XiR7fSgpW1xcXS9cXFxcXS9nO1xyXG4vKipcclxuICogQ3JlYXRlcyBhIHBhdGggcGFyc2VyIGZyb20gYW4gYXJyYXkgb2YgU2VnbWVudHMgKGEgc2VnbWVudCBpcyBhbiBhcnJheSBvZiBUb2tlbnMpXHJcbiAqXHJcbiAqIEBwYXJhbSBzZWdtZW50cyAtIGFycmF5IG9mIHNlZ21lbnRzIHJldHVybmVkIGJ5IHRva2VuaXplUGF0aFxyXG4gKiBAcGFyYW0gZXh0cmFPcHRpb25zIC0gb3B0aW9uYWwgb3B0aW9ucyBmb3IgdGhlIHJlZ2V4cFxyXG4gKiBAcmV0dXJucyBhIFBhdGhQYXJzZXJcclxuICovXHJcbmZ1bmN0aW9uIHRva2Vuc1RvUGFyc2VyKHNlZ21lbnRzLCBleHRyYU9wdGlvbnMpIHtcclxuICAgIGNvbnN0IG9wdGlvbnMgPSBhc3NpZ24oe30sIEJBU0VfUEFUSF9QQVJTRVJfT1BUSU9OUywgZXh0cmFPcHRpb25zKTtcclxuICAgIC8vIHRoZSBhbW91bnQgb2Ygc2NvcmVzIGlzIHRoZSBzYW1lIGFzIHRoZSBsZW5ndGggb2Ygc2VnbWVudHMgZXhjZXB0IGZvciB0aGUgcm9vdCBzZWdtZW50IFwiL1wiXHJcbiAgICBjb25zdCBzY29yZSA9IFtdO1xyXG4gICAgLy8gdGhlIHJlZ2V4cCBhcyBhIHN0cmluZ1xyXG4gICAgbGV0IHBhdHRlcm4gPSBvcHRpb25zLnN0YXJ0ID8gJ14nIDogJyc7XHJcbiAgICAvLyBleHRyYWN0ZWQga2V5c1xyXG4gICAgY29uc3Qga2V5cyA9IFtdO1xyXG4gICAgZm9yIChjb25zdCBzZWdtZW50IG9mIHNlZ21lbnRzKSB7XHJcbiAgICAgICAgLy8gdGhlIHJvb3Qgc2VnbWVudCBuZWVkcyBzcGVjaWFsIHRyZWF0bWVudFxyXG4gICAgICAgIGNvbnN0IHNlZ21lbnRTY29yZXMgPSBzZWdtZW50Lmxlbmd0aCA/IFtdIDogWzkwIC8qIFJvb3QgKi9dO1xyXG4gICAgICAgIC8vIGFsbG93IHRyYWlsaW5nIHNsYXNoXHJcbiAgICAgICAgaWYgKG9wdGlvbnMuc3RyaWN0ICYmICFzZWdtZW50Lmxlbmd0aClcclxuICAgICAgICAgICAgcGF0dGVybiArPSAnLyc7XHJcbiAgICAgICAgZm9yIChsZXQgdG9rZW5JbmRleCA9IDA7IHRva2VuSW5kZXggPCBzZWdtZW50Lmxlbmd0aDsgdG9rZW5JbmRleCsrKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHRva2VuID0gc2VnbWVudFt0b2tlbkluZGV4XTtcclxuICAgICAgICAgICAgLy8gcmVzZXRzIHRoZSBzY29yZSBpZiB3ZSBhcmUgaW5zaWRlIGEgc3ViIHNlZ21lbnQgLzphLW90aGVyLTpiXHJcbiAgICAgICAgICAgIGxldCBzdWJTZWdtZW50U2NvcmUgPSA0MCAvKiBTZWdtZW50ICovICtcclxuICAgICAgICAgICAgICAgIChvcHRpb25zLnNlbnNpdGl2ZSA/IDAuMjUgLyogQm9udXNDYXNlU2Vuc2l0aXZlICovIDogMCk7XHJcbiAgICAgICAgICAgIGlmICh0b2tlbi50eXBlID09PSAwIC8qIFN0YXRpYyAqLykge1xyXG4gICAgICAgICAgICAgICAgLy8gcHJlcGVuZCB0aGUgc2xhc2ggaWYgd2UgYXJlIHN0YXJ0aW5nIGEgbmV3IHNlZ21lbnRcclxuICAgICAgICAgICAgICAgIGlmICghdG9rZW5JbmRleClcclxuICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuICs9ICcvJztcclxuICAgICAgICAgICAgICAgIHBhdHRlcm4gKz0gdG9rZW4udmFsdWUucmVwbGFjZShSRUdFWF9DSEFSU19SRSwgJ1xcXFwkJicpO1xyXG4gICAgICAgICAgICAgICAgc3ViU2VnbWVudFNjb3JlICs9IDQwIC8qIFN0YXRpYyAqLztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmICh0b2tlbi50eXBlID09PSAxIC8qIFBhcmFtICovKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCB7IHZhbHVlLCByZXBlYXRhYmxlLCBvcHRpb25hbCwgcmVnZXhwIH0gPSB0b2tlbjtcclxuICAgICAgICAgICAgICAgIGtleXMucHVzaCh7XHJcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogdmFsdWUsXHJcbiAgICAgICAgICAgICAgICAgICAgcmVwZWF0YWJsZSxcclxuICAgICAgICAgICAgICAgICAgICBvcHRpb25hbCxcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcmUgPSByZWdleHAgPyByZWdleHAgOiBCQVNFX1BBUkFNX1BBVFRFUk47XHJcbiAgICAgICAgICAgICAgICAvLyB0aGUgdXNlciBwcm92aWRlZCBhIGN1c3RvbSByZWdleHAgLzppZChcXFxcZCspXHJcbiAgICAgICAgICAgICAgICBpZiAocmUgIT09IEJBU0VfUEFSQU1fUEFUVEVSTikge1xyXG4gICAgICAgICAgICAgICAgICAgIHN1YlNlZ21lbnRTY29yZSArPSAxMCAvKiBCb251c0N1c3RvbVJlZ0V4cCAqLztcclxuICAgICAgICAgICAgICAgICAgICAvLyBtYWtlIHN1cmUgdGhlIHJlZ2V4cCBpcyB2YWxpZCBiZWZvcmUgdXNpbmcgaXRcclxuICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXcgUmVnRXhwKGAoJHtyZX0pYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGN1c3RvbSBSZWdFeHAgZm9yIHBhcmFtIFwiJHt2YWx1ZX1cIiAoJHtyZX0pOiBgICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVyci5tZXNzYWdlKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAvLyB3aGVuIHdlIHJlcGVhdCB3ZSBtdXN0IHRha2UgY2FyZSBvZiB0aGUgcmVwZWF0aW5nIGxlYWRpbmcgc2xhc2hcclxuICAgICAgICAgICAgICAgIGxldCBzdWJQYXR0ZXJuID0gcmVwZWF0YWJsZSA/IGAoKD86JHtyZX0pKD86Lyg/OiR7cmV9KSkqKWAgOiBgKCR7cmV9KWA7XHJcbiAgICAgICAgICAgICAgICAvLyBwcmVwZW5kIHRoZSBzbGFzaCBpZiB3ZSBhcmUgc3RhcnRpbmcgYSBuZXcgc2VnbWVudFxyXG4gICAgICAgICAgICAgICAgaWYgKCF0b2tlbkluZGV4KVxyXG4gICAgICAgICAgICAgICAgICAgIHN1YlBhdHRlcm4gPVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBhdm9pZCBhbiBvcHRpb25hbCAvIGlmIHRoZXJlIGFyZSBtb3JlIHNlZ21lbnRzIGUuZy4gLzpwPy1zdGF0aWNcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gb3IgLzpwPy06cDJcclxuICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uYWwgJiYgc2VnbWVudC5sZW5ndGggPCAyXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGAoPzovJHtzdWJQYXR0ZXJufSlgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICcvJyArIHN1YlBhdHRlcm47XHJcbiAgICAgICAgICAgICAgICBpZiAob3B0aW9uYWwpXHJcbiAgICAgICAgICAgICAgICAgICAgc3ViUGF0dGVybiArPSAnPyc7XHJcbiAgICAgICAgICAgICAgICBwYXR0ZXJuICs9IHN1YlBhdHRlcm47XHJcbiAgICAgICAgICAgICAgICBzdWJTZWdtZW50U2NvcmUgKz0gMjAgLyogRHluYW1pYyAqLztcclxuICAgICAgICAgICAgICAgIGlmIChvcHRpb25hbClcclxuICAgICAgICAgICAgICAgICAgICBzdWJTZWdtZW50U2NvcmUgKz0gLTggLyogQm9udXNPcHRpb25hbCAqLztcclxuICAgICAgICAgICAgICAgIGlmIChyZXBlYXRhYmxlKVxyXG4gICAgICAgICAgICAgICAgICAgIHN1YlNlZ21lbnRTY29yZSArPSAtMjAgLyogQm9udXNSZXBlYXRhYmxlICovO1xyXG4gICAgICAgICAgICAgICAgaWYgKHJlID09PSAnLionKVxyXG4gICAgICAgICAgICAgICAgICAgIHN1YlNlZ21lbnRTY29yZSArPSAtNTAgLyogQm9udXNXaWxkY2FyZCAqLztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBzZWdtZW50U2NvcmVzLnB1c2goc3ViU2VnbWVudFNjb3JlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gYW4gZW1wdHkgYXJyYXkgbGlrZSAvaG9tZS8gLT4gW1t7aG9tZX1dLCBbXV1cclxuICAgICAgICAvLyBpZiAoIXNlZ21lbnQubGVuZ3RoKSBwYXR0ZXJuICs9ICcvJ1xyXG4gICAgICAgIHNjb3JlLnB1c2goc2VnbWVudFNjb3Jlcyk7XHJcbiAgICB9XHJcbiAgICAvLyBvbmx5IGFwcGx5IHRoZSBzdHJpY3QgYm9udXMgdG8gdGhlIGxhc3Qgc2NvcmVcclxuICAgIGlmIChvcHRpb25zLnN0cmljdCAmJiBvcHRpb25zLmVuZCkge1xyXG4gICAgICAgIGNvbnN0IGkgPSBzY29yZS5sZW5ndGggLSAxO1xyXG4gICAgICAgIHNjb3JlW2ldW3Njb3JlW2ldLmxlbmd0aCAtIDFdICs9IDAuNzAwMDAwMDAwMDAwMDAwMSAvKiBCb251c1N0cmljdCAqLztcclxuICAgIH1cclxuICAgIC8vIFRPRE86IGRldiBvbmx5IHdhcm4gZG91YmxlIHRyYWlsaW5nIHNsYXNoXHJcbiAgICBpZiAoIW9wdGlvbnMuc3RyaWN0KVxyXG4gICAgICAgIHBhdHRlcm4gKz0gJy8/JztcclxuICAgIGlmIChvcHRpb25zLmVuZClcclxuICAgICAgICBwYXR0ZXJuICs9ICckJztcclxuICAgIC8vIGFsbG93IHBhdGhzIGxpa2UgL2R5bmFtaWMgdG8gb25seSBtYXRjaCBkeW5hbWljIG9yIGR5bmFtaWMvLi4uIGJ1dCBub3QgZHluYW1pY19zb21ldGhpbmdfZWxzZVxyXG4gICAgZWxzZSBpZiAob3B0aW9ucy5zdHJpY3QpXHJcbiAgICAgICAgcGF0dGVybiArPSAnKD86L3wkKSc7XHJcbiAgICBjb25zdCByZSA9IG5ldyBSZWdFeHAocGF0dGVybiwgb3B0aW9ucy5zZW5zaXRpdmUgPyAnJyA6ICdpJyk7XHJcbiAgICBmdW5jdGlvbiBwYXJzZShwYXRoKSB7XHJcbiAgICAgICAgY29uc3QgbWF0Y2ggPSBwYXRoLm1hdGNoKHJlKTtcclxuICAgICAgICBjb25zdCBwYXJhbXMgPSB7fTtcclxuICAgICAgICBpZiAoIW1hdGNoKVxyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IG1hdGNoLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gbWF0Y2hbaV0gfHwgJyc7XHJcbiAgICAgICAgICAgIGNvbnN0IGtleSA9IGtleXNbaSAtIDFdO1xyXG4gICAgICAgICAgICBwYXJhbXNba2V5Lm5hbWVdID0gdmFsdWUgJiYga2V5LnJlcGVhdGFibGUgPyB2YWx1ZS5zcGxpdCgnLycpIDogdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBwYXJhbXM7XHJcbiAgICB9XHJcbiAgICBmdW5jdGlvbiBzdHJpbmdpZnkocGFyYW1zKSB7XHJcbiAgICAgICAgbGV0IHBhdGggPSAnJztcclxuICAgICAgICAvLyBmb3Igb3B0aW9uYWwgcGFyYW1ldGVycyB0byBhbGxvdyB0byBiZSBlbXB0eVxyXG4gICAgICAgIGxldCBhdm9pZER1cGxpY2F0ZWRTbGFzaCA9IGZhbHNlO1xyXG4gICAgICAgIGZvciAoY29uc3Qgc2VnbWVudCBvZiBzZWdtZW50cykge1xyXG4gICAgICAgICAgICBpZiAoIWF2b2lkRHVwbGljYXRlZFNsYXNoIHx8ICFwYXRoLmVuZHNXaXRoKCcvJykpXHJcbiAgICAgICAgICAgICAgICBwYXRoICs9ICcvJztcclxuICAgICAgICAgICAgYXZvaWREdXBsaWNhdGVkU2xhc2ggPSBmYWxzZTtcclxuICAgICAgICAgICAgZm9yIChjb25zdCB0b2tlbiBvZiBzZWdtZW50KSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodG9rZW4udHlwZSA9PT0gMCAvKiBTdGF0aWMgKi8pIHtcclxuICAgICAgICAgICAgICAgICAgICBwYXRoICs9IHRva2VuLnZhbHVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodG9rZW4udHlwZSA9PT0gMSAvKiBQYXJhbSAqLykge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgdmFsdWUsIHJlcGVhdGFibGUsIG9wdGlvbmFsIH0gPSB0b2tlbjtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwYXJhbSA9IHZhbHVlIGluIHBhcmFtcyA/IHBhcmFtc1t2YWx1ZV0gOiAnJztcclxuICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShwYXJhbSkgJiYgIXJlcGVhdGFibGUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgUHJvdmlkZWQgcGFyYW0gXCIke3ZhbHVlfVwiIGlzIGFuIGFycmF5IGJ1dCBpdCBpcyBub3QgcmVwZWF0YWJsZSAoKiBvciArIG1vZGlmaWVycylgKTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCB0ZXh0ID0gQXJyYXkuaXNBcnJheShwYXJhbSkgPyBwYXJhbS5qb2luKCcvJykgOiBwYXJhbTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIXRleHQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbmFsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiB3ZSBoYXZlIG1vcmUgdGhhbiBvbmUgb3B0aW9uYWwgcGFyYW0gbGlrZSAvOmE/LXN0YXRpYyB3ZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZG9uJ3QgbmVlZCB0byBjYXJlIGFib3V0IHRoZSBvcHRpb25hbCBwYXJhbVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlZ21lbnQubGVuZ3RoIDwgMikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlbW92ZSB0aGUgbGFzdCBzbGFzaCBhcyB3ZSBjb3VsZCBiZSBhdCB0aGUgZW5kXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhdGguZW5kc1dpdGgoJy8nKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aCA9IHBhdGguc2xpY2UoMCwgLTEpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRvIG5vdCBhcHBlbmQgYSBzbGFzaCBvbiB0aGUgbmV4dCBpdGVyYXRpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF2b2lkRHVwbGljYXRlZFNsYXNoID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE1pc3NpbmcgcmVxdWlyZWQgcGFyYW0gXCIke3ZhbHVlfVwiYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHBhdGggKz0gdGV4dDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcGF0aDtcclxuICAgIH1cclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgcmUsXHJcbiAgICAgICAgc2NvcmUsXHJcbiAgICAgICAga2V5cyxcclxuICAgICAgICBwYXJzZSxcclxuICAgICAgICBzdHJpbmdpZnksXHJcbiAgICB9O1xyXG59XHJcbi8qKlxyXG4gKiBDb21wYXJlcyBhbiBhcnJheSBvZiBudW1iZXJzIGFzIHVzZWQgaW4gUGF0aFBhcnNlci5zY29yZSBhbmQgcmV0dXJucyBhXHJcbiAqIG51bWJlci4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byBgc29ydGAgYW4gYXJyYXlcclxuICpcclxuICogQHBhcmFtIGEgLSBmaXJzdCBhcnJheSBvZiBudW1iZXJzXHJcbiAqIEBwYXJhbSBiIC0gc2Vjb25kIGFycmF5IG9mIG51bWJlcnNcclxuICogQHJldHVybnMgMCBpZiBib3RoIGFyZSBlcXVhbCwgPCAwIGlmIGEgc2hvdWxkIGJlIHNvcnRlZCBmaXJzdCwgPiAwIGlmIGJcclxuICogc2hvdWxkIGJlIHNvcnRlZCBmaXJzdFxyXG4gKi9cclxuZnVuY3Rpb24gY29tcGFyZVNjb3JlQXJyYXkoYSwgYikge1xyXG4gICAgbGV0IGkgPSAwO1xyXG4gICAgd2hpbGUgKGkgPCBhLmxlbmd0aCAmJiBpIDwgYi5sZW5ndGgpIHtcclxuICAgICAgICBjb25zdCBkaWZmID0gYltpXSAtIGFbaV07XHJcbiAgICAgICAgLy8gb25seSBrZWVwIGdvaW5nIGlmIGRpZmYgPT09IDBcclxuICAgICAgICBpZiAoZGlmZilcclxuICAgICAgICAgICAgcmV0dXJuIGRpZmY7XHJcbiAgICAgICAgaSsrO1xyXG4gICAgfVxyXG4gICAgLy8gaWYgdGhlIGxhc3Qgc3Vic2VnbWVudCB3YXMgU3RhdGljLCB0aGUgc2hvcnRlciBzZWdtZW50cyBzaG91bGQgYmUgc29ydGVkIGZpcnN0XHJcbiAgICAvLyBvdGhlcndpc2Ugc29ydCB0aGUgbG9uZ2VzdCBzZWdtZW50IGZpcnN0XHJcbiAgICBpZiAoYS5sZW5ndGggPCBiLmxlbmd0aCkge1xyXG4gICAgICAgIHJldHVybiBhLmxlbmd0aCA9PT0gMSAmJiBhWzBdID09PSA0MCAvKiBTdGF0aWMgKi8gKyA0MCAvKiBTZWdtZW50ICovXHJcbiAgICAgICAgICAgID8gLTFcclxuICAgICAgICAgICAgOiAxO1xyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAoYS5sZW5ndGggPiBiLmxlbmd0aCkge1xyXG4gICAgICAgIHJldHVybiBiLmxlbmd0aCA9PT0gMSAmJiBiWzBdID09PSA0MCAvKiBTdGF0aWMgKi8gKyA0MCAvKiBTZWdtZW50ICovXHJcbiAgICAgICAgICAgID8gMVxyXG4gICAgICAgICAgICA6IC0xO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIDA7XHJcbn1cclxuLyoqXHJcbiAqIENvbXBhcmUgZnVuY3Rpb24gdGhhdCBjYW4gYmUgdXNlZCB3aXRoIGBzb3J0YCB0byBzb3J0IGFuIGFycmF5IG9mIFBhdGhQYXJzZXJcclxuICpcclxuICogQHBhcmFtIGEgLSBmaXJzdCBQYXRoUGFyc2VyXHJcbiAqIEBwYXJhbSBiIC0gc2Vjb25kIFBhdGhQYXJzZXJcclxuICogQHJldHVybnMgMCBpZiBib3RoIGFyZSBlcXVhbCwgPCAwIGlmIGEgc2hvdWxkIGJlIHNvcnRlZCBmaXJzdCwgPiAwIGlmIGJcclxuICovXHJcbmZ1bmN0aW9uIGNvbXBhcmVQYXRoUGFyc2VyU2NvcmUoYSwgYikge1xyXG4gICAgbGV0IGkgPSAwO1xyXG4gICAgY29uc3QgYVNjb3JlID0gYS5zY29yZTtcclxuICAgIGNvbnN0IGJTY29yZSA9IGIuc2NvcmU7XHJcbiAgICB3aGlsZSAoaSA8IGFTY29yZS5sZW5ndGggJiYgaSA8IGJTY29yZS5sZW5ndGgpIHtcclxuICAgICAgICBjb25zdCBjb21wID0gY29tcGFyZVNjb3JlQXJyYXkoYVNjb3JlW2ldLCBiU2NvcmVbaV0pO1xyXG4gICAgICAgIC8vIGRvIG5vdCByZXR1cm4gaWYgYm90aCBhcmUgZXF1YWxcclxuICAgICAgICBpZiAoY29tcClcclxuICAgICAgICAgICAgcmV0dXJuIGNvbXA7XHJcbiAgICAgICAgaSsrO1xyXG4gICAgfVxyXG4gICAgLy8gaWYgYSBhbmQgYiBzaGFyZSB0aGUgc2FtZSBzY29yZSBlbnRyaWVzIGJ1dCBiIGhhcyBtb3JlLCBzb3J0IGIgZmlyc3RcclxuICAgIHJldHVybiBiU2NvcmUubGVuZ3RoIC0gYVNjb3JlLmxlbmd0aDtcclxuICAgIC8vIHRoaXMgaXMgdGhlIHRlcm5hcnkgdmVyc2lvblxyXG4gICAgLy8gcmV0dXJuIGFTY29yZS5sZW5ndGggPCBiU2NvcmUubGVuZ3RoXHJcbiAgICAvLyAgID8gMVxyXG4gICAgLy8gICA6IGFTY29yZS5sZW5ndGggPiBiU2NvcmUubGVuZ3RoXHJcbiAgICAvLyAgID8gLTFcclxuICAgIC8vICAgOiAwXHJcbn1cblxuY29uc3QgUk9PVF9UT0tFTiA9IHtcclxuICAgIHR5cGU6IDAgLyogU3RhdGljICovLFxyXG4gICAgdmFsdWU6ICcnLFxyXG59O1xyXG5jb25zdCBWQUxJRF9QQVJBTV9SRSA9IC9bYS16QS1aMC05X10vO1xyXG4vLyBBZnRlciBzb21lIHByb2ZpbGluZywgdGhlIGNhY2hlIHNlZW1zIHRvIGJlIHVubmVjZXNzYXJ5IGJlY2F1c2UgdG9rZW5pemVQYXRoXHJcbi8vICh0aGUgc2xvd2VzdCBwYXJ0IG9mIGFkZGluZyBhIHJvdXRlKSBpcyB2ZXJ5IGZhc3RcclxuLy8gY29uc3QgdG9rZW5DYWNoZSA9IG5ldyBNYXA8c3RyaW5nLCBUb2tlbltdW10+KClcclxuZnVuY3Rpb24gdG9rZW5pemVQYXRoKHBhdGgpIHtcclxuICAgIGlmICghcGF0aClcclxuICAgICAgICByZXR1cm4gW1tdXTtcclxuICAgIGlmIChwYXRoID09PSAnLycpXHJcbiAgICAgICAgcmV0dXJuIFtbUk9PVF9UT0tFTl1dO1xyXG4gICAgaWYgKCFwYXRoLnN0YXJ0c1dpdGgoJy8nKSkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcigocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJylcclxuICAgICAgICAgICAgPyBgUm91dGUgcGF0aHMgc2hvdWxkIHN0YXJ0IHdpdGggYSBcIi9cIjogXCIke3BhdGh9XCIgc2hvdWxkIGJlIFwiLyR7cGF0aH1cIi5gXHJcbiAgICAgICAgICAgIDogYEludmFsaWQgcGF0aCBcIiR7cGF0aH1cImApO1xyXG4gICAgfVxyXG4gICAgLy8gaWYgKHRva2VuQ2FjaGUuaGFzKHBhdGgpKSByZXR1cm4gdG9rZW5DYWNoZS5nZXQocGF0aCkhXHJcbiAgICBmdW5jdGlvbiBjcmFzaChtZXNzYWdlKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBFUlIgKCR7c3RhdGV9KS9cIiR7YnVmZmVyfVwiOiAke21lc3NhZ2V9YCk7XHJcbiAgICB9XHJcbiAgICBsZXQgc3RhdGUgPSAwIC8qIFN0YXRpYyAqLztcclxuICAgIGxldCBwcmV2aW91c1N0YXRlID0gc3RhdGU7XHJcbiAgICBjb25zdCB0b2tlbnMgPSBbXTtcclxuICAgIC8vIHRoZSBzZWdtZW50IHdpbGwgYWx3YXlzIGJlIHZhbGlkIGJlY2F1c2Ugd2UgZ2V0IGludG8gdGhlIGluaXRpYWwgc3RhdGVcclxuICAgIC8vIHdpdGggdGhlIGxlYWRpbmcgL1xyXG4gICAgbGV0IHNlZ21lbnQ7XHJcbiAgICBmdW5jdGlvbiBmaW5hbGl6ZVNlZ21lbnQoKSB7XHJcbiAgICAgICAgaWYgKHNlZ21lbnQpXHJcbiAgICAgICAgICAgIHRva2Vucy5wdXNoKHNlZ21lbnQpO1xyXG4gICAgICAgIHNlZ21lbnQgPSBbXTtcclxuICAgIH1cclxuICAgIC8vIGluZGV4IG9uIHRoZSBwYXRoXHJcbiAgICBsZXQgaSA9IDA7XHJcbiAgICAvLyBjaGFyIGF0IGluZGV4XHJcbiAgICBsZXQgY2hhcjtcclxuICAgIC8vIGJ1ZmZlciBvZiB0aGUgdmFsdWUgcmVhZFxyXG4gICAgbGV0IGJ1ZmZlciA9ICcnO1xyXG4gICAgLy8gY3VzdG9tIHJlZ2V4cCBmb3IgYSBwYXJhbVxyXG4gICAgbGV0IGN1c3RvbVJlID0gJyc7XHJcbiAgICBmdW5jdGlvbiBjb25zdW1lQnVmZmVyKCkge1xyXG4gICAgICAgIGlmICghYnVmZmVyKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgaWYgKHN0YXRlID09PSAwIC8qIFN0YXRpYyAqLykge1xyXG4gICAgICAgICAgICBzZWdtZW50LnB1c2goe1xyXG4gICAgICAgICAgICAgICAgdHlwZTogMCAvKiBTdGF0aWMgKi8sXHJcbiAgICAgICAgICAgICAgICB2YWx1ZTogYnVmZmVyLFxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoc3RhdGUgPT09IDEgLyogUGFyYW0gKi8gfHxcclxuICAgICAgICAgICAgc3RhdGUgPT09IDIgLyogUGFyYW1SZWdFeHAgKi8gfHxcclxuICAgICAgICAgICAgc3RhdGUgPT09IDMgLyogUGFyYW1SZWdFeHBFbmQgKi8pIHtcclxuICAgICAgICAgICAgaWYgKHNlZ21lbnQubGVuZ3RoID4gMSAmJiAoY2hhciA9PT0gJyonIHx8IGNoYXIgPT09ICcrJykpXHJcbiAgICAgICAgICAgICAgICBjcmFzaChgQSByZXBlYXRhYmxlIHBhcmFtICgke2J1ZmZlcn0pIG11c3QgYmUgYWxvbmUgaW4gaXRzIHNlZ21lbnQuIGVnOiAnLzppZHMrLmApO1xyXG4gICAgICAgICAgICBzZWdtZW50LnB1c2goe1xyXG4gICAgICAgICAgICAgICAgdHlwZTogMSAvKiBQYXJhbSAqLyxcclxuICAgICAgICAgICAgICAgIHZhbHVlOiBidWZmZXIsXHJcbiAgICAgICAgICAgICAgICByZWdleHA6IGN1c3RvbVJlLFxyXG4gICAgICAgICAgICAgICAgcmVwZWF0YWJsZTogY2hhciA9PT0gJyonIHx8IGNoYXIgPT09ICcrJyxcclxuICAgICAgICAgICAgICAgIG9wdGlvbmFsOiBjaGFyID09PSAnKicgfHwgY2hhciA9PT0gJz8nLFxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGNyYXNoKCdJbnZhbGlkIHN0YXRlIHRvIGNvbnN1bWUgYnVmZmVyJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGJ1ZmZlciA9ICcnO1xyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gYWRkQ2hhclRvQnVmZmVyKCkge1xyXG4gICAgICAgIGJ1ZmZlciArPSBjaGFyO1xyXG4gICAgfVxyXG4gICAgd2hpbGUgKGkgPCBwYXRoLmxlbmd0aCkge1xyXG4gICAgICAgIGNoYXIgPSBwYXRoW2krK107XHJcbiAgICAgICAgaWYgKGNoYXIgPT09ICdcXFxcJyAmJiBzdGF0ZSAhPT0gMiAvKiBQYXJhbVJlZ0V4cCAqLykge1xyXG4gICAgICAgICAgICBwcmV2aW91c1N0YXRlID0gc3RhdGU7XHJcbiAgICAgICAgICAgIHN0YXRlID0gNCAvKiBFc2NhcGVOZXh0ICovO1xyXG4gICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgc3dpdGNoIChzdGF0ZSkge1xyXG4gICAgICAgICAgICBjYXNlIDAgLyogU3RhdGljICovOlxyXG4gICAgICAgICAgICAgICAgaWYgKGNoYXIgPT09ICcvJykge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChidWZmZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3VtZUJ1ZmZlcigpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmaW5hbGl6ZVNlZ21lbnQoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNoYXIgPT09ICc6Jykge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN1bWVCdWZmZXIoKTtcclxuICAgICAgICAgICAgICAgICAgICBzdGF0ZSA9IDEgLyogUGFyYW0gKi87XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBhZGRDaGFyVG9CdWZmZXIoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlIDQgLyogRXNjYXBlTmV4dCAqLzpcclxuICAgICAgICAgICAgICAgIGFkZENoYXJUb0J1ZmZlcigpO1xyXG4gICAgICAgICAgICAgICAgc3RhdGUgPSBwcmV2aW91c1N0YXRlO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgMSAvKiBQYXJhbSAqLzpcclxuICAgICAgICAgICAgICAgIGlmIChjaGFyID09PSAnKCcpIHtcclxuICAgICAgICAgICAgICAgICAgICBzdGF0ZSA9IDIgLyogUGFyYW1SZWdFeHAgKi87XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmIChWQUxJRF9QQVJBTV9SRS50ZXN0KGNoYXIpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYWRkQ2hhclRvQnVmZmVyKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdW1lQnVmZmVyKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgc3RhdGUgPSAwIC8qIFN0YXRpYyAqLztcclxuICAgICAgICAgICAgICAgICAgICAvLyBnbyBiYWNrIG9uZSBjaGFyYWN0ZXIgaWYgd2Ugd2VyZSBub3QgbW9kaWZ5aW5nXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNoYXIgIT09ICcqJyAmJiBjaGFyICE9PSAnPycgJiYgY2hhciAhPT0gJysnKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpLS07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgY2FzZSAyIC8qIFBhcmFtUmVnRXhwICovOlxyXG4gICAgICAgICAgICAgICAgLy8gVE9ETzogaXMgaXQgd29ydGggaGFuZGxpbmcgbmVzdGVkIHJlZ2V4cD8gbGlrZSA6cCg/OnByZWZpeF8oW14vXSspX3N1ZmZpeClcclxuICAgICAgICAgICAgICAgIC8vIGl0IGFscmVhZHkgd29ya3MgYnkgZXNjYXBpbmcgdGhlIGNsb3NpbmcgKVxyXG4gICAgICAgICAgICAgICAgLy8gaHR0cHM6Ly9wYXRocy5lc20uZGV2Lz9wPUFBTWVKYmlBd1FFY0RLYkFvQUFrUDYwUEcyUjZRQXZnTmFBNkFGQUNNMkFCdVFCQiNcclxuICAgICAgICAgICAgICAgIC8vIGlzIHRoaXMgcmVhbGx5IHNvbWV0aGluZyBwZW9wbGUgbmVlZCBzaW5jZSB5b3UgY2FuIGFsc28gd3JpdGVcclxuICAgICAgICAgICAgICAgIC8vIC9wcmVmaXhfOnAoKV9zdWZmaXhcclxuICAgICAgICAgICAgICAgIGlmIChjaGFyID09PSAnKScpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBoYW5kbGUgdGhlIGVzY2FwZWQgKVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjdXN0b21SZVtjdXN0b21SZS5sZW5ndGggLSAxXSA9PSAnXFxcXCcpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1c3RvbVJlID0gY3VzdG9tUmUuc2xpY2UoMCwgLTEpICsgY2hhcjtcclxuICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlID0gMyAvKiBQYXJhbVJlZ0V4cEVuZCAqLztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGN1c3RvbVJlICs9IGNoYXI7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgY2FzZSAzIC8qIFBhcmFtUmVnRXhwRW5kICovOlxyXG4gICAgICAgICAgICAgICAgLy8gc2FtZSBhcyBmaW5hbGl6aW5nIGEgcGFyYW1cclxuICAgICAgICAgICAgICAgIGNvbnN1bWVCdWZmZXIoKTtcclxuICAgICAgICAgICAgICAgIHN0YXRlID0gMCAvKiBTdGF0aWMgKi87XHJcbiAgICAgICAgICAgICAgICAvLyBnbyBiYWNrIG9uZSBjaGFyYWN0ZXIgaWYgd2Ugd2VyZSBub3QgbW9kaWZ5aW5nXHJcbiAgICAgICAgICAgICAgICBpZiAoY2hhciAhPT0gJyonICYmIGNoYXIgIT09ICc/JyAmJiBjaGFyICE9PSAnKycpXHJcbiAgICAgICAgICAgICAgICAgICAgaS0tO1xyXG4gICAgICAgICAgICAgICAgY3VzdG9tUmUgPSAnJztcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgY3Jhc2goJ1Vua25vd24gc3RhdGUnKTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGlmIChzdGF0ZSA9PT0gMiAvKiBQYXJhbVJlZ0V4cCAqLylcclxuICAgICAgICBjcmFzaChgVW5maW5pc2hlZCBjdXN0b20gUmVnRXhwIGZvciBwYXJhbSBcIiR7YnVmZmVyfVwiYCk7XHJcbiAgICBjb25zdW1lQnVmZmVyKCk7XHJcbiAgICBmaW5hbGl6ZVNlZ21lbnQoKTtcclxuICAgIC8vIHRva2VuQ2FjaGUuc2V0KHBhdGgsIHRva2VucylcclxuICAgIHJldHVybiB0b2tlbnM7XHJcbn1cblxuZnVuY3Rpb24gY3JlYXRlUm91dGVSZWNvcmRNYXRjaGVyKHJlY29yZCwgcGFyZW50LCBvcHRpb25zKSB7XHJcbiAgICBjb25zdCBwYXJzZXIgPSB0b2tlbnNUb1BhcnNlcih0b2tlbml6ZVBhdGgocmVjb3JkLnBhdGgpLCBvcHRpb25zKTtcclxuICAgIC8vIHdhcm4gYWdhaW5zdCBwYXJhbXMgd2l0aCB0aGUgc2FtZSBuYW1lXHJcbiAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpKSB7XHJcbiAgICAgICAgY29uc3QgZXhpc3RpbmdLZXlzID0gbmV3IFNldCgpO1xyXG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIHBhcnNlci5rZXlzKSB7XHJcbiAgICAgICAgICAgIGlmIChleGlzdGluZ0tleXMuaGFzKGtleS5uYW1lKSlcclxuICAgICAgICAgICAgICAgIHdhcm4oYEZvdW5kIGR1cGxpY2F0ZWQgcGFyYW1zIHdpdGggbmFtZSBcIiR7a2V5Lm5hbWV9XCIgZm9yIHBhdGggXCIke3JlY29yZC5wYXRofVwiLiBPbmx5IHRoZSBsYXN0IG9uZSB3aWxsIGJlIGF2YWlsYWJsZSBvbiBcIiRyb3V0ZS5wYXJhbXNcIi5gKTtcclxuICAgICAgICAgICAgZXhpc3RpbmdLZXlzLmFkZChrZXkubmFtZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgY29uc3QgbWF0Y2hlciA9IGFzc2lnbihwYXJzZXIsIHtcclxuICAgICAgICByZWNvcmQsXHJcbiAgICAgICAgcGFyZW50LFxyXG4gICAgICAgIC8vIHRoZXNlIG5lZWRzIHRvIGJlIHBvcHVsYXRlZCBieSB0aGUgcGFyZW50XHJcbiAgICAgICAgY2hpbGRyZW46IFtdLFxyXG4gICAgICAgIGFsaWFzOiBbXSxcclxuICAgIH0pO1xyXG4gICAgaWYgKHBhcmVudCkge1xyXG4gICAgICAgIC8vIGJvdGggYXJlIGFsaWFzZXMgb3IgYm90aCBhcmUgbm90IGFsaWFzZXNcclxuICAgICAgICAvLyB3ZSBkb24ndCB3YW50IHRvIG1peCB0aGVtIGJlY2F1c2UgdGhlIG9yZGVyIGlzIHVzZWQgd2hlblxyXG4gICAgICAgIC8vIHBhc3Npbmcgb3JpZ2luYWxSZWNvcmQgaW4gTWF0Y2hlci5hZGRSb3V0ZVxyXG4gICAgICAgIGlmICghbWF0Y2hlci5yZWNvcmQuYWxpYXNPZiA9PT0gIXBhcmVudC5yZWNvcmQuYWxpYXNPZilcclxuICAgICAgICAgICAgcGFyZW50LmNoaWxkcmVuLnB1c2gobWF0Y2hlcik7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbWF0Y2hlcjtcclxufVxuXG4vKipcclxuICogQ3JlYXRlcyBhIFJvdXRlciBNYXRjaGVyLlxyXG4gKlxyXG4gKiBAaW50ZXJuYWxcclxuICogQHBhcmFtIHJvdXRlcyAtIGFycmF5IG9mIGluaXRpYWwgcm91dGVzXHJcbiAqIEBwYXJhbSBnbG9iYWxPcHRpb25zIC0gZ2xvYmFsIHJvdXRlIG9wdGlvbnNcclxuICovXHJcbmZ1bmN0aW9uIGNyZWF0ZVJvdXRlck1hdGNoZXIocm91dGVzLCBnbG9iYWxPcHRpb25zKSB7XHJcbiAgICAvLyBub3JtYWxpemVkIG9yZGVyZWQgYXJyYXkgb2YgbWF0Y2hlcnNcclxuICAgIGNvbnN0IG1hdGNoZXJzID0gW107XHJcbiAgICBjb25zdCBtYXRjaGVyTWFwID0gbmV3IE1hcCgpO1xyXG4gICAgZ2xvYmFsT3B0aW9ucyA9IG1lcmdlT3B0aW9ucyh7IHN0cmljdDogZmFsc2UsIGVuZDogdHJ1ZSwgc2Vuc2l0aXZlOiBmYWxzZSB9LCBnbG9iYWxPcHRpb25zKTtcclxuICAgIGZ1bmN0aW9uIGdldFJlY29yZE1hdGNoZXIobmFtZSkge1xyXG4gICAgICAgIHJldHVybiBtYXRjaGVyTWFwLmdldChuYW1lKTtcclxuICAgIH1cclxuICAgIGZ1bmN0aW9uIGFkZFJvdXRlKHJlY29yZCwgcGFyZW50LCBvcmlnaW5hbFJlY29yZCkge1xyXG4gICAgICAgIC8vIHVzZWQgbGF0ZXIgb24gdG8gcmVtb3ZlIGJ5IG5hbWVcclxuICAgICAgICBjb25zdCBpc1Jvb3RBZGQgPSAhb3JpZ2luYWxSZWNvcmQ7XHJcbiAgICAgICAgY29uc3QgbWFpbk5vcm1hbGl6ZWRSZWNvcmQgPSBub3JtYWxpemVSb3V0ZVJlY29yZChyZWNvcmQpO1xyXG4gICAgICAgIC8vIHdlIG1pZ2h0IGJlIHRoZSBjaGlsZCBvZiBhbiBhbGlhc1xyXG4gICAgICAgIG1haW5Ob3JtYWxpemVkUmVjb3JkLmFsaWFzT2YgPSBvcmlnaW5hbFJlY29yZCAmJiBvcmlnaW5hbFJlY29yZC5yZWNvcmQ7XHJcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG1lcmdlT3B0aW9ucyhnbG9iYWxPcHRpb25zLCByZWNvcmQpO1xyXG4gICAgICAgIC8vIGdlbmVyYXRlIGFuIGFycmF5IG9mIHJlY29yZHMgdG8gY29ycmVjdGx5IGhhbmRsZSBhbGlhc2VzXHJcbiAgICAgICAgY29uc3Qgbm9ybWFsaXplZFJlY29yZHMgPSBbXHJcbiAgICAgICAgICAgIG1haW5Ob3JtYWxpemVkUmVjb3JkLFxyXG4gICAgICAgIF07XHJcbiAgICAgICAgaWYgKCdhbGlhcycgaW4gcmVjb3JkKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGFsaWFzZXMgPSB0eXBlb2YgcmVjb3JkLmFsaWFzID09PSAnc3RyaW5nJyA/IFtyZWNvcmQuYWxpYXNdIDogcmVjb3JkLmFsaWFzO1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGFsaWFzIG9mIGFsaWFzZXMpIHtcclxuICAgICAgICAgICAgICAgIG5vcm1hbGl6ZWRSZWNvcmRzLnB1c2goYXNzaWduKHt9LCBtYWluTm9ybWFsaXplZFJlY29yZCwge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgYWxsb3dzIHVzIHRvIGhvbGQgYSBjb3B5IG9mIHRoZSBgY29tcG9uZW50c2Agb3B0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gc28gdGhhdCBhc3luYyBjb21wb25lbnRzIGNhY2hlIGlzIGhvbGQgb24gdGhlIG9yaWdpbmFsIHJlY29yZFxyXG4gICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudHM6IG9yaWdpbmFsUmVjb3JkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgID8gb3JpZ2luYWxSZWNvcmQucmVjb3JkLmNvbXBvbmVudHNcclxuICAgICAgICAgICAgICAgICAgICAgICAgOiBtYWluTm9ybWFsaXplZFJlY29yZC5jb21wb25lbnRzLFxyXG4gICAgICAgICAgICAgICAgICAgIHBhdGg6IGFsaWFzLFxyXG4gICAgICAgICAgICAgICAgICAgIC8vIHdlIG1pZ2h0IGJlIHRoZSBjaGlsZCBvZiBhbiBhbGlhc1xyXG4gICAgICAgICAgICAgICAgICAgIGFsaWFzT2Y6IG9yaWdpbmFsUmVjb3JkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgID8gb3JpZ2luYWxSZWNvcmQucmVjb3JkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDogbWFpbk5vcm1hbGl6ZWRSZWNvcmQsXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGFsaWFzZXMgYXJlIGFsd2F5cyBvZiB0aGUgc2FtZSBraW5kIGFzIHRoZSBvcmlnaW5hbCBzaW5jZSB0aGV5XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gYXJlIGRlZmluZWQgb24gdGhlIHNhbWUgcmVjb3JkXHJcbiAgICAgICAgICAgICAgICB9KSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgbGV0IG1hdGNoZXI7XHJcbiAgICAgICAgbGV0IG9yaWdpbmFsTWF0Y2hlcjtcclxuICAgICAgICBmb3IgKGNvbnN0IG5vcm1hbGl6ZWRSZWNvcmQgb2Ygbm9ybWFsaXplZFJlY29yZHMpIHtcclxuICAgICAgICAgICAgY29uc3QgeyBwYXRoIH0gPSBub3JtYWxpemVkUmVjb3JkO1xyXG4gICAgICAgICAgICAvLyBCdWlsZCB1cCB0aGUgcGF0aCBmb3IgbmVzdGVkIHJvdXRlcyBpZiB0aGUgY2hpbGQgaXNuJ3QgYW4gYWJzb2x1dGVcclxuICAgICAgICAgICAgLy8gcm91dGUuIE9ubHkgYWRkIHRoZSAvIGRlbGltaXRlciBpZiB0aGUgY2hpbGQgcGF0aCBpc24ndCBlbXB0eSBhbmQgaWYgdGhlXHJcbiAgICAgICAgICAgIC8vIHBhcmVudCBwYXRoIGRvZXNuJ3QgaGF2ZSBhIHRyYWlsaW5nIHNsYXNoXHJcbiAgICAgICAgICAgIGlmIChwYXJlbnQgJiYgcGF0aFswXSAhPT0gJy8nKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBwYXJlbnRQYXRoID0gcGFyZW50LnJlY29yZC5wYXRoO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgY29ubmVjdGluZ1NsYXNoID0gcGFyZW50UGF0aFtwYXJlbnRQYXRoLmxlbmd0aCAtIDFdID09PSAnLycgPyAnJyA6ICcvJztcclxuICAgICAgICAgICAgICAgIG5vcm1hbGl6ZWRSZWNvcmQucGF0aCA9XHJcbiAgICAgICAgICAgICAgICAgICAgcGFyZW50LnJlY29yZC5wYXRoICsgKHBhdGggJiYgY29ubmVjdGluZ1NsYXNoICsgcGF0aCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiBub3JtYWxpemVkUmVjb3JkLnBhdGggPT09ICcqJykge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYXRjaCBhbGwgcm91dGVzIChcIipcIikgbXVzdCBub3cgYmUgZGVmaW5lZCB1c2luZyBhIHBhcmFtIHdpdGggYSBjdXN0b20gcmVnZXhwLlxcbicgK1xyXG4gICAgICAgICAgICAgICAgICAgICdTZWUgbW9yZSBhdCBodHRwczovL25leHQucm91dGVyLnZ1ZWpzLm9yZy9ndWlkZS9taWdyYXRpb24vI3JlbW92ZWQtc3Rhci1vci1jYXRjaC1hbGwtcm91dGVzLicpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIGNyZWF0ZSB0aGUgb2JqZWN0IGJlZm9yZSBoYW5kIHNvIGl0IGNhbiBiZSBwYXNzZWQgdG8gY2hpbGRyZW5cclxuICAgICAgICAgICAgbWF0Y2hlciA9IGNyZWF0ZVJvdXRlUmVjb3JkTWF0Y2hlcihub3JtYWxpemVkUmVjb3JkLCBwYXJlbnQsIG9wdGlvbnMpO1xyXG4gICAgICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmIHBhcmVudCAmJiBwYXRoWzBdID09PSAnLycpXHJcbiAgICAgICAgICAgICAgICBjaGVja01pc3NpbmdQYXJhbXNJbkFic29sdXRlUGF0aChtYXRjaGVyLCBwYXJlbnQpO1xyXG4gICAgICAgICAgICAvLyBpZiB3ZSBhcmUgYW4gYWxpYXMgd2UgbXVzdCB0ZWxsIHRoZSBvcmlnaW5hbCByZWNvcmQgdGhhdCB3ZSBleGlzdFxyXG4gICAgICAgICAgICAvLyBzbyB3ZSBjYW4gYmUgcmVtb3ZlZFxyXG4gICAgICAgICAgICBpZiAob3JpZ2luYWxSZWNvcmQpIHtcclxuICAgICAgICAgICAgICAgIG9yaWdpbmFsUmVjb3JkLmFsaWFzLnB1c2gobWF0Y2hlcik7XHJcbiAgICAgICAgICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2hlY2tTYW1lUGFyYW1zKG9yaWdpbmFsUmVjb3JkLCBtYXRjaGVyKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIC8vIG90aGVyd2lzZSwgdGhlIGZpcnN0IHJlY29yZCBpcyB0aGUgb3JpZ2luYWwgYW5kIG90aGVycyBhcmUgYWxpYXNlc1xyXG4gICAgICAgICAgICAgICAgb3JpZ2luYWxNYXRjaGVyID0gb3JpZ2luYWxNYXRjaGVyIHx8IG1hdGNoZXI7XHJcbiAgICAgICAgICAgICAgICBpZiAob3JpZ2luYWxNYXRjaGVyICE9PSBtYXRjaGVyKVxyXG4gICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsTWF0Y2hlci5hbGlhcy5wdXNoKG1hdGNoZXIpO1xyXG4gICAgICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSByb3V0ZSBpZiBuYW1lZCBhbmQgb25seSBmb3IgdGhlIHRvcCByZWNvcmQgKGF2b2lkIGluIG5lc3RlZCBjYWxscylcclxuICAgICAgICAgICAgICAgIC8vIHRoaXMgd29ya3MgYmVjYXVzZSB0aGUgb3JpZ2luYWwgcmVjb3JkIGlzIHRoZSBmaXJzdCBvbmVcclxuICAgICAgICAgICAgICAgIGlmIChpc1Jvb3RBZGQgJiYgcmVjb3JkLm5hbWUgJiYgIWlzQWxpYXNSZWNvcmQobWF0Y2hlcikpXHJcbiAgICAgICAgICAgICAgICAgICAgcmVtb3ZlUm91dGUocmVjb3JkLm5hbWUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICgnY2hpbGRyZW4nIGluIG1haW5Ob3JtYWxpemVkUmVjb3JkKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBjaGlsZHJlbiA9IG1haW5Ob3JtYWxpemVkUmVjb3JkLmNoaWxkcmVuO1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGFkZFJvdXRlKGNoaWxkcmVuW2ldLCBtYXRjaGVyLCBvcmlnaW5hbFJlY29yZCAmJiBvcmlnaW5hbFJlY29yZC5jaGlsZHJlbltpXSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gaWYgdGhlcmUgd2FzIG5vIG9yaWdpbmFsIHJlY29yZCwgdGhlbiB0aGUgZmlyc3Qgb25lIHdhcyBub3QgYW4gYWxpYXMgYW5kIGFsbFxyXG4gICAgICAgICAgICAvLyBvdGhlciBhbGlhcyAoaWYgYW55KSBuZWVkIHRvIHJlZmVyZW5jZSB0aGlzIHJlY29yZCB3aGVuIGFkZGluZyBjaGlsZHJlblxyXG4gICAgICAgICAgICBvcmlnaW5hbFJlY29yZCA9IG9yaWdpbmFsUmVjb3JkIHx8IG1hdGNoZXI7XHJcbiAgICAgICAgICAgIC8vIFRPRE86IGFkZCBub3JtYWxpemVkIHJlY29yZHMgZm9yIG1vcmUgZmxleGliaWxpdHlcclxuICAgICAgICAgICAgLy8gaWYgKHBhcmVudCAmJiBpc0FsaWFzUmVjb3JkKG9yaWdpbmFsUmVjb3JkKSkge1xyXG4gICAgICAgICAgICAvLyAgIHBhcmVudC5jaGlsZHJlbi5wdXNoKG9yaWdpbmFsUmVjb3JkKVxyXG4gICAgICAgICAgICAvLyB9XHJcbiAgICAgICAgICAgIGluc2VydE1hdGNoZXIobWF0Y2hlcik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBvcmlnaW5hbE1hdGNoZXJcclxuICAgICAgICAgICAgPyAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAvLyBzaW5jZSBvdGhlciBtYXRjaGVycyBhcmUgYWxpYXNlcywgdGhleSBzaG91bGQgYmUgcmVtb3ZlZCBieSB0aGUgb3JpZ2luYWwgbWF0Y2hlclxyXG4gICAgICAgICAgICAgICAgcmVtb3ZlUm91dGUob3JpZ2luYWxNYXRjaGVyKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICA6IG5vb3A7XHJcbiAgICB9XHJcbiAgICBmdW5jdGlvbiByZW1vdmVSb3V0ZShtYXRjaGVyUmVmKSB7XHJcbiAgICAgICAgaWYgKGlzUm91dGVOYW1lKG1hdGNoZXJSZWYpKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IG1hdGNoZXIgPSBtYXRjaGVyTWFwLmdldChtYXRjaGVyUmVmKTtcclxuICAgICAgICAgICAgaWYgKG1hdGNoZXIpIHtcclxuICAgICAgICAgICAgICAgIG1hdGNoZXJNYXAuZGVsZXRlKG1hdGNoZXJSZWYpO1xyXG4gICAgICAgICAgICAgICAgbWF0Y2hlcnMuc3BsaWNlKG1hdGNoZXJzLmluZGV4T2YobWF0Y2hlciksIDEpO1xyXG4gICAgICAgICAgICAgICAgbWF0Y2hlci5jaGlsZHJlbi5mb3JFYWNoKHJlbW92ZVJvdXRlKTtcclxuICAgICAgICAgICAgICAgIG1hdGNoZXIuYWxpYXMuZm9yRWFjaChyZW1vdmVSb3V0ZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gbWF0Y2hlcnMuaW5kZXhPZihtYXRjaGVyUmVmKTtcclxuICAgICAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcclxuICAgICAgICAgICAgICAgIG1hdGNoZXJzLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICAgICAgICAgICAgICBpZiAobWF0Y2hlclJlZi5yZWNvcmQubmFtZSlcclxuICAgICAgICAgICAgICAgICAgICBtYXRjaGVyTWFwLmRlbGV0ZShtYXRjaGVyUmVmLnJlY29yZC5uYW1lKTtcclxuICAgICAgICAgICAgICAgIG1hdGNoZXJSZWYuY2hpbGRyZW4uZm9yRWFjaChyZW1vdmVSb3V0ZSk7XHJcbiAgICAgICAgICAgICAgICBtYXRjaGVyUmVmLmFsaWFzLmZvckVhY2gocmVtb3ZlUm91dGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gZ2V0Um91dGVzKCkge1xyXG4gICAgICAgIHJldHVybiBtYXRjaGVycztcclxuICAgIH1cclxuICAgIGZ1bmN0aW9uIGluc2VydE1hdGNoZXIobWF0Y2hlcikge1xyXG4gICAgICAgIGxldCBpID0gMDtcclxuICAgICAgICAvLyBjb25zb2xlLmxvZygnaSBpcycsIHsgaSB9KVxyXG4gICAgICAgIHdoaWxlIChpIDwgbWF0Y2hlcnMubGVuZ3RoICYmXHJcbiAgICAgICAgICAgIGNvbXBhcmVQYXRoUGFyc2VyU2NvcmUobWF0Y2hlciwgbWF0Y2hlcnNbaV0pID49IDApXHJcbiAgICAgICAgICAgIGkrKztcclxuICAgICAgICAvLyBjb25zb2xlLmxvZygnRU5EIGkgaXMnLCB7IGkgfSlcclxuICAgICAgICAvLyB3aGlsZSAoaSA8IG1hdGNoZXJzLmxlbmd0aCAmJiBtYXRjaGVyLnNjb3JlIDw9IG1hdGNoZXJzW2ldLnNjb3JlKSBpKytcclxuICAgICAgICBtYXRjaGVycy5zcGxpY2UoaSwgMCwgbWF0Y2hlcik7XHJcbiAgICAgICAgLy8gb25seSBhZGQgdGhlIG9yaWdpbmFsIHJlY29yZCB0byB0aGUgbmFtZSBtYXBcclxuICAgICAgICBpZiAobWF0Y2hlci5yZWNvcmQubmFtZSAmJiAhaXNBbGlhc1JlY29yZChtYXRjaGVyKSlcclxuICAgICAgICAgICAgbWF0Y2hlck1hcC5zZXQobWF0Y2hlci5yZWNvcmQubmFtZSwgbWF0Y2hlcik7XHJcbiAgICB9XHJcbiAgICBmdW5jdGlvbiByZXNvbHZlKGxvY2F0aW9uLCBjdXJyZW50TG9jYXRpb24pIHtcclxuICAgICAgICBsZXQgbWF0Y2hlcjtcclxuICAgICAgICBsZXQgcGFyYW1zID0ge307XHJcbiAgICAgICAgbGV0IHBhdGg7XHJcbiAgICAgICAgbGV0IG5hbWU7XHJcbiAgICAgICAgaWYgKCduYW1lJyBpbiBsb2NhdGlvbiAmJiBsb2NhdGlvbi5uYW1lKSB7XHJcbiAgICAgICAgICAgIG1hdGNoZXIgPSBtYXRjaGVyTWFwLmdldChsb2NhdGlvbi5uYW1lKTtcclxuICAgICAgICAgICAgaWYgKCFtYXRjaGVyKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlUm91dGVyRXJyb3IoMSAvKiBNQVRDSEVSX05PVF9GT1VORCAqLywge1xyXG4gICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uLFxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIG5hbWUgPSBtYXRjaGVyLnJlY29yZC5uYW1lO1xyXG4gICAgICAgICAgICBwYXJhbXMgPSBhc3NpZ24oXHJcbiAgICAgICAgICAgIC8vIHBhcmFtc0Zyb21Mb2NhdGlvbiBpcyBhIG5ldyBvYmplY3RcclxuICAgICAgICAgICAgcGFyYW1zRnJvbUxvY2F0aW9uKGN1cnJlbnRMb2NhdGlvbi5wYXJhbXMsIFxyXG4gICAgICAgICAgICAvLyBvbmx5IGtlZXAgcGFyYW1zIHRoYXQgZXhpc3QgaW4gdGhlIHJlc29sdmVkIGxvY2F0aW9uXHJcbiAgICAgICAgICAgIC8vIFRPRE86IG9ubHkga2VlcCBvcHRpb25hbCBwYXJhbXMgY29taW5nIGZyb20gYSBwYXJlbnQgcmVjb3JkXHJcbiAgICAgICAgICAgIG1hdGNoZXIua2V5cy5maWx0ZXIoayA9PiAhay5vcHRpb25hbCkubWFwKGsgPT4gay5uYW1lKSksIGxvY2F0aW9uLnBhcmFtcyk7XHJcbiAgICAgICAgICAgIC8vIHRocm93cyBpZiBjYW5ub3QgYmUgc3RyaW5naWZpZWRcclxuICAgICAgICAgICAgcGF0aCA9IG1hdGNoZXIuc3RyaW5naWZ5KHBhcmFtcyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKCdwYXRoJyBpbiBsb2NhdGlvbikge1xyXG4gICAgICAgICAgICAvLyBubyBuZWVkIHRvIHJlc29sdmUgdGhlIHBhdGggd2l0aCB0aGUgbWF0Y2hlciBhcyBpdCB3YXMgcHJvdmlkZWRcclxuICAgICAgICAgICAgLy8gdGhpcyBhbHNvIGFsbG93cyB0aGUgdXNlciB0byBjb250cm9sIHRoZSBlbmNvZGluZ1xyXG4gICAgICAgICAgICBwYXRoID0gbG9jYXRpb24ucGF0aDtcclxuICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiAhcGF0aC5zdGFydHNXaXRoKCcvJykpIHtcclxuICAgICAgICAgICAgICAgIHdhcm4oYFRoZSBNYXRjaGVyIGNhbm5vdCByZXNvbHZlIHJlbGF0aXZlIHBhdGhzIGJ1dCByZWNlaXZlZCBcIiR7cGF0aH1cIi4gVW5sZXNzIHlvdSBkaXJlY3RseSBjYWxsZWQgXFxgbWF0Y2hlci5yZXNvbHZlKFwiJHtwYXRofVwiKVxcYCwgdGhpcyBpcyBwcm9iYWJseSBhIGJ1ZyBpbiB2dWUtcm91dGVyLiBQbGVhc2Ugb3BlbiBhbiBpc3N1ZSBhdCBodHRwczovL25ldy1pc3N1ZS52dWVqcy5vcmcvP3JlcG89dnVlanMvdnVlLXJvdXRlci1uZXh0LmApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIG1hdGNoZXIgPSBtYXRjaGVycy5maW5kKG0gPT4gbS5yZS50ZXN0KHBhdGgpKTtcclxuICAgICAgICAgICAgLy8gbWF0Y2hlciBzaG91bGQgaGF2ZSBhIHZhbHVlIGFmdGVyIHRoZSBsb29wXHJcbiAgICAgICAgICAgIGlmIChtYXRjaGVyKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBUT0RPOiBkZXYgd2FybmluZyBvZiB1bnVzZWQgcGFyYW1zIGlmIHByb3ZpZGVkXHJcbiAgICAgICAgICAgICAgICAvLyB3ZSBrbm93IHRoZSBtYXRjaGVyIHdvcmtzIGJlY2F1c2Ugd2UgdGVzdGVkIHRoZSByZWdleHBcclxuICAgICAgICAgICAgICAgIHBhcmFtcyA9IG1hdGNoZXIucGFyc2UocGF0aCk7XHJcbiAgICAgICAgICAgICAgICBuYW1lID0gbWF0Y2hlci5yZWNvcmQubmFtZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBsb2NhdGlvbiBpcyBhIHJlbGF0aXZlIHBhdGhcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIG1hdGNoIGJ5IG5hbWUgb3IgcGF0aCBvZiBjdXJyZW50IHJvdXRlXHJcbiAgICAgICAgICAgIG1hdGNoZXIgPSBjdXJyZW50TG9jYXRpb24ubmFtZVxyXG4gICAgICAgICAgICAgICAgPyBtYXRjaGVyTWFwLmdldChjdXJyZW50TG9jYXRpb24ubmFtZSlcclxuICAgICAgICAgICAgICAgIDogbWF0Y2hlcnMuZmluZChtID0+IG0ucmUudGVzdChjdXJyZW50TG9jYXRpb24ucGF0aCkpO1xyXG4gICAgICAgICAgICBpZiAoIW1hdGNoZXIpXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVSb3V0ZXJFcnJvcigxIC8qIE1BVENIRVJfTk9UX0ZPVU5EICovLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgbG9jYXRpb24sXHJcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudExvY2F0aW9uLFxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIG5hbWUgPSBtYXRjaGVyLnJlY29yZC5uYW1lO1xyXG4gICAgICAgICAgICAvLyBzaW5jZSB3ZSBhcmUgbmF2aWdhdGluZyB0byB0aGUgc2FtZSBsb2NhdGlvbiwgd2UgZG9uJ3QgbmVlZCB0byBwaWNrIHRoZVxyXG4gICAgICAgICAgICAvLyBwYXJhbXMgbGlrZSB3aGVuIGBuYW1lYCBpcyBwcm92aWRlZFxyXG4gICAgICAgICAgICBwYXJhbXMgPSBhc3NpZ24oe30sIGN1cnJlbnRMb2NhdGlvbi5wYXJhbXMsIGxvY2F0aW9uLnBhcmFtcyk7XHJcbiAgICAgICAgICAgIHBhdGggPSBtYXRjaGVyLnN0cmluZ2lmeShwYXJhbXMpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBtYXRjaGVkID0gW107XHJcbiAgICAgICAgbGV0IHBhcmVudE1hdGNoZXIgPSBtYXRjaGVyO1xyXG4gICAgICAgIHdoaWxlIChwYXJlbnRNYXRjaGVyKSB7XHJcbiAgICAgICAgICAgIC8vIHJldmVyc2VkIG9yZGVyIHNvIHBhcmVudHMgYXJlIGF0IHRoZSBiZWdpbm5pbmdcclxuICAgICAgICAgICAgbWF0Y2hlZC51bnNoaWZ0KHBhcmVudE1hdGNoZXIucmVjb3JkKTtcclxuICAgICAgICAgICAgcGFyZW50TWF0Y2hlciA9IHBhcmVudE1hdGNoZXIucGFyZW50O1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBuYW1lLFxyXG4gICAgICAgICAgICBwYXRoLFxyXG4gICAgICAgICAgICBwYXJhbXMsXHJcbiAgICAgICAgICAgIG1hdGNoZWQsXHJcbiAgICAgICAgICAgIG1ldGE6IG1lcmdlTWV0YUZpZWxkcyhtYXRjaGVkKSxcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG4gICAgLy8gYWRkIGluaXRpYWwgcm91dGVzXHJcbiAgICByb3V0ZXMuZm9yRWFjaChyb3V0ZSA9PiBhZGRSb3V0ZShyb3V0ZSkpO1xyXG4gICAgcmV0dXJuIHsgYWRkUm91dGUsIHJlc29sdmUsIHJlbW92ZVJvdXRlLCBnZXRSb3V0ZXMsIGdldFJlY29yZE1hdGNoZXIgfTtcclxufVxyXG5mdW5jdGlvbiBwYXJhbXNGcm9tTG9jYXRpb24ocGFyYW1zLCBrZXlzKSB7XHJcbiAgICBjb25zdCBuZXdQYXJhbXMgPSB7fTtcclxuICAgIGZvciAoY29uc3Qga2V5IG9mIGtleXMpIHtcclxuICAgICAgICBpZiAoa2V5IGluIHBhcmFtcylcclxuICAgICAgICAgICAgbmV3UGFyYW1zW2tleV0gPSBwYXJhbXNba2V5XTtcclxuICAgIH1cclxuICAgIHJldHVybiBuZXdQYXJhbXM7XHJcbn1cclxuLyoqXHJcbiAqIE5vcm1hbGl6ZXMgYSBSb3V0ZVJlY29yZFJhdy4gQ3JlYXRlcyBhIGNvcHlcclxuICpcclxuICogQHBhcmFtIHJlY29yZFxyXG4gKiBAcmV0dXJucyB0aGUgbm9ybWFsaXplZCB2ZXJzaW9uXHJcbiAqL1xyXG5mdW5jdGlvbiBub3JtYWxpemVSb3V0ZVJlY29yZChyZWNvcmQpIHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgcGF0aDogcmVjb3JkLnBhdGgsXHJcbiAgICAgICAgcmVkaXJlY3Q6IHJlY29yZC5yZWRpcmVjdCxcclxuICAgICAgICBuYW1lOiByZWNvcmQubmFtZSxcclxuICAgICAgICBtZXRhOiByZWNvcmQubWV0YSB8fCB7fSxcclxuICAgICAgICBhbGlhc09mOiB1bmRlZmluZWQsXHJcbiAgICAgICAgYmVmb3JlRW50ZXI6IHJlY29yZC5iZWZvcmVFbnRlcixcclxuICAgICAgICBwcm9wczogbm9ybWFsaXplUmVjb3JkUHJvcHMocmVjb3JkKSxcclxuICAgICAgICBjaGlsZHJlbjogcmVjb3JkLmNoaWxkcmVuIHx8IFtdLFxyXG4gICAgICAgIGluc3RhbmNlczoge30sXHJcbiAgICAgICAgbGVhdmVHdWFyZHM6IG5ldyBTZXQoKSxcclxuICAgICAgICB1cGRhdGVHdWFyZHM6IG5ldyBTZXQoKSxcclxuICAgICAgICBlbnRlckNhbGxiYWNrczoge30sXHJcbiAgICAgICAgY29tcG9uZW50czogJ2NvbXBvbmVudHMnIGluIHJlY29yZFxyXG4gICAgICAgICAgICA/IHJlY29yZC5jb21wb25lbnRzIHx8IHt9XHJcbiAgICAgICAgICAgIDogeyBkZWZhdWx0OiByZWNvcmQuY29tcG9uZW50IH0sXHJcbiAgICB9O1xyXG59XHJcbi8qKlxyXG4gKiBOb3JtYWxpemUgdGhlIG9wdGlvbmFsIGBwcm9wc2AgaW4gYSByZWNvcmQgdG8gYWx3YXlzIGJlIGFuIG9iamVjdCBzaW1pbGFyIHRvXHJcbiAqIGNvbXBvbmVudHMuIEFsc28gYWNjZXB0IGEgYm9vbGVhbiBmb3IgY29tcG9uZW50cy5cclxuICogQHBhcmFtIHJlY29yZFxyXG4gKi9cclxuZnVuY3Rpb24gbm9ybWFsaXplUmVjb3JkUHJvcHMocmVjb3JkKSB7XHJcbiAgICBjb25zdCBwcm9wc09iamVjdCA9IHt9O1xyXG4gICAgLy8gcHJvcHMgZG9lcyBub3QgZXhpc3Qgb24gcmVkaXJlY3QgcmVjb3JkcyBidXQgd2UgY2FuIHNldCBmYWxzZSBkaXJlY3RseVxyXG4gICAgY29uc3QgcHJvcHMgPSByZWNvcmQucHJvcHMgfHwgZmFsc2U7XHJcbiAgICBpZiAoJ2NvbXBvbmVudCcgaW4gcmVjb3JkKSB7XHJcbiAgICAgICAgcHJvcHNPYmplY3QuZGVmYXVsdCA9IHByb3BzO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgLy8gTk9URTogd2UgY291bGQgYWxzbyBhbGxvdyBhIGZ1bmN0aW9uIHRvIGJlIGFwcGxpZWQgdG8gZXZlcnkgY29tcG9uZW50LlxyXG4gICAgICAgIC8vIFdvdWxkIG5lZWQgdXNlciBmZWVkYmFjayBmb3IgdXNlIGNhc2VzXHJcbiAgICAgICAgZm9yIChjb25zdCBuYW1lIGluIHJlY29yZC5jb21wb25lbnRzKVxyXG4gICAgICAgICAgICBwcm9wc09iamVjdFtuYW1lXSA9IHR5cGVvZiBwcm9wcyA9PT0gJ2Jvb2xlYW4nID8gcHJvcHMgOiBwcm9wc1tuYW1lXTtcclxuICAgIH1cclxuICAgIHJldHVybiBwcm9wc09iamVjdDtcclxufVxyXG4vKipcclxuICogQ2hlY2tzIGlmIGEgcmVjb3JkIG9yIGFueSBvZiBpdHMgcGFyZW50IGlzIGFuIGFsaWFzXHJcbiAqIEBwYXJhbSByZWNvcmRcclxuICovXHJcbmZ1bmN0aW9uIGlzQWxpYXNSZWNvcmQocmVjb3JkKSB7XHJcbiAgICB3aGlsZSAocmVjb3JkKSB7XHJcbiAgICAgICAgaWYgKHJlY29yZC5yZWNvcmQuYWxpYXNPZilcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgcmVjb3JkID0gcmVjb3JkLnBhcmVudDtcclxuICAgIH1cclxuICAgIHJldHVybiBmYWxzZTtcclxufVxyXG4vKipcclxuICogTWVyZ2UgbWV0YSBmaWVsZHMgb2YgYW4gYXJyYXkgb2YgcmVjb3Jkc1xyXG4gKlxyXG4gKiBAcGFyYW0gbWF0Y2hlZCAtIGFycmF5IG9mIG1hdGNoZWQgcmVjb3Jkc1xyXG4gKi9cclxuZnVuY3Rpb24gbWVyZ2VNZXRhRmllbGRzKG1hdGNoZWQpIHtcclxuICAgIHJldHVybiBtYXRjaGVkLnJlZHVjZSgobWV0YSwgcmVjb3JkKSA9PiBhc3NpZ24obWV0YSwgcmVjb3JkLm1ldGEpLCB7fSk7XHJcbn1cclxuZnVuY3Rpb24gbWVyZ2VPcHRpb25zKGRlZmF1bHRzLCBwYXJ0aWFsT3B0aW9ucykge1xyXG4gICAgY29uc3Qgb3B0aW9ucyA9IHt9O1xyXG4gICAgZm9yIChjb25zdCBrZXkgaW4gZGVmYXVsdHMpIHtcclxuICAgICAgICBvcHRpb25zW2tleV0gPSBrZXkgaW4gcGFydGlhbE9wdGlvbnMgPyBwYXJ0aWFsT3B0aW9uc1trZXldIDogZGVmYXVsdHNba2V5XTtcclxuICAgIH1cclxuICAgIHJldHVybiBvcHRpb25zO1xyXG59XHJcbmZ1bmN0aW9uIGlzU2FtZVBhcmFtKGEsIGIpIHtcclxuICAgIHJldHVybiAoYS5uYW1lID09PSBiLm5hbWUgJiZcclxuICAgICAgICBhLm9wdGlvbmFsID09PSBiLm9wdGlvbmFsICYmXHJcbiAgICAgICAgYS5yZXBlYXRhYmxlID09PSBiLnJlcGVhdGFibGUpO1xyXG59XHJcbi8qKlxyXG4gKiBDaGVjayBpZiBhIHBhdGggYW5kIGl0cyBhbGlhcyBoYXZlIHRoZSBzYW1lIHJlcXVpcmVkIHBhcmFtc1xyXG4gKlxyXG4gKiBAcGFyYW0gYSAtIG9yaWdpbmFsIHJlY29yZFxyXG4gKiBAcGFyYW0gYiAtIGFsaWFzIHJlY29yZFxyXG4gKi9cclxuZnVuY3Rpb24gY2hlY2tTYW1lUGFyYW1zKGEsIGIpIHtcclxuICAgIGZvciAoY29uc3Qga2V5IG9mIGEua2V5cykge1xyXG4gICAgICAgIGlmICgha2V5Lm9wdGlvbmFsICYmICFiLmtleXMuZmluZChpc1NhbWVQYXJhbS5iaW5kKG51bGwsIGtleSkpKVxyXG4gICAgICAgICAgICByZXR1cm4gd2FybihgQWxpYXMgXCIke2IucmVjb3JkLnBhdGh9XCIgYW5kIHRoZSBvcmlnaW5hbCByZWNvcmQ6IFwiJHthLnJlY29yZC5wYXRofVwiIHNob3VsZCBoYXZlIHRoZSBleGFjdCBzYW1lIHBhcmFtIG5hbWVkIFwiJHtrZXkubmFtZX1cImApO1xyXG4gICAgfVxyXG4gICAgZm9yIChjb25zdCBrZXkgb2YgYi5rZXlzKSB7XHJcbiAgICAgICAgaWYgKCFrZXkub3B0aW9uYWwgJiYgIWEua2V5cy5maW5kKGlzU2FtZVBhcmFtLmJpbmQobnVsbCwga2V5KSkpXHJcbiAgICAgICAgICAgIHJldHVybiB3YXJuKGBBbGlhcyBcIiR7Yi5yZWNvcmQucGF0aH1cIiBhbmQgdGhlIG9yaWdpbmFsIHJlY29yZDogXCIke2EucmVjb3JkLnBhdGh9XCIgc2hvdWxkIGhhdmUgdGhlIGV4YWN0IHNhbWUgcGFyYW0gbmFtZWQgXCIke2tleS5uYW1lfVwiYCk7XHJcbiAgICB9XHJcbn1cclxuZnVuY3Rpb24gY2hlY2tNaXNzaW5nUGFyYW1zSW5BYnNvbHV0ZVBhdGgocmVjb3JkLCBwYXJlbnQpIHtcclxuICAgIGZvciAoY29uc3Qga2V5IG9mIHBhcmVudC5rZXlzKSB7XHJcbiAgICAgICAgaWYgKCFyZWNvcmQua2V5cy5maW5kKGlzU2FtZVBhcmFtLmJpbmQobnVsbCwga2V5KSkpXHJcbiAgICAgICAgICAgIHJldHVybiB3YXJuKGBBYnNvbHV0ZSBwYXRoIFwiJHtyZWNvcmQucmVjb3JkLnBhdGh9XCIgc2hvdWxkIGhhdmUgdGhlIGV4YWN0IHNhbWUgcGFyYW0gbmFtZWQgXCIke2tleS5uYW1lfVwiIGFzIGl0cyBwYXJlbnQgXCIke3BhcmVudC5yZWNvcmQucGF0aH1cIi5gKTtcclxuICAgIH1cclxufVxuXG4vKipcclxuICogRW5jb2RpbmcgUnVsZXMg4pCjID0gU3BhY2UgUGF0aDog4pCjIFwiIDwgPiAjID8geyB9IFF1ZXJ5OiDikKMgXCIgPCA+ICMgJiA9IEhhc2g6IOKQoyBcIlxyXG4gKiA8ID4gYFxyXG4gKlxyXG4gKiBPbiB0b3Agb2YgdGhhdCwgdGhlIFJGQzM5ODYgKGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmMzOTg2I3NlY3Rpb24tMi4yKVxyXG4gKiBkZWZpbmVzIHNvbWUgZXh0cmEgY2hhcmFjdGVycyB0byBiZSBlbmNvZGVkLiBNb3N0IGJyb3dzZXJzIGRvIG5vdCBlbmNvZGUgdGhlbVxyXG4gKiBpbiBlbmNvZGVVUkkgaHR0cHM6Ly9naXRodWIuY29tL3doYXR3Zy91cmwvaXNzdWVzLzM2OSwgc28gaXQgbWF5IGJlIHNhZmVyIHRvXHJcbiAqIGFsc28gZW5jb2RlIGAhJygpKmAuIExlYXZpbmcgdW5lbmNvZGVkIG9ubHkgQVNDSUkgYWxwaGFudW1lcmljKGBhLXpBLVowLTlgKVxyXG4gKiBwbHVzIGAtLl9+YC4gVGhpcyBleHRyYSBzYWZldHkgc2hvdWxkIGJlIGFwcGxpZWQgdG8gcXVlcnkgYnkgcGF0Y2hpbmcgdGhlXHJcbiAqIHN0cmluZyByZXR1cm5lZCBieSBlbmNvZGVVUklDb21wb25lbnQgZW5jb2RlVVJJIGFsc28gZW5jb2RlcyBgW1xcXV5gLiBgXFxgXHJcbiAqIHNob3VsZCBiZSBlbmNvZGVkIHRvIGF2b2lkIGFtYmlndWl0eS4gQnJvd3NlcnMgKElFLCBGRiwgQykgdHJhbnNmb3JtIGEgYFxcYFxyXG4gKiBpbnRvIGEgYC9gIGlmIGRpcmVjdGx5IHR5cGVkIGluLiBUaGUgX2JhY2t0aWNrXyAoYGBgYGApIHNob3VsZCBhbHNvIGJlXHJcbiAqIGVuY29kZWQgZXZlcnl3aGVyZSBiZWNhdXNlIHNvbWUgYnJvd3NlcnMgbGlrZSBGRiBlbmNvZGUgaXQgd2hlbiBkaXJlY3RseVxyXG4gKiB3cml0dGVuIHdoaWxlIG90aGVycyBkb24ndC4gU2FmYXJpIGFuZCBJRSBkb24ndCBlbmNvZGUgYGBcIjw+e31gYGAgaW4gaGFzaC5cclxuICovXHJcbi8vIGNvbnN0IEVYVFJBX1JFU0VSVkVEX1JFID0gL1shJygpKl0vZ1xyXG4vLyBjb25zdCBlbmNvZGVSZXNlcnZlZFJlcGxhY2VyID0gKGM6IHN0cmluZykgPT4gJyUnICsgYy5jaGFyQ29kZUF0KDApLnRvU3RyaW5nKDE2KVxyXG5jb25zdCBIQVNIX1JFID0gLyMvZzsgLy8gJTIzXHJcbmNvbnN0IEFNUEVSU0FORF9SRSA9IC8mL2c7IC8vICUyNlxyXG5jb25zdCBTTEFTSF9SRSA9IC9cXC8vZzsgLy8gJTJGXHJcbmNvbnN0IEVRVUFMX1JFID0gLz0vZzsgLy8gJTNEXHJcbmNvbnN0IElNX1JFID0gL1xcPy9nOyAvLyAlM0ZcclxuY29uc3QgUExVU19SRSA9IC9cXCsvZzsgLy8gJTJCXHJcbi8qKlxyXG4gKiBOT1RFOiBJdCdzIG5vdCBjbGVhciB0byBtZSBpZiB3ZSBzaG91bGQgZW5jb2RlIHRoZSArIHN5bWJvbCBpbiBxdWVyaWVzLCBpdFxyXG4gKiBzZWVtcyB0byBiZSBsZXNzIGZsZXhpYmxlIHRoYW4gbm90IGRvaW5nIHNvIGFuZCBJIGNhbid0IGZpbmQgb3V0IHRoZSBsZWdhY3lcclxuICogc3lzdGVtcyByZXF1aXJpbmcgdGhpcyBmb3IgcmVndWxhciByZXF1ZXN0cyBsaWtlIHRleHQvaHRtbC4gSW4gdGhlIHN0YW5kYXJkLFxyXG4gKiB0aGUgZW5jb2Rpbmcgb2YgdGhlIHBsdXMgY2hhcmFjdGVyIGlzIG9ubHkgbWVudGlvbmVkIGZvclxyXG4gKiBhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWRcclxuICogKGh0dHBzOi8vdXJsLnNwZWMud2hhdHdnLm9yZy8jdXJsZW5jb2RlZC1wYXJzaW5nKSBhbmQgbW9zdCBicm93c2VycyBzZWVtcyBsb1xyXG4gKiBsZWF2ZSB0aGUgcGx1cyBjaGFyYWN0ZXIgYXMgaXMgaW4gcXVlcmllcy4gVG8gYmUgbW9yZSBmbGV4aWJsZSwgd2UgYWxsb3cgdGhlXHJcbiAqIHBsdXMgY2hhcmFjdGVyIG9uIHRoZSBxdWVyeSBidXQgaXQgY2FuIGFsc28gYmUgbWFudWFsbHkgZW5jb2RlZCBieSB0aGUgdXNlci5cclxuICpcclxuICogUmVzb3VyY2VzOlxyXG4gKiAtIGh0dHBzOi8vdXJsLnNwZWMud2hhdHdnLm9yZy8jdXJsZW5jb2RlZC1wYXJzaW5nXHJcbiAqIC0gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTYzNDI3MS91cmwtZW5jb2RpbmctdGhlLXNwYWNlLWNoYXJhY3Rlci1vci0yMFxyXG4gKi9cclxuY29uc3QgRU5DX0JSQUNLRVRfT1BFTl9SRSA9IC8lNUIvZzsgLy8gW1xyXG5jb25zdCBFTkNfQlJBQ0tFVF9DTE9TRV9SRSA9IC8lNUQvZzsgLy8gXVxyXG5jb25zdCBFTkNfQ0FSRVRfUkUgPSAvJTVFL2c7IC8vIF5cclxuY29uc3QgRU5DX0JBQ0tUSUNLX1JFID0gLyU2MC9nOyAvLyBgXHJcbmNvbnN0IEVOQ19DVVJMWV9PUEVOX1JFID0gLyU3Qi9nOyAvLyB7XHJcbmNvbnN0IEVOQ19QSVBFX1JFID0gLyU3Qy9nOyAvLyB8XHJcbmNvbnN0IEVOQ19DVVJMWV9DTE9TRV9SRSA9IC8lN0QvZzsgLy8gfVxyXG5jb25zdCBFTkNfU1BBQ0VfUkUgPSAvJTIwL2c7IC8vIH1cclxuLyoqXHJcbiAqIEVuY29kZSBjaGFyYWN0ZXJzIHRoYXQgbmVlZCB0byBiZSBlbmNvZGVkIG9uIHRoZSBwYXRoLCBzZWFyY2ggYW5kIGhhc2hcclxuICogc2VjdGlvbnMgb2YgdGhlIFVSTC5cclxuICpcclxuICogQGludGVybmFsXHJcbiAqIEBwYXJhbSB0ZXh0IC0gc3RyaW5nIHRvIGVuY29kZVxyXG4gKiBAcmV0dXJucyBlbmNvZGVkIHN0cmluZ1xyXG4gKi9cclxuZnVuY3Rpb24gY29tbW9uRW5jb2RlKHRleHQpIHtcclxuICAgIHJldHVybiBlbmNvZGVVUkkoJycgKyB0ZXh0KVxyXG4gICAgICAgIC5yZXBsYWNlKEVOQ19QSVBFX1JFLCAnfCcpXHJcbiAgICAgICAgLnJlcGxhY2UoRU5DX0JSQUNLRVRfT1BFTl9SRSwgJ1snKVxyXG4gICAgICAgIC5yZXBsYWNlKEVOQ19CUkFDS0VUX0NMT1NFX1JFLCAnXScpO1xyXG59XHJcbi8qKlxyXG4gKiBFbmNvZGUgY2hhcmFjdGVycyB0aGF0IG5lZWQgdG8gYmUgZW5jb2RlZCBvbiB0aGUgaGFzaCBzZWN0aW9uIG9mIHRoZSBVUkwuXHJcbiAqXHJcbiAqIEBwYXJhbSB0ZXh0IC0gc3RyaW5nIHRvIGVuY29kZVxyXG4gKiBAcmV0dXJucyBlbmNvZGVkIHN0cmluZ1xyXG4gKi9cclxuZnVuY3Rpb24gZW5jb2RlSGFzaCh0ZXh0KSB7XHJcbiAgICByZXR1cm4gY29tbW9uRW5jb2RlKHRleHQpXHJcbiAgICAgICAgLnJlcGxhY2UoRU5DX0NVUkxZX09QRU5fUkUsICd7JylcclxuICAgICAgICAucmVwbGFjZShFTkNfQ1VSTFlfQ0xPU0VfUkUsICd9JylcclxuICAgICAgICAucmVwbGFjZShFTkNfQ0FSRVRfUkUsICdeJyk7XHJcbn1cclxuLyoqXHJcbiAqIEVuY29kZSBjaGFyYWN0ZXJzIHRoYXQgbmVlZCB0byBiZSBlbmNvZGVkIHF1ZXJ5IHZhbHVlcyBvbiB0aGUgcXVlcnlcclxuICogc2VjdGlvbiBvZiB0aGUgVVJMLlxyXG4gKlxyXG4gKiBAcGFyYW0gdGV4dCAtIHN0cmluZyB0byBlbmNvZGVcclxuICogQHJldHVybnMgZW5jb2RlZCBzdHJpbmdcclxuICovXHJcbmZ1bmN0aW9uIGVuY29kZVF1ZXJ5VmFsdWUodGV4dCkge1xyXG4gICAgcmV0dXJuIChjb21tb25FbmNvZGUodGV4dClcclxuICAgICAgICAvLyBFbmNvZGUgdGhlIHNwYWNlIGFzICssIGVuY29kZSB0aGUgKyB0byBkaWZmZXJlbnRpYXRlIGl0IGZyb20gdGhlIHNwYWNlXHJcbiAgICAgICAgLnJlcGxhY2UoUExVU19SRSwgJyUyQicpXHJcbiAgICAgICAgLnJlcGxhY2UoRU5DX1NQQUNFX1JFLCAnKycpXHJcbiAgICAgICAgLnJlcGxhY2UoSEFTSF9SRSwgJyUyMycpXHJcbiAgICAgICAgLnJlcGxhY2UoQU1QRVJTQU5EX1JFLCAnJTI2JylcclxuICAgICAgICAucmVwbGFjZShFTkNfQkFDS1RJQ0tfUkUsICdgJylcclxuICAgICAgICAucmVwbGFjZShFTkNfQ1VSTFlfT1BFTl9SRSwgJ3snKVxyXG4gICAgICAgIC5yZXBsYWNlKEVOQ19DVVJMWV9DTE9TRV9SRSwgJ30nKVxyXG4gICAgICAgIC5yZXBsYWNlKEVOQ19DQVJFVF9SRSwgJ14nKSk7XHJcbn1cclxuLyoqXHJcbiAqIExpa2UgYGVuY29kZVF1ZXJ5VmFsdWVgIGJ1dCBhbHNvIGVuY29kZXMgdGhlIGA9YCBjaGFyYWN0ZXIuXHJcbiAqXHJcbiAqIEBwYXJhbSB0ZXh0IC0gc3RyaW5nIHRvIGVuY29kZVxyXG4gKi9cclxuZnVuY3Rpb24gZW5jb2RlUXVlcnlLZXkodGV4dCkge1xyXG4gICAgcmV0dXJuIGVuY29kZVF1ZXJ5VmFsdWUodGV4dCkucmVwbGFjZShFUVVBTF9SRSwgJyUzRCcpO1xyXG59XHJcbi8qKlxyXG4gKiBFbmNvZGUgY2hhcmFjdGVycyB0aGF0IG5lZWQgdG8gYmUgZW5jb2RlZCBvbiB0aGUgcGF0aCBzZWN0aW9uIG9mIHRoZSBVUkwuXHJcbiAqXHJcbiAqIEBwYXJhbSB0ZXh0IC0gc3RyaW5nIHRvIGVuY29kZVxyXG4gKiBAcmV0dXJucyBlbmNvZGVkIHN0cmluZ1xyXG4gKi9cclxuZnVuY3Rpb24gZW5jb2RlUGF0aCh0ZXh0KSB7XHJcbiAgICByZXR1cm4gY29tbW9uRW5jb2RlKHRleHQpLnJlcGxhY2UoSEFTSF9SRSwgJyUyMycpLnJlcGxhY2UoSU1fUkUsICclM0YnKTtcclxufVxyXG4vKipcclxuICogRW5jb2RlIGNoYXJhY3RlcnMgdGhhdCBuZWVkIHRvIGJlIGVuY29kZWQgb24gdGhlIHBhdGggc2VjdGlvbiBvZiB0aGUgVVJMIGFzIGFcclxuICogcGFyYW0uIFRoaXMgZnVuY3Rpb24gZW5jb2RlcyBldmVyeXRoaW5nIHtAbGluayBlbmNvZGVQYXRofSBkb2VzIHBsdXMgdGhlXHJcbiAqIHNsYXNoIChgL2ApIGNoYXJhY3Rlci4gSWYgYHRleHRgIGlzIGBudWxsYCBvciBgdW5kZWZpbmVkYCwgcmV0dXJucyBhbiBlbXB0eVxyXG4gKiBzdHJpbmcgaW5zdGVhZC5cclxuICpcclxuICogQHBhcmFtIHRleHQgLSBzdHJpbmcgdG8gZW5jb2RlXHJcbiAqIEByZXR1cm5zIGVuY29kZWQgc3RyaW5nXHJcbiAqL1xyXG5mdW5jdGlvbiBlbmNvZGVQYXJhbSh0ZXh0KSB7XHJcbiAgICByZXR1cm4gdGV4dCA9PSBudWxsID8gJycgOiBlbmNvZGVQYXRoKHRleHQpLnJlcGxhY2UoU0xBU0hfUkUsICclMkYnKTtcclxufVxyXG4vKipcclxuICogRGVjb2RlIHRleHQgdXNpbmcgYGRlY29kZVVSSUNvbXBvbmVudGAuIFJldHVybnMgdGhlIG9yaWdpbmFsIHRleHQgaWYgaXRcclxuICogZmFpbHMuXHJcbiAqXHJcbiAqIEBwYXJhbSB0ZXh0IC0gc3RyaW5nIHRvIGRlY29kZVxyXG4gKiBAcmV0dXJucyBkZWNvZGVkIHN0cmluZ1xyXG4gKi9cclxuZnVuY3Rpb24gZGVjb2RlKHRleHQpIHtcclxuICAgIHRyeSB7XHJcbiAgICAgICAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudCgnJyArIHRleHQpO1xyXG4gICAgfVxyXG4gICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiB3YXJuKGBFcnJvciBkZWNvZGluZyBcIiR7dGV4dH1cIi4gVXNpbmcgb3JpZ2luYWwgdmFsdWVgKTtcclxuICAgIH1cclxuICAgIHJldHVybiAnJyArIHRleHQ7XHJcbn1cblxuLyoqXHJcbiAqIFRyYW5zZm9ybXMgYSBxdWVyeVN0cmluZyBpbnRvIGEge0BsaW5rIExvY2F0aW9uUXVlcnl9IG9iamVjdC4gQWNjZXB0IGJvdGgsIGFcclxuICogdmVyc2lvbiB3aXRoIHRoZSBsZWFkaW5nIGA/YCBhbmQgd2l0aG91dCBTaG91bGQgd29yayBhcyBVUkxTZWFyY2hQYXJhbXNcclxuXG4gKiBAaW50ZXJuYWxcclxuICpcclxuICogQHBhcmFtIHNlYXJjaCAtIHNlYXJjaCBzdHJpbmcgdG8gcGFyc2VcclxuICogQHJldHVybnMgYSBxdWVyeSBvYmplY3RcclxuICovXHJcbmZ1bmN0aW9uIHBhcnNlUXVlcnkoc2VhcmNoKSB7XHJcbiAgICBjb25zdCBxdWVyeSA9IHt9O1xyXG4gICAgLy8gYXZvaWQgY3JlYXRpbmcgYW4gb2JqZWN0IHdpdGggYW4gZW1wdHkga2V5IGFuZCBlbXB0eSB2YWx1ZVxyXG4gICAgLy8gYmVjYXVzZSBvZiBzcGxpdCgnJicpXHJcbiAgICBpZiAoc2VhcmNoID09PSAnJyB8fCBzZWFyY2ggPT09ICc/JylcclxuICAgICAgICByZXR1cm4gcXVlcnk7XHJcbiAgICBjb25zdCBoYXNMZWFkaW5nSU0gPSBzZWFyY2hbMF0gPT09ICc/JztcclxuICAgIGNvbnN0IHNlYXJjaFBhcmFtcyA9IChoYXNMZWFkaW5nSU0gPyBzZWFyY2guc2xpY2UoMSkgOiBzZWFyY2gpLnNwbGl0KCcmJyk7XHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNlYXJjaFBhcmFtcy5sZW5ndGg7ICsraSkge1xyXG4gICAgICAgIC8vIHByZSBkZWNvZGUgdGhlICsgaW50byBzcGFjZVxyXG4gICAgICAgIGNvbnN0IHNlYXJjaFBhcmFtID0gc2VhcmNoUGFyYW1zW2ldLnJlcGxhY2UoUExVU19SRSwgJyAnKTtcclxuICAgICAgICAvLyBhbGxvdyB0aGUgPSBjaGFyYWN0ZXJcclxuICAgICAgICBjb25zdCBlcVBvcyA9IHNlYXJjaFBhcmFtLmluZGV4T2YoJz0nKTtcclxuICAgICAgICBjb25zdCBrZXkgPSBkZWNvZGUoZXFQb3MgPCAwID8gc2VhcmNoUGFyYW0gOiBzZWFyY2hQYXJhbS5zbGljZSgwLCBlcVBvcykpO1xyXG4gICAgICAgIGNvbnN0IHZhbHVlID0gZXFQb3MgPCAwID8gbnVsbCA6IGRlY29kZShzZWFyY2hQYXJhbS5zbGljZShlcVBvcyArIDEpKTtcclxuICAgICAgICBpZiAoa2V5IGluIHF1ZXJ5KSB7XHJcbiAgICAgICAgICAgIC8vIGFuIGV4dHJhIHZhcmlhYmxlIGZvciB0cyB0eXBlc1xyXG4gICAgICAgICAgICBsZXQgY3VycmVudFZhbHVlID0gcXVlcnlba2V5XTtcclxuICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGN1cnJlbnRWYWx1ZSkpIHtcclxuICAgICAgICAgICAgICAgIGN1cnJlbnRWYWx1ZSA9IHF1ZXJ5W2tleV0gPSBbY3VycmVudFZhbHVlXTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjdXJyZW50VmFsdWUucHVzaCh2YWx1ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBxdWVyeVtrZXldID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHF1ZXJ5O1xyXG59XHJcbi8qKlxyXG4gKiBTdHJpbmdpZmllcyBhIHtAbGluayBMb2NhdGlvblF1ZXJ5UmF3fSBvYmplY3QuIExpa2UgYFVSTFNlYXJjaFBhcmFtc2AsIGl0XHJcbiAqIGRvZXNuJ3QgcHJlcGVuZCBhIGA/YFxyXG4gKlxyXG4gKiBAaW50ZXJuYWxcclxuICpcclxuICogQHBhcmFtIHF1ZXJ5IC0gcXVlcnkgb2JqZWN0IHRvIHN0cmluZ2lmeVxyXG4gKiBAcmV0dXJucyBzdHJpbmcgdmVyc2lvbiBvZiB0aGUgcXVlcnkgd2l0aG91dCB0aGUgbGVhZGluZyBgP2BcclxuICovXHJcbmZ1bmN0aW9uIHN0cmluZ2lmeVF1ZXJ5KHF1ZXJ5KSB7XHJcbiAgICBsZXQgc2VhcmNoID0gJyc7XHJcbiAgICBmb3IgKGxldCBrZXkgaW4gcXVlcnkpIHtcclxuICAgICAgICBjb25zdCB2YWx1ZSA9IHF1ZXJ5W2tleV07XHJcbiAgICAgICAga2V5ID0gZW5jb2RlUXVlcnlLZXkoa2V5KTtcclxuICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAvLyBvbmx5IG51bGwgYWRkcyB0aGUgdmFsdWVcclxuICAgICAgICAgICAgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgIHNlYXJjaCArPSAoc2VhcmNoLmxlbmd0aCA/ICcmJyA6ICcnKSArIGtleTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8ga2VlcCBudWxsIHZhbHVlc1xyXG4gICAgICAgIGNvbnN0IHZhbHVlcyA9IEFycmF5LmlzQXJyYXkodmFsdWUpXHJcbiAgICAgICAgICAgID8gdmFsdWUubWFwKHYgPT4gdiAmJiBlbmNvZGVRdWVyeVZhbHVlKHYpKVxyXG4gICAgICAgICAgICA6IFt2YWx1ZSAmJiBlbmNvZGVRdWVyeVZhbHVlKHZhbHVlKV07XHJcbiAgICAgICAgdmFsdWVzLmZvckVhY2godmFsdWUgPT4ge1xyXG4gICAgICAgICAgICAvLyBza2lwIHVuZGVmaW5lZCB2YWx1ZXMgaW4gYXJyYXlzIGFzIGlmIHRoZXkgd2VyZSBub3QgcHJlc2VudFxyXG4gICAgICAgICAgICAvLyBzbWFsbGVyIGNvZGUgdGhhbiB1c2luZyBmaWx0ZXJcclxuICAgICAgICAgICAgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgIC8vIG9ubHkgYXBwZW5kICYgd2l0aCBub24tZW1wdHkgc2VhcmNoXHJcbiAgICAgICAgICAgICAgICBzZWFyY2ggKz0gKHNlYXJjaC5sZW5ndGggPyAnJicgOiAnJykgKyBrZXk7XHJcbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbClcclxuICAgICAgICAgICAgICAgICAgICBzZWFyY2ggKz0gJz0nICsgdmFsdWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIHJldHVybiBzZWFyY2g7XHJcbn1cclxuLyoqXHJcbiAqIFRyYW5zZm9ybXMgYSB7QGxpbmsgTG9jYXRpb25RdWVyeVJhd30gaW50byBhIHtAbGluayBMb2NhdGlvblF1ZXJ5fSBieSBjYXN0aW5nXHJcbiAqIG51bWJlcnMgaW50byBzdHJpbmdzLCByZW1vdmluZyBrZXlzIHdpdGggYW4gdW5kZWZpbmVkIHZhbHVlIGFuZCByZXBsYWNpbmdcclxuICogdW5kZWZpbmVkIHdpdGggbnVsbCBpbiBhcnJheXNcclxuICpcclxuICogQHBhcmFtIHF1ZXJ5IC0gcXVlcnkgb2JqZWN0IHRvIG5vcm1hbGl6ZVxyXG4gKiBAcmV0dXJucyBhIG5vcm1hbGl6ZWQgcXVlcnkgb2JqZWN0XHJcbiAqL1xyXG5mdW5jdGlvbiBub3JtYWxpemVRdWVyeShxdWVyeSkge1xyXG4gICAgY29uc3Qgbm9ybWFsaXplZFF1ZXJ5ID0ge307XHJcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBxdWVyeSkge1xyXG4gICAgICAgIGNvbnN0IHZhbHVlID0gcXVlcnlba2V5XTtcclxuICAgICAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICBub3JtYWxpemVkUXVlcnlba2V5XSA9IEFycmF5LmlzQXJyYXkodmFsdWUpXHJcbiAgICAgICAgICAgICAgICA/IHZhbHVlLm1hcCh2ID0+ICh2ID09IG51bGwgPyBudWxsIDogJycgKyB2KSlcclxuICAgICAgICAgICAgICAgIDogdmFsdWUgPT0gbnVsbFxyXG4gICAgICAgICAgICAgICAgICAgID8gdmFsdWVcclxuICAgICAgICAgICAgICAgICAgICA6ICcnICsgdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIG5vcm1hbGl6ZWRRdWVyeTtcclxufVxuXG4vKipcclxuICogQ3JlYXRlIGEgbGlzdCBvZiBjYWxsYmFja3MgdGhhdCBjYW4gYmUgcmVzZXQuIFVzZWQgdG8gY3JlYXRlIGJlZm9yZSBhbmQgYWZ0ZXIgbmF2aWdhdGlvbiBndWFyZHMgbGlzdFxyXG4gKi9cclxuZnVuY3Rpb24gdXNlQ2FsbGJhY2tzKCkge1xyXG4gICAgbGV0IGhhbmRsZXJzID0gW107XHJcbiAgICBmdW5jdGlvbiBhZGQoaGFuZGxlcikge1xyXG4gICAgICAgIGhhbmRsZXJzLnB1c2goaGFuZGxlcik7XHJcbiAgICAgICAgcmV0dXJuICgpID0+IHtcclxuICAgICAgICAgICAgY29uc3QgaSA9IGhhbmRsZXJzLmluZGV4T2YoaGFuZGxlcik7XHJcbiAgICAgICAgICAgIGlmIChpID4gLTEpXHJcbiAgICAgICAgICAgICAgICBoYW5kbGVycy5zcGxpY2UoaSwgMSk7XHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuICAgIGZ1bmN0aW9uIHJlc2V0KCkge1xyXG4gICAgICAgIGhhbmRsZXJzID0gW107XHJcbiAgICB9XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIGFkZCxcclxuICAgICAgICBsaXN0OiAoKSA9PiBoYW5kbGVycyxcclxuICAgICAgICByZXNldCxcclxuICAgIH07XHJcbn1cblxuZnVuY3Rpb24gcmVnaXN0ZXJHdWFyZChyZWNvcmQsIG5hbWUsIGd1YXJkKSB7XHJcbiAgICBjb25zdCByZW1vdmVGcm9tTGlzdCA9ICgpID0+IHtcclxuICAgICAgICByZWNvcmRbbmFtZV0uZGVsZXRlKGd1YXJkKTtcclxuICAgIH07XHJcbiAgICBvblVubW91bnRlZChyZW1vdmVGcm9tTGlzdCk7XHJcbiAgICBvbkRlYWN0aXZhdGVkKHJlbW92ZUZyb21MaXN0KTtcclxuICAgIG9uQWN0aXZhdGVkKCgpID0+IHtcclxuICAgICAgICByZWNvcmRbbmFtZV0uYWRkKGd1YXJkKTtcclxuICAgIH0pO1xyXG4gICAgcmVjb3JkW25hbWVdLmFkZChndWFyZCk7XHJcbn1cclxuLyoqXHJcbiAqIEFkZCBhIG5hdmlnYXRpb24gZ3VhcmQgdGhhdCB0cmlnZ2VycyB3aGVuZXZlciB0aGUgY29tcG9uZW50IGZvciB0aGUgY3VycmVudFxyXG4gKiBsb2NhdGlvbiBpcyBhYm91dCB0byBiZSBsZWZ0LiBTaW1pbGFyIHRvIHtAbGluayBiZWZvcmVSb3V0ZUxlYXZlfSBidXQgY2FuIGJlXHJcbiAqIHVzZWQgaW4gYW55IGNvbXBvbmVudC4gVGhlIGd1YXJkIGlzIHJlbW92ZWQgd2hlbiB0aGUgY29tcG9uZW50IGlzIHVubW91bnRlZC5cclxuICpcclxuICogQHBhcmFtIGxlYXZlR3VhcmQgLSB7QGxpbmsgTmF2aWdhdGlvbkd1YXJkfVxyXG4gKi9cclxuZnVuY3Rpb24gb25CZWZvcmVSb3V0ZUxlYXZlKGxlYXZlR3VhcmQpIHtcclxuICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiYgIWdldEN1cnJlbnRJbnN0YW5jZSgpKSB7XHJcbiAgICAgICAgd2FybignZ2V0Q3VycmVudEluc3RhbmNlKCkgcmV0dXJuZWQgbnVsbC4gb25CZWZvcmVSb3V0ZUxlYXZlKCkgbXVzdCBiZSBjYWxsZWQgYXQgdGhlIHRvcCBvZiBhIHNldHVwIGZ1bmN0aW9uJyk7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgY29uc3QgYWN0aXZlUmVjb3JkID0gaW5qZWN0KG1hdGNoZWRSb3V0ZUtleSwgXHJcbiAgICAvLyB0byBhdm9pZCB3YXJuaW5nXHJcbiAgICB7fSkudmFsdWU7XHJcbiAgICBpZiAoIWFjdGl2ZVJlY29yZCkge1xyXG4gICAgICAgIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJlxyXG4gICAgICAgICAgICB3YXJuKCdObyBhY3RpdmUgcm91dGUgcmVjb3JkIHdhcyBmb3VuZCB3aGVuIGNhbGxpbmcgYG9uQmVmb3JlUm91dGVMZWF2ZSgpYC4gTWFrZSBzdXJlIHlvdSBjYWxsIHRoaXMgZnVuY3Rpb24gaW5zaWRlIG9mIGEgY29tcG9uZW50IGNoaWxkIG9mIDxyb3V0ZXItdmlldz4uIE1heWJlIHlvdSBjYWxsZWQgaXQgaW5zaWRlIG9mIEFwcC52dWU/Jyk7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgcmVnaXN0ZXJHdWFyZChhY3RpdmVSZWNvcmQsICdsZWF2ZUd1YXJkcycsIGxlYXZlR3VhcmQpO1xyXG59XHJcbi8qKlxyXG4gKiBBZGQgYSBuYXZpZ2F0aW9uIGd1YXJkIHRoYXQgdHJpZ2dlcnMgd2hlbmV2ZXIgdGhlIGN1cnJlbnQgbG9jYXRpb24gaXMgYWJvdXRcclxuICogdG8gYmUgdXBkYXRlZC4gU2ltaWxhciB0byB7QGxpbmsgYmVmb3JlUm91dGVVcGRhdGV9IGJ1dCBjYW4gYmUgdXNlZCBpbiBhbnlcclxuICogY29tcG9uZW50LiBUaGUgZ3VhcmQgaXMgcmVtb3ZlZCB3aGVuIHRoZSBjb21wb25lbnQgaXMgdW5tb3VudGVkLlxyXG4gKlxyXG4gKiBAcGFyYW0gdXBkYXRlR3VhcmQgLSB7QGxpbmsgTmF2aWdhdGlvbkd1YXJkfVxyXG4gKi9cclxuZnVuY3Rpb24gb25CZWZvcmVSb3V0ZVVwZGF0ZSh1cGRhdGVHdWFyZCkge1xyXG4gICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiAhZ2V0Q3VycmVudEluc3RhbmNlKCkpIHtcclxuICAgICAgICB3YXJuKCdnZXRDdXJyZW50SW5zdGFuY2UoKSByZXR1cm5lZCBudWxsLiBvbkJlZm9yZVJvdXRlVXBkYXRlKCkgbXVzdCBiZSBjYWxsZWQgYXQgdGhlIHRvcCBvZiBhIHNldHVwIGZ1bmN0aW9uJyk7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgY29uc3QgYWN0aXZlUmVjb3JkID0gaW5qZWN0KG1hdGNoZWRSb3V0ZUtleSwgXHJcbiAgICAvLyB0byBhdm9pZCB3YXJuaW5nXHJcbiAgICB7fSkudmFsdWU7XHJcbiAgICBpZiAoIWFjdGl2ZVJlY29yZCkge1xyXG4gICAgICAgIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJlxyXG4gICAgICAgICAgICB3YXJuKCdObyBhY3RpdmUgcm91dGUgcmVjb3JkIHdhcyBmb3VuZCB3aGVuIGNhbGxpbmcgYG9uQmVmb3JlUm91dGVVcGRhdGUoKWAuIE1ha2Ugc3VyZSB5b3UgY2FsbCB0aGlzIGZ1bmN0aW9uIGluc2lkZSBvZiBhIGNvbXBvbmVudCBjaGlsZCBvZiA8cm91dGVyLXZpZXc+LiBNYXliZSB5b3UgY2FsbGVkIGl0IGluc2lkZSBvZiBBcHAudnVlPycpO1xyXG4gICAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIHJlZ2lzdGVyR3VhcmQoYWN0aXZlUmVjb3JkLCAndXBkYXRlR3VhcmRzJywgdXBkYXRlR3VhcmQpO1xyXG59XHJcbmZ1bmN0aW9uIGd1YXJkVG9Qcm9taXNlRm4oZ3VhcmQsIHRvLCBmcm9tLCByZWNvcmQsIG5hbWUpIHtcclxuICAgIC8vIGtlZXAgYSByZWZlcmVuY2UgdG8gdGhlIGVudGVyQ2FsbGJhY2tBcnJheSB0byBwcmV2ZW50IHB1c2hpbmcgY2FsbGJhY2tzIGlmIGEgbmV3IG5hdmlnYXRpb24gdG9vayBwbGFjZVxyXG4gICAgY29uc3QgZW50ZXJDYWxsYmFja0FycmF5ID0gcmVjb3JkICYmXHJcbiAgICAgICAgLy8gbmFtZSBpcyBkZWZpbmVkIGlmIHJlY29yZCBpcyBiZWNhdXNlIG9mIHRoZSBmdW5jdGlvbiBvdmVybG9hZFxyXG4gICAgICAgIChyZWNvcmQuZW50ZXJDYWxsYmFja3NbbmFtZV0gPSByZWNvcmQuZW50ZXJDYWxsYmFja3NbbmFtZV0gfHwgW10pO1xyXG4gICAgcmV0dXJuICgpID0+IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgICBjb25zdCBuZXh0ID0gKHZhbGlkKSA9PiB7XHJcbiAgICAgICAgICAgIGlmICh2YWxpZCA9PT0gZmFsc2UpXHJcbiAgICAgICAgICAgICAgICByZWplY3QoY3JlYXRlUm91dGVyRXJyb3IoNCAvKiBOQVZJR0FUSU9OX0FCT1JURUQgKi8sIHtcclxuICAgICAgICAgICAgICAgICAgICBmcm9tLFxyXG4gICAgICAgICAgICAgICAgICAgIHRvLFxyXG4gICAgICAgICAgICAgICAgfSkpO1xyXG4gICAgICAgICAgICBlbHNlIGlmICh2YWxpZCBpbnN0YW5jZW9mIEVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICByZWplY3QodmFsaWQpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGlzUm91dGVMb2NhdGlvbih2YWxpZCkpIHtcclxuICAgICAgICAgICAgICAgIHJlamVjdChjcmVhdGVSb3V0ZXJFcnJvcigyIC8qIE5BVklHQVRJT05fR1VBUkRfUkVESVJFQ1QgKi8sIHtcclxuICAgICAgICAgICAgICAgICAgICBmcm9tOiB0byxcclxuICAgICAgICAgICAgICAgICAgICB0bzogdmFsaWQsXHJcbiAgICAgICAgICAgICAgICB9KSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZW50ZXJDYWxsYmFja0FycmF5ICYmXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gc2luY2UgZW50ZXJDYWxsYmFja0FycmF5IGlzIHRydXRoeSwgYm90aCByZWNvcmQgYW5kIG5hbWUgYWxzbyBhcmVcclxuICAgICAgICAgICAgICAgICAgICByZWNvcmQuZW50ZXJDYWxsYmFja3NbbmFtZV0gPT09IGVudGVyQ2FsbGJhY2tBcnJheSAmJlxyXG4gICAgICAgICAgICAgICAgICAgIHR5cGVvZiB2YWxpZCA9PT0gJ2Z1bmN0aW9uJylcclxuICAgICAgICAgICAgICAgICAgICBlbnRlckNhbGxiYWNrQXJyYXkucHVzaCh2YWxpZCk7XHJcbiAgICAgICAgICAgICAgICByZXNvbHZlKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIC8vIHdyYXBwaW5nIHdpdGggUHJvbWlzZS5yZXNvbHZlIGFsbG93cyBpdCB0byB3b3JrIHdpdGggYm90aCBhc3luYyBhbmQgc3luYyBndWFyZHNcclxuICAgICAgICBjb25zdCBndWFyZFJldHVybiA9IGd1YXJkLmNhbGwocmVjb3JkICYmIHJlY29yZC5pbnN0YW5jZXNbbmFtZV0sIHRvLCBmcm9tLCAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgPyBjYW5Pbmx5QmVDYWxsZWRPbmNlKG5leHQsIHRvLCBmcm9tKSA6IG5leHQpO1xyXG4gICAgICAgIGxldCBndWFyZENhbGwgPSBQcm9taXNlLnJlc29sdmUoZ3VhcmRSZXR1cm4pO1xyXG4gICAgICAgIGlmIChndWFyZC5sZW5ndGggPCAzKVxyXG4gICAgICAgICAgICBndWFyZENhbGwgPSBndWFyZENhbGwudGhlbihuZXh0KTtcclxuICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmIGd1YXJkLmxlbmd0aCA+IDIpIHtcclxuICAgICAgICAgICAgY29uc3QgbWVzc2FnZSA9IGBUaGUgXCJuZXh0XCIgY2FsbGJhY2sgd2FzIG5ldmVyIGNhbGxlZCBpbnNpZGUgb2YgJHtndWFyZC5uYW1lID8gJ1wiJyArIGd1YXJkLm5hbWUgKyAnXCInIDogJyd9OlxcbiR7Z3VhcmQudG9TdHJpbmcoKX1cXG4uIElmIHlvdSBhcmUgcmV0dXJuaW5nIGEgdmFsdWUgaW5zdGVhZCBvZiBjYWxsaW5nIFwibmV4dFwiLCBtYWtlIHN1cmUgdG8gcmVtb3ZlIHRoZSBcIm5leHRcIiBwYXJhbWV0ZXIgZnJvbSB5b3VyIGZ1bmN0aW9uLmA7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZ3VhcmRSZXR1cm4gPT09ICdvYmplY3QnICYmICd0aGVuJyBpbiBndWFyZFJldHVybikge1xyXG4gICAgICAgICAgICAgICAgZ3VhcmRDYWxsID0gZ3VhcmRDYWxsLnRoZW4ocmVzb2x2ZWRWYWx1ZSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvcjogX2NhbGxlZCBpcyBhZGRlZCBhdCBjYW5Pbmx5QmVDYWxsZWRPbmNlXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFuZXh0Ll9jYWxsZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgd2FybihtZXNzYWdlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcignSW52YWxpZCBuYXZpZ2F0aW9uIGd1YXJkJykpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZWRWYWx1ZTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgLy8gVE9ETzogdGVzdCBtZSFcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChndWFyZFJldHVybiAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yOiBfY2FsbGVkIGlzIGFkZGVkIGF0IGNhbk9ubHlCZUNhbGxlZE9uY2VcclxuICAgICAgICAgICAgICAgIGlmICghbmV4dC5fY2FsbGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgd2FybihtZXNzYWdlKTtcclxuICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKCdJbnZhbGlkIG5hdmlnYXRpb24gZ3VhcmQnKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGd1YXJkQ2FsbC5jYXRjaChlcnIgPT4gcmVqZWN0KGVycikpO1xyXG4gICAgfSk7XHJcbn1cclxuZnVuY3Rpb24gY2FuT25seUJlQ2FsbGVkT25jZShuZXh0LCB0bywgZnJvbSkge1xyXG4gICAgbGV0IGNhbGxlZCA9IDA7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGlmIChjYWxsZWQrKyA9PT0gMSlcclxuICAgICAgICAgICAgd2FybihgVGhlIFwibmV4dFwiIGNhbGxiYWNrIHdhcyBjYWxsZWQgbW9yZSB0aGFuIG9uY2UgaW4gb25lIG5hdmlnYXRpb24gZ3VhcmQgd2hlbiBnb2luZyBmcm9tIFwiJHtmcm9tLmZ1bGxQYXRofVwiIHRvIFwiJHt0by5mdWxsUGF0aH1cIi4gSXQgc2hvdWxkIGJlIGNhbGxlZCBleGFjdGx5IG9uZSB0aW1lIGluIGVhY2ggbmF2aWdhdGlvbiBndWFyZC4gVGhpcyB3aWxsIGZhaWwgaW4gcHJvZHVjdGlvbi5gKTtcclxuICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yOiB3ZSBwdXQgaXQgaW4gdGhlIG9yaWdpbmFsIG9uZSBiZWNhdXNlIGl0J3MgZWFzaWVyIHRvIGNoZWNrXHJcbiAgICAgICAgbmV4dC5fY2FsbGVkID0gdHJ1ZTtcclxuICAgICAgICBpZiAoY2FsbGVkID09PSAxKVxyXG4gICAgICAgICAgICBuZXh0LmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XHJcbiAgICB9O1xyXG59XHJcbmZ1bmN0aW9uIGV4dHJhY3RDb21wb25lbnRzR3VhcmRzKG1hdGNoZWQsIGd1YXJkVHlwZSwgdG8sIGZyb20pIHtcclxuICAgIGNvbnN0IGd1YXJkcyA9IFtdO1xyXG4gICAgZm9yIChjb25zdCByZWNvcmQgb2YgbWF0Y2hlZCkge1xyXG4gICAgICAgIGZvciAoY29uc3QgbmFtZSBpbiByZWNvcmQuY29tcG9uZW50cykge1xyXG4gICAgICAgICAgICBsZXQgcmF3Q29tcG9uZW50ID0gcmVjb3JkLmNvbXBvbmVudHNbbmFtZV07XHJcbiAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICAgICAgICAgIGlmICghcmF3Q29tcG9uZW50IHx8XHJcbiAgICAgICAgICAgICAgICAgICAgKHR5cGVvZiByYXdDb21wb25lbnQgIT09ICdvYmplY3QnICYmXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVvZiByYXdDb21wb25lbnQgIT09ICdmdW5jdGlvbicpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgd2FybihgQ29tcG9uZW50IFwiJHtuYW1lfVwiIGluIHJlY29yZCB3aXRoIHBhdGggXCIke3JlY29yZC5wYXRofVwiIGlzIG5vdGAgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBgIGEgdmFsaWQgY29tcG9uZW50LiBSZWNlaXZlZCBcIiR7U3RyaW5nKHJhd0NvbXBvbmVudCl9XCIuYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gdGhyb3cgdG8gZW5zdXJlIHdlIHN0b3AgaGVyZSBidXQgd2FybiB0byBlbnN1cmUgdGhlIG1lc3NhZ2UgaXNuJ3RcclxuICAgICAgICAgICAgICAgICAgICAvLyBtaXNzZWQgYnkgdGhlIHVzZXJcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgcm91dGUgY29tcG9uZW50Jyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmICgndGhlbicgaW4gcmF3Q29tcG9uZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gd2FybiBpZiB1c2VyIHdyb3RlIGltcG9ydCgnL2NvbXBvbmVudC52dWUnKSBpbnN0ZWFkIG9mICgpID0+XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gaW1wb3J0KCcuL2NvbXBvbmVudC52dWUnKVxyXG4gICAgICAgICAgICAgICAgICAgIHdhcm4oYENvbXBvbmVudCBcIiR7bmFtZX1cIiBpbiByZWNvcmQgd2l0aCBwYXRoIFwiJHtyZWNvcmQucGF0aH1cIiBpcyBhIGAgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBgUHJvbWlzZSBpbnN0ZWFkIG9mIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIGEgUHJvbWlzZS4gRGlkIHlvdSBgICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYHdyaXRlIFwiaW1wb3J0KCcuL015UGFnZS52dWUnKVwiIGluc3RlYWQgb2YgYCArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGBcIigpID0+IGltcG9ydCgnLi9NeVBhZ2UudnVlJylcIiA/IFRoaXMgd2lsbCBicmVhayBpbiBgICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYHByb2R1Y3Rpb24gaWYgbm90IGZpeGVkLmApO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHByb21pc2UgPSByYXdDb21wb25lbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgcmF3Q29tcG9uZW50ID0gKCkgPT4gcHJvbWlzZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHJhd0NvbXBvbmVudC5fX2FzeW5jTG9hZGVyICYmXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gd2FybiBvbmx5IG9uY2UgcGVyIGNvbXBvbmVudFxyXG4gICAgICAgICAgICAgICAgICAgICFyYXdDb21wb25lbnQuX193YXJuZWREZWZpbmVBc3luYykge1xyXG4gICAgICAgICAgICAgICAgICAgIHJhd0NvbXBvbmVudC5fX3dhcm5lZERlZmluZUFzeW5jID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB3YXJuKGBDb21wb25lbnQgXCIke25hbWV9XCIgaW4gcmVjb3JkIHdpdGggcGF0aCBcIiR7cmVjb3JkLnBhdGh9XCIgaXMgZGVmaW5lZCBgICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYHVzaW5nIFwiZGVmaW5lQXN5bmNDb21wb25lbnQoKVwiLiBgICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYFdyaXRlIFwiKCkgPT4gaW1wb3J0KCcuL015UGFnZS52dWUnKVwiIGluc3RlYWQgb2YgYCArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGBcImRlZmluZUFzeW5jQ29tcG9uZW50KCgpID0+IGltcG9ydCgnLi9NeVBhZ2UudnVlJykpXCIuYCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gc2tpcCB1cGRhdGUgYW5kIGxlYXZlIGd1YXJkcyBpZiB0aGUgcm91dGUgY29tcG9uZW50IGlzIG5vdCBtb3VudGVkXHJcbiAgICAgICAgICAgIGlmIChndWFyZFR5cGUgIT09ICdiZWZvcmVSb3V0ZUVudGVyJyAmJiAhcmVjb3JkLmluc3RhbmNlc1tuYW1lXSlcclxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICBpZiAoaXNSb3V0ZUNvbXBvbmVudChyYXdDb21wb25lbnQpKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBfX3ZjY09wdHMgaXMgYWRkZWQgYnkgdnVlLWNsYXNzLWNvbXBvbmVudCBhbmQgY29udGFpbiB0aGUgcmVndWxhciBvcHRpb25zXHJcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0gcmF3Q29tcG9uZW50Ll9fdmNjT3B0cyB8fCByYXdDb21wb25lbnQ7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBndWFyZCA9IG9wdGlvbnNbZ3VhcmRUeXBlXTtcclxuICAgICAgICAgICAgICAgIGd1YXJkICYmIGd1YXJkcy5wdXNoKGd1YXJkVG9Qcm9taXNlRm4oZ3VhcmQsIHRvLCBmcm9tLCByZWNvcmQsIG5hbWUpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIC8vIHN0YXJ0IHJlcXVlc3RpbmcgdGhlIGNodW5rIGFscmVhZHlcclxuICAgICAgICAgICAgICAgIGxldCBjb21wb25lbnRQcm9taXNlID0gcmF3Q29tcG9uZW50KCk7XHJcbiAgICAgICAgICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmICEoJ2NhdGNoJyBpbiBjb21wb25lbnRQcm9taXNlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHdhcm4oYENvbXBvbmVudCBcIiR7bmFtZX1cIiBpbiByZWNvcmQgd2l0aCBwYXRoIFwiJHtyZWNvcmQucGF0aH1cIiBpcyBhIGZ1bmN0aW9uIHRoYXQgZG9lcyBub3QgcmV0dXJuIGEgUHJvbWlzZS4gSWYgeW91IHdlcmUgcGFzc2luZyBhIGZ1bmN0aW9uYWwgY29tcG9uZW50LCBtYWtlIHN1cmUgdG8gYWRkIGEgXCJkaXNwbGF5TmFtZVwiIHRvIHRoZSBjb21wb25lbnQuIFRoaXMgd2lsbCBicmVhayBpbiBwcm9kdWN0aW9uIGlmIG5vdCBmaXhlZC5gKTtcclxuICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRQcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKGNvbXBvbmVudFByb21pc2UpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZ3VhcmRzLnB1c2goKCkgPT4gY29tcG9uZW50UHJvbWlzZS50aGVuKHJlc29sdmVkID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIXJlc29sdmVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKGBDb3VsZG4ndCByZXNvbHZlIGNvbXBvbmVudCBcIiR7bmFtZX1cIiBhdCBcIiR7cmVjb3JkLnBhdGh9XCJgKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzb2x2ZWRDb21wb25lbnQgPSBpc0VTTW9kdWxlKHJlc29sdmVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICA/IHJlc29sdmVkLmRlZmF1bHRcclxuICAgICAgICAgICAgICAgICAgICAgICAgOiByZXNvbHZlZDtcclxuICAgICAgICAgICAgICAgICAgICAvLyByZXBsYWNlIHRoZSBmdW5jdGlvbiB3aXRoIHRoZSByZXNvbHZlZCBjb21wb25lbnRcclxuICAgICAgICAgICAgICAgICAgICByZWNvcmQuY29tcG9uZW50c1tuYW1lXSA9IHJlc29sdmVkQ29tcG9uZW50O1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIF9fdmNjT3B0cyBpcyBhZGRlZCBieSB2dWUtY2xhc3MtY29tcG9uZW50IGFuZCBjb250YWluIHRoZSByZWd1bGFyIG9wdGlvbnNcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0gcmVzb2x2ZWRDb21wb25lbnQuX192Y2NPcHRzIHx8IHJlc29sdmVkQ29tcG9uZW50O1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGd1YXJkID0gb3B0aW9uc1tndWFyZFR5cGVdO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBndWFyZCAmJiBndWFyZFRvUHJvbWlzZUZuKGd1YXJkLCB0bywgZnJvbSwgcmVjb3JkLCBuYW1lKSgpO1xyXG4gICAgICAgICAgICAgICAgfSkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGd1YXJkcztcclxufVxyXG4vKipcclxuICogQWxsb3dzIGRpZmZlcmVudGlhdGluZyBsYXp5IGNvbXBvbmVudHMgZnJvbSBmdW5jdGlvbmFsIGNvbXBvbmVudHMgYW5kIHZ1ZS1jbGFzcy1jb21wb25lbnRcclxuICpcclxuICogQHBhcmFtIGNvbXBvbmVudFxyXG4gKi9cclxuZnVuY3Rpb24gaXNSb3V0ZUNvbXBvbmVudChjb21wb25lbnQpIHtcclxuICAgIHJldHVybiAodHlwZW9mIGNvbXBvbmVudCA9PT0gJ29iamVjdCcgfHxcclxuICAgICAgICAnZGlzcGxheU5hbWUnIGluIGNvbXBvbmVudCB8fFxyXG4gICAgICAgICdwcm9wcycgaW4gY29tcG9uZW50IHx8XHJcbiAgICAgICAgJ19fdmNjT3B0cycgaW4gY29tcG9uZW50KTtcclxufVxuXG4vLyBUT0RPOiB3ZSBjb3VsZCBhbGxvdyBjdXJyZW50Um91dGUgYXMgYSBwcm9wIHRvIGV4cG9zZSBgaXNBY3RpdmVgIGFuZFxyXG4vLyBgaXNFeGFjdEFjdGl2ZWAgYmVoYXZpb3Igc2hvdWxkIGdvIHRocm91Z2ggYW4gUkZDXHJcbmZ1bmN0aW9uIHVzZUxpbmsocHJvcHMpIHtcclxuICAgIGNvbnN0IHJvdXRlciA9IGluamVjdChyb3V0ZXJLZXkpO1xyXG4gICAgY29uc3QgY3VycmVudFJvdXRlID0gaW5qZWN0KHJvdXRlTG9jYXRpb25LZXkpO1xyXG4gICAgY29uc3Qgcm91dGUgPSBjb21wdXRlZCgoKSA9PiByb3V0ZXIucmVzb2x2ZSh1bnJlZihwcm9wcy50bykpKTtcclxuICAgIGNvbnN0IGFjdGl2ZVJlY29yZEluZGV4ID0gY29tcHV0ZWQoKCkgPT4ge1xyXG4gICAgICAgIGNvbnN0IHsgbWF0Y2hlZCB9ID0gcm91dGUudmFsdWU7XHJcbiAgICAgICAgY29uc3QgeyBsZW5ndGggfSA9IG1hdGNoZWQ7XHJcbiAgICAgICAgY29uc3Qgcm91dGVNYXRjaGVkID0gbWF0Y2hlZFtsZW5ndGggLSAxXTtcclxuICAgICAgICBjb25zdCBjdXJyZW50TWF0Y2hlZCA9IGN1cnJlbnRSb3V0ZS5tYXRjaGVkO1xyXG4gICAgICAgIGlmICghcm91dGVNYXRjaGVkIHx8ICFjdXJyZW50TWF0Y2hlZC5sZW5ndGgpXHJcbiAgICAgICAgICAgIHJldHVybiAtMTtcclxuICAgICAgICBjb25zdCBpbmRleCA9IGN1cnJlbnRNYXRjaGVkLmZpbmRJbmRleChpc1NhbWVSb3V0ZVJlY29yZC5iaW5kKG51bGwsIHJvdXRlTWF0Y2hlZCkpO1xyXG4gICAgICAgIGlmIChpbmRleCA+IC0xKVxyXG4gICAgICAgICAgICByZXR1cm4gaW5kZXg7XHJcbiAgICAgICAgLy8gcG9zc2libGUgcGFyZW50IHJlY29yZFxyXG4gICAgICAgIGNvbnN0IHBhcmVudFJlY29yZFBhdGggPSBnZXRPcmlnaW5hbFBhdGgobWF0Y2hlZFtsZW5ndGggLSAyXSk7XHJcbiAgICAgICAgcmV0dXJuIChcclxuICAgICAgICAvLyB3ZSBhcmUgZGVhbGluZyB3aXRoIG5lc3RlZCByb3V0ZXNcclxuICAgICAgICBsZW5ndGggPiAxICYmXHJcbiAgICAgICAgICAgIC8vIGlmIHRoZSBwYXJlbnQgYW5kIG1hdGNoZWQgcm91dGUgaGF2ZSB0aGUgc2FtZSBwYXRoLCB0aGlzIGxpbmsgaXNcclxuICAgICAgICAgICAgLy8gcmVmZXJyaW5nIHRvIHRoZSBlbXB0eSBjaGlsZC4gT3Igd2UgY3VycmVudGx5IGFyZSBvbiBhIGRpZmZlcmVudFxyXG4gICAgICAgICAgICAvLyBjaGlsZCBvZiB0aGUgc2FtZSBwYXJlbnRcclxuICAgICAgICAgICAgZ2V0T3JpZ2luYWxQYXRoKHJvdXRlTWF0Y2hlZCkgPT09IHBhcmVudFJlY29yZFBhdGggJiZcclxuICAgICAgICAgICAgLy8gYXZvaWQgY29tcGFyaW5nIHRoZSBjaGlsZCB3aXRoIGl0cyBwYXJlbnRcclxuICAgICAgICAgICAgY3VycmVudE1hdGNoZWRbY3VycmVudE1hdGNoZWQubGVuZ3RoIC0gMV0ucGF0aCAhPT0gcGFyZW50UmVjb3JkUGF0aFxyXG4gICAgICAgICAgICA/IGN1cnJlbnRNYXRjaGVkLmZpbmRJbmRleChpc1NhbWVSb3V0ZVJlY29yZC5iaW5kKG51bGwsIG1hdGNoZWRbbGVuZ3RoIC0gMl0pKVxyXG4gICAgICAgICAgICA6IGluZGV4KTtcclxuICAgIH0pO1xyXG4gICAgY29uc3QgaXNBY3RpdmUgPSBjb21wdXRlZCgoKSA9PiBhY3RpdmVSZWNvcmRJbmRleC52YWx1ZSA+IC0xICYmXHJcbiAgICAgICAgaW5jbHVkZXNQYXJhbXMoY3VycmVudFJvdXRlLnBhcmFtcywgcm91dGUudmFsdWUucGFyYW1zKSk7XHJcbiAgICBjb25zdCBpc0V4YWN0QWN0aXZlID0gY29tcHV0ZWQoKCkgPT4gYWN0aXZlUmVjb3JkSW5kZXgudmFsdWUgPiAtMSAmJlxyXG4gICAgICAgIGFjdGl2ZVJlY29yZEluZGV4LnZhbHVlID09PSBjdXJyZW50Um91dGUubWF0Y2hlZC5sZW5ndGggLSAxICYmXHJcbiAgICAgICAgaXNTYW1lUm91dGVMb2NhdGlvblBhcmFtcyhjdXJyZW50Um91dGUucGFyYW1zLCByb3V0ZS52YWx1ZS5wYXJhbXMpKTtcclxuICAgIGZ1bmN0aW9uIG5hdmlnYXRlKGUgPSB7fSkge1xyXG4gICAgICAgIGlmIChndWFyZEV2ZW50KGUpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiByb3V0ZXJbdW5yZWYocHJvcHMucmVwbGFjZSkgPyAncmVwbGFjZScgOiAncHVzaCddKHVucmVmKHByb3BzLnRvKVxyXG4gICAgICAgICAgICAvLyBhdm9pZCB1bmNhdWdodCBlcnJvcnMgYXJlIHRoZXkgYXJlIGxvZ2dlZCBhbnl3YXlcclxuICAgICAgICAgICAgKS5jYXRjaChub29wKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgfVxyXG4gICAgLy8gZGV2dG9vbHMgb25seVxyXG4gICAgaWYgKCgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgfHwgX19WVUVfUFJPRF9ERVZUT09MU19fKSAmJiBpc0Jyb3dzZXIpIHtcclxuICAgICAgICBjb25zdCBpbnN0YW5jZSA9IGdldEN1cnJlbnRJbnN0YW5jZSgpO1xyXG4gICAgICAgIGlmIChpbnN0YW5jZSkge1xyXG4gICAgICAgICAgICBjb25zdCBsaW5rQ29udGV4dERldnRvb2xzID0ge1xyXG4gICAgICAgICAgICAgICAgcm91dGU6IHJvdXRlLnZhbHVlLFxyXG4gICAgICAgICAgICAgICAgaXNBY3RpdmU6IGlzQWN0aXZlLnZhbHVlLFxyXG4gICAgICAgICAgICAgICAgaXNFeGFjdEFjdGl2ZTogaXNFeGFjdEFjdGl2ZS52YWx1ZSxcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvcjogdGhpcyBpcyBpbnRlcm5hbFxyXG4gICAgICAgICAgICBpbnN0YW5jZS5fX3ZybF9kZXZ0b29scyA9IGluc3RhbmNlLl9fdnJsX2RldnRvb2xzIHx8IFtdO1xyXG4gICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yOiB0aGlzIGlzIGludGVybmFsXHJcbiAgICAgICAgICAgIGluc3RhbmNlLl9fdnJsX2RldnRvb2xzLnB1c2gobGlua0NvbnRleHREZXZ0b29scyk7XHJcbiAgICAgICAgICAgIHdhdGNoRWZmZWN0KCgpID0+IHtcclxuICAgICAgICAgICAgICAgIGxpbmtDb250ZXh0RGV2dG9vbHMucm91dGUgPSByb3V0ZS52YWx1ZTtcclxuICAgICAgICAgICAgICAgIGxpbmtDb250ZXh0RGV2dG9vbHMuaXNBY3RpdmUgPSBpc0FjdGl2ZS52YWx1ZTtcclxuICAgICAgICAgICAgICAgIGxpbmtDb250ZXh0RGV2dG9vbHMuaXNFeGFjdEFjdGl2ZSA9IGlzRXhhY3RBY3RpdmUudmFsdWU7XHJcbiAgICAgICAgICAgIH0sIHsgZmx1c2g6ICdwb3N0JyB9KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIHJvdXRlLFxyXG4gICAgICAgIGhyZWY6IGNvbXB1dGVkKCgpID0+IHJvdXRlLnZhbHVlLmhyZWYpLFxyXG4gICAgICAgIGlzQWN0aXZlLFxyXG4gICAgICAgIGlzRXhhY3RBY3RpdmUsXHJcbiAgICAgICAgbmF2aWdhdGUsXHJcbiAgICB9O1xyXG59XHJcbmNvbnN0IFJvdXRlckxpbmtJbXBsID0gLyojX19QVVJFX18qLyBkZWZpbmVDb21wb25lbnQoe1xyXG4gICAgbmFtZTogJ1JvdXRlckxpbmsnLFxyXG4gICAgcHJvcHM6IHtcclxuICAgICAgICB0bzoge1xyXG4gICAgICAgICAgICB0eXBlOiBbU3RyaW5nLCBPYmplY3RdLFxyXG4gICAgICAgICAgICByZXF1aXJlZDogdHJ1ZSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHJlcGxhY2U6IEJvb2xlYW4sXHJcbiAgICAgICAgYWN0aXZlQ2xhc3M6IFN0cmluZyxcclxuICAgICAgICAvLyBpbmFjdGl2ZUNsYXNzOiBTdHJpbmcsXHJcbiAgICAgICAgZXhhY3RBY3RpdmVDbGFzczogU3RyaW5nLFxyXG4gICAgICAgIGN1c3RvbTogQm9vbGVhbixcclxuICAgICAgICBhcmlhQ3VycmVudFZhbHVlOiB7XHJcbiAgICAgICAgICAgIHR5cGU6IFN0cmluZyxcclxuICAgICAgICAgICAgZGVmYXVsdDogJ3BhZ2UnLFxyXG4gICAgICAgIH0sXHJcbiAgICB9LFxyXG4gICAgdXNlTGluayxcclxuICAgIHNldHVwKHByb3BzLCB7IHNsb3RzIH0pIHtcclxuICAgICAgICBjb25zdCBsaW5rID0gcmVhY3RpdmUodXNlTGluayhwcm9wcykpO1xyXG4gICAgICAgIGNvbnN0IHsgb3B0aW9ucyB9ID0gaW5qZWN0KHJvdXRlcktleSk7XHJcbiAgICAgICAgY29uc3QgZWxDbGFzcyA9IGNvbXB1dGVkKCgpID0+ICh7XHJcbiAgICAgICAgICAgIFtnZXRMaW5rQ2xhc3MocHJvcHMuYWN0aXZlQ2xhc3MsIG9wdGlvbnMubGlua0FjdGl2ZUNsYXNzLCAncm91dGVyLWxpbmstYWN0aXZlJyldOiBsaW5rLmlzQWN0aXZlLFxyXG4gICAgICAgICAgICAvLyBbZ2V0TGlua0NsYXNzKFxyXG4gICAgICAgICAgICAvLyAgIHByb3BzLmluYWN0aXZlQ2xhc3MsXHJcbiAgICAgICAgICAgIC8vICAgb3B0aW9ucy5saW5rSW5hY3RpdmVDbGFzcyxcclxuICAgICAgICAgICAgLy8gICAncm91dGVyLWxpbmstaW5hY3RpdmUnXHJcbiAgICAgICAgICAgIC8vICldOiAhbGluay5pc0V4YWN0QWN0aXZlLFxyXG4gICAgICAgICAgICBbZ2V0TGlua0NsYXNzKHByb3BzLmV4YWN0QWN0aXZlQ2xhc3MsIG9wdGlvbnMubGlua0V4YWN0QWN0aXZlQ2xhc3MsICdyb3V0ZXItbGluay1leGFjdC1hY3RpdmUnKV06IGxpbmsuaXNFeGFjdEFjdGl2ZSxcclxuICAgICAgICB9KSk7XHJcbiAgICAgICAgcmV0dXJuICgpID0+IHtcclxuICAgICAgICAgICAgY29uc3QgY2hpbGRyZW4gPSBzbG90cy5kZWZhdWx0ICYmIHNsb3RzLmRlZmF1bHQobGluayk7XHJcbiAgICAgICAgICAgIHJldHVybiBwcm9wcy5jdXN0b21cclxuICAgICAgICAgICAgICAgID8gY2hpbGRyZW5cclxuICAgICAgICAgICAgICAgIDogaCgnYScsIHtcclxuICAgICAgICAgICAgICAgICAgICAnYXJpYS1jdXJyZW50JzogbGluay5pc0V4YWN0QWN0aXZlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgID8gcHJvcHMuYXJpYUN1cnJlbnRWYWx1ZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICA6IG51bGwsXHJcbiAgICAgICAgICAgICAgICAgICAgaHJlZjogbGluay5ocmVmLFxyXG4gICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgd291bGQgb3ZlcnJpZGUgdXNlciBhZGRlZCBhdHRycyBidXQgVnVlIHdpbGwgc3RpbGwgYWRkXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGxpc3RlbmVyIHNvIHdlIGVuZCB1cCB0cmlnZ2VyaW5nIGJvdGhcclxuICAgICAgICAgICAgICAgICAgICBvbkNsaWNrOiBsaW5rLm5hdmlnYXRlLFxyXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzOiBlbENsYXNzLnZhbHVlLFxyXG4gICAgICAgICAgICAgICAgfSwgY2hpbGRyZW4pO1xyXG4gICAgICAgIH07XHJcbiAgICB9LFxyXG59KTtcclxuLy8gZXhwb3J0IHRoZSBwdWJsaWMgdHlwZSBmb3IgaC90c3ggaW5mZXJlbmNlXHJcbi8vIGFsc28gdG8gYXZvaWQgaW5saW5lIGltcG9ydCgpIGluIGdlbmVyYXRlZCBkLnRzIGZpbGVzXHJcbi8qKlxyXG4gKiBDb21wb25lbnQgdG8gcmVuZGVyIGEgbGluayB0aGF0IHRyaWdnZXJzIGEgbmF2aWdhdGlvbiBvbiBjbGljay5cclxuICovXHJcbmNvbnN0IFJvdXRlckxpbmsgPSBSb3V0ZXJMaW5rSW1wbDtcclxuZnVuY3Rpb24gZ3VhcmRFdmVudChlKSB7XHJcbiAgICAvLyBkb24ndCByZWRpcmVjdCB3aXRoIGNvbnRyb2wga2V5c1xyXG4gICAgaWYgKGUubWV0YUtleSB8fCBlLmFsdEtleSB8fCBlLmN0cmxLZXkgfHwgZS5zaGlmdEtleSlcclxuICAgICAgICByZXR1cm47XHJcbiAgICAvLyBkb24ndCByZWRpcmVjdCB3aGVuIHByZXZlbnREZWZhdWx0IGNhbGxlZFxyXG4gICAgaWYgKGUuZGVmYXVsdFByZXZlbnRlZClcclxuICAgICAgICByZXR1cm47XHJcbiAgICAvLyBkb24ndCByZWRpcmVjdCBvbiByaWdodCBjbGlja1xyXG4gICAgaWYgKGUuYnV0dG9uICE9PSB1bmRlZmluZWQgJiYgZS5idXR0b24gIT09IDApXHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgLy8gZG9uJ3QgcmVkaXJlY3QgaWYgYHRhcmdldD1cIl9ibGFua1wiYFxyXG4gICAgLy8gQHRzLWV4cGVjdC1lcnJvciBnZXRBdHRyaWJ1dGUgZG9lcyBleGlzdFxyXG4gICAgaWYgKGUuY3VycmVudFRhcmdldCAmJiBlLmN1cnJlbnRUYXJnZXQuZ2V0QXR0cmlidXRlKSB7XHJcbiAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBnZXRBdHRyaWJ1dGUgZXhpc3RzXHJcbiAgICAgICAgY29uc3QgdGFyZ2V0ID0gZS5jdXJyZW50VGFyZ2V0LmdldEF0dHJpYnV0ZSgndGFyZ2V0Jyk7XHJcbiAgICAgICAgaWYgKC9cXGJfYmxhbmtcXGIvaS50ZXN0KHRhcmdldCkpXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIC8vIHRoaXMgbWF5IGJlIGEgV2VleCBldmVudCB3aGljaCBkb2Vzbid0IGhhdmUgdGhpcyBtZXRob2RcclxuICAgIGlmIChlLnByZXZlbnREZWZhdWx0KVxyXG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgIHJldHVybiB0cnVlO1xyXG59XHJcbmZ1bmN0aW9uIGluY2x1ZGVzUGFyYW1zKG91dGVyLCBpbm5lcikge1xyXG4gICAgZm9yIChjb25zdCBrZXkgaW4gaW5uZXIpIHtcclxuICAgICAgICBjb25zdCBpbm5lclZhbHVlID0gaW5uZXJba2V5XTtcclxuICAgICAgICBjb25zdCBvdXRlclZhbHVlID0gb3V0ZXJba2V5XTtcclxuICAgICAgICBpZiAodHlwZW9mIGlubmVyVmFsdWUgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICAgIGlmIChpbm5lclZhbHVlICE9PSBvdXRlclZhbHVlKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG91dGVyVmFsdWUpIHx8XHJcbiAgICAgICAgICAgICAgICBvdXRlclZhbHVlLmxlbmd0aCAhPT0gaW5uZXJWYWx1ZS5sZW5ndGggfHxcclxuICAgICAgICAgICAgICAgIGlubmVyVmFsdWUuc29tZSgodmFsdWUsIGkpID0+IHZhbHVlICE9PSBvdXRlclZhbHVlW2ldKSlcclxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdHJ1ZTtcclxufVxyXG4vKipcclxuICogR2V0IHRoZSBvcmlnaW5hbCBwYXRoIHZhbHVlIG9mIGEgcmVjb3JkIGJ5IGZvbGxvd2luZyBpdHMgYWxpYXNPZlxyXG4gKiBAcGFyYW0gcmVjb3JkXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRPcmlnaW5hbFBhdGgocmVjb3JkKSB7XHJcbiAgICByZXR1cm4gcmVjb3JkID8gKHJlY29yZC5hbGlhc09mID8gcmVjb3JkLmFsaWFzT2YucGF0aCA6IHJlY29yZC5wYXRoKSA6ICcnO1xyXG59XHJcbi8qKlxyXG4gKiBVdGlsaXR5IGNsYXNzIHRvIGdldCB0aGUgYWN0aXZlIGNsYXNzIGJhc2VkIG9uIGRlZmF1bHRzLlxyXG4gKiBAcGFyYW0gcHJvcENsYXNzXHJcbiAqIEBwYXJhbSBnbG9iYWxDbGFzc1xyXG4gKiBAcGFyYW0gZGVmYXVsdENsYXNzXHJcbiAqL1xyXG5jb25zdCBnZXRMaW5rQ2xhc3MgPSAocHJvcENsYXNzLCBnbG9iYWxDbGFzcywgZGVmYXVsdENsYXNzKSA9PiBwcm9wQ2xhc3MgIT0gbnVsbFxyXG4gICAgPyBwcm9wQ2xhc3NcclxuICAgIDogZ2xvYmFsQ2xhc3MgIT0gbnVsbFxyXG4gICAgICAgID8gZ2xvYmFsQ2xhc3NcclxuICAgICAgICA6IGRlZmF1bHRDbGFzcztcblxuY29uc3QgUm91dGVyVmlld0ltcGwgPSAvKiNfX1BVUkVfXyovIGRlZmluZUNvbXBvbmVudCh7XHJcbiAgICBuYW1lOiAnUm91dGVyVmlldycsXHJcbiAgICAvLyAjNjc0IHdlIG1hbnVhbGx5IGluaGVyaXQgdGhlbVxyXG4gICAgaW5oZXJpdEF0dHJzOiBmYWxzZSxcclxuICAgIHByb3BzOiB7XHJcbiAgICAgICAgbmFtZToge1xyXG4gICAgICAgICAgICB0eXBlOiBTdHJpbmcsXHJcbiAgICAgICAgICAgIGRlZmF1bHQ6ICdkZWZhdWx0JyxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHJvdXRlOiBPYmplY3QsXHJcbiAgICB9LFxyXG4gICAgc2V0dXAocHJvcHMsIHsgYXR0cnMsIHNsb3RzIH0pIHtcclxuICAgICAgICAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiYgd2FybkRlcHJlY2F0ZWRVc2FnZSgpO1xyXG4gICAgICAgIGNvbnN0IGluamVjdGVkUm91dGUgPSBpbmplY3Qocm91dGVyVmlld0xvY2F0aW9uS2V5KTtcclxuICAgICAgICBjb25zdCByb3V0ZVRvRGlzcGxheSA9IGNvbXB1dGVkKCgpID0+IHByb3BzLnJvdXRlIHx8IGluamVjdGVkUm91dGUudmFsdWUpO1xyXG4gICAgICAgIGNvbnN0IGRlcHRoID0gaW5qZWN0KHZpZXdEZXB0aEtleSwgMCk7XHJcbiAgICAgICAgY29uc3QgbWF0Y2hlZFJvdXRlUmVmID0gY29tcHV0ZWQoKCkgPT4gcm91dGVUb0Rpc3BsYXkudmFsdWUubWF0Y2hlZFtkZXB0aF0pO1xyXG4gICAgICAgIHByb3ZpZGUodmlld0RlcHRoS2V5LCBkZXB0aCArIDEpO1xyXG4gICAgICAgIHByb3ZpZGUobWF0Y2hlZFJvdXRlS2V5LCBtYXRjaGVkUm91dGVSZWYpO1xyXG4gICAgICAgIHByb3ZpZGUocm91dGVyVmlld0xvY2F0aW9uS2V5LCByb3V0ZVRvRGlzcGxheSk7XHJcbiAgICAgICAgY29uc3Qgdmlld1JlZiA9IHJlZigpO1xyXG4gICAgICAgIC8vIHdhdGNoIGF0IHRoZSBzYW1lIHRpbWUgdGhlIGNvbXBvbmVudCBpbnN0YW5jZSwgdGhlIHJvdXRlIHJlY29yZCB3ZSBhcmVcclxuICAgICAgICAvLyByZW5kZXJpbmcsIGFuZCB0aGUgbmFtZVxyXG4gICAgICAgIHdhdGNoKCgpID0+IFt2aWV3UmVmLnZhbHVlLCBtYXRjaGVkUm91dGVSZWYudmFsdWUsIHByb3BzLm5hbWVdLCAoW2luc3RhbmNlLCB0bywgbmFtZV0sIFtvbGRJbnN0YW5jZSwgZnJvbSwgb2xkTmFtZV0pID0+IHtcclxuICAgICAgICAgICAgLy8gY29weSByZXVzZWQgaW5zdGFuY2VzXHJcbiAgICAgICAgICAgIGlmICh0bykge1xyXG4gICAgICAgICAgICAgICAgLy8gdGhpcyB3aWxsIHVwZGF0ZSB0aGUgaW5zdGFuY2UgZm9yIG5ldyBpbnN0YW5jZXMgYXMgd2VsbCBhcyByZXVzZWRcclxuICAgICAgICAgICAgICAgIC8vIGluc3RhbmNlcyB3aGVuIG5hdmlnYXRpbmcgdG8gYSBuZXcgcm91dGVcclxuICAgICAgICAgICAgICAgIHRvLmluc3RhbmNlc1tuYW1lXSA9IGluc3RhbmNlO1xyXG4gICAgICAgICAgICAgICAgLy8gdGhlIGNvbXBvbmVudCBpbnN0YW5jZSBpcyByZXVzZWQgZm9yIGEgZGlmZmVyZW50IHJvdXRlIG9yIG5hbWUgc29cclxuICAgICAgICAgICAgICAgIC8vIHdlIGNvcHkgYW55IHNhdmVkIHVwZGF0ZSBvciBsZWF2ZSBndWFyZHMuIFdpdGggYXN5bmMgc2V0dXAsIHRoZVxyXG4gICAgICAgICAgICAgICAgLy8gbW91bnRpbmcgY29tcG9uZW50IHdpbGwgbW91bnQgYmVmb3JlIHRoZSBtYXRjaGVkUm91dGUgY2hhbmdlcyxcclxuICAgICAgICAgICAgICAgIC8vIG1ha2luZyBpbnN0YW5jZSA9PT0gb2xkSW5zdGFuY2UsIHNvIHdlIGNoZWNrIGlmIGd1YXJkcyBoYXZlIGJlZW5cclxuICAgICAgICAgICAgICAgIC8vIGFkZGVkIGJlZm9yZS4gVGhpcyB3b3JrcyBiZWNhdXNlIHdlIHJlbW92ZSBndWFyZHMgd2hlblxyXG4gICAgICAgICAgICAgICAgLy8gdW5tb3VudGluZy9kZWFjdGl2YXRpbmcgY29tcG9uZW50c1xyXG4gICAgICAgICAgICAgICAgaWYgKGZyb20gJiYgZnJvbSAhPT0gdG8gJiYgaW5zdGFuY2UgJiYgaW5zdGFuY2UgPT09IG9sZEluc3RhbmNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0by5sZWF2ZUd1YXJkcy5zaXplKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvLmxlYXZlR3VhcmRzID0gZnJvbS5sZWF2ZUd1YXJkcztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0by51cGRhdGVHdWFyZHMuc2l6ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0by51cGRhdGVHdWFyZHMgPSBmcm9tLnVwZGF0ZUd1YXJkcztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gdHJpZ2dlciBiZWZvcmVSb3V0ZUVudGVyIG5leHQgY2FsbGJhY2tzXHJcbiAgICAgICAgICAgIGlmIChpbnN0YW5jZSAmJlxyXG4gICAgICAgICAgICAgICAgdG8gJiZcclxuICAgICAgICAgICAgICAgIC8vIGlmIHRoZXJlIGlzIG5vIGluc3RhbmNlIGJ1dCB0byBhbmQgZnJvbSBhcmUgdGhlIHNhbWUgdGhpcyBtaWdodCBiZVxyXG4gICAgICAgICAgICAgICAgLy8gdGhlIGZpcnN0IHZpc2l0XHJcbiAgICAgICAgICAgICAgICAoIWZyb20gfHwgIWlzU2FtZVJvdXRlUmVjb3JkKHRvLCBmcm9tKSB8fCAhb2xkSW5zdGFuY2UpKSB7XHJcbiAgICAgICAgICAgICAgICAodG8uZW50ZXJDYWxsYmFja3NbbmFtZV0gfHwgW10pLmZvckVhY2goY2FsbGJhY2sgPT4gY2FsbGJhY2soaW5zdGFuY2UpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sIHsgZmx1c2g6ICdwb3N0JyB9KTtcclxuICAgICAgICByZXR1cm4gKCkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCByb3V0ZSA9IHJvdXRlVG9EaXNwbGF5LnZhbHVlO1xyXG4gICAgICAgICAgICBjb25zdCBtYXRjaGVkUm91dGUgPSBtYXRjaGVkUm91dGVSZWYudmFsdWU7XHJcbiAgICAgICAgICAgIGNvbnN0IFZpZXdDb21wb25lbnQgPSBtYXRjaGVkUm91dGUgJiYgbWF0Y2hlZFJvdXRlLmNvbXBvbmVudHNbcHJvcHMubmFtZV07XHJcbiAgICAgICAgICAgIC8vIHdlIG5lZWQgdGhlIHZhbHVlIGF0IHRoZSB0aW1lIHdlIHJlbmRlciBiZWNhdXNlIHdoZW4gd2UgdW5tb3VudCwgd2VcclxuICAgICAgICAgICAgLy8gbmF2aWdhdGVkIHRvIGEgZGlmZmVyZW50IGxvY2F0aW9uIHNvIHRoZSB2YWx1ZSBpcyBkaWZmZXJlbnRcclxuICAgICAgICAgICAgY29uc3QgY3VycmVudE5hbWUgPSBwcm9wcy5uYW1lO1xyXG4gICAgICAgICAgICBpZiAoIVZpZXdDb21wb25lbnQpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBub3JtYWxpemVTbG90KHNsb3RzLmRlZmF1bHQsIHsgQ29tcG9uZW50OiBWaWV3Q29tcG9uZW50LCByb3V0ZSB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBwcm9wcyBmcm9tIHJvdXRlIGNvbmZpZ3VyYXRpb25cclxuICAgICAgICAgICAgY29uc3Qgcm91dGVQcm9wc09wdGlvbiA9IG1hdGNoZWRSb3V0ZS5wcm9wc1twcm9wcy5uYW1lXTtcclxuICAgICAgICAgICAgY29uc3Qgcm91dGVQcm9wcyA9IHJvdXRlUHJvcHNPcHRpb25cclxuICAgICAgICAgICAgICAgID8gcm91dGVQcm9wc09wdGlvbiA9PT0gdHJ1ZVxyXG4gICAgICAgICAgICAgICAgICAgID8gcm91dGUucGFyYW1zXHJcbiAgICAgICAgICAgICAgICAgICAgOiB0eXBlb2Ygcm91dGVQcm9wc09wdGlvbiA9PT0gJ2Z1bmN0aW9uJ1xyXG4gICAgICAgICAgICAgICAgICAgICAgICA/IHJvdXRlUHJvcHNPcHRpb24ocm91dGUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDogcm91dGVQcm9wc09wdGlvblxyXG4gICAgICAgICAgICAgICAgOiBudWxsO1xyXG4gICAgICAgICAgICBjb25zdCBvblZub2RlVW5tb3VudGVkID0gdm5vZGUgPT4ge1xyXG4gICAgICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSBpbnN0YW5jZSByZWZlcmVuY2UgdG8gcHJldmVudCBsZWFrXHJcbiAgICAgICAgICAgICAgICBpZiAodm5vZGUuY29tcG9uZW50LmlzVW5tb3VudGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbWF0Y2hlZFJvdXRlLmluc3RhbmNlc1tjdXJyZW50TmFtZV0gPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBjb25zdCBjb21wb25lbnQgPSBoKFZpZXdDb21wb25lbnQsIGFzc2lnbih7fSwgcm91dGVQcm9wcywgYXR0cnMsIHtcclxuICAgICAgICAgICAgICAgIG9uVm5vZGVVbm1vdW50ZWQsXHJcbiAgICAgICAgICAgICAgICByZWY6IHZpZXdSZWYsXHJcbiAgICAgICAgICAgIH0pKTtcclxuICAgICAgICAgICAgaWYgKCgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgfHwgX19WVUVfUFJPRF9ERVZUT09MU19fKSAmJlxyXG4gICAgICAgICAgICAgICAgaXNCcm93c2VyICYmXHJcbiAgICAgICAgICAgICAgICBjb21wb25lbnQucmVmKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBUT0RPOiBjYW4gZGlzcGxheSBpZiBpdCdzIGFuIGFsaWFzLCBpdHMgcHJvcHNcclxuICAgICAgICAgICAgICAgIGNvbnN0IGluZm8gPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZGVwdGgsXHJcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogbWF0Y2hlZFJvdXRlLm5hbWUsXHJcbiAgICAgICAgICAgICAgICAgICAgcGF0aDogbWF0Y2hlZFJvdXRlLnBhdGgsXHJcbiAgICAgICAgICAgICAgICAgICAgbWV0YTogbWF0Y2hlZFJvdXRlLm1ldGEsXHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgY29uc3QgaW50ZXJuYWxJbnN0YW5jZXMgPSBBcnJheS5pc0FycmF5KGNvbXBvbmVudC5yZWYpXHJcbiAgICAgICAgICAgICAgICAgICAgPyBjb21wb25lbnQucmVmLm1hcChyID0+IHIuaSlcclxuICAgICAgICAgICAgICAgICAgICA6IFtjb21wb25lbnQucmVmLmldO1xyXG4gICAgICAgICAgICAgICAgaW50ZXJuYWxJbnN0YW5jZXMuZm9yRWFjaChpbnN0YW5jZSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxyXG4gICAgICAgICAgICAgICAgICAgIGluc3RhbmNlLl9fdnJ2X2RldnRvb2xzID0gaW5mbztcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiAoXHJcbiAgICAgICAgICAgIC8vIHBhc3MgdGhlIHZub2RlIHRvIHRoZSBzbG90IGFzIGEgcHJvcC5cclxuICAgICAgICAgICAgLy8gaCBhbmQgPGNvbXBvbmVudCA6aXM9XCIuLi5cIj4gYm90aCBhY2NlcHQgdm5vZGVzXHJcbiAgICAgICAgICAgIG5vcm1hbGl6ZVNsb3Qoc2xvdHMuZGVmYXVsdCwgeyBDb21wb25lbnQ6IGNvbXBvbmVudCwgcm91dGUgfSkgfHxcclxuICAgICAgICAgICAgICAgIGNvbXBvbmVudCk7XHJcbiAgICAgICAgfTtcclxuICAgIH0sXHJcbn0pO1xyXG5mdW5jdGlvbiBub3JtYWxpemVTbG90KHNsb3QsIGRhdGEpIHtcclxuICAgIGlmICghc2xvdClcclxuICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgIGNvbnN0IHNsb3RDb250ZW50ID0gc2xvdChkYXRhKTtcclxuICAgIHJldHVybiBzbG90Q29udGVudC5sZW5ndGggPT09IDEgPyBzbG90Q29udGVudFswXSA6IHNsb3RDb250ZW50O1xyXG59XHJcbi8vIGV4cG9ydCB0aGUgcHVibGljIHR5cGUgZm9yIGgvdHN4IGluZmVyZW5jZVxyXG4vLyBhbHNvIHRvIGF2b2lkIGlubGluZSBpbXBvcnQoKSBpbiBnZW5lcmF0ZWQgZC50cyBmaWxlc1xyXG4vKipcclxuICogQ29tcG9uZW50IHRvIGRpc3BsYXkgdGhlIGN1cnJlbnQgcm91dGUgdGhlIHVzZXIgaXMgYXQuXHJcbiAqL1xyXG5jb25zdCBSb3V0ZXJWaWV3ID0gUm91dGVyVmlld0ltcGw7XHJcbi8vIHdhcm4gYWdhaW5zdCBkZXByZWNhdGVkIHVzYWdlIHdpdGggPHRyYW5zaXRpb24+ICYgPGtlZXAtYWxpdmU+XHJcbi8vIGR1ZSB0byBmdW5jdGlvbmFsIGNvbXBvbmVudCBiZWluZyBubyBsb25nZXIgZWFnZXIgaW4gVnVlIDNcclxuZnVuY3Rpb24gd2FybkRlcHJlY2F0ZWRVc2FnZSgpIHtcclxuICAgIGNvbnN0IGluc3RhbmNlID0gZ2V0Q3VycmVudEluc3RhbmNlKCk7XHJcbiAgICBjb25zdCBwYXJlbnROYW1lID0gaW5zdGFuY2UucGFyZW50ICYmIGluc3RhbmNlLnBhcmVudC50eXBlLm5hbWU7XHJcbiAgICBpZiAocGFyZW50TmFtZSAmJlxyXG4gICAgICAgIChwYXJlbnROYW1lID09PSAnS2VlcEFsaXZlJyB8fCBwYXJlbnROYW1lLmluY2x1ZGVzKCdUcmFuc2l0aW9uJykpKSB7XHJcbiAgICAgICAgY29uc3QgY29tcCA9IHBhcmVudE5hbWUgPT09ICdLZWVwQWxpdmUnID8gJ2tlZXAtYWxpdmUnIDogJ3RyYW5zaXRpb24nO1xyXG4gICAgICAgIHdhcm4oYDxyb3V0ZXItdmlldz4gY2FuIG5vIGxvbmdlciBiZSB1c2VkIGRpcmVjdGx5IGluc2lkZSA8dHJhbnNpdGlvbj4gb3IgPGtlZXAtYWxpdmU+LlxcbmAgK1xyXG4gICAgICAgICAgICBgVXNlIHNsb3QgcHJvcHMgaW5zdGVhZDpcXG5cXG5gICtcclxuICAgICAgICAgICAgYDxyb3V0ZXItdmlldyB2LXNsb3Q9XCJ7IENvbXBvbmVudCB9XCI+XFxuYCArXHJcbiAgICAgICAgICAgIGAgIDwke2NvbXB9PlxcbmAgK1xyXG4gICAgICAgICAgICBgICAgIDxjb21wb25lbnQgOmlzPVwiQ29tcG9uZW50XCIgLz5cXG5gICtcclxuICAgICAgICAgICAgYCAgPC8ke2NvbXB9PlxcbmAgK1xyXG4gICAgICAgICAgICBgPC9yb3V0ZXItdmlldz5gKTtcclxuICAgIH1cclxufVxuXG5mdW5jdGlvbiBmb3JtYXRSb3V0ZUxvY2F0aW9uKHJvdXRlTG9jYXRpb24sIHRvb2x0aXApIHtcclxuICAgIGNvbnN0IGNvcHkgPSBhc3NpZ24oe30sIHJvdXRlTG9jYXRpb24sIHtcclxuICAgICAgICAvLyByZW1vdmUgdmFyaWFibGVzIHRoYXQgY2FuIGNvbnRhaW4gdnVlIGluc3RhbmNlc1xyXG4gICAgICAgIG1hdGNoZWQ6IHJvdXRlTG9jYXRpb24ubWF0Y2hlZC5tYXAobWF0Y2hlZCA9PiBvbWl0KG1hdGNoZWQsIFsnaW5zdGFuY2VzJywgJ2NoaWxkcmVuJywgJ2FsaWFzT2YnXSkpLFxyXG4gICAgfSk7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIF9jdXN0b206IHtcclxuICAgICAgICAgICAgdHlwZTogbnVsbCxcclxuICAgICAgICAgICAgcmVhZE9ubHk6IHRydWUsXHJcbiAgICAgICAgICAgIGRpc3BsYXk6IHJvdXRlTG9jYXRpb24uZnVsbFBhdGgsXHJcbiAgICAgICAgICAgIHRvb2x0aXAsXHJcbiAgICAgICAgICAgIHZhbHVlOiBjb3B5LFxyXG4gICAgICAgIH0sXHJcbiAgICB9O1xyXG59XHJcbmZ1bmN0aW9uIGZvcm1hdERpc3BsYXkoZGlzcGxheSkge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICBfY3VzdG9tOiB7XHJcbiAgICAgICAgICAgIGRpc3BsYXksXHJcbiAgICAgICAgfSxcclxuICAgIH07XHJcbn1cclxuLy8gdG8gc3VwcG9ydCBtdWx0aXBsZSByb3V0ZXIgaW5zdGFuY2VzXHJcbmxldCByb3V0ZXJJZCA9IDA7XHJcbmZ1bmN0aW9uIGFkZERldnRvb2xzKGFwcCwgcm91dGVyLCBtYXRjaGVyKSB7XHJcbiAgICAvLyBUYWtlIG92ZXIgcm91dGVyLmJlZm9yZUVhY2ggYW5kIGFmdGVyRWFjaFxyXG4gICAgLy8gbWFrZSBzdXJlIHdlIGFyZSBub3QgcmVnaXN0ZXJpbmcgdGhlIGRldnRvb2wgdHdpY2VcclxuICAgIGlmIChyb3V0ZXIuX19oYXNEZXZ0b29scylcclxuICAgICAgICByZXR1cm47XHJcbiAgICByb3V0ZXIuX19oYXNEZXZ0b29scyA9IHRydWU7XHJcbiAgICAvLyBpbmNyZW1lbnQgdG8gc3VwcG9ydCBtdWx0aXBsZSByb3V0ZXIgaW5zdGFuY2VzXHJcbiAgICBjb25zdCBpZCA9IHJvdXRlcklkKys7XHJcbiAgICBzZXR1cERldnRvb2xzUGx1Z2luKHtcclxuICAgICAgICBpZDogJ29yZy52dWVqcy5yb3V0ZXInICsgKGlkID8gJy4nICsgaWQgOiAnJyksXHJcbiAgICAgICAgbGFiZWw6ICdWdWUgUm91dGVyJyxcclxuICAgICAgICBwYWNrYWdlTmFtZTogJ3Z1ZS1yb3V0ZXInLFxyXG4gICAgICAgIGhvbWVwYWdlOiAnaHR0cHM6Ly9uZXh0LnJvdXRlci52dWVqcy5vcmcvJyxcclxuICAgICAgICBsb2dvOiAnaHR0cHM6Ly92dWVqcy5vcmcvaW1hZ2VzL2ljb25zL2Zhdmljb24tOTZ4OTYucG5nJyxcclxuICAgICAgICBjb21wb25lbnRTdGF0ZVR5cGVzOiBbJ1JvdXRpbmcnXSxcclxuICAgICAgICBhcHAsXHJcbiAgICB9LCBhcGkgPT4ge1xyXG4gICAgICAgIC8vIGRpc3BsYXkgc3RhdGUgYWRkZWQgYnkgdGhlIHJvdXRlclxyXG4gICAgICAgIGFwaS5vbi5pbnNwZWN0Q29tcG9uZW50KChwYXlsb2FkLCBjdHgpID0+IHtcclxuICAgICAgICAgICAgaWYgKHBheWxvYWQuaW5zdGFuY2VEYXRhKSB7XHJcbiAgICAgICAgICAgICAgICBwYXlsb2FkLmluc3RhbmNlRGF0YS5zdGF0ZS5wdXNoKHtcclxuICAgICAgICAgICAgICAgICAgICB0eXBlOiAnUm91dGluZycsXHJcbiAgICAgICAgICAgICAgICAgICAga2V5OiAnJHJvdXRlJyxcclxuICAgICAgICAgICAgICAgICAgICBlZGl0YWJsZTogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGZvcm1hdFJvdXRlTG9jYXRpb24ocm91dGVyLmN1cnJlbnRSb3V0ZS52YWx1ZSwgJ0N1cnJlbnQgUm91dGUnKSxcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgLy8gbWFyayByb3V0ZXItbGluayBhcyBhY3RpdmUgYW5kIGRpc3BsYXkgdGFncyBvbiByb3V0ZXIgdmlld3NcclxuICAgICAgICBhcGkub24udmlzaXRDb21wb25lbnRUcmVlKCh7IHRyZWVOb2RlOiBub2RlLCBjb21wb25lbnRJbnN0YW5jZSB9KSA9PiB7XHJcbiAgICAgICAgICAgIGlmIChjb21wb25lbnRJbnN0YW5jZS5fX3Zydl9kZXZ0b29scykge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgaW5mbyA9IGNvbXBvbmVudEluc3RhbmNlLl9fdnJ2X2RldnRvb2xzO1xyXG4gICAgICAgICAgICAgICAgbm9kZS50YWdzLnB1c2goe1xyXG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiAoaW5mby5uYW1lID8gYCR7aW5mby5uYW1lLnRvU3RyaW5nKCl9OiBgIDogJycpICsgaW5mby5wYXRoLFxyXG4gICAgICAgICAgICAgICAgICAgIHRleHRDb2xvcjogMCxcclxuICAgICAgICAgICAgICAgICAgICB0b29sdGlwOiAnVGhpcyBjb21wb25lbnQgaXMgcmVuZGVyZWQgYnkgJmx0O3JvdXRlci12aWV3Jmd0OycsXHJcbiAgICAgICAgICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiBQSU5LXzUwMCxcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIGlmIG11bHRpcGxlIHVzZUxpbmsgYXJlIHVzZWRcclxuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoY29tcG9uZW50SW5zdGFuY2UuX192cmxfZGV2dG9vbHMpKSB7XHJcbiAgICAgICAgICAgICAgICBjb21wb25lbnRJbnN0YW5jZS5fX2RldnRvb2xzQXBpID0gYXBpO1xyXG4gICAgICAgICAgICAgICAgY29tcG9uZW50SW5zdGFuY2UuX192cmxfZGV2dG9vbHMuZm9yRWFjaChkZXZ0b29sc0RhdGEgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBiYWNrZ3JvdW5kQ29sb3IgPSBPUkFOR0VfNDAwO1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCB0b29sdGlwID0gJyc7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRldnRvb2xzRGF0YS5pc0V4YWN0QWN0aXZlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJhY2tncm91bmRDb2xvciA9IExJTUVfNTAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0b29sdGlwID0gJ1RoaXMgaXMgZXhhY3RseSBhY3RpdmUnO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChkZXZ0b29sc0RhdGEuaXNBY3RpdmUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yID0gQkxVRV82MDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvb2x0aXAgPSAnVGhpcyBsaW5rIGlzIGFjdGl2ZSc7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIG5vZGUudGFncy5wdXNoKHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw6IGRldnRvb2xzRGF0YS5yb3V0ZS5wYXRoLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0Q29sb3I6IDAsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvb2x0aXAsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcixcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgd2F0Y2gocm91dGVyLmN1cnJlbnRSb3V0ZSwgKCkgPT4ge1xyXG4gICAgICAgICAgICAvLyByZWZyZXNoIGFjdGl2ZSBzdGF0ZVxyXG4gICAgICAgICAgICByZWZyZXNoUm91dGVzVmlldygpO1xyXG4gICAgICAgICAgICBhcGkubm90aWZ5Q29tcG9uZW50VXBkYXRlKCk7XHJcbiAgICAgICAgICAgIGFwaS5zZW5kSW5zcGVjdG9yVHJlZShyb3V0ZXJJbnNwZWN0b3JJZCk7XHJcbiAgICAgICAgICAgIGFwaS5zZW5kSW5zcGVjdG9yU3RhdGUocm91dGVySW5zcGVjdG9ySWQpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIGNvbnN0IG5hdmlnYXRpb25zTGF5ZXJJZCA9ICdyb3V0ZXI6bmF2aWdhdGlvbnM6JyArIGlkO1xyXG4gICAgICAgIGFwaS5hZGRUaW1lbGluZUxheWVyKHtcclxuICAgICAgICAgICAgaWQ6IG5hdmlnYXRpb25zTGF5ZXJJZCxcclxuICAgICAgICAgICAgbGFiZWw6IGBSb3V0ZXIke2lkID8gJyAnICsgaWQgOiAnJ30gTmF2aWdhdGlvbnNgLFxyXG4gICAgICAgICAgICBjb2xvcjogMHg0MGE4YzQsXHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgLy8gY29uc3QgZXJyb3JzTGF5ZXJJZCA9ICdyb3V0ZXI6ZXJyb3JzJ1xyXG4gICAgICAgIC8vIGFwaS5hZGRUaW1lbGluZUxheWVyKHtcclxuICAgICAgICAvLyAgIGlkOiBlcnJvcnNMYXllcklkLFxyXG4gICAgICAgIC8vICAgbGFiZWw6ICdSb3V0ZXIgRXJyb3JzJyxcclxuICAgICAgICAvLyAgIGNvbG9yOiAweGVhNTQ1NSxcclxuICAgICAgICAvLyB9KVxyXG4gICAgICAgIHJvdXRlci5vbkVycm9yKChlcnJvciwgdG8pID0+IHtcclxuICAgICAgICAgICAgYXBpLmFkZFRpbWVsaW5lRXZlbnQoe1xyXG4gICAgICAgICAgICAgICAgbGF5ZXJJZDogbmF2aWdhdGlvbnNMYXllcklkLFxyXG4gICAgICAgICAgICAgICAgZXZlbnQ6IHtcclxuICAgICAgICAgICAgICAgICAgICB0aXRsZTogJ0Vycm9yIGR1cmluZyBOYXZpZ2F0aW9uJyxcclxuICAgICAgICAgICAgICAgICAgICBzdWJ0aXRsZTogdG8uZnVsbFBhdGgsXHJcbiAgICAgICAgICAgICAgICAgICAgbG9nVHlwZTogJ2Vycm9yJyxcclxuICAgICAgICAgICAgICAgICAgICB0aW1lOiBEYXRlLm5vdygpLFxyXG4gICAgICAgICAgICAgICAgICAgIGRhdGE6IHsgZXJyb3IgfSxcclxuICAgICAgICAgICAgICAgICAgICBncm91cElkOiB0by5tZXRhLl9fbmF2aWdhdGlvbklkLFxyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgLy8gYXR0YWNoZWQgdG8gYG1ldGFgIGFuZCB1c2VkIHRvIGdyb3VwIGV2ZW50c1xyXG4gICAgICAgIGxldCBuYXZpZ2F0aW9uSWQgPSAwO1xyXG4gICAgICAgIHJvdXRlci5iZWZvcmVFYWNoKCh0bywgZnJvbSkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBkYXRhID0ge1xyXG4gICAgICAgICAgICAgICAgZ3VhcmQ6IGZvcm1hdERpc3BsYXkoJ2JlZm9yZUVhY2gnKSxcclxuICAgICAgICAgICAgICAgIGZyb206IGZvcm1hdFJvdXRlTG9jYXRpb24oZnJvbSwgJ0N1cnJlbnQgTG9jYXRpb24gZHVyaW5nIHRoaXMgbmF2aWdhdGlvbicpLFxyXG4gICAgICAgICAgICAgICAgdG86IGZvcm1hdFJvdXRlTG9jYXRpb24odG8sICdUYXJnZXQgbG9jYXRpb24nKSxcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgLy8gVXNlZCB0byBncm91cCBuYXZpZ2F0aW9ucyB0b2dldGhlciwgaGlkZSBmcm9tIGRldnRvb2xzXHJcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0by5tZXRhLCAnX19uYXZpZ2F0aW9uSWQnLCB7XHJcbiAgICAgICAgICAgICAgICB2YWx1ZTogbmF2aWdhdGlvbklkKyssXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICBhcGkuYWRkVGltZWxpbmVFdmVudCh7XHJcbiAgICAgICAgICAgICAgICBsYXllcklkOiBuYXZpZ2F0aW9uc0xheWVySWQsXHJcbiAgICAgICAgICAgICAgICBldmVudDoge1xyXG4gICAgICAgICAgICAgICAgICAgIHRpbWU6IERhdGUubm93KCksXHJcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU6ICdTdGFydCBvZiBuYXZpZ2F0aW9uJyxcclxuICAgICAgICAgICAgICAgICAgICBzdWJ0aXRsZTogdG8uZnVsbFBhdGgsXHJcbiAgICAgICAgICAgICAgICAgICAgZGF0YSxcclxuICAgICAgICAgICAgICAgICAgICBncm91cElkOiB0by5tZXRhLl9fbmF2aWdhdGlvbklkLFxyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcm91dGVyLmFmdGVyRWFjaCgodG8sIGZyb20sIGZhaWx1cmUpID0+IHtcclxuICAgICAgICAgICAgY29uc3QgZGF0YSA9IHtcclxuICAgICAgICAgICAgICAgIGd1YXJkOiBmb3JtYXREaXNwbGF5KCdhZnRlckVhY2gnKSxcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgaWYgKGZhaWx1cmUpIHtcclxuICAgICAgICAgICAgICAgIGRhdGEuZmFpbHVyZSA9IHtcclxuICAgICAgICAgICAgICAgICAgICBfY3VzdG9tOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IEVycm9yLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZWFkT25seTogdHJ1ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGxheTogZmFpbHVyZSA/IGZhaWx1cmUubWVzc2FnZSA6ICcnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0b29sdGlwOiAnTmF2aWdhdGlvbiBGYWlsdXJlJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGZhaWx1cmUsXHJcbiAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICBkYXRhLnN0YXR1cyA9IGZvcm1hdERpc3BsYXkoJ+KdjCcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgZGF0YS5zdGF0dXMgPSBmb3JtYXREaXNwbGF5KCfinIUnKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyB3ZSBzZXQgaGVyZSB0byBoYXZlIHRoZSByaWdodCBvcmRlclxyXG4gICAgICAgICAgICBkYXRhLmZyb20gPSBmb3JtYXRSb3V0ZUxvY2F0aW9uKGZyb20sICdDdXJyZW50IExvY2F0aW9uIGR1cmluZyB0aGlzIG5hdmlnYXRpb24nKTtcclxuICAgICAgICAgICAgZGF0YS50byA9IGZvcm1hdFJvdXRlTG9jYXRpb24odG8sICdUYXJnZXQgbG9jYXRpb24nKTtcclxuICAgICAgICAgICAgYXBpLmFkZFRpbWVsaW5lRXZlbnQoe1xyXG4gICAgICAgICAgICAgICAgbGF5ZXJJZDogbmF2aWdhdGlvbnNMYXllcklkLFxyXG4gICAgICAgICAgICAgICAgZXZlbnQ6IHtcclxuICAgICAgICAgICAgICAgICAgICB0aXRsZTogJ0VuZCBvZiBuYXZpZ2F0aW9uJyxcclxuICAgICAgICAgICAgICAgICAgICBzdWJ0aXRsZTogdG8uZnVsbFBhdGgsXHJcbiAgICAgICAgICAgICAgICAgICAgdGltZTogRGF0ZS5ub3coKSxcclxuICAgICAgICAgICAgICAgICAgICBkYXRhLFxyXG4gICAgICAgICAgICAgICAgICAgIGxvZ1R5cGU6IGZhaWx1cmUgPyAnd2FybmluZycgOiAnZGVmYXVsdCcsXHJcbiAgICAgICAgICAgICAgICAgICAgZ3JvdXBJZDogdG8ubWV0YS5fX25hdmlnYXRpb25JZCxcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEluc3BlY3RvciBvZiBFeGlzdGluZyByb3V0ZXNcclxuICAgICAgICAgKi9cclxuICAgICAgICBjb25zdCByb3V0ZXJJbnNwZWN0b3JJZCA9ICdyb3V0ZXItaW5zcGVjdG9yOicgKyBpZDtcclxuICAgICAgICBhcGkuYWRkSW5zcGVjdG9yKHtcclxuICAgICAgICAgICAgaWQ6IHJvdXRlckluc3BlY3RvcklkLFxyXG4gICAgICAgICAgICBsYWJlbDogJ1JvdXRlcycgKyAoaWQgPyAnICcgKyBpZCA6ICcnKSxcclxuICAgICAgICAgICAgaWNvbjogJ2Jvb2snLFxyXG4gICAgICAgICAgICB0cmVlRmlsdGVyUGxhY2Vob2xkZXI6ICdTZWFyY2ggcm91dGVzJyxcclxuICAgICAgICB9KTtcclxuICAgICAgICBmdW5jdGlvbiByZWZyZXNoUm91dGVzVmlldygpIHtcclxuICAgICAgICAgICAgLy8gdGhlIHJvdXRlcyB2aWV3IGlzbid0IGFjdGl2ZVxyXG4gICAgICAgICAgICBpZiAoIWFjdGl2ZVJvdXRlc1BheWxvYWQpXHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIGNvbnN0IHBheWxvYWQgPSBhY3RpdmVSb3V0ZXNQYXlsb2FkO1xyXG4gICAgICAgICAgICAvLyBjaGlsZHJlbiByb3V0ZXMgd2lsbCBhcHBlYXIgYXMgbmVzdGVkXHJcbiAgICAgICAgICAgIGxldCByb3V0ZXMgPSBtYXRjaGVyLmdldFJvdXRlcygpLmZpbHRlcihyb3V0ZSA9PiAhcm91dGUucGFyZW50KTtcclxuICAgICAgICAgICAgLy8gcmVzZXQgbWF0Y2ggc3RhdGUgdG8gZmFsc2VcclxuICAgICAgICAgICAgcm91dGVzLmZvckVhY2gocmVzZXRNYXRjaFN0YXRlT25Sb3V0ZVJlY29yZCk7XHJcbiAgICAgICAgICAgIC8vIGFwcGx5IGEgbWF0Y2ggc3RhdGUgaWYgdGhlcmUgaXMgYSBwYXlsb2FkXHJcbiAgICAgICAgICAgIGlmIChwYXlsb2FkLmZpbHRlcikge1xyXG4gICAgICAgICAgICAgICAgcm91dGVzID0gcm91dGVzLmZpbHRlcihyb3V0ZSA9PiBcclxuICAgICAgICAgICAgICAgIC8vIHNhdmUgbWF0Y2hlcyBzdGF0ZSBiYXNlZCBvbiB0aGUgcGF5bG9hZFxyXG4gICAgICAgICAgICAgICAgaXNSb3V0ZU1hdGNoaW5nKHJvdXRlLCBwYXlsb2FkLmZpbHRlci50b0xvd2VyQ2FzZSgpKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gbWFyayBhY3RpdmUgcm91dGVzXHJcbiAgICAgICAgICAgIHJvdXRlcy5mb3JFYWNoKHJvdXRlID0+IG1hcmtSb3V0ZVJlY29yZEFjdGl2ZShyb3V0ZSwgcm91dGVyLmN1cnJlbnRSb3V0ZS52YWx1ZSkpO1xyXG4gICAgICAgICAgICBwYXlsb2FkLnJvb3ROb2RlcyA9IHJvdXRlcy5tYXAoZm9ybWF0Um91dGVSZWNvcmRGb3JJbnNwZWN0b3IpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBsZXQgYWN0aXZlUm91dGVzUGF5bG9hZDtcclxuICAgICAgICBhcGkub24uZ2V0SW5zcGVjdG9yVHJlZShwYXlsb2FkID0+IHtcclxuICAgICAgICAgICAgYWN0aXZlUm91dGVzUGF5bG9hZCA9IHBheWxvYWQ7XHJcbiAgICAgICAgICAgIGlmIChwYXlsb2FkLmFwcCA9PT0gYXBwICYmIHBheWxvYWQuaW5zcGVjdG9ySWQgPT09IHJvdXRlckluc3BlY3RvcklkKSB7XHJcbiAgICAgICAgICAgICAgICByZWZyZXNoUm91dGVzVmlldygpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRGlzcGxheSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgY3VycmVudGx5IHNlbGVjdGVkIHJvdXRlIHJlY29yZFxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGFwaS5vbi5nZXRJbnNwZWN0b3JTdGF0ZShwYXlsb2FkID0+IHtcclxuICAgICAgICAgICAgaWYgKHBheWxvYWQuYXBwID09PSBhcHAgJiYgcGF5bG9hZC5pbnNwZWN0b3JJZCA9PT0gcm91dGVySW5zcGVjdG9ySWQpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHJvdXRlcyA9IG1hdGNoZXIuZ2V0Um91dGVzKCk7XHJcbiAgICAgICAgICAgICAgICBjb25zdCByb3V0ZSA9IHJvdXRlcy5maW5kKHJvdXRlID0+IHJvdXRlLnJlY29yZC5fX3ZkX2lkID09PSBwYXlsb2FkLm5vZGVJZCk7XHJcbiAgICAgICAgICAgICAgICBpZiAocm91dGUpIHtcclxuICAgICAgICAgICAgICAgICAgICBwYXlsb2FkLnN0YXRlID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zOiBmb3JtYXRSb3V0ZVJlY29yZE1hdGNoZXJGb3JTdGF0ZUluc3BlY3Rvcihyb3V0ZSksXHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIGFwaS5zZW5kSW5zcGVjdG9yVHJlZShyb3V0ZXJJbnNwZWN0b3JJZCk7XHJcbiAgICAgICAgYXBpLnNlbmRJbnNwZWN0b3JTdGF0ZShyb3V0ZXJJbnNwZWN0b3JJZCk7XHJcbiAgICB9KTtcclxufVxyXG5mdW5jdGlvbiBtb2RpZmllckZvcktleShrZXkpIHtcclxuICAgIGlmIChrZXkub3B0aW9uYWwpIHtcclxuICAgICAgICByZXR1cm4ga2V5LnJlcGVhdGFibGUgPyAnKicgOiAnPyc7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICByZXR1cm4ga2V5LnJlcGVhdGFibGUgPyAnKycgOiAnJztcclxuICAgIH1cclxufVxyXG5mdW5jdGlvbiBmb3JtYXRSb3V0ZVJlY29yZE1hdGNoZXJGb3JTdGF0ZUluc3BlY3Rvcihyb3V0ZSkge1xyXG4gICAgY29uc3QgeyByZWNvcmQgfSA9IHJvdXRlO1xyXG4gICAgY29uc3QgZmllbGRzID0gW1xyXG4gICAgICAgIHsgZWRpdGFibGU6IGZhbHNlLCBrZXk6ICdwYXRoJywgdmFsdWU6IHJlY29yZC5wYXRoIH0sXHJcbiAgICBdO1xyXG4gICAgaWYgKHJlY29yZC5uYW1lICE9IG51bGwpIHtcclxuICAgICAgICBmaWVsZHMucHVzaCh7XHJcbiAgICAgICAgICAgIGVkaXRhYmxlOiBmYWxzZSxcclxuICAgICAgICAgICAga2V5OiAnbmFtZScsXHJcbiAgICAgICAgICAgIHZhbHVlOiByZWNvcmQubmFtZSxcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIGZpZWxkcy5wdXNoKHsgZWRpdGFibGU6IGZhbHNlLCBrZXk6ICdyZWdleHAnLCB2YWx1ZTogcm91dGUucmUgfSk7XHJcbiAgICBpZiAocm91dGUua2V5cy5sZW5ndGgpIHtcclxuICAgICAgICBmaWVsZHMucHVzaCh7XHJcbiAgICAgICAgICAgIGVkaXRhYmxlOiBmYWxzZSxcclxuICAgICAgICAgICAga2V5OiAna2V5cycsXHJcbiAgICAgICAgICAgIHZhbHVlOiB7XHJcbiAgICAgICAgICAgICAgICBfY3VzdG9tOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogbnVsbCxcclxuICAgICAgICAgICAgICAgICAgICByZWFkT25seTogdHJ1ZSxcclxuICAgICAgICAgICAgICAgICAgICBkaXNwbGF5OiByb3V0ZS5rZXlzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC5tYXAoa2V5ID0+IGAke2tleS5uYW1lfSR7bW9kaWZpZXJGb3JLZXkoa2V5KX1gKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAuam9pbignICcpLFxyXG4gICAgICAgICAgICAgICAgICAgIHRvb2x0aXA6ICdQYXJhbSBrZXlzJyxcclxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogcm91dGUua2V5cyxcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBpZiAocmVjb3JkLnJlZGlyZWN0ICE9IG51bGwpIHtcclxuICAgICAgICBmaWVsZHMucHVzaCh7XHJcbiAgICAgICAgICAgIGVkaXRhYmxlOiBmYWxzZSxcclxuICAgICAgICAgICAga2V5OiAncmVkaXJlY3QnLFxyXG4gICAgICAgICAgICB2YWx1ZTogcmVjb3JkLnJlZGlyZWN0LFxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgaWYgKHJvdXRlLmFsaWFzLmxlbmd0aCkge1xyXG4gICAgICAgIGZpZWxkcy5wdXNoKHtcclxuICAgICAgICAgICAgZWRpdGFibGU6IGZhbHNlLFxyXG4gICAgICAgICAgICBrZXk6ICdhbGlhc2VzJyxcclxuICAgICAgICAgICAgdmFsdWU6IHJvdXRlLmFsaWFzLm1hcChhbGlhcyA9PiBhbGlhcy5yZWNvcmQucGF0aCksXHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBmaWVsZHMucHVzaCh7XHJcbiAgICAgICAga2V5OiAnc2NvcmUnLFxyXG4gICAgICAgIGVkaXRhYmxlOiBmYWxzZSxcclxuICAgICAgICB2YWx1ZToge1xyXG4gICAgICAgICAgICBfY3VzdG9tOiB7XHJcbiAgICAgICAgICAgICAgICB0eXBlOiBudWxsLFxyXG4gICAgICAgICAgICAgICAgcmVhZE9ubHk6IHRydWUsXHJcbiAgICAgICAgICAgICAgICBkaXNwbGF5OiByb3V0ZS5zY29yZS5tYXAoc2NvcmUgPT4gc2NvcmUuam9pbignLCAnKSkuam9pbignIHwgJyksXHJcbiAgICAgICAgICAgICAgICB0b29sdGlwOiAnU2NvcmUgdXNlZCB0byBzb3J0IHJvdXRlcycsXHJcbiAgICAgICAgICAgICAgICB2YWx1ZTogcm91dGUuc2NvcmUsXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgfSxcclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIGZpZWxkcztcclxufVxyXG4vKipcclxuICogRXh0cmFjdGVkIGZyb20gdGFpbHdpbmQgcGFsZXR0ZVxyXG4gKi9cclxuY29uc3QgUElOS181MDAgPSAweGVjNDg5OTtcclxuY29uc3QgQkxVRV82MDAgPSAweDI1NjNlYjtcclxuY29uc3QgTElNRV81MDAgPSAweDg0Y2MxNjtcclxuY29uc3QgQ1lBTl80MDAgPSAweDIyZDNlZTtcclxuY29uc3QgT1JBTkdFXzQwMCA9IDB4ZmI5MjNjO1xyXG4vLyBjb25zdCBHUkFZXzEwMCA9IDB4ZjRmNGY1XHJcbmNvbnN0IERBUksgPSAweDY2NjY2NjtcclxuZnVuY3Rpb24gZm9ybWF0Um91dGVSZWNvcmRGb3JJbnNwZWN0b3Iocm91dGUpIHtcclxuICAgIGNvbnN0IHRhZ3MgPSBbXTtcclxuICAgIGNvbnN0IHsgcmVjb3JkIH0gPSByb3V0ZTtcclxuICAgIGlmIChyZWNvcmQubmFtZSAhPSBudWxsKSB7XHJcbiAgICAgICAgdGFncy5wdXNoKHtcclxuICAgICAgICAgICAgbGFiZWw6IFN0cmluZyhyZWNvcmQubmFtZSksXHJcbiAgICAgICAgICAgIHRleHRDb2xvcjogMCxcclxuICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiBDWUFOXzQwMCxcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIGlmIChyZWNvcmQuYWxpYXNPZikge1xyXG4gICAgICAgIHRhZ3MucHVzaCh7XHJcbiAgICAgICAgICAgIGxhYmVsOiAnYWxpYXMnLFxyXG4gICAgICAgICAgICB0ZXh0Q29sb3I6IDAsXHJcbiAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogT1JBTkdFXzQwMCxcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIGlmIChyb3V0ZS5fX3ZkX21hdGNoKSB7XHJcbiAgICAgICAgdGFncy5wdXNoKHtcclxuICAgICAgICAgICAgbGFiZWw6ICdtYXRjaGVzJyxcclxuICAgICAgICAgICAgdGV4dENvbG9yOiAwLFxyXG4gICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IFBJTktfNTAwLFxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgaWYgKHJvdXRlLl9fdmRfZXhhY3RBY3RpdmUpIHtcclxuICAgICAgICB0YWdzLnB1c2goe1xyXG4gICAgICAgICAgICBsYWJlbDogJ2V4YWN0JyxcclxuICAgICAgICAgICAgdGV4dENvbG9yOiAwLFxyXG4gICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IExJTUVfNTAwLFxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgaWYgKHJvdXRlLl9fdmRfYWN0aXZlKSB7XHJcbiAgICAgICAgdGFncy5wdXNoKHtcclxuICAgICAgICAgICAgbGFiZWw6ICdhY3RpdmUnLFxyXG4gICAgICAgICAgICB0ZXh0Q29sb3I6IDAsXHJcbiAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogQkxVRV82MDAsXHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBpZiAocmVjb3JkLnJlZGlyZWN0KSB7XHJcbiAgICAgICAgdGFncy5wdXNoKHtcclxuICAgICAgICAgICAgbGFiZWw6ICdyZWRpcmVjdDogJyArXHJcbiAgICAgICAgICAgICAgICAodHlwZW9mIHJlY29yZC5yZWRpcmVjdCA9PT0gJ3N0cmluZycgPyByZWNvcmQucmVkaXJlY3QgOiAnT2JqZWN0JyksXHJcbiAgICAgICAgICAgIHRleHRDb2xvcjogMHhmZmZmZmYsXHJcbiAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogREFSSyxcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIC8vIGFkZCBhbiBpZCB0byBiZSBhYmxlIHRvIHNlbGVjdCBpdC4gVXNpbmcgdGhlIGBwYXRoYCBpcyBub3QgcG9zc2libGUgYmVjYXVzZVxyXG4gICAgLy8gZW1wdHkgcGF0aCBjaGlsZHJlbiB3b3VsZCBjb2xsaWRlIHdpdGggdGhlaXIgcGFyZW50c1xyXG4gICAgbGV0IGlkID0gcmVjb3JkLl9fdmRfaWQ7XHJcbiAgICBpZiAoaWQgPT0gbnVsbCkge1xyXG4gICAgICAgIGlkID0gU3RyaW5nKHJvdXRlUmVjb3JkSWQrKyk7XHJcbiAgICAgICAgcmVjb3JkLl9fdmRfaWQgPSBpZDtcclxuICAgIH1cclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgaWQsXHJcbiAgICAgICAgbGFiZWw6IHJlY29yZC5wYXRoLFxyXG4gICAgICAgIHRhZ3MsXHJcbiAgICAgICAgY2hpbGRyZW46IHJvdXRlLmNoaWxkcmVuLm1hcChmb3JtYXRSb3V0ZVJlY29yZEZvckluc3BlY3RvciksXHJcbiAgICB9O1xyXG59XHJcbi8vICBpbmNyZW1lbnRhbCBpZCBmb3Igcm91dGUgcmVjb3JkcyBhbmQgaW5zcGVjdG9yIHN0YXRlXHJcbmxldCByb3V0ZVJlY29yZElkID0gMDtcclxuY29uc3QgRVhUUkFDVF9SRUdFWFBfUkUgPSAvXlxcLyguKilcXC8oW2Etel0qKSQvO1xyXG5mdW5jdGlvbiBtYXJrUm91dGVSZWNvcmRBY3RpdmUocm91dGUsIGN1cnJlbnRSb3V0ZSkge1xyXG4gICAgLy8gbm8gcm91dGUgd2lsbCBiZSBhY3RpdmUgaWYgbWF0Y2hlZCBpcyBlbXB0eVxyXG4gICAgLy8gcmVzZXQgdGhlIG1hdGNoaW5nIHN0YXRlXHJcbiAgICBjb25zdCBpc0V4YWN0QWN0aXZlID0gY3VycmVudFJvdXRlLm1hdGNoZWQubGVuZ3RoICYmXHJcbiAgICAgICAgaXNTYW1lUm91dGVSZWNvcmQoY3VycmVudFJvdXRlLm1hdGNoZWRbY3VycmVudFJvdXRlLm1hdGNoZWQubGVuZ3RoIC0gMV0sIHJvdXRlLnJlY29yZCk7XHJcbiAgICByb3V0ZS5fX3ZkX2V4YWN0QWN0aXZlID0gcm91dGUuX192ZF9hY3RpdmUgPSBpc0V4YWN0QWN0aXZlO1xyXG4gICAgaWYgKCFpc0V4YWN0QWN0aXZlKSB7XHJcbiAgICAgICAgcm91dGUuX192ZF9hY3RpdmUgPSBjdXJyZW50Um91dGUubWF0Y2hlZC5zb21lKG1hdGNoID0+IGlzU2FtZVJvdXRlUmVjb3JkKG1hdGNoLCByb3V0ZS5yZWNvcmQpKTtcclxuICAgIH1cclxuICAgIHJvdXRlLmNoaWxkcmVuLmZvckVhY2goY2hpbGRSb3V0ZSA9PiBtYXJrUm91dGVSZWNvcmRBY3RpdmUoY2hpbGRSb3V0ZSwgY3VycmVudFJvdXRlKSk7XHJcbn1cclxuZnVuY3Rpb24gcmVzZXRNYXRjaFN0YXRlT25Sb3V0ZVJlY29yZChyb3V0ZSkge1xyXG4gICAgcm91dGUuX192ZF9tYXRjaCA9IGZhbHNlO1xyXG4gICAgcm91dGUuY2hpbGRyZW4uZm9yRWFjaChyZXNldE1hdGNoU3RhdGVPblJvdXRlUmVjb3JkKTtcclxufVxyXG5mdW5jdGlvbiBpc1JvdXRlTWF0Y2hpbmcocm91dGUsIGZpbHRlcikge1xyXG4gICAgY29uc3QgZm91bmQgPSBTdHJpbmcocm91dGUucmUpLm1hdGNoKEVYVFJBQ1RfUkVHRVhQX1JFKTtcclxuICAgIHJvdXRlLl9fdmRfbWF0Y2ggPSBmYWxzZTtcclxuICAgIGlmICghZm91bmQgfHwgZm91bmQubGVuZ3RoIDwgMykge1xyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIC8vIHVzZSBhIHJlZ2V4cCB3aXRob3V0ICQgYXQgdGhlIGVuZCB0byBtYXRjaCBuZXN0ZWQgcm91dGVzIGJldHRlclxyXG4gICAgY29uc3Qgbm9uRW5kaW5nUkUgPSBuZXcgUmVnRXhwKGZvdW5kWzFdLnJlcGxhY2UoL1xcJCQvLCAnJyksIGZvdW5kWzJdKTtcclxuICAgIGlmIChub25FbmRpbmdSRS50ZXN0KGZpbHRlcikpIHtcclxuICAgICAgICAvLyBtYXJrIGNoaWxkcmVuIGFzIG1hdGNoZXNcclxuICAgICAgICByb3V0ZS5jaGlsZHJlbi5mb3JFYWNoKGNoaWxkID0+IGlzUm91dGVNYXRjaGluZyhjaGlsZCwgZmlsdGVyKSk7XHJcbiAgICAgICAgLy8gZXhjZXB0aW9uIGNhc2U6IGAvYFxyXG4gICAgICAgIGlmIChyb3V0ZS5yZWNvcmQucGF0aCAhPT0gJy8nIHx8IGZpbHRlciA9PT0gJy8nKSB7XHJcbiAgICAgICAgICAgIHJvdXRlLl9fdmRfbWF0Y2ggPSByb3V0ZS5yZS50ZXN0KGZpbHRlcik7XHJcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBoaWRlIHRoZSAvIHJvdXRlXHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gICAgY29uc3QgcGF0aCA9IHJvdXRlLnJlY29yZC5wYXRoLnRvTG93ZXJDYXNlKCk7XHJcbiAgICBjb25zdCBkZWNvZGVkUGF0aCA9IGRlY29kZShwYXRoKTtcclxuICAgIC8vIGFsc28gYWxsb3cgcGFydGlhbCBtYXRjaGluZyBvbiB0aGUgcGF0aFxyXG4gICAgaWYgKCFmaWx0ZXIuc3RhcnRzV2l0aCgnLycpICYmXHJcbiAgICAgICAgKGRlY29kZWRQYXRoLmluY2x1ZGVzKGZpbHRlcikgfHwgcGF0aC5pbmNsdWRlcyhmaWx0ZXIpKSlcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIGlmIChkZWNvZGVkUGF0aC5zdGFydHNXaXRoKGZpbHRlcikgfHwgcGF0aC5zdGFydHNXaXRoKGZpbHRlcikpXHJcbiAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICBpZiAocm91dGUucmVjb3JkLm5hbWUgJiYgU3RyaW5nKHJvdXRlLnJlY29yZC5uYW1lKS5pbmNsdWRlcyhmaWx0ZXIpKVxyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgcmV0dXJuIHJvdXRlLmNoaWxkcmVuLnNvbWUoY2hpbGQgPT4gaXNSb3V0ZU1hdGNoaW5nKGNoaWxkLCBmaWx0ZXIpKTtcclxufVxyXG5mdW5jdGlvbiBvbWl0KG9iaiwga2V5cykge1xyXG4gICAgY29uc3QgcmV0ID0ge307XHJcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBvYmopIHtcclxuICAgICAgICBpZiAoIWtleXMuaW5jbHVkZXMoa2V5KSkge1xyXG4gICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXHJcbiAgICAgICAgICAgIHJldFtrZXldID0gb2JqW2tleV07XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHJldDtcclxufVxuXG4vKipcclxuICogQ3JlYXRlcyBhIFJvdXRlciBpbnN0YW5jZSB0aGF0IGNhbiBiZSB1c2VkIGJ5IGEgVnVlIGFwcC5cclxuICpcclxuICogQHBhcmFtIG9wdGlvbnMgLSB7QGxpbmsgUm91dGVyT3B0aW9uc31cclxuICovXHJcbmZ1bmN0aW9uIGNyZWF0ZVJvdXRlcihvcHRpb25zKSB7XHJcbiAgICBjb25zdCBtYXRjaGVyID0gY3JlYXRlUm91dGVyTWF0Y2hlcihvcHRpb25zLnJvdXRlcywgb3B0aW9ucyk7XHJcbiAgICBjb25zdCBwYXJzZVF1ZXJ5JDEgPSBvcHRpb25zLnBhcnNlUXVlcnkgfHwgcGFyc2VRdWVyeTtcclxuICAgIGNvbnN0IHN0cmluZ2lmeVF1ZXJ5JDEgPSBvcHRpb25zLnN0cmluZ2lmeVF1ZXJ5IHx8IHN0cmluZ2lmeVF1ZXJ5O1xyXG4gICAgY29uc3Qgcm91dGVySGlzdG9yeSA9IG9wdGlvbnMuaGlzdG9yeTtcclxuICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiYgIXJvdXRlckhpc3RvcnkpXHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdQcm92aWRlIHRoZSBcImhpc3RvcnlcIiBvcHRpb24gd2hlbiBjYWxsaW5nIFwiY3JlYXRlUm91dGVyKClcIjonICtcclxuICAgICAgICAgICAgJyBodHRwczovL25leHQucm91dGVyLnZ1ZWpzLm9yZy9hcGkvI2hpc3RvcnkuJyk7XHJcbiAgICBjb25zdCBiZWZvcmVHdWFyZHMgPSB1c2VDYWxsYmFja3MoKTtcclxuICAgIGNvbnN0IGJlZm9yZVJlc29sdmVHdWFyZHMgPSB1c2VDYWxsYmFja3MoKTtcclxuICAgIGNvbnN0IGFmdGVyR3VhcmRzID0gdXNlQ2FsbGJhY2tzKCk7XHJcbiAgICBjb25zdCBjdXJyZW50Um91dGUgPSBzaGFsbG93UmVmKFNUQVJUX0xPQ0FUSU9OX05PUk1BTElaRUQpO1xyXG4gICAgbGV0IHBlbmRpbmdMb2NhdGlvbiA9IFNUQVJUX0xPQ0FUSU9OX05PUk1BTElaRUQ7XHJcbiAgICAvLyBsZWF2ZSB0aGUgc2Nyb2xsUmVzdG9yYXRpb24gaWYgbm8gc2Nyb2xsQmVoYXZpb3IgaXMgcHJvdmlkZWRcclxuICAgIGlmIChpc0Jyb3dzZXIgJiYgb3B0aW9ucy5zY3JvbGxCZWhhdmlvciAmJiAnc2Nyb2xsUmVzdG9yYXRpb24nIGluIGhpc3RvcnkpIHtcclxuICAgICAgICBoaXN0b3J5LnNjcm9sbFJlc3RvcmF0aW9uID0gJ21hbnVhbCc7XHJcbiAgICB9XHJcbiAgICBjb25zdCBub3JtYWxpemVQYXJhbXMgPSBhcHBseVRvUGFyYW1zLmJpbmQobnVsbCwgcGFyYW1WYWx1ZSA9PiAnJyArIHBhcmFtVmFsdWUpO1xyXG4gICAgY29uc3QgZW5jb2RlUGFyYW1zID0gYXBwbHlUb1BhcmFtcy5iaW5kKG51bGwsIGVuY29kZVBhcmFtKTtcclxuICAgIGNvbnN0IGRlY29kZVBhcmFtcyA9IFxyXG4gICAgLy8gQHRzLWV4cGVjdC1lcnJvcjogaW50ZW50aW9uYWxseSBhdm9pZCB0aGUgdHlwZSBjaGVja1xyXG4gICAgYXBwbHlUb1BhcmFtcy5iaW5kKG51bGwsIGRlY29kZSk7XHJcbiAgICBmdW5jdGlvbiBhZGRSb3V0ZShwYXJlbnRPclJvdXRlLCByb3V0ZSkge1xyXG4gICAgICAgIGxldCBwYXJlbnQ7XHJcbiAgICAgICAgbGV0IHJlY29yZDtcclxuICAgICAgICBpZiAoaXNSb3V0ZU5hbWUocGFyZW50T3JSb3V0ZSkpIHtcclxuICAgICAgICAgICAgcGFyZW50ID0gbWF0Y2hlci5nZXRSZWNvcmRNYXRjaGVyKHBhcmVudE9yUm91dGUpO1xyXG4gICAgICAgICAgICByZWNvcmQgPSByb3V0ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHJlY29yZCA9IHBhcmVudE9yUm91dGU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBtYXRjaGVyLmFkZFJvdXRlKHJlY29yZCwgcGFyZW50KTtcclxuICAgIH1cclxuICAgIGZ1bmN0aW9uIHJlbW92ZVJvdXRlKG5hbWUpIHtcclxuICAgICAgICBjb25zdCByZWNvcmRNYXRjaGVyID0gbWF0Y2hlci5nZXRSZWNvcmRNYXRjaGVyKG5hbWUpO1xyXG4gICAgICAgIGlmIChyZWNvcmRNYXRjaGVyKSB7XHJcbiAgICAgICAgICAgIG1hdGNoZXIucmVtb3ZlUm91dGUocmVjb3JkTWF0Y2hlcik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgICAgICB3YXJuKGBDYW5ub3QgcmVtb3ZlIG5vbi1leGlzdGVudCByb3V0ZSBcIiR7U3RyaW5nKG5hbWUpfVwiYCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gZ2V0Um91dGVzKCkge1xyXG4gICAgICAgIHJldHVybiBtYXRjaGVyLmdldFJvdXRlcygpLm1hcChyb3V0ZU1hdGNoZXIgPT4gcm91dGVNYXRjaGVyLnJlY29yZCk7XHJcbiAgICB9XHJcbiAgICBmdW5jdGlvbiBoYXNSb3V0ZShuYW1lKSB7XHJcbiAgICAgICAgcmV0dXJuICEhbWF0Y2hlci5nZXRSZWNvcmRNYXRjaGVyKG5hbWUpO1xyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gcmVzb2x2ZShyYXdMb2NhdGlvbiwgY3VycmVudExvY2F0aW9uKSB7XHJcbiAgICAgICAgLy8gY29uc3Qgb2JqZWN0TG9jYXRpb24gPSByb3V0ZXJMb2NhdGlvbkFzT2JqZWN0KHJhd0xvY2F0aW9uKVxyXG4gICAgICAgIC8vIHdlIGNyZWF0ZSBhIGNvcHkgdG8gbW9kaWZ5IGl0IGxhdGVyXHJcbiAgICAgICAgY3VycmVudExvY2F0aW9uID0gYXNzaWduKHt9LCBjdXJyZW50TG9jYXRpb24gfHwgY3VycmVudFJvdXRlLnZhbHVlKTtcclxuICAgICAgICBpZiAodHlwZW9mIHJhd0xvY2F0aW9uID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICBjb25zdCBsb2NhdGlvbk5vcm1hbGl6ZWQgPSBwYXJzZVVSTChwYXJzZVF1ZXJ5JDEsIHJhd0xvY2F0aW9uLCBjdXJyZW50TG9jYXRpb24ucGF0aCk7XHJcbiAgICAgICAgICAgIGNvbnN0IG1hdGNoZWRSb3V0ZSA9IG1hdGNoZXIucmVzb2x2ZSh7IHBhdGg6IGxvY2F0aW9uTm9ybWFsaXplZC5wYXRoIH0sIGN1cnJlbnRMb2NhdGlvbik7XHJcbiAgICAgICAgICAgIGNvbnN0IGhyZWYgPSByb3V0ZXJIaXN0b3J5LmNyZWF0ZUhyZWYobG9jYXRpb25Ob3JtYWxpemVkLmZ1bGxQYXRoKTtcclxuICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGhyZWYuc3RhcnRzV2l0aCgnLy8nKSlcclxuICAgICAgICAgICAgICAgICAgICB3YXJuKGBMb2NhdGlvbiBcIiR7cmF3TG9jYXRpb259XCIgcmVzb2x2ZWQgdG8gXCIke2hyZWZ9XCIuIEEgcmVzb2x2ZWQgbG9jYXRpb24gY2Fubm90IHN0YXJ0IHdpdGggbXVsdGlwbGUgc2xhc2hlcy5gKTtcclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFtYXRjaGVkUm91dGUubWF0Y2hlZC5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgICAgICB3YXJuKGBObyBtYXRjaCBmb3VuZCBmb3IgbG9jYXRpb24gd2l0aCBwYXRoIFwiJHtyYXdMb2NhdGlvbn1cImApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIGxvY2F0aW9uTm9ybWFsaXplZCBpcyBhbHdheXMgYSBuZXcgb2JqZWN0XHJcbiAgICAgICAgICAgIHJldHVybiBhc3NpZ24obG9jYXRpb25Ob3JtYWxpemVkLCBtYXRjaGVkUm91dGUsIHtcclxuICAgICAgICAgICAgICAgIHBhcmFtczogZGVjb2RlUGFyYW1zKG1hdGNoZWRSb3V0ZS5wYXJhbXMpLFxyXG4gICAgICAgICAgICAgICAgaGFzaDogZGVjb2RlKGxvY2F0aW9uTm9ybWFsaXplZC5oYXNoKSxcclxuICAgICAgICAgICAgICAgIHJlZGlyZWN0ZWRGcm9tOiB1bmRlZmluZWQsXHJcbiAgICAgICAgICAgICAgICBocmVmLFxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgbGV0IG1hdGNoZXJMb2NhdGlvbjtcclxuICAgICAgICAvLyBwYXRoIGNvdWxkIGJlIHJlbGF0aXZlIGluIG9iamVjdCBhcyB3ZWxsXHJcbiAgICAgICAgaWYgKCdwYXRoJyBpbiByYXdMb2NhdGlvbikge1xyXG4gICAgICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmXHJcbiAgICAgICAgICAgICAgICAncGFyYW1zJyBpbiByYXdMb2NhdGlvbiAmJlxyXG4gICAgICAgICAgICAgICAgISgnbmFtZScgaW4gcmF3TG9jYXRpb24pICYmXHJcbiAgICAgICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yOiB0aGUgdHlwZSBpcyBuZXZlclxyXG4gICAgICAgICAgICAgICAgT2JqZWN0LmtleXMocmF3TG9jYXRpb24ucGFyYW1zKS5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgIHdhcm4oYFBhdGggXCIke1xyXG4gICAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvcjogdGhlIHR5cGUgaXMgbmV2ZXJcclxuICAgICAgICAgICAgICAgIHJhd0xvY2F0aW9uLnBhdGh9XCIgd2FzIHBhc3NlZCB3aXRoIHBhcmFtcyBidXQgdGhleSB3aWxsIGJlIGlnbm9yZWQuIFVzZSBhIG5hbWVkIHJvdXRlIGFsb25nc2lkZSBwYXJhbXMgaW5zdGVhZC5gKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBtYXRjaGVyTG9jYXRpb24gPSBhc3NpZ24oe30sIHJhd0xvY2F0aW9uLCB7XHJcbiAgICAgICAgICAgICAgICBwYXRoOiBwYXJzZVVSTChwYXJzZVF1ZXJ5JDEsIHJhd0xvY2F0aW9uLnBhdGgsIGN1cnJlbnRMb2NhdGlvbi5wYXRoKS5wYXRoLFxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIHJlbW92ZSBhbnkgbnVsbGlzaCBwYXJhbVxyXG4gICAgICAgICAgICBjb25zdCB0YXJnZXRQYXJhbXMgPSBhc3NpZ24oe30sIHJhd0xvY2F0aW9uLnBhcmFtcyk7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIHRhcmdldFBhcmFtcykge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRhcmdldFBhcmFtc1trZXldID09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGFyZ2V0UGFyYW1zW2tleV07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gcGFzcyBlbmNvZGVkIHZhbHVlcyB0byB0aGUgbWF0Y2hlciBzbyBpdCBjYW4gcHJvZHVjZSBlbmNvZGVkIHBhdGggYW5kIGZ1bGxQYXRoXHJcbiAgICAgICAgICAgIG1hdGNoZXJMb2NhdGlvbiA9IGFzc2lnbih7fSwgcmF3TG9jYXRpb24sIHtcclxuICAgICAgICAgICAgICAgIHBhcmFtczogZW5jb2RlUGFyYW1zKHJhd0xvY2F0aW9uLnBhcmFtcyksXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAvLyBjdXJyZW50IGxvY2F0aW9uIHBhcmFtcyBhcmUgZGVjb2RlZCwgd2UgbmVlZCB0byBlbmNvZGUgdGhlbSBpbiBjYXNlIHRoZVxyXG4gICAgICAgICAgICAvLyBtYXRjaGVyIG1lcmdlcyB0aGUgcGFyYW1zXHJcbiAgICAgICAgICAgIGN1cnJlbnRMb2NhdGlvbi5wYXJhbXMgPSBlbmNvZGVQYXJhbXMoY3VycmVudExvY2F0aW9uLnBhcmFtcyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IG1hdGNoZWRSb3V0ZSA9IG1hdGNoZXIucmVzb2x2ZShtYXRjaGVyTG9jYXRpb24sIGN1cnJlbnRMb2NhdGlvbik7XHJcbiAgICAgICAgY29uc3QgaGFzaCA9IHJhd0xvY2F0aW9uLmhhc2ggfHwgJyc7XHJcbiAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiBoYXNoICYmICFoYXNoLnN0YXJ0c1dpdGgoJyMnKSkge1xyXG4gICAgICAgICAgICB3YXJuKGBBIFxcYGhhc2hcXGAgc2hvdWxkIGFsd2F5cyBzdGFydCB3aXRoIHRoZSBjaGFyYWN0ZXIgXCIjXCIuIFJlcGxhY2UgXCIke2hhc2h9XCIgd2l0aCBcIiMke2hhc2h9XCIuYCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGRlY29kaW5nIHRoZW0pIHRoZSBtYXRjaGVyIG1pZ2h0IGhhdmUgbWVyZ2VkIGN1cnJlbnQgbG9jYXRpb24gcGFyYW1zIHNvXHJcbiAgICAgICAgLy8gd2UgbmVlZCB0byBydW4gdGhlIGRlY29kaW5nIGFnYWluXHJcbiAgICAgICAgbWF0Y2hlZFJvdXRlLnBhcmFtcyA9IG5vcm1hbGl6ZVBhcmFtcyhkZWNvZGVQYXJhbXMobWF0Y2hlZFJvdXRlLnBhcmFtcykpO1xyXG4gICAgICAgIGNvbnN0IGZ1bGxQYXRoID0gc3RyaW5naWZ5VVJMKHN0cmluZ2lmeVF1ZXJ5JDEsIGFzc2lnbih7fSwgcmF3TG9jYXRpb24sIHtcclxuICAgICAgICAgICAgaGFzaDogZW5jb2RlSGFzaChoYXNoKSxcclxuICAgICAgICAgICAgcGF0aDogbWF0Y2hlZFJvdXRlLnBhdGgsXHJcbiAgICAgICAgfSkpO1xyXG4gICAgICAgIGNvbnN0IGhyZWYgPSByb3V0ZXJIaXN0b3J5LmNyZWF0ZUhyZWYoZnVsbFBhdGgpO1xyXG4gICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICAgICAgaWYgKGhyZWYuc3RhcnRzV2l0aCgnLy8nKSkge1xyXG4gICAgICAgICAgICAgICAgd2FybihgTG9jYXRpb24gXCIke3Jhd0xvY2F0aW9ufVwiIHJlc29sdmVkIHRvIFwiJHtocmVmfVwiLiBBIHJlc29sdmVkIGxvY2F0aW9uIGNhbm5vdCBzdGFydCB3aXRoIG11bHRpcGxlIHNsYXNoZXMuYCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAoIW1hdGNoZWRSb3V0ZS5tYXRjaGVkLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgd2FybihgTm8gbWF0Y2ggZm91bmQgZm9yIGxvY2F0aW9uIHdpdGggcGF0aCBcIiR7J3BhdGgnIGluIHJhd0xvY2F0aW9uID8gcmF3TG9jYXRpb24ucGF0aCA6IHJhd0xvY2F0aW9ufVwiYCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGFzc2lnbih7XHJcbiAgICAgICAgICAgIGZ1bGxQYXRoLFxyXG4gICAgICAgICAgICAvLyBrZWVwIHRoZSBoYXNoIGVuY29kZWQgc28gZnVsbFBhdGggaXMgZWZmZWN0aXZlbHkgcGF0aCArIGVuY29kZWRRdWVyeSArXHJcbiAgICAgICAgICAgIC8vIGhhc2hcclxuICAgICAgICAgICAgaGFzaCxcclxuICAgICAgICAgICAgcXVlcnk6IFxyXG4gICAgICAgICAgICAvLyBpZiB0aGUgdXNlciBpcyB1c2luZyBhIGN1c3RvbSBxdWVyeSBsaWIgbGlrZSBxcywgd2UgbWlnaHQgaGF2ZVxyXG4gICAgICAgICAgICAvLyBuZXN0ZWQgb2JqZWN0cywgc28gd2Uga2VlcCB0aGUgcXVlcnkgYXMgaXMsIG1lYW5pbmcgaXQgY2FuIGNvbnRhaW5cclxuICAgICAgICAgICAgLy8gbnVtYmVycyBhdCBgJHJvdXRlLnF1ZXJ5YCwgYnV0IGF0IHRoZSBwb2ludCwgdGhlIHVzZXIgd2lsbCBoYXZlIHRvXHJcbiAgICAgICAgICAgIC8vIHVzZSB0aGVpciBvd24gdHlwZSBhbnl3YXkuXHJcbiAgICAgICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS92dWVqcy92dWUtcm91dGVyLW5leHQvaXNzdWVzLzMyOCNpc3N1ZWNvbW1lbnQtNjQ5NDgxNTY3XHJcbiAgICAgICAgICAgIHN0cmluZ2lmeVF1ZXJ5JDEgPT09IHN0cmluZ2lmeVF1ZXJ5XHJcbiAgICAgICAgICAgICAgICA/IG5vcm1hbGl6ZVF1ZXJ5KHJhd0xvY2F0aW9uLnF1ZXJ5KVxyXG4gICAgICAgICAgICAgICAgOiAocmF3TG9jYXRpb24ucXVlcnkgfHwge30pLFxyXG4gICAgICAgIH0sIG1hdGNoZWRSb3V0ZSwge1xyXG4gICAgICAgICAgICByZWRpcmVjdGVkRnJvbTogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICBocmVmLFxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gbG9jYXRpb25Bc09iamVjdCh0bykge1xyXG4gICAgICAgIHJldHVybiB0eXBlb2YgdG8gPT09ICdzdHJpbmcnXHJcbiAgICAgICAgICAgID8gcGFyc2VVUkwocGFyc2VRdWVyeSQxLCB0bywgY3VycmVudFJvdXRlLnZhbHVlLnBhdGgpXHJcbiAgICAgICAgICAgIDogYXNzaWduKHt9LCB0byk7XHJcbiAgICB9XHJcbiAgICBmdW5jdGlvbiBjaGVja0NhbmNlbGVkTmF2aWdhdGlvbih0bywgZnJvbSkge1xyXG4gICAgICAgIGlmIChwZW5kaW5nTG9jYXRpb24gIT09IHRvKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBjcmVhdGVSb3V0ZXJFcnJvcig4IC8qIE5BVklHQVRJT05fQ0FOQ0VMTEVEICovLCB7XHJcbiAgICAgICAgICAgICAgICBmcm9tLFxyXG4gICAgICAgICAgICAgICAgdG8sXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGZ1bmN0aW9uIHB1c2godG8pIHtcclxuICAgICAgICByZXR1cm4gcHVzaFdpdGhSZWRpcmVjdCh0byk7XHJcbiAgICB9XHJcbiAgICBmdW5jdGlvbiByZXBsYWNlKHRvKSB7XHJcbiAgICAgICAgcmV0dXJuIHB1c2goYXNzaWduKGxvY2F0aW9uQXNPYmplY3QodG8pLCB7IHJlcGxhY2U6IHRydWUgfSkpO1xyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gaGFuZGxlUmVkaXJlY3RSZWNvcmQodG8pIHtcclxuICAgICAgICBjb25zdCBsYXN0TWF0Y2hlZCA9IHRvLm1hdGNoZWRbdG8ubWF0Y2hlZC5sZW5ndGggLSAxXTtcclxuICAgICAgICBpZiAobGFzdE1hdGNoZWQgJiYgbGFzdE1hdGNoZWQucmVkaXJlY3QpIHtcclxuICAgICAgICAgICAgY29uc3QgeyByZWRpcmVjdCB9ID0gbGFzdE1hdGNoZWQ7XHJcbiAgICAgICAgICAgIGxldCBuZXdUYXJnZXRMb2NhdGlvbiA9IHR5cGVvZiByZWRpcmVjdCA9PT0gJ2Z1bmN0aW9uJyA/IHJlZGlyZWN0KHRvKSA6IHJlZGlyZWN0O1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG5ld1RhcmdldExvY2F0aW9uID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICAgICAgbmV3VGFyZ2V0TG9jYXRpb24gPVxyXG4gICAgICAgICAgICAgICAgICAgIG5ld1RhcmdldExvY2F0aW9uLmluY2x1ZGVzKCc/JykgfHwgbmV3VGFyZ2V0TG9jYXRpb24uaW5jbHVkZXMoJyMnKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICA/IChuZXdUYXJnZXRMb2NhdGlvbiA9IGxvY2F0aW9uQXNPYmplY3QobmV3VGFyZ2V0TG9jYXRpb24pKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICA6IC8vIGZvcmNlIGVtcHR5IHBhcmFtc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeyBwYXRoOiBuZXdUYXJnZXRMb2NhdGlvbiB9O1xyXG4gICAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvcjogZm9yY2UgZW1wdHkgcGFyYW1zIHdoZW4gYSBzdHJpbmcgaXMgcGFzc2VkIHRvIGxldFxyXG4gICAgICAgICAgICAgICAgLy8gdGhlIHJvdXRlciBwYXJzZSB0aGVtIGFnYWluXHJcbiAgICAgICAgICAgICAgICBuZXdUYXJnZXRMb2NhdGlvbi5wYXJhbXMgPSB7fTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmXHJcbiAgICAgICAgICAgICAgICAhKCdwYXRoJyBpbiBuZXdUYXJnZXRMb2NhdGlvbikgJiZcclxuICAgICAgICAgICAgICAgICEoJ25hbWUnIGluIG5ld1RhcmdldExvY2F0aW9uKSkge1xyXG4gICAgICAgICAgICAgICAgd2FybihgSW52YWxpZCByZWRpcmVjdCBmb3VuZDpcXG4ke0pTT04uc3RyaW5naWZ5KG5ld1RhcmdldExvY2F0aW9uLCBudWxsLCAyKX1cXG4gd2hlbiBuYXZpZ2F0aW5nIHRvIFwiJHt0by5mdWxsUGF0aH1cIi4gQSByZWRpcmVjdCBtdXN0IGNvbnRhaW4gYSBuYW1lIG9yIHBhdGguIFRoaXMgd2lsbCBicmVhayBpbiBwcm9kdWN0aW9uLmApO1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHJlZGlyZWN0Jyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIGFzc2lnbih7XHJcbiAgICAgICAgICAgICAgICBxdWVyeTogdG8ucXVlcnksXHJcbiAgICAgICAgICAgICAgICBoYXNoOiB0by5oYXNoLFxyXG4gICAgICAgICAgICAgICAgcGFyYW1zOiB0by5wYXJhbXMsXHJcbiAgICAgICAgICAgIH0sIG5ld1RhcmdldExvY2F0aW9uKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBmdW5jdGlvbiBwdXNoV2l0aFJlZGlyZWN0KHRvLCByZWRpcmVjdGVkRnJvbSkge1xyXG4gICAgICAgIGNvbnN0IHRhcmdldExvY2F0aW9uID0gKHBlbmRpbmdMb2NhdGlvbiA9IHJlc29sdmUodG8pKTtcclxuICAgICAgICBjb25zdCBmcm9tID0gY3VycmVudFJvdXRlLnZhbHVlO1xyXG4gICAgICAgIGNvbnN0IGRhdGEgPSB0by5zdGF0ZTtcclxuICAgICAgICBjb25zdCBmb3JjZSA9IHRvLmZvcmNlO1xyXG4gICAgICAgIC8vIHRvIGNvdWxkIGJlIGEgc3RyaW5nIHdoZXJlIGByZXBsYWNlYCBpcyBhIGZ1bmN0aW9uXHJcbiAgICAgICAgY29uc3QgcmVwbGFjZSA9IHRvLnJlcGxhY2UgPT09IHRydWU7XHJcbiAgICAgICAgY29uc3Qgc2hvdWxkUmVkaXJlY3QgPSBoYW5kbGVSZWRpcmVjdFJlY29yZCh0YXJnZXRMb2NhdGlvbik7XHJcbiAgICAgICAgaWYgKHNob3VsZFJlZGlyZWN0KVxyXG4gICAgICAgICAgICByZXR1cm4gcHVzaFdpdGhSZWRpcmVjdChhc3NpZ24obG9jYXRpb25Bc09iamVjdChzaG91bGRSZWRpcmVjdCksIHtcclxuICAgICAgICAgICAgICAgIHN0YXRlOiBkYXRhLFxyXG4gICAgICAgICAgICAgICAgZm9yY2UsXHJcbiAgICAgICAgICAgICAgICByZXBsYWNlLFxyXG4gICAgICAgICAgICB9KSwgXHJcbiAgICAgICAgICAgIC8vIGtlZXAgb3JpZ2luYWwgcmVkaXJlY3RlZEZyb20gaWYgaXQgZXhpc3RzXHJcbiAgICAgICAgICAgIHJlZGlyZWN0ZWRGcm9tIHx8IHRhcmdldExvY2F0aW9uKTtcclxuICAgICAgICAvLyBpZiBpdCB3YXMgYSByZWRpcmVjdCB3ZSBhbHJlYWR5IGNhbGxlZCBgcHVzaFdpdGhSZWRpcmVjdGAgYWJvdmVcclxuICAgICAgICBjb25zdCB0b0xvY2F0aW9uID0gdGFyZ2V0TG9jYXRpb247XHJcbiAgICAgICAgdG9Mb2NhdGlvbi5yZWRpcmVjdGVkRnJvbSA9IHJlZGlyZWN0ZWRGcm9tO1xyXG4gICAgICAgIGxldCBmYWlsdXJlO1xyXG4gICAgICAgIGlmICghZm9yY2UgJiYgaXNTYW1lUm91dGVMb2NhdGlvbihzdHJpbmdpZnlRdWVyeSQxLCBmcm9tLCB0YXJnZXRMb2NhdGlvbikpIHtcclxuICAgICAgICAgICAgZmFpbHVyZSA9IGNyZWF0ZVJvdXRlckVycm9yKDE2IC8qIE5BVklHQVRJT05fRFVQTElDQVRFRCAqLywgeyB0bzogdG9Mb2NhdGlvbiwgZnJvbSB9KTtcclxuICAgICAgICAgICAgLy8gdHJpZ2dlciBzY3JvbGwgdG8gYWxsb3cgc2Nyb2xsaW5nIHRvIHRoZSBzYW1lIGFuY2hvclxyXG4gICAgICAgICAgICBoYW5kbGVTY3JvbGwoZnJvbSwgZnJvbSwgXHJcbiAgICAgICAgICAgIC8vIHRoaXMgaXMgYSBwdXNoLCB0aGUgb25seSB3YXkgZm9yIGl0IHRvIGJlIHRyaWdnZXJlZCBmcm9tIGFcclxuICAgICAgICAgICAgLy8gaGlzdG9yeS5saXN0ZW4gaXMgd2l0aCBhIHJlZGlyZWN0LCB3aGljaCBtYWtlcyBpdCBiZWNvbWUgYSBwdXNoXHJcbiAgICAgICAgICAgIHRydWUsIFxyXG4gICAgICAgICAgICAvLyBUaGlzIGNhbm5vdCBiZSB0aGUgZmlyc3QgbmF2aWdhdGlvbiBiZWNhdXNlIHRoZSBpbml0aWFsIGxvY2F0aW9uXHJcbiAgICAgICAgICAgIC8vIGNhbm5vdCBiZSBtYW51YWxseSBuYXZpZ2F0ZWQgdG9cclxuICAgICAgICAgICAgZmFsc2UpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gKGZhaWx1cmUgPyBQcm9taXNlLnJlc29sdmUoZmFpbHVyZSkgOiBuYXZpZ2F0ZSh0b0xvY2F0aW9uLCBmcm9tKSlcclxuICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4gaXNOYXZpZ2F0aW9uRmFpbHVyZShlcnJvcilcclxuICAgICAgICAgICAgPyBlcnJvclxyXG4gICAgICAgICAgICA6IC8vIHJlamVjdCBhbnkgdW5rbm93biBlcnJvclxyXG4gICAgICAgICAgICAgICAgdHJpZ2dlckVycm9yKGVycm9yLCB0b0xvY2F0aW9uLCBmcm9tKSlcclxuICAgICAgICAgICAgLnRoZW4oKGZhaWx1cmUpID0+IHtcclxuICAgICAgICAgICAgaWYgKGZhaWx1cmUpIHtcclxuICAgICAgICAgICAgICAgIGlmIChpc05hdmlnYXRpb25GYWlsdXJlKGZhaWx1cmUsIDIgLyogTkFWSUdBVElPTl9HVUFSRF9SRURJUkVDVCAqLykpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdlIGFyZSByZWRpcmVjdGluZyB0byB0aGUgc2FtZSBsb2NhdGlvbiB3ZSB3ZXJlIGFscmVhZHkgYXRcclxuICAgICAgICAgICAgICAgICAgICAgICAgaXNTYW1lUm91dGVMb2NhdGlvbihzdHJpbmdpZnlRdWVyeSQxLCByZXNvbHZlKGZhaWx1cmUudG8pLCB0b0xvY2F0aW9uKSAmJlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBhbmQgd2UgaGF2ZSBkb25lIGl0IGEgY291cGxlIG9mIHRpbWVzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZGlyZWN0ZWRGcm9tICYmXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3I6IGFkZGVkIG9ubHkgaW4gZGV2XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIChyZWRpcmVjdGVkRnJvbS5fY291bnQgPSByZWRpcmVjdGVkRnJvbS5fY291bnRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gLy8gQHRzLWV4cGVjdC1lcnJvclxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZGlyZWN0ZWRGcm9tLl9jb3VudCArIDFcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogMSkgPiAxMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB3YXJuKGBEZXRlY3RlZCBhbiBpbmZpbml0ZSByZWRpcmVjdGlvbiBpbiBhIG5hdmlnYXRpb24gZ3VhcmQgd2hlbiBnb2luZyBmcm9tIFwiJHtmcm9tLmZ1bGxQYXRofVwiIHRvIFwiJHt0b0xvY2F0aW9uLmZ1bGxQYXRofVwiLiBBYm9ydGluZyB0byBhdm9pZCBhIFN0YWNrIE92ZXJmbG93LiBUaGlzIHdpbGwgYnJlYWsgaW4gcHJvZHVjdGlvbiBpZiBub3QgZml4ZWQuYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoJ0luZmluaXRlIHJlZGlyZWN0IGluIG5hdmlnYXRpb24gZ3VhcmQnKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBwdXNoV2l0aFJlZGlyZWN0KFxyXG4gICAgICAgICAgICAgICAgICAgIC8vIGtlZXAgb3B0aW9uc1xyXG4gICAgICAgICAgICAgICAgICAgIGFzc2lnbihsb2NhdGlvbkFzT2JqZWN0KGZhaWx1cmUudG8pLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlOiBkYXRhLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3JjZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVwbGFjZSxcclxuICAgICAgICAgICAgICAgICAgICB9KSwgXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gcHJlc2VydmUgdGhlIG9yaWdpbmFsIHJlZGlyZWN0ZWRGcm9tIGlmIGFueVxyXG4gICAgICAgICAgICAgICAgICAgIHJlZGlyZWN0ZWRGcm9tIHx8IHRvTG9jYXRpb24pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgLy8gaWYgd2UgZmFpbCB3ZSBkb24ndCBmaW5hbGl6ZSB0aGUgbmF2aWdhdGlvblxyXG4gICAgICAgICAgICAgICAgZmFpbHVyZSA9IGZpbmFsaXplTmF2aWdhdGlvbih0b0xvY2F0aW9uLCBmcm9tLCB0cnVlLCByZXBsYWNlLCBkYXRhKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0cmlnZ2VyQWZ0ZXJFYWNoKHRvTG9jYXRpb24sIGZyb20sIGZhaWx1cmUpO1xyXG4gICAgICAgICAgICByZXR1cm4gZmFpbHVyZTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICogSGVscGVyIHRvIHJlamVjdCBhbmQgc2tpcCBhbGwgbmF2aWdhdGlvbiBndWFyZHMgaWYgYSBuZXcgbmF2aWdhdGlvbiBoYXBwZW5lZFxyXG4gICAgICogQHBhcmFtIHRvXHJcbiAgICAgKiBAcGFyYW0gZnJvbVxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBjaGVja0NhbmNlbGVkTmF2aWdhdGlvbkFuZFJlamVjdCh0bywgZnJvbSkge1xyXG4gICAgICAgIGNvbnN0IGVycm9yID0gY2hlY2tDYW5jZWxlZE5hdmlnYXRpb24odG8sIGZyb20pO1xyXG4gICAgICAgIHJldHVybiBlcnJvciA/IFByb21pc2UucmVqZWN0KGVycm9yKSA6IFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgfVxyXG4gICAgLy8gVE9ETzogcmVmYWN0b3IgdGhlIHdob2xlIGJlZm9yZSBndWFyZHMgYnkgaW50ZXJuYWxseSB1c2luZyByb3V0ZXIuYmVmb3JlRWFjaFxyXG4gICAgZnVuY3Rpb24gbmF2aWdhdGUodG8sIGZyb20pIHtcclxuICAgICAgICBsZXQgZ3VhcmRzO1xyXG4gICAgICAgIGNvbnN0IFtsZWF2aW5nUmVjb3JkcywgdXBkYXRpbmdSZWNvcmRzLCBlbnRlcmluZ1JlY29yZHNdID0gZXh0cmFjdENoYW5naW5nUmVjb3Jkcyh0bywgZnJvbSk7XHJcbiAgICAgICAgLy8gYWxsIGNvbXBvbmVudHMgaGVyZSBoYXZlIGJlZW4gcmVzb2x2ZWQgb25jZSBiZWNhdXNlIHdlIGFyZSBsZWF2aW5nXHJcbiAgICAgICAgZ3VhcmRzID0gZXh0cmFjdENvbXBvbmVudHNHdWFyZHMobGVhdmluZ1JlY29yZHMucmV2ZXJzZSgpLCAnYmVmb3JlUm91dGVMZWF2ZScsIHRvLCBmcm9tKTtcclxuICAgICAgICAvLyBsZWF2aW5nUmVjb3JkcyBpcyBhbHJlYWR5IHJldmVyc2VkXHJcbiAgICAgICAgZm9yIChjb25zdCByZWNvcmQgb2YgbGVhdmluZ1JlY29yZHMpIHtcclxuICAgICAgICAgICAgcmVjb3JkLmxlYXZlR3VhcmRzLmZvckVhY2goZ3VhcmQgPT4ge1xyXG4gICAgICAgICAgICAgICAgZ3VhcmRzLnB1c2goZ3VhcmRUb1Byb21pc2VGbihndWFyZCwgdG8sIGZyb20pKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IGNhbmNlbGVkTmF2aWdhdGlvbkNoZWNrID0gY2hlY2tDYW5jZWxlZE5hdmlnYXRpb25BbmRSZWplY3QuYmluZChudWxsLCB0bywgZnJvbSk7XHJcbiAgICAgICAgZ3VhcmRzLnB1c2goY2FuY2VsZWROYXZpZ2F0aW9uQ2hlY2spO1xyXG4gICAgICAgIC8vIHJ1biB0aGUgcXVldWUgb2YgcGVyIHJvdXRlIGJlZm9yZVJvdXRlTGVhdmUgZ3VhcmRzXHJcbiAgICAgICAgcmV0dXJuIChydW5HdWFyZFF1ZXVlKGd1YXJkcylcclxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAvLyBjaGVjayBnbG9iYWwgZ3VhcmRzIGJlZm9yZUVhY2hcclxuICAgICAgICAgICAgZ3VhcmRzID0gW107XHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgZ3VhcmQgb2YgYmVmb3JlR3VhcmRzLmxpc3QoKSkge1xyXG4gICAgICAgICAgICAgICAgZ3VhcmRzLnB1c2goZ3VhcmRUb1Byb21pc2VGbihndWFyZCwgdG8sIGZyb20pKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBndWFyZHMucHVzaChjYW5jZWxlZE5hdmlnYXRpb25DaGVjayk7XHJcbiAgICAgICAgICAgIHJldHVybiBydW5HdWFyZFF1ZXVlKGd1YXJkcyk7XHJcbiAgICAgICAgfSlcclxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAvLyBjaGVjayBpbiBjb21wb25lbnRzIGJlZm9yZVJvdXRlVXBkYXRlXHJcbiAgICAgICAgICAgIGd1YXJkcyA9IGV4dHJhY3RDb21wb25lbnRzR3VhcmRzKHVwZGF0aW5nUmVjb3JkcywgJ2JlZm9yZVJvdXRlVXBkYXRlJywgdG8sIGZyb20pO1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHJlY29yZCBvZiB1cGRhdGluZ1JlY29yZHMpIHtcclxuICAgICAgICAgICAgICAgIHJlY29yZC51cGRhdGVHdWFyZHMuZm9yRWFjaChndWFyZCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgZ3VhcmRzLnB1c2goZ3VhcmRUb1Byb21pc2VGbihndWFyZCwgdG8sIGZyb20pKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGd1YXJkcy5wdXNoKGNhbmNlbGVkTmF2aWdhdGlvbkNoZWNrKTtcclxuICAgICAgICAgICAgLy8gcnVuIHRoZSBxdWV1ZSBvZiBwZXIgcm91dGUgYmVmb3JlRW50ZXIgZ3VhcmRzXHJcbiAgICAgICAgICAgIHJldHVybiBydW5HdWFyZFF1ZXVlKGd1YXJkcyk7XHJcbiAgICAgICAgfSlcclxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAvLyBjaGVjayB0aGUgcm91dGUgYmVmb3JlRW50ZXJcclxuICAgICAgICAgICAgZ3VhcmRzID0gW107XHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgcmVjb3JkIG9mIHRvLm1hdGNoZWQpIHtcclxuICAgICAgICAgICAgICAgIC8vIGRvIG5vdCB0cmlnZ2VyIGJlZm9yZUVudGVyIG9uIHJldXNlZCB2aWV3c1xyXG4gICAgICAgICAgICAgICAgaWYgKHJlY29yZC5iZWZvcmVFbnRlciAmJiAhZnJvbS5tYXRjaGVkLmluY2x1ZGVzKHJlY29yZCkpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShyZWNvcmQuYmVmb3JlRW50ZXIpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgYmVmb3JlRW50ZXIgb2YgcmVjb3JkLmJlZm9yZUVudGVyKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3VhcmRzLnB1c2goZ3VhcmRUb1Byb21pc2VGbihiZWZvcmVFbnRlciwgdG8sIGZyb20pKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGd1YXJkcy5wdXNoKGd1YXJkVG9Qcm9taXNlRm4ocmVjb3JkLmJlZm9yZUVudGVyLCB0bywgZnJvbSkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBndWFyZHMucHVzaChjYW5jZWxlZE5hdmlnYXRpb25DaGVjayk7XHJcbiAgICAgICAgICAgIC8vIHJ1biB0aGUgcXVldWUgb2YgcGVyIHJvdXRlIGJlZm9yZUVudGVyIGd1YXJkc1xyXG4gICAgICAgICAgICByZXR1cm4gcnVuR3VhcmRRdWV1ZShndWFyZHMpO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgLy8gTk9URTogYXQgdGhpcyBwb2ludCB0by5tYXRjaGVkIGlzIG5vcm1hbGl6ZWQgYW5kIGRvZXMgbm90IGNvbnRhaW4gYW55ICgpID0+IFByb21pc2U8Q29tcG9uZW50PlxyXG4gICAgICAgICAgICAvLyBjbGVhciBleGlzdGluZyBlbnRlckNhbGxiYWNrcywgdGhlc2UgYXJlIGFkZGVkIGJ5IGV4dHJhY3RDb21wb25lbnRzR3VhcmRzXHJcbiAgICAgICAgICAgIHRvLm1hdGNoZWQuZm9yRWFjaChyZWNvcmQgPT4gKHJlY29yZC5lbnRlckNhbGxiYWNrcyA9IHt9KSk7XHJcbiAgICAgICAgICAgIC8vIGNoZWNrIGluLWNvbXBvbmVudCBiZWZvcmVSb3V0ZUVudGVyXHJcbiAgICAgICAgICAgIGd1YXJkcyA9IGV4dHJhY3RDb21wb25lbnRzR3VhcmRzKGVudGVyaW5nUmVjb3JkcywgJ2JlZm9yZVJvdXRlRW50ZXInLCB0bywgZnJvbSk7XHJcbiAgICAgICAgICAgIGd1YXJkcy5wdXNoKGNhbmNlbGVkTmF2aWdhdGlvbkNoZWNrKTtcclxuICAgICAgICAgICAgLy8gcnVuIHRoZSBxdWV1ZSBvZiBwZXIgcm91dGUgYmVmb3JlRW50ZXIgZ3VhcmRzXHJcbiAgICAgICAgICAgIHJldHVybiBydW5HdWFyZFF1ZXVlKGd1YXJkcyk7XHJcbiAgICAgICAgfSlcclxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAvLyBjaGVjayBnbG9iYWwgZ3VhcmRzIGJlZm9yZVJlc29sdmVcclxuICAgICAgICAgICAgZ3VhcmRzID0gW107XHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgZ3VhcmQgb2YgYmVmb3JlUmVzb2x2ZUd1YXJkcy5saXN0KCkpIHtcclxuICAgICAgICAgICAgICAgIGd1YXJkcy5wdXNoKGd1YXJkVG9Qcm9taXNlRm4oZ3VhcmQsIHRvLCBmcm9tKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZ3VhcmRzLnB1c2goY2FuY2VsZWROYXZpZ2F0aW9uQ2hlY2spO1xyXG4gICAgICAgICAgICByZXR1cm4gcnVuR3VhcmRRdWV1ZShndWFyZHMpO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICAgICAgIC8vIGNhdGNoIGFueSBuYXZpZ2F0aW9uIGNhbmNlbGVkXHJcbiAgICAgICAgICAgIC5jYXRjaChlcnIgPT4gaXNOYXZpZ2F0aW9uRmFpbHVyZShlcnIsIDggLyogTkFWSUdBVElPTl9DQU5DRUxMRUQgKi8pXHJcbiAgICAgICAgICAgID8gZXJyXHJcbiAgICAgICAgICAgIDogUHJvbWlzZS5yZWplY3QoZXJyKSkpO1xyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gdHJpZ2dlckFmdGVyRWFjaCh0bywgZnJvbSwgZmFpbHVyZSkge1xyXG4gICAgICAgIC8vIG5hdmlnYXRpb24gaXMgY29uZmlybWVkLCBjYWxsIGFmdGVyR3VhcmRzXHJcbiAgICAgICAgLy8gVE9ETzogd3JhcCB3aXRoIGVycm9yIGhhbmRsZXJzXHJcbiAgICAgICAgZm9yIChjb25zdCBndWFyZCBvZiBhZnRlckd1YXJkcy5saXN0KCkpXHJcbiAgICAgICAgICAgIGd1YXJkKHRvLCBmcm9tLCBmYWlsdXJlKTtcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICogLSBDbGVhbnMgdXAgYW55IG5hdmlnYXRpb24gZ3VhcmRzXHJcbiAgICAgKiAtIENoYW5nZXMgdGhlIHVybCBpZiBuZWNlc3NhcnlcclxuICAgICAqIC0gQ2FsbHMgdGhlIHNjcm9sbEJlaGF2aW9yXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIGZpbmFsaXplTmF2aWdhdGlvbih0b0xvY2F0aW9uLCBmcm9tLCBpc1B1c2gsIHJlcGxhY2UsIGRhdGEpIHtcclxuICAgICAgICAvLyBhIG1vcmUgcmVjZW50IG5hdmlnYXRpb24gdG9vayBwbGFjZVxyXG4gICAgICAgIGNvbnN0IGVycm9yID0gY2hlY2tDYW5jZWxlZE5hdmlnYXRpb24odG9Mb2NhdGlvbiwgZnJvbSk7XHJcbiAgICAgICAgaWYgKGVycm9yKVxyXG4gICAgICAgICAgICByZXR1cm4gZXJyb3I7XHJcbiAgICAgICAgLy8gb25seSBjb25zaWRlciBhcyBwdXNoIGlmIGl0J3Mgbm90IHRoZSBmaXJzdCBuYXZpZ2F0aW9uXHJcbiAgICAgICAgY29uc3QgaXNGaXJzdE5hdmlnYXRpb24gPSBmcm9tID09PSBTVEFSVF9MT0NBVElPTl9OT1JNQUxJWkVEO1xyXG4gICAgICAgIGNvbnN0IHN0YXRlID0gIWlzQnJvd3NlciA/IHt9IDogaGlzdG9yeS5zdGF0ZTtcclxuICAgICAgICAvLyBjaGFuZ2UgVVJMIG9ubHkgaWYgdGhlIHVzZXIgZGlkIGEgcHVzaC9yZXBsYWNlIGFuZCBpZiBpdCdzIG5vdCB0aGUgaW5pdGlhbCBuYXZpZ2F0aW9uIGJlY2F1c2VcclxuICAgICAgICAvLyBpdCdzIGp1c3QgcmVmbGVjdGluZyB0aGUgdXJsXHJcbiAgICAgICAgaWYgKGlzUHVzaCkge1xyXG4gICAgICAgICAgICAvLyBvbiB0aGUgaW5pdGlhbCBuYXZpZ2F0aW9uLCB3ZSB3YW50IHRvIHJldXNlIHRoZSBzY3JvbGwgcG9zaXRpb24gZnJvbVxyXG4gICAgICAgICAgICAvLyBoaXN0b3J5IHN0YXRlIGlmIGl0IGV4aXN0c1xyXG4gICAgICAgICAgICBpZiAocmVwbGFjZSB8fCBpc0ZpcnN0TmF2aWdhdGlvbilcclxuICAgICAgICAgICAgICAgIHJvdXRlckhpc3RvcnkucmVwbGFjZSh0b0xvY2F0aW9uLmZ1bGxQYXRoLCBhc3NpZ24oe1xyXG4gICAgICAgICAgICAgICAgICAgIHNjcm9sbDogaXNGaXJzdE5hdmlnYXRpb24gJiYgc3RhdGUgJiYgc3RhdGUuc2Nyb2xsLFxyXG4gICAgICAgICAgICAgICAgfSwgZGF0YSkpO1xyXG4gICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICByb3V0ZXJIaXN0b3J5LnB1c2godG9Mb2NhdGlvbi5mdWxsUGF0aCwgZGF0YSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGFjY2VwdCBjdXJyZW50IG5hdmlnYXRpb25cclxuICAgICAgICBjdXJyZW50Um91dGUudmFsdWUgPSB0b0xvY2F0aW9uO1xyXG4gICAgICAgIGhhbmRsZVNjcm9sbCh0b0xvY2F0aW9uLCBmcm9tLCBpc1B1c2gsIGlzRmlyc3ROYXZpZ2F0aW9uKTtcclxuICAgICAgICBtYXJrQXNSZWFkeSgpO1xyXG4gICAgfVxyXG4gICAgbGV0IHJlbW92ZUhpc3RvcnlMaXN0ZW5lcjtcclxuICAgIC8vIGF0dGFjaCBsaXN0ZW5lciB0byBoaXN0b3J5IHRvIHRyaWdnZXIgbmF2aWdhdGlvbnNcclxuICAgIGZ1bmN0aW9uIHNldHVwTGlzdGVuZXJzKCkge1xyXG4gICAgICAgIHJlbW92ZUhpc3RvcnlMaXN0ZW5lciA9IHJvdXRlckhpc3RvcnkubGlzdGVuKCh0bywgX2Zyb20sIGluZm8pID0+IHtcclxuICAgICAgICAgICAgLy8gY2Fubm90IGJlIGEgcmVkaXJlY3Qgcm91dGUgYmVjYXVzZSBpdCB3YXMgaW4gaGlzdG9yeVxyXG4gICAgICAgICAgICBjb25zdCB0b0xvY2F0aW9uID0gcmVzb2x2ZSh0byk7XHJcbiAgICAgICAgICAgIC8vIGR1ZSB0byBkeW5hbWljIHJvdXRpbmcsIGFuZCB0byBoYXNoIGhpc3Rvcnkgd2l0aCBtYW51YWwgbmF2aWdhdGlvblxyXG4gICAgICAgICAgICAvLyAobWFudWFsbHkgY2hhbmdpbmcgdGhlIHVybCBvciBjYWxsaW5nIGhpc3RvcnkuaGFzaCA9ICcjL3NvbWV3aGVyZScpLFxyXG4gICAgICAgICAgICAvLyB0aGVyZSBjb3VsZCBiZSBhIHJlZGlyZWN0IHJlY29yZCBpbiBoaXN0b3J5XHJcbiAgICAgICAgICAgIGNvbnN0IHNob3VsZFJlZGlyZWN0ID0gaGFuZGxlUmVkaXJlY3RSZWNvcmQodG9Mb2NhdGlvbik7XHJcbiAgICAgICAgICAgIGlmIChzaG91bGRSZWRpcmVjdCkge1xyXG4gICAgICAgICAgICAgICAgcHVzaFdpdGhSZWRpcmVjdChhc3NpZ24oc2hvdWxkUmVkaXJlY3QsIHsgcmVwbGFjZTogdHJ1ZSB9KSwgdG9Mb2NhdGlvbikuY2F0Y2gobm9vcCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcGVuZGluZ0xvY2F0aW9uID0gdG9Mb2NhdGlvbjtcclxuICAgICAgICAgICAgY29uc3QgZnJvbSA9IGN1cnJlbnRSb3V0ZS52YWx1ZTtcclxuICAgICAgICAgICAgLy8gVE9ETzogc2hvdWxkIGJlIG1vdmVkIHRvIHdlYiBoaXN0b3J5P1xyXG4gICAgICAgICAgICBpZiAoaXNCcm93c2VyKSB7XHJcbiAgICAgICAgICAgICAgICBzYXZlU2Nyb2xsUG9zaXRpb24oZ2V0U2Nyb2xsS2V5KGZyb20uZnVsbFBhdGgsIGluZm8uZGVsdGEpLCBjb21wdXRlU2Nyb2xsUG9zaXRpb24oKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgbmF2aWdhdGUodG9Mb2NhdGlvbiwgZnJvbSlcclxuICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmIChpc05hdmlnYXRpb25GYWlsdXJlKGVycm9yLCA0IC8qIE5BVklHQVRJT05fQUJPUlRFRCAqLyB8IDggLyogTkFWSUdBVElPTl9DQU5DRUxMRUQgKi8pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVycm9yO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKGlzTmF2aWdhdGlvbkZhaWx1cmUoZXJyb3IsIDIgLyogTkFWSUdBVElPTl9HVUFSRF9SRURJUkVDVCAqLykpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBIZXJlIHdlIGNvdWxkIGNhbGwgaWYgKGluZm8uZGVsdGEpIHJvdXRlckhpc3RvcnkuZ28oLWluZm8uZGVsdGEsXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gZmFsc2UpIGJ1dCB0aGlzIGlzIGJ1ZyBwcm9uZSBhcyB3ZSBoYXZlIG5vIHdheSB0byB3YWl0IHRoZVxyXG4gICAgICAgICAgICAgICAgICAgIC8vIG5hdmlnYXRpb24gdG8gYmUgZmluaXNoZWQgYmVmb3JlIGNhbGxpbmcgcHVzaFdpdGhSZWRpcmVjdC4gVXNpbmdcclxuICAgICAgICAgICAgICAgICAgICAvLyBhIHNldFRpbWVvdXQgb2YgMTZtcyBzZWVtcyB0byB3b3JrIGJ1dCB0aGVyZSBpcyBub3QgZ3VhcmFudGVlIGZvclxyXG4gICAgICAgICAgICAgICAgICAgIC8vIGl0IHRvIHdvcmsgb24gZXZlcnkgYnJvd3Nlci4gU28gSW5zdGVhZCB3ZSBkbyBub3QgcmVzdG9yZSB0aGVcclxuICAgICAgICAgICAgICAgICAgICAvLyBoaXN0b3J5IGVudHJ5IGFuZCB0cmlnZ2VyIGEgbmV3IG5hdmlnYXRpb24gYXMgcmVxdWVzdGVkIGJ5IHRoZVxyXG4gICAgICAgICAgICAgICAgICAgIC8vIG5hdmlnYXRpb24gZ3VhcmQuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGVycm9yIGlzIGFscmVhZHkgaGFuZGxlZCBieSByb3V0ZXIucHVzaCB3ZSBqdXN0IHdhbnQgdG8gYXZvaWRcclxuICAgICAgICAgICAgICAgICAgICAvLyBsb2dnaW5nIHRoZSBlcnJvclxyXG4gICAgICAgICAgICAgICAgICAgIHB1c2hXaXRoUmVkaXJlY3QoZXJyb3IudG8sIHRvTG9jYXRpb25cclxuICAgICAgICAgICAgICAgICAgICAvLyBhdm9pZCBhbiB1bmNhdWdodCByZWplY3Rpb24sIGxldCBwdXNoIGNhbGwgdHJpZ2dlckVycm9yXHJcbiAgICAgICAgICAgICAgICAgICAgKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAudGhlbihmYWlsdXJlID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWFudWFsIGNoYW5nZSBpbiBoYXNoIGhpc3RvcnkgIzkxNiBlbmRpbmcgdXAgaW4gdGhlIFVSTCBub3RcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2hhbmdpbmcgYnV0IGl0IHdhcyBjaGFuZ2VkIGJ5IHRoZSBtYW51YWwgdXJsIGNoYW5nZSwgc28gd2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gbmVlZCB0byBtYW51YWxseSBjaGFuZ2UgaXQgb3Vyc2VsdmVzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc05hdmlnYXRpb25GYWlsdXJlKGZhaWx1cmUsIDQgLyogTkFWSUdBVElPTl9BQk9SVEVEICovIHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDE2IC8qIE5BVklHQVRJT05fRFVQTElDQVRFRCAqLykgJiZcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICFpbmZvLmRlbHRhICYmXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmZvLnR5cGUgPT09IE5hdmlnYXRpb25UeXBlLnBvcCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcm91dGVySGlzdG9yeS5nbygtMSwgZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKG5vb3ApO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGF2b2lkIHRoZSB0aGVuIGJyYW5jaFxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgLy8gZG8gbm90IHJlc3RvcmUgaGlzdG9yeSBvbiB1bmtub3duIGRpcmVjdGlvblxyXG4gICAgICAgICAgICAgICAgaWYgKGluZm8uZGVsdGEpXHJcbiAgICAgICAgICAgICAgICAgICAgcm91dGVySGlzdG9yeS5nbygtaW5mby5kZWx0YSwgZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgLy8gdW5yZWNvZ25pemVkIGVycm9yLCB0cmFuc2ZlciB0byB0aGUgZ2xvYmFsIGhhbmRsZXJcclxuICAgICAgICAgICAgICAgIHJldHVybiB0cmlnZ2VyRXJyb3IoZXJyb3IsIHRvTG9jYXRpb24sIGZyb20pO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgLnRoZW4oKGZhaWx1cmUpID0+IHtcclxuICAgICAgICAgICAgICAgIGZhaWx1cmUgPVxyXG4gICAgICAgICAgICAgICAgICAgIGZhaWx1cmUgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxpemVOYXZpZ2F0aW9uKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBhZnRlciBuYXZpZ2F0aW9uLCBhbGwgbWF0Y2hlZCBjb21wb25lbnRzIGFyZSByZXNvbHZlZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0b0xvY2F0aW9uLCBmcm9tLCBmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAvLyByZXZlcnQgdGhlIG5hdmlnYXRpb25cclxuICAgICAgICAgICAgICAgIGlmIChmYWlsdXJlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGluZm8uZGVsdGEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcm91dGVySGlzdG9yeS5nbygtaW5mby5kZWx0YSwgZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChpbmZvLnR5cGUgPT09IE5hdmlnYXRpb25UeXBlLnBvcCAmJlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpc05hdmlnYXRpb25GYWlsdXJlKGZhaWx1cmUsIDQgLyogTkFWSUdBVElPTl9BQk9SVEVEICovIHwgMTYgLyogTkFWSUdBVElPTl9EVVBMSUNBVEVEICovKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBtYW51YWwgY2hhbmdlIGluIGhhc2ggaGlzdG9yeSAjOTE2XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGl0J3MgbGlrZSBhIHB1c2ggYnV0IGxhY2tzIHRoZSBpbmZvcm1hdGlvbiBvZiB0aGUgZGlyZWN0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJvdXRlckhpc3RvcnkuZ28oLTEsIGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0cmlnZ2VyQWZ0ZXJFYWNoKHRvTG9jYXRpb24sIGZyb20sIGZhaWx1cmUpO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgLmNhdGNoKG5vb3ApO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgLy8gSW5pdGlhbGl6YXRpb24gYW5kIEVycm9yc1xyXG4gICAgbGV0IHJlYWR5SGFuZGxlcnMgPSB1c2VDYWxsYmFja3MoKTtcclxuICAgIGxldCBlcnJvckhhbmRsZXJzID0gdXNlQ2FsbGJhY2tzKCk7XHJcbiAgICBsZXQgcmVhZHk7XHJcbiAgICAvKipcclxuICAgICAqIFRyaWdnZXIgZXJyb3JIYW5kbGVycyBhZGRlZCB2aWEgb25FcnJvciBhbmQgdGhyb3dzIHRoZSBlcnJvciBhcyB3ZWxsXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIGVycm9yIC0gZXJyb3IgdG8gdGhyb3dcclxuICAgICAqIEBwYXJhbSB0byAtIGxvY2F0aW9uIHdlIHdlcmUgbmF2aWdhdGluZyB0byB3aGVuIHRoZSBlcnJvciBoYXBwZW5lZFxyXG4gICAgICogQHBhcmFtIGZyb20gLSBsb2NhdGlvbiB3ZSB3ZXJlIG5hdmlnYXRpbmcgZnJvbSB3aGVuIHRoZSBlcnJvciBoYXBwZW5lZFxyXG4gICAgICogQHJldHVybnMgdGhlIGVycm9yIGFzIGEgcmVqZWN0ZWQgcHJvbWlzZVxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiB0cmlnZ2VyRXJyb3IoZXJyb3IsIHRvLCBmcm9tKSB7XHJcbiAgICAgICAgbWFya0FzUmVhZHkoZXJyb3IpO1xyXG4gICAgICAgIGNvbnN0IGxpc3QgPSBlcnJvckhhbmRsZXJzLmxpc3QoKTtcclxuICAgICAgICBpZiAobGlzdC5sZW5ndGgpIHtcclxuICAgICAgICAgICAgbGlzdC5mb3JFYWNoKGhhbmRsZXIgPT4gaGFuZGxlcihlcnJvciwgdG8sIGZyb20pKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICAgICAgICAgIHdhcm4oJ3VuY2F1Z2h0IGVycm9yIGR1cmluZyByb3V0ZSBuYXZpZ2F0aW9uOicpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyb3IpO1xyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gaXNSZWFkeSgpIHtcclxuICAgICAgICBpZiAocmVhZHkgJiYgY3VycmVudFJvdXRlLnZhbHVlICE9PSBTVEFSVF9MT0NBVElPTl9OT1JNQUxJWkVEKVxyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgICAgICAgcmVhZHlIYW5kbGVycy5hZGQoW3Jlc29sdmUsIHJlamVjdF0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBNYXJrIHRoZSByb3V0ZXIgYXMgcmVhZHksIHJlc29sdmluZyB0aGUgcHJvbWlzZWQgcmV0dXJuZWQgYnkgaXNSZWFkeSgpLiBDYW5cclxuICAgICAqIG9ubHkgYmUgY2FsbGVkIG9uY2UsIG90aGVyd2lzZSBkb2VzIG5vdGhpbmcuXHJcbiAgICAgKiBAcGFyYW0gZXJyIC0gb3B0aW9uYWwgZXJyb3JcclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gbWFya0FzUmVhZHkoZXJyKSB7XHJcbiAgICAgICAgaWYgKHJlYWR5KVxyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgcmVhZHkgPSB0cnVlO1xyXG4gICAgICAgIHNldHVwTGlzdGVuZXJzKCk7XHJcbiAgICAgICAgcmVhZHlIYW5kbGVyc1xyXG4gICAgICAgICAgICAubGlzdCgpXHJcbiAgICAgICAgICAgIC5mb3JFYWNoKChbcmVzb2x2ZSwgcmVqZWN0XSkgPT4gKGVyciA/IHJlamVjdChlcnIpIDogcmVzb2x2ZSgpKSk7XHJcbiAgICAgICAgcmVhZHlIYW5kbGVycy5yZXNldCgpO1xyXG4gICAgfVxyXG4gICAgLy8gU2Nyb2xsIGJlaGF2aW9yXHJcbiAgICBmdW5jdGlvbiBoYW5kbGVTY3JvbGwodG8sIGZyb20sIGlzUHVzaCwgaXNGaXJzdE5hdmlnYXRpb24pIHtcclxuICAgICAgICBjb25zdCB7IHNjcm9sbEJlaGF2aW9yIH0gPSBvcHRpb25zO1xyXG4gICAgICAgIGlmICghaXNCcm93c2VyIHx8ICFzY3JvbGxCZWhhdmlvcilcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgICAgIGNvbnN0IHNjcm9sbFBvc2l0aW9uID0gKCFpc1B1c2ggJiYgZ2V0U2F2ZWRTY3JvbGxQb3NpdGlvbihnZXRTY3JvbGxLZXkodG8uZnVsbFBhdGgsIDApKSkgfHxcclxuICAgICAgICAgICAgKChpc0ZpcnN0TmF2aWdhdGlvbiB8fCAhaXNQdXNoKSAmJlxyXG4gICAgICAgICAgICAgICAgaGlzdG9yeS5zdGF0ZSAmJlxyXG4gICAgICAgICAgICAgICAgaGlzdG9yeS5zdGF0ZS5zY3JvbGwpIHx8XHJcbiAgICAgICAgICAgIG51bGw7XHJcbiAgICAgICAgcmV0dXJuIG5leHRUaWNrKClcclxuICAgICAgICAgICAgLnRoZW4oKCkgPT4gc2Nyb2xsQmVoYXZpb3IodG8sIGZyb20sIHNjcm9sbFBvc2l0aW9uKSlcclxuICAgICAgICAgICAgLnRoZW4ocG9zaXRpb24gPT4gcG9zaXRpb24gJiYgc2Nyb2xsVG9Qb3NpdGlvbihwb3NpdGlvbikpXHJcbiAgICAgICAgICAgIC5jYXRjaChlcnIgPT4gdHJpZ2dlckVycm9yKGVyciwgdG8sIGZyb20pKTtcclxuICAgIH1cclxuICAgIGNvbnN0IGdvID0gKGRlbHRhKSA9PiByb3V0ZXJIaXN0b3J5LmdvKGRlbHRhKTtcclxuICAgIGxldCBzdGFydGVkO1xyXG4gICAgY29uc3QgaW5zdGFsbGVkQXBwcyA9IG5ldyBTZXQoKTtcclxuICAgIGNvbnN0IHJvdXRlciA9IHtcclxuICAgICAgICBjdXJyZW50Um91dGUsXHJcbiAgICAgICAgYWRkUm91dGUsXHJcbiAgICAgICAgcmVtb3ZlUm91dGUsXHJcbiAgICAgICAgaGFzUm91dGUsXHJcbiAgICAgICAgZ2V0Um91dGVzLFxyXG4gICAgICAgIHJlc29sdmUsXHJcbiAgICAgICAgb3B0aW9ucyxcclxuICAgICAgICBwdXNoLFxyXG4gICAgICAgIHJlcGxhY2UsXHJcbiAgICAgICAgZ28sXHJcbiAgICAgICAgYmFjazogKCkgPT4gZ28oLTEpLFxyXG4gICAgICAgIGZvcndhcmQ6ICgpID0+IGdvKDEpLFxyXG4gICAgICAgIGJlZm9yZUVhY2g6IGJlZm9yZUd1YXJkcy5hZGQsXHJcbiAgICAgICAgYmVmb3JlUmVzb2x2ZTogYmVmb3JlUmVzb2x2ZUd1YXJkcy5hZGQsXHJcbiAgICAgICAgYWZ0ZXJFYWNoOiBhZnRlckd1YXJkcy5hZGQsXHJcbiAgICAgICAgb25FcnJvcjogZXJyb3JIYW5kbGVycy5hZGQsXHJcbiAgICAgICAgaXNSZWFkeSxcclxuICAgICAgICBpbnN0YWxsKGFwcCkge1xyXG4gICAgICAgICAgICBjb25zdCByb3V0ZXIgPSB0aGlzO1xyXG4gICAgICAgICAgICBhcHAuY29tcG9uZW50KCdSb3V0ZXJMaW5rJywgUm91dGVyTGluayk7XHJcbiAgICAgICAgICAgIGFwcC5jb21wb25lbnQoJ1JvdXRlclZpZXcnLCBSb3V0ZXJWaWV3KTtcclxuICAgICAgICAgICAgYXBwLmNvbmZpZy5nbG9iYWxQcm9wZXJ0aWVzLiRyb3V0ZXIgPSByb3V0ZXI7XHJcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShhcHAuY29uZmlnLmdsb2JhbFByb3BlcnRpZXMsICckcm91dGUnLCB7XHJcbiAgICAgICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgZ2V0OiAoKSA9PiB1bnJlZihjdXJyZW50Um91dGUpLFxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgLy8gdGhpcyBpbml0aWFsIG5hdmlnYXRpb24gaXMgb25seSBuZWNlc3Nhcnkgb24gY2xpZW50LCBvbiBzZXJ2ZXIgaXQgZG9lc24ndFxyXG4gICAgICAgICAgICAvLyBtYWtlIHNlbnNlIGJlY2F1c2UgaXQgd2lsbCBjcmVhdGUgYW4gZXh0cmEgdW5uZWNlc3NhcnkgbmF2aWdhdGlvbiBhbmQgY291bGRcclxuICAgICAgICAgICAgLy8gbGVhZCB0byBwcm9ibGVtc1xyXG4gICAgICAgICAgICBpZiAoaXNCcm93c2VyICYmXHJcbiAgICAgICAgICAgICAgICAvLyB1c2VkIGZvciB0aGUgaW5pdGlhbCBuYXZpZ2F0aW9uIGNsaWVudCBzaWRlIHRvIGF2b2lkIHB1c2hpbmdcclxuICAgICAgICAgICAgICAgIC8vIG11bHRpcGxlIHRpbWVzIHdoZW4gdGhlIHJvdXRlciBpcyB1c2VkIGluIG11bHRpcGxlIGFwcHNcclxuICAgICAgICAgICAgICAgICFzdGFydGVkICYmXHJcbiAgICAgICAgICAgICAgICBjdXJyZW50Um91dGUudmFsdWUgPT09IFNUQVJUX0xPQ0FUSU9OX05PUk1BTElaRUQpIHtcclxuICAgICAgICAgICAgICAgIC8vIHNlZSBhYm92ZVxyXG4gICAgICAgICAgICAgICAgc3RhcnRlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICBwdXNoKHJvdXRlckhpc3RvcnkubG9jYXRpb24pLmNhdGNoKGVyciA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgd2FybignVW5leHBlY3RlZCBlcnJvciB3aGVuIHN0YXJ0aW5nIHRoZSByb3V0ZXI6JywgZXJyKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNvbnN0IHJlYWN0aXZlUm91dGUgPSB7fTtcclxuICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gU1RBUlRfTE9DQVRJT05fTk9STUFMSVpFRCkge1xyXG4gICAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvcjogdGhlIGtleSBtYXRjaGVzXHJcbiAgICAgICAgICAgICAgICByZWFjdGl2ZVJvdXRlW2tleV0gPSBjb21wdXRlZCgoKSA9PiBjdXJyZW50Um91dGUudmFsdWVba2V5XSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgYXBwLnByb3ZpZGUocm91dGVyS2V5LCByb3V0ZXIpO1xyXG4gICAgICAgICAgICBhcHAucHJvdmlkZShyb3V0ZUxvY2F0aW9uS2V5LCByZWFjdGl2ZShyZWFjdGl2ZVJvdXRlKSk7XHJcbiAgICAgICAgICAgIGFwcC5wcm92aWRlKHJvdXRlclZpZXdMb2NhdGlvbktleSwgY3VycmVudFJvdXRlKTtcclxuICAgICAgICAgICAgY29uc3QgdW5tb3VudEFwcCA9IGFwcC51bm1vdW50O1xyXG4gICAgICAgICAgICBpbnN0YWxsZWRBcHBzLmFkZChhcHApO1xyXG4gICAgICAgICAgICBhcHAudW5tb3VudCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIGluc3RhbGxlZEFwcHMuZGVsZXRlKGFwcCk7XHJcbiAgICAgICAgICAgICAgICAvLyB0aGUgcm91dGVyIGlzIG5vdCBhdHRhY2hlZCB0byBhbiBhcHAgYW55bW9yZVxyXG4gICAgICAgICAgICAgICAgaWYgKGluc3RhbGxlZEFwcHMuc2l6ZSA8IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBpbnZhbGlkYXRlIHRoZSBjdXJyZW50IG5hdmlnYXRpb25cclxuICAgICAgICAgICAgICAgICAgICBwZW5kaW5nTG9jYXRpb24gPSBTVEFSVF9MT0NBVElPTl9OT1JNQUxJWkVEO1xyXG4gICAgICAgICAgICAgICAgICAgIHJlbW92ZUhpc3RvcnlMaXN0ZW5lciAmJiByZW1vdmVIaXN0b3J5TGlzdGVuZXIoKTtcclxuICAgICAgICAgICAgICAgICAgICBjdXJyZW50Um91dGUudmFsdWUgPSBTVEFSVF9MT0NBVElPTl9OT1JNQUxJWkVEO1xyXG4gICAgICAgICAgICAgICAgICAgIHN0YXJ0ZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICByZWFkeSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdW5tb3VudEFwcCgpO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBpZiAoKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB8fCBfX1ZVRV9QUk9EX0RFVlRPT0xTX18pICYmIGlzQnJvd3Nlcikge1xyXG4gICAgICAgICAgICAgICAgYWRkRGV2dG9vbHMoYXBwLCByb3V0ZXIsIG1hdGNoZXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuICAgIH07XHJcbiAgICByZXR1cm4gcm91dGVyO1xyXG59XHJcbmZ1bmN0aW9uIHJ1bkd1YXJkUXVldWUoZ3VhcmRzKSB7XHJcbiAgICByZXR1cm4gZ3VhcmRzLnJlZHVjZSgocHJvbWlzZSwgZ3VhcmQpID0+IHByb21pc2UudGhlbigoKSA9PiBndWFyZCgpKSwgUHJvbWlzZS5yZXNvbHZlKCkpO1xyXG59XHJcbmZ1bmN0aW9uIGV4dHJhY3RDaGFuZ2luZ1JlY29yZHModG8sIGZyb20pIHtcclxuICAgIGNvbnN0IGxlYXZpbmdSZWNvcmRzID0gW107XHJcbiAgICBjb25zdCB1cGRhdGluZ1JlY29yZHMgPSBbXTtcclxuICAgIGNvbnN0IGVudGVyaW5nUmVjb3JkcyA9IFtdO1xyXG4gICAgY29uc3QgbGVuID0gTWF0aC5tYXgoZnJvbS5tYXRjaGVkLmxlbmd0aCwgdG8ubWF0Y2hlZC5sZW5ndGgpO1xyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgIGNvbnN0IHJlY29yZEZyb20gPSBmcm9tLm1hdGNoZWRbaV07XHJcbiAgICAgICAgaWYgKHJlY29yZEZyb20pIHtcclxuICAgICAgICAgICAgaWYgKHRvLm1hdGNoZWQuZmluZChyZWNvcmQgPT4gaXNTYW1lUm91dGVSZWNvcmQocmVjb3JkLCByZWNvcmRGcm9tKSkpXHJcbiAgICAgICAgICAgICAgICB1cGRhdGluZ1JlY29yZHMucHVzaChyZWNvcmRGcm9tKTtcclxuICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgbGVhdmluZ1JlY29yZHMucHVzaChyZWNvcmRGcm9tKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgcmVjb3JkVG8gPSB0by5tYXRjaGVkW2ldO1xyXG4gICAgICAgIGlmIChyZWNvcmRUbykge1xyXG4gICAgICAgICAgICAvLyB0aGUgdHlwZSBkb2Vzbid0IG1hdHRlciBiZWNhdXNlIHdlIGFyZSBjb21wYXJpbmcgcGVyIHJlZmVyZW5jZVxyXG4gICAgICAgICAgICBpZiAoIWZyb20ubWF0Y2hlZC5maW5kKHJlY29yZCA9PiBpc1NhbWVSb3V0ZVJlY29yZChyZWNvcmQsIHJlY29yZFRvKSkpIHtcclxuICAgICAgICAgICAgICAgIGVudGVyaW5nUmVjb3Jkcy5wdXNoKHJlY29yZFRvKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBbbGVhdmluZ1JlY29yZHMsIHVwZGF0aW5nUmVjb3JkcywgZW50ZXJpbmdSZWNvcmRzXTtcclxufVxuXG4vKipcclxuICogUmV0dXJucyB0aGUgcm91dGVyIGluc3RhbmNlLiBFcXVpdmFsZW50IHRvIHVzaW5nIGAkcm91dGVyYCBpbnNpZGVcclxuICogdGVtcGxhdGVzLlxyXG4gKi9cclxuZnVuY3Rpb24gdXNlUm91dGVyKCkge1xyXG4gICAgcmV0dXJuIGluamVjdChyb3V0ZXJLZXkpO1xyXG59XHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRoZSBjdXJyZW50IHJvdXRlIGxvY2F0aW9uLiBFcXVpdmFsZW50IHRvIHVzaW5nIGAkcm91dGVgIGluc2lkZVxyXG4gKiB0ZW1wbGF0ZXMuXHJcbiAqL1xyXG5mdW5jdGlvbiB1c2VSb3V0ZSgpIHtcclxuICAgIHJldHVybiBpbmplY3Qocm91dGVMb2NhdGlvbktleSk7XHJcbn1cblxuZXhwb3J0IHsgTmF2aWdhdGlvbkZhaWx1cmVUeXBlLCBSb3V0ZXJMaW5rLCBSb3V0ZXJWaWV3LCBTVEFSVF9MT0NBVElPTl9OT1JNQUxJWkVEIGFzIFNUQVJUX0xPQ0FUSU9OLCBjcmVhdGVNZW1vcnlIaXN0b3J5LCBjcmVhdGVSb3V0ZXIsIGNyZWF0ZVJvdXRlck1hdGNoZXIsIGNyZWF0ZVdlYkhhc2hIaXN0b3J5LCBjcmVhdGVXZWJIaXN0b3J5LCBpc05hdmlnYXRpb25GYWlsdXJlLCBtYXRjaGVkUm91dGVLZXksIG9uQmVmb3JlUm91dGVMZWF2ZSwgb25CZWZvcmVSb3V0ZVVwZGF0ZSwgcGFyc2VRdWVyeSwgcm91dGVMb2NhdGlvbktleSwgcm91dGVyS2V5LCByb3V0ZXJWaWV3TG9jYXRpb25LZXksIHN0cmluZ2lmeVF1ZXJ5LCB1c2VMaW5rLCB1c2VSb3V0ZSwgdXNlUm91dGVyLCB2aWV3RGVwdGhLZXkgfTtcbiIsIjx0ZW1wbGF0ZT5cbiAgICA8ZGl2IGlkPVwiY29udGVudENvbnRhaW5lclwiIGNsYXNzPVwiY29udGVudC1jb250YWluZXJcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImxvYWRpbmctdmlld1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInByb2dyZXNzLWJhci1kaXZcIj5cbiAgICAgICAgICAgICAgICA8cHJvZ3Jlc3MgY2xhc3M9XCJwcm9ncmVzcy1iYXJcIiBtYXg9XCIxMDBcIiB2YWx1ZT1cIjEwXCI+XG4gICAgICAgICAgICAgICAgICAgIDxzdHJvbmc+UHJvZ3Jlc3M6IDEwMCUgQ29tcGxldGUuPC9zdHJvbmc+XG4gICAgICAgICAgICAgICAgPC9wcm9ncmVzcz5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInByb2dyZXNzLWxhYmVsXCI+SW5pdGlhbGl6aW5nLi4uPC9zcGFuPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuPC90ZW1wbGF0ZT5cblxuPHNjcmlwdD5cblxuZXhwb3J0IGRlZmF1bHQge1xuICAgIG5hbWU6IFwiTGVnYWN5Vmlld1wiLFxuICAgIGNvbXBvbmVudHM6IHt9XG59O1xuPC9zY3JpcHQ+XG5cbjxzdHlsZT5cbjwvc3R5bGU+IiwiZXhwb3J0ICogZnJvbSBcIi0hLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvZGlzdC90ZW1wbGF0ZUxvYWRlci5qcz8/cnVsZVNldFsxXS5ydWxlc1sxXSEuLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9kaXN0L2luZGV4LmpzPz9ydWxlU2V0WzFdLnJ1bGVzWzZdLnVzZVswXSEuL0xlZ2FjeVZpZXcudnVlP3Z1ZSZ0eXBlPXRlbXBsYXRlJmlkPTM3NGJhNGE4XCIiLCJleHBvcnQgeyBkZWZhdWx0IH0gZnJvbSBcIi0hLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvZGlzdC9pbmRleC5qcz8/cnVsZVNldFsxXS5ydWxlc1s2XS51c2VbMF0hLi9MZWdhY3lWaWV3LnZ1ZT92dWUmdHlwZT1zY3JpcHQmbGFuZz1qc1wiOyBleHBvcnQgKiBmcm9tIFwiLSEuLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9kaXN0L2luZGV4LmpzPz9ydWxlU2V0WzFdLnJ1bGVzWzZdLnVzZVswXSEuL0xlZ2FjeVZpZXcudnVlP3Z1ZSZ0eXBlPXNjcmlwdCZsYW5nPWpzXCIiLCJpbXBvcnQgeyByZW5kZXIgfSBmcm9tIFwiLi9MZWdhY3lWaWV3LnZ1ZT92dWUmdHlwZT10ZW1wbGF0ZSZpZD0zNzRiYTRhOFwiXG5pbXBvcnQgc2NyaXB0IGZyb20gXCIuL0xlZ2FjeVZpZXcudnVlP3Z1ZSZ0eXBlPXNjcmlwdCZsYW5nPWpzXCJcbmV4cG9ydCAqIGZyb20gXCIuL0xlZ2FjeVZpZXcudnVlP3Z1ZSZ0eXBlPXNjcmlwdCZsYW5nPWpzXCJcblxuaW1wb3J0IGV4cG9ydENvbXBvbmVudCBmcm9tIFwiL2hvbWUvbWlrZWIvdGltZXRyZXgvdHJ1bmsvbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvZGlzdC9leHBvcnRIZWxwZXIuanNcIlxuY29uc3QgX19leHBvcnRzX18gPSAvKiNfX1BVUkVfXyovZXhwb3J0Q29tcG9uZW50KHNjcmlwdCwgW1sncmVuZGVyJyxyZW5kZXJdXSlcblxuZXhwb3J0IGRlZmF1bHQgX19leHBvcnRzX18iLCIvLyBpbXBvcnQgeyBjcmVhdGVSb3V0ZXIsIGNyZWF0ZVdlYkhpc3RvcnkgfSBmcm9tICd2dWUtcm91dGVyJ1xuaW1wb3J0IHsgY3JlYXRlUm91dGVyLCBjcmVhdGVNZW1vcnlIaXN0b3J5IH0gZnJvbSAndnVlLXJvdXRlcidcblxuaW1wb3J0IExlZ2FjeVZpZXcgZnJvbSAnQC9jb21wb25lbnRzL0xlZ2FjeVZpZXcnO1xuLy8gaW1wb3J0IFJlcG9ydFZpZXcgZnJvbSAnQC9jb21wb25lbnRzL1JlcG9ydFZpZXcnO1xuXG5jb25zdCBsYXp5X2xvYWRfdGVzdCA9ICgpID0+IGltcG9ydCgvKiB3ZWJwYWNrQ2h1bmtOYW1lOiBcImR5bmFtaWMtdGVzdHZpZXdcIiAqLydAL2NvbXBvbmVudHMvVFRUZXN0VmlldycpOyAvLyAjVlVFVEVTVFxuXG4vLyBDYW4gYWxzbyBpbXBvcnQgdGhpcyBmcm9tIGFub3RoZXIgZmlsZS5cbmNvbnN0IHJvdXRlcyA9IFtcblx0eyBwYXRoOiAnL3Rlc3QnLCBuYW1lOiAndGVzdCcsIGNvbXBvbmVudDogbGF6eV9sb2FkX3Rlc3QsIHByb3BzOnRydWUgfSwgLy8gI1ZVRVRFU1QgTGF6eSBsb2FkZWQsIHNvIG5vdCBsb2FkZWQgbm9ybWFsbHkuIE9ubHkgd2hlbiB1c2VkIHdpdGggYFZ1ZVJvdXRlci5wdXNoKCd0ZXN0JylgIG9yIHZpYSBkZXYgdG9vbHMuXG5cdC8vIHsgcGF0aDogJy92aWV3Lzp2aWV3SWQnLCBuYW1lOiAndmlldycsIGNvbXBvbmVudDogTGVnYWN5VmlldywgcHJvcHM6dHJ1ZSB9LFxuXHQvLyB7IHBhdGg6ICcvcmVwb3J0Lzp2aWV3SWQnLCBuYW1lOiAncmVwb3J0JywgY29tcG9uZW50OiBSZXBvcnRWaWV3LCBwcm9wczp0cnVlIH0sXG5cdC8vIHsgcGF0aDogJy9yZXBvcnQvOnJlcG9ydElkJywgbmFtZTogJ3JlcG9ydCcsIGNvbXBvbmVudDogTGVnYWN5VmlldyB9LFxuXHQvLyB7IHBhdGg6ICcvd2l6YXJkLzp3aXphcmRJZCcsIG5hbWU6ICd3aXphcmQnLCBjb21wb25lbnQ6IExlZ2FjeVZpZXcgfSxcblx0eyBwYXRoOiAnLzpwYXRoTWF0Y2goLiopKicsIG5hbWU6ICdjYXRjaC1hbGwnLCBjb21wb25lbnQ6IExlZ2FjeVZpZXcgfSxcblx0Ly8geyBwYXRoOiAnLyMhbT1Mb2dpbicsIG5hbWU6ICdub3QtZm91bmQnLCBjb21wb25lbnQ6IExlZ2FjeVZpZXcgfSxcblx0Ly8geyBwYXRoOiAnLyMhbT06dmlld0lkJio6cmVzdE9mKC4qKScsIG5hbWU6ICdub3QtZm91bmQnLCBjb21wb25lbnQ6IExlZ2FjeVZpZXcgfSxcblxuXTtcblxuY29uc3QgbWFpbl91aV9yb3V0ZXIgPSBjcmVhdGVSb3V0ZXIoe1xuXHQvLyBoaXN0b3J5OiBjcmVhdGVXZWJIaXN0b3J5KCksXG5cdGhpc3Rvcnk6IGNyZWF0ZU1lbW9yeUhpc3RvcnkoKSxcblx0cm91dGVzLFxufSk7XG5cbmV4cG9ydCBkZWZhdWx0IG1haW5fdWlfcm91dGVyO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2237\n")},6378:(__unused_webpack_module,__unused_webpack_exports,__webpack_require__)=>{eval("/* provided dependency */ var jQuery = __webpack_require__(9755);\n/*!\n * jQuery i18n plugin\n * @requires jQuery v1.1 or later\n *\n * See https://github.com/recurser/jquery-i18n\n *\n * Licensed under the MIT license.\n *\n * Version: <%= pkg.version %> (<%= meta.date %>)\n */\n(function($) {\n\t/**\n\t * i18n provides a mechanism for translating strings using a jscript dictionary.\n\t *\n\t */\n\n\tvar __slice = Array.prototype.slice;\n\n\t/*\n\t * i18n property list\n\t */\n\tvar i18n = {\n\n\t\tdict: null,\n\t\tmissingPattern: null,\n\n\t\t/**\n\t\t * load()\n\t\t *\n\t\t * Load translations.\n\t\t *\n\t\t * @param property_list i18nDict : The dictionary to use for translation.\n\t\t */\n\t\tload: function(i18nDict, missingPattern) {\n\t\t\tif (this.dict !== null) {\n\t\t\t\t$.extend(this.dict, i18nDict);\n\t\t\t} else {\n\t\t\t\tthis.dict = i18nDict;\n\t\t\t}\n\n\t\t\tif (missingPattern) {\n\t\t\t\tthis.missingPattern = missingPattern;\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * unload()\n\t\t *\n\t\t * Unloads translations and clears the dictionary.\n\t\t */\n\t\tunload: function() {\n\t\t\tthis.dict = null;\n\t\t\tthis.missingPattern = null;\n\t\t},\n\n\t\t/**\n\t\t * _()\n\t\t *\n\t\t * Looks the given string up in the dictionary and returns the translation if\n\t\t * one exists. If a translation is not found, returns the original word.\n\t\t *\n\t\t * @param string str : The string to translate.\n\t\t * @param property_list params.. : params for using printf() on the string.\n\t\t *\n\t\t * @return string : Translated word.\n\t\t */\n\t\t_: function (str) {\n\t\t\tdict = this.dict;\n\t\t\tif (dict && dict.hasOwnProperty(str)) {\n\t\t\t\tstr = dict[str];\n\t\t\t} else if (this.missingPattern !== null) {\n\t\t\t\treturn this.printf(this.missingPattern, str);\n\t\t\t}\n\t\t\tvar args = __slice.call(arguments);\n\t\t\targs[0] = str;\n\t\t\t// Substitute any params.\n\t\t\treturn this.printf.apply(this, args);\n\t\t},\n\n\t\t/*\n\t\t * printf()\n\t\t *\n\t\t * Substitutes %s with parameters given in list. %%s is used to escape %s.\n\t\t *\n\t\t * @param string str : String to perform printf on.\n\t\t * @param string args : Array of arguments for printf.\n\t\t *\n\t\t * @return string result : Substituted string\n\t\t */\n\t\tprintf: function(str, args) {\n\t\t\tif (arguments.length < 2) return str;\n\t\t\tvar args = $.isArray(args) ? args : __slice.call(arguments, 1);\n\t\t\treturn str.replace(/([^%]|^)%(?:(\\d+)\\$)?s/g, function(p0, p, position) {\n\t\t\t\tif (position) {\n\t\t\t\t\treturn p + args[parseInt(position)-1];\n\t\t\t\t}\n\t\t\t\treturn p + args.shift();\n\t\t\t}).replace(/%%s/g, '%s');\n\t\t}\n\n\t};\n\n\t/*\n\t * _t()\n\t *\n\t * Allows you to translate a jQuery selector.\n\t *\n\t * eg $('h1')._t('some text')\n\t *\n\t * @param string str : The string to translate .\n\t * @param property_list params : Params for using printf() on the string.\n\t *\n\t * @return element : Chained and translated element(s).\n\t*/\n\t$.fn._t = function(str, params) {\n\t\treturn $(this).html(i18n._.apply(i18n, arguments));\n\t};\n\n\t$.i18n = i18n;\n})(jQuery);//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjM3OC5qcyIsIm1hcHBpbmdzIjoiO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDLEVBQUUsTUFBTSIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL2ludGVyZmFjZS9odG1sNS9mcmFtZXdvcmsvanF1ZXJ5LmkxOG4uanM/OTAzNiJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiFcbiAqIGpRdWVyeSBpMThuIHBsdWdpblxuICogQHJlcXVpcmVzIGpRdWVyeSB2MS4xIG9yIGxhdGVyXG4gKlxuICogU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9yZWN1cnNlci9qcXVlcnktaTE4blxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZS5cbiAqXG4gKiBWZXJzaW9uOiA8JT0gcGtnLnZlcnNpb24gJT4gKDwlPSBtZXRhLmRhdGUgJT4pXG4gKi9cbihmdW5jdGlvbigkKSB7XG5cdC8qKlxuXHQgKiBpMThuIHByb3ZpZGVzIGEgbWVjaGFuaXNtIGZvciB0cmFuc2xhdGluZyBzdHJpbmdzIHVzaW5nIGEganNjcmlwdCBkaWN0aW9uYXJ5LlxuXHQgKlxuXHQgKi9cblxuXHR2YXIgX19zbGljZSA9IEFycmF5LnByb3RvdHlwZS5zbGljZTtcblxuXHQvKlxuXHQgKiBpMThuIHByb3BlcnR5IGxpc3Rcblx0ICovXG5cdHZhciBpMThuID0ge1xuXG5cdFx0ZGljdDogbnVsbCxcblx0XHRtaXNzaW5nUGF0dGVybjogbnVsbCxcblxuXHRcdC8qKlxuXHRcdCAqIGxvYWQoKVxuXHRcdCAqXG5cdFx0ICogTG9hZCB0cmFuc2xhdGlvbnMuXG5cdFx0ICpcblx0XHQgKiBAcGFyYW0gIHByb3BlcnR5X2xpc3QgaTE4bkRpY3QgOiBUaGUgZGljdGlvbmFyeSB0byB1c2UgZm9yIHRyYW5zbGF0aW9uLlxuXHRcdCAqL1xuXHRcdGxvYWQ6IGZ1bmN0aW9uKGkxOG5EaWN0LCBtaXNzaW5nUGF0dGVybikge1xuXHRcdFx0aWYgKHRoaXMuZGljdCAhPT0gbnVsbCkge1xuXHRcdFx0XHQkLmV4dGVuZCh0aGlzLmRpY3QsIGkxOG5EaWN0KTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRoaXMuZGljdCA9IGkxOG5EaWN0O1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAobWlzc2luZ1BhdHRlcm4pIHtcblx0XHRcdFx0dGhpcy5taXNzaW5nUGF0dGVybiA9IG1pc3NpbmdQYXR0ZXJuO1xuXHRcdFx0fVxuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiB1bmxvYWQoKVxuXHRcdCAqXG5cdFx0ICogVW5sb2FkcyB0cmFuc2xhdGlvbnMgYW5kIGNsZWFycyB0aGUgZGljdGlvbmFyeS5cblx0XHQgKi9cblx0XHR1bmxvYWQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dGhpcy5kaWN0ICAgICAgICAgICA9IG51bGw7XG5cdFx0XHR0aGlzLm1pc3NpbmdQYXR0ZXJuID0gbnVsbDtcblx0XHR9LFxuXG5cdFx0LyoqXG5cdFx0ICogXygpXG5cdFx0ICpcblx0XHQgKiBMb29rcyB0aGUgZ2l2ZW4gc3RyaW5nIHVwIGluIHRoZSBkaWN0aW9uYXJ5IGFuZCByZXR1cm5zIHRoZSB0cmFuc2xhdGlvbiBpZlxuXHRcdCAqIG9uZSBleGlzdHMuIElmIGEgdHJhbnNsYXRpb24gaXMgbm90IGZvdW5kLCByZXR1cm5zIHRoZSBvcmlnaW5hbCB3b3JkLlxuXHRcdCAqXG5cdFx0ICogQHBhcmFtICBzdHJpbmcgc3RyICAgICAgICAgICA6IFRoZSBzdHJpbmcgdG8gdHJhbnNsYXRlLlxuXHRcdCAqIEBwYXJhbSAgcHJvcGVydHlfbGlzdCBwYXJhbXMuLiA6IHBhcmFtcyBmb3IgdXNpbmcgcHJpbnRmKCkgb24gdGhlIHN0cmluZy5cblx0XHQgKlxuXHRcdCAqIEByZXR1cm4gc3RyaW5nICAgICAgICAgICAgICAgOiBUcmFuc2xhdGVkIHdvcmQuXG5cdFx0ICovXG5cdFx0XzogZnVuY3Rpb24gKHN0cikge1xuXHRcdFx0ZGljdCA9IHRoaXMuZGljdDtcblx0XHRcdGlmIChkaWN0ICYmIGRpY3QuaGFzT3duUHJvcGVydHkoc3RyKSkge1xuXHRcdFx0XHRzdHIgPSBkaWN0W3N0cl07XG5cdFx0XHR9IGVsc2UgaWYgKHRoaXMubWlzc2luZ1BhdHRlcm4gIT09IG51bGwpIHtcblx0XHRcdFx0cmV0dXJuIHRoaXMucHJpbnRmKHRoaXMubWlzc2luZ1BhdHRlcm4sIHN0cik7XG5cdFx0XHR9XG5cdFx0XHR2YXIgYXJncyA9IF9fc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuXHRcdFx0YXJnc1swXSA9IHN0cjtcblx0XHRcdC8vIFN1YnN0aXR1dGUgYW55IHBhcmFtcy5cblx0XHRcdHJldHVybiB0aGlzLnByaW50Zi5hcHBseSh0aGlzLCBhcmdzKTtcblx0XHR9LFxuXG5cdFx0Lypcblx0XHQgKiBwcmludGYoKVxuXHRcdCAqXG5cdFx0ICogU3Vic3RpdHV0ZXMgJXMgd2l0aCBwYXJhbWV0ZXJzIGdpdmVuIGluIGxpc3QuICUlcyBpcyB1c2VkIHRvIGVzY2FwZSAlcy5cblx0XHQgKlxuXHRcdCAqIEBwYXJhbSAgc3RyaW5nIHN0ciAgICA6IFN0cmluZyB0byBwZXJmb3JtIHByaW50ZiBvbi5cblx0XHQgKiBAcGFyYW0gIHN0cmluZyBhcmdzICAgOiBBcnJheSBvZiBhcmd1bWVudHMgZm9yIHByaW50Zi5cblx0XHQgKlxuXHRcdCAqIEByZXR1cm4gc3RyaW5nIHJlc3VsdCA6IFN1YnN0aXR1dGVkIHN0cmluZ1xuXHRcdCAqL1xuXHRcdHByaW50ZjogZnVuY3Rpb24oc3RyLCBhcmdzKSB7XG5cdFx0XHRpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDIpIHJldHVybiBzdHI7XG5cdFx0XHR2YXIgYXJncyA9ICQuaXNBcnJheShhcmdzKSA/IGFyZ3MgOiBfX3NsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcblx0XHRcdHJldHVybiBzdHIucmVwbGFjZSgvKFteJV18XiklKD86KFxcZCspXFwkKT9zL2csIGZ1bmN0aW9uKHAwLCBwLCBwb3NpdGlvbikge1xuXHRcdFx0XHRpZiAocG9zaXRpb24pIHtcblx0XHRcdFx0XHRyZXR1cm4gcCArIGFyZ3NbcGFyc2VJbnQocG9zaXRpb24pLTFdO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBwICsgYXJncy5zaGlmdCgpO1xuXHRcdFx0fSkucmVwbGFjZSgvJSVzL2csICclcycpO1xuXHRcdH1cblxuXHR9O1xuXG5cdC8qXG5cdCAqIF90KClcblx0ICpcblx0ICogQWxsb3dzIHlvdSB0byB0cmFuc2xhdGUgYSBqUXVlcnkgc2VsZWN0b3IuXG5cdCAqXG5cdCAqIGVnICQoJ2gxJykuX3QoJ3NvbWUgdGV4dCcpXG5cdCAqXG5cdCAqIEBwYXJhbSAgc3RyaW5nIHN0ciAgICAgICAgICAgOiBUaGUgc3RyaW5nIHRvIHRyYW5zbGF0ZSAuXG5cdCAqIEBwYXJhbSAgcHJvcGVydHlfbGlzdCBwYXJhbXMgOiBQYXJhbXMgZm9yIHVzaW5nIHByaW50ZigpIG9uIHRoZSBzdHJpbmcuXG5cdCAqXG5cdCAqIEByZXR1cm4gZWxlbWVudCAgICAgICAgICAgICAgOiBDaGFpbmVkIGFuZCB0cmFuc2xhdGVkIGVsZW1lbnQocykuXG5cdCovXG5cdCQuZm4uX3QgPSBmdW5jdGlvbihzdHIsIHBhcmFtcykge1xuXHRcdHJldHVybiAkKHRoaXMpLmh0bWwoaTE4bi5fLmFwcGx5KGkxOG4sIGFyZ3VtZW50cykpO1xuXHR9O1xuXG5cdCQuaTE4biA9IGkxOG47XG59KShqUXVlcnkpOyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///6378\n")},9490:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval("/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"x\": () => (/* binding */ Global)\n/* harmony export */ });\n/* harmony import */ var _global_TTUUID__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4936);\n/* harmony import */ var _services_TimeTrexClientAPI__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7526);\n/* harmony import */ var _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2548);\n/* harmony import */ var _global_RateLimit__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(7046);\n/* harmony import */ var _global_widgets_view_min_tab_ViewMinTabBar__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(8287);\n/* harmony import */ var _global_widgets_view_min_tab_ViewMinTabBar__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_global_widgets_view_min_tab_ViewMinTabBar__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var _services_ServiceCaller__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(12);\n/* harmony import */ var _services_TTEventBus__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(7967);\n/* harmony import */ var _services_HtmlTemplates__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(4578);\n/* harmony import */ var _services_TTVueUtils__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(4966);\n/* harmony import */ var _components_login_TTMultiFactorAuthentication__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(7024);\n/* provided dependency */ var $ = __webpack_require__(9755);\n/* provided dependency */ var _ = __webpack_require__(9050);\n/* provided dependency */ var jQuery = __webpack_require__(9755);\n// import { LocalCacheData } from 'exports-loader?exports=LocalCacheData!@/global/LocalCacheData';\n\n\n // TODO: duplicated in merged js files.\n\n\n\n\n\n\n\n// import { createApp } from 'vue'; // Currently only used by Global.initEditTest\n// import TTEditView from '@/components/TTEditView'; // Used by Global.initEditTest which is currently commented out as its for testing only.\n\n//Global variables and functions will be used everywhere\nvar Global = function() {\n};\nGlobal.event_bus = new _services_TTEventBus__WEBPACK_IMPORTED_MODULE_6__/* [\"default\"] */ .Z({ view_id: 'global' });\nGlobal.sortOrderRegex = /^-([0-9]{3,9})-/;\nGlobal.current_ping = -1;\n\nGlobal.UNIT_TEST_MODE = false;\n\nGlobal.app_min_width = 990;\n\nGlobal.theme = 'default';\n\n/**\n * UIReadyStatus:\n * 0 - Global.setUINotready() - the UI is not ready\n * 1 - Global.setUIReady() - the overlay is out of the way but ui is not done rendering\n * 2 - Global.setUIInitComplete() the overlay is done rendering\n */\nGlobal.UIReadyStatus = 0;\n\nGlobal.signal_timer = null;\n\nGlobal.isScrolledIntoView = function( elem ) {\n\tvar $elem = elem;\n\tvar $window = $( window );\n\tvar docViewTop = $window.scrollTop();\n\tvar docViewBottom = docViewTop + $window.height();\n\tif ( !$elem.offset() ) {\n\t\treturn true;\n\t}\n\tvar elemTop = $elem.offset().top;\n\t//var elemBottom = elemTop + $elem.height();\n\t//((elemBottom <= (docViewBottom + 200)) && (elemTop >= docViewTop));\n\treturn elemTop < docViewBottom;\n};\n\n//Check if the DOM (not jQuery) element requires a vertical scrollbar.\nGlobal.isVerticalScrollBarRequired = function( element ) {\n\treturn element && element.scrollHeight > element.clientHeight;\n};\n\n//Check if the DOM (not jQuery) element requires a horizontal scrollbar.\nGlobal.isHorizontalScrollBarRequired = function( element ) {\n\treturn element && element.scrollWidth > element.clientWidth;\n};\n\n//Gets the width of the browsers scrollbar. This value depends on the users OS/browser.\nGlobal.getScrollbarWidth = function() {\n\tif ( LocalCacheData.getScrollbarWidth() > 0 ) {\n return LocalCacheData.getScrollbarWidth();\n }\n\n\tlet scroll_div = document.createElement(\"div\");\n\tscroll_div.style.visibility = 'hidden';\n\tscroll_div.style.overflow = 'scroll';\n\tdocument.body.appendChild(scroll_div);\n\tlet scroll_bar_width = scroll_div.offsetWidth - scroll_div.clientWidth;\n\tdocument.body.removeChild(scroll_div);\n\n\t//If for some reason we cannot get the width, default the width to 17 which is most common value. (Windows\n\tif ( !scroll_bar_width ) {\n scroll_bar_width = 17;\n }\n\n\tLocalCacheData.setScrollBarWidth( scroll_bar_width );\n\n\treturn scroll_bar_width;\n}\n\n//Gets the height of the browsers scrollbar. This value depends on the users OS/browser.\nGlobal.getScrollbarHeight = function() {\n\tif ( LocalCacheData.getScrollbarHeight() > 0 ) {\n\t\treturn LocalCacheData.getScrollbarHeight();\n\t}\n\n\tlet scroll_div = document.createElement(\"div\");\n\tscroll_div.style.visibility = 'hidden';\n\tscroll_div.style.overflow = 'scroll';\n\tdocument.body.appendChild(scroll_div);\n\tlet scroll_bar_height = scroll_div.offsetHeight - scroll_div.clientHeight;\n\tdocument.body.removeChild(scroll_div);\n\n\t//If for some reason we cannot get the height, default the height to 17 which is most common value. (Windows\n\tif ( !scroll_bar_height ) {\n\t\tscroll_bar_height = 17;\n }\n\n\tLocalCacheData.setScrollBarHeight( scroll_bar_height );\n\n\treturn scroll_bar_height;\n}\n\nGlobal.KEYCODES = {\n\t'48': '0',\n\t'49': '1',\n\t'50': '2',\n\t'51': '3',\n\t'52': '4',\n\t'53': '5',\n\t'54': '6',\n\t'55': '7',\n\t'56': '8',\n\t'59': '9',\n\t'65': 'a',\n\t'66': 'b',\n\t'67': 'c',\n\t'68': 'd',\n\t'69': 'e',\n\t'70': 'f',\n\t'71': 'g',\n\t'72': 'h',\n\t'73': 'i',\n\t'74': 'j',\n\t'75': 'k',\n\t'76': 'l',\n\t'77': 'm',\n\t'78': 'n',\n\t'79': 'o',\n\t'80': 'p',\n\t'81': 'q',\n\t'82': 'r',\n\t'83': 's',\n\t'84': 't',\n\t'85': 'u',\n\t'86': 'v',\n\t'87': 'w',\n\t'88': 'x',\n\t'89': 'y',\n\t'90': 'z'\n};\n\nGlobal.needReloadBrowser = false; // Need reload browser after set new cookie. To make router work for new session.\n\n// this attribute use to block UI in speical case that we allow users to click part of them and block other parts.\n// For example, when open edit view to block context menu.\nGlobal.block_ui = false;\n\nGlobal.sendErrorReport = function() {\n\tvar error_string = arguments[0];\n\tvar from_file = arguments[1];\n\tvar line = arguments[2];\n\tvar col = arguments[3];\n\tvar error_obj = arguments[4]; //Error object.\n\n\t_global_RateLimit__WEBPACK_IMPORTED_MODULE_3__/* .RateLimit.setID */ .b.setID( 'sendErrorReport' );\n\t_global_RateLimit__WEBPACK_IMPORTED_MODULE_3__/* .RateLimit.setAllowedCalls */ .b.setAllowedCalls( 6 );\n\t_global_RateLimit__WEBPACK_IMPORTED_MODULE_3__/* .RateLimit.setTimeFrame */ .b.setTimeFrame( 7200 ); //2hrs\n\n\tif ( _global_RateLimit__WEBPACK_IMPORTED_MODULE_3__/* .RateLimit.check */ .b.check() ) {\n\t\tvar captureScreenShot = function( error_msg, error_obj ) {\n\t\t\tif ( Global.isCanvasSupported() && typeof Promise !== 'undefined' ) { //HTML2Canvas requires promises, which IE11 does not have.\n\t\t\t\thtml2canvas( document.body ).then( function( canvas ) {\n\t\t\t\t\tvar image_string = canvas.toDataURL().split( ',' )[1];\n\t\t\t\t\tsourceMapStackTrace( error_msg, error_obj, image_string );\n\t\t\t\t} );\n\t\t\t} else {\n\t\t\t\tsourceMapStackTrace( error_msg, error_obj, null );\n\t\t\t}\n\t\t};\n\n\t\tvar sourceMapStackTrace = function( error_msg, error_obj, image_string ) {\n\t\t\tif ( error_obj ) {\n\t\t\t\tvar stacktrace_callback = function( stackframes, error_msg, error_obj, image_string ) {\n\t\t\t\t\tvar stringified_stack = stackframes.map( function( sf ) {\n\t\t\t\t\t\treturn ' ' + sf.toString(); //Indent stack trace.\n\t\t\t\t\t} ).join( '\\n' );\n\n\t\t\t\t\terror_msg = error_msg + '\\n\\n\\n' + 'Stack Trace (Mapped): \\n' + error_obj.name + ': ' + error_obj.message + '\\n' + stringified_stack;\n\t\t\t\t\terror_msg = error_msg + '\\n\\n\\n' + 'Stack Trace (Raw): \\n' + error_obj.stack;\n\n\t\t\t\t\tsendErrorReport( error_msg, error_obj, image_string );\n\t\t\t\t};\n\n\t\t\t\tvar stacktrace_errback = function( error_msg, error_obj, image_string ) {\n\t\t\t\t\tconsole.error( 'ERROR: Unable to source map stack trace!' );\n\t\t\t\t\tsendErrorReport( error_msg, error_obj, image_string );\n\t\t\t\t};\n\n\t\t\t\tStackTrace.fromError( error_obj ).then( stackframes => stacktrace_callback( stackframes, error_msg, error_obj, image_string ) ).catch( error => stacktrace_errback( error_msg, error_obj, image_string ) );\n\t\t\t} else {\n\t\t\t\tsendErrorReport( error_msg, error_obj, image_string );\n\t\t\t}\n\t\t};\n\n\t\tvar sendErrorReport = function( error_msg, error_obj, image_string ) {\n\t\t\tDebug.Text( 'ERROR: ' + error_msg, 'Global.js', '', 'sendErrorReport', 1 );\n\n\t\t\tvar api_authentication = _services_TimeTrexClientAPI__WEBPACK_IMPORTED_MODULE_1__/* .TTAPI.APIAuthentication */ .y.APIAuthentication;\n\t\t\tapi_authentication.sendErrorReport( error_msg, image_string, {\n\t\t\t\tonResult: function( result ) {\n\t\t\t\t\tif ( !Global.dont_check_browser_cache && APIGlobal.pre_login_data.production === true && result.getResult() !== APIGlobal.pre_login_data.application_build ) {\n\t\t\t\t\t\tresult = result.getResult();\n\t\t\t\t\t\tvar message = $.i18n._( 'Your web browser is caching incorrect data, please press the refresh button on your web browser or log out, clear your web browsers cache and try logging in again.' ) + '
' + $.i18n._( 'Local Version' ) + ': ' + result + ' ' + $.i18n._( 'Remote Version' ) + ': ' + APIGlobal.pre_login_data.application_build;\n\t\t\t\t\t\tGlobal.dont_check_browser_cache = true;\n\t\t\t\t\t\tGlobal.sendErrorReport( 'Your web browser is caching incorrect data. Local Version' + ': ' + result + ' Remote Version' + ': ' + APIGlobal.pre_login_data.application_build, _services_ServiceCaller__WEBPACK_IMPORTED_MODULE_5__/* .ServiceCaller.root_url */ .n.root_url, '', '', '' );\n\n\t\t\t\t\t\tvar timeout_handler = window.setTimeout( function() {\n\t\t\t\t\t\t\twindow.location.reload( true );\n\t\t\t\t\t\t}, 120000 );\n\n\t\t\t\t\t\tTAlertManager.showAlert( message, '', function() {\n\t\t\t\t\t\t\tLocalCacheData.loadedScriptNames = {};\n\t\t\t\t\t\t\tDebug.Text( 'Incorrect cache... Forcing reload after JS exception...', 'Global.js', 'Global', 'cachingIncorrectData', 10 );\n\t\t\t\t\t\t\twindow.clearTimeout( timeout_handler );\n\t\t\t\t\t\t\twindow.location.reload( true );\n\t\t\t\t\t\t} );\n\t\t\t\t\t} else if ( Global.dont_check_browser_cache ) {\n\t\t\t\t\t\tGlobal.dont_check_browser_cache = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\t\t};\n\n\t\tvar login_user = LocalCacheData.getLoginUser();\n\n\t\t/*\n\t\t * JavaScript exception ignore list\n\t\t */\n\t\tif ( from_file && typeof from_file == 'string' && from_file.indexOf( 'extension://' ) >= 0 ) { //Error happened in some Chrome Extension, ignore.\n\t\t\tconsole.error( 'Ignoring javascript exception from browser extension outside of our control...' );\n\t\t\treturn;\n\t\t}\n\n\t\tif ( error_string.indexOf( 'Script error' ) >= 0 || //Script error. in: line: 0 -- Likely browser extensions or errors from injected or outside javascript.\n\t\t\terror_string.indexOf( 'Unspecified error' ) >= 0 || //From IE: Unspecified error. in N/A line 1\n\t\t\terror_string.indexOf( 'TypeError: \\'null\\' is not an object' ) >= 0 ||\n\t\t\terror_string.indexOf( '_avast_submit' ) >= 0 || //Errors from anti-virus extension\n\t\t\terror_string.indexOf( 'ResizeObserver loop limit exceeded' ) >= 0 ||\n\t\t\terror_string.indexOf( 'googletag' ) >= 0 || //Errors from google tag extension -- Uncaught TypeError: Cannot redefine property: googletag\n\t\t\terror_string.indexOf( 'NS_ERROR_' ) >= 0 ||\n\t\t\terror_string.indexOf( 'NS_ERROR_OUT_OF_MEMORY' ) >= 0 ||\n\t\t\terror_string.indexOf( 'NPObject' ) >= 0 ) { //Error calling method on NPObject - likely caused by an extension or plugin in the browser\n\t\t\tconsole.error( 'Ignoring javascript exception outside of our control...' );\n\t\t\treturn;\n\t\t}\n\n\t\tif ( Global.idle_time > 15 ) {\n\t\t\tDebug.Text( 'User inactive more than 15 mins, not sending error report.', 'Global.js', '', 'sendErrorReport', 1 );\n\t\t\tif ( typeof ( gtag ) !== 'undefined' && APIGlobal.pre_login_data.analytics_enabled === true ) {\n\t\t\t\tgtag( 'event', 'exception', {\n\t\t\t\t\t'exDescription': 'Session Idle: ' + error_string + ' File: ' + ( ( from_file ) ? from_file.replace( Global.getBaseURL(), '' ) : 'N/A' ) + ' Line: ' + line,\n\t\t\t\t\t'exFatal': false\n\t\t\t\t} )\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tvar error;\n\n\t\t//BUG#2066 - allow this function to be called earlier.\n\t\tvar script_name = '~unknown~';\n\t\tif ( Global.isSet( LocalCacheData ) && Global.isSet( LocalCacheData.current_open_primary_controller ) && Global.isSet( LocalCacheData.current_open_primary_controller.script_name ) ) {\n\t\t\tscript_name = LocalCacheData.current_open_primary_controller.script_name;\n\t\t}\n\n\t\tvar pre_login_data;\n\t\tif ( APIGlobal.pre_login_data ) {\n\t\t\tpre_login_data = APIGlobal.pre_login_data;\n\t\t} else {\n\t\t\tpre_login_data = null;\n\t\t}\n\n\t\tvar current_company_obj;\n\t\tif ( Global.isSet( LocalCacheData ) && LocalCacheData['current_company'] ) { //getCurrentCompany() which in turn calls getRequiredLocalCache(), which can call sendErroReport causing a loop. So try to prevent that by checking LocalCacheData['current_company'] first.\n\t\t\tcurrent_company_obj = LocalCacheData.getCurrentCompany();\n\t\t} else {\n\t\t\tcurrent_company_obj = null;\n\t\t}\n\n\t\tif ( login_user && Debug.varDump ) {\n\t\t\terror = 'Client Version: ' + APIGlobal.pre_login_data.application_build + '\\n\\nUncaught Error From: ' + script_name + '\\n\\nError: ' + error_string + ' in: ' + from_file + ' line: ' + line + ':' + col + '\\n\\nUser: ' + login_user.user_name + '\\n\\nURL: ' + window.location.href + '\\n\\nUser-Agent: ' + navigator.userAgent + ' ' + '\\n\\nIE: ' + window.ie + '\\n\\nCurrent Ping: ' + Global.current_ping + '\\n\\nIdle Time: ' + Global.idle_time + '\\n\\nSession ID Key: ' + LocalCacheData.getSessionID() + '\\n\\nCurrent User Object: \\n' + Debug.varDump( login_user ) + '\\n\\nCurrent Company Object: \\n' + Debug.varDump( current_company_obj ) + '\\n\\nPreLogin: \\n' + Debug.varDump( pre_login_data ) + ' ';\n\t\t} else {\n\t\t\terror = 'Client Version: ' + APIGlobal.pre_login_data.application_build + '\\n\\nUncaught Error From: ' + script_name + '\\n\\nError: ' + error_string + ' in: ' + from_file + ' line: ' + line + ':' + col + '\\n\\nUser: N/A' + '\\n\\nURL: ' + window.location.href + ' ' + '\\n\\nUser-Agent: ' + navigator.userAgent + ' ' + '\\n\\nIE: ' + window.ie;\n\t\t}\n\n\t\tconsole.error( 'JAVASCRIPT EXCEPTION:\\n---------------------------------------------\\n' + error + '\\n---------------------------------------------' );\n\t\tdebugger;\n\n\t\t//When not in production mode, popup alert box anytime an exception appears so it can't be missed.\n\t\tif ( APIGlobal.pre_login_data.production !== true && APIGlobal.pre_login_data.demo_mode !== true && APIGlobal.pre_login_data.sandbox !== true ) {\n\t\t\talert( 'JAVASCRIPT EXCEPTION:\\n---------------------------------------------\\n' + error + '\\n---------------------------------------------' );\n\t\t}\n\n\t\tif ( typeof ( gtag ) !== 'undefined' && APIGlobal.pre_login_data.analytics_enabled === true ) {\n\t\t\t// Send an exception hit to Google Analytics. Must be 8192 bytes or smaller.\n\t\t\t// Strip the domain part off the URL on 'from_file' to better account for similar errors.\n\t\t\tgtag( 'event', 'exception', {\n\t\t\t\t'exDescription': error_string + ' File: ' + ( ( from_file ) ? from_file.replace( Global.getBaseURL(), '' ) : 'N/A' ) + ' Line: ' + line + ':' + col,\n\t\t\t\t'exFatal': false\n\t\t\t} )\n\t\t}\n\n\t\t//Don't send error report if exception not happens in our codes.\n\t\t//from_file should always contains the root url\n\t\t//If URL is not sent by IE, assume its our own code and report the error still.\n\t\t// Modern browsers won't send error reports from other domains due to security issues now, so I think this can be removed.\n\t\t// if ( from_file && from_file.indexOf( ServiceCaller.root_url ) < 0 ) {\n\t\t// \tDebug.Text( 'Exception caught from unauthorized source, not sending report. Source: \"' + ServiceCaller.root_url + '\" Script: ' + from_file, 'Global.js', '', 'sendErrorReport', 1 );\n\t\t// \treturn;\n\t\t// }\n\n\t\tif ( current_company_obj ) { //getCurrentCompany() which in turn calls getRequiredLocalCache(), which can call sendErroReport causing a loop. So try to prevent that by checking LocalCacheData['current_company'] first.\n\t\t\terror = error + '\\n\\n' + 'Product Edition: ' + current_company_obj.product_edition_id;\n\t\t}\n\n\t\terror = error + '\\n\\n\\n' + 'Clicked target stacks: ' + JSON.stringify( LocalCacheData.ui_click_stack, undefined, 2 );\n\t\terror = error + '\\n\\n\\n' + 'API stacks: ' + JSON.stringify( LocalCacheData.api_stack, undefined, 2 );\n\n\t\tcaptureScreenShot( error, error_obj );\n\t}\n};\n\nGlobal.initStaticStrings = function() {\n\tGlobal.network_lost_msg = $.i18n._( 'The network connection was lost. Please check your network connection then try again.' );\n\n\tGlobal.any_item = '-- ' + $.i18n._( 'Any' ) + ' --';\n\n\tGlobal.all_item = '-- ' + $.i18n._( 'All' ) + ' --';\n\n\tGlobal.root_item = $.i18n._( 'Root' );\n\n\tGlobal.loading_label = '...';\n\n\tGlobal.customize_item = '-- ' + $.i18n._( 'Customize' ) + ' --';\n\n\tGlobal.default_item = '-- ' + $.i18n._( 'Default' ) + ' --';\n\n\tGlobal.selected_item = '-- ' + $.i18n._( 'Selected' ) + ' --';\n\n\tGlobal.open_item = '-- ' + $.i18n._( 'Open' ) + ' --';\n\n\tGlobal.empty_item = '-- ' + $.i18n._( 'None' ) + ' --';\n\n\tGlobal.view_mode_message = $.i18n._( 'You are currently in \\'View\\' mode' );\n\n\tGlobal.view_mode_edit_message = $.i18n._( 'instead click the \\'Edit\\' icon to modify fields' ); //Does not start with a capital as it is appended text.\n\n\tGlobal.no_result_message = $.i18n._( 'No Results Found' );\n\n\tGlobal.save_and_continue_message = $.i18n._( 'Please save this record before modifying any related data' );\n\n\tGlobal.no_hierarchy_message = $.i18n._( 'No Hierarchies Defined' );\n\n\tGlobal.modify_alert_message = $.i18n._( 'You have modified data without saving, are you sure you want to continue and lose your changes' );\n\n\tGlobal.confirm_on_exit_message = $.i18n._( 'Are you sure you want to continue without saving?' );\n\n\tGlobal.delete_confirm_message = $.i18n._( 'You are about to delete data, once data is deleted it can not be recovered. Are you sure you wish to continue?' );\n\n\tGlobal.delete_dashlet_confirm_message = $.i18n._( 'You are about to delete this dashlet, once a dashlet is deleted it can not be recovered. Are you sure you wish to continue?' );\n\n\tGlobal.copy_multiple_confirm_message = $.i18n._( 'You are about to copy multiple records. Are you sure you wish to continue?' );\n\n\tGlobal.auto_arrange_dashlet_confirm_message = $.i18n._( 'You are about to restore all dashlets to their default size/layout. Are you sure you wish to continue?' );\n\n\tGlobal.rese_all_dashlet_confirm_message = $.i18n._( 'You are about to remove all your customized dashlets and restore them back to the defaults. Are you sure you wish to continue?' );\n};\n\nGlobal.getUpgradeMessage = function() {\n\tvar message = $.i18n._( 'This functionality is only available in' ) +\n\t\t' ' + LocalCacheData.getLoginData().application_name + ' ';\n\n\tif ( Global.getProductEdition() < 15 ) {\n\t\t//Do not mention professional if user is on professional edition.\n\t\tmessage += $.i18n._( 'Professional, Corporate, or Enterprise Editions.' );\n\t} else if ( Global.getProductEdition() < 20 ) {\n\t\t//Do not mention corporate if user is on corporate edition.\n\t\tmessage += $.i18n._( 'Corporate or Enterprise Editions.' );\n\t} else {\n\t\tmessage += $.i18n._( 'Enterprise Editions.' );\n\t}\n\n\tmessage += ' ' + $.i18n._( 'For more information please visit' ) + ' www.timetrex.com';\n\n\tGlobal.trackView( 'CommunityUpgrade' );\n\treturn message;\n};\n\nGlobal.doPingIfNecessary = function() {\n\tif ( Global.idle_time < Math.min( 15, APIGlobal.pre_login_data.session_idle_timeout / 60 ) ) { //idle_time is minutes, session_idle_timeout is seconds.\n\t\tGlobal.idle_time = 0;\n\t\treturn;\n\t}\n\n\tDebug.Text( 'User is active again after idle for: ' + Global.idle_time + '... Resetting idle to 0', 'Global.js', '', 'doPingIfNecessary', 1 );\n\tGlobal.idle_time = 0;\n\n\tif ( LocalCacheData.current_open_primary_controller.viewId === 'LoginView' ) {\n\t\treturn;\n\t}\n\n\tvar api = _services_TimeTrexClientAPI__WEBPACK_IMPORTED_MODULE_1__/* .TTAPI.APIAuthentication */ .y.APIAuthentication;\n\tapi.isLoggedIn( false, {\n\t\tonResult: function( result ) {\n\t\t\tvar res_data = result.getResult();\n\n\t\t\tif ( res_data !== true ) {\n\t\t\t\t//Don't do Logout here, as we need to display a \"Session Expired\" message to the user, which is triggered from the ServiceCaller.\n\t\t\t\t// In order to trigger that though, we need to make an *Authenticated* API call to APIMisc.Ping(), rather than UnAuthenticated call to APIAuthentication.Ping()\n\t\t\t\tvar api = _services_TimeTrexClientAPI__WEBPACK_IMPORTED_MODULE_1__/* .TTAPI.APIMisc */ .y.APIMisc;\n\t\t\t\tapi.ping( {\n\t\t\t\t\tonResult: function() {\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t} );\n};\n\nGlobal.setupPing = function() {\n\tGlobal.idle_time = 0;\n\t$( 'body' ).mousemove( Global.debounce( function setupPingMouseMoveEvent( e ) {\n\t\tGlobal.doPingIfNecessary();\n\t}, 1000 ) );\n\t$( 'body' ).keypress( Global.debounce( function setupPingKeyPressEvent( e ) {\n\t\tGlobal.doPingIfNecessary();\n\t}, 1000 ) );\n\n\tsetInterval( timerIncrement, 60000 ); // 1 minute\n\tfunction timerIncrement() {\n\t\tGlobal.idle_time = Global.idle_time + 1;\n\t\tif ( Global.idle_time >= Math.min( 15, APIGlobal.pre_login_data.session_idle_timeout / 60 ) ) {\n\t\t\tDebug.Text( 'User is idle: ' + Global.idle_time, 'Global.js', '', 'setupPing', 1 );\n\t\t}\n\t}\n};\n\nGlobal.clearCache = function( function_name ) {\n\tfor ( var key in LocalCacheData.result_cache ) {\n\t\tif ( key.indexOf( function_name ) >= 0 ) {\n\t\t\tdelete LocalCacheData.result_cache[key];\n\t\t}\n\t}\n};\n\nGlobal.getHost = function( host ) {\n\tif ( !host ) {\n\t\thost = window.location.hostname;\n\t}\n\n\t//Make sure its not an IPv4 address, and if its a domain has more than 1 dot in it before parsing off the sub-domain part.\n\t// So both IPv4 addresses and domains like: localhost (no dot at all), mycompany.com should not be modified at all. Only: sub.mycompany.com, sub.sub2.mycompany.com\n\tvar is_sub_domain = host.match( /\\./g );\n\tif ( /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/.test( host ) == false && is_sub_domain && is_sub_domain.length > 1 ) {\n\t\thost = host.substring( ( host.indexOf( '.' ) + 1 ) );\n\t}\n\n\treturn host;\n};\n\nGlobal.setWidgetEnabled = function( widget, val ) {\n\tif ( widget ) {\n\t\tif ( !val ) {\n\t\t\twidget.attr( 'disabled', 'true' );\n\t\t\twidget.addClass( 'disable-filter' );\n\t\t} else {\n\t\t\twidget.removeAttr( 'disabled' );\n\t\t\twidget.removeClass( 'disable-filter' );\n\t\t}\n\t}\n};\n\nGlobal.createViewTabs = function() {\n\t//JS load Optimize\n\tif ( typeof _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.WidgetNamesDic == 'undefined' ) {\n\t\treturn;\n\t}\n\tif ( LocalCacheData.loadViewRequiredJSReady ) {\n\t\tif ( !LocalCacheData.view_min_tab_bar ) {\n\t\t\tvar view_min_tab_bar = Global.loadWidgetByName( _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.WidgetNamesDic.VIEW_MIN_TAB_BAR );\n\t\t\tview_min_tab_bar = $( view_min_tab_bar ).ViewMinTabBar();\n\t\t\t$( '.layout-menu-container' ).append( view_min_tab_bar );\n\n\t\t\tLocalCacheData.view_min_tab_bar = view_min_tab_bar;\n\t\t}\n\n\t\tLocalCacheData.view_min_tab_bar.buildTabs( LocalCacheData.view_min_map );\n\t}\n};\n\nGlobal.addViewTab = function( view_id, view_name, url ) {\n\n\tLocalCacheData.view_min_map[view_id] = view_name;\n\n\tLocalCacheData.view_min_map[view_id + '_url'] = url;\n\n\tGlobal.createViewTabs();\n};\n\nGlobal.removeViewTab = function( view_id ) {\n\n\tdelete LocalCacheData.view_min_map[view_id];\n\t$( '#min_tab_' + view_id ).remove();\n};\n\nGlobal.cleanViewTab = function() {\n\n\tLocalCacheData.view_min_map = {};\n\tGlobal.createViewTabs();\n};\n\nGlobal.upCaseFirstLetter = function( str ) {\n\tif ( typeof str == 'string' ) { //in case null or false is passed, we should check the type.\n\t\tstr = str.charAt( 0 ).toUpperCase() + str.slice( 1 );\n\t}\n\treturn str;\n};\n\nGlobal.calculateTextWidth = function( text, options ) {\n\tif ( typeof options === \"undefined\" ) {\n\t\toptions = {};\n\t}\n\n\tif ( !options.fontSize ) {\n\t\toptions.fontSize = '12px';\n\t}\n\n\tvar element = document.createElement( 'div' );\n\tvar textNode = document.createTextNode( text );\n\n\telement.appendChild( textNode );\n\n\tif ( options.font ) {\n\t\telement.style.fontFamily = options.font;\n\t}\n\n\tif ( options.fontWeight ) {\n\t\telement.style.fontWeight = options.fontWeight;\n\t}\n\n\tif ( options.wordBreak ) {\n\t\telement.style.wordBreak = options.wordBreak;\n\t}\n\n\telement.style.fontSize = options.fontSize;\n\telement.style.position = 'absolute';\n\telement.style.visibility = 'hidden';\n\telement.style.left = '-999px';\n\telement.style.top = '-999px';\n\telement.style.height = 'auto';\n\n\tdocument.body.appendChild( element );\n\tvar content_width = element.offsetWidth;\n\telement.parentNode.removeChild( element );\n\n\tif ( options.min_width && options.min_width > 0 && content_width < options.min_width ) {\n\t\tcontent_width = options.min_width;\n\t}\n\tif ( options.padding && options.padding > 0 ) {\n\t\tcontent_width = content_width + options.padding;\n\t}\n\tif ( options.max_width > 0 && content_width > options.max_width ) {\n\t\tcontent_width = options.max_width;\n\t}\n\n\treturn content_width;\n};\n\nGlobal.strToDate = function( date_string, format ) {\n\n\t//better to use Date.parse, let's see\n\tif ( !Global.isSet( format ) && LocalCacheData.getLoginUserPreference() ) {\n\t\tformat = LocalCacheData.getLoginUserPreference().date_format;\n\t}\n\n\tif ( !format ) {\n\t\tformat = 'DD-MMM-YY';\n\t}\n\n\tvar date = moment( date_string, format );\n\tdate = date.toDate();\n\n\t//The moment will pass everything as a date. Judge if the year less 1000 than 1900 or beyond 1000 of 1900,\n\t//we think it's a invalid year\n\tif ( date.getYear() < -1000 || date.getYear() > 1000 ) {\n\t\treturn null;\n\t}\n\n\treturn date;\n};\n\nGlobal.strToDateTime = function( date_string ) {\n\t//Error: TypeError: Global.strToDateTime(...) is null in /interface/html5/framework/jquery.min.js?v=8.0.0-20141117-153515 line 4862\n\tif ( !date_string || !LocalCacheData.getLoginUserPreference() ) {\n\t\treturn null;\n\t}\n\n\tvar date_format = LocalCacheData.getLoginUserPreference().date_format;\n\tvar time_format = LocalCacheData.getLoginUserPreference().js_time_format[LocalCacheData.getLoginUserPreference().time_format];\n\tvar date = moment( date_string, date_format + ' ' + time_format ).toDate();\n\n\treturn date;\n\t//return Date.parse( date_string );\n};\n\n//Convert all kinds of date time to mm/dd/yyyy so Date.parse can parse it correct\nGlobal.getStandardDateTimeStr = function( date_str, time_str ) {\n\t//var result = Global.strToDate( date_str ).format( 'MM/DD/YYYY' ) + ' ' + time_str;\n\n\treturn date_str;\n};\n\nGlobal.convertTojQueryFormat = function( date_format ) {\n\t//For moment date parser\n\tvar jquery_date_format = {\n\t\t'd-M-y': 'dd-M-y',\n\t\t'd-M-Y': 'dd-M-yy',\n\t\t'dMY': 'ddMyy',\n\t\t'd/m/Y': 'dd/mm/yy',\n\t\t'd/m/y': 'dd/mm/y',\n\t\t'd-m-y': 'dd-mm-y',\n\t\t'd-m-Y': 'dd-mm-yy',\n\t\t'm/d/y': 'mm/dd/y',\n\t\t'm/d/Y': 'mm/dd/yy',\n\t\t'm-d-y': 'mm-dd-y',\n\t\t'm-d-Y': 'mm-dd-yy',\n\t\t'Y-m-d': 'yy-mm-dd',\n\t\t'M-d-y': 'M-dd-y',\n\t\t'M-d-Y': 'M-dd-yy',\n\t\t'l, F d Y': 'DD, MM dd yy',\n\t\t'D, F d Y': 'D, MM dd yy',\n\t\t'D, M d Y': 'D, M dd yy',\n\t\t'D, d-M-Y': 'D, dd-M-yy',\n\t\t'D, dMY': 'D, ddMyy',\n\n\t\t'g:i A': 'h:mm TT',\n\t\t'g:i a': 'h:mm tt',\n\t\t'G:i': 'H:mm',\n\t\t'g:i A T': 'h:mm TT',\n\t\t'G:i T': 'H:mm',\n\n\t\t'g:i:s A': 'h:mm:ss TT',\n\t\t'g:i:s a': 'h:mm:ss tt',\n\t\t'G:i:s': 'H:mm:ss',\n\t\t'g:i:s A T': 'h:mm:ss TT',\n\t\t'G:i:s T': 'H:mm:ss'\n\t};\n\n\treturn jquery_date_format[date_format];\n};\n\nGlobal.updateUserPreference = function( callBack, message ) {\n\tvar user_preference_api = _services_TimeTrexClientAPI__WEBPACK_IMPORTED_MODULE_1__/* .TTAPI.APIUserPreference */ .y.APIUserPreference;\n\tvar current_user_aou = _services_TimeTrexClientAPI__WEBPACK_IMPORTED_MODULE_1__/* .TTAPI.APIAuthentication */ .y.APIAuthentication;\n\n\tif ( message ) {\n\t\tProgressBar.changeProgressBarMessage( message );\n\t}\n\n\tcurrent_user_aou.getCurrentUserPreference( {\n\t\tonResult: function( result ) {\n\t\t\tvar result_data = result.getResult();\n\t\t\tLocalCacheData.loginUserPreference = result_data;\n\n\t\t\tuser_preference_api.getOptions( 'moment_date_format', {\n\t\t\t\tonResult: function( jsDateFormatRes ) {\n\t\t\t\t\tvar jsDateFormatResultData = jsDateFormatRes.getResult();\n\n\t\t\t\t\t//For moment date parser\n\t\t\t\t\tLocalCacheData.loginUserPreference.js_date_format = jsDateFormatResultData;\n\n\t\t\t\t\tvar date_format = LocalCacheData.loginUserPreference.date_format;\n\t\t\t\t\tif ( !date_format ) {\n\t\t\t\t\t\tdate_format = 'DD-MMM-YY';\n\t\t\t\t\t}\n\n\t\t\t\t\tLocalCacheData.loginUserPreference.date_format = LocalCacheData.loginUserPreference.js_date_format[date_format];\n\n\t\t\t\t\tLocalCacheData.loginUserPreference.date_format_1 = Global.convertTojQueryFormat( date_format ); //TDatePicker, TRangePicker\n\t\t\t\t\tLocalCacheData.loginUserPreference.time_format_1 = Global.convertTojQueryFormat( LocalCacheData.loginUserPreference.time_format ); //TTimePicker\n\n\t\t\t\t\tuser_preference_api.getOptions( 'moment_time_format', {\n\t\t\t\t\t\tonResult: function( jsTimeFormatRes ) {\n\t\t\t\t\t\t\tvar jsTimeFormatResultData = jsTimeFormatRes.getResult();\n\n\t\t\t\t\t\t\tLocalCacheData.loginUserPreference.js_time_format = jsTimeFormatResultData;\n\n\t\t\t\t\t\t\tLocalCacheData.setLoginUserPreference( LocalCacheData.loginUserPreference );\n\n\t\t\t\t\t\t\tif ( callBack ) {\n\t\t\t\t\t\t\t\tcallBack();\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\t\t\t\t\t} );\n\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t} );\n};\n\n/* jshint ignore:start */\nGlobal.roundTime = function( epoch, round_value, round_type ) {\n\tvar round_type = round_type || 20;\n\n\tswitch ( round_type ) {\n\t\tcase 10: //Down\n\t\t\tepoch = ( epoch - ( epoch % round_value ) );\n\t\t\tbreak;\n\t\tcase 20: //Average\n\t\tcase 25: //Average (round split seconds up)\n\t\tcase 27: //Average (round split seconds down)\n\t\t\tvar tmp_round_value;\n\t\t\tif ( round_type == 20 || round_value <= 60 ) {\n\t\t\t\ttmp_round_value = ( round_value / 2 );\n\t\t\t} else if ( round_type == 25 ) { //Average (Partial Min. Down)\n\t\t\t\ttmp_round_value = Global.roundTime( ( round_value / 2 ), 60, 10 ); //This is opposite rounding\n\t\t\t} else if ( round_type == 27 ) { //Average (Partial Min. Up)\n\t\t\t\ttmp_round_value = Global.roundTime( ( round_value / 2 ), 60, 30 );\n\t\t\t}\n\n\t\t\tif ( epoch > 0 ) {\n\t\t\t\t//When doing a 15min average rounding, US law states 7mins and 59 seconds can be rounded down in favor of the employer, and 8mins and 0 seconds must be rounded up.\n\t\t\t\t//So if the round interval is not an even number, round it up to the nearest minute before doing the calculations to avoid issues with seconds.\n\t\t\t\tepoch = ( Math.floor( ( epoch + tmp_round_value ) / round_value ) * round_value );\n\t\t\t} else {\n\t\t\t\tepoch = ( Math.ceil( ( epoch - tmp_round_value ) / round_value ) * round_value );\n\t\t\t}\n\n\t\t\tbreak;\n\t\tcase 30: //Up\n\t\t\tepoch = ( ( ( epoch + ( round_value - 1 ) ) / round_value ) * round_value );\n\t\t\tbreak;\n\t}\n\n\treturn epoch;\n},\n\n\tGlobal.parseTimeUnit = function( time_unit, format ) {\n\t\tvar format, time_unit, time_units, seconds, negative_number;\n\n\t\tvar time_unit = time_unit.toString(); //Needs to be a string so we can use .charAt and .replace below.\n\n\t\tif ( !format ) {\n\t\t\tformat = LocalCacheData.getLoginUserPreference().time_unit_format;\n\t\t}\n\t\tformat = parseInt( format );\n\n\t\tvar enable_rounding = true;\n\t\tif ( time_unit.charAt( 0 ) == '\"' ) {\n\t\t\tenable_rounding = false;\n\t\t}\n\n\t\tvar thousands_separator = ',';\n\t\tvar decimal_separator = '.';\n\n\t\ttime_unit = time_unit.replace( new RegExp( thousands_separator, 'g' ), '' ).replace( new RegExp( ' ', 'g' ), '' ).replace( new RegExp( '\"', 'g' ), '' ); //Need to use regex to replace all instances.\n\n\t\tswitch ( format ) {\n\t\t\tcase 10: //hh:mm\n\t\t\tcase 12: //hh:mm:ss\n\t\t\t\tif ( time_unit.indexOf( decimal_separator ) !== -1 && time_unit.indexOf( ':' ) === -1 ) { //Hybrid mode, they passed a decimal format HH:MM, try to handle properly.\n\t\t\t\t\ttime_unit = Global.getTimeUnit( Global.parseTimeUnit( time_unit, 20 ), format );\n\t\t\t\t}\n\n\t\t\t\ttime_units = time_unit.split( ':' );\n\n\t\t\t\tif ( !time_units[0] ) {\n\t\t\t\t\ttime_units[0] = 0;\n\t\t\t\t}\n\n\t\t\t\tif ( !time_units[1] ) {\n\t\t\t\t\ttime_units[1] = 0;\n\t\t\t\t}\n\n\t\t\t\tif ( !time_units[2] ) {\n\t\t\t\t\ttime_units[2] = 0;\n\t\t\t\t} else {\n\t\t\t\t\tif ( time_units[2] != 0 ) {\n\t\t\t\t\t\tenable_rounding = false; //Since seconds were specified, don't round to nearest minute.\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tnegative_number = false;\n\t\t\t\tif ( time_units[0].toString().charAt( 0 ) == '-' || time_units[0] < 0 || time_units[1] < 0 || time_units[2] < 0 ) {\n\t\t\t\t\tnegative_number = true;\n\t\t\t\t}\n\n\t\t\t\tseconds = ( ( Math.abs( Math.floor( time_units[0] ) ) * 3600 ) + ( Math.abs( Math.floor( time_units[1] ) ) * 60 ) + Math.abs( Math.floor( time_units[2] ) ) );\n\n\t\t\t\tif ( negative_number == true ) {\n\t\t\t\t\tseconds = ( seconds * -1 );\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\tcase 20: //hours\n\t\t\tcase 22: //hours [Precise]\n\t\t\tcase 23: //hours [Super Precise]\n\t\t\t\tif ( time_unit.indexOf( ':' ) !== -1 ) { //Hybrid mode, they passed a decimal format HH:MM, try to handle properly.\n\t\t\t\t\ttime_unit = Global.getTimeUnit( Global.parseTimeUnit( time_unit, 10 ), format );\n\t\t\t\t}\n\n\t\t\t\tseconds = ( time_unit * 3600 );\n\t\t\t\tbreak;\n\t\t\tcase 30: //minutes\n\t\t\t\tseconds = ( time_unit * 60 );\n\t\t\t\tbreak;\n\t\t\tcase 40: //seconds\n\t\t\t\tseconds = time_unit;\n\t\t\t\tif ( enable_rounding == true ) {\n\t\t\t\t\tseconds = round( seconds ); //Round to nearest whole number by default.\n\t\t\t\t}\n\t\t\t\tenable_rounding = false; //Since seconds were specified, don't round to nearest minute. Also for accruals might need to allow decimal seconds.\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif ( enable_rounding == true ) {\n\t\t\tseconds = Global.roundTime( seconds, 60 );\n\t\t}\n\n\t\t//Debug.Text( 'Time Unit: '+ time_unit +' Retval: '+ seconds, 'Global.js', '', 'parseTimeUnit', 10 );\n\t\treturn seconds;\n\t},\n\n\tGlobal.convertSecondsToHMS = function( seconds, include_seconds, exclude_hours ) {\n\t\tvar negative_number = false;\n\n\t\tif ( seconds < 0 ) {\n\t\t\tnegative_number = true;\n\t\t}\n\n\t\tseconds = Math.round( Math.abs( seconds ) );\n\n\t\tvar tmp_hours = Math.floor( seconds / 3600 );\n\t\tvar tmp_minutes = Math.floor( ( seconds / 60 ) % 60 );\n\t\tvar tmp_seconds = Math.floor( seconds % 60 );\n\n\t\tif ( exclude_hours == true ) { //Convert hours to minutes before we pad it.\n\t\t\ttmp_minutes = ( ( tmp_hours * 60 ) + tmp_minutes );\n\t\t\ttmp_hours = 0;\n\t\t}\n\n\t\tif ( tmp_hours < 10 ) {\n\t\t\ttmp_hours = '0' + tmp_hours;\n\t\t}\n\n\t\tif ( tmp_minutes < 10 ) {\n\t\t\ttmp_minutes = '0' + tmp_minutes;\n\t\t}\n\n\t\tif ( tmp_seconds < 10 ) {\n\t\t\ttmp_seconds = '0' + tmp_seconds;\n\t\t}\n\n\t\tvar retval;\n\t\tif ( exclude_hours == true ) {\n\t\t\tretval = [tmp_minutes, tmp_seconds].join( ':' );\n\t\t} else {\n\t\t\tif ( include_seconds == true ) {\n\t\t\t\tretval = [tmp_hours, tmp_minutes, tmp_seconds].join( ':' );\n\t\t\t} else {\n\t\t\t\tretval = [tmp_hours, tmp_minutes].join( ':' );\n\t\t\t}\n\t\t}\n\n\t\tif ( negative_number == true ) {\n\t\t\tretval = '-' + retval;\n\t\t}\n\n\t\treturn retval;\n\t},\n\n//Was: Global.secondToHHMMSS\n\tGlobal.getTimeUnit = function( seconds, format ) {\n\t\tvar retval;\n\n\t\t//always return hh:ss. if we can't parse to float, then work with 0 tmp_seconds\n\t\tvar seconds = parseFloat( seconds );\n\t\tif ( isNaN( seconds ) ) {\n\t\t\tseconds = 0;\n\t\t}\n\n\t\t//FIXES BUG#2071 - don't check the local cache data for default value, or it will fail and cause errors when unauthenticated. For example in the installer.\n\t\tvar format;\n\t\tif ( !format ) {\n\t\t\tif ( LocalCacheData.getLoginUserPreference() ) {\n\t\t\t\tformat = LocalCacheData.getLoginUserPreference().time_unit_format;\n\t\t\t} else {\n\t\t\t\tformat = 10;\n\t\t\t}\n\t\t}\n\t\tformat = parseInt( format );\n\n\t\tswitch ( format ) {\n\t\t\tcase 10:\n\t\t\t\tretval = Global.convertSecondsToHMS( seconds );\n\t\t\t\tbreak;\n\t\t\tcase 12:\n\t\t\t\tretval = Global.convertSecondsToHMS( seconds, true );\n\t\t\t\tbreak;\n\t\t\tcase 99: //For local use only, in progress bar always show tmp_minutes and tmp_seconds\n\t\t\t\tretval = Global.convertSecondsToHMS( seconds, true, true );\n\t\t\t\tbreak;\n\t\t\tcase 20:\n\t\t\t\tretval = ( seconds / 3600 ).toFixed( 2 );\n\t\t\t\tbreak;\n\t\t\tcase 22:\n\t\t\t\tretval = ( seconds / 3600 ).toFixed( 3 );\n\t\t\t\tbreak;\n\t\t\tcase 23:\n\t\t\t\tretval = ( seconds / 3600 ).toFixed( 4 );\n\t\t\t\tbreak;\n\t\t\tcase 30:\n\t\t\t\tretval = ( seconds / 60 ).toFixed( 0 );\n\t\t\t\tbreak;\n\t\t\tcase 40:\n\t\t\t\tretval = seconds;\n\t\t\t\tbreak;\n\t\t}\n\n\t\t//Debug.Text( 'Seconds: '+ seconds +' Retval: '+ retval, 'Global.js', '', 'getTimeUnit', 10 );\n\t\treturn retval;\n\t};\n\nGlobal.removeTrailingZeros = function( value, minimum_decimals ) {\n\tif ( !minimum_decimals ) {\n\t\tminimum_decimals = 2;\n\t}\n\tif ( value ) {\n\t\tvalue = parseFloat( value ); // first to remove the zero after the point.\n\n\t\tvar trimmed_value = value.toString();\n\n\t\tif ( trimmed_value.indexOf( '.' ) > 0 ) {\n\t\t\t// If after removed has the point, then reverse it.\n\t\t\tvar tmp_minimum_decimals = parseInt( trimmed_value.split( '' ).reverse().join( '' ) ).toString().length;\n\t\t\tif ( tmp_minimum_decimals >= minimum_decimals && tmp_minimum_decimals <= 4 ) {\n\t\t\t\tminimum_decimals = tmp_minimum_decimals;\n\t\t\t}\n\n\t\t}\n\n\t\treturn value.toFixed( minimum_decimals );\n\t}\n\n\treturn value;\n};\n\n/* jshint ignore:end */\n\nGlobal.isCanvasSupported = function() {\n\tvar elem = document.createElement( 'canvas' );\n\treturn !!( elem.getContext && elem.getContext( '2d' ) );\n};\n\nGlobal.getRandomNum = function() {\n\n\tvar number = Math.floor( Math.random() * 999 );//0-23\n\n\treturn number;\n\n};\n\n/* jshint ignore:start */\n\nGlobal.getScriptNameByAPI = function( api_class ) {\n\n\tif ( !api_class || !api_class.className ) {\n\t\treturn null;\n\t}\n\n\tvar script_name = '';\n\tswitch ( api_class.className ) {\n\t\tcase 'APIUser':\n\t\t\tscript_name = 'EmployeeView';\n\t\t\tbreak;\n\t\tcase 'APIBranch':\n\t\t\tscript_name = 'BranchView';\n\t\t\tbreak;\n\t\tcase 'APIDepartment':\n\t\t\tscript_name = 'DepartmentView';\n\t\t\tbreak;\n\t\tcase 'APIUserWage':\n\t\t\tscript_name = 'WageView';\n\t\t\tbreak;\n\t\tcase 'APIUserContact':\n\t\t\tscript_name = 'UserContactView';\n\t\t\tbreak;\n\t\tcase 'APIUserTitle':\n\t\t\tscript_name = 'UserTitleView';\n\t\t\tbreak;\n\t\tcase 'APIWageGroup':\n\t\t\tscript_name = 'WageGroupView';\n\t\t\tbreak;\n\t\tcase 'APILog':\n\t\t\tscript_name = 'LogView';\n\t\t\tbreak;\n\t\tcase 'APIUserGroup':\n\t\t\tscript_name = 'UserGroupView';\n\t\t\tbreak;\n\t\tcase 'APIPayStubEntryAccount':\n\t\t\tscript_name = 'PayStubEntryAccountView';\n\t\t\tbreak;\n\t\tcase 'APIPayStubEntryAccountLink':\n\t\t\tscript_name = 'PayStubEntryAccountLinkView';\n\t\t\tbreak;\n\t\tcase 'APIPayPeriod':\n\t\tcase 'APIPayPeriodSchedule':\n\t\t\tscript_name = 'PayPeriodsView';\n\t\t\tbreak;\n\t\tcase 'APIAccrual':\n\t\t\tscript_name = 'APIAccrual';\n\t\t\tbreak;\n\t\tcase 'APIAccrualBalance':\n\t\t\tscript_name = 'AccrualBalanceView';\n\t\t\tbreak;\n\t\tcase 'APIException':\n\t\t\tscript_name = 'ExceptionView';\n\t\t\tbreak;\n\t\tcase 'APIJobGroup':\n\t\t\tscript_name = 'JobGroupView';\n\t\t\tbreak;\n\t\tcase 'APIJob':\n\t\t\tscript_name = 'JobView';\n\t\t\tbreak;\n\t\tcase 'APIJobItemGroup':\n\t\t\tscript_name = 'JobItemGroupView';\n\t\t\tbreak;\n\t\tcase 'APIJobItem':\n\t\t\tscript_name = 'JobItemView';\n\t\t\tbreak;\n\t\tcase 'APIJobItemAmendment':\n\t\t\tscript_name = 'JobItemAmendment';\n\t\t\tbreak;\n\t\tcase 'APIPunch':\n\t\t\tscript_name = 'PunchesView';\n\t\t\tbreak;\n\t\tcase 'APIPunchTag':\n\t\t\tscript_name = 'PunchTagView';\n\t\t\tbreak;\n\t\tcase 'APIPunchTagGroup':\n\t\t\tscript_name = 'PunchTagGroupView';\n\t\t\tbreak;\n\t\tcase 'APIRecurringScheduleControl':\n\t\t\tscript_name = 'RecurringScheduleControlView';\n\t\t\tbreak;\n\n\t\tcase 'APIRecurringScheduleTemplateControl':\n\t\t\tscript_name = 'RecurringScheduleTemplateControlView';\n\t\t\tbreak;\n\t\tcase 'APISchedule':\n\t\t\tscript_name = 'ScheduleShiftView';\n\t\t\tbreak;\n\t\tcase 'APIBankAccount':\n\t\t\tscript_name = 'BankAccountView';\n\t\t\tbreak;\n\t\tcase 'APICompany':\n\t\t\tscript_name = 'CompanyView';\n\t\t\tbreak;\n\t\tcase 'APICurrency':\n\t\t\tscript_name = 'CurrencyView';\n\t\t\tbreak;\n\t\tcase 'APICurrencyRate':\n\t\t\tscript_name = 'CurrencyRate';\n\t\t\tbreak;\n\t\tcase 'APIHierarchyControl':\n\t\t\tscript_name = 'HierarchyControlView';\n\t\t\tbreak;\n\t\tcase 'APIEthnicGroup':\n\t\t\tscript_name = 'EthnicGroupView';\n\t\t\tbreak;\n\t\tcase 'APICustomField':\n\t\t\tscript_name = 'CustomFieldView';\n\t\t\tbreak;\n\t\tcase 'APIPermissionControl':\n\t\t\tscript_name = 'PermissionControlView';\n\t\t\tbreak;\n\t\tcase 'APIStation':\n\t\t\tscript_name = 'StationView';\n\t\t\tbreak;\n\t\tcase 'APIDocumentRevision':\n\t\t\tscript_name = 'DocumentRevisionView';\n\t\t\tbreak;\n\t\tcase 'APIDocumentGroup':\n\t\t\tscript_name = 'DocumentGroupView';\n\t\t\tbreak;\n\t\tcase 'APIDocument':\n\t\t\tscript_name = 'DocumentView';\n\t\t\tbreak;\n\t\tcase 'APIROE':\n\t\t\tscript_name = 'ROEView';\n\t\t\tbreak;\n\t\tcase 'APIUserDefault':\n\t\t\tscript_name = 'UserDefaultView';\n\t\t\tbreak;\n\t\tcase 'APIUserPreference':\n\t\t\tscript_name = 'UserPreferenceView';\n\t\t\tbreak;\n\t\tcase 'APIKPI':\n\t\t\tscript_name = 'KPIView';\n\t\t\tbreak;\n\t\tcase 'APIUserReviewControl':\n\t\t\tscript_name = 'UserReviewControlView';\n\t\t\tbreak;\n\t\tcase 'APIQualification':\n\t\t\tscript_name = 'QualificationView';\n\t\t\tbreak;\n\t\tcase 'APIUserEducation':\n\t\t\tscript_name = 'UserTitleView';\n\t\t\tbreak;\n\t\tcase 'APIUserLanguage':\n\t\t\tscript_name = 'UserTitleView';\n\t\t\tbreak;\n\t\tcase 'APIUserLicense':\n\t\t\tscript_name = 'UserLicenseView';\n\t\t\tbreak;\n\t\tcase 'APIUserMembership':\n\t\t\tscript_name = 'UserMembershipView';\n\t\t\tbreak;\n\t\tcase 'APIUserSkill':\n\t\t\tscript_name = 'UserSkillView';\n\t\t\tbreak;\n\t\tcase 'APIJobApplicantEducation':\n\t\t\tscript_name = 'JobApplicantEducationView';\n\t\t\tbreak;\n\t\tcase 'APIJobApplicantEmployment':\n\t\t\tscript_name = 'JobApplicantEducationView';\n\t\t\tbreak;\n\t\tcase 'APIJobApplicantLanguage':\n\t\t\tscript_name = 'JobApplicantLanguageView';\n\t\t\tbreak;\n\t\tcase 'APIJobApplicantLicense':\n\t\t\tscript_name = 'JobApplicantLicenseView';\n\t\t\tbreak;\n\t\tcase 'APIJobApplicantLocation':\n\t\t\tscript_name = 'JobApplicantLicenseView';\n\t\t\tbreak;\n\t\tcase 'APIJobApplicantMembership':\n\t\t\tscript_name = 'JobApplicantMembershipView';\n\t\t\tbreak;\n\t\tcase 'APIJobApplicantReference':\n\t\t\tscript_name = 'JobApplicantReferenceView';\n\t\t\tbreak;\n\t\tcase 'APIJobApplicantSkill':\n\t\t\tscript_name = 'JobApplicantSkillView';\n\t\t\tbreak;\n\t\tcase 'APIJobApplicant':\n\t\t\tscript_name = 'JobApplicantSkillView';\n\t\t\tbreak;\n\t\tcase 'APIJobApplication':\n\t\t\tscript_name = 'JobApplicationView';\n\t\t\tbreak;\n\t\tcase 'APIJobVacancy':\n\t\t\tscript_name = 'JobVacancyView';\n\t\t\tbreak;\n\t\tcase 'APIAreaPolicy':\n\t\t\tscript_name = 'JobVacancyView';\n\t\t\tbreak;\n\t\tcase 'APIClient':\n\t\t\tscript_name = 'ClientView';\n\t\t\tbreak;\n\t\tcase 'APIClientContact':\n\t\t\tscript_name = 'ClientContactView';\n\t\t\tbreak;\n\t\tcase 'APIClientGroup':\n\t\t\tscript_name = 'ClientGroupView';\n\t\t\tbreak;\n\t\tcase 'APIClientPayment':\n\t\t\tscript_name = 'ClientPaymentView';\n\t\t\tbreak;\n\t\tcase 'APIInvoiceDistrict':\n\t\t\tscript_name = 'InvoiceDistrictView';\n\t\t\tbreak;\n\t\tcase 'APIInvoice':\n\t\t\tscript_name = 'InvoiceView';\n\t\t\tbreak;\n\t\tcase 'APITransaction':\n\t\t\tscript_name = 'InvoiceTransactionView';\n\t\t\tbreak;\n\t\tcase 'APIPaymentGateway':\n\t\t\tscript_name = 'PaymentGatewayView';\n\t\t\tbreak;\n\t\tcase 'APIProductGroup':\n\t\t\tscript_name = 'ProductGroupView';\n\t\t\tbreak;\n\t\tcase 'APIProduct':\n\t\t\tscript_name = 'ProductView';\n\t\t\tbreak;\n\t\tcase 'APIInvoiceConfig':\n\t\t\tscript_name = 'InvoiceConfigView';\n\t\t\tbreak;\n\t\tcase 'APIShippingPolicy':\n\t\t\tscript_name = 'ShippingPolicyView';\n\t\t\tbreak;\n\t\tcase 'APITaxPolicy':\n\t\t\tscript_name = 'TaxPolicyView';\n\t\t\tbreak;\n\t\tcase 'APICompanyDeduction':\n\t\t\tscript_name = 'CompanyTaxDeductionView';\n\t\t\tbreak;\n\t\tcase 'APIPayStub':\n\t\t\tscript_name = 'PayStubView';\n\t\t\tbreak;\n\t\tcase 'APIPayStubTransaction':\n\t\t\tscript_name = 'PayStubTransactionView';\n\t\t\tbreak;\n\t\tcase 'APIPayStubEntry':\n\t\t\tscript_name = 'PayStubEntryView';\n\t\t\tbreak;\n\t\tcase 'APIPayStubAmendment':\n\t\t\tscript_name = 'PayStubAmendmentView';\n\t\t\tbreak;\n\t\tcase 'APIRecurringPayStubAmendment':\n\t\t\tscript_name = 'RecurringPayStubAmendmentView';\n\t\t\tbreak;\n\t\tcase 'APIUserExpense':\n\t\t\tscript_name = 'UserExpenseView';\n\t\t\tbreak;\n\t\tcase 'APILegalEntity':\n\t\t\tscript_name = 'LegalEntityView';\n\t\t\tbreak;\n\t\tcase 'APIPayrollRemittanceAgency':\n\t\t\tscript_name = 'PayrollRemittanceAgencyView';\n\t\t\tbreak;\n\t\tcase 'APIPayrollRemittanceAgencyEvent':\n\t\t\tscript_name = 'PayrollRemittanceAgencyViewEvent';\n\t\t\tbreak;\n\t\tcase 'APIAbsencePolicy':\n\t\t\tscript_name = 'AbsencePolicyView';\n\t\t\tbreak;\n\t\tcase 'APIAccrualPolicyAccount':\n\t\t\tscript_name = 'AccrualPolicyAccountView';\n\t\t\tbreak;\n\t\tcase 'APIAccrualPolicy':\n\t\t\tscript_name = 'AccrualPolicyView';\n\t\t\tbreak;\n\t\tcase 'APIAccrualPolicyUserModifier':\n\t\t\tscript_name = 'AccrualPolicyUserModifierView';\n\t\t\tbreak;\n\t\tcase 'APIBreakPolicy':\n\t\t\tscript_name = 'BreakPolicyView';\n\t\t\tbreak;\n\t\tcase 'APIExceptionPolicyControl':\n\t\t\tscript_name = 'ExceptionPolicyControlView';\n\t\t\tbreak;\n\t\tcase 'APIExpensePolicy':\n\t\t\tscript_name = 'ExpensePolicyView';\n\t\t\tbreak;\n\t\tcase 'APIHoliday':\n\t\t\tscript_name = 'HolidayView';\n\t\t\tbreak;\n\t\tcase 'APIHolidayPolicy':\n\t\t\tscript_name = 'HolidayPolicyView';\n\t\t\tbreak;\n\t\tcase 'APIMealPolicy':\n\t\t\tscript_name = 'MealPolicyView';\n\t\t\tbreak;\n\t\tcase 'APIOvertimePolicy':\n\t\t\tscript_name = 'OvertimePolicyView';\n\t\t\tbreak;\n\t\tcase 'APIPolicyGroup':\n\t\t\tscript_name = 'PolicyGroupView';\n\t\t\tbreak;\n\t\tcase 'APIPremiumPolicy':\n\t\t\tscript_name = 'PremiumPolicyView';\n\t\t\tbreak;\n\t\tcase 'APIRecurringHoliday':\n\t\t\tscript_name = 'RecurringHolidayView';\n\t\t\tbreak;\n\t\tcase 'APIRoundIntervalPolicy':\n\t\t\tscript_name = 'RoundIntervalPolicyView';\n\t\t\tbreak;\n\t\tcase 'APISchedulePolicy':\n\t\t\tscript_name = 'SchedulePolicyView';\n\t\t\tbreak;\n\t\tcase 'APIUserReportData':\n\t\t\tscript_name = 'UserReportDataView';\n\t\t\tbreak;\n\t\tcase 'APIInstall':\n\t\t\tscript_name = 'InstallView';\n\t\t\tbreak;\n\t}\n\n\treturn script_name;\n};\n\n/* jshint ignore:end */\n\nGlobal.isObject = function( obj ) {\n\tif ( obj !== null && typeof obj === 'object' ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n};\n\nGlobal.isArray = function( obj ) {\n\n\tif ( Object.prototype.toString.call( obj ) !== '[object Array]' ) {\n\t\treturn false;\n\t}\n\n\treturn true;\n};\n\nGlobal.isString = function( obj ) {\n\n\tif ( Object.prototype.toString.call( obj ) !== '[object String]' ) {\n\t\treturn false;\n\t}\n\n\treturn true;\n};\n\nGlobal.isValidDate = function( obj ) {\n\tif ( obj instanceof Date && !isNaN( obj ) ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n};\n\nGlobal.decodeCellValue = function( val ) {\n\tif ( !val || _.isObject( val ) ) {\n\t\treturn val;\n\t}\n\tval = val.toString();\n\tval = val.replace( /\\n|\\r|(\\r\\n)|(\\u0085)|(\\u2028)|(\\u2029)/g, ' ' );\n\tval = val.replace( /\\n|\\r|(\\r\\n)|(\\u0085)|(\\u2028)|(\\u2029)/g, ' ' );\n\tval = Global.htmlEncode( val );\n\tval = val.replace( /<br>/g, ' ' );\n\n\treturn val;\n};\n\nGlobal.buildTreeRecord = function( array, parentId ) {\n\tvar finalArray = [];\n\n\t$.each( array, function( key, item ) {\n\t\titem.expanded = true;\n\t\titem.loaded = true;\n\n\t\tif ( Global.isSet( parentId ) ) {\n\t\t\titem.parent = parentId;\n\t\t}\n\n\t\tfinalArray.push( item );\n\n\t\tif ( Global.isSet( item.children ) ) {\n\t\t\tvar childrenArray = Global.buildTreeRecord( item.children, item.id );\n\t\t\tfinalArray = finalArray.concat( childrenArray );\n\t\t} else {\n\t\t\titem.isLeaf = true;\n\t\t}\n\n\t} );\n\n\treturn finalArray;\n};\n\nGlobal.getParentIdByTreeRecord = function( array, selectId ) {\n\n\tvar retval = [];\n\tfor ( var i = 0; i < array.length; i++ ) {\n\t\tvar item = array[i];\n\t\tif ( item.id.toString() === selectId.toString() ) {\n\t\t\tvar new_row = {};\n\t\t\tif ( typeof item.parent != 'undefined' ) {\n\t\t\t\tnew_row = { parent_id: item.parent.toString(), name: item.name };\n\t\t\t} else {\n\t\t\t\tnew_row = { name: item.name };\n\t\t\t}\n\n\t\t\t//Without created and updated info, audit tab shows N/A for both\n\t\t\tif ( typeof item.created_by != 'undefined' ) {\n\t\t\t\tnew_row.created_by = item.created_by;\n\t\t\t\tnew_row.created_date = item.created_date;\n\t\t\t\tnew_row.updated_by = item.updated_by;\n\t\t\t\tnew_row.updated_date = item.updated_date;\n\t\t\t}\n\n\t\t\tretval.push( new_row );\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn retval;\n\n};\n\nGlobal.addFirstItemToArray = function( array, firstItemType, customLabel ) {\n\t//Error: Unable to get property 'unshift' of undefined or null reference in /interface/html5/global/Global.js?v=8.0.0-20141230-153942 line 903\n\tvar label;\n\tif ( array ) {\n\t\tif ( firstItemType === 'any' ) {\n\t\t\tif ( customLabel ) {\n\t\t\t\tlabel = customLabel;\n\t\t\t} else {\n\t\t\t\tlabel = Global.any_item;\n\t\t\t}\n\t\t\t//#2301 - don't duplicate the --Any-- case when the array is recycled.\n\t\t\tif ( !array[0] || array[0].value != _global_TTUUID__WEBPACK_IMPORTED_MODULE_0__/* .TTUUID.not_exist_id */ .d.not_exist_id ) {\n\t\t\t\tarray.unshift( {\n\t\t\t\t\tlabel: label,\n\t\t\t\t\tvalue: _global_TTUUID__WEBPACK_IMPORTED_MODULE_0__/* .TTUUID.not_exist_id */ .d.not_exist_id,\n\t\t\t\t\tfullValue: _global_TTUUID__WEBPACK_IMPORTED_MODULE_0__/* .TTUUID.not_exist_id */ .d.not_exist_id,\n\t\t\t\t\torderValue: ''\n\t\t\t\t} );\n\t\t\t}\n\t\t} else if ( firstItemType === 'empty' ) {\n\t\t\tif ( customLabel ) {\n\t\t\t\tlabel = customLabel;\n\t\t\t} else {\n\t\t\t\tlabel = Global.empty_item;\n\t\t\t}\n\t\t\t//#2301 - don't duplicate the --None-- case when the array is recycled.\n\t\t\tif ( !array[0] || array[0].value != _global_TTUUID__WEBPACK_IMPORTED_MODULE_0__/* .TTUUID.zero_id */ .d.zero_id ) {\n\t\t\t\tarray.unshift( {\n\t\t\t\t\tlabel: label,\n\t\t\t\t\tvalue: _global_TTUUID__WEBPACK_IMPORTED_MODULE_0__/* .TTUUID.zero_id */ .d.zero_id,\n\t\t\t\t\tfullValue: _global_TTUUID__WEBPACK_IMPORTED_MODULE_0__/* .TTUUID.zero_id */ .d.zero_id,\n\t\t\t\t\torderValue: ''\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn array;\n};\n\n//Add item on to the end of the array, but make sure its not already there and therefore never duplicated.\nGlobal.addLastItemToArray = function( array, key, label ) {\n\tvar label;\n\tif ( array ) {\n\t\tvar last_array_element = array[( array.length - 1 )];\n\t\tif ( last_array_element.value != key ) {\n\t\t\tarray.push( {\n\t\t\t\tfullValue: key,\n\t\t\t\tvalue: key,\n\t\t\t\tlabel: label,\n\t\t\t\tid: 2000\n\t\t\t} );\n\t\t}\n\t}\n\n\treturn array;\n};\n\nGlobal.convertRecordArrayToOptions = function( array ) {\n\tvar len = array.length;\n\tvar options = {};\n\n\tfor ( var i = 0; i < len; i++ ) {\n\t\tvar item = array[i];\n\n\t\toptions[item.value] = item.label;\n\t}\n\n\treturn options;\n};\n\nGlobal.buildColumnArray = function( array ) {\n\tvar columns = [];\n\tvar id = 1000;\n\n\tfor ( var key in array ) {\n\t\tvar order_value = Global.getSortValue( key, true );\n\t\tvar column = {\n\t\t\tlabel: array[key],\n\t\t\tvalue: Global.removeSortPrefix( key ),\n\t\t\torderValue: order_value,\n\t\t\tid: id\n\t\t};\n\t\tcolumns.push( column );\n\t\tid = id + 1;\n\t}\n\treturn columns;\n};\n\nGlobal.removeSortPrefixFromArray = function( array ) {\n\tvar finalArray = {};\n\n\tif ( Global.isSet( array ) ) {\n\n\t\t$.each( array, function( key, item ) {\n\t\t\tfinalArray[Global.removeSortPrefix( key )] = item;\n\t\t} );\n\n\t\treturn finalArray;\n\t}\n\n\treturn array;\n};\n\nGlobal.removeSortPrefix = function( key ) {\n\tif ( typeof key == 'string' && key.match( Global.sortOrderRegex ) ) {\n\t\tkey = key.replace( Global.sortOrderRegex, '' );\n\t}\n\treturn key;\n};\n\nGlobal.getSortValue = function( key, return_key_on_null ) {\n\tvar order_value = 999;\n\tif ( typeof key == 'string' ) {\n\t\tvar regex_result = key.match( Global.sortOrderRegex );\n\t\tif ( regex_result == null ) {\n\t\t\tif ( return_key_on_null === true ) {\n\t\t\t\torder_value = key;\n\t\t\t}\n\t\t} else if ( regex_result[1] ) {\n\t\t\torder_value = regex_result[1];\n\t\t} else {\n\t\t\tDebug.Error( 'Error: Unable to parse order_value', 'Global', 'Global', 'buildColumnArray', 10 );\n\t\t}\n\t}\n\treturn order_value;\n};\n\nGlobal.convertToNumberIfPossible = function( val ) {\n\t//if value is number convert to number type\n\tvar reg = new RegExp( '^[0-9]*$' );\n\n\tif ( reg.test( val ) && val !== '00' ) {\n\t\tval = parseFloat( val );\n\t}\n\n\tif ( val === '-1' || val === -1 ) {\n\t\tval = -1;\n\t}\n\n\treturn val;\n};\n\nGlobal.buildRecordArray = function( array, first_item, orderType ) {\n\tvar finalArray = [];\n\n\tif ( first_item ) {\n\t\tfinalArray.push( first_item );\n\t}\n\n\tvar id = 1000;\n\n\tif ( Global.isSet( array ) ) {\n\n\t\tfor ( var key in array ) {\n\t\t\tvar item = array[key];\n\t\t\tvar value = Global.removeSortPrefix( key );\n\t\t\tvar order_value = Global.getSortValue( key );\n\n\t\t\t// 6/4 changed id to same as value to make flex show correct data when show search result saved in html5, flex use id if it existed.\n\t\t\tvar record = { label: item, value: value, fullValue: key, orderValue: order_value, id: value };\n\n\t\t\tid = id + 1;\n\n\t\t\tfinalArray.push( record );\n\n\t\t}\n\n\t}\n\n\treturn finalArray;\n\n};\n\nGlobal.topContainer = function() {\n\treturn $( '#topContainer' );\n};\n\nGlobal.overlay = function() {\n\treturn $( '#overlay' );\n};\n\nGlobal.bottomContainer = function() {\n\treturn $( '#bottomContainer' );\n};\n\nGlobal.bottomFeedbackLinkContainer = function() {\n\treturn $( '#feedbackLinkContainer' );\n};\n\nGlobal.showPoweredBy = function() {\n\tvar powered_by_img = $( '#powered_by' );\n\tpowered_by_img.show();\n\tpowered_by_img.attr( 'src', _services_ServiceCaller__WEBPACK_IMPORTED_MODULE_5__/* .ServiceCaller.getURLByObjectType */ .n.getURLByObjectType( 'copyright' ) );\n\tpowered_by_img.attr( 'alt', LocalCacheData.loginData.application_name + ' Workforce Management Software' );\n\tvar powered_by_link = $( '' );\n\tpowered_by_link.addClass( 'powered-by-img-seo' );\n\tpowered_by_img.wrap( powered_by_link );\n};\n\nGlobal.setSignalStrength = function() {\n\tif ( Global.signal_timer ) {\n\t\treturn;\n\t}\n\t$( '.signal-strength' ).css( 'display', 'block' );\n\tvar status = '......';\n\tvar average_time = 0;\n\tvar checking_array = [];\n\tvar single_strength = null;\n\tvar single_strength_tooltip = null;\n\n\tsetTooltip();\n\n\tsetTimeout( function() {\n\t\tdoPing();\n\t}, 10000 );\n\tGlobal.signal_timer = setInterval( function() {\n\t\tdoPing();\n\t}, 60000 );\n\n\tfunction doPing() {\n\t\tif ( ( LocalCacheData.current_open_primary_controller && LocalCacheData.current_open_primary_controller.viewId === 'LoginView' ) || Global.idle_time >= Math.min( 15, APIGlobal.pre_login_data.session_idle_timeout / 60 ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tping( _services_ServiceCaller__WEBPACK_IMPORTED_MODULE_5__/* .ServiceCaller.base_url */ .n.base_url + 'interface/ping.html?t=' + new Date().getTime(), function( time ) {\n\t\t\t$( '.signal-strength-empty' ).removeClass( 'signal-strength-empty' );\n\n\t\t\tif ( checking_array.length >= 3 ) {\n\t\t\t\tchecking_array.shift();\n\t\t\t}\n\t\t\tchecking_array.push( time );\n\t\t\tvar total_time = 0;\n\t\t\tfor ( var i = 0; i < checking_array.length; i++ ) {\n\t\t\t\ttotal_time = checking_array[i] + total_time;\n\t\t\t}\n\t\t\taverage_time = total_time / checking_array.length;\n\t\t\tDebug.Text( 'Current Ping: ' + time + 'ms Average: ' + average_time + 'ms Date: ' + ( new Date ).toISOString().replace( /z|t/gi, ' ' ), 'Global.js', '', 'doPing', 6 );\n\t\t\tGlobal.current_ping = average_time;\n\t\t\tstatus = $.i18n._( 'Good' );\n\t\t\t//do not allow signal strength variation in unit test mode\n\t\t\tif ( Global.UNIT_TEST_MODE == false ) {\n\t\t\t\tif ( average_time > 400 ) {\n\t\t\t\t\t$( '.signal-strength-pretty-strong' ).addClass( 'signal-strength-empty' );\n\t\t\t\t\t$( '.signal-strength-strong' ).addClass( 'signal-strength-empty' );\n\t\t\t\t\t$( '.signal-strength-weak' ).addClass( 'signal-strength-empty' );\n\t\t\t\t\tstatus = $.i18n._( 'Poor' );\n\t\t\t\t} else if ( average_time > 250 ) {\n\t\t\t\t\t$( '.signal-strength-pretty-strong' ).addClass( 'signal-strength-empty' );\n\t\t\t\t\t$( '.signal-strength-strong' ).addClass( 'signal-strength-empty' );\n\t\t\t\t\tstatus = $.i18n._( 'Below Average' );\n\t\t\t\t} else if ( average_time > 150 ) {\n\t\t\t\t\t$( '.signal-strength-pretty-strong' ).addClass( 'signal-strength-empty' );\n\t\t\t\t\tstatus = $.i18n._( 'Average' );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsetTooltip();\n\n\t\t} );\n\t}\n\n\tfunction setTooltip() {\n\t\tvar html = '
';\n\t\t$( '.signal-strength' ).qtip( {\n\t\t\tid: 'single_strength',\n\t\t\tcontent: {\n\t\t\t\ttext: html\n\t\t\t},\n\t\t\tposition: {\n\t\t\t\tmy: 'bottom left',\n\t\t\t\tat: 'top right'\n\t\t\t}\n\t\t} );\n\t}\n\n\tfunction ping( url, callback ) {\n\t\tvar inUse, start, img, timer;\n\t\tif ( !inUse ) {\n\t\t\tinUse = true;\n\t\t\timg = new Image();\n\t\t\timg.onload = function() {\n\t\t\t\tvar endTime = new Date().getTime();\n\t\t\t\tinUse = false;\n\t\t\t\tcallback( ( endTime - start ) );\n\n\t\t\t};\n\t\t\timg.onerror = function( e ) {\n\t\t\t\tif ( inUse ) {\n\t\t\t\t\tinUse = false;\n\t\t\t\t\tvar endTime = new Date().getTime();\n\t\t\t\t\tcallback( ( endTime - start ) );\n\t\t\t\t}\n\n\t\t\t};\n\t\t\tstart = new Date().getTime();\n\t\t\timg.src = url;\n\t\t\ttimer = setTimeout( function() {\n\t\t\t\tif ( inUse ) {\n\t\t\t\t\tvar endTime = new Date().getTime();\n\t\t\t\t\tinUse = false;\n\t\t\t\t\tcallback( ( endTime - start ) );\n\t\t\t\t}\n\t\t\t}, 5000 );\n\t\t}\n\t}\n};\n\nGlobal.contentContainer = function() {\n\treturn $( '#contentContainer' );\n};\n\nGlobal.bodyWidth = function() {\n\treturn $( window ).width();\n};\n\nGlobal.bodyHeight = function() {\n\treturn $( window ).height();\n};\n\nGlobal.hasRequireLoaded = function( script_path ) {\n\tvar split_script_path = script_path.split( '/' );\n\n\tvar id = split_script_path[split_script_path.length - 1];\n\tid = id.replace( '.js', '' );\n\n\t//Check alternative script names (ie: with/without the .js) when a full path is specified to see if it was loaded in different ways with requireJS and make sure its not loaded twice.\n\tif ( script_path.indexOf( '.js' ) == -1 ) {\n\t\tvar alternative_script_path = script_path + '.js';\n\t} else {\n\t\tvar alternative_script_path = script_path.replace( '.js', '' );\n\t}\n\n\t//Make sure the function is both specified and defined. This helps cases where the user is on a Slow 3G network and double clicks Attendance -> In/Out.\n\t// In this case the same InOutViewController.js file is in the process of being loaded, then is cancelled,\n\t// and another one tries to load and the success callback where the class is instantiated is called before it can be instantiated, causing a JS exception (ReferenceError: InOutViewController is not defined).\n\t// Better double-click prevention would also help.\n\t// if ( typeof require === 'function' && typeof require.specified === 'function' && ( require.specified( id ) || require.specified( script_path ) || require.specified( alternative_script_path ) ) ) {\n\t// if ( typeof require === 'function' && typeof require.defined === 'function' && ( require.defined( id ) || require.defined( script_path ) || require.defined( alternative_script_path ) ) ) {\n\t// \treturn true;\n\t// //}\n\n\treturn false;\n};\n\nGlobal.loadScript = function( scriptPath, onResult ) {\n\tif ( typeof scriptPath !== 'string' ) {\n\t\t// Not ideal fix but this is to handle the scriptPath.split is not a function error in #2696. if the path is not a string, split does not exist as a function.\n\t\t// Hard to find root-cause/reproduce, so this fix is to reduce the occurances of the JS exceptions related to it.\n\t\treturn false;\n\t}\n\n\tvar async = true;\n\tif ( typeof ( onResult ) === 'undefined' ) {\n\t\tasync = false;\n\t}\n\n\tif ( Global.hasRequireLoaded( scriptPath ) ) {\n\t\tif ( async ) {\n\t\t\tonResult();\n\t\t}\n\t\treturn true;\n\t}\n\n\t//Ensures that the js cached scripts are not loaded twice\n\tif ( async ) {\n\t\tif ( LocalCacheData.loadedScriptNames[scriptPath] ) {\n\t\t\tonResult();\n\t\t\treturn;\n\t\t}\n\t} else {\n\t\tif ( LocalCacheData.loadedScriptNames[scriptPath] ) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tvar successflag = false;\n\n\tvar realPath = scriptPath;\n\n\t// Mainly used in the async code, but put here to also catch duplicate declared classes in both async and synchronous calls.\n\tvar split_script_path = realPath.split( '/' );\n\tvar import_file_name = split_script_path[split_script_path.length - 1].replace( '.js', '' );\n\t//var import_path = realPath.replace('views/', '');\n\n\tvar class_exists = eval(\"typeof \"+ import_file_name +\" === 'function'\");\n\tif ( class_exists ) {\n\t\t// This means class already exists on the window object, so it must have been already loaded.\n\t\t// DEV NOTE: This should NOT happen. If it happens, it means script is being loaded twice. Check manual loading calls like requirejs or Webpack MergeIntoSingleFilePlugin plugin\n\t\t// In all likelyhood, it is listed in the concatenation array for MergeIntoSingleFilePlugin. Best to try to remove it from there, as long as its correctly loaded on demand in all relevant places. See what else uses the class to be sure.\n\t\tGlobal.sendAnalyticsEvent( 'error:scriptload:duplicate_class', 'load', 'error:scriptload:duplicate:'+ scriptPath );\n\t\tDebug.Error( 'Duplicate class declaration: '+ import_file_name, 'Global.js', 'Global', 'loadScript', 1 );\n\t\treturn true;\n\t}\n\n\tif ( Global.url_offset ) {\n\t\trealPath = Global.getBaseURL( Global.url_offset + realPath );\n\t}\n\n\tif ( async ) {\n\t\tDebug.Text( 'ASYNC-LOADING: ' + scriptPath, 'Global.js', 'Global', 'loadScript', 10 );\n\n\t\tvar import_path;\n\t\tif ( scriptPath.indexOf('views') !== -1 ){\n\t\t\timport_path = scriptPath.replace('views/', ''); // This is to ensure the variable in the dynamic webpack import() is a single variable rather than a full path.\n\t\t\t__webpack_require__(1430)(`./${import_path}`).then((module) => {\n\t\t\t\tif ( module && module[import_file_name] ) {\n\t\t\t\t\twindow[import_file_name] = module[import_file_name]; // After html2js this may not be needed anymore. But leave for now as this allows the legacy html files to trigger the 'new MyViewController()' code in their html files.\n\n\t\t\t\t\tLocalCacheData.loadedScriptNames[scriptPath] = true;\n\t\t\t\t\tonResult();\n\t\t\t\t} else {\n\t\t\t\t\tif( import_file_name === 'debugPanelController') {\n\t\t\t\t\t\t// debugPanel is coded different, with no classes/constructor, so this is not a fail.\n\t\t\t\t\t\tLocalCacheData.loadedScriptNames[scriptPath] = true;\n\t\t\t\t\t\tonResult();\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Loading class failed.\n\t\t\t\t\t\t// If there is not an attribute matching the class on the module result, then this suggests a missing export on the class. There will also be a default attribute with an empty object to show no default classes exported.\n\t\t\t\t\t\tDebug.Error( 'Loading view class failed. Potential missing export for: ' + import_file_name, 'Global.js', 'Global', 'loadScript', 1 );\n\n\t\t\t\t\t\tonResult(); // To allow callbacks to work for non-module scripts like debugPanelController.\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} ).catch( Global.importErrorHandler );\n\t\t} else if ( scriptPath.indexOf('global/widgets') !== -1 ) {\n\t\t\timport_path = scriptPath.replace('global/widgets/', ''); // This is to ensure the variable in the dynamic webpack import() is a single variable rather than a full path.\n\t\t\t__webpack_require__(9769)(`./${import_path}`).then((module) => {\n\t\t\t\tif( module && module[import_file_name] ) {\n\t\t\t\t\twindow[import_file_name] = module[import_file_name];\n\t\t\t\t\tLocalCacheData.loadedScriptNames[scriptPath] = true;\n\t\t\t\t\tonResult();\n\t\t\t\t} else {\n\t\t\t\t\t// Loading class failed.\n\t\t\t\t\t// If there is not an attribute matching the class on the module result, then this suggests a missing export on the class. There will also be a default attribute with an empty object to show no default classes exported.\n\t\t\t\t\t// This could also be a widget that is historically meant to load synchronously with the jQuery.ajax code further down. If this is the case, refactor the callback to load the widget syncronously instead.\n\t\t\t\t\tDebug.Error( 'Loading widget class failed. Potential missing export for: '+ import_file_name, 'Global.js', 'Global', 'loadScript', 1 );\n\t\t\t\t}\n\n\t\t\t} ).catch( Global.importErrorHandler );\n\t\t} else {\n\t\t\tDebug.Error( 'Loading class failed. Unhandled file type path request: '+ scriptPath, 'Global.js', 'Global', 'loadScript', 1 );\n\t\t}\n\n\t} else {\n\t\tvar calling_script = '';\n\t\tif ( LocalCacheData.current_open_primary_controller && LocalCacheData.current_open_primary_controller.viewId ) {\n\t\t\tcalling_script = ' from ' + LocalCacheData.current_open_primary_controller.viewId + 'ViewController';\n\t\t}\n\t\tDebug.Text( 'SYNC-LOADING: ' + scriptPath + calling_script );\n\n\t\tvar id = scriptPath.split( '/' );\n\t\tvar id = id[id.length - 1];\n\t\tid = id.replace( '.js', '' );\n\t\tif ( !window.badScripts ) {\n\t\t\twindow.badScripts = [];\n\t\t}\n\t\twindow.badScripts.push( id ); //When the page is done loading punch \"badScripts into the console to see a nice array of all the scripts that were not loaded async.\n\n\t\t/**\n\t\t * this seems to work, but causes the script erro at line 0 problem.\n\t\t * try to refactor to not use jquery.ajax\n\t\t */\n\t\tjQuery.ajax( {\n\t\t\tasync: false,\n\t\t\ttype: 'GET',\n\t\t\turl: realPath + '?v=' + APIGlobal.pre_login_data.application_build,\n\t\t\tcrossOrigin: false,\n\t\t\tdata: null,\n\t\t\tcache: true,\n\t\t\tsuccess: function() {\n\t\t\t\tsuccessflag = true;\n\t\t\t\tif ( async ) {\n\t\t\t\t\tLocalCacheData.loadedScriptNames[scriptPath] = true;\n\t\t\t\t\tonResult();\n\t\t\t\t}\n\t\t\t},\n\t\t\terror: function( jqXHR, textStatus, errorThrown ) {\n\t\t\t\tTAlertManager.showNetworkErrorAlert( jqXHR, textStatus, errorThrown );\n\t\t\t},\n\t\t\tdataType: 'script'\n\t\t} );\n\t}\n\n\tif ( !async ) {\n\t\tLocalCacheData.loadedScriptNames[scriptPath] = true;\n\t\treturn ( successflag );\n\t}\n\n};\n\nGlobal.importErrorHandler = function( error ) {\n\tif ( error.name == 'ChunkLoadError' ) {\n\t\tif ( window.script_error_shown === undefined ) {\n\t\t\twindow.script_error_shown = 1;\n\t\t\t//There is no pretty errorbox at this time. You may only have basic javascript.\n\t\t\tif ( confirm( 'Unable to download required data. Your internet connection may have failed press Ok to reload.' ) ) {\n\t\t\t\t//For testing, so that there's time to turn internet back on after confirm is clicked.\n\t\t\t\t//window.setTimeout(function() {window.location.reload()},5000);\n\n\t\t\t\t//This can also happen if the user manually modifies the URL to be a bogus ViewId (ie: #!m=homeABC)\n\t\t\t\t//So try to redirect back to the home page first, otherwise try to do a browser reload.\n\t\t\t\tif ( _services_ServiceCaller__WEBPACK_IMPORTED_MODULE_5__/* .ServiceCaller.root_url */ .n.root_url && APIGlobal.pre_login_data.base_url ) {\n\t\t\t\t\tGlobal.setURLToBrowser( _services_ServiceCaller__WEBPACK_IMPORTED_MODULE_5__/* .ServiceCaller.root_url */ .n.root_url + APIGlobal.pre_login_data.base_url );\n\t\t\t\t} else {\n\t\t\t\t\twindow.location.reload();\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\t\tconsole.debug( error.message );\n\t\t//Stop error from bubbling up.\n\t\t// delete e; // commented out from old code as webpack complains about deleting local variable in strict mode.\n\n\t} else {\n\t\tDebug.Error( 'Error loading script during import(): ' + error, 'Global.js', 'Global', 'importErrorHandler', 1 );\n\t\t// Throw general error?\n\t}\n};\n\nGlobal.getRealImagePath = function( path ) {\n\n\tvar realPath = 'theme/' + Global.theme + '/' + path;\n\n\tif ( Global.url_offset ) {\n\t\trealPath = Global.url_offset + realPath;\n\t}\n\n\treturn realPath;\n};\n\nGlobal.getRibbonIconRealPath = function( icon ) {\n\tvar realPath = 'theme/' + Global.theme + '/css/global/widgets/ribbon/icons/' + icon;\n\n\tif ( Global.url_offset ) {\n\t\trealPath = Global.url_offset + realPath;\n\t}\n\n\treturn realPath;\n};\n\nGlobal.loadLanguage = function( name ) {\n\tvar successflag = false;\n\tvar message_id = _global_TTUUID__WEBPACK_IMPORTED_MODULE_0__/* .TTUUID.generateUUID */ .d.generateUUID();\n\tProgressBar.showProgressBar( message_id );\n\tvar res_data = {};\n\n\tif ( LocalCacheData.getI18nDic() ) {\n\t\tProgressBar.removeProgressBar( message_id );\n\t\treturn LocalCacheData.getI18nDic();\n\t}\n\tvar realPath = '../locale/' + name + '/LC_MESSAGES/messages.json' + '?v=' + APIGlobal.pre_login_data.application_build;\n\n\tif ( Global.url_offset ) {\n\t\trealPath = Global.url_offset + realPath;\n\t}\n\n\tjQuery.ajax( {\n\t\tasync: false,\n\t\ttype: 'GET',\n\t\turl: realPath,\n\t\tdata: null,\n\t\tcache: true,\n\t\tconverters: {\n\t\t\t//Because this is a dataType: script, and jquery will blindy try to eval() any result returned by the server, including a HTML 404 error message.\n\t\t\t// resulting in\" Uncaught SyntaxError: Unexpected token < in line 1\" being triggered.\n\t\t\t// Instead just return the raw result and eval() it in the success function ourselves instead.\n\t\t\t'text script': function( text ) {\n\t\t\t\treturn text;\n\t\t\t}\n\t\t},\n\t\tsuccess: function( result ) {\n\t\t\tsuccessflag = true;\n\t\t\tjQuery.globalEval( result );\n\t\t},\n\t\terror: function( jqXHR, textStatus, errorThrown ) {\n\t\t\t//Unable to load or parse i18n dictionary. Could be due to a 404 error?\n\t\t\tDebug.Text( 'Unable to load Locale: ' + errorThrown, 'Global.js', '', 'loadLanguage', 10 );\n\t\t\tsuccessflag = false;\n\t\t},\n\t\tdataType: 'script'\n\t} );\n\n\tProgressBar.removeProgressBar( message_id );\n\n\tif ( successflag ) {\n\t\tLocalCacheData.setI18nDic( i18n_dictionary );\n\t} else {\n\t\tLocalCacheData.setI18nDic( {} );\n\t}\n\n\treturn successflag;\n};\n\nGlobal.getProductEdition = function() {\n\tvar current_company_data = LocalCacheData.getCurrentCompany();\n\n\tif ( current_company_data && current_company_data.product_edition_id ) {\n\t\treturn current_company_data.product_edition_id;\n\t}\n\n\treturn 10; //Community\n};\n\nGlobal.setURLToBrowser = function( new_url ) {\n\tif ( new_url != window.location.href ) {\n\t\tDebug.Text( 'Changing URL to: ' + new_url, 'Global.js', 'Global', 'setURLToBrowser', 9 );\n\t\twindow.location = new_url;\n\t}\n};\n\nGlobal.clone = function( obj ) {\n\treturn jQuery.extend( true, {}, obj ); // true means deep clone, omit for shallow, false is not an option\n};\n\nGlobal.getFirstKeyFromObject = function( obj ) {\n\tfor ( var key in obj ) {\n\n\t\tif ( obj.hasOwnProperty( key ) ) {\n\t\t\treturn key;\n\t\t}\n\n\t}\n};\n\nGlobal.getFuncName = function( _callee ) {\n\tvar _text = _callee.toString();\n\tvar _scriptArr = document.scripts;\n\tfor ( var i = 0; i < _scriptArr.length; i++ ) {\n\t\tvar _start = _scriptArr[i].text.indexOf( _text );\n\t\tif ( _start !== -1 ) {\n\t\t\tif ( /^function\\s*\\(.*\\).*\\r\\n/.test( _text ) ) {\n\t\t\t\tvar _tempArr = _scriptArr[i].text.substr( 0, _start ).split( '\\r\\n' );\n\t\t\t\treturn _tempArr[( _tempArr.length - 1 )].replace( /(var)|(\\s*)/g, '' ).replace( /=/g, '' );\n\t\t\t} else {\n\t\t\t\treturn _text.match( /^function\\s*([^\\(]+).*\\r\\n/ )[1];\n\t\t\t}\n\t\t}\n\t}\n};\n\nGlobal.concatArraysUniqueWithSort = function( thisArray, otherArray ) {\n\tvar newArray = thisArray.concat( otherArray ).sort( function( a, b ) {\n\t\treturn a > b ? 1 : a < b ? -1 : 0;\n\t} );\n\n\treturn newArray.filter( function( item, index ) {\n\t\treturn newArray.indexOf( item ) === index;\n\t} );\n};\n\nGlobal.addCss = function( path, callback ) {\n\tif ( LocalCacheData.loadedScriptNames[path] ) {\n\t\tif ( callback ) {\n\t\t\tcallback();\n\t\t}\n\t\treturn true;\n\t}\n\tLocalCacheData.loadedScriptNames[path] = true;\n\tvar realPath = 'theme/' + Global.theme + '/css/' + path;\n\tif ( Global.url_offset ) {\n\t\trealPath = Global.url_offset + realPath;\n\t}\n\trealPath = realPath + '?v=' + APIGlobal.pre_login_data.application_build;\n\tGlobal.loadStyleSheet( realPath, callback );\n};\n\n//JS think 0 is false, so use this to get 0 correctly.\nGlobal.isFalseOrNull = function( object ) {\n\n\tif ( object === false || object === null || object === 0 || object === '0' || object == _global_TTUUID__WEBPACK_IMPORTED_MODULE_0__/* .TTUUID.zero_id */ .d.zero_id ) {\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n\n};\n\nGlobal.isSet = function( object ) {\n\n\tif ( _.isUndefined( object ) || _.isNull( object ) ) {\n\t\treturn false;\n\t} else {\n\t\treturn true;\n\t}\n\n};\n\nGlobal.getIconPathByContextName = function( id ) {\n\n\tswitch ( id ) {\n\t\tcase 'add':\n\t\t\treturn Global.getRealImagePath( 'css/global/widgets/ribbon/icons/copy-35x35.png' );\n\t}\n};\n\nGlobal.isEmpty = function( obj ) {\n\n\t// null and undefined are \"empty\"\n\tif ( obj === null ) {\n\t\treturn true;\n\t}\n\n\t// Assume if it has a length property with a non-zero value\n\t// that that property is correct.\n\tif ( obj.length > 0 ) {\n\t\treturn false;\n\t}\n\tif ( obj.length === 0 ) {\n\t\treturn true;\n\t}\n\n\t// Otherwise, does it have any properties of its own?\n\t// Note that this doesn't handle\n\t// toString and valueOf enumeration bugs in IE < 9\n\tfor ( var key in obj ) {\n\t\tif ( hasOwnProperty.call( obj, key ) ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n\n};\n\nGlobal.convertColumnsTojGridFormat = function( columns, layout_name, setWidthCallBack ) {\n\tvar column_info_array = [];\n\tvar len = columns.length;\n\n\tvar total_width = 0;\n\tfor ( var i = 0; i < len; i++ ) {\n\t\tvar view_column_data = columns[i];\n\t\tvar column_info;\n\n\t\tvar text_width = Global.calculateTextWidth( view_column_data.label );\n\n\t\ttotal_width = total_width + text_width;\n\n\t\tif ( view_column_data.label === '' ) {\n\t\t\tcolumn_info = {\n\t\t\t\tname: view_column_data.value,\n\t\t\t\tindex: view_column_data.value,\n\t\t\t\tlabel: view_column_data.label,\n\t\t\t\tkey: true,\n\t\t\t\twidth: 100,\n\t\t\t\tsortable: false,\n\t\t\t\thidden: true,\n\t\t\t\ttitle: false\n\t\t\t};\n\t\t} else if ( layout_name === 'global_sort_columns' ) {\n\n\t\t\tif ( view_column_data.value === 'sort' ) {\n\t\t\t\tcolumn_info = {\n\t\t\t\t\tname: view_column_data.value,\n\t\t\t\t\tindex: view_column_data.value,\n\t\t\t\t\tlabel: view_column_data.label,\n\t\t\t\t\twidth: 100,\n\t\t\t\t\tsortable: false,\n\t\t\t\t\tformatter: 'select',\n\t\t\t\t\teditable: true,\n\t\t\t\t\ttitle: false,\n\t\t\t\t\tedittype: 'select',\n\t\t\t\t\teditoptions: { value: 'asc:ASC;desc:DESC' }\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tcolumn_info = {\n\t\t\t\t\tname: view_column_data.value,\n\t\t\t\t\tindex: view_column_data.value,\n\t\t\t\t\tlabel: view_column_data.label,\n\t\t\t\t\twidth: 100,\n\t\t\t\t\tsortable: false,\n\t\t\t\t\ttitle: false\n\t\t\t\t};\n\t\t\t}\n\n\t\t} else {\n\t\t\tcolumn_info = {\n\t\t\t\tname: view_column_data.value,\n\t\t\t\tindex: view_column_data.value,\n\t\t\t\tlabel: view_column_data.label,\n\t\t\t\twidth: 100,\n\t\t\t\tsortable: false,\n\t\t\t\ttitle: false\n\t\t\t};\n\t\t}\n\n\t\tcolumn_info_array.push( column_info );\n\t}\n\n\tif ( setWidthCallBack ) {\n\t\tsetWidthCallBack( total_width );\n\t}\n\n\treturn column_info_array;\n};\n/* jshint ignore:start */\nGlobal.loadWidgetByName = function( widgetName, raw_text ) {\n\tvar input = false;\n\tvar widget_path = false;\n\tvar widget_constructor = false;\n\tvar raw_text = false;\n\tswitch ( widgetName ) {\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.COLOR_PICKER:\n\t\t\tinput = $.fn.TColorPicker.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.FORMULA_BUILDER:\n\t\t\tinput = $.fn.FormulaBuilder.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.AWESOME_BOX:\n\t\t\tinput = $.fn.AComboBox.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.AWESOME_DROPDOWN:\n\t\t\tinput = $.fn.ADropDown.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.TEXT_INPUT:\n\t\t\tinput = $.fn.TTextInput.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.PASSWORD_INPUT:\n\t\t\tinput = $.fn.TPasswordInput.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.TEXT:\n\t\t\tinput = $.fn.TText.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.CHECKBOX:\n\t\t\tinput = $.fn.TCheckbox.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.COMBO_BOX:\n\t\t\tinput = $.fn.TComboBox.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.LIST: //Does not seem to be used anywhere.\n\t\t\tinput = $.fn.TList.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.TAG_INPUT:\n\t\t\tinput = $.fn.TTagInput.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.DATE_PICKER:\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.RANGE_PICKER:\n\t\t\tinput = $.fn.TDatePicker.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.TIME_PICKER:\n\t\t\tinput = $.fn.TTimePicker.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.TEXT_AREA:\n\t\t\tinput = $.fn.TTextArea.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.TINYMCE_TEXT_AREA:\n\t\t\tinput = $.fn.TTextArea.tinymce_html_template;\n\t\t\traw_text = true;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.SEPARATED_BOX:\n\t\t\tinput = $.fn.SeparatedBox.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.IMAGE_BROWSER:\n\t\t\tinput = $.fn.TImageBrowser.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.FILE_BROWSER: //There is no file browser JS file for this widget.\n\t\t\tinput = `
\n\t\t\t\t\t\t\n\t\t\t\t\t
`;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.IMAGE_AVD_BROWSER:\n\t\t\tinput = $.fn.TImageAdvBrowser.html_template;\n\t\t\twidget_constructor = 'TImageAdvBrowser';\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.CAMERA_BROWSER:\n\t\t\tinput = $.fn.CameraBrowser.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.IMAGE_CUT:\n\t\t\tinput = $.fn.TImageCutArea.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.IMAGE:\n\t\t\tinput = '';\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.INSIDE_EDITOR:\n\t\t\tinput = $.fn.InsideEditor.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.WidgetNamesDic.PAGING:\n\t\t\t// widget_path = 'global/widgets/paging/Paging.html'; // TODO: #3023: Delete this line once all widget html converted and no longer need this quick reference for the old format.\n\t\t\tinput = $.fn.Paging2.html.paging;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.WidgetNamesDic.PAGING_2:\n\t\t\t// widget_path = 'global/widgets/paging/Paging2.html'; // TODO: #3023: Delete this line once all widget html converted and no longer need this quick reference for the old format.\n\t\t\tinput = $.fn.Paging2.html.paging2;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.WidgetNamesDic.ERROR_TOOLTIP:\n\t\t\tinput = $.fn.ErrorTipBox.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.FEEDBACK_BOX:\n\t\t\tinput = $.fn.TFeedback.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.WidgetNamesDic.EDIT_VIEW_FORM_ITEM: //There is no file browser JS file for this widget.\n\t\t\tinput = `\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\n\t\t\t
`;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.WidgetNamesDic.EDIT_VIEW_SUB_FORM_ITEM: //There is no file browser JS file for this widget.\n\t\t\tinput = `\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\n\t\t\t
`;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.WidgetNamesDic.NO_RESULT_BOX:\n\t\t\tinput = $.fn.NoResultBox.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.WidgetNamesDic.VIEW_MIN_TAB:\n\t\t\tinput = $.fn.ViewMinTabBar.html.tab;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.WidgetNamesDic.VIEW_MIN_TAB_BAR:\n\t\t\tinput = $.fn.ViewMinTabBar.html.tab_bar;\n\t\t\tbreak;\n\t}\n\n\tif ( widget_path != false ) {\n\t\tinput = Global.loadWidget( widget_path );\n\t}\n\n\tif ( input && raw_text == true ) {\n\t\treturn input;\n\t} else {\n\t\t//#2571 - Error: Unable to get property 'indexOf' of undefined or null reference\n\t\tif ( input && input.indexOf( '<' ) != -1 ) {\n\t\t\tif ( !raw_text ) {\n\t\t\t\tinput = $( input );\n\n\t\t\t\tif ( widget_constructor && !input[widget_constructor] ) {\n\t\t\t\t\tvar error_string = $.i18n._( 'Class could not be found for' ) + ': ' + widgetName + '. ' + $.i18n._( 'Check that class is properly required.' );\n\t\t\t\t\tthrow( new Error( error_string ) );\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t//See comment in Global.loadWidget() regarding return null return values.\n\t\t\tvar error_string = $.i18n._( 'Network error, failed to load' ) + ': ' + widgetName + ' ' + $.i18n._( 'Result' ) + ': \"' + input + '\"';\n\t\t\tTAlertManager.showNetworkErrorAlert( { status: 999 }, error_string, null ); //Show the user an error popoup.\n\t\t\tthrow( new Error( error_string ) ); //Halt execution and ensure that the email has a good error message because of failure of web server to provide the requested file.\n\t\t}\n\n\t\treturn input;\n\t}\n};\n\n/* jshint ignore:end */\n\nGlobal.loadWidget = function( url ) {\n\tif ( LocalCacheData.loadedWidgetCache[url] ) {\n\t\treturn ( LocalCacheData.loadedWidgetCache[url] );\n\t}\n\n\tvar realPath = url + '?v=' + APIGlobal.pre_login_data.application_build;\n\n\tif ( Global.url_offset ) {\n\t\trealPath = Global.url_offset + realPath;\n\t}\n\n\tvar message_id = _global_TTUUID__WEBPACK_IMPORTED_MODULE_0__/* .TTUUID.generateUUID */ .d.generateUUID();\n\tProgressBar.showProgressBar( message_id );\n\tvar successflag = false;\n\tvar responseData = $.ajax( {\n\t\tasync: false,\n\t\ttype: 'GET',\n\t\turl: realPath,\n\t\tdata: null,\n\t\tcache: true,\n\t\tsuccess: function() {\n\t\t\tsuccessflag = true;\n\t\t},\n\t\terror: function( jqXHR, textStatus, errorThrown ) {\n\t\t\tTAlertManager.showNetworkErrorAlert( jqXHR, textStatus, errorThrown );\n\t\t}\n\t} );\n\n\tProgressBar.removeProgressBar( message_id );\n\t//Error: Uncaught ReferenceError: responseText is not defined in interface/html5/global/Global.js?v=9.0.2-20151106-092147 line 1747\n\t// Upon further investigation (IRC discussions on #jQuery) it was suggested to stop using 'async: false' as that could be whats causing a null return value when we are expecting a jqXHR object.\n\t// Since the ultimate goal is to refactor things so .html is embedded in the .js files anyways, may as well just wait for that.\n\tif ( !responseData ) {\n\t\treturn null;\n\t} else {\n\t\tLocalCacheData.loadedWidgetCache[url] = responseData.responseText;\n\t\treturn ( responseData.responseText );\n\t}\n\n};\n\nGlobal.removeCss = function( path ) {\n\tvar realPath = 'theme/' + Global.theme + '/css/' + path;\n\n\tif ( Global.url_offset ) {\n\t\trealPath = Global.url_offset + realPath;\n\t}\n\n\t$( 'link[href=\\'\\' + realPath + \\'?v=\\' + APIGlobal.pre_login_data.application_build + \\'\\']' ).remove();\n};\n\n/* jshint ignore:start */\n\nGlobal.getViewPathByViewId = function( viewId ) {\n\tvar path;\n\tswitch ( viewId ) {\n\t\t//Recruitment Portal\n\t\tcase 'GridTest':\n\t\tcase 'WidgetTest':\n\t\tcase 'AwesomeboxTest':\n\t\t\tpath = 'views/developer_tools/';\n\t\t\tbreak;\n\t\tcase 'MyProfile':\n\t\t\tpath = 'views/portal/hr/my_profile/';\n\t\t\tbreak;\n\t\tcase 'MyJobApplication':\n\t\t\tpath = 'views/portal/hr/my_jobapplication/';\n\t\t\tbreak;\n\t\tcase 'MyProfileEmployment':\n\t\t\tpath = 'views/portal/hr/my_profile/';\n\t\t\tbreak;\n\n\t\tcase 'Map':\n\t\t\tpath = 'views/attendance/map/';\n\t\t\tbreak;\n\t\tcase 'ManualTimeSheet':\n\t\t\tpath = 'views/attendance/manual_timesheet/';\n\t\t\tbreak;\n\t\tcase 'Home':\n\t\t\tpath = 'views/home/dashboard/';\n\t\t\tbreak;\n\t\tcase 'PortalJobVacancyDetail':\n\t\tcase 'PortalJobVacancy':\n\t\t\tpath = 'views/portal/hr/recruitment/';\n\t\t\tbreak;\n\t\tcase 'PortalLogin':\n\t\t\tpath = 'views/portal/login/';\n\t\t\tbreak;\n\t\tcase 'QuickPunchLogin':\n\t\t\tpath = 'views/quick_punch/login/';\n\t\t\tbreak;\n\t\tcase 'QuickPunch':\n\t\t\tpath = 'views/quick_punch/punch/';\n\t\t\tbreak;\n\t\tcase 'UserDateTotalParent':\n\t\tcase 'UserDateTotal':\n\t\t\tpath = 'views/attendance/timesheet/';\n\t\t\tbreak;\n\t\tcase 'Product':\n\t\t\tpath = 'views/invoice/products/';\n\t\t\tbreak;\n\t\tcase 'InvoiceDistrict':\n\t\t\tpath = 'views/invoice/district/';\n\t\t\tbreak;\n\t\tcase 'PaymentGateway':\n\t\t\tpath = 'views/invoice/payment_gateway/';\n\t\t\tbreak;\n\t\tcase 'InvoiceConfig':\n\t\t\tpath = 'views/invoice/settings/';\n\t\t\tbreak;\n\t\tcase 'ShippingPolicy':\n\t\t\tpath = 'views/invoice/shipping_policy/';\n\t\t\tbreak;\n\t\tcase 'AreaPolicy':\n\t\t\tpath = 'views/invoice/area_policy/';\n\t\t\tbreak;\n\t\tcase 'TaxPolicy':\n\t\t\tpath = 'views/invoice/tax_policy/';\n\t\t\tbreak;\n\t\tcase 'ClientGroup':\n\t\t\tpath = 'views/invoice/client_group/';\n\t\t\tbreak;\n\t\tcase 'ProductGroup':\n\t\t\tpath = 'views/invoice/product_group/';\n\t\t\tbreak;\n\t\tcase 'Exception':\n\t\t\tpath = 'views/attendance/exceptions/';\n\t\t\tbreak;\n\t\tcase 'Employee':\n\t\t\tpath = 'views/employees/employee/';\n\t\t\tbreak;\n\t\tcase 'RemittanceDestinationAccount':\n\t\t\tpath = 'views/employees/remittance_destination_account/';\n\t\t\tbreak;\n\t\tcase 'Wage':\n\t\t\tpath = 'views/company/wage/';\n\t\t\tbreak;\n\t\tcase 'Login':\n\t\t\tpath = 'views/login/';\n\t\t\tbreak;\n\t\tcase 'TimeSheet':\n\t\t\tpath = 'views/attendance/timesheet/';\n\t\t\tbreak;\n\t\tcase 'InOut':\n\t\t\tpath = 'views/attendance/in_out/';\n\t\t\tbreak;\n\t\tcase 'RecurringScheduleControl':\n\t\t\tpath = 'views/attendance/recurring_schedule_control/';\n\t\t\tbreak;\n\t\tcase 'RecurringScheduleTemplateControl':\n\t\t\tpath = 'views/attendance/recurring_schedule_template_control/';\n\t\t\tbreak;\n\t\tcase 'ScheduleShift':\n\t\tcase 'Schedule':\n\t\t\tpath = 'views/attendance/schedule/';\n\t\t\tbreak;\n\t\tcase 'Accrual':\n\t\t\tpath = 'views/attendance/accrual/';\n\t\t\tbreak;\n\t\tcase 'AccrualBalance':\n\t\t\tpath = 'views/attendance/accrual_balance/';\n\t\t\tbreak;\n\t\tcase 'Punches':\n\t\t\tpath = 'views/attendance/punches/';\n\t\t\tbreak;\n\t\tcase 'PunchTagGroup':\n\t\tcase 'PunchTag':\n\t\t\tpath = 'views/attendance/punch_tag/';\n\t\t\tbreak;\n\t\tcase 'JobGroup':\n\t\tcase 'Job':\n\t\t\tpath = 'views/attendance/job/';\n\t\t\tbreak;\n\t\tcase 'JobItemGroup':\n\t\tcase 'JobItem':\n\t\t\tpath = 'views/attendance/job_item/';\n\t\t\tbreak;\n\t\tcase 'JobItemAmendment':\n\t\t\tpath = 'views/attendance/job_item_amendment/';\n\t\t\tbreak;\n\t\tcase 'UserTitle':\n\t\t\tpath = 'views/employees/user_title/';\n\t\t\tbreak;\n\t\tcase 'UserContact':\n\t\t\tpath = 'views/employees/user_contact/';\n\t\t\tbreak;\n\t\tcase 'UserPreference':\n\t\t\tpath = 'views/employees/user_preference/';\n\t\t\tbreak;\n\t\tcase 'UserGroup':\n\t\t\tpath = 'views/employees/user_group/';\n\t\t\tbreak;\n\t\tcase 'Log':\n\t\t\tpath = 'views/core/log/';\n\t\t\tbreak;\n\t\tcase 'UserDefault':\n\t\t\tpath = 'views/employees/user_default/';\n\t\t\tbreak;\n\t\tcase 'ROE':\n\t\t\tpath = 'views/employees/roe/';\n\t\t\tbreak;\n\t\tcase 'Company':\n\t\t\tpath = 'views/company/company/';\n\t\t\tbreak;\n\t\tcase 'Companies':\n\t\t\tpath = 'views/company/companies/';\n\t\t\tbreak;\n\t\tcase 'PayPeriodSchedule':\n\t\t\tpath = 'views/payperiod/';\n\t\t\tbreak;\n\t\tcase 'PayPeriods':\n\t\t\tpath = 'views/payroll/pay_periods/';\n\t\t\tbreak;\n\t\tcase 'LegalEntity':\n\t\t\tpath = 'views/company/legal_entity/';\n\t\t\tbreak;\n\t\tcase 'PayrollRemittanceAgencyEvent':\n\t\tcase 'PayrollRemittanceAgency':\n\t\t\tpath = 'views/company/payroll_remittance_agency/';\n\t\t\tbreak;\n\t\tcase 'RemittanceSourceAccount':\n\t\t\tpath = 'views/company/remittance_source_account/';\n\t\t\tbreak;\n\t\tcase 'Branch':\n\t\t\tpath = 'views/company/branch/';\n\t\t\tbreak;\n\t\tcase 'GEOFence':\n\t\t\tpath = 'views/company/geo_fence/';\n\t\t\tbreak;\n\t\tcase 'Department':\n\t\t\tpath = 'views/company/department/';\n\t\t\tbreak;\n\t\tcase 'HierarchyControl':\n\t\t\tpath = 'views/company/hierarchy_control/';\n\t\t\tbreak;\n\t\tcase 'WageGroup':\n\t\t\tpath = 'views/company/wage_group/';\n\t\t\tbreak;\n\t\tcase 'EthnicGroup':\n\t\t\tpath = 'views/company/ethnic_group/';\n\t\t\tbreak;\n\t\tcase 'Currency':\n\t\tcase 'CurrencyRate':\n\t\t\tpath = 'views/company/currency/';\n\t\t\tbreak;\n\t\tcase 'PermissionControl':\n\t\t\tpath = 'views/company/permission_control/';\n\t\t\tbreak;\n\t\tcase 'CustomField':\n\t\t\tpath = 'views/company/custom_field/';\n\t\t\tbreak;\n\t\tcase 'Station':\n\t\t\tpath = 'views/company/station/';\n\t\t\tbreak;\n\t\tcase 'PayStub':\n\t\t\tpath = 'views/payroll/pay_stub/';\n\t\t\tbreak;\n\t\tcase 'PayStubTransaction':\n\t\t\tpath = 'views/payroll/pay_stub_transaction/';\n\t\t\tbreak;\n\t\tcase 'GovernmentDocument':\n\t\t\tpath = 'views/payroll/government_document/';\n\t\t\tbreak;\n\t\tcase 'Request':\n\t\t\tpath = 'views/my_account/request/';\n\t\t\tbreak;\n\t\tcase 'ChangePassword':\n\t\t\tpath = 'views/my_account/password/';\n\t\t\tbreak;\n\t\tcase 'RequestAuthorization':\n\t\t\tpath = 'views/my_account/request_authorization/';\n\t\t\tbreak;\n\t\tcase 'TimeSheetAuthorization':\n\t\t\tpath = 'views/my_account/timesheet_authorization/';\n\t\t\tbreak;\n\t\tcase 'MessageControl':\n\t\t\tpath = 'views/my_account/message_control/';\n\t\t\tbreak;\n\t\tcase 'Notification':\n\t\t\tpath = 'views/my_account/notification/';\n\t\t\tbreak;\n\t\tcase 'LoginUserContact':\n\t\t\tpath = 'views/my_account/user_contact/';\n\t\t\tbreak;\n\t\tcase 'LoginUserPreference':\n\t\t\tpath = 'views/my_account/user_preference/';\n\t\t\tbreak;\n\t\tcase 'LoginUserExpense':\n\t\tcase 'ExpenseAuthorization':\n\t\t\tpath = 'views/my_account/expense/';\n\t\t\tbreak;\n\t\tcase 'PayStubAmendment':\n\t\t\tpath = 'views/payroll/pay_stub_amendment/';\n\t\t\tbreak;\n\t\tcase 'RecurringPayStubAmendment':\n\t\t\tpath = 'views/payroll/recurring_pay_stub_amendment/';\n\t\t\tbreak;\n\t\tcase 'PayStubEntryAccount':\n\t\t\tpath = 'views/payroll/pay_stub_entry_account/';\n\t\t\tbreak;\n\t\tcase 'CompanyTaxDeduction':\n\t\t\tpath = 'views/payroll/company_tax_deduction/';\n\t\t\tbreak;\n\t\tcase 'UserExpense':\n\t\t\tpath = 'views/payroll/user_expense/';\n\t\t\tbreak;\n\t\tcase 'PolicyGroup':\n\t\t\tpath = 'views/policy/policy_group/';\n\t\t\tbreak;\n\t\tcase 'PayCode':\n\t\t\tpath = 'views/policy/pay_code/';\n\t\t\tbreak;\n\t\tcase 'PayFormulaPolicy':\n\t\t\tpath = 'views/policy/pay_formula_policy/';\n\t\t\tbreak;\n\t\tcase 'ContributingPayCodePolicy':\n\t\t\tpath = 'views/policy/contributing_pay_code_policy/';\n\t\t\tbreak;\n\t\tcase 'ContributingShiftPolicy':\n\t\t\tpath = 'views/policy/contributing_shift_policy/';\n\t\t\tbreak;\n\t\tcase 'RoundIntervalPolicy':\n\t\t\tpath = 'views/policy/round_interval_policy/';\n\t\t\tbreak;\n\t\tcase 'MealPolicy':\n\t\t\tpath = 'views/policy/meal_policy/';\n\t\t\tbreak;\n\t\tcase 'BreakPolicy':\n\t\t\tpath = 'views/policy/break_policy/';\n\t\t\tbreak;\n\t\tcase 'RegularTimePolicy':\n\t\t\tpath = 'views/policy/regular_time_policy/';\n\t\t\tbreak;\n\t\tcase 'ExpensePolicy':\n\t\t\tpath = 'views/policy/expense_policy/';\n\t\t\tbreak;\n\t\tcase 'OvertimePolicy':\n\t\t\tpath = 'views/policy/overtime_policy/';\n\t\t\tbreak;\n\t\tcase 'AbsencePolicy':\n\t\t\tpath = 'views/policy/absence_policy/';\n\t\t\tbreak;\n\t\tcase 'PremiumPolicy':\n\t\t\tpath = 'views/policy/premium_policy/';\n\t\t\tbreak;\n\t\tcase 'ExceptionPolicyControl':\n\t\t\tpath = 'views/policy/exception_policy/';\n\t\t\tbreak;\n\n\t\tcase 'RecurringHoliday':\n\t\t\tpath = 'views/policy/recurring_holiday/';\n\t\t\tbreak;\n\t\tcase 'HolidayPolicy':\n\t\t\tpath = 'views/policy/holiday_policy/';\n\t\t\tbreak;\n\t\tcase 'Holiday':\n\t\t\tpath = 'views/policy/holiday/';\n\t\t\tbreak;\n\t\tcase 'SchedulePolicy':\n\t\t\tpath = 'views/policy/schedule_policy/';\n\t\t\tbreak;\n\t\tcase 'AccrualPolicy':\n\t\tcase 'AccrualPolicyAccount':\n\t\tcase 'AccrualPolicyUserModifier':\n\t\t\tpath = 'views/policy/accrual_policy/';\n\t\t\tbreak;\n\t\tcase 'DocumentRevision':\n\t\tcase 'Document':\n\t\tcase 'DocumentGroup':\n\t\t\tpath = 'views/document/';\n\t\t\tbreak;\n\t\tcase 'About':\n\t\t\tpath = 'views/help/';\n\t\t\tbreak;\n\t\tcase 'ActiveShiftReport':\n\t\t\tpath = 'views/reports/whos_in_summary/';\n\t\t\tbreak;\n\t\tcase 'UserSummaryReport':\n\t\t\tpath = 'views/reports/employee_information/';\n\t\t\tbreak;\n\t\tcase 'SavedReport':\n\t\t\tpath = 'views/reports/saved_report/';\n\t\t\tbreak;\n\t\tcase 'ReportSchedule':\n\t\t\tpath = 'views/reports/report_schedule/';\n\t\t\tbreak;\n\t\tcase 'ScheduleSummaryReport':\n\t\t\tpath = 'views/reports/schedule_summary/';\n\t\t\tbreak;\n\t\tcase 'TimesheetSummaryReport':\n\t\t\tpath = 'views/reports/timesheet_summary/';\n\t\t\tbreak;\n\t\tcase 'TimesheetDetailReport':\n\t\t\tpath = 'views/reports/timesheet_detail/';\n\t\t\tbreak;\n\t\tcase 'PunchSummaryReport':\n\t\t\tpath = 'views/reports/punch_summary/';\n\t\t\tbreak;\n\t\tcase 'ExceptionSummaryReport':\n\t\t\tpath = 'views/reports/exception_summary/';\n\t\t\tbreak;\n\t\tcase 'PayStubTransactionSummaryReport':\n\t\t\tpath = 'views/reports/pay_stub_transaction_summary/';\n\t\t\tbreak;\n\t\tcase 'PayStubSummaryReport':\n\t\t\tpath = 'views/reports/pay_stub_summary/';\n\t\t\tbreak;\n\t\tcase 'KPI':\n\t\tcase 'KPIGroup':\n\t\tcase 'UserReviewControl':\n\t\t\tpath = 'views/hr/kpi/';\n\t\t\tbreak;\n\t\tcase 'QualificationGroup':\n\t\tcase 'Qualification':\n\t\tcase 'UserSkill':\n\t\tcase 'UserEducation':\n\t\tcase 'UserMembership':\n\t\tcase 'UserLicense':\n\t\tcase 'UserLanguage':\n\t\t\tpath = 'views/hr/qualification/';\n\t\t\tbreak;\n\t\tcase 'JobApplication':\n\t\tcase 'JobVacancy':\n\t\tcase 'JobApplicant':\n\t\tcase 'JobApplicantEmployment':\n\t\tcase 'JobApplicantReference':\n\t\tcase 'JobApplicantLocation':\n\t\tcase 'JobApplicantSkill':\n\t\tcase 'JobApplicantEducation':\n\t\tcase 'JobApplicantMembership':\n\t\tcase 'JobApplicantLicense':\n\t\tcase 'JobApplicantLanguage':\n\t\tcase 'RecruitmentPortalConfig':\n\t\t\tpath = 'views/hr/recruitment/';\n\t\t\tbreak;\n\t\tcase 'PayrollExportReport':\n\t\t\tpath = 'views/reports/payroll_export/';\n\t\t\tbreak;\n\t\tcase 'GeneralLedgerSummaryReport':\n\t\t\tpath = 'views/reports/general_ledger_summary/';\n\t\t\tbreak;\n\t\tcase 'ExpenseSummaryReport':\n\t\t\tpath = 'views/reports/expense_summary/';\n\t\t\tbreak;\n\t\tcase 'AccrualBalanceSummaryReport':\n\t\t\tpath = 'views/reports/accrual_balance_summary/';\n\t\t\tbreak;\n\t\tcase 'JobSummaryReport':\n\t\t\tpath = 'views/reports/job_summary/';\n\t\t\tbreak;\n\t\tcase 'JobAnalysisReport':\n\t\t\tpath = 'views/reports/job_analysis/';\n\t\t\tbreak;\n\t\tcase 'JobInformationReport':\n\t\t\tpath = 'views/reports/job_info/';\n\t\t\tbreak;\n\t\tcase 'JobItemInformationReport':\n\t\t\tpath = 'views/reports/job_item_info/';\n\t\t\tbreak;\n\t\tcase 'InvoiceTransactionSummaryReport':\n\t\t\tpath = 'views/reports/invoice_transaction_summary/';\n\t\t\tbreak;\n\t\tcase 'RemittanceSummaryReport':\n\t\t\tpath = 'views/reports/remittance_summary/';\n\t\t\tbreak;\n\t\tcase 'T4SummaryReport':\n\t\t\tpath = 'views/reports/t4_summary/';\n\t\t\tbreak;\n\t\tcase 'T4ASummaryReport':\n\t\t\tpath = 'views/reports/t4a_summary/';\n\t\t\tbreak;\n\t\tcase 'TaxSummaryReport':\n\t\t\tpath = 'views/reports/tax_summary/';\n\t\t\tbreak;\n\t\tcase 'Form940Report':\n\t\t\tpath = 'views/reports/form940/';\n\t\t\tbreak;\n\t\tcase 'Form941Report':\n\t\t\tpath = 'views/reports/form941/';\n\t\t\tbreak;\n\t\tcase 'Form1099NecReport':\n\t\t\tpath = 'views/reports/form1099/';\n\t\t\tbreak;\n\t\tcase 'FormW2Report':\n\t\t\tpath = 'views/reports/formw2/';\n\t\t\tbreak;\n\t\tcase 'USStateUnemploymentReport':\n\t\t\tpath = 'views/reports/us_state_unemployment/';\n\t\t\tbreak;\n\t\tcase 'AffordableCareReport':\n\t\t\tpath = 'views/reports/affordable_care/';\n\t\t\tbreak;\n\t\tcase 'UserQualificationReport':\n\t\t\tpath = 'views/reports/qualification_summary/';\n\t\t\tbreak;\n\t\tcase 'KPIReport':\n\t\t\tpath = 'views/reports/review_summary/';\n\t\t\tbreak;\n\t\tcase 'UserRecruitmentSummaryReport':\n\t\t\tpath = 'views/reports/recruitment_summary/';\n\t\t\tbreak;\n\t\tcase 'UserRecruitmentDetailReport':\n\t\t\tpath = 'views/reports/recruitment_detail/';\n\t\t\tbreak;\n\t\tcase 'Client':\n\t\t\tpath = 'views/invoice/client/';\n\t\t\tbreak;\n\t\tcase 'ClientContact':\n\t\t\tpath = 'views/invoice/client_contact/';\n\t\t\tbreak;\n\t\tcase 'ClientPayment':\n\t\t\tpath = 'views/invoice/client_payment/';\n\t\t\tbreak;\n\t\tcase 'InvoiceTransaction':\n\t\t\tpath = 'views/invoice/invoice_transaction/';\n\t\t\tbreak;\n\t\tcase 'Invoice':\n\t\t\tpath = 'views/invoice/invoice/';\n\t\t\tbreak;\n\t\tcase 'CustomColumn':\n\t\t\tpath = 'views/reports/custom_column/';\n\t\t\tbreak;\n\t\tcase 'AuditTrailReport':\n\t\t\tpath = 'views/reports/audittrail/';\n\t\t\tbreak;\n\t\tcase 'ReCalculateTimeSheetWizard':\n\t\t\tpath = 'views/wizard/re_calculate_timesheet/';\n\t\t\tbreak;\n\t\tcase 'GeneratePayStubWizard':\n\t\t\tpath = 'views/wizard/generate_pay_stub/';\n\t\t\tbreak;\n\t\tcase 'UserGenericStatus':\n\t\t\tpath = 'views/wizard/user_generic_data_status/';\n\t\t\tbreak;\n\t\tcase 'ProcessPayrollWizard':\n\t\t\tpath = 'views/wizard/process_payroll/';\n\t\t\tbreak;\n\t\tcase 'PayrollRemittanceAgencyEventWizardController':\n\t\t\tpath = 'views/payroll/remittance_wizard/';\n\t\t\tbreak;\n\t\tcase 'ProcessTransactionsWizardController':\n\t\t\tpath = 'views/payroll/process_transactions_wizard/';\n\t\t\tbreak;\n\t\tcase 'ImportCSVWizard':\n\t\t\tpath = 'views/wizard/import_csv/';\n\t\t\tbreak;\n\t\tcase 'JobInvoiceWizard':\n\t\t\tpath = 'views/wizard/job_invoice/';\n\t\t\tbreak;\n\t\tcase 'LoginUserWizard':\n\t\tcase 'LoginUser':\n\t\t\tpath = 'views/wizard/login_user/';\n\t\t\tbreak;\n\t\tcase 'QuickStartWizard':\n\t\t\tpath = 'views/wizard/quick_start/';\n\t\t\tbreak;\n\t\tcase 'UserPhotoWizard':\n\t\t\tpath = 'views/wizard/user_photo/';\n\t\t\tbreak;\n\t\tcase 'FindAvailableWizard':\n\t\tcase 'FindAvailable':\n\t\t\tpath = 'views/wizard/find_available/';\n\t\t\tbreak;\n\t\tcase 'PermissionWizard':\n\t\t\tpath = 'views/wizard/permission_wizard/';\n\t\t\tbreak;\n\t\tcase 'FormulaBuilderWizard':\n\t\t\tpath = 'views/wizard/formula_builder_wizard/';\n\t\t\tbreak;\n\t\tcase 'ReCalculateAccrualWizard':\n\t\t\tpath = 'views/wizard/re_calculate_accrual/';\n\t\t\tbreak;\n\t\tcase 'ResetPasswordWizard':\n\t\t\tpath = 'views/wizard/reset_password/';\n\t\t\tbreak;\n\t\tcase 'ShareReportWizard':\n\t\t\tpath = 'views/wizard/share_report/';\n\t\t\tbreak;\n\t\tcase 'PayCodeWizard':\n\t\t\tpath = 'views/wizard/pay_code/';\n\t\t\tbreak;\n\t\tcase 'InstallWizard':\n\t\t\tpath = 'views/wizard/install/';\n\t\t\tbreak;\n\t\tcase 'PayStubAccountWizard':\n\t\t\tpath = 'views/wizard/pay_stub_account/';\n\t\t\tbreak;\n\t\tcase 'DashletWizard':\n\t\t\tpath = 'views/wizard/dashlet/';\n\t\t\tbreak;\n\t\tcase 'ReportViewWizard':\n\t\t\tpath = 'views/wizard/report_view/';\n\t\t\tbreak;\n\t\tcase 'PortalApplyJobWizard':\n\t\t\tpath = 'views/wizard/portal_apply_job/';\n\t\t\tbreak;\n\t\tcase 'ForgotPasswordWizard':\n\t\t\tpath = 'views/wizard/forgot_password/';\n\t\t\tbreak;\n\t\tcase 'ResetForgotPasswordWizard':\n\t\t\tpath = 'views/wizard/reset_forgot_password/';\n\t\t\tbreak;\n\t\tcase 'DeveloperTools':\n\t\t\tpath = 'views/developer_tools/';\n\t\t\tbreak;\n\t\tcase 'UIKitSample':\n\t\tcase 'UIKitChildSample':\n\t\t\tpath = 'views/ui_kit_sample/';\n\t\t\tbreak;\n\t}\n\treturn path;\n};\n/* jshint ignore:end */\n\n//returns exact filepaths for class dependencies\nGlobal.getViewPreloadPathByViewId = function( viewId ) {\n\t// DEPRECATED: Moved the loading of these preloads to post-login-main_ui-dependancies.js\n\n\tvar preloads = [];\n\t// switch ( viewId ) {\n\t// \tcase 'Request':\n\t// \tcase 'RequestAuthorization':\n\t// \t\tpreloads = ['views/common/AuthorizationHistoryCommon.js', 'views/common/RequestViewCommonController.js', 'views/common/EmbeddedMessageCommon.js'];\n\t// \t\tbreak;\n\t// \tcase 'ExpenseAuthorization':\n\t// \tcase 'UserExpense':\n\t// \tcase 'LoginUserExpense':\n\t// \tcase 'TimeSheetAuthorization':\n\t// \t\tpreloads = ['views/common/AuthorizationHistoryCommon.js'];\n\t// \t\tbreak;\n\t// }\n\treturn preloads;\n};\n\nGlobal.removeViewCss = function( viewId, fileName ) {\n\tGlobal.removeCss( Global.getViewPathByViewId( viewId ) + fileName );\n};\n\nGlobal.sanitizeViewId = function( viewId ) {\n\tif ( typeof viewId === 'string' || viewId instanceof String ) {\n\t\treturn viewId.replace( '/', '' ).replace( '\\\\', '' );\n\t}\n\n\treturn viewId;\n};\n\nGlobal.loadViewSource = function( viewId, fileName, onResult, sync ) {\n\tvar viewId = Global.sanitizeViewId( viewId );\n\tvar path = Global.getViewPathByViewId( viewId );\n\n\tif ( fileName.indexOf( '.js' ) > 0 ) {\n\t\tvar preloads = Global.getViewPreloadPathByViewId( viewId );\n\t\tif ( preloads.length > 0 ) {\n\t\t\tfor ( var p in preloads ) {\n\t\t\t\tGlobal.loadScript( preloads[p] );\n\t\t\t}\n\t\t}\n\n\t\tif ( path ) {\n\t\t\tif ( sync ) {\n\t\t\t\treturn Global.loadScript( path + fileName );\n\t\t\t} else {\n\t\t\t\tGlobal.loadScript( path + fileName, onResult );\n\t\t\t}\n\t\t} else {\n\t\t\t//Invalid viewId, redirect to home page?\n\t\t\tconsole.debug( 'View does not exist! ViewId: ' + viewId + ' File Name: ' + fileName );\n\t\t\tif ( _services_ServiceCaller__WEBPACK_IMPORTED_MODULE_5__/* .ServiceCaller.root_url */ .n.root_url && APIGlobal.pre_login_data.base_url ) {\n\t\t\t\tGlobal.setURLToBrowser( _services_ServiceCaller__WEBPACK_IMPORTED_MODULE_5__/* .ServiceCaller.root_url */ .n.root_url + APIGlobal.pre_login_data.base_url );\n\t\t\t}\n\t\t}\n\n\t} else if ( fileName.indexOf( '.css' ) > 0 ) {\n\t\tGlobal.addCss( path + fileName );\n\t} else {\n\t\tif ( path ) {\n\t\t\t// HTML2JS\n\t\t\tvar template_type = _services_HtmlTemplates__WEBPACK_IMPORTED_MODULE_7__/* .HtmlTemplatesGlobal.getTemplateTypeFromFilename */ .H.getTemplateTypeFromFilename( fileName );\n\t\t\tvar template_options = _services_HtmlTemplates__WEBPACK_IMPORTED_MODULE_7__/* .HtmlTemplatesGlobal.getTemplateOptionsFromViewId */ .H.getTemplateOptionsFromViewId( viewId );\n\n\t\t\tif( template_type === _services_HtmlTemplates__WEBPACK_IMPORTED_MODULE_7__/* .TemplateType.INLINE_HTML */ .W.INLINE_HTML ) {\n\t\t\t\ttemplate_options.filename = fileName; // Needed by HtmlTemplates.checkViewClassForInlineHtmlbyFilename() which uses filename, not view id.\n\t\t\t}\n\t\t\tif ( sync ) {\n\t\t\t\t// Note: for #HTML2JS This path is taken for things such as: CompanyInformation, CompanyEditView.html, and general edit views.\n\n\t\t\t\t// Check if we should use the new templating logic, or legacy html load.\n\t\t\t\tif( template_type !== _services_HtmlTemplates__WEBPACK_IMPORTED_MODULE_7__/* .TemplateType.LEGACY_HTML */ .W.LEGACY_HTML ) {\n\t\t\t\t\t// Use new HTML2JS template class\n\t\t\t\t\treturn _services_HtmlTemplates__WEBPACK_IMPORTED_MODULE_7__/* .HtmlTemplatesGlobal.getTemplate */ .H.getTemplate( template_type, template_options, null ); // no onResult, as its syncronous.\n\t\t\t\t} else {\n\t\t\t\t\t// Legacy html file load for syncronous files.\n\t\t\t\t\treturn Global.loadPageSync( path + fileName );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Check if we should use the new templating logic, or legacy html load.\n\t\t\t\tif( template_type !== _services_HtmlTemplates__WEBPACK_IMPORTED_MODULE_7__/* .TemplateType.LEGACY_HTML */ .W.LEGACY_HTML ) {\n\t\t\t\t\t// Use new HTML2JS template class\n\t\t\t\t\t_services_HtmlTemplates__WEBPACK_IMPORTED_MODULE_7__/* .HtmlTemplatesGlobal.getTemplate */ .H.getTemplate( template_type, template_options, onResult );\n\t\t\t\t} else {\n\t\t\t\t\t// Legacy html file load\n\t\t\t\t\tGlobal.loadPage( path + fileName, onResult );\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t//Invalid viewId, redirect to home page?\n\t\t\tconsole.debug( 'View does not exist! ViewId: ' + viewId + ' File Name: ' + fileName );\n\t\t\tif ( _services_ServiceCaller__WEBPACK_IMPORTED_MODULE_5__/* .ServiceCaller.root_url */ .n.root_url && APIGlobal.pre_login_data.base_url ) {\n\t\t\t\tGlobal.setURLToBrowser( _services_ServiceCaller__WEBPACK_IMPORTED_MODULE_5__/* .ServiceCaller.root_url */ .n.root_url + APIGlobal.pre_login_data.base_url );\n\t\t\t}\n\t\t}\n\t}\n};\n\nGlobal.loadPageSync = function( url ) {\n\n\tvar realPath = url + '?v=' + APIGlobal.pre_login_data.application_build;\n\n\tif ( Global.url_offset ) {\n\t\trealPath = Global.url_offset + realPath;\n\t}\n\tvar message_id = _global_TTUUID__WEBPACK_IMPORTED_MODULE_0__/* .TTUUID.generateUUID */ .d.generateUUID();\n\tProgressBar.showProgressBar( message_id );\n\tvar successflag = false;\n\tvar responseData = $.ajax( {\n\t\tasync: false,\n\t\ttype: 'GET',\n\t\turl: realPath,\n\t\tdata: null,\n\t\tcache: true,\n\t\tsuccess: function() {\n\t\t\tsuccessflag = true;\n\t\t},\n\n\t\terror: function( jqXHR, textStatus, errorThrown ) {\n\t\t\tTAlertManager.showNetworkErrorAlert( jqXHR, textStatus, errorThrown );\n\t\t}\n\t} );\n\n\tProgressBar.removeProgressBar( message_id );\n\n\treturn ( responseData.responseText );\n\n};\n\nGlobal.loadPage = function( url, onResult ) {\n\n\tvar realPath = url + '?v=' + APIGlobal.pre_login_data.application_build;\n\tvar message_id = _global_TTUUID__WEBPACK_IMPORTED_MODULE_0__/* .TTUUID.generateUUID */ .d.generateUUID();\n\tif ( Global.url_offset ) {\n\t\trealPath = Global.url_offset + realPath;\n\t}\n\n\tProgressBar.showProgressBar( message_id );\n\t$.ajax( {\n\t\tasync: true,\n\t\ttype: 'GET',\n\t\turl: realPath,\n\t\tdata: null,\n\t\tcache: true,\n\t\tsuccess: function( result ) {\n\t\t\tProgressBar.removeProgressBar( message_id );\n\t\t\tonResult( result );\n\t\t},\n\t\terror: function( jqXHR, textStatus, errorThrown ) {\n\t\t\tTAlertManager.showNetworkErrorAlert( jqXHR, textStatus, errorThrown );\n\t\t}\n\t} );\n\n};\n\nGlobal.getRootURL = function( url ) {\n\tif ( !url ) {\n\t\turl = location.href;\n\t}\n\n\t//Rather than parse the URL ourselves, lets use the URL API and build it back up from its components.\n\tvar url_obj = new URL( url );\n\tvar retval = url_obj.protocol + '//' + url_obj.host;\n\n\treturn retval;\n};\n\nGlobal.getBaseURL = function( url_relative_path, include_search = true ) {\n\t//Rather than parse the URL ourselves, lets use the URL API and build it back up from its components.\n\tvar url_obj = new URL( location.href );\n\tvar retval = url_obj.protocol + '//' + url_obj.host + url_obj.pathname;\n\n\t//Resolve any specified relative path here, so we can append the search component of the URL after.\n\t// This is needed for the recruitment portal to work if Facebook or some other 3rd party appends search components on the URL, ie: ?test=1#!m=PortalJobVacancyDetail&id=05a45d0b-b982-2a1f-2003-21ea65522bf3&company_id=ABC\n\tif ( url_relative_path ) {\n\t\tretval = new URL( url_relative_path, retval ).href;\n\t}\n\n\tif ( include_search == true ) {\n\t\tretval += url_obj.search; //Can't put the search component back on when getting BaseURL.\n\t}\n\n\treturn retval;\n};\n\nGlobal.isArrayAndHasItems = function( object ) {\n\n\tif ( $.type( object ) === 'array' && object.length > 0 ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n\n};\n\nGlobal.isValidInputCodes = function( keyCode ) {\n\tvar result = true;\n\tswitch ( keyCode ) {\n\t\tcase 9:\n\t\tcase 16:\n\t\tcase 17:\n\t\tcase 18:\n\t\tcase 19:\n\t\tcase 20:\n\t\tcase 33:\n\t\tcase 34:\n\t\t// case 37:\n\t\t// case 38:\n\t\t// case 39:\n\t\t// case 40:\n\t\tcase 45:\n\t\tcase 91:\n\t\tcase 92:\n\t\tcase 93:\n\t\t\tresult = false;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tif ( keyCode >= 112 && keyCode <= 123 ) {\n\t\t\t\tresult = false;\n\t\t\t}\n\t}\n\treturn result;\n};\n\n/* jshint ignore:start */\nGlobal.convertLayoutFilterToAPIFilter = function( layout ) {\n\tvar convert_filter_data = {};\n\n\tif ( !layout ) {\n\t\treturn null;\n\t}\n\n\tvar filter_data = layout.data.filter_data;\n\n\tif ( !filter_data ) {\n\t\treturn null;\n\t}\n\n\t$.each( filter_data, function( key, content ) {\n\t\t// Cannot read property 'value' of undefined\n\t\tif ( !content ) {\n\t\t\treturn;//continue;\n\t\t}\n\t\tif ( ( content.value instanceof Array && content.value.length > 0 ) || ( content.value instanceof Object ) ) {\n\t\t\tvar values = [];\n\t\t\tvar obj = content.value;\n\t\t\tif ( content.value instanceof Array ) {\n\n\t\t\t\tvar len = content.value.length;\n\t\t\t\tfor ( var i = 0; i < len; i++ ) {\n\n\t\t\t\t\tif ( Global.isSet( content.value[i].value ) ) {\n\t\t\t\t\t\tvalues.push( content.value[i].value ); //Options,\n\t\t\t\t\t} else if ( content.value[i].id || content.value[i].id === 0 || content.value[i].id === '0' ) {\n\t\t\t\t\t\tvalues.push( content.value[i].id ); //Awesomebox\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvalues.push( content.value[i] ); // default_filter_data_for_next_view\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tconvert_filter_data[key] = values;\n\t\t\t\t//only add search filter which not equal to false, see if this cause any bugs\n\t\t\t} else if ( content.value instanceof Object ) {\n\t\t\t\tvar final_value = '';\n\t\t\t\tif ( Global.isSet( content.value.value ) ) {\n\t\t\t\t\tfinal_value = content.value.value; //Options,\n\t\t\t\t} else if ( content.value.id || content.value.id === 0 || content.value.id === '0' ) {\n\t\t\t\t\tfinal_value = content.value.id; //Awesomebox\n\t\t\t\t} else {\n\t\t\t\t\tfinal_value = content.value; // default_filter_data_for_next_view\n\t\t\t\t}\n\n\t\t\t\tconvert_filter_data[key] = final_value;\n\n\t\t\t} else if ( obj.value === false ) {\n\t\t\t\treturn;//continue;\n\t\t\t} else {\n\t\t\t\tif ( Global.isSet( obj.value ) ) {\n\n\t\t\t\t\tconvert_filter_data[key] = obj.value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t} else if ( filter_data[key].value === false ) {\n\t\t\treturn; //continue;\n\t\t} else if ( Global.isSet( filter_data[key].value ) ) {\n\t\t\tconvert_filter_data[key] = filter_data[key].value;\n\t\t} else {\n\t\t\tconvert_filter_data[key] = filter_data[key];\n\t\t}\n\t} );\n\n\tif ( LocalCacheData.extra_filter_for_next_open_view ) { //MUST removed this when close the view which used this attribute.\n\n\t\tfor ( var key in LocalCacheData.extra_filter_for_next_open_view.filter_data ) {\n\t\t\tconvert_filter_data[key] = LocalCacheData.extra_filter_for_next_open_view.filter_data[key];\n\t\t}\n\n\t}\n\n\treturn convert_filter_data;\n\n};\n/* jshint ignore:end */\n\n//ASC\nGlobal.compare = function( a, b, orderKey, order_type ) {\n\n\tif ( !Global.isSet( order_type ) ) {\n\t\torder_type = 'asc';\n\t}\n\n\tif ( order_type === 'asc' ) {\n\t\tif ( a[orderKey] < b[orderKey] ) {\n\t\t\treturn -1;\n\t\t}\n\t\tif ( a[orderKey] > b[orderKey] ) {\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n\t} else {\n\t\tif ( a[orderKey] < b[orderKey] ) {\n\t\t\treturn 1;\n\t\t}\n\t\tif ( a[orderKey] > b[orderKey] ) {\n\t\t\treturn -1;\n\t\t}\n\t\treturn 0;\n\t}\n\n};\n\nGlobal.buildFilter = function() {\n\tvar filterCondition = arguments[0];\n\tvar filter = [];\n\n\tif ( filterCondition ) {\n\n\t\tfor ( var key in filterCondition ) {\n\t\t\tfilter[key] = filterCondition[key];\n\t\t}\n\n\t}\n\n\treturn filter;\n\n};\n\nGlobal.getLoginUserDateFormat = function() {\n\tvar format = 'DD-MMM-YY';\n\n\tif ( LocalCacheData.getLoginUserPreference() ) {\n\t\tformat = LocalCacheData.getLoginUserPreference().date_format;\n\t}\n\n\treturn format;\n};\n/* jshint ignore:start */\nGlobal.formatGridData = function( grid_data, key_name ) {\n\n\tif ( $.type( grid_data ) !== 'array' ) {\n\t\treturn grid_data;\n\t}\n\n\tfor ( var i = 0; i < grid_data.length; i++ ) {\n\t\tfor ( var key in grid_data[i] ) {\n\n\t\t\tif ( !grid_data[i].hasOwnProperty( key ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t//Need to convert custom fields time_unit to string\n\t\t\tif ( key.indexOf( 'custom_field' ) === 0 && Array.isArray( LocalCacheData.current_open_primary_controller.custom_fields ) ) {\n\t\t\t\tlet custom_field = LocalCacheData.current_open_primary_controller.custom_fields.find( ( field ) => {\n\t\t\t\t\treturn field.id === key.replace( 'custom_field-', '' );\n\t\t\t\t} );\n\n\t\t\t\tif ( custom_field && custom_field.type_id == 1300 ) {\n\t\t\t\t\tif ( Global.isNumeric( grid_data[i][key] ) ) {\n\t\t\t\t\t\tgrid_data[i][key] = Global.getTimeUnit( grid_data[i][key] );\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// The same format for all views.\n\t\t\tswitch ( key ) {\n\t\t\t\tcase 'maximum_shift_time':\n\t\t\t\tcase 'new_day_trigger_time':\n\t\t\t\tcase 'trigger_time':\n\t\t\t\tcase 'minimum_punch_time':\n\t\t\t\tcase 'maximum_punch_time':\n\t\t\t\tcase 'window_length':\n\t\t\t\tcase 'start_window':\n\t\t\t\tcase 'round_interval':\n\t\t\t\tcase 'grace':\n\t\t\t\tcase 'estimate_time':\n\t\t\t\tcase 'minimum_time':\n\t\t\t\tcase 'maximum_time':\n\t\t\t\tcase 'total_time':\n\t\t\t\tcase 'start_stop_window':\n\t\t\t\t\tif ( Global.isNumeric( grid_data[i][key] ) ) {\n\t\t\t\t\t\tgrid_data[i][key] = Global.getTimeUnit( grid_data[i][key] );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tgrid_data[i][key] = null; //Prevent string \"false\" from being returned when the column isn't defined on the server side.\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'include_break_punch_time':\n\t\t\t\tcase 'include_multiple_breaks':\n\t\t\t\tcase 'include_lunch_punch_time':\n\t\t\t\tcase 'is_default':\n\t\t\t\tcase 'is_base':\n\t\t\t\tcase 'auto_update':\n\t\t\t\tcase 'currently_employed':\n\t\t\t\tcase 'criminal_record':\n\t\t\t\tcase 'immediate_drug_test':\n\t\t\t\tcase 'is_current_employer':\n\t\t\t\tcase 'is_contact_available':\n\t\t\t\tcase 'enable_pay_stub_balance_display':\n\t\t\t\tcase 'enable_login':\n\t\t\t\tcase 'ytd_adjustment':\n\t\t\t\tcase 'authorized':\n\t\t\t\tcase 'is_reimbursable':\n\t\t\t\tcase 'reimbursable':\n\t\t\t\tcase 'tainted':\n\t\t\t\tcase 'auto_fill':\n\t\t\t\tcase 'private':\n\t\t\t\t\tif ( grid_data[i][key] === true ) {\n\t\t\t\t\t\tgrid_data[i][key] = $.i18n._( 'Yes' );\n\t\t\t\t\t} else if ( grid_data[i][key] === false ) {\n\t\t\t\t\t\tgrid_data[i][key] = $.i18n._( 'No' );\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'override':\n\t\t\t\t\tif ( grid_data[i][key] === true ) {\n\t\t\t\t\t\tgrid_data[i][key] = $.i18n._( 'Yes' );\n\t\t\t\t\t\tgrid_data[i]['is_override'] = true;\n\t\t\t\t\t} else if ( grid_data[i][key] === false ) {\n\t\t\t\t\t\tgrid_data[i][key] = $.i18n._( 'No' );\n\t\t\t\t\t\tgrid_data[i]['is_override'] = false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'is_scheduled':\n\t\t\t\t\tif ( grid_data[i][key] === '1' ) {\n\t\t\t\t\t\tgrid_data[i][key] = $.i18n._( 'Yes' );\n\t\t\t\t\t} else if ( grid_data[i][key] === '0' ) {\n\t\t\t\t\t\tgrid_data[i][key] = $.i18n._( 'No' );\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'in_use':\n\t\t\t\t\tif ( grid_data[i][key] === '1' ) {\n\t\t\t\t\t\tgrid_data[i][key] = $.i18n._( 'Yes' );\n\t\t\t\t\t\tgrid_data[i]['is_in_use'] = true;\n\t\t\t\t\t} else if ( grid_data[i][key] === '0' ) {\n\t\t\t\t\t\tgrid_data[i][key] = $.i18n._( 'No' );\n\t\t\t\t\t\tgrid_data[i]['is_in_use'] = false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tif ( grid_data[i][key] === false ) {\n\t\t\t\t\t\tgrid_data[i][key] = '';\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Handle the specially format columns which are not different with others.\n\t\t\tswitch ( key_name ) {\n\t\t\t\tcase 'AccrualPolicyUserModifier':\n\t\t\t\t\tswitch ( key ) {\n\t\t\t\t\t\tcase 'annual_maximum_time_modifier':\n\t\t\t\t\t\t\tif ( grid_data[i]['type_id'] === 20 ) {\n\t\t\t\t\t\t\t\tgrid_data[i][key] = $.i18n._( 'N/A' );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'BreakPolicy':\n\t\t\t\tcase 'MealPolicy':\n\t\t\t\tcase 'Accrual':\n\t\t\t\t\tswitch ( key ) {\n\t\t\t\t\t\tcase 'amount':\n\t\t\t\t\t\t\tif ( Global.isNumeric( grid_data[i][key] ) ) {\n\t\t\t\t\t\t\t\tgrid_data[i][key] = Global.getTimeUnit( grid_data[i][key] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'accrual_balance_summary':\n\t\t\t\tcase 'AccrualBalance':\n\t\t\t\t\tswitch ( key ) {\n\t\t\t\t\t\tcase 'balance':\n\t\t\t\t\t\t\tif ( Global.isNumeric( grid_data[i][key] ) ) {\n\t\t\t\t\t\t\t\tgrid_data[i][key] = Global.getTimeUnit( grid_data[i][key] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'RecurringScheduleControl':\n\t\t\t\t\tswitch ( key ) {\n\t\t\t\t\t\tcase 'end_date':\n\t\t\t\t\t\t\tif ( grid_data[i][key] === '' ) {\n\t\t\t\t\t\t\t\tgrid_data[i][key] = 'Never';\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t}\n\t}\n\n\treturn grid_data;\n\n};\n/* jshint ignore:end */\n\n// Commented out as we have now fully refactored the old _super and __super references in the new ES6 code.\n// //make backone support a simple super funciton\n// Backbone.Model.prototype._super = function( funcName ) {\n// \treturn this.constructor.__super__[funcName].apply( this, _.rest( arguments ) );\n// };\n//\n// //make backone support a simple super function\n// Backbone.View.prototype._super = function( funcName ) {\n// \t// Note: If 'Maximum call stack size exceeded' error encountered, and view is extending twice (BaseView->ReportBaseView->SomeRandomView), then make sure you define `this.real_this` at the 2nd level extend. See reportBaseViewController init for example.\n// \tif ( this.real_this && this.real_this.constructor.__super__[funcName] ) {\n// \t\treturn this.real_this.constructor.__super__[funcName].apply( this, _.rest( arguments ) );\n// \t} else {\n// \t\treturn this.constructor.__super__[funcName].apply( this, _.rest( arguments ) );\n// \t}\n//\n// };\n//\n// //make backone support a simple super funciton for second level class\n// Backbone.View.prototype.__super = function( funcName ) {\n// \tif ( !this.real_this ) {\n// \t\tthis.real_this = this.constructor.__super__;\n// \t}\n//\n// \treturn this.constructor.__super__[funcName].apply( this, _.rest( arguments ) );\n//\n// };\n\n/*\n * Date Format 1.2.3\n * (c) 2007-2009 Steven Levithan \n * MIT license\n *\n * Includes enhancements by Scott Trenda \n * and Kris Kowal \n *\n * Accepts a date, a mask, or a date and a mask.\n * Returns a formatted version of the given date.\n * The date defaults to the current date/time.\n * The mask defaults to dateFormat.masks.default.\n */\n\nvar dateFormat = function() {\n\tvar token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\\1?|[LloSZ]|'[^']*\"|'[^']*'/g,\n\t\ttimezone = /\\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\\d{4})?)\\b/g,\n\t\ttimezoneClip = /[^-+\\dA-Z]/g,\n\t\tpad = function( val, len ) {\n\t\t\tval = String( val );\n\t\t\tlen = len || 2;\n\t\t\twhile ( val.length < len ) {\n\t\t\t\tval = '0' + val;\n\t\t\t}\n\t\t\treturn val;\n\t\t};\n\n\t// Regexes and supporting functions are cached through closure\n\n\t/* jshint ignore:start */\n\treturn function( date, mask, utc ) {\n\t\tvar dF = dateFormat;\n\n\t\t// You can't provide utc if you skip other args (use the 'UTC:' mask prefix)\n\t\tif ( arguments.length === 1 && Object.prototype.toString.call( date ) === '[object String]' && !/\\d/.test( date ) ) {\n\t\t\tmask = date;\n\t\t\tdate = undefined;\n\t\t}\n\n\t\t// Passing date through Date applies Date.parse, if necessary\n\t\tdate = date ? new Date( date ) : new Date();\n\t\tif ( isNaN( date ) ) {\n\t\t\tthrow SyntaxError( 'invalid date' );\n\t\t}\n\n\t\tmask = String( dF.masks[mask] || mask || dF.masks['default'] );\n\n\t\t// Allow setting the utc argument via the mask\n\t\tif ( mask.slice( 0, 4 ) === 'UTC:' ) {\n\t\t\tmask = mask.slice( 4 );\n\t\t\tutc = true;\n\t\t}\n\n\t\tvar _ = utc ? 'getUTC' : 'get',\n\t\t\td = date[_ + 'Date'](),\n\t\t\tD = date[_ + 'Day'](),\n\t\t\tm = date[_ + 'Month'](),\n\t\t\ty = date[_ + 'FullYear'](),\n\t\t\tH = date[_ + 'Hours'](),\n\t\t\tM = date[_ + 'Minutes'](),\n\t\t\ts = date[_ + 'Seconds'](),\n\t\t\tL = date[_ + 'Milliseconds'](),\n\t\t\to = utc ? 0 : date.getTimezoneOffset(),\n\t\t\tflags = {\n\t\t\t\td: d,\n\t\t\t\tdd: pad( d ),\n\t\t\t\tddd: dF.i18n.dayNames[D],\n\t\t\t\tdddd: dF.i18n.dayNames[D + 7],\n\t\t\t\tm: m + 1,\n\t\t\t\tmm: pad( m + 1 ),\n\t\t\t\tmmm: dF.i18n.monthNames[m],\n\t\t\t\tmmmm: dF.i18n.monthNames[m + 12],\n\t\t\t\tyy: String( y ).slice( 2 ),\n\t\t\t\tyyyy: y,\n\t\t\t\th: H % 12 || 12,\n\t\t\t\thh: pad( H % 12 || 12 ),\n\t\t\t\tH: H,\n\t\t\t\tHH: pad( H ),\n\t\t\t\tM: M,\n\t\t\t\tMM: pad( M ),\n\t\t\t\ts: s,\n\t\t\t\tss: pad( s ),\n\t\t\t\tl: pad( L, 3 ),\n\t\t\t\tL: pad( L > 99 ? Math.round( L / 10 ) : L ),\n\t\t\t\tt: H < 12 ? 'a' : 'p',\n\t\t\t\ttt: H < 12 ? 'am' : 'pm',\n\t\t\t\tT: H < 12 ? 'A' : 'P',\n\t\t\t\tTT: H < 12 ? 'AM' : 'PM',\n\t\t\t\tZ: utc ? 'UTC' : ( String( date ).match( timezone ) || [''] ).pop().replace( timezoneClip, '' ),\n\t\t\t\to: ( o > 0 ? '-' : '+' ) + pad( Math.floor( Math.abs( o ) / 60 ) * 100 + Math.abs( o ) % 60, 4 ),\n\t\t\t\tS: ['th', 'st', 'nd', 'rd'][d % 10 > 3 ? 0 : ( d % 100 - d % 10 !== 10 ) * d % 10]\n\t\t\t};\n\n\t\treturn mask.replace( token, function( $0 ) {\n\t\t\treturn $0 in flags ? flags[$0] : $0.slice( 1, $0.length - 1 );\n\t\t} );\n\t};\n\t/* jshint ignore:end */\n}();\n\n// Some common format strings\ndateFormat.masks = {\n\t'default': 'ddd mmm dd yyyy HH:MM:ss',\n\tshortDate: 'm/d/yy',\n\tmediumDate: 'mmm d, yyyy',\n\tlongDate: 'mmmm d, yyyy',\n\tfullDate: 'dddd, mmmm d, yyyy',\n\tshortTime: 'h:MM TT',\n\tmediumTime: 'h:MM:ss TT',\n\tlongTime: 'h:MM:ss TT Z',\n\tisoDate: 'yyyy-mm-dd',\n\tisoTime: 'HH:MM:ss',\n\tisoDateTime: 'yyyy-mm-dd\\'T\\'HH:MM:ss',\n\tisoUtcDateTime: 'UTC:yyyy-mm-dd\\'T\\'HH:MM:ss\\'Z\\''\n};\n\n// Internationalization strings\ndateFormat.i18n = {\n\tdayNames: [\n\t\t'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat',\n\t\t'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'\n\t],\n\tmonthNames: [\n\t\t'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec',\n\t\t'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'\n\t]\n};\n\n// For convenience...\nDate.prototype.format = function( mask, utc ) {\n\t//JS Exception: Uncaught TypeError: Cannot read properties of undefined (reading 'date_format')\n\tif ( !Global.isSet( mask ) && LocalCacheData.getLoginUserPreference() ) {\n\t\tmask = LocalCacheData.getLoginUserPreference().date_format;\n\t}\n\n\tif ( !mask ) {\n\t\tmask = 'DD-MMM-YY';\n\t}\n\n\tvar format_str = moment( this ).format( mask );\n\n\treturn format_str;\n};\n\nwindow.RightClickMenuType = function() {\n\n};\n\nRightClickMenuType.LISTVIEW = '1';\nRightClickMenuType.EDITVIEW = '2';\nRightClickMenuType.NORESULTBOX = '3';\nRightClickMenuType.ABSENCE_GRID = '4';\nRightClickMenuType.VIEW_ICON = '5';\n\n/**\n * Decoding encoded html enitities (ie: \">\")\n * to avoid XSS vulnerabilities do not eval anything that has gone through this function\n *\n * @param str\n * @returns {*|jQuery}\n */\nGlobal.htmlDecode = function( str ) {\n\treturn $( '' ).html( str ).text();\n};\n\nGlobal.htmlEncode = function( str ) {\n\tvar encodedStr = str;\n\n\tif ( encodedStr ) {\n\t\t// This replaces 'S' in 'MST' with the encoded value, which is invalid.\n\t\t// encodedStr = str.replace( /[\\u00A0-\\u9999<>\\'\"\\&]/gim, function( i ) {\n\t\t// \treturn '' + i.charCodeAt( 0 ) + ';';\n\t\t// } );\n\t\t// encodedStr = encodedStr.replace( /<br>/g, ' ' );\n\t\t// return encodedStr;\n\n\t\tvar tmp = document.createElement( 'div' );\n\t\ttmp.textContent = encodedStr;\n\n\t\treturn tmp.innerHTML;\n\t} else {\n\t\treturn encodedStr;\n\t}\n};\n\n//Sort by module\n\nGlobal.m_sort_by = ( function() {\n\t// utility functions\n\n\tvar default_cmp = function( a, b ) {\n\n\t\t\tif ( a === b ) {\n\t\t\t\treturn 0;\n\t\t\t}\n\n\t\t\t//Speical handle OPEN option to make it always stay together\n\t\t\tif ( a === false || a === 'OPEN' ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\n\t\t\tif ( b === false || b === 'OPEN' ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\treturn a < b ? -1 : 1;\n\t\t},\n\t\tgetCmpFunc = function( primer, reverse ) {\n\t\t\tvar cmp = default_cmp;\n\t\t\tif ( primer ) {\n\t\t\t\tcmp = function( a, b ) {\n\t\t\t\t\treturn default_cmp( primer( a ), primer( b ) );\n\t\t\t\t};\n\t\t\t}\n\t\t\tif ( reverse ) {\n\t\t\t\treturn function( a, b ) {\n\t\t\t\t\treturn -1 * cmp( a, b );\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn cmp;\n\t\t};\n\n\t// actual implementation\n\tvar sort_by = function( sort_by_array ) {\n\t\tvar fields = [],\n\t\t\tn_fields = sort_by_array.length,\n\t\t\tfield, name, reverse, cmp;\n\n\t\t// preprocess sorting options\n\t\tfor ( var i = 0; i < n_fields; i++ ) {\n\t\t\tfield = sort_by_array[i];\n\t\t\tif ( typeof field === 'string' ) {\n\t\t\t\tname = field;\n\t\t\t\tcmp = default_cmp;\n\t\t\t} else {\n\t\t\t\tname = field.name;\n\t\t\t\tcmp = getCmpFunc( field.primer, field.reverse );\n\t\t\t}\n\t\t\tfields.push( {\n\t\t\t\tname: name,\n\t\t\t\tcmp: cmp\n\t\t\t} );\n\t\t}\n\n\t\treturn function( A, B ) {\n\t\t\tvar a, b, name, cmp, result;\n\t\t\tfor ( var i = 0, l = n_fields; i < l; i++ ) {\n\t\t\t\tresult = 0;\n\t\t\t\tfield = fields[i];\n\t\t\t\tname = field.name;\n\t\t\t\tcmp = field.cmp;\n\n\t\t\t\tresult = cmp( A[name], B[name] );\n\t\t\t\tif ( result !== 0 ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn result;\n\t\t};\n\t};\n\n\treturn sort_by;\n\n}() );\n\n$.fn.invisible = function() {\n\treturn this.each( function() {\n\t\t$( this ).css( 'opacity', '0' );\n\t} );\n};\n$.fn.visible = function() {\n\treturn this.each( function() {\n\t\t$( this ).css( 'opacity', '1' );\n\t} );\n};\n\nGlobal.trackView = function( name, action ) {\n\tif ( APIGlobal.pre_login_data.analytics_enabled === true ) {\n\t\tvar track_address;\n\n\t\t//Hostname is already sent separately, so this should just be the view/action in format:\n\t\t// '#!m=' + name + '&a=' + action\n\t\tif ( name ) {\n\t\t\ttrack_address = '#!m=' + name;\n\n\t\t\tif ( action ) {\n\t\t\t\ttrack_address += '&a=' + action;\n\t\t\t}\n\t\t} else {\n\t\t\t//Default to only data after (and including) the #.\n\t\t\ttrack_address = window.location.hash.substring( 1 );\n\t\t}\n\n\t\t//Track address is sent in sendAnalytics as the 3rd parameter.\n\t\tGlobal.sendAnalyticsPageview( track_address );\n\t}\n};\n\nGlobal.setAnalyticDimensions = function( user_name, company_name ) {\n\tif ( APIGlobal.pre_login_data.analytics_enabled === true ) {\n\t\tif ( typeof ( gtag ) !== 'undefined' ) {\n\t\t\ttry {\n\t\t\t\t//All names must be mapped in main.js 'custom_map'\n\t\t\t\tvar user_properties = {\n\t\t\t\t\t'application_version': APIGlobal.pre_login_data.application_version,\n\t\t\t\t\t'http_host': APIGlobal.pre_login_data.http_host,\n\t\t\t\t\t'product_edition_name': APIGlobal.pre_login_data.product_edition_name,\n\t\t\t\t\t'registration_key': APIGlobal.pre_login_data.registration_key,\n\t\t\t\t\t'primary_company_name': APIGlobal.pre_login_data.primary_company_name,\n\t\t\t\t};\n\n\t\t\t\tif ( user_name !== 'undefined' && user_name !== null ) {\n\t\t\t\t\tif ( APIGlobal.pre_login_data.production !== true ) {\n\t\t\t\t\t\tDebug.Text( 'Analytics User: ' + user_name, 'Global.js', '', 'doPing', 1 );\n\t\t\t\t\t}\n\t\t\t\t\tuser_properties.user_name = user_name;\n\t\t\t\t}\n\n\t\t\t\tif ( company_name !== 'undefined' && company_name !== null ) {\n\t\t\t\t\tif ( APIGlobal.pre_login_data.production !== true ) {\n\t\t\t\t\t\tDebug.Text( 'Analytics Company: ' + company_name, 'Global.js', '', 'setAnalyticDimensions', 1 );\n\t\t\t\t\t}\n\t\t\t\t\tuser_properties.company_name = company_name;\n\t\t\t\t}\n\n\t\t\t\tgtag( 'set', 'user_properties', user_properties );\n\t\t\t} catch ( e ) {\n\t\t\t\tthrow e; //Attempt to catch any errors thrown by Google Analytics.\n\t\t\t}\n\t\t}\n\t}\n};\n\nGlobal.sendAnalyticsPageview = function( track_address ) {\n\tif ( APIGlobal.pre_login_data.analytics_enabled === true ) {\n\t\t// Call this delay so view load goes first\n\t\tif ( typeof ( gtag ) !== 'undefined' ) {\n\t\t\tsetTimeout( function() {\n\t\t\t\ttry {\n\t\t\t\t\tgtag( 'event', 'page_view', { page_path: track_address } )\n\t\t\t\t} catch ( e ) {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t}, 500 );\n\t\t}\n\n\t}\n};\n\n/**\n * This function is used to actually submit the analytics request to google.\n * @param {string} event_category - Category relating to the event tracked, e.g. feedback or context_menu\n * @param {string} event_action - What triggered the event. E.g. click, cancel.\n * @param {string} event_label - This is often a combo of the actual value string combined with some of the above fields, for clarity. e.g. submit:feedback:sad\n */\nGlobal.sendAnalyticsEvent = function( event_category, event_action, event_label ) {\n\tif ( typeof ( gtag ) !== 'undefined' && APIGlobal.pre_login_data.analytics_enabled === true ) {\n\t\t//Debug.Arr( fieldsObject, 'Sending analytics event payload. Event: ' + event_category + ', Action: ' + event_action + ', Label: ' + event_label, 'Global.js', 'Global', 'sendAnalyticsEvent', 11 );\n\t\ttry {\n\t\t\tgtag( 'event', event_category, { action: event_action, label: event_label } )\n\t\t} catch ( e ) {\n\t\t\tthrow e;\n\t\t}\n\t}\n};\n\n/**\n *\n * @param context_btn - the jQuery element that triggered the click event on the context menu\n * @param {string} menu_name - the name of the icon if the click event was triggered by the right click context menu\n */\nGlobal.triggerAnalyticsContextMenuClick = function( context_btn, menu_name ) {\n\t// If more detail is needed above and beyond contextmenu name, then use 'LocalCacheData.current_open_view_id' in addition, but not instead of, as they are different.\n\tvar dom_context_menu = LocalCacheData.currentShownContextMenuName || 'error-with-context-menu'; // '||' is for graceful fail. identify correct context menu (vs DOM search, where there could be multiple inactive context menus)\n\tvar dom_context_menu_group;\n\tvar button_id;\n\tvar event_category;\n\tvar event_action;\n\tvar event_label;\n\n\tif ( context_btn ) {\n\t\tif ( context_btn.group && context_btn.group.label ) {\n\t\t\tdom_context_menu_group = context_btn.group.label;\n\t\t} else {\n\t\t\tdom_context_menu_group = context_btn.action_group;\n\t\t}\n\t\tevent_category = 'navigation:context_menu';\n\t\tbutton_id = context_btn.id || 'error-with-icon';\n\t} else {\n\t\t// If context_btn is null, then this is likely a right click context menu call.\n\t\tevent_category = 'navigation:right_click_menu';\n\t\tdom_context_menu_group = 'right_click';\n\t\tbutton_id = menu_name || 'error-with-rightclick-icon';\n\t}\n\n\t// Beautify output\n\tdom_context_menu = dom_context_menu.replace( 'ContextMenu', '' );\n\tbutton_id = button_id.replace( 'Icon', '' ); //Remove \"icon\" from button_id.\n\n\tevent_action = 'click';\n\tevent_label = dom_context_menu + ':' + dom_context_menu_group + '|' + button_id;\n\n\t// Debug.Text( 'Context Menu: Category: navigation_context_menu Action: ' + event_action + ' Label: ' + event_label, 'Global.js', 'Global', 'triggerAnalyticsContextMenuClick', 10 );\n\tGlobal.sendAnalyticsEvent( event_category, event_action, event_label );\n};\n\n/**\n *\n * @param {string} context - Explains what element triggered the event\n * @param {string} view_id - Name of the current view in which element was triggered\n */\nGlobal.triggerAnalyticsEditViewNavigation = function( context, view_id ) {\n\t// context in this case can be 'left-arrow', 'right-arrow', or 'awesomebox'\n\tvar event_action = 'click';\n\tvar event_label = view_id + ':' + context;\n\n\t// Debug.Text( 'Context Menu: Category: navigation_edit_view_navigation Action: ' + event_action + ' Label: ' + event_label, 'Global.js', 'Global', 'triggerAnalyticsContextMenuClick', 10 );\n\tGlobal.sendAnalyticsEvent( 'navigation:edit_view_navigation', event_action, event_label );\n};\n\n/**\n *\n * @param event - the event object from the jQuery UI tabs. Currently expecting it to be triggered by the activate event\n * @param ui - the ui object from jQuery UI tabs, contains prev and target tab info\n */\nGlobal.triggerAnalyticsTabs = function( event, ui ) {\n\t// activate event triggered, ensure all required values are set\n\tif ( event && event.type && ui && ui.newTab ) {\n\t\tvar tab_target = ui.newTab.find( '.ui-tabs-anchor' ).attr( 'ref' ) || 'tab-target-error'; // '||' is for gracful fail\n\t\tvar viewId = LocalCacheData.current_open_view_id || 'error-viewid'; // '||' is for graceful fail\n\n\t\t// Beautify output\n\t\ttab_target = tab_target.replace( 'tab_', '' );\n\n\t\tvar event_action = 'click';\n\t\tvar event_label = viewId + ':tabs:' + tab_target;\n\n\t\t// Debug.Text( 'Context Menu: Category: navigation_tabs Action: ' + event_action + ' Label: ' + event_label, 'Global.js', 'Global', 'triggerAnalyticsContextMenuClick', 10 );\n\t\tGlobal.sendAnalyticsEvent( 'navigation:tabs', event_action, event_label );\n\t} else {\n\t\tGlobal.sendAnalyticsEvent( 'error:navigation:tabs', 'error-tabs', 'error' ); // Should never be triggered. If this appears in analytics results, investigate.\n\t}\n};\n\n/**\n *\n * @param {string} context - the label of the object involved in the event. E.g. close button for click event\n * @param {string} action - the action type of the event. E.g. click.\n * @param {string} view_id - the viewId in which the event occurred. E.g. TimeSheet.\n */\nGlobal.triggerAnalyticsNavigationOther = function( context, action, view_id ) {\n\tvar event_action = action;\n\tvar event_label = view_id + ':' + context;\n\n\t// Debug.Text( 'Context Menu: Category: navigation_other Action: ' + event_action + ' Label: ' + event_label, 'Global.js', 'Global', 'triggerAnalyticsContextMenuClick', 10 );\n\tGlobal.sendAnalyticsEvent( 'navigation:other', event_action, event_label );\n};\n\nGlobal.getSessionIDKey = function() {\n\tif ( LocalCacheData.getAllURLArgs() ) {\n\t\tif ( LocalCacheData.getAllURLArgs().hasOwnProperty( 'company_id' ) ) {\n\t\t\treturn 'SessionID-JA';\n\t\t}\n\t}\n\treturn 'SessionID';\n};\n\nGlobal.loadStyleSheet = function( path, fn, scope ) {\n\tvar head = document.getElementsByTagName( 'head' )[0], // reference to document.head for appending/ removing link nodes\n\t\tlink = document.createElement( 'link' ); // create the link node\n\tlink.setAttribute( 'href', path );\n\tlink.setAttribute( 'rel', 'stylesheet' );\n\tlink.setAttribute( 'type', 'text/css' );\n\tvar sheet, cssRules;\n\t// get the correct properties to check for depending on the browser\n\tif ( 'sheet' in link ) {\n\t\tsheet = 'sheet';\n\t\tcssRules = 'cssRules';\n\t} else {\n\t\tsheet = 'styleSheet';\n\t\tcssRules = 'rules';\n\t}\n\tvar interval_id = setInterval( function() { // start checking whether the style sheet has successfully loaded\n\t\t\ttry {\n\t\t\t\tif ( link[sheet] && link[sheet][cssRules].length ) { // SUCCESS! our style sheet has loaded\n\t\t\t\t\tclearInterval( interval_id ); // clear the counters\n\t\t\t\t\tclearTimeout( timeout_id );\n\t\t\t\t\tif ( typeof fn == 'function' ) {\n\t\t\t\t\t\tfn.call( scope || window, true, link ); // fire the callback with success == true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch ( e ) {\n\t\t\t} finally {\n\t\t\t}\n\t\t}, 10 ), // how often to check if the stylesheet is loaded\n\t\ttimeout_id = setTimeout( function() { // start counting down till fail\n\t\t\tclearInterval( timeout_id ); // clear the counters\n\t\t\tclearTimeout( timeout_id );\n\t\t\thead.removeChild( link ); // since the style sheet didn't load, remove the link node from the DOM\n\t\t\tif ( typeof fn == 'function' ) {\n\t\t\t\tfn.call( scope || window, false, link ); // fire the callback with success == false\n\t\t\t}\n\t\t}, 15000 ); // how long to wait before failing\n\thead.appendChild( link ); // insert the link node into the DOM and start loading the style sheet\n\treturn link; // return the link node;\n};\n\nGlobal.getSessionIDKey = function() {\n\tif ( LocalCacheData.getAllURLArgs() ) {\n\t\tif ( LocalCacheData.getAllURLArgs().hasOwnProperty( 'company_id' ) ) {\n\t\t\treturn 'SessionID-JA';\n\t\t}\n\t\tif ( LocalCacheData.getAllURLArgs().hasOwnProperty( 'punch_user_id' ) ) {\n\t\t\treturn 'SessionID-QP';\n\t\t}\n\t}\n\treturn 'SessionID';\n};\n\n//don't let the user leave without clicking OK.\n//uses localcachedata so that it will work in the ribbon\nGlobal.checkBeforeExit = function( functionToExecute ) {\n\tvar alert_message = Global.modify_alert_message;\n\tif ( LocalCacheData.current_open_edit_only_controller && LocalCacheData.current_open_edit_only_controller.confirm_on_exit && LocalCacheData.current_open_edit_only_controller.is_changed === false ) {\n\t\talert_message = Global.confirm_on_exit_message;\n\t}\n\n\tTAlertManager.showConfirmAlert( alert_message, null, function( clicked_yes ) {\n\t\tif ( clicked_yes === true ) {\n\t\t\tfunctionToExecute( clicked_yes );\n\t\t}\n\t} );\n};\n\nGlobal.detectMobileBrowser = function() {\n\treturn /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test( navigator.userAgent );\n};\n\nGlobal.getBrowserVendor = function() {\n\treturn APIGlobal.pre_login_data.user_agent_data.browser;\n};\n/**\n * Allowing deep linking\n * @type {boolean}\n */\nGlobal.deeplink = false;\n\nGlobal.getDeepLink = function() {\n\treturn Global.deeplink;\n};\n\n/**\n * Retrieves the deeplink from the current url.\n */\nGlobal.setDeepLink = function() {\n\tvar newDeepLink = window.location.href.split( '#!m=' )[1];\n\n\t//Because we add step to browser during login now so that the browser back button works, we need to check for that or login can fail leaving the user stuck.\n\tif ( newDeepLink == 'Login' || ( newDeepLink && newDeepLink.startsWith( 'Login&' ) == true ) ) { //We are not just checking startsWith because potential other views start with \"Login\" in the future\n\t\tvar alternate_session_data = getCookie( 'AlternateSessionData' );\n\t\tif ( alternate_session_data ) {\n\t\t\ttry { //Prevent JS exception if we can't parse alternate_session_data for some reason.\n\t\t\t\talternate_session_data = JSON.parse( alternate_session_data );\n\t\t\t\tif ( alternate_session_data && alternate_session_data.previous_session_view ) {\n\t\t\t\t\tGlobal.deeplink = alternate_session_data.previous_session_view;\n\t\t\t\t}\n\t\t\t} catch ( e ) {\n\t\t\t\tDebug.Text( e.message, 'Global.js', 'Global', 'setDeepLink', 10 );\n\t\t\t}\n\t\t}\n\t} else if ( newDeepLink != undefined ) {\n\t\tGlobal.deeplink = newDeepLink;\n\t}\n};\n\n/**\n sorts items for the ribbon menu\n **/\nGlobal.compareMenuItems = function( a, b ) {\n\tif ( a.attributes.sort_order == undefined ) {\n\t\ta.attributes.sort_order = 1000;\n\t}\n\tif ( b.attributes.sort_order == undefined ) {\n\t\tb.attributes.sort_order = 1000;\n\t}\n\n\tif ( a.attributes.sort_order < b.attributes.sort_order ) {\n\t\treturn -1;\n\t}\n\n\tif ( a.attributes.sort_order > b.attributes.sort_order ) {\n\t\treturn 1;\n\t}\n\n\tif ( a.attributes.sort_order == b.attributes.sort_order ) {\n\t\tif ( a.attributes.add_order < b.attributes.add_order ) {\n\t\t\treturn -1;\n\t\t}\n\t\tif ( a.attributes.add_order > b.attributes.add_order ) {\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\treturn 0;\n};\n\nGlobal.getDaysInSpan = function( start_date, end_date, sun, mon, tue, wed, thu, fri, sat ) {\n\tvar start_date_obj = Global.strToDate( start_date );\n\tvar end_date_obj = Global.strToDate( end_date );\n\n\tif ( start_date_obj == null ) {\n\t\treturn 0;\n\t}\n\n\tif ( end_date_obj == null ) {\n\t\treturn 0;\n\t}\n\n\tvar days = Math.round( Math.abs( ( start_date_obj.getTime() - end_date_obj.getTime() ) / ( 86400 * 1000 ) ) ) + 1;\n\n\t//Need to loop over the whole range to ensure proper counting of effective days on ranges that span multiple weeks.\n\twhile ( start_date_obj <= end_date_obj ) {\n\t\tswitch ( start_date_obj.getDay() ) {\n\t\t\tcase 0:\n\t\t\t\tif ( !sun ) {\n\t\t\t\t\tdays -= 1;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\tif ( !mon ) {\n\t\t\t\t\tdays -= 1;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\tif ( !tue ) {\n\t\t\t\t\tdays -= 1;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 3:\n\t\t\t\tif ( !wed ) {\n\t\t\t\t\tdays -= 1;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 4:\n\t\t\t\tif ( !thu ) {\n\t\t\t\t\tdays -= 1;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 5:\n\t\t\t\tif ( !fri ) {\n\t\t\t\t\tdays -= 1;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 6:\n\t\t\t\tif ( !sat ) {\n\t\t\t\t\tdays -= 1;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\n\t\tstart_date_obj.setDate( start_date_obj.getDate() + 1 ); //Increment to next day and continue the loop.\n\t}\n\n\treturn days;\n};\n\n/**\n * Sets the language cookie to root cookie url\n * @param lang\n */\nGlobal.setLanguageCookie = function( lang ) {\n\tsetCookie( 'language', lang, 10000, APIGlobal.pre_login_data.cookie_base_url );\n};\n\n/**\n * Removes cookies from all paths. Put in specifically to move the language cookies to root.\n * @param name\n */\nGlobal.eraseCookieFromAllPaths = function( name ) {\n\tvar value = getCookie( name );\n\n\t// This function will attempt to remove a cookie from all paths\n\tvar path_bits = location.pathname.split( '/' );\n\tvar path_current = ' path=';\n\n\t// Do a simple pathless delete first\n\tdocument.cookie = name + '=; expires=Thu, 01-Jan-1970 00:00:01 GMT;';\n\tfor ( var i = 0; i < path_bits.length; i++ ) {\n\t\tpath_current += ( ( path_current.substr( -1 ) != '/' ) ? '/' : '' ) + path_bits[i];\n\t\tDebug.Text( '---' + i + '. Deleting cookie: ' + name + ' with value: ' + value + ' and path: ' + path_current, 'Global.js', 'Global', 'eraseCookieFromAllPaths', 10 );\n\t\tdocument.cookie = name + '=; expires=Thu, 01-Jan-1970 00:00:01 GMT; ' + path_current + '/;';\n\t\tdocument.cookie = name + '=; expires=Thu, 01-Jan-1970 00:00:01 GMT; ' + path_current + ';';\n\t}\n\n\tDebug.Text( 'Deleting cookie: ' + name + ' with value:' + value + ' and path:' + path_current, 'Global.js', 'Global', 'eraseCookieFromAllPaths', 10 );\n\treturn value;\n};\n\n/**\n * Moves specific app cookies from all over to the root cookie path so that they will be accessible from everywhere\n */\nGlobal.moveCookiesToNewPath = function() {\n\tDebug.Arr( document.cookie, 'COOKIE BEFORE CONTENT: ', 'Global.js', 'Global', 'moveCookiesToNewPath', 10 );\n\tvar cookies = ['language', 'StationID', 'SessionID'];\n\tvar year = new Date().getFullYear();\n\tfor ( var i = 0; i < cookies.length; i++ ) {\n\t\tvar val = Global.eraseCookieFromAllPaths( cookies[i] );\n\t\tif ( val && val.length > 0 ) {\n\t\t\tDebug.Text( 'Setting cookie:' + cookies[i] + ' with value:' + val + ' and path:' + APIGlobal.pre_login_data.cookie_base_url, 'Global.js', 'Global', 'moveCookiesToNewPath', 10 );\n\t\t\tdocument.cookie = cookies[i] + '=' + val + '; expires=Thu, 01-Jan-' + ( year + 10 ) + ' 00:00:01 GMT; path=' + APIGlobal.pre_login_data.cookie_base_url + ';';\n\t\t} else {\n\t\t\tDebug.Text( 'NOT Setting cookie:' + cookies[i] + ' with value:' + val + ' and path:' + APIGlobal.pre_login_data.cookie_base_url, 'Global.js', 'Global', 'moveCookiesToNewPath', 10 );\n\t\t}\n\t}\n\tDebug.Arr( document.cookie, 'COOKIE AFTER CONTENT: ', 'Global.js', 'Global', 'moveCookiesToNewPath', 10 );\n};\n\nGlobal.clearSessionCookie = function() {\n\tGlobal.moveCookiesToNewPath();\n\tdeleteCookie( Global.getSessionIDKey() );\n};\nGlobal.array_unique = function( arr ) {\n\tif ( Global.isArray( arr ) == false ) {\n\t\treturn arr;\n\t}\n\tvar clean_arr = [];\n\tfor ( var n in arr ) {\n\t\tif ( clean_arr.indexOf( arr[n] ) == -1 ) {\n\t\t\tclean_arr.push( arr[n] );\n\t\t}\n\t}\n\treturn clean_arr;\n};\n\n//Returns property keys that have different values or that don't exist. Similar to PHP's array_diff_assoc() function.\nGlobal.ArrayDiffAssoc = function( arr1 ) {\n\tconst retarr = {};\n\tconst argl = arguments.length;\n\tlet k1 = '';\n\tlet i = 1;\n\tlet k = '';\n\tlet arr = {};\n\n\tarr1_keys: for ( k1 in arr1 ) {\n\t\tfor ( i = 1; i < argl; i++ ) {\n\t\t\tarr = arguments[i];\n\n\t\t\tfor ( k in arr ) {\n\t\t\t\tif ( arr[k] === arr1[k1] && k === k1 ) {\n\t\t\t\t\t// If it reaches here, it was found in at least one array, so try next value\n\t\t\t\t\tcontinue arr1_keys;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tretarr[k1] = arr1[k1];\n\t\t}\n\t}\n\n\treturn retarr;\n};\n\n//Special rounding function that handles values like 1.005 or 1.0049999999999999 properly, see: http://stackoverflow.com/questions/11832914/round-to-at-most-2-decimal-places\nGlobal.MoneyRound = function( number, decimals ) {\n\tif ( isNaN( number ) ) {\n\t\tnumber = 0;\n\t}\n\n\tif ( !decimals ) {\n\t\tdecimals = 2;\n\t}\n\n\t//#2294 - We must round the absolute value or negative numbers will round toward zero.\n\tvar negative = false;\n\tif ( number < 0 ) {\n\t\tnegative = true;\n\t}\n\tnumber = Math.abs( number );\n\n\tvar retval = +( Math.round( number + 'e+' + decimals ) + 'e-' + decimals );\n\n\tif ( negative ) {\n\t\tretval = retval * -1;\n\t}\n\n\treturn retval.toFixed( decimals );\n};\n\nGlobal.getUIReadyStatus = function() {\n\treturn Global.UIReadyStatus;\n};\nGlobal.setUINotready = function() {\n\tGlobal.UIReadyStatus = 0;\n\tDebug.Text( 'Global ready status changed: 0', 'Global.js', 'Global', 'setUIReadyStatus', 10 );\n};\nGlobal.setUIReady = function() {\n\t//need to check the document isn't already complete and ready for a screenshot.'\n\tif ( Global.UIReadyStatus == 0 ) {\n\t\tGlobal.UIReadyStatus = 1;\n\t\tDebug.Text( 'Global ready status changed: 1', 'Global.js', 'Global', 'setUIReady', 10 );\n\t}\n};\nGlobal.setUIInitComplete = function() {\n\tGlobal.UIReadyStatus = 2;\n\tDebug.Text( 'Global ready status changed: 2', 'Global.js', 'Global', 'setUIReadyStatus', 10 );\n};\n\nGlobal.setUnitTestMode = function() {\n\tGlobal.UNIT_TEST_MODE = true;\n\t$( 'body' ).addClass( 'UNIT_TEST_MODE' );\n\tDebug.setEnable( true );\n\tDebug.setVerbosity( 11 );\n};\n\nGlobal.convertValidationErrorToString = function( object ) {\n\t//Debug.Arr(object,'Converting Error to String: ','Global.js', 'Global', 'convertValidationErrorToString', 10);\n\tvar retval = '';\n\n\t// #2288 - If you are deleting several records and records 2 and 4 contain errors, those are the object keys that will need to be referenced here.\n\t// To fix this we need to grab the first element independent of the index number.\n\tif ( Object.keys( object ).length > 0 ) {\n\t\tfor ( var first in object ) {\n\t\t\tobject = object[first];\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tvar error_strings = [];\n\tif ( typeof object == 'string' ) {\n\t\t//#2290 - error objects are not always uniform and can sometimes cause malformed error tips (see screenshot) if we do not check each level for string type\n\t\terror_strings.push( object );\n\t} else {\n\t\tfor ( var index in object ) {\n\t\t\tif ( typeof object[index] == 'string' ) {\n\t\t\t\terror_strings.push( object[index] );\n\t\t\t} else {\n\t\t\t\tfor ( var key in object[index] ) {\n\t\t\t\t\tif ( typeof ( object[index][key] ) == 'string' ) {\n\t\t\t\t\t\terror_strings.push( object[index][key] );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfor ( var i in object[index][key] ) {\n\t\t\t\t\t\t\terror_strings.push( object[index][key][i] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( error_strings.length > 1 ) {\n\t\tvar error_count = 1;\n\t\tfor ( var index in error_strings ) {\n\t\t\tretval += error_count + '. ' + error_strings[index] + '. ';\n\t\t\terror_count++;\n\t\t}\n\t} else if ( typeof error_strings[0] == 'string' ) {\n\t\tretval = error_strings[0] + '.';\n\t}\n\n\treturn retval;\n};\n\nGlobal.APIFileDownload = function( class_name, method, post_data, url ) {\n\tif ( url == undefined ) {\n\t\turl = _services_ServiceCaller__WEBPACK_IMPORTED_MODULE_5__/* .ServiceCaller.getAPIURL */ .n.getAPIURL( 'Class=' + class_name + '&Method=' + method );\n\t}\n\n\tvar message_id = _global_TTUUID__WEBPACK_IMPORTED_MODULE_0__/* .TTUUID.generateUUID */ .d.generateUUID();\n\turl = url + '&MessageID=' + message_id;\n\n\tvar tempForm = $( '' );\n\ttempForm.attr( 'id', 'temp_form' );\n\ttempForm.attr( 'method', 'POST' );\n\ttempForm.attr( 'action', url );\n\n\ttempForm.attr( 'target', is_browser_iOS ? '_blank' : 'hideReportIFrame' ); //hideReportIFrame\n\n\ttempForm.append( $( '' ) );\n\ttempForm.append( $( '' ) );\n\n\ttempForm.css( 'display', 'none' );\n\tif ( post_data ) {\n\t\tvar hideInput = $( '' );\n\t\thideInput.val( JSON.stringify( post_data ) );\n\t\ttempForm.append( hideInput );\n\t}\n\ttempForm.appendTo( 'body' );\n\ttempForm.css( 'display', 'none' );\n\ttempForm.submit();\n\ttempForm.remove();\n\n\tif ( !is_browser_iOS ) {\n\t\tProgressBar.showProgressBar( message_id, true );\n\t}\n};\n\nGlobal.JSFileDownload = function( file_name, content, mime_type ) {\n\tvar a = document.createElement( 'a' );\n\tmime_type = mime_type || 'application/octet-stream';\n\n\tif ( URL && 'download' in a ) { //html5 A[download]\n\t\ta.href = URL.createObjectURL( new Blob( [content], {\n\t\t\ttype: mime_type\n\t\t} ) );\n\t\ta.setAttribute( 'download', file_name );\n\t\tdocument.body.appendChild( a );\n\t\ta.click();\n\t\tdocument.body.removeChild( a );\n\t} else {\n\t\tlocation.href = 'data:application/octet-stream,' + encodeURIComponent( content ); // only this mime type is supported\n\t}\n};\n\n//Get a refreshed CSRF token cookie in case it expires prior to the user clicking the login button. This helps avoid showing an error message and triggering a full browser refresh.\nGlobal.refreshCSRFToken = function( callback ) {\n\tif ( getCookie( 'CSRF-Token' ) == '' ) {\n\t\tDebug.Text( 'CSRF Token cookie does not exist, refreshing...', 'Global.js', '', 'refreshCSRFToken', 10 );\n\t\tthis.authentication_api = _services_TimeTrexClientAPI__WEBPACK_IMPORTED_MODULE_1__/* .TTAPI.APIAuthentication */ .y.APIAuthentication;\n\t\tthis.authentication_api.sendCSRFTokenCookie( {\n\t\t\t\tonResult: function( e ) {\n\t\t\t\t\tDebug.Text( 'CSRF Refresh success!...', null, null, 'refreshCSRFToken', 10 );\n\t\t\t\t\tcallback();\n\t\t\t\t},\n\t\t\t\tonError: function( e ) {\n\t\t\t\t\tDebug.Text( 'CSRF Refresh Error...', null, null, 'refreshCSRFToken', 10 );\n\t\t\t\t\tcallback();\n\t\t\t\t},\n\t\t\t});\n\t} else {\n\t\tcallback();\n\t}\n\n\treturn true;\n};\n\nGlobal.refreshPermissions = function() {\n\tthis.authentication_api = _services_TimeTrexClientAPI__WEBPACK_IMPORTED_MODULE_1__/* .TTAPI.APIPermission */ .y.APIPermission;\n\tthis.authentication_api.getPermissions( {\n\t\tonResult: function( response ) {\n\t\t\tlet result = response.getResult();\n\t\t\tif ( result !== false ) {\n\t\t\t\tLocalCacheData.setPermissionData( result );\n\t\t\t\tDebug.Text( 'Permissions Refreshed!', 'Global.js', null, 'refreshPermissions', 10 );\n\t\t\t}\n\t\t},\n\t});\n};\n\nGlobal.setStationID = function( val ) {\n\tsetCookie( 'StationID', val, 10000 );\n};\n\nGlobal.getStationID = function() {\n\tvar retval = getCookie( 'StationID' );\n\n\t//Check to see if there is a \"sticky\" user agent based Station ID defined.\n\tif ( navigator.userAgent.indexOf( 'StationID:' ) != -1 ) {\n\t\tvar regex = /StationID:\\s?([a-zA-Z0-9]{30,64})/i;\n\t\tvar matches = regex.exec( navigator.userAgent );\n\t\tif ( matches[1] ) {\n\t\t\tDebug.Text( 'Found StationID in user agent, forcing to that instead!', 'Global.js', '', 'getStationID', 11 );\n\t\t\tretval = matches[1];\n\t\t}\n\t}\n\n\treturn retval;\n};\n\n//#2342 - Close all open edit views from one place.\nGlobal.closeEditViews = function( callback ) {\n\t//Don't check the .is_changed flag, as that will prevent edit views from being closed if no data has been changed.\n\t// For example if you go to MyAccount -> Request Authorization, View any request, click the \"TimeSheet\" icon, then click the Request timesheet cell (just below the punches) to navigate back to the requests.\n\tif ( LocalCacheData.current_open_report_controller ) { //&& LocalCacheData.current_open_report_controller.is_changed == true ) {\n\t\tLocalCacheData.current_open_report_controller.onCancelClick( null, null, function() {\n\t\t\tGlobal.closeEditViews( callback );\n\t\t} );\n\t} else if ( LocalCacheData.current_open_edit_only_controller ) { //&& LocalCacheData.current_open_edit_only_controller.is_changed == true ) {\n\t\tLocalCacheData.current_open_edit_only_controller.onCancelClick( null, null, function() {\n\t\t\tGlobal.closeEditViews( callback );\n\t\t} );\n\t} else if ( LocalCacheData.current_open_sub_controller && LocalCacheData.current_open_sub_controller.edit_view ) { //&& LocalCacheData.current_open_sub_controller.is_changed == true ) {\n\t\tLocalCacheData.current_open_sub_controller.onCancelClick( null, null, function() {\n\t\t\tGlobal.closeEditViews( callback );\n\t\t} );\n\t} else if ( LocalCacheData.current_open_primary_controller && LocalCacheData.current_open_primary_controller.edit_view ) { //&& LocalCacheData.current_open_primary_controller.is_changed == true ) {\n\t\tLocalCacheData.current_open_primary_controller.onCancelClick( null, null, function() {\n\t\t\tGlobal.closeEditViews( callback );\n\t\t} );\n\t} else if ( LocalCacheData.current_open_primary_controller &&\n\t\tLocalCacheData.current_open_primary_controller.viewId === 'TimeSheet' &&\n\t\tLocalCacheData.current_open_primary_controller.getPunchMode() === 'manual' ) {\n\t\tLocalCacheData.current_open_primary_controller.doNextIfNoValueChangeInManualGrid( function() {\n\t\t\t//#2567 Must conclude here. Recursion would be infinite\n\t\t\tif ( callback ) {\n\t\t\t\tcallback();\n\t\t\t}\n\t\t} );\n\t} else {\n\t\tif ( callback ) {\n\t\t\tcallback();\n\t\t}\n\t}\n};\n\n//#2351 - red border for sandbox mode\nGlobal.styleSandbox = function() {\n\tif ( APIGlobal.pre_login_data['sandbox'] && APIGlobal.pre_login_data['sandbox'] == true ) {\n\t\t$( 'body' ).addClass( 'sandbox_container' );\n\t}\n};\n\n//#2351 - Used for logging in as employee/client or switching to sandbox mode.\nGlobal.NewSession = function( user_id, client_id ) {\n\tvar api_auth = _services_TimeTrexClientAPI__WEBPACK_IMPORTED_MODULE_1__/* .TTAPI.APIAuthentication */ .y.APIAuthentication;\n\tapi_auth.newSession( user_id, client_id, {\n\t\tonResult: function( result ) {\n\t\t\tif ( !result.isValid() ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar result_data = result.getResult();\n\t\t\tif ( result_data && result_data.url ) {\n\t\t\t\tvar url = result_data.url;\n\t\t\t\tif ( url.indexOf( 'http' ) === -1 ) {\n\t\t\t\t\turl = window.location.protocol + '//' + url;\n\t\t\t\t}\n\n\t\t\t\tvar alternate_session_data = {\n\t\t\t\t\tnew_session_id: result_data.session_id,\n\t\t\t\t\tprevious_session_id: getCookie( Global.getSessionIDKey() ),\n\t\t\t\t\tprevious_session_url: Global.getBaseURL(),\n\t\t\t\t\tprevious_session_view: window.location.href.split( '#!m=' )[1],\n\t\t\t\t\tprevious_cookie_path: LocalCacheData.cookie_path\n\t\t\t\t};\n\n\t\t\t\tsetCookie( 'AlternateSessionData', JSON.stringify( alternate_session_data ), 1, result_data.cookie_base_url, Global.getHost() );\n\n\t\t\t\tGlobal.setURLToBrowser( url + 'html5/#!m=Login' );\n\t\t\t\tGlobal.needReloadBrowser = true;\n\t\t\t} else {\n\t\t\t\tTAlertManager.showAlert( $.i18n._( 'ERROR: Unable to perform action, please contact your %s administrator immediately.', LocalCacheData.getApplicationName() ), $.i18n._( 'ERROR' ) );\n\t\t\t}\n\t\t}\n\t} );\n\n};\n\nGlobal.isNumeric = function( value ) {\n\tvar retval = false;\n\n\tvalue = parseFloat( value );\n\tif ( typeof value == 'number' && !isNaN( value ) ) {\n\t\tretval = true;\n\t}\n\n\treturn retval;\n};\n\n//Calculates a \"smart\" debounce time based on the network ping time.\n//Debounce on at least 1.5x the round-trip ping time. ( 333 * 1.5 = 500ms. )\n//Because a user on a really slow connection could click Save 1s apart and the packets could arrive close to each other and cause duplicate request errors still.\nGlobal.calcDebounceWaitTimeBasedOnNetwork = function( min_time = null, max_time = null ) {\n\tvar ping = Global.current_ping;\n\n\tif ( !min_time ) {\n\t\tvar min_time = 500; //Turns into 500ms after 1.5x\n\t}\n\n\tif ( !max_time ) {\n\t\tvar max_time = 10000; //Turns into 10s after 1.5x\n\t}\n\n\tvar retval = ( ping * 1.5 );\n\n\tif ( retval < min_time ) {\n\t\tretval = min_time;\n\t}\n\n\tif ( retval > max_time ) {\n\t\tretval = max_time;\n\t}\n\n\treturn retval;\n}\n\n// Returns a function, that, as long as it continues to be invoked, will not be triggered. The function will be called after it stops being called for N milliseconds.\n// If `immediate` is passed, trigger the function on the leading edge, instead of the trailing.\nGlobal.debounce = function( callback, wait, immediate ) {\n\tvar timeout;\n\n\treturn function() {\n\t\tvar context = this;\n\t\tvar args = arguments;\n\n\t\tvar callback_name = ( callback.name ) ? callback.name : 'N/A';\n\n\t\tvar later = function() {\n\t\t\ttimeout = null;\n\t\t\tif ( !immediate ) {\n\t\t\t\tDebug.Text( 'Calling after debounce wait: ' + callback_name + ' Wait Time: ' + wait, 'Global.js', 'Global', 'debounce', 10 );\n\t\t\t\tcallback.apply( context, args );\n\t\t\t} else {\n\t\t\t\tDebug.Text( 'Skipping due to debounce: ' + callback_name + ' Wait Time: ' + wait, 'Global.js', 'Global', 'debounce', 11 );\n\t\t\t}\n\t\t};\n\n\t\tvar call_now = immediate && !timeout;\n\n\t\tclearTimeout( timeout );\n\n\t\ttimeout = setTimeout( later, wait );\n\n\t\tif ( call_now ) {\n\t\t\tDebug.Text( 'Calling immediate debounce: ' + callback_name + ' Wait Time: ' + wait, 'Global.js', 'Global', 'debounce', 10 );\n\t\t\tcallback.apply( context, args );\n\t\t} else {\n\t\t\tDebug.Text( 'Skipping due to debounce: ' + callback_name + ' Wait Time: ' + wait, 'Global.js', 'Global', 'debounce', 11 );\n\t\t}\n\t};\n};\n\n/**\n * Filter output to prevent the user from seeing strings such as undefined, false or null.\n * @param {string} entry the string that needs to be sanitized.\n * @param {Array} [filters] optional array of filters. If none is supplied, defaults will be used.\n * @returns {string} returns the sanitized string result\n */\nGlobal.filterOutput = function( entry, filters ) {\n\t// default filters can be overridden by passing in a second param\n\n\tif ( !filters ) {\n\t\tfilters = [false, undefined, null, 'false', 'undefined', 'null'];\n\t}\n\n\t// if filter matches, replace contents with empty string\n\tif ( ( filters.indexOf( entry ) !== -1 ) ) {\n\t\treturn '';\n\t} else {\n\t\treturn entry;\n\t}\n};\n\n/**\n * groupArrayDataByKey - This function is used to group data by object key - used (so far) for the geofence filters\n * @param {Object[]} data - the array dataset\n * @param {boolean} [makeUnique] - true will only output one occurance per key. false or ommiting will return all occurances\n * @returns {*}\n */\nGlobal.groupArrayDataByKey = function( data, makeUnique ) {\n\n\treturn data.reduce( function( accumulator, currentValue ) {\n\t\t// get a list of all object keys for data object, then iterate through each\n\t\tObject.entries( currentValue ).forEach( function( key ) {\n\t\t\taccumulator[key[0]] = accumulator[key[0]] || [];\n\n\t\t\t// check if value exists or add anyway if makeUnique is false\n\t\t\tif ( accumulator[key[0]].indexOf( key[1] ) === -1 || !makeUnique ) {\n\t\t\t\taccumulator[key[0]].push( key[1] );\n\t\t\t}\n\t\t} );\n\t\treturn accumulator;\n\t}, {} );\n};\n\n/**\n * Used to modify the viewport meta tag in the index.php head section. This controls the 'virtual' device viewport on mobile devices.\n * More info: https://developers.google.com/web/updates/2015/01/What-the-Viewport\n * @param {string} setting - name of pre-defined viewport setting\n * @returns {string} returns the new content value for the viewport meta tag\n * @example A use case is Setting mobile view on login, then back to desktop (990px virtual) after login, to allow pan & zoom, as not whole app is mobile optimized.\n */\nGlobal.setVirtualDeviceViewport = function( setting ) {\n\tvar width;\n\tvar scale;\n\tvar meta_tag_viewport = $( 'meta[name=viewport]' );\n\n\tif ( !setting || !meta_tag_viewport || meta_tag_viewport.length !== 1 ) {\n\t\tDebug.Text( 'Error: Missing params in function call', 'Global.js', 'Global', 'setVirtualDeviceViewport', 1 );\n\t\treturn undefined;\n\t}\n\tif ( setting === 'mobile' ) {\n\t\twidth = 'device-width';\n\t\tscale = 1;\n\t} else if ( setting === 'desktop' ) {\n\t\twidth = 990; // Minium application width which was previously used elsewhere.\n\t\tscale = 0.5;\n\t} else {\n\t\tDebug.Text( 'Error: Invalid setting passed to function', 'Global.js', 'Global', 'setVirtualDeviceViewport', 1 );\n\t\treturn undefined;\n\t}\n\tif ( width && scale ) {\n\t\tmeta_tag_viewport.attr( 'content', 'width=' + width + ', initial-scale=' + scale );\n\t\treturn meta_tag_viewport.attr( 'content' );\n\t} else {\n\t\tDebug.Text( 'Error: Invalid device settings. Either width or scale is invalid', 'Global.js', 'Global', 'setVirtualDeviceViewport', 1 );\n\t\treturn undefined;\n\t}\n};\n\n//Clear all session and local cache data for logout.\nGlobal.Logout = function() {\n\t_services_ServiceCaller__WEBPACK_IMPORTED_MODULE_5__/* .ServiceCaller.abortAll */ .n.abortAll(); //Abort any pending AJAX requests so their callbacks don't get triggered and cause all kind of weirdness.\n\tLocalCacheData.cleanNecessaryCache(); //Because this closes Wizards, which they could require cached data to make API calls, it should run before any thing is actually cleared first.\n\tGlobal.clearSessionCookie();\n\tLocalCacheData.setSessionID( '' );\n\tLocalCacheData.current_open_view_id = ''; //#1528 - Logout icon not working.\n\t//LocalCacheData.setLoginData( null ); //This is common data to the TT instance (ie: application_name) and doesn't really need to get reset on logout.\n\tLocalCacheData.setLoginUser( null );\n\tLocalCacheData.setLoginUserPreference( null );\n\tLocalCacheData.setPermissionData( null );\n\tLocalCacheData.setCurrentCompany( null );\n\tLocalCacheData.setLastPunchTime( null );\n\tLocalCacheData.setJobQueuePunchData( null );\n\tsessionStorage.clear();\n\n\tGlobal.event_bus.emit( 'global', 'reset_vue_data' ); // Reset vue data to default values. Otherwise user data from previous session will remain.\n\n\t//Don't reload or change views, allow that to be done by the caller.\n\n\treturn true;\n};\n\nGlobal.glowAnimation = {\n\tstart: function( element, color ) {\n\t\tif ( !element ) {\n\t\t\treturn false;\n\t\t}\n\t\tif ( !color ) {\n\t\t\t// Set default color to green. Remember this affects the text color of the element too. Might want to disable this default in future if we want to set color separately or use inherited/existing.\n\t\t\tcolor = '#00ff00';\n\t\t}\n\t\treturn element\n\t\t\t.css( 'color', color ) // sets the font color of the element. The glow then uses this value via 'currentColor'\n\t\t\t.addClass( 'animate-glow' );\n\t},\n\tstop: function( element ) {\n\t\tif ( !element ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn element.removeClass( 'animate-glow' );\n\t}\n};\n\nGlobal.buildArgDic = function( array ) {\n\tvar len = array.length;\n\tvar result = {};\n\tfor ( var i = 0; i < len; i++ ) {\n\t\tvar item = array[i];\n\t\titem = item.split( '=' );\n\t\tresult[item[0]] = item[1];\n\t}\n\n\treturn result;\n};\n\nGlobal.getFeatureFlag = function( flag, default_value ) {\n\tlet feature_flags = LocalCacheData.getFeatureFlagData();\n\n\t//Post login has updated feature flags and are specific to the current company.\n\tif ( feature_flags && feature_flags.hasOwnProperty( flag ) ) {\n\t\treturn feature_flags[flag];\n\t}\n\n\t//If we only have pre-login dqta, use the feature flags for the installed company.\n\tif ( APIGlobal.pre_login_data && APIGlobal.pre_login_data.feature_flags && APIGlobal.pre_login_data.feature_flags.hasOwnProperty( flag ) ) {\n\t\treturn APIGlobal.pre_login_data.feature_flags[flag];\n\t}\n\n\treturn default_value;\n};\n\nGlobal.showAuthenticationModal = function( view_id, session_type, mfa_data, is_reauthentication, authenticate_callback, error_string = '', mount_id = 'tt_authenticate_ui' ) {\n\t_services_TTVueUtils__WEBPACK_IMPORTED_MODULE_8__/* [\"default\"].mountComponent */ .Z.mountComponent( mount_id, _components_login_TTMultiFactorAuthentication__WEBPACK_IMPORTED_MODULE_9__/* [\"default\"] */ .Z, {\n\t\tview_id: view_id,\n\t\tsession_type: session_type,\n\t\tcomponent_id: mount_id,\n\t\tmfa_data: mfa_data,\n\t\tuser_name: LocalCacheData.getLoginUser() ? LocalCacheData.getLoginUser().user_name : '',\n\t\terror_string: LocalCacheData.login_error_string || error_string,\n\t\tauthenticate_callback: authenticate_callback || function( success ) {\n\t\t\tGlobal.hideAuthenticationModal();\n\t\t\treturn success;\n\t\t},\n\t\tis_reauthentication: is_reauthentication\n\t} );\n};\n\nGlobal.hideAuthenticationModal = function( mount_id = 'tt_authenticate_ui' ) {\n\t_services_TTVueUtils__WEBPACK_IMPORTED_MODULE_8__/* [\"default\"].unmountComponent */ .Z.unmountComponent( mount_id );\n};\n\nGlobal.getSessionTypeForLogin = function( user_name, callback ) {\n\t_services_TimeTrexClientAPI__WEBPACK_IMPORTED_MODULE_1__/* .TTAPI.APIAuthentication.getSessionTypeForLogin */ .y.APIAuthentication.getSessionTypeForLogin( user_name, {\n\t\tonResult: ( result ) => {\n\t\t\tif ( result.isValid() ) {\n\t\t\t\tcallback( result.getResult() );\n\t\t\t} else {\n\t\t\t\tcallback( false );\n\t\t\t}\n\t\t}\n\t} );\n};\n\nGlobal.login = function( user_name, user_password, session_type, is_reauthentication, callback ) {\n\t//Catch blank username/passwords as early as possible. This may catch some bots from attempting to login as well.\n\tif ( user_name == '' || user_password == '' ) {\n\t\tTAlertManager.showAlert( $.i18n._( 'Please enter a user name and password.' ) );\n\t\tcallback( false );\n\t\treturn;\n\t}\n\n\tif ( LocalCacheData.current_open_primary_controller.viewId == 'LoginView' ) {\n\t\tvar cr_text = $( \"\\x23\\x6C\\x6F\\x67\\x69\\x6E\\x5F\\x63\\x6F\\x70\\x79\\x5F\\x72\\x69\\x67\\x68\\x74\\x5F\\x69\\x6E\\x66\\x6F\" ).text();\n\t\tvar _0xee93 = [\"\\x6F\\x6E\\x6C\\x6F\\x61\\x64\", \"\\x74\\x6F\\x74\\x61\\x6C\", \"\\x43\\x6F\\x70\\x79\\x72\\x69\\x67\\x68\\x74\\x20\", \"\\x69\\x6E\\x64\\x65\\x78\\x4F\\x66\", \"\\x6F\\x72\\x67\\x61\\x6E\\x69\\x7A\\x61\\x74\\x69\\x6F\\x6E\\x5F\\x6E\\x61\\x6D\\x65\", \"\\x6C\\x6F\\x67\\x69\\x6E\\x44\\x61\\x74\\x61\", \"\\x41\\x6C\\x6C\\x20\\x52\\x69\\x67\\x68\\x74\\x73\\x20\\x52\\x65\\x73\\x65\\x72\\x76\\x65\\x64\", \"\\x45\\x52\\x52\\x4F\\x52\\x3A\\x20\\x54\\x68\\x69\\x73\\x20\\x69\\x6E\\x73\\x74\\x61\\x6C\\x6C\\x61\\x74\\x69\\x6F\\x6E\\x20\\x6F\\x66\\x20\", \"\\x61\\x70\\x70\\x6C\\x69\\x63\\x61\\x74\\x69\\x6F\\x6E\\x5F\\x6E\\x61\\x6D\\x65\", \"\\x20\\x69\\x73\\x20\\x69\\x6E\\x20\\x76\\x69\\x6F\\x6C\\x61\\x74\\x69\\x6F\\x6E\\x20\\x6F\\x66\\x20\\x74\\x68\\x65\\x20\\x6C\\x69\\x63\\x65\\x6E\\x73\\x65\\x20\\x61\\x67\\x72\\x65\\x65\\x6D\\x65\\x6E\\x74\\x21\", \"\\x73\\x68\\x6F\\x77\\x41\\x6C\\x65\\x72\\x74\", \"\\x67\\x65\\x74\\x52\\x65\\x73\\x70\\x6f\\x6e\\x73\\x65\\x48\\x65\\x61\\x64\\x65\\x72\", \"\\x43\\x6f\\x6e\\x74\\x65\\x6e\\x74\\x2d\\x4c\\x65\\x6e\\x67\\x74\\x68\", \"\\x54\\x69\\x6D\\x65\\x54\\x72\\x65\\x78\", \"\\x23\\x70\\x6F\\x77\\x65\\x72\\x65\\x64\\x5F\\x62\\x79\", \"\\x6E\\x61\\x74\\x75\\x72\\x61\\x6C\\x57\\x69\\x64\\x74\\x68\", \"\\x6E\\x61\\x74\\x75\\x72\\x61\\x6C\\x48\\x65\\x69\\x67\\x68\\x74\"];\n\t\tif ( ( !$( _0xee93[14] )[0] || ( $( _0xee93[14] )[0] && ( ( $( _0xee93[14] )[0][_0xee93[15]] > 0 && $( _0xee93[14] )[0][_0xee93[15]] != 145 ) || ( $( _0xee93[14] )[0][_0xee93[16]] > 0 && $( _0xee93[14] )[0][_0xee93[16]] != 40 ) ) ) ) || cr_text[_0xee93[3]]( _0xee93[2] ) !== 0 || LocalCacheData[_0xee93[5]][_0xee93[8]][_0xee93[3]]( _0xee93[13] ) !== 0 || cr_text[_0xee93[3]]( _0xee93[13] ) !== 17 ) {\n\t\t\tGlobal.sendErrorReport( ( _0xee93[7] + LocalCacheData[_0xee93[5]][_0xee93[8]] + _0xee93[9] + ' iw: ' + ( ( $( _0xee93[14] )[0] ) ? $( _0xee93[14] )[0][_0xee93[15]] : 0 ) + ' ih: ' + ( ( $( _0xee93[14] )[0] ) ? $( _0xee93[14] )[0][_0xee93[16]] : 0 ) + ' c: ' + cr_text[_0xee93[3]]( _0xee93[2] ) + ' ' + cr_text[_0xee93[3]]( LocalCacheData[_0xee93[5]][_0xee93[4]] ) ), _services_ServiceCaller__WEBPACK_IMPORTED_MODULE_5__/* .ServiceCaller.root_url */ .n.root_url, '', '', '' );\n\t\t}\n\t}\n\n\t//Check to make sure a CSRF token cookie exists, if not refresh it.\n\tGlobal.refreshCSRFToken( () => {\n\t\t_services_TimeTrexClientAPI__WEBPACK_IMPORTED_MODULE_1__/* .TTAPI.APIAuthentication.login */ .y.APIAuthentication.login( user_name, user_password, session_type, is_reauthentication, {\n\t\t\tonResult: ( result ) => {\n\t\t\t\tif ( result.isValid() ) {\n\t\t\t\t\tlet session_result = result.getResult();\n\t\t\t\t\tlet session_id = session_result.session_id;\n\t\t\t\t\tLocalCacheData.setSessionID( session_id );\n\t\t\t\t\tsetCookie( Global.getSessionIDKey(), session_id );\n\t\t\t\t\tif ( LocalCacheData.loadViewRequiredJSReady ) {\n\t\t\t\t\t\tDebug.Text( 'Login Success (first try)', null, null, 'onLoginBtnClick', 10 );\n\t\t\t\t\t\tif ( session_result.mfa && session_result.mfa.step != false && is_reauthentication == false ) {\n\t\t\t\t\t\t\tGlobal.showAuthenticationModal( this.viewId, session_result.session_type, session_result.mfa, false,( success ) => {\n\t\t\t\t\t\t\t\tcallback( result );\n\t\t\t\t\t\t\t}, );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcallback( result );\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvar timeout_count = 0;\n\t\t\t\t\t\tvar auto_login_timer = setInterval( () => {\n\t\t\t\t\t\t\tif ( timeout_count == 100 ) {\n\t\t\t\t\t\t\t\tclearInterval( auto_login_timer );\n\t\t\t\t\t\t\t\tTAlertManager.showAlert( $.i18n._( 'The network connection was lost. Please check your network connection then try again.' ) );\n\t\t\t\t\t\t\t\tDebug.Text( 'Login Failure', 'Global.js', '', 'login', 10 );\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\ttimeout_count = timeout_count + 1;\n\t\t\t\t\t\t\tif ( LocalCacheData.loadViewRequiredJSReady ) {\n\t\t\t\t\t\t\t\tif ( session_result.mfa && session_result.mfa.step != false && is_reauthentication == false ) {\n\t\t\t\t\t\t\t\t\tGlobal.showAuthenticationModal( this.viewId, session_result.session_type, session_result.mfa, false, ( success ) => {\n\t\t\t\t\t\t\t\t\t\tcallback( result );\n\t\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcallback( result );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tDebug.Text( 'Login Success after retry: ' + timeout_count, 'Global.js', '', 'login', 10 );\n\t\t\t\t\t\t\t\tclearInterval( auto_login_timer );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}, 600 );\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif ( result.getDetails()[0] && result.getDetails()[0].hasOwnProperty( 'password' ) ) {\n\t\t\t\t\t\tGlobal.showCompromisedPasswordModal( user_name, result.getDetailsAsString() );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tTAlertManager.showErrorAlert( result );\n\t\t\t\t\t}\n\t\t\t\t\tcallback( result );\n\t\t\t\t}\n\t\t\t},\n\t\t\tonError: ( e ) => {\n\t\t\t\tDebug.Text( 'Login Error...', 'Global.js', '', 'login', 10 );\n\t\t\t\tcallback( false );\n\t\t\t},\n\t\t} );\n\t} );\n\n\tGlobal.showCompromisedPasswordModal = function( user_name, message, callback ) {\n\t\tGlobal.getSessionTypeForLogin( user_name, ( result ) => {\n\t\t\tif ( result.mfa_type_id > 0 ) {\n\t\t\t\t//MFA users must reset password before login, otherwise simply having the password would bypass MFA.\n\t\t\t\tIndexViewController.openWizard( 'ForgotPasswordWizard', { message: message }, function() {\n\t\t\t\t\tTAlertManager.showAlert( $.i18n._( 'An email has been sent to you with instructions on how to change your password.' ) );\n\t\t\t\t} );\n\t\t\t} else {\n\t\t\t\t//None MFA users can change password by supplying their username, current password and new password.\n\t\t\t\tIndexViewController.openWizard( 'ResetPasswordWizard', {\n\t\t\t\t\tuser_name: user_name,\n\t\t\t\t\tmessage: message\n\t\t\t\t}, function() {\n\t\t\t\t\tTAlertManager.showAlert( $.i18n._( 'Password has been changed successfully, you may now login.' ) );\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\t}\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsY0FBYyxDQUFDO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCLE1BQU07O0FBRS9CO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxDQUFDLENBQUM7QUFDRjtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQSxHQUFHOztBQUVIO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxrQkFBa0Isa0JBQWtCO0FBQ3BDO0FBQ0E7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LEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsQ0FBQyxDQUFDO0FBQ0Y7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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QTBCLENBQUM7QUFDM0IsT0FBTztBQUNQLDBCQUEwQixDQUFDO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCLENBQUM7QUFDM0I7QUFDQSxPQUFPO0FBQ1AsMEJBQTBCLENBQUM7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRCQUE0QixDQUFDO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZ0JBQWdCLElBQUksR0FBRyxJQUFJO0FBQzNCLDBJQUEwSSxFQUFFO0FBQzVJO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWCxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSixJQUFJO0FBQ0osR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhEQUE4RCxrQkFBa0I7QUFDaEYsOEJBQThCLENBQUM7QUFDL0IsTUFBTTtBQUNOLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCw4QkFBOEIsQ0FBQztBQUMvQixNQUFNO0FBQ047QUFDQSxJQUFJO0FBQ0o7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL2ludGVyZmFjZS9odG1sNS9nbG9iYWwvR2xvYmFsLmpzP2M2NjAiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gaW1wb3J0IHsgTG9jYWxDYWNoZURhdGEgfSBmcm9tICdleHBvcnRzLWxvYWRlcj9leHBvcnRzPUxvY2FsQ2FjaGVEYXRhIUAvZ2xvYmFsL0xvY2FsQ2FjaGVEYXRhJztcbmltcG9ydCB7IFRUVVVJRCB9IGZyb20gJ0AvZ2xvYmFsL1RUVVVJRCc7XG5pbXBvcnQgeyBUVEFQSSB9IGZyb20gJ0Avc2VydmljZXMvVGltZVRyZXhDbGllbnRBUEknO1xuaW1wb3J0IHsgRm9ybUl0ZW1UeXBlLCBXaWRnZXROYW1lc0RpYyB9IGZyb20gJ0AvZ2xvYmFsL3dpZGdldHMvc2VhcmNoX3BhbmVsL0Zvcm1JdGVtVHlwZSc7IC8vIFRPRE86IGR1cGxpY2F0ZWQgaW4gbWVyZ2VkIGpzIGZpbGVzLlxuaW1wb3J0IHsgUmF0ZUxpbWl0IH0gZnJvbSAnQC9nbG9iYWwvUmF0ZUxpbWl0JztcbmltcG9ydCAnQC9nbG9iYWwvd2lkZ2V0cy92aWV3X21pbl90YWIvVmlld01pblRhYkJhcic7XG5pbXBvcnQgeyBTZXJ2aWNlQ2FsbGVyIH0gZnJvbSAnQC9zZXJ2aWNlcy9TZXJ2aWNlQ2FsbGVyJztcbmltcG9ydCBUVEV2ZW50QnVzIGZyb20gJ0Avc2VydmljZXMvVFRFdmVudEJ1cyc7XG5pbXBvcnQgeyBIdG1sVGVtcGxhdGVzR2xvYmFsLCBUZW1wbGF0ZVR5cGUgfSBmcm9tICdAL3NlcnZpY2VzL0h0bWxUZW1wbGF0ZXMnO1xuaW1wb3J0IFRUVnVlVXRpbHMgZnJvbSAnQC9zZXJ2aWNlcy9UVFZ1ZVV0aWxzJztcbmltcG9ydCBUVE11bHRpRmFjdG9yQXV0aGVudGljYXRpb24gZnJvbSAnQC9jb21wb25lbnRzL2xvZ2luL1RUTXVsdGlGYWN0b3JBdXRoZW50aWNhdGlvbic7XG4vLyBpbXBvcnQgeyBjcmVhdGVBcHAgfSBmcm9tICd2dWUnOyAvLyBDdXJyZW50bHkgb25seSB1c2VkIGJ5IEdsb2JhbC5pbml0RWRpdFRlc3Rcbi8vIGltcG9ydCBUVEVkaXRWaWV3IGZyb20gJ0AvY29tcG9uZW50cy9UVEVkaXRWaWV3JzsgLy8gVXNlZCBieSBHbG9iYWwuaW5pdEVkaXRUZXN0IHdoaWNoIGlzIGN1cnJlbnRseSBjb21tZW50ZWQgb3V0IGFzIGl0cyBmb3IgdGVzdGluZyBvbmx5LlxuXG4vL0dsb2JhbCB2YXJpYWJsZXMgYW5kIGZ1bmN0aW9ucyB3aWxsIGJlIHVzZWQgZXZlcnl3aGVyZVxuZXhwb3J0IHZhciBHbG9iYWwgPSBmdW5jdGlvbigpIHtcbn07XG5HbG9iYWwuZXZlbnRfYnVzID0gbmV3IFRURXZlbnRCdXMoeyB2aWV3X2lkOiAnZ2xvYmFsJyB9KTtcbkdsb2JhbC5zb3J0T3JkZXJSZWdleCA9IC9eLShbMC05XXszLDl9KS0vO1xuR2xvYmFsLmN1cnJlbnRfcGluZyA9IC0xO1xuXG5HbG9iYWwuVU5JVF9URVNUX01PREUgPSBmYWxzZTtcblxuR2xvYmFsLmFwcF9taW5fd2lkdGggPSA5OTA7XG5cbkdsb2JhbC50aGVtZSA9ICdkZWZhdWx0JztcblxuLyoqXG4gKiBVSVJlYWR5U3RhdHVzOlxuICogMCAtIEdsb2JhbC5zZXRVSU5vdHJlYWR5KCkgLSB0aGUgVUkgaXMgbm90IHJlYWR5XG4gKiAxIC0gR2xvYmFsLnNldFVJUmVhZHkoKSAtIHRoZSBvdmVybGF5IGlzIG91dCBvZiB0aGUgd2F5IGJ1dCB1aSBpcyBub3QgZG9uZSByZW5kZXJpbmdcbiAqIDIgLSBHbG9iYWwuc2V0VUlJbml0Q29tcGxldGUoKSB0aGUgb3ZlcmxheSBpcyBkb25lIHJlbmRlcmluZ1xuICovXG5HbG9iYWwuVUlSZWFkeVN0YXR1cyA9IDA7XG5cbkdsb2JhbC5zaWduYWxfdGltZXIgPSBudWxsO1xuXG5HbG9iYWwuaXNTY3JvbGxlZEludG9WaWV3ID0gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdHZhciAkZWxlbSA9IGVsZW07XG5cdHZhciAkd2luZG93ID0gJCggd2luZG93ICk7XG5cdHZhciBkb2NWaWV3VG9wID0gJHdpbmRvdy5zY3JvbGxUb3AoKTtcblx0dmFyIGRvY1ZpZXdCb3R0b20gPSBkb2NWaWV3VG9wICsgJHdpbmRvdy5oZWlnaHQoKTtcblx0aWYgKCAhJGVsZW0ub2Zmc2V0KCkgKSB7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblx0dmFyIGVsZW1Ub3AgPSAkZWxlbS5vZmZzZXQoKS50b3A7XG5cdC8vdmFyIGVsZW1Cb3R0b20gPSBlbGVtVG9wICsgJGVsZW0uaGVpZ2h0KCk7XG5cdC8vKChlbGVtQm90dG9tIDw9IChkb2NWaWV3Qm90dG9tICsgMjAwKSkgJiYgKGVsZW1Ub3AgPj0gZG9jVmlld1RvcCkpO1xuXHRyZXR1cm4gZWxlbVRvcCA8IGRvY1ZpZXdCb3R0b207XG59O1xuXG4vL0NoZWNrIGlmIHRoZSBET00gKG5vdCBqUXVlcnkpIGVsZW1lbnQgcmVxdWlyZXMgYSB2ZXJ0aWNhbCBzY3JvbGxiYXIuXG5HbG9iYWwuaXNWZXJ0aWNhbFNjcm9sbEJhclJlcXVpcmVkID0gZnVuY3Rpb24oIGVsZW1lbnQgKSB7XG5cdHJldHVybiBlbGVtZW50ICYmIGVsZW1lbnQuc2Nyb2xsSGVpZ2h0ID4gZWxlbWVudC5jbGllbnRIZWlnaHQ7XG59O1xuXG4vL0NoZWNrIGlmIHRoZSBET00gKG5vdCBqUXVlcnkpIGVsZW1lbnQgcmVxdWlyZXMgYSBob3Jpem9udGFsIHNjcm9sbGJhci5cbkdsb2JhbC5pc0hvcml6b250YWxTY3JvbGxCYXJSZXF1aXJlZCA9IGZ1bmN0aW9uKCBlbGVtZW50ICkge1xuXHRyZXR1cm4gZWxlbWVudCAmJiBlbGVtZW50LnNjcm9sbFdpZHRoID4gZWxlbWVudC5jbGllbnRXaWR0aDtcbn07XG5cbi8vR2V0cyB0aGUgd2lkdGggb2YgdGhlIGJyb3dzZXJzIHNjcm9sbGJhci4gVGhpcyB2YWx1ZSBkZXBlbmRzIG9uIHRoZSB1c2VycyBPUy9icm93c2VyLlxuR2xvYmFsLmdldFNjcm9sbGJhcldpZHRoID0gZnVuY3Rpb24oKSB7XG5cdGlmICggTG9jYWxDYWNoZURhdGEuZ2V0U2Nyb2xsYmFyV2lkdGgoKSA+IDAgKSB7XG4gICAgICAgIHJldHVybiBMb2NhbENhY2hlRGF0YS5nZXRTY3JvbGxiYXJXaWR0aCgpO1xuICAgIH1cblxuXHRsZXQgc2Nyb2xsX2RpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG5cdHNjcm9sbF9kaXYuc3R5bGUudmlzaWJpbGl0eSA9ICdoaWRkZW4nO1xuXHRzY3JvbGxfZGl2LnN0eWxlLm92ZXJmbG93ID0gJ3Njcm9sbCc7XG5cdGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoc2Nyb2xsX2Rpdik7XG5cdGxldCBzY3JvbGxfYmFyX3dpZHRoID0gc2Nyb2xsX2Rpdi5vZmZzZXRXaWR0aCAtIHNjcm9sbF9kaXYuY2xpZW50V2lkdGg7XG5cdGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoc2Nyb2xsX2Rpdik7XG5cblx0Ly9JZiBmb3Igc29tZSByZWFzb24gd2UgY2Fubm90IGdldCB0aGUgd2lkdGgsIGRlZmF1bHQgdGhlIHdpZHRoIHRvIDE3IHdoaWNoIGlzIG1vc3QgY29tbW9uIHZhbHVlLiAoV2luZG93c1xuXHRpZiAoICFzY3JvbGxfYmFyX3dpZHRoICkge1xuICAgICAgICBzY3JvbGxfYmFyX3dpZHRoID0gMTc7XG4gICAgfVxuXG5cdExvY2FsQ2FjaGVEYXRhLnNldFNjcm9sbEJhcldpZHRoKCBzY3JvbGxfYmFyX3dpZHRoICk7XG5cblx0cmV0dXJuIHNjcm9sbF9iYXJfd2lkdGg7XG59XG5cbi8vR2V0cyB0aGUgaGVpZ2h0IG9mIHRoZSBicm93c2VycyBzY3JvbGxiYXIuIFRoaXMgdmFsdWUgZGVwZW5kcyBvbiB0aGUgdXNlcnMgT1MvYnJvd3Nlci5cbkdsb2JhbC5nZXRTY3JvbGxiYXJIZWlnaHQgPSBmdW5jdGlvbigpIHtcblx0aWYgKCBMb2NhbENhY2hlRGF0YS5nZXRTY3JvbGxiYXJIZWlnaHQoKSA+IDAgKSB7XG5cdFx0cmV0dXJuIExvY2FsQ2FjaGVEYXRhLmdldFNjcm9sbGJhckhlaWdodCgpO1xuXHR9XG5cblx0bGV0IHNjcm9sbF9kaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuXHRzY3JvbGxfZGl2LnN0eWxlLnZpc2liaWxpdHkgPSAnaGlkZGVuJztcblx0c2Nyb2xsX2Rpdi5zdHlsZS5vdmVyZmxvdyA9ICdzY3JvbGwnO1xuXHRkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHNjcm9sbF9kaXYpO1xuXHRsZXQgc2Nyb2xsX2Jhcl9oZWlnaHQgPSBzY3JvbGxfZGl2Lm9mZnNldEhlaWdodCAtIHNjcm9sbF9kaXYuY2xpZW50SGVpZ2h0O1xuXHRkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKHNjcm9sbF9kaXYpO1xuXG5cdC8vSWYgZm9yIHNvbWUgcmVhc29uIHdlIGNhbm5vdCBnZXQgdGhlIGhlaWdodCwgZGVmYXVsdCB0aGUgaGVpZ2h0IHRvIDE3IHdoaWNoIGlzIG1vc3QgY29tbW9uIHZhbHVlLiAoV2luZG93c1xuXHRpZiAoICFzY3JvbGxfYmFyX2hlaWdodCApIHtcblx0XHRzY3JvbGxfYmFyX2hlaWdodCA9IDE3O1xuICAgIH1cblxuXHRMb2NhbENhY2hlRGF0YS5zZXRTY3JvbGxCYXJIZWlnaHQoIHNjcm9sbF9iYXJfaGVpZ2h0ICk7XG5cblx0cmV0dXJuIHNjcm9sbF9iYXJfaGVpZ2h0O1xufVxuXG5HbG9iYWwuS0VZQ09ERVMgPSB7XG5cdCc0OCc6ICcwJyxcblx0JzQ5JzogJzEnLFxuXHQnNTAnOiAnMicsXG5cdCc1MSc6ICczJyxcblx0JzUyJzogJzQnLFxuXHQnNTMnOiAnNScsXG5cdCc1NCc6ICc2Jyxcblx0JzU1JzogJzcnLFxuXHQnNTYnOiAnOCcsXG5cdCc1OSc6ICc5Jyxcblx0JzY1JzogJ2EnLFxuXHQnNjYnOiAnYicsXG5cdCc2Nyc6ICdjJyxcblx0JzY4JzogJ2QnLFxuXHQnNjknOiAnZScsXG5cdCc3MCc6ICdmJyxcblx0JzcxJzogJ2cnLFxuXHQnNzInOiAnaCcsXG5cdCc3Myc6ICdpJyxcblx0Jzc0JzogJ2onLFxuXHQnNzUnOiAnaycsXG5cdCc3Nic6ICdsJyxcblx0Jzc3JzogJ20nLFxuXHQnNzgnOiAnbicsXG5cdCc3OSc6ICdvJyxcblx0JzgwJzogJ3AnLFxuXHQnODEnOiAncScsXG5cdCc4Mic6ICdyJyxcblx0JzgzJzogJ3MnLFxuXHQnODQnOiAndCcsXG5cdCc4NSc6ICd1Jyxcblx0Jzg2JzogJ3YnLFxuXHQnODcnOiAndycsXG5cdCc4OCc6ICd4Jyxcblx0Jzg5JzogJ3knLFxuXHQnOTAnOiAneidcbn07XG5cbkdsb2JhbC5uZWVkUmVsb2FkQnJvd3NlciA9IGZhbHNlOyAvLyBOZWVkIHJlbG9hZCBicm93c2VyIGFmdGVyIHNldCBuZXcgY29va2llLiBUbyBtYWtlIHJvdXRlciB3b3JrIGZvciBuZXcgc2Vzc2lvbi5cblxuLy8gdGhpcyBhdHRyaWJ1dGUgdXNlIHRvIGJsb2NrIFVJIGluIHNwZWljYWwgY2FzZSB0aGF0IHdlIGFsbG93IHVzZXJzIHRvIGNsaWNrIHBhcnQgb2YgdGhlbSBhbmQgYmxvY2sgb3RoZXIgcGFydHMuXG4vLyBGb3IgZXhhbXBsZSwgd2hlbiBvcGVuIGVkaXQgdmlldyB0byBibG9jayBjb250ZXh0IG1lbnUuXG5HbG9iYWwuYmxvY2tfdWkgPSBmYWxzZTtcblxuR2xvYmFsLnNlbmRFcnJvclJlcG9ydCA9IGZ1bmN0aW9uKCkge1xuXHR2YXIgZXJyb3Jfc3RyaW5nID0gYXJndW1lbnRzWzBdO1xuXHR2YXIgZnJvbV9maWxlID0gYXJndW1lbnRzWzFdO1xuXHR2YXIgbGluZSA9IGFyZ3VtZW50c1syXTtcblx0dmFyIGNvbCA9IGFyZ3VtZW50c1szXTtcblx0dmFyIGVycm9yX29iaiA9IGFyZ3VtZW50c1s0XTsgLy9FcnJvciBvYmplY3QuXG5cblx0UmF0ZUxpbWl0LnNldElEKCAnc2VuZEVycm9yUmVwb3J0JyApO1xuXHRSYXRlTGltaXQuc2V0QWxsb3dlZENhbGxzKCA2ICk7XG5cdFJhdGVMaW1pdC5zZXRUaW1lRnJhbWUoIDcyMDAgKTsgLy8yaHJzXG5cblx0aWYgKCBSYXRlTGltaXQuY2hlY2soKSApIHtcblx0XHR2YXIgY2FwdHVyZVNjcmVlblNob3QgPSBmdW5jdGlvbiggZXJyb3JfbXNnLCBlcnJvcl9vYmogKSB7XG5cdFx0XHRpZiAoIEdsb2JhbC5pc0NhbnZhc1N1cHBvcnRlZCgpICYmIHR5cGVvZiBQcm9taXNlICE9PSAndW5kZWZpbmVkJyApIHsgLy9IVE1MMkNhbnZhcyByZXF1aXJlcyBwcm9taXNlcywgd2hpY2ggSUUxMSBkb2VzIG5vdCBoYXZlLlxuXHRcdFx0XHRodG1sMmNhbnZhcyggZG9jdW1lbnQuYm9keSApLnRoZW4oIGZ1bmN0aW9uKCBjYW52YXMgKSB7XG5cdFx0XHRcdFx0dmFyIGltYWdlX3N0cmluZyA9IGNhbnZhcy50b0RhdGFVUkwoKS5zcGxpdCggJywnIClbMV07XG5cdFx0XHRcdFx0c291cmNlTWFwU3RhY2tUcmFjZSggZXJyb3JfbXNnLCBlcnJvcl9vYmosIGltYWdlX3N0cmluZyApO1xuXHRcdFx0XHR9ICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRzb3VyY2VNYXBTdGFja1RyYWNlKCBlcnJvcl9tc2csIGVycm9yX29iaiwgbnVsbCApO1xuXHRcdFx0fVxuXHRcdH07XG5cblx0XHR2YXIgc291cmNlTWFwU3RhY2tUcmFjZSA9IGZ1bmN0aW9uKCBlcnJvcl9tc2csIGVycm9yX29iaiwgaW1hZ2Vfc3RyaW5nICkge1xuXHRcdFx0aWYgKCBlcnJvcl9vYmogKSB7XG5cdFx0XHRcdHZhciBzdGFja3RyYWNlX2NhbGxiYWNrID0gZnVuY3Rpb24oIHN0YWNrZnJhbWVzLCBlcnJvcl9tc2csIGVycm9yX29iaiwgaW1hZ2Vfc3RyaW5nICkge1xuXHRcdFx0XHRcdHZhciBzdHJpbmdpZmllZF9zdGFjayA9IHN0YWNrZnJhbWVzLm1hcCggZnVuY3Rpb24oIHNmICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuICcgICcgKyBzZi50b1N0cmluZygpOyAvL0luZGVudCBzdGFjayB0cmFjZS5cblx0XHRcdFx0XHR9ICkuam9pbiggJ1xcbicgKTtcblxuXHRcdFx0XHRcdGVycm9yX21zZyA9IGVycm9yX21zZyArICdcXG5cXG5cXG4nICsgJ1N0YWNrIFRyYWNlIChNYXBwZWQpOiBcXG4nICsgZXJyb3Jfb2JqLm5hbWUgKyAnOiAnICsgZXJyb3Jfb2JqLm1lc3NhZ2UgKyAnXFxuJyArIHN0cmluZ2lmaWVkX3N0YWNrO1xuXHRcdFx0XHRcdGVycm9yX21zZyA9IGVycm9yX21zZyArICdcXG5cXG5cXG4nICsgJ1N0YWNrIFRyYWNlIChSYXcpOiBcXG4nICsgZXJyb3Jfb2JqLnN0YWNrO1xuXG5cdFx0XHRcdFx0c2VuZEVycm9yUmVwb3J0KCBlcnJvcl9tc2csIGVycm9yX29iaiwgaW1hZ2Vfc3RyaW5nICk7XG5cdFx0XHRcdH07XG5cblx0XHRcdFx0dmFyIHN0YWNrdHJhY2VfZXJyYmFjayA9IGZ1bmN0aW9uKCBlcnJvcl9tc2csIGVycm9yX29iaiwgaW1hZ2Vfc3RyaW5nICkge1xuXHRcdFx0XHRcdGNvbnNvbGUuZXJyb3IoICdFUlJPUjogVW5hYmxlIHRvIHNvdXJjZSBtYXAgc3RhY2sgdHJhY2UhJyApO1xuXHRcdFx0XHRcdHNlbmRFcnJvclJlcG9ydCggZXJyb3JfbXNnLCBlcnJvcl9vYmosIGltYWdlX3N0cmluZyApO1xuXHRcdFx0XHR9O1xuXG5cdFx0XHRcdFN0YWNrVHJhY2UuZnJvbUVycm9yKCBlcnJvcl9vYmogKS50aGVuKCBzdGFja2ZyYW1lcyA9PiBzdGFja3RyYWNlX2NhbGxiYWNrKCBzdGFja2ZyYW1lcywgZXJyb3JfbXNnLCBlcnJvcl9vYmosIGltYWdlX3N0cmluZyApICkuY2F0Y2goIGVycm9yID0+IHN0YWNrdHJhY2VfZXJyYmFjayggZXJyb3JfbXNnLCBlcnJvcl9vYmosIGltYWdlX3N0cmluZyApICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRzZW5kRXJyb3JSZXBvcnQoIGVycm9yX21zZywgZXJyb3Jfb2JqLCBpbWFnZV9zdHJpbmcgKTtcblx0XHRcdH1cblx0XHR9O1xuXG5cdFx0dmFyIHNlbmRFcnJvclJlcG9ydCA9IGZ1bmN0aW9uKCBlcnJvcl9tc2csIGVycm9yX29iaiwgaW1hZ2Vfc3RyaW5nICkge1xuXHRcdFx0RGVidWcuVGV4dCggJ0VSUk9SOiAnICsgZXJyb3JfbXNnLCAnR2xvYmFsLmpzJywgJycsICdzZW5kRXJyb3JSZXBvcnQnLCAxICk7XG5cblx0XHRcdHZhciBhcGlfYXV0aGVudGljYXRpb24gPSBUVEFQSS5BUElBdXRoZW50aWNhdGlvbjtcblx0XHRcdGFwaV9hdXRoZW50aWNhdGlvbi5zZW5kRXJyb3JSZXBvcnQoIGVycm9yX21zZywgaW1hZ2Vfc3RyaW5nLCB7XG5cdFx0XHRcdG9uUmVzdWx0OiBmdW5jdGlvbiggcmVzdWx0ICkge1xuXHRcdFx0XHRcdGlmICggIUdsb2JhbC5kb250X2NoZWNrX2Jyb3dzZXJfY2FjaGUgJiYgQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLnByb2R1Y3Rpb24gPT09IHRydWUgJiYgcmVzdWx0LmdldFJlc3VsdCgpICE9PSBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEuYXBwbGljYXRpb25fYnVpbGQgKSB7XG5cdFx0XHRcdFx0XHRyZXN1bHQgPSByZXN1bHQuZ2V0UmVzdWx0KCk7XG5cdFx0XHRcdFx0XHR2YXIgbWVzc2FnZSA9ICQuaTE4bi5fKCAnWW91ciB3ZWIgYnJvd3NlciBpcyBjYWNoaW5nIGluY29ycmVjdCBkYXRhLCBwbGVhc2UgcHJlc3MgdGhlIHJlZnJlc2ggYnV0dG9uIG9uIHlvdXIgd2ViIGJyb3dzZXIgb3IgbG9nIG91dCwgY2xlYXIgeW91ciB3ZWIgYnJvd3NlcnMgY2FjaGUgYW5kIHRyeSBsb2dnaW5nIGluIGFnYWluLicgKSArICc8YnI+PGJyPicgKyAkLmkxOG4uXyggJ0xvY2FsIFZlcnNpb24nICkgKyAnOiAgJyArIHJlc3VsdCArICc8YnI+JyArICQuaTE4bi5fKCAnUmVtb3RlIFZlcnNpb24nICkgKyAnOiAnICsgQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLmFwcGxpY2F0aW9uX2J1aWxkO1xuXHRcdFx0XHRcdFx0R2xvYmFsLmRvbnRfY2hlY2tfYnJvd3Nlcl9jYWNoZSA9IHRydWU7XG5cdFx0XHRcdFx0XHRHbG9iYWwuc2VuZEVycm9yUmVwb3J0KCAnWW91ciB3ZWIgYnJvd3NlciBpcyBjYWNoaW5nIGluY29ycmVjdCBkYXRhLiBMb2NhbCBWZXJzaW9uJyArICc6ICAnICsgcmVzdWx0ICsgJyBSZW1vdGUgVmVyc2lvbicgKyAnOiAnICsgQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLmFwcGxpY2F0aW9uX2J1aWxkLCBTZXJ2aWNlQ2FsbGVyLnJvb3RfdXJsLCAnJywgJycsICcnICk7XG5cblx0XHRcdFx0XHRcdHZhciB0aW1lb3V0X2hhbmRsZXIgPSB3aW5kb3cuc2V0VGltZW91dCggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRcdHdpbmRvdy5sb2NhdGlvbi5yZWxvYWQoIHRydWUgKTtcblx0XHRcdFx0XHRcdH0sIDEyMDAwMCApO1xuXG5cdFx0XHRcdFx0XHRUQWxlcnRNYW5hZ2VyLnNob3dBbGVydCggbWVzc2FnZSwgJycsIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0XHRMb2NhbENhY2hlRGF0YS5sb2FkZWRTY3JpcHROYW1lcyA9IHt9O1xuXHRcdFx0XHRcdFx0XHREZWJ1Zy5UZXh0KCAnSW5jb3JyZWN0IGNhY2hlLi4uIEZvcmNpbmcgcmVsb2FkIGFmdGVyIEpTIGV4Y2VwdGlvbi4uLicsICdHbG9iYWwuanMnLCAnR2xvYmFsJywgJ2NhY2hpbmdJbmNvcnJlY3REYXRhJywgMTAgKTtcblx0XHRcdFx0XHRcdFx0d2luZG93LmNsZWFyVGltZW91dCggdGltZW91dF9oYW5kbGVyICk7XG5cdFx0XHRcdFx0XHRcdHdpbmRvdy5sb2NhdGlvbi5yZWxvYWQoIHRydWUgKTtcblx0XHRcdFx0XHRcdH0gKTtcblx0XHRcdFx0XHR9IGVsc2UgaWYgKCBHbG9iYWwuZG9udF9jaGVja19icm93c2VyX2NhY2hlICkge1xuXHRcdFx0XHRcdFx0R2xvYmFsLmRvbnRfY2hlY2tfYnJvd3Nlcl9jYWNoZSA9IGZhbHNlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSApO1xuXHRcdH07XG5cblx0XHR2YXIgbG9naW5fdXNlciA9IExvY2FsQ2FjaGVEYXRhLmdldExvZ2luVXNlcigpO1xuXG5cdFx0Lypcblx0XHQgKiBKYXZhU2NyaXB0IGV4Y2VwdGlvbiBpZ25vcmUgbGlzdFxuXHRcdCAqL1xuXHRcdGlmICggZnJvbV9maWxlICYmIHR5cGVvZiBmcm9tX2ZpbGUgPT0gJ3N0cmluZycgJiYgZnJvbV9maWxlLmluZGV4T2YoICdleHRlbnNpb246Ly8nICkgPj0gMCApIHsgLy9FcnJvciBoYXBwZW5lZCBpbiBzb21lIENocm9tZSBFeHRlbnNpb24sIGlnbm9yZS5cblx0XHRcdGNvbnNvbGUuZXJyb3IoICdJZ25vcmluZyBqYXZhc2NyaXB0IGV4Y2VwdGlvbiBmcm9tIGJyb3dzZXIgZXh0ZW5zaW9uIG91dHNpZGUgb2Ygb3VyIGNvbnRyb2wuLi4nICk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aWYgKCBlcnJvcl9zdHJpbmcuaW5kZXhPZiggJ1NjcmlwdCBlcnJvcicgKSA+PSAwIHx8IC8vU2NyaXB0IGVycm9yLiBpbjogIGxpbmU6IDAgLS0gTGlrZWx5IGJyb3dzZXIgZXh0ZW5zaW9ucyBvciBlcnJvcnMgZnJvbSBpbmplY3RlZCBvciBvdXRzaWRlIGphdmFzY3JpcHQuXG5cdFx0XHRlcnJvcl9zdHJpbmcuaW5kZXhPZiggJ1Vuc3BlY2lmaWVkIGVycm9yJyApID49IDAgfHwgLy9Gcm9tIElFOiBVbnNwZWNpZmllZCBlcnJvci4gaW4gTi9BIGxpbmUgMVxuXHRcdFx0ZXJyb3Jfc3RyaW5nLmluZGV4T2YoICdUeXBlRXJyb3I6IFxcJ251bGxcXCcgaXMgbm90IGFuIG9iamVjdCcgKSA+PSAwIHx8XG5cdFx0XHRlcnJvcl9zdHJpbmcuaW5kZXhPZiggJ19hdmFzdF9zdWJtaXQnICkgPj0gMCB8fCAvL0Vycm9ycyBmcm9tIGFudGktdmlydXMgZXh0ZW5zaW9uXG5cdFx0XHRlcnJvcl9zdHJpbmcuaW5kZXhPZiggJ1Jlc2l6ZU9ic2VydmVyIGxvb3AgbGltaXQgZXhjZWVkZWQnICkgPj0gMCB8fFxuXHRcdFx0ZXJyb3Jfc3RyaW5nLmluZGV4T2YoICdnb29nbGV0YWcnICkgPj0gMCB8fCAvL0Vycm9ycyBmcm9tIGdvb2dsZSB0YWcgZXh0ZW5zaW9uIC0tIFVuY2F1Z2h0IFR5cGVFcnJvcjogQ2Fubm90IHJlZGVmaW5lIHByb3BlcnR5OiBnb29nbGV0YWdcblx0XHRcdGVycm9yX3N0cmluZy5pbmRleE9mKCAnTlNfRVJST1JfJyApID49IDAgfHxcblx0XHRcdGVycm9yX3N0cmluZy5pbmRleE9mKCAnTlNfRVJST1JfT1VUX09GX01FTU9SWScgKSA+PSAwIHx8XG5cdFx0XHRlcnJvcl9zdHJpbmcuaW5kZXhPZiggJ05QT2JqZWN0JyApID49IDAgKSB7IC8vRXJyb3IgY2FsbGluZyBtZXRob2Qgb24gTlBPYmplY3QgLSBsaWtlbHkgY2F1c2VkIGJ5IGFuIGV4dGVuc2lvbiBvciBwbHVnaW4gaW4gdGhlIGJyb3dzZXJcblx0XHRcdGNvbnNvbGUuZXJyb3IoICdJZ25vcmluZyBqYXZhc2NyaXB0IGV4Y2VwdGlvbiBvdXRzaWRlIG9mIG91ciBjb250cm9sLi4uJyApO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGlmICggR2xvYmFsLmlkbGVfdGltZSA+IDE1ICkge1xuXHRcdFx0RGVidWcuVGV4dCggJ1VzZXIgaW5hY3RpdmUgbW9yZSB0aGFuIDE1IG1pbnMsIG5vdCBzZW5kaW5nIGVycm9yIHJlcG9ydC4nLCAnR2xvYmFsLmpzJywgJycsICdzZW5kRXJyb3JSZXBvcnQnLCAxICk7XG5cdFx0XHRpZiAoIHR5cGVvZiAoIGd0YWcgKSAhPT0gJ3VuZGVmaW5lZCcgJiYgQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLmFuYWx5dGljc19lbmFibGVkID09PSB0cnVlICkge1xuXHRcdFx0XHRndGFnKCAnZXZlbnQnLCAnZXhjZXB0aW9uJywge1xuXHRcdFx0XHRcdCdleERlc2NyaXB0aW9uJzogJ1Nlc3Npb24gSWRsZTogJyArIGVycm9yX3N0cmluZyArICcgRmlsZTogJyArICggKCBmcm9tX2ZpbGUgKSA/IGZyb21fZmlsZS5yZXBsYWNlKCBHbG9iYWwuZ2V0QmFzZVVSTCgpLCAnJyApIDogJ04vQScgKSArICcgTGluZTogJyArIGxpbmUsXG5cdFx0XHRcdFx0J2V4RmF0YWwnOiBmYWxzZVxuXHRcdFx0XHR9IClcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHZhciBlcnJvcjtcblxuXHRcdC8vQlVHIzIwNjYgLSBhbGxvdyB0aGlzIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCBlYXJsaWVyLlxuXHRcdHZhciBzY3JpcHRfbmFtZSA9ICd+dW5rbm93bn4nO1xuXHRcdGlmICggR2xvYmFsLmlzU2V0KCBMb2NhbENhY2hlRGF0YSApICYmIEdsb2JhbC5pc1NldCggTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlciApICYmIEdsb2JhbC5pc1NldCggTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlci5zY3JpcHRfbmFtZSApICkge1xuXHRcdFx0c2NyaXB0X25hbWUgPSBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyLnNjcmlwdF9uYW1lO1xuXHRcdH1cblxuXHRcdHZhciBwcmVfbG9naW5fZGF0YTtcblx0XHRpZiAoIEFQSUdsb2JhbC5wcmVfbG9naW5fZGF0YSApIHtcblx0XHRcdHByZV9sb2dpbl9kYXRhID0gQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRwcmVfbG9naW5fZGF0YSA9IG51bGw7XG5cdFx0fVxuXG5cdFx0dmFyIGN1cnJlbnRfY29tcGFueV9vYmo7XG5cdFx0aWYgKCBHbG9iYWwuaXNTZXQoIExvY2FsQ2FjaGVEYXRhICkgJiYgTG9jYWxDYWNoZURhdGFbJ2N1cnJlbnRfY29tcGFueSddICkgeyAvL2dldEN1cnJlbnRDb21wYW55KCkgd2hpY2ggaW4gdHVybiBjYWxscyBnZXRSZXF1aXJlZExvY2FsQ2FjaGUoKSwgd2hpY2ggY2FuIGNhbGwgc2VuZEVycm9SZXBvcnQgY2F1c2luZyBhIGxvb3AuIFNvIHRyeSB0byBwcmV2ZW50IHRoYXQgYnkgY2hlY2tpbmcgTG9jYWxDYWNoZURhdGFbJ2N1cnJlbnRfY29tcGFueSddIGZpcnN0LlxuXHRcdFx0Y3VycmVudF9jb21wYW55X29iaiA9IExvY2FsQ2FjaGVEYXRhLmdldEN1cnJlbnRDb21wYW55KCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGN1cnJlbnRfY29tcGFueV9vYmogPSBudWxsO1xuXHRcdH1cblxuXHRcdGlmICggbG9naW5fdXNlciAmJiBEZWJ1Zy52YXJEdW1wICkge1xuXHRcdFx0ZXJyb3IgPSAnQ2xpZW50IFZlcnNpb246ICcgKyBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEuYXBwbGljYXRpb25fYnVpbGQgKyAnXFxuXFxuVW5jYXVnaHQgRXJyb3IgRnJvbTogJyArIHNjcmlwdF9uYW1lICsgJ1xcblxcbkVycm9yOiAnICsgZXJyb3Jfc3RyaW5nICsgJyBpbjogJyArIGZyb21fZmlsZSArICcgbGluZTogJyArIGxpbmUgKyAnOicgKyBjb2wgKyAnXFxuXFxuVXNlcjogJyArIGxvZ2luX3VzZXIudXNlcl9uYW1lICsgJ1xcblxcblVSTDogJyArIHdpbmRvdy5sb2NhdGlvbi5ocmVmICsgJ1xcblxcblVzZXItQWdlbnQ6ICcgKyBuYXZpZ2F0b3IudXNlckFnZW50ICsgJyAnICsgJ1xcblxcbklFOiAnICsgd2luZG93LmllICsgJ1xcblxcbkN1cnJlbnQgUGluZzogJyArIEdsb2JhbC5jdXJyZW50X3BpbmcgKyAnXFxuXFxuSWRsZSBUaW1lOiAnICsgR2xvYmFsLmlkbGVfdGltZSArICdcXG5cXG5TZXNzaW9uIElEIEtleTogJyArIExvY2FsQ2FjaGVEYXRhLmdldFNlc3Npb25JRCgpICsgJ1xcblxcbkN1cnJlbnQgVXNlciBPYmplY3Q6IFxcbicgKyBEZWJ1Zy52YXJEdW1wKCBsb2dpbl91c2VyICkgKyAnXFxuXFxuQ3VycmVudCBDb21wYW55IE9iamVjdDogXFxuJyArIERlYnVnLnZhckR1bXAoIGN1cnJlbnRfY29tcGFueV9vYmogKSArICdcXG5cXG5QcmVMb2dpbjogXFxuJyArIERlYnVnLnZhckR1bXAoIHByZV9sb2dpbl9kYXRhICkgKyAnICc7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGVycm9yID0gJ0NsaWVudCBWZXJzaW9uOiAnICsgQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLmFwcGxpY2F0aW9uX2J1aWxkICsgJ1xcblxcblVuY2F1Z2h0IEVycm9yIEZyb206ICcgKyBzY3JpcHRfbmFtZSArICdcXG5cXG5FcnJvcjogJyArIGVycm9yX3N0cmluZyArICcgaW46ICcgKyBmcm9tX2ZpbGUgKyAnIGxpbmU6ICcgKyBsaW5lICsgJzonICsgY29sICsgJ1xcblxcblVzZXI6IE4vQScgKyAnXFxuXFxuVVJMOiAnICsgd2luZG93LmxvY2F0aW9uLmhyZWYgKyAnICcgKyAnXFxuXFxuVXNlci1BZ2VudDogJyArIG5hdmlnYXRvci51c2VyQWdlbnQgKyAnICcgKyAnXFxuXFxuSUU6ICcgKyB3aW5kb3cuaWU7XG5cdFx0fVxuXG5cdFx0Y29uc29sZS5lcnJvciggJ0pBVkFTQ1JJUFQgRVhDRVBUSU9OOlxcbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxcbicgKyBlcnJvciArICdcXG4tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nICk7XG5cdFx0ZGVidWdnZXI7XG5cblx0XHQvL1doZW4gbm90IGluIHByb2R1Y3Rpb24gbW9kZSwgcG9wdXAgYWxlcnQgYm94IGFueXRpbWUgYW4gZXhjZXB0aW9uIGFwcGVhcnMgc28gaXQgY2FuJ3QgYmUgbWlzc2VkLlxuXHRcdGlmICggQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLnByb2R1Y3Rpb24gIT09IHRydWUgJiYgQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLmRlbW9fbW9kZSAhPT0gdHJ1ZSAmJiBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEuc2FuZGJveCAhPT0gdHJ1ZSApIHtcblx0XHRcdGFsZXJ0KCAnSkFWQVNDUklQVCBFWENFUFRJT046XFxuLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXFxuJyArIGVycm9yICsgJ1xcbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScgKTtcblx0XHR9XG5cblx0XHRpZiAoIHR5cGVvZiAoIGd0YWcgKSAhPT0gJ3VuZGVmaW5lZCcgJiYgQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLmFuYWx5dGljc19lbmFibGVkID09PSB0cnVlICkge1xuXHRcdFx0Ly8gU2VuZCBhbiBleGNlcHRpb24gaGl0IHRvIEdvb2dsZSBBbmFseXRpY3MuIE11c3QgYmUgODE5MiBieXRlcyBvciBzbWFsbGVyLlxuXHRcdFx0Ly8gU3RyaXAgdGhlIGRvbWFpbiBwYXJ0IG9mZiB0aGUgVVJMIG9uICdmcm9tX2ZpbGUnIHRvIGJldHRlciBhY2NvdW50IGZvciBzaW1pbGFyIGVycm9ycy5cblx0XHRcdGd0YWcoICdldmVudCcsICdleGNlcHRpb24nLCB7XG5cdFx0XHRcdCdleERlc2NyaXB0aW9uJzogZXJyb3Jfc3RyaW5nICsgJyBGaWxlOiAnICsgKCAoIGZyb21fZmlsZSApID8gZnJvbV9maWxlLnJlcGxhY2UoIEdsb2JhbC5nZXRCYXNlVVJMKCksICcnICkgOiAnTi9BJyApICsgJyBMaW5lOiAnICsgbGluZSArICc6JyArIGNvbCxcblx0XHRcdFx0J2V4RmF0YWwnOiBmYWxzZVxuXHRcdFx0fSApXG5cdFx0fVxuXG5cdFx0Ly9Eb24ndCBzZW5kIGVycm9yIHJlcG9ydCBpZiBleGNlcHRpb24gbm90IGhhcHBlbnMgaW4gb3VyIGNvZGVzLlxuXHRcdC8vZnJvbV9maWxlIHNob3VsZCBhbHdheXMgY29udGFpbnMgdGhlIHJvb3QgdXJsXG5cdFx0Ly9JZiBVUkwgaXMgbm90IHNlbnQgYnkgSUUsIGFzc3VtZSBpdHMgb3VyIG93biBjb2RlIGFuZCByZXBvcnQgdGhlIGVycm9yIHN0aWxsLlxuXHRcdC8vIE1vZGVybiBicm93c2VycyB3b24ndCBzZW5kIGVycm9yIHJlcG9ydHMgZnJvbSBvdGhlciBkb21haW5zIGR1ZSB0byBzZWN1cml0eSBpc3N1ZXMgbm93LCBzbyBJIHRoaW5rIHRoaXMgY2FuIGJlIHJlbW92ZWQuXG5cdFx0Ly8gaWYgKCBmcm9tX2ZpbGUgJiYgZnJvbV9maWxlLmluZGV4T2YoIFNlcnZpY2VDYWxsZXIucm9vdF91cmwgKSA8IDAgKSB7XG5cdFx0Ly8gXHREZWJ1Zy5UZXh0KCAnRXhjZXB0aW9uIGNhdWdodCBmcm9tIHVuYXV0aG9yaXplZCBzb3VyY2UsIG5vdCBzZW5kaW5nIHJlcG9ydC4gU291cmNlOiBcIicgKyBTZXJ2aWNlQ2FsbGVyLnJvb3RfdXJsICsgJ1wiIFNjcmlwdDogJyArIGZyb21fZmlsZSwgJ0dsb2JhbC5qcycsICcnLCAnc2VuZEVycm9yUmVwb3J0JywgMSApO1xuXHRcdC8vIFx0cmV0dXJuO1xuXHRcdC8vIH1cblxuXHRcdGlmICggY3VycmVudF9jb21wYW55X29iaiApIHsgLy9nZXRDdXJyZW50Q29tcGFueSgpIHdoaWNoIGluIHR1cm4gY2FsbHMgZ2V0UmVxdWlyZWRMb2NhbENhY2hlKCksIHdoaWNoIGNhbiBjYWxsIHNlbmRFcnJvUmVwb3J0IGNhdXNpbmcgYSBsb29wLiBTbyB0cnkgdG8gcHJldmVudCB0aGF0IGJ5IGNoZWNraW5nIExvY2FsQ2FjaGVEYXRhWydjdXJyZW50X2NvbXBhbnknXSBmaXJzdC5cblx0XHRcdGVycm9yID0gZXJyb3IgKyAnXFxuXFxuJyArICdQcm9kdWN0IEVkaXRpb246ICcgKyBjdXJyZW50X2NvbXBhbnlfb2JqLnByb2R1Y3RfZWRpdGlvbl9pZDtcblx0XHR9XG5cblx0XHRlcnJvciA9IGVycm9yICsgJ1xcblxcblxcbicgKyAnQ2xpY2tlZCB0YXJnZXQgc3RhY2tzOiAnICsgSlNPTi5zdHJpbmdpZnkoIExvY2FsQ2FjaGVEYXRhLnVpX2NsaWNrX3N0YWNrLCB1bmRlZmluZWQsIDIgKTtcblx0XHRlcnJvciA9IGVycm9yICsgJ1xcblxcblxcbicgKyAnQVBJIHN0YWNrczogJyArIEpTT04uc3RyaW5naWZ5KCBMb2NhbENhY2hlRGF0YS5hcGlfc3RhY2ssIHVuZGVmaW5lZCwgMiApO1xuXG5cdFx0Y2FwdHVyZVNjcmVlblNob3QoIGVycm9yLCBlcnJvcl9vYmogKTtcblx0fVxufTtcblxuR2xvYmFsLmluaXRTdGF0aWNTdHJpbmdzID0gZnVuY3Rpb24oKSB7XG5cdEdsb2JhbC5uZXR3b3JrX2xvc3RfbXNnID0gJC5pMThuLl8oICdUaGUgbmV0d29yayBjb25uZWN0aW9uIHdhcyBsb3N0LiBQbGVhc2UgY2hlY2sgeW91ciBuZXR3b3JrIGNvbm5lY3Rpb24gdGhlbiB0cnkgYWdhaW4uJyApO1xuXG5cdEdsb2JhbC5hbnlfaXRlbSA9ICctLSAnICsgJC5pMThuLl8oICdBbnknICkgKyAnIC0tJztcblxuXHRHbG9iYWwuYWxsX2l0ZW0gPSAnLS0gJyArICQuaTE4bi5fKCAnQWxsJyApICsgJyAtLSc7XG5cblx0R2xvYmFsLnJvb3RfaXRlbSA9ICQuaTE4bi5fKCAnUm9vdCcgKTtcblxuXHRHbG9iYWwubG9hZGluZ19sYWJlbCA9ICcuLi4nO1xuXG5cdEdsb2JhbC5jdXN0b21pemVfaXRlbSA9ICctLSAnICsgJC5pMThuLl8oICdDdXN0b21pemUnICkgKyAnIC0tJztcblxuXHRHbG9iYWwuZGVmYXVsdF9pdGVtID0gJy0tICcgKyAkLmkxOG4uXyggJ0RlZmF1bHQnICkgKyAnIC0tJztcblxuXHRHbG9iYWwuc2VsZWN0ZWRfaXRlbSA9ICctLSAnICsgJC5pMThuLl8oICdTZWxlY3RlZCcgKSArICcgLS0nO1xuXG5cdEdsb2JhbC5vcGVuX2l0ZW0gPSAnLS0gJyArICQuaTE4bi5fKCAnT3BlbicgKSArICcgLS0nO1xuXG5cdEdsb2JhbC5lbXB0eV9pdGVtID0gJy0tICcgKyAkLmkxOG4uXyggJ05vbmUnICkgKyAnIC0tJztcblxuXHRHbG9iYWwudmlld19tb2RlX21lc3NhZ2UgPSAkLmkxOG4uXyggJ1lvdSBhcmUgY3VycmVudGx5IGluIFxcJ1ZpZXdcXCcgbW9kZScgKTtcblxuXHRHbG9iYWwudmlld19tb2RlX2VkaXRfbWVzc2FnZSA9ICQuaTE4bi5fKCAnaW5zdGVhZCBjbGljayB0aGUgXFwnRWRpdFxcJyBpY29uIHRvIG1vZGlmeSBmaWVsZHMnICk7IC8vRG9lcyBub3Qgc3RhcnQgd2l0aCBhIGNhcGl0YWwgYXMgaXQgaXMgYXBwZW5kZWQgdGV4dC5cblxuXHRHbG9iYWwubm9fcmVzdWx0X21lc3NhZ2UgPSAkLmkxOG4uXyggJ05vIFJlc3VsdHMgRm91bmQnICk7XG5cblx0R2xvYmFsLnNhdmVfYW5kX2NvbnRpbnVlX21lc3NhZ2UgPSAkLmkxOG4uXyggJ1BsZWFzZSBzYXZlIHRoaXMgcmVjb3JkIGJlZm9yZSBtb2RpZnlpbmcgYW55IHJlbGF0ZWQgZGF0YScgKTtcblxuXHRHbG9iYWwubm9faGllcmFyY2h5X21lc3NhZ2UgPSAkLmkxOG4uXyggJ05vIEhpZXJhcmNoaWVzIERlZmluZWQnICk7XG5cblx0R2xvYmFsLm1vZGlmeV9hbGVydF9tZXNzYWdlID0gJC5pMThuLl8oICdZb3UgaGF2ZSBtb2RpZmllZCBkYXRhIHdpdGhvdXQgc2F2aW5nLCBhcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gY29udGludWUgYW5kIGxvc2UgeW91ciBjaGFuZ2VzJyApO1xuXG5cdEdsb2JhbC5jb25maXJtX29uX2V4aXRfbWVzc2FnZSA9ICQuaTE4bi5fKCAnQXJlIHlvdSBzdXJlIHlvdSB3YW50IHRvIGNvbnRpbnVlIHdpdGhvdXQgc2F2aW5nPycgKTtcblxuXHRHbG9iYWwuZGVsZXRlX2NvbmZpcm1fbWVzc2FnZSA9ICQuaTE4bi5fKCAnWW91IGFyZSBhYm91dCB0byBkZWxldGUgZGF0YSwgb25jZSBkYXRhIGlzIGRlbGV0ZWQgaXQgY2FuIG5vdCBiZSByZWNvdmVyZWQuPGJyPkFyZSB5b3Ugc3VyZSB5b3Ugd2lzaCB0byBjb250aW51ZT8nICk7XG5cblx0R2xvYmFsLmRlbGV0ZV9kYXNobGV0X2NvbmZpcm1fbWVzc2FnZSA9ICQuaTE4bi5fKCAnWW91IGFyZSBhYm91dCB0byBkZWxldGUgdGhpcyBkYXNobGV0LCBvbmNlIGEgZGFzaGxldCBpcyBkZWxldGVkIGl0IGNhbiBub3QgYmUgcmVjb3ZlcmVkLjxicj5BcmUgeW91IHN1cmUgeW91IHdpc2ggdG8gY29udGludWU/JyApO1xuXG5cdEdsb2JhbC5jb3B5X211bHRpcGxlX2NvbmZpcm1fbWVzc2FnZSA9ICQuaTE4bi5fKCAnWW91IGFyZSBhYm91dCB0byBjb3B5IG11bHRpcGxlIHJlY29yZHMuPGJyPkFyZSB5b3Ugc3VyZSB5b3Ugd2lzaCB0byBjb250aW51ZT8nICk7XG5cblx0R2xvYmFsLmF1dG9fYXJyYW5nZV9kYXNobGV0X2NvbmZpcm1fbWVzc2FnZSA9ICQuaTE4bi5fKCAnWW91IGFyZSBhYm91dCB0byByZXN0b3JlIGFsbCBkYXNobGV0cyB0byB0aGVpciBkZWZhdWx0IHNpemUvbGF5b3V0Ljxicj5BcmUgeW91IHN1cmUgeW91IHdpc2ggdG8gY29udGludWU/JyApO1xuXG5cdEdsb2JhbC5yZXNlX2FsbF9kYXNobGV0X2NvbmZpcm1fbWVzc2FnZSA9ICQuaTE4bi5fKCAnWW91IGFyZSBhYm91dCB0byByZW1vdmUgYWxsIHlvdXIgY3VzdG9taXplZCBkYXNobGV0cyBhbmQgcmVzdG9yZSB0aGVtIGJhY2sgdG8gdGhlIGRlZmF1bHRzLjxicj5BcmUgeW91IHN1cmUgeW91IHdpc2ggdG8gY29udGludWU/JyApO1xufTtcblxuR2xvYmFsLmdldFVwZ3JhZGVNZXNzYWdlID0gZnVuY3Rpb24oKSB7XG5cdHZhciBtZXNzYWdlID0gJC5pMThuLl8oICdUaGlzIGZ1bmN0aW9uYWxpdHkgaXMgb25seSBhdmFpbGFibGUgaW4nICkgK1xuXHRcdCcgJyArIExvY2FsQ2FjaGVEYXRhLmdldExvZ2luRGF0YSgpLmFwcGxpY2F0aW9uX25hbWUgKyAnICc7XG5cblx0aWYgKCBHbG9iYWwuZ2V0UHJvZHVjdEVkaXRpb24oKSA8IDE1ICkge1xuXHRcdC8vRG8gbm90IG1lbnRpb24gcHJvZmVzc2lvbmFsIGlmIHVzZXIgaXMgb24gcHJvZmVzc2lvbmFsIGVkaXRpb24uXG5cdFx0bWVzc2FnZSArPSAkLmkxOG4uXyggJ1Byb2Zlc3Npb25hbCwgQ29ycG9yYXRlLCBvciBFbnRlcnByaXNlIEVkaXRpb25zLicgKTtcblx0fSBlbHNlIGlmICggR2xvYmFsLmdldFByb2R1Y3RFZGl0aW9uKCkgPCAyMCApIHtcblx0XHQvL0RvIG5vdCBtZW50aW9uIGNvcnBvcmF0ZSBpZiB1c2VyIGlzIG9uIGNvcnBvcmF0ZSBlZGl0aW9uLlxuXHRcdG1lc3NhZ2UgKz0gJC5pMThuLl8oICdDb3Jwb3JhdGUgb3IgRW50ZXJwcmlzZSBFZGl0aW9ucy4nICk7XG5cdH0gZWxzZSB7XG5cdFx0bWVzc2FnZSArPSAkLmkxOG4uXyggJ0VudGVycHJpc2UgRWRpdGlvbnMuJyApO1xuXHR9XG5cblx0bWVzc2FnZSArPSAnICcgKyAkLmkxOG4uXyggJ0ZvciBtb3JlIGluZm9ybWF0aW9uIHBsZWFzZSB2aXNpdCcgKSArICcgPGEgaHJlZj1cImh0dHBzOi8vd3d3LnRpbWV0cmV4LmNvbS9yP2lkPTgxMFwiIHRhcmdldD1cIl9ibGFua1wiPnd3dy50aW1ldHJleC5jb208L2E+JztcblxuXHRHbG9iYWwudHJhY2tWaWV3KCAnQ29tbXVuaXR5VXBncmFkZScgKTtcblx0cmV0dXJuIG1lc3NhZ2U7XG59O1xuXG5HbG9iYWwuZG9QaW5nSWZOZWNlc3NhcnkgPSBmdW5jdGlvbigpIHtcblx0aWYgKCBHbG9iYWwuaWRsZV90aW1lIDwgTWF0aC5taW4oIDE1LCBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEuc2Vzc2lvbl9pZGxlX3RpbWVvdXQgLyA2MCApICkgeyAvL2lkbGVfdGltZSBpcyBtaW51dGVzLCBzZXNzaW9uX2lkbGVfdGltZW91dCBpcyBzZWNvbmRzLlxuXHRcdEdsb2JhbC5pZGxlX3RpbWUgPSAwO1xuXHRcdHJldHVybjtcblx0fVxuXG5cdERlYnVnLlRleHQoICdVc2VyIGlzIGFjdGl2ZSBhZ2FpbiBhZnRlciBpZGxlIGZvcjogJyArIEdsb2JhbC5pZGxlX3RpbWUgKyAnLi4uIFJlc2V0dGluZyBpZGxlIHRvIDAnLCAnR2xvYmFsLmpzJywgJycsICdkb1BpbmdJZk5lY2Vzc2FyeScsIDEgKTtcblx0R2xvYmFsLmlkbGVfdGltZSA9IDA7XG5cblx0aWYgKCBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyLnZpZXdJZCA9PT0gJ0xvZ2luVmlldycgKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0dmFyIGFwaSA9IFRUQVBJLkFQSUF1dGhlbnRpY2F0aW9uO1xuXHRhcGkuaXNMb2dnZWRJbiggZmFsc2UsIHtcblx0XHRvblJlc3VsdDogZnVuY3Rpb24oIHJlc3VsdCApIHtcblx0XHRcdHZhciByZXNfZGF0YSA9IHJlc3VsdC5nZXRSZXN1bHQoKTtcblxuXHRcdFx0aWYgKCByZXNfZGF0YSAhPT0gdHJ1ZSApIHtcblx0XHRcdFx0Ly9Eb24ndCBkbyBMb2dvdXQgaGVyZSwgYXMgd2UgbmVlZCB0byBkaXNwbGF5IGEgXCJTZXNzaW9uIEV4cGlyZWRcIiBtZXNzYWdlIHRvIHRoZSB1c2VyLCB3aGljaCBpcyB0cmlnZ2VyZWQgZnJvbSB0aGUgU2VydmljZUNhbGxlci5cblx0XHRcdFx0Ly8gIEluIG9yZGVyIHRvIHRyaWdnZXIgdGhhdCB0aG91Z2gsIHdlIG5lZWQgdG8gbWFrZSBhbiAqQXV0aGVudGljYXRlZCogQVBJIGNhbGwgdG8gQVBJTWlzYy5QaW5nKCksIHJhdGhlciB0aGFuIFVuQXV0aGVudGljYXRlZCBjYWxsIHRvIEFQSUF1dGhlbnRpY2F0aW9uLlBpbmcoKVxuXHRcdFx0XHR2YXIgYXBpID0gVFRBUEkuQVBJTWlzYztcblx0XHRcdFx0YXBpLnBpbmcoIHtcblx0XHRcdFx0XHRvblJlc3VsdDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9ICk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9ICk7XG59O1xuXG5HbG9iYWwuc2V0dXBQaW5nID0gZnVuY3Rpb24oKSB7XG5cdEdsb2JhbC5pZGxlX3RpbWUgPSAwO1xuXHQkKCAnYm9keScgKS5tb3VzZW1vdmUoIEdsb2JhbC5kZWJvdW5jZSggZnVuY3Rpb24gc2V0dXBQaW5nTW91c2VNb3ZlRXZlbnQoIGUgKSB7XG5cdFx0R2xvYmFsLmRvUGluZ0lmTmVjZXNzYXJ5KCk7XG5cdH0sIDEwMDAgKSApO1xuXHQkKCAnYm9keScgKS5rZXlwcmVzcyggR2xvYmFsLmRlYm91bmNlKCBmdW5jdGlvbiBzZXR1cFBpbmdLZXlQcmVzc0V2ZW50KCBlICkge1xuXHRcdEdsb2JhbC5kb1BpbmdJZk5lY2Vzc2FyeSgpO1xuXHR9LCAxMDAwICkgKTtcblxuXHRzZXRJbnRlcnZhbCggdGltZXJJbmNyZW1lbnQsIDYwMDAwICk7IC8vIDEgbWludXRlXG5cdGZ1bmN0aW9uIHRpbWVySW5jcmVtZW50KCkge1xuXHRcdEdsb2JhbC5pZGxlX3RpbWUgPSBHbG9iYWwuaWRsZV90aW1lICsgMTtcblx0XHRpZiAoIEdsb2JhbC5pZGxlX3RpbWUgPj0gTWF0aC5taW4oIDE1LCBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEuc2Vzc2lvbl9pZGxlX3RpbWVvdXQgLyA2MCApICkge1xuXHRcdFx0RGVidWcuVGV4dCggJ1VzZXIgaXMgaWRsZTogJyArIEdsb2JhbC5pZGxlX3RpbWUsICdHbG9iYWwuanMnLCAnJywgJ3NldHVwUGluZycsIDEgKTtcblx0XHR9XG5cdH1cbn07XG5cbkdsb2JhbC5jbGVhckNhY2hlID0gZnVuY3Rpb24oIGZ1bmN0aW9uX25hbWUgKSB7XG5cdGZvciAoIHZhciBrZXkgaW4gTG9jYWxDYWNoZURhdGEucmVzdWx0X2NhY2hlICkge1xuXHRcdGlmICgga2V5LmluZGV4T2YoIGZ1bmN0aW9uX25hbWUgKSA+PSAwICkge1xuXHRcdFx0ZGVsZXRlIExvY2FsQ2FjaGVEYXRhLnJlc3VsdF9jYWNoZVtrZXldO1xuXHRcdH1cblx0fVxufTtcblxuR2xvYmFsLmdldEhvc3QgPSBmdW5jdGlvbiggaG9zdCApIHtcblx0aWYgKCAhaG9zdCApIHtcblx0XHRob3N0ID0gd2luZG93LmxvY2F0aW9uLmhvc3RuYW1lO1xuXHR9XG5cblx0Ly9NYWtlIHN1cmUgaXRzIG5vdCBhbiBJUHY0IGFkZHJlc3MsIGFuZCBpZiBpdHMgYSBkb21haW4gaGFzIG1vcmUgdGhhbiAxIGRvdCBpbiBpdCBiZWZvcmUgcGFyc2luZyBvZmYgdGhlIHN1Yi1kb21haW4gcGFydC5cblx0Ly8gU28gYm90aCBJUHY0IGFkZHJlc3NlcyBhbmQgZG9tYWlucyBsaWtlOiBsb2NhbGhvc3QgKG5vIGRvdCBhdCBhbGwpLCBteWNvbXBhbnkuY29tIHNob3VsZCBub3QgYmUgbW9kaWZpZWQgYXQgYWxsLiBPbmx5OiBzdWIubXljb21wYW55LmNvbSwgc3ViLnN1YjIubXljb21wYW55LmNvbVxuXHR2YXIgaXNfc3ViX2RvbWFpbiA9IGhvc3QubWF0Y2goIC9cXC4vZyApO1xuXHRpZiAoIC9eKChbMC05XXxbMS05XVswLTldfDFbMC05XXsyfXwyWzAtNF1bMC05XXwyNVswLTVdKVxcLil7M30oWzAtOV18WzEtOV1bMC05XXwxWzAtOV17Mn18MlswLTRdWzAtOV18MjVbMC01XSkkLy50ZXN0KCBob3N0ICkgPT0gZmFsc2UgJiYgaXNfc3ViX2RvbWFpbiAmJiBpc19zdWJfZG9tYWluLmxlbmd0aCA+IDEgKSB7XG5cdFx0aG9zdCA9IGhvc3Quc3Vic3RyaW5nKCAoIGhvc3QuaW5kZXhPZiggJy4nICkgKyAxICkgKTtcblx0fVxuXG5cdHJldHVybiBob3N0O1xufTtcblxuR2xvYmFsLnNldFdpZGdldEVuYWJsZWQgPSBmdW5jdGlvbiggd2lkZ2V0LCB2YWwgKSB7XG5cdGlmICggd2lkZ2V0ICkge1xuXHRcdGlmICggIXZhbCApIHtcblx0XHRcdHdpZGdldC5hdHRyKCAnZGlzYWJsZWQnLCAndHJ1ZScgKTtcblx0XHRcdHdpZGdldC5hZGRDbGFzcyggJ2Rpc2FibGUtZmlsdGVyJyApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR3aWRnZXQucmVtb3ZlQXR0ciggJ2Rpc2FibGVkJyApO1xuXHRcdFx0d2lkZ2V0LnJlbW92ZUNsYXNzKCAnZGlzYWJsZS1maWx0ZXInICk7XG5cdFx0fVxuXHR9XG59O1xuXG5HbG9iYWwuY3JlYXRlVmlld1RhYnMgPSBmdW5jdGlvbigpIHtcblx0Ly9KUyBsb2FkIE9wdGltaXplXG5cdGlmICggdHlwZW9mIFdpZGdldE5hbWVzRGljID09ICd1bmRlZmluZWQnICkge1xuXHRcdHJldHVybjtcblx0fVxuXHRpZiAoIExvY2FsQ2FjaGVEYXRhLmxvYWRWaWV3UmVxdWlyZWRKU1JlYWR5ICkge1xuXHRcdGlmICggIUxvY2FsQ2FjaGVEYXRhLnZpZXdfbWluX3RhYl9iYXIgKSB7XG5cdFx0XHR2YXIgdmlld19taW5fdGFiX2JhciA9IEdsb2JhbC5sb2FkV2lkZ2V0QnlOYW1lKCBXaWRnZXROYW1lc0RpYy5WSUVXX01JTl9UQUJfQkFSICk7XG5cdFx0XHR2aWV3X21pbl90YWJfYmFyID0gJCggdmlld19taW5fdGFiX2JhciApLlZpZXdNaW5UYWJCYXIoKTtcblx0XHRcdCQoICcubGF5b3V0LW1lbnUtY29udGFpbmVyJyApLmFwcGVuZCggdmlld19taW5fdGFiX2JhciApO1xuXG5cdFx0XHRMb2NhbENhY2hlRGF0YS52aWV3X21pbl90YWJfYmFyID0gdmlld19taW5fdGFiX2Jhcjtcblx0XHR9XG5cblx0XHRMb2NhbENhY2hlRGF0YS52aWV3X21pbl90YWJfYmFyLmJ1aWxkVGFicyggTG9jYWxDYWNoZURhdGEudmlld19taW5fbWFwICk7XG5cdH1cbn07XG5cbkdsb2JhbC5hZGRWaWV3VGFiID0gZnVuY3Rpb24oIHZpZXdfaWQsIHZpZXdfbmFtZSwgdXJsICkge1xuXG5cdExvY2FsQ2FjaGVEYXRhLnZpZXdfbWluX21hcFt2aWV3X2lkXSA9IHZpZXdfbmFtZTtcblxuXHRMb2NhbENhY2hlRGF0YS52aWV3X21pbl9tYXBbdmlld19pZCArICdfdXJsJ10gPSB1cmw7XG5cblx0R2xvYmFsLmNyZWF0ZVZpZXdUYWJzKCk7XG59O1xuXG5HbG9iYWwucmVtb3ZlVmlld1RhYiA9IGZ1bmN0aW9uKCB2aWV3X2lkICkge1xuXG5cdGRlbGV0ZSBMb2NhbENhY2hlRGF0YS52aWV3X21pbl9tYXBbdmlld19pZF07XG5cdCQoICcjbWluX3RhYl8nICsgdmlld19pZCApLnJlbW92ZSgpO1xufTtcblxuR2xvYmFsLmNsZWFuVmlld1RhYiA9IGZ1bmN0aW9uKCkge1xuXG5cdExvY2FsQ2FjaGVEYXRhLnZpZXdfbWluX21hcCA9IHt9O1xuXHRHbG9iYWwuY3JlYXRlVmlld1RhYnMoKTtcbn07XG5cbkdsb2JhbC51cENhc2VGaXJzdExldHRlciA9IGZ1bmN0aW9uKCBzdHIgKSB7XG5cdGlmICggdHlwZW9mIHN0ciA9PSAnc3RyaW5nJyApIHsgLy9pbiBjYXNlIG51bGwgb3IgZmFsc2UgaXMgcGFzc2VkLCB3ZSBzaG91bGQgY2hlY2sgdGhlIHR5cGUuXG5cdFx0c3RyID0gc3RyLmNoYXJBdCggMCApLnRvVXBwZXJDYXNlKCkgKyBzdHIuc2xpY2UoIDEgKTtcblx0fVxuXHRyZXR1cm4gc3RyO1xufTtcblxuR2xvYmFsLmNhbGN1bGF0ZVRleHRXaWR0aCA9IGZ1bmN0aW9uKCB0ZXh0LCBvcHRpb25zICkge1xuXHRpZiAoIHR5cGVvZiBvcHRpb25zID09PSBcInVuZGVmaW5lZFwiICkge1xuXHRcdG9wdGlvbnMgPSB7fTtcblx0fVxuXG5cdGlmICggIW9wdGlvbnMuZm9udFNpemUgKSB7XG5cdFx0b3B0aW9ucy5mb250U2l6ZSA9ICcxMnB4Jztcblx0fVxuXG5cdHZhciBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggJ2RpdicgKTtcblx0dmFyIHRleHROb2RlID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoIHRleHQgKTtcblxuXHRlbGVtZW50LmFwcGVuZENoaWxkKCB0ZXh0Tm9kZSApO1xuXG5cdGlmICggb3B0aW9ucy5mb250ICkge1xuXHRcdGVsZW1lbnQuc3R5bGUuZm9udEZhbWlseSA9IG9wdGlvbnMuZm9udDtcblx0fVxuXG5cdGlmICggb3B0aW9ucy5mb250V2VpZ2h0ICkge1xuXHRcdGVsZW1lbnQuc3R5bGUuZm9udFdlaWdodCA9IG9wdGlvbnMuZm9udFdlaWdodDtcblx0fVxuXG5cdGlmICggb3B0aW9ucy53b3JkQnJlYWsgKSB7XG5cdFx0ZWxlbWVudC5zdHlsZS53b3JkQnJlYWsgPSBvcHRpb25zLndvcmRCcmVhaztcblx0fVxuXG5cdGVsZW1lbnQuc3R5bGUuZm9udFNpemUgPSBvcHRpb25zLmZvbnRTaXplO1xuXHRlbGVtZW50LnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcblx0ZWxlbWVudC5zdHlsZS52aXNpYmlsaXR5ID0gJ2hpZGRlbic7XG5cdGVsZW1lbnQuc3R5bGUubGVmdCA9ICctOTk5cHgnO1xuXHRlbGVtZW50LnN0eWxlLnRvcCA9ICctOTk5cHgnO1xuXHRlbGVtZW50LnN0eWxlLmhlaWdodCA9ICdhdXRvJztcblxuXHRkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKCBlbGVtZW50ICk7XG5cdHZhciBjb250ZW50X3dpZHRoID0gZWxlbWVudC5vZmZzZXRXaWR0aDtcblx0ZWxlbWVudC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKCBlbGVtZW50ICk7XG5cblx0aWYgKCBvcHRpb25zLm1pbl93aWR0aCAmJiBvcHRpb25zLm1pbl93aWR0aCA+IDAgJiYgY29udGVudF93aWR0aCA8IG9wdGlvbnMubWluX3dpZHRoICkge1xuXHRcdGNvbnRlbnRfd2lkdGggPSBvcHRpb25zLm1pbl93aWR0aDtcblx0fVxuXHRpZiAoIG9wdGlvbnMucGFkZGluZyAmJiBvcHRpb25zLnBhZGRpbmcgPiAwICkge1xuXHRcdGNvbnRlbnRfd2lkdGggPSBjb250ZW50X3dpZHRoICsgb3B0aW9ucy5wYWRkaW5nO1xuXHR9XG5cdGlmICggb3B0aW9ucy5tYXhfd2lkdGggPiAwICYmIGNvbnRlbnRfd2lkdGggPiBvcHRpb25zLm1heF93aWR0aCApIHtcblx0XHRjb250ZW50X3dpZHRoID0gb3B0aW9ucy5tYXhfd2lkdGg7XG5cdH1cblxuXHRyZXR1cm4gY29udGVudF93aWR0aDtcbn07XG5cbkdsb2JhbC5zdHJUb0RhdGUgPSBmdW5jdGlvbiggZGF0ZV9zdHJpbmcsIGZvcm1hdCApIHtcblxuXHQvL2JldHRlciB0byB1c2UgRGF0ZS5wYXJzZSwgbGV0J3Mgc2VlXG5cdGlmICggIUdsb2JhbC5pc1NldCggZm9ybWF0ICkgJiYgTG9jYWxDYWNoZURhdGEuZ2V0TG9naW5Vc2VyUHJlZmVyZW5jZSgpICkge1xuXHRcdGZvcm1hdCA9IExvY2FsQ2FjaGVEYXRhLmdldExvZ2luVXNlclByZWZlcmVuY2UoKS5kYXRlX2Zvcm1hdDtcblx0fVxuXG5cdGlmICggIWZvcm1hdCApIHtcblx0XHRmb3JtYXQgPSAnREQtTU1NLVlZJztcblx0fVxuXG5cdHZhciBkYXRlID0gbW9tZW50KCBkYXRlX3N0cmluZywgZm9ybWF0ICk7XG5cdGRhdGUgPSBkYXRlLnRvRGF0ZSgpO1xuXG5cdC8vVGhlIG1vbWVudCB3aWxsIHBhc3MgZXZlcnl0aGluZyBhcyBhIGRhdGUuIEp1ZGdlIGlmIHRoZSB5ZWFyIGxlc3MgMTAwMCB0aGFuIDE5MDAgb3IgYmV5b25kIDEwMDAgb2YgMTkwMCxcblx0Ly93ZSB0aGluayBpdCdzIGEgaW52YWxpZCB5ZWFyXG5cdGlmICggZGF0ZS5nZXRZZWFyKCkgPCAtMTAwMCB8fCBkYXRlLmdldFllYXIoKSA+IDEwMDAgKSB7XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblxuXHRyZXR1cm4gZGF0ZTtcbn07XG5cbkdsb2JhbC5zdHJUb0RhdGVUaW1lID0gZnVuY3Rpb24oIGRhdGVfc3RyaW5nICkge1xuXHQvL0Vycm9yOiBUeXBlRXJyb3I6IEdsb2JhbC5zdHJUb0RhdGVUaW1lKC4uLikgaXMgbnVsbCBpbiAvaW50ZXJmYWNlL2h0bWw1L2ZyYW1ld29yay9qcXVlcnkubWluLmpzP3Y9OC4wLjAtMjAxNDExMTctMTUzNTE1IGxpbmUgNDg2MlxuXHRpZiAoICFkYXRlX3N0cmluZyB8fCAhTG9jYWxDYWNoZURhdGEuZ2V0TG9naW5Vc2VyUHJlZmVyZW5jZSgpICkge1xuXHRcdHJldHVybiBudWxsO1xuXHR9XG5cblx0dmFyIGRhdGVfZm9ybWF0ID0gTG9jYWxDYWNoZURhdGEuZ2V0TG9naW5Vc2VyUHJlZmVyZW5jZSgpLmRhdGVfZm9ybWF0O1xuXHR2YXIgdGltZV9mb3JtYXQgPSBMb2NhbENhY2hlRGF0YS5nZXRMb2dpblVzZXJQcmVmZXJlbmNlKCkuanNfdGltZV9mb3JtYXRbTG9jYWxDYWNoZURhdGEuZ2V0TG9naW5Vc2VyUHJlZmVyZW5jZSgpLnRpbWVfZm9ybWF0XTtcblx0dmFyIGRhdGUgPSBtb21lbnQoIGRhdGVfc3RyaW5nLCBkYXRlX2Zvcm1hdCArICcgJyArIHRpbWVfZm9ybWF0ICkudG9EYXRlKCk7XG5cblx0cmV0dXJuIGRhdGU7XG5cdC8vcmV0dXJuIERhdGUucGFyc2UoIGRhdGVfc3RyaW5nICk7XG59O1xuXG4vL0NvbnZlcnQgYWxsIGtpbmRzIG9mIGRhdGUgdGltZSB0byBtbS9kZC95eXl5IHNvIERhdGUucGFyc2UgY2FuIHBhcnNlIGl0IGNvcnJlY3Rcbkdsb2JhbC5nZXRTdGFuZGFyZERhdGVUaW1lU3RyID0gZnVuY3Rpb24oIGRhdGVfc3RyLCB0aW1lX3N0ciApIHtcblx0Ly92YXIgcmVzdWx0ID0gR2xvYmFsLnN0clRvRGF0ZSggZGF0ZV9zdHIgKS5mb3JtYXQoICdNTS9ERC9ZWVlZJyApICsgJyAnICsgdGltZV9zdHI7XG5cblx0cmV0dXJuIGRhdGVfc3RyO1xufTtcblxuR2xvYmFsLmNvbnZlcnRUb2pRdWVyeUZvcm1hdCA9IGZ1bmN0aW9uKCBkYXRlX2Zvcm1hdCApIHtcblx0Ly9Gb3IgbW9tZW50IGRhdGUgcGFyc2VyXG5cdHZhciBqcXVlcnlfZGF0ZV9mb3JtYXQgPSB7XG5cdFx0J2QtTS15JzogJ2RkLU0teScsXG5cdFx0J2QtTS1ZJzogJ2RkLU0teXknLFxuXHRcdCdkTVknOiAnZGRNeXknLFxuXHRcdCdkL20vWSc6ICdkZC9tbS95eScsXG5cdFx0J2QvbS95JzogJ2RkL21tL3knLFxuXHRcdCdkLW0teSc6ICdkZC1tbS15Jyxcblx0XHQnZC1tLVknOiAnZGQtbW0teXknLFxuXHRcdCdtL2QveSc6ICdtbS9kZC95Jyxcblx0XHQnbS9kL1knOiAnbW0vZGQveXknLFxuXHRcdCdtLWQteSc6ICdtbS1kZC15Jyxcblx0XHQnbS1kLVknOiAnbW0tZGQteXknLFxuXHRcdCdZLW0tZCc6ICd5eS1tbS1kZCcsXG5cdFx0J00tZC15JzogJ00tZGQteScsXG5cdFx0J00tZC1ZJzogJ00tZGQteXknLFxuXHRcdCdsLCBGIGQgWSc6ICdERCwgTU0gZGQgeXknLFxuXHRcdCdELCBGIGQgWSc6ICdELCBNTSBkZCB5eScsXG5cdFx0J0QsIE0gZCBZJzogJ0QsIE0gZGQgeXknLFxuXHRcdCdELCBkLU0tWSc6ICdELCBkZC1NLXl5Jyxcblx0XHQnRCwgZE1ZJzogJ0QsIGRkTXl5JyxcblxuXHRcdCdnOmkgQSc6ICdoOm1tIFRUJyxcblx0XHQnZzppIGEnOiAnaDptbSB0dCcsXG5cdFx0J0c6aSc6ICdIOm1tJyxcblx0XHQnZzppIEEgVCc6ICdoOm1tIFRUJyxcblx0XHQnRzppIFQnOiAnSDptbScsXG5cblx0XHQnZzppOnMgQSc6ICdoOm1tOnNzIFRUJyxcblx0XHQnZzppOnMgYSc6ICdoOm1tOnNzIHR0Jyxcblx0XHQnRzppOnMnOiAnSDptbTpzcycsXG5cdFx0J2c6aTpzIEEgVCc6ICdoOm1tOnNzIFRUJyxcblx0XHQnRzppOnMgVCc6ICdIOm1tOnNzJ1xuXHR9O1xuXG5cdHJldHVybiBqcXVlcnlfZGF0ZV9mb3JtYXRbZGF0ZV9mb3JtYXRdO1xufTtcblxuR2xvYmFsLnVwZGF0ZVVzZXJQcmVmZXJlbmNlID0gZnVuY3Rpb24oIGNhbGxCYWNrLCBtZXNzYWdlICkge1xuXHR2YXIgdXNlcl9wcmVmZXJlbmNlX2FwaSA9IFRUQVBJLkFQSVVzZXJQcmVmZXJlbmNlO1xuXHR2YXIgY3VycmVudF91c2VyX2FvdSA9IFRUQVBJLkFQSUF1dGhlbnRpY2F0aW9uO1xuXG5cdGlmICggbWVzc2FnZSApIHtcblx0XHRQcm9ncmVzc0Jhci5jaGFuZ2VQcm9ncmVzc0Jhck1lc3NhZ2UoIG1lc3NhZ2UgKTtcblx0fVxuXG5cdGN1cnJlbnRfdXNlcl9hb3UuZ2V0Q3VycmVudFVzZXJQcmVmZXJlbmNlKCB7XG5cdFx0b25SZXN1bHQ6IGZ1bmN0aW9uKCByZXN1bHQgKSB7XG5cdFx0XHR2YXIgcmVzdWx0X2RhdGEgPSByZXN1bHQuZ2V0UmVzdWx0KCk7XG5cdFx0XHRMb2NhbENhY2hlRGF0YS5sb2dpblVzZXJQcmVmZXJlbmNlID0gcmVzdWx0X2RhdGE7XG5cblx0XHRcdHVzZXJfcHJlZmVyZW5jZV9hcGkuZ2V0T3B0aW9ucyggJ21vbWVudF9kYXRlX2Zvcm1hdCcsIHtcblx0XHRcdFx0b25SZXN1bHQ6IGZ1bmN0aW9uKCBqc0RhdGVGb3JtYXRSZXMgKSB7XG5cdFx0XHRcdFx0dmFyIGpzRGF0ZUZvcm1hdFJlc3VsdERhdGEgPSBqc0RhdGVGb3JtYXRSZXMuZ2V0UmVzdWx0KCk7XG5cblx0XHRcdFx0XHQvL0ZvciBtb21lbnQgZGF0ZSBwYXJzZXJcblx0XHRcdFx0XHRMb2NhbENhY2hlRGF0YS5sb2dpblVzZXJQcmVmZXJlbmNlLmpzX2RhdGVfZm9ybWF0ID0ganNEYXRlRm9ybWF0UmVzdWx0RGF0YTtcblxuXHRcdFx0XHRcdHZhciBkYXRlX2Zvcm1hdCA9IExvY2FsQ2FjaGVEYXRhLmxvZ2luVXNlclByZWZlcmVuY2UuZGF0ZV9mb3JtYXQ7XG5cdFx0XHRcdFx0aWYgKCAhZGF0ZV9mb3JtYXQgKSB7XG5cdFx0XHRcdFx0XHRkYXRlX2Zvcm1hdCA9ICdERC1NTU0tWVknO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdExvY2FsQ2FjaGVEYXRhLmxvZ2luVXNlclByZWZlcmVuY2UuZGF0ZV9mb3JtYXQgPSBMb2NhbENhY2hlRGF0YS5sb2dpblVzZXJQcmVmZXJlbmNlLmpzX2RhdGVfZm9ybWF0W2RhdGVfZm9ybWF0XTtcblxuXHRcdFx0XHRcdExvY2FsQ2FjaGVEYXRhLmxvZ2luVXNlclByZWZlcmVuY2UuZGF0ZV9mb3JtYXRfMSA9IEdsb2JhbC5jb252ZXJ0VG9qUXVlcnlGb3JtYXQoIGRhdGVfZm9ybWF0ICk7IC8vVERhdGVQaWNrZXIsIFRSYW5nZVBpY2tlclxuXHRcdFx0XHRcdExvY2FsQ2FjaGVEYXRhLmxvZ2luVXNlclByZWZlcmVuY2UudGltZV9mb3JtYXRfMSA9IEdsb2JhbC5jb252ZXJ0VG9qUXVlcnlGb3JtYXQoIExvY2FsQ2FjaGVEYXRhLmxvZ2luVXNlclByZWZlcmVuY2UudGltZV9mb3JtYXQgKTsgLy9UVGltZVBpY2tlclxuXG5cdFx0XHRcdFx0dXNlcl9wcmVmZXJlbmNlX2FwaS5nZXRPcHRpb25zKCAnbW9tZW50X3RpbWVfZm9ybWF0Jywge1xuXHRcdFx0XHRcdFx0b25SZXN1bHQ6IGZ1bmN0aW9uKCBqc1RpbWVGb3JtYXRSZXMgKSB7XG5cdFx0XHRcdFx0XHRcdHZhciBqc1RpbWVGb3JtYXRSZXN1bHREYXRhID0ganNUaW1lRm9ybWF0UmVzLmdldFJlc3VsdCgpO1xuXG5cdFx0XHRcdFx0XHRcdExvY2FsQ2FjaGVEYXRhLmxvZ2luVXNlclByZWZlcmVuY2UuanNfdGltZV9mb3JtYXQgPSBqc1RpbWVGb3JtYXRSZXN1bHREYXRhO1xuXG5cdFx0XHRcdFx0XHRcdExvY2FsQ2FjaGVEYXRhLnNldExvZ2luVXNlclByZWZlcmVuY2UoIExvY2FsQ2FjaGVEYXRhLmxvZ2luVXNlclByZWZlcmVuY2UgKTtcblxuXHRcdFx0XHRcdFx0XHRpZiAoIGNhbGxCYWNrICkge1xuXHRcdFx0XHRcdFx0XHRcdGNhbGxCYWNrKCk7XG5cdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0gKTtcblxuXHRcdFx0XHR9XG5cdFx0XHR9ICk7XG5cdFx0fVxuXHR9ICk7XG59O1xuXG4vKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXG5HbG9iYWwucm91bmRUaW1lID0gZnVuY3Rpb24oIGVwb2NoLCByb3VuZF92YWx1ZSwgcm91bmRfdHlwZSApIHtcblx0dmFyIHJvdW5kX3R5cGUgPSByb3VuZF90eXBlIHx8IDIwO1xuXG5cdHN3aXRjaCAoIHJvdW5kX3R5cGUgKSB7XG5cdFx0Y2FzZSAxMDogLy9Eb3duXG5cdFx0XHRlcG9jaCA9ICggZXBvY2ggLSAoIGVwb2NoICUgcm91bmRfdmFsdWUgKSApO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAyMDogLy9BdmVyYWdlXG5cdFx0Y2FzZSAyNTogLy9BdmVyYWdlIChyb3VuZCBzcGxpdCBzZWNvbmRzIHVwKVxuXHRcdGNhc2UgMjc6IC8vQXZlcmFnZSAocm91bmQgc3BsaXQgc2Vjb25kcyBkb3duKVxuXHRcdFx0dmFyIHRtcF9yb3VuZF92YWx1ZTtcblx0XHRcdGlmICggcm91bmRfdHlwZSA9PSAyMCB8fCByb3VuZF92YWx1ZSA8PSA2MCApIHtcblx0XHRcdFx0dG1wX3JvdW5kX3ZhbHVlID0gKCByb3VuZF92YWx1ZSAvIDIgKTtcblx0XHRcdH0gZWxzZSBpZiAoIHJvdW5kX3R5cGUgPT0gMjUgKSB7IC8vQXZlcmFnZSAoUGFydGlhbCBNaW4uIERvd24pXG5cdFx0XHRcdHRtcF9yb3VuZF92YWx1ZSA9IEdsb2JhbC5yb3VuZFRpbWUoICggcm91bmRfdmFsdWUgLyAyICksIDYwLCAxMCApOyAvL1RoaXMgaXMgb3Bwb3NpdGUgcm91bmRpbmdcblx0XHRcdH0gZWxzZSBpZiAoIHJvdW5kX3R5cGUgPT0gMjcgKSB7IC8vQXZlcmFnZSAoUGFydGlhbCBNaW4uIFVwKVxuXHRcdFx0XHR0bXBfcm91bmRfdmFsdWUgPSBHbG9iYWwucm91bmRUaW1lKCAoIHJvdW5kX3ZhbHVlIC8gMiApLCA2MCwgMzAgKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBlcG9jaCA+IDAgKSB7XG5cdFx0XHRcdC8vV2hlbiBkb2luZyBhIDE1bWluIGF2ZXJhZ2Ugcm91bmRpbmcsIFVTIGxhdyBzdGF0ZXMgN21pbnMgYW5kIDU5IHNlY29uZHMgY2FuIGJlIHJvdW5kZWQgZG93biBpbiBmYXZvciBvZiB0aGUgZW1wbG95ZXIsIGFuZCA4bWlucyBhbmQgMCBzZWNvbmRzIG11c3QgYmUgcm91bmRlZCB1cC5cblx0XHRcdFx0Ly9TbyBpZiB0aGUgcm91bmQgaW50ZXJ2YWwgaXMgbm90IGFuIGV2ZW4gbnVtYmVyLCByb3VuZCBpdCB1cCB0byB0aGUgbmVhcmVzdCBtaW51dGUgYmVmb3JlIGRvaW5nIHRoZSBjYWxjdWxhdGlvbnMgdG8gYXZvaWQgaXNzdWVzIHdpdGggc2Vjb25kcy5cblx0XHRcdFx0ZXBvY2ggPSAoIE1hdGguZmxvb3IoICggZXBvY2ggKyB0bXBfcm91bmRfdmFsdWUgKSAvIHJvdW5kX3ZhbHVlICkgKiByb3VuZF92YWx1ZSApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZXBvY2ggPSAoIE1hdGguY2VpbCggKCBlcG9jaCAtIHRtcF9yb3VuZF92YWx1ZSApIC8gcm91bmRfdmFsdWUgKSAqIHJvdW5kX3ZhbHVlICk7XG5cdFx0XHR9XG5cblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgMzA6IC8vVXBcblx0XHRcdGVwb2NoID0gKCAoICggZXBvY2ggKyAoIHJvdW5kX3ZhbHVlIC0gMSApICkgLyByb3VuZF92YWx1ZSApICogcm91bmRfdmFsdWUgKTtcblx0XHRcdGJyZWFrO1xuXHR9XG5cblx0cmV0dXJuIGVwb2NoO1xufSxcblxuXHRHbG9iYWwucGFyc2VUaW1lVW5pdCA9IGZ1bmN0aW9uKCB0aW1lX3VuaXQsIGZvcm1hdCApIHtcblx0XHR2YXIgZm9ybWF0LCB0aW1lX3VuaXQsIHRpbWVfdW5pdHMsIHNlY29uZHMsIG5lZ2F0aXZlX251bWJlcjtcblxuXHRcdHZhciB0aW1lX3VuaXQgPSB0aW1lX3VuaXQudG9TdHJpbmcoKTsgLy9OZWVkcyB0byBiZSBhIHN0cmluZyBzbyB3ZSBjYW4gdXNlIC5jaGFyQXQgYW5kIC5yZXBsYWNlIGJlbG93LlxuXG5cdFx0aWYgKCAhZm9ybWF0ICkge1xuXHRcdFx0Zm9ybWF0ID0gTG9jYWxDYWNoZURhdGEuZ2V0TG9naW5Vc2VyUHJlZmVyZW5jZSgpLnRpbWVfdW5pdF9mb3JtYXQ7XG5cdFx0fVxuXHRcdGZvcm1hdCA9IHBhcnNlSW50KCBmb3JtYXQgKTtcblxuXHRcdHZhciBlbmFibGVfcm91bmRpbmcgPSB0cnVlO1xuXHRcdGlmICggdGltZV91bml0LmNoYXJBdCggMCApID09ICdcIicgKSB7XG5cdFx0XHRlbmFibGVfcm91bmRpbmcgPSBmYWxzZTtcblx0XHR9XG5cblx0XHR2YXIgdGhvdXNhbmRzX3NlcGFyYXRvciA9ICcsJztcblx0XHR2YXIgZGVjaW1hbF9zZXBhcmF0b3IgPSAnLic7XG5cblx0XHR0aW1lX3VuaXQgPSB0aW1lX3VuaXQucmVwbGFjZSggbmV3IFJlZ0V4cCggdGhvdXNhbmRzX3NlcGFyYXRvciwgJ2cnICksICcnICkucmVwbGFjZSggbmV3IFJlZ0V4cCggJyAnLCAnZycgKSwgJycgKS5yZXBsYWNlKCBuZXcgUmVnRXhwKCAnXCInLCAnZycgKSwgJycgKTsgLy9OZWVkIHRvIHVzZSByZWdleCB0byByZXBsYWNlIGFsbCBpbnN0YW5jZXMuXG5cblx0XHRzd2l0Y2ggKCBmb3JtYXQgKSB7XG5cdFx0XHRjYXNlIDEwOiAvL2hoOm1tXG5cdFx0XHRjYXNlIDEyOiAvL2hoOm1tOnNzXG5cdFx0XHRcdGlmICggdGltZV91bml0LmluZGV4T2YoIGRlY2ltYWxfc2VwYXJhdG9yICkgIT09IC0xICYmIHRpbWVfdW5pdC5pbmRleE9mKCAnOicgKSA9PT0gLTEgKSB7IC8vSHlicmlkIG1vZGUsIHRoZXkgcGFzc2VkIGEgZGVjaW1hbCBmb3JtYXQgSEg6TU0sIHRyeSB0byBoYW5kbGUgcHJvcGVybHkuXG5cdFx0XHRcdFx0dGltZV91bml0ID0gR2xvYmFsLmdldFRpbWVVbml0KCBHbG9iYWwucGFyc2VUaW1lVW5pdCggdGltZV91bml0LCAyMCApLCBmb3JtYXQgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHRpbWVfdW5pdHMgPSB0aW1lX3VuaXQuc3BsaXQoICc6JyApO1xuXG5cdFx0XHRcdGlmICggIXRpbWVfdW5pdHNbMF0gKSB7XG5cdFx0XHRcdFx0dGltZV91bml0c1swXSA9IDA7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoICF0aW1lX3VuaXRzWzFdICkge1xuXHRcdFx0XHRcdHRpbWVfdW5pdHNbMV0gPSAwO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKCAhdGltZV91bml0c1syXSApIHtcblx0XHRcdFx0XHR0aW1lX3VuaXRzWzJdID0gMDtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRpZiAoIHRpbWVfdW5pdHNbMl0gIT0gMCApIHtcblx0XHRcdFx0XHRcdGVuYWJsZV9yb3VuZGluZyA9IGZhbHNlOyAvL1NpbmNlIHNlY29uZHMgd2VyZSBzcGVjaWZpZWQsIGRvbid0IHJvdW5kIHRvIG5lYXJlc3QgbWludXRlLlxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdG5lZ2F0aXZlX251bWJlciA9IGZhbHNlO1xuXHRcdFx0XHRpZiAoIHRpbWVfdW5pdHNbMF0udG9TdHJpbmcoKS5jaGFyQXQoIDAgKSA9PSAnLScgfHwgdGltZV91bml0c1swXSA8IDAgfHwgdGltZV91bml0c1sxXSA8IDAgfHwgdGltZV91bml0c1syXSA8IDAgKSB7XG5cdFx0XHRcdFx0bmVnYXRpdmVfbnVtYmVyID0gdHJ1ZTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHNlY29uZHMgPSAoICggTWF0aC5hYnMoIE1hdGguZmxvb3IoIHRpbWVfdW5pdHNbMF0gKSApICogMzYwMCApICsgKCBNYXRoLmFicyggTWF0aC5mbG9vciggdGltZV91bml0c1sxXSApICkgKiA2MCApICsgTWF0aC5hYnMoIE1hdGguZmxvb3IoIHRpbWVfdW5pdHNbMl0gKSApICk7XG5cblx0XHRcdFx0aWYgKCBuZWdhdGl2ZV9udW1iZXIgPT0gdHJ1ZSApIHtcblx0XHRcdFx0XHRzZWNvbmRzID0gKCBzZWNvbmRzICogLTEgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAyMDogLy9ob3Vyc1xuXHRcdFx0Y2FzZSAyMjogLy9ob3VycyBbUHJlY2lzZV1cblx0XHRcdGNhc2UgMjM6IC8vaG91cnMgW1N1cGVyIFByZWNpc2VdXG5cdFx0XHRcdGlmICggdGltZV91bml0LmluZGV4T2YoICc6JyApICE9PSAtMSApIHsgLy9IeWJyaWQgbW9kZSwgdGhleSBwYXNzZWQgYSBkZWNpbWFsIGZvcm1hdCBISDpNTSwgdHJ5IHRvIGhhbmRsZSBwcm9wZXJseS5cblx0XHRcdFx0XHR0aW1lX3VuaXQgPSBHbG9iYWwuZ2V0VGltZVVuaXQoIEdsb2JhbC5wYXJzZVRpbWVVbml0KCB0aW1lX3VuaXQsIDEwICksIGZvcm1hdCApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0c2Vjb25kcyA9ICggdGltZV91bml0ICogMzYwMCApO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgMzA6IC8vbWludXRlc1xuXHRcdFx0XHRzZWNvbmRzID0gKCB0aW1lX3VuaXQgKiA2MCApO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgNDA6IC8vc2Vjb25kc1xuXHRcdFx0XHRzZWNvbmRzID0gdGltZV91bml0O1xuXHRcdFx0XHRpZiAoIGVuYWJsZV9yb3VuZGluZyA9PSB0cnVlICkge1xuXHRcdFx0XHRcdHNlY29uZHMgPSByb3VuZCggc2Vjb25kcyApOyAvL1JvdW5kIHRvIG5lYXJlc3Qgd2hvbGUgbnVtYmVyIGJ5IGRlZmF1bHQuXG5cdFx0XHRcdH1cblx0XHRcdFx0ZW5hYmxlX3JvdW5kaW5nID0gZmFsc2U7IC8vU2luY2Ugc2Vjb25kcyB3ZXJlIHNwZWNpZmllZCwgZG9uJ3Qgcm91bmQgdG8gbmVhcmVzdCBtaW51dGUuIEFsc28gZm9yIGFjY3J1YWxzIG1pZ2h0IG5lZWQgdG8gYWxsb3cgZGVjaW1hbCBzZWNvbmRzLlxuXHRcdFx0XHRicmVhaztcblx0XHR9XG5cblx0XHRpZiAoIGVuYWJsZV9yb3VuZGluZyA9PSB0cnVlICkge1xuXHRcdFx0c2Vjb25kcyA9IEdsb2JhbC5yb3VuZFRpbWUoIHNlY29uZHMsIDYwICk7XG5cdFx0fVxuXG5cdFx0Ly9EZWJ1Zy5UZXh0KCAnVGltZSBVbml0OiAnKyB0aW1lX3VuaXQgKycgUmV0dmFsOiAnKyBzZWNvbmRzLCAnR2xvYmFsLmpzJywgJycsICdwYXJzZVRpbWVVbml0JywgMTAgKTtcblx0XHRyZXR1cm4gc2Vjb25kcztcblx0fSxcblxuXHRHbG9iYWwuY29udmVydFNlY29uZHNUb0hNUyA9IGZ1bmN0aW9uKCBzZWNvbmRzLCBpbmNsdWRlX3NlY29uZHMsIGV4Y2x1ZGVfaG91cnMgKSB7XG5cdFx0dmFyIG5lZ2F0aXZlX251bWJlciA9IGZhbHNlO1xuXG5cdFx0aWYgKCBzZWNvbmRzIDwgMCApIHtcblx0XHRcdG5lZ2F0aXZlX251bWJlciA9IHRydWU7XG5cdFx0fVxuXG5cdFx0c2Vjb25kcyA9IE1hdGgucm91bmQoIE1hdGguYWJzKCBzZWNvbmRzICkgKTtcblxuXHRcdHZhciB0bXBfaG91cnMgPSBNYXRoLmZsb29yKCBzZWNvbmRzIC8gMzYwMCApO1xuXHRcdHZhciB0bXBfbWludXRlcyA9IE1hdGguZmxvb3IoICggc2Vjb25kcyAvIDYwICkgJSA2MCApO1xuXHRcdHZhciB0bXBfc2Vjb25kcyA9IE1hdGguZmxvb3IoIHNlY29uZHMgJSA2MCApO1xuXG5cdFx0aWYgKCBleGNsdWRlX2hvdXJzID09IHRydWUgKSB7IC8vQ29udmVydCBob3VycyB0byBtaW51dGVzIGJlZm9yZSB3ZSBwYWQgaXQuXG5cdFx0XHR0bXBfbWludXRlcyA9ICggKCB0bXBfaG91cnMgKiA2MCApICsgdG1wX21pbnV0ZXMgKTtcblx0XHRcdHRtcF9ob3VycyA9IDA7XG5cdFx0fVxuXG5cdFx0aWYgKCB0bXBfaG91cnMgPCAxMCApIHtcblx0XHRcdHRtcF9ob3VycyA9ICcwJyArIHRtcF9ob3Vycztcblx0XHR9XG5cblx0XHRpZiAoIHRtcF9taW51dGVzIDwgMTAgKSB7XG5cdFx0XHR0bXBfbWludXRlcyA9ICcwJyArIHRtcF9taW51dGVzO1xuXHRcdH1cblxuXHRcdGlmICggdG1wX3NlY29uZHMgPCAxMCApIHtcblx0XHRcdHRtcF9zZWNvbmRzID0gJzAnICsgdG1wX3NlY29uZHM7XG5cdFx0fVxuXG5cdFx0dmFyIHJldHZhbDtcblx0XHRpZiAoIGV4Y2x1ZGVfaG91cnMgPT0gdHJ1ZSApIHtcblx0XHRcdHJldHZhbCA9IFt0bXBfbWludXRlcywgdG1wX3NlY29uZHNdLmpvaW4oICc6JyApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRpZiAoIGluY2x1ZGVfc2Vjb25kcyA9PSB0cnVlICkge1xuXHRcdFx0XHRyZXR2YWwgPSBbdG1wX2hvdXJzLCB0bXBfbWludXRlcywgdG1wX3NlY29uZHNdLmpvaW4oICc6JyApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cmV0dmFsID0gW3RtcF9ob3VycywgdG1wX21pbnV0ZXNdLmpvaW4oICc6JyApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmICggbmVnYXRpdmVfbnVtYmVyID09IHRydWUgKSB7XG5cdFx0XHRyZXR2YWwgPSAnLScgKyByZXR2YWw7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHJldHZhbDtcblx0fSxcblxuLy9XYXM6IEdsb2JhbC5zZWNvbmRUb0hITU1TU1xuXHRHbG9iYWwuZ2V0VGltZVVuaXQgPSBmdW5jdGlvbiggc2Vjb25kcywgZm9ybWF0ICkge1xuXHRcdHZhciByZXR2YWw7XG5cblx0XHQvL2Fsd2F5cyByZXR1cm4gaGg6c3MuIGlmIHdlIGNhbid0IHBhcnNlIHRvIGZsb2F0LCB0aGVuIHdvcmsgd2l0aCAwIHRtcF9zZWNvbmRzXG5cdFx0dmFyIHNlY29uZHMgPSBwYXJzZUZsb2F0KCBzZWNvbmRzICk7XG5cdFx0aWYgKCBpc05hTiggc2Vjb25kcyApICkge1xuXHRcdFx0c2Vjb25kcyA9IDA7XG5cdFx0fVxuXG5cdFx0Ly9GSVhFUyBCVUcjMjA3MSAtIGRvbid0IGNoZWNrIHRoZSBsb2NhbCBjYWNoZSBkYXRhIGZvciBkZWZhdWx0IHZhbHVlLCBvciBpdCB3aWxsIGZhaWwgYW5kIGNhdXNlIGVycm9ycyB3aGVuIHVuYXV0aGVudGljYXRlZC4gRm9yIGV4YW1wbGUgaW4gdGhlIGluc3RhbGxlci5cblx0XHR2YXIgZm9ybWF0O1xuXHRcdGlmICggIWZvcm1hdCApIHtcblx0XHRcdGlmICggTG9jYWxDYWNoZURhdGEuZ2V0TG9naW5Vc2VyUHJlZmVyZW5jZSgpICkge1xuXHRcdFx0XHRmb3JtYXQgPSBMb2NhbENhY2hlRGF0YS5nZXRMb2dpblVzZXJQcmVmZXJlbmNlKCkudGltZV91bml0X2Zvcm1hdDtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGZvcm1hdCA9IDEwO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRmb3JtYXQgPSBwYXJzZUludCggZm9ybWF0ICk7XG5cblx0XHRzd2l0Y2ggKCBmb3JtYXQgKSB7XG5cdFx0XHRjYXNlIDEwOlxuXHRcdFx0XHRyZXR2YWwgPSBHbG9iYWwuY29udmVydFNlY29uZHNUb0hNUyggc2Vjb25kcyApO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgMTI6XG5cdFx0XHRcdHJldHZhbCA9IEdsb2JhbC5jb252ZXJ0U2Vjb25kc1RvSE1TKCBzZWNvbmRzLCB0cnVlICk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSA5OTogLy9Gb3IgbG9jYWwgdXNlIG9ubHksIGluIHByb2dyZXNzIGJhciBhbHdheXMgc2hvdyB0bXBfbWludXRlcyBhbmQgdG1wX3NlY29uZHNcblx0XHRcdFx0cmV0dmFsID0gR2xvYmFsLmNvbnZlcnRTZWNvbmRzVG9ITVMoIHNlY29uZHMsIHRydWUsIHRydWUgKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIDIwOlxuXHRcdFx0XHRyZXR2YWwgPSAoIHNlY29uZHMgLyAzNjAwICkudG9GaXhlZCggMiApO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgMjI6XG5cdFx0XHRcdHJldHZhbCA9ICggc2Vjb25kcyAvIDM2MDAgKS50b0ZpeGVkKCAzICk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAyMzpcblx0XHRcdFx0cmV0dmFsID0gKCBzZWNvbmRzIC8gMzYwMCApLnRvRml4ZWQoIDQgKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIDMwOlxuXHRcdFx0XHRyZXR2YWwgPSAoIHNlY29uZHMgLyA2MCApLnRvRml4ZWQoIDAgKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIDQwOlxuXHRcdFx0XHRyZXR2YWwgPSBzZWNvbmRzO1xuXHRcdFx0XHRicmVhaztcblx0XHR9XG5cblx0XHQvL0RlYnVnLlRleHQoICdTZWNvbmRzOiAnKyBzZWNvbmRzICsnIFJldHZhbDogJysgcmV0dmFsLCAnR2xvYmFsLmpzJywgJycsICdnZXRUaW1lVW5pdCcsIDEwICk7XG5cdFx0cmV0dXJuIHJldHZhbDtcblx0fTtcblxuR2xvYmFsLnJlbW92ZVRyYWlsaW5nWmVyb3MgPSBmdW5jdGlvbiggdmFsdWUsIG1pbmltdW1fZGVjaW1hbHMgKSB7XG5cdGlmICggIW1pbmltdW1fZGVjaW1hbHMgKSB7XG5cdFx0bWluaW11bV9kZWNpbWFscyA9IDI7XG5cdH1cblx0aWYgKCB2YWx1ZSApIHtcblx0XHR2YWx1ZSA9IHBhcnNlRmxvYXQoIHZhbHVlICk7IC8vIGZpcnN0IHRvIHJlbW92ZSB0aGUgemVybyBhZnRlciB0aGUgcG9pbnQuXG5cblx0XHR2YXIgdHJpbW1lZF92YWx1ZSA9IHZhbHVlLnRvU3RyaW5nKCk7XG5cblx0XHRpZiAoIHRyaW1tZWRfdmFsdWUuaW5kZXhPZiggJy4nICkgPiAwICkge1xuXHRcdFx0Ly8gSWYgYWZ0ZXIgcmVtb3ZlZCBoYXMgdGhlIHBvaW50LCB0aGVuIHJldmVyc2UgaXQuXG5cdFx0XHR2YXIgdG1wX21pbmltdW1fZGVjaW1hbHMgPSBwYXJzZUludCggdHJpbW1lZF92YWx1ZS5zcGxpdCggJycgKS5yZXZlcnNlKCkuam9pbiggJycgKSApLnRvU3RyaW5nKCkubGVuZ3RoO1xuXHRcdFx0aWYgKCB0bXBfbWluaW11bV9kZWNpbWFscyA+PSBtaW5pbXVtX2RlY2ltYWxzICYmIHRtcF9taW5pbXVtX2RlY2ltYWxzIDw9IDQgKSB7XG5cdFx0XHRcdG1pbmltdW1fZGVjaW1hbHMgPSB0bXBfbWluaW11bV9kZWNpbWFscztcblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdHJldHVybiB2YWx1ZS50b0ZpeGVkKCBtaW5pbXVtX2RlY2ltYWxzICk7XG5cdH1cblxuXHRyZXR1cm4gdmFsdWU7XG59O1xuXG4vKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuXG5HbG9iYWwuaXNDYW52YXNTdXBwb3J0ZWQgPSBmdW5jdGlvbigpIHtcblx0dmFyIGVsZW0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCAnY2FudmFzJyApO1xuXHRyZXR1cm4gISEoIGVsZW0uZ2V0Q29udGV4dCAmJiBlbGVtLmdldENvbnRleHQoICcyZCcgKSApO1xufTtcblxuR2xvYmFsLmdldFJhbmRvbU51bSA9IGZ1bmN0aW9uKCkge1xuXG5cdHZhciBudW1iZXIgPSBNYXRoLmZsb29yKCBNYXRoLnJhbmRvbSgpICogOTk5ICk7Ly8wLTIzXG5cblx0cmV0dXJuIG51bWJlcjtcblxufTtcblxuLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuXG5HbG9iYWwuZ2V0U2NyaXB0TmFtZUJ5QVBJID0gZnVuY3Rpb24oIGFwaV9jbGFzcyApIHtcblxuXHRpZiAoICFhcGlfY2xhc3MgfHwgIWFwaV9jbGFzcy5jbGFzc05hbWUgKSB7XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblxuXHR2YXIgc2NyaXB0X25hbWUgPSAnJztcblx0c3dpdGNoICggYXBpX2NsYXNzLmNsYXNzTmFtZSApIHtcblx0XHRjYXNlICdBUElVc2VyJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0VtcGxveWVlVmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElCcmFuY2gnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnQnJhbmNoVmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElEZXBhcnRtZW50Jzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0RlcGFydG1lbnRWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVVzZXJXYWdlJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1dhZ2VWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVVzZXJDb250YWN0Jzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1VzZXJDb250YWN0Vmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElVc2VyVGl0bGUnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnVXNlclRpdGxlVmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElXYWdlR3JvdXAnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnV2FnZUdyb3VwVmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElMb2cnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnTG9nVmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElVc2VyR3JvdXAnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnVXNlckdyb3VwVmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElQYXlTdHViRW50cnlBY2NvdW50Jzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1BheVN0dWJFbnRyeUFjY291bnRWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVBheVN0dWJFbnRyeUFjY291bnRMaW5rJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1BheVN0dWJFbnRyeUFjY291bnRMaW5rVmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElQYXlQZXJpb2QnOlxuXHRcdGNhc2UgJ0FQSVBheVBlcmlvZFNjaGVkdWxlJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1BheVBlcmlvZHNWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUFjY3J1YWwnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnQVBJQWNjcnVhbCc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElBY2NydWFsQmFsYW5jZSc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdBY2NydWFsQmFsYW5jZVZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJRXhjZXB0aW9uJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0V4Y2VwdGlvblZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJSm9iR3JvdXAnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnSm9iR3JvdXBWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUpvYic6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdKb2JWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUpvYkl0ZW1Hcm91cCc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdKb2JJdGVtR3JvdXBWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUpvYkl0ZW0nOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnSm9iSXRlbVZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJSm9iSXRlbUFtZW5kbWVudCc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdKb2JJdGVtQW1lbmRtZW50Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVB1bmNoJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1B1bmNoZXNWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVB1bmNoVGFnJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1B1bmNoVGFnVmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElQdW5jaFRhZ0dyb3VwJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1B1bmNoVGFnR3JvdXBWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVJlY3VycmluZ1NjaGVkdWxlQ29udHJvbCc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdSZWN1cnJpbmdTY2hlZHVsZUNvbnRyb2xWaWV3Jztcblx0XHRcdGJyZWFrO1xuXG5cdFx0Y2FzZSAnQVBJUmVjdXJyaW5nU2NoZWR1bGVUZW1wbGF0ZUNvbnRyb2wnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnUmVjdXJyaW5nU2NoZWR1bGVUZW1wbGF0ZUNvbnRyb2xWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVNjaGVkdWxlJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1NjaGVkdWxlU2hpZnRWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUJhbmtBY2NvdW50Jzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0JhbmtBY2NvdW50Vmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElDb21wYW55Jzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0NvbXBhbnlWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUN1cnJlbmN5Jzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0N1cnJlbmN5Vmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElDdXJyZW5jeVJhdGUnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnQ3VycmVuY3lSYXRlJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUhpZXJhcmNoeUNvbnRyb2wnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnSGllcmFyY2h5Q29udHJvbFZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJRXRobmljR3JvdXAnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnRXRobmljR3JvdXBWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUN1c3RvbUZpZWxkJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0N1c3RvbUZpZWxkVmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElQZXJtaXNzaW9uQ29udHJvbCc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdQZXJtaXNzaW9uQ29udHJvbFZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJU3RhdGlvbic6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdTdGF0aW9uVmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElEb2N1bWVudFJldmlzaW9uJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0RvY3VtZW50UmV2aXNpb25WaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSURvY3VtZW50R3JvdXAnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnRG9jdW1lbnRHcm91cFZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJRG9jdW1lbnQnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnRG9jdW1lbnRWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVJPRSc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdST0VWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVVzZXJEZWZhdWx0Jzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1VzZXJEZWZhdWx0Vmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElVc2VyUHJlZmVyZW5jZSc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdVc2VyUHJlZmVyZW5jZVZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJS1BJJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0tQSVZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJVXNlclJldmlld0NvbnRyb2wnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnVXNlclJldmlld0NvbnRyb2xWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVF1YWxpZmljYXRpb24nOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnUXVhbGlmaWNhdGlvblZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJVXNlckVkdWNhdGlvbic6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdVc2VyVGl0bGVWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVVzZXJMYW5ndWFnZSc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdVc2VyVGl0bGVWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVVzZXJMaWNlbnNlJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1VzZXJMaWNlbnNlVmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElVc2VyTWVtYmVyc2hpcCc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdVc2VyTWVtYmVyc2hpcFZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJVXNlclNraWxsJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1VzZXJTa2lsbFZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJSm9iQXBwbGljYW50RWR1Y2F0aW9uJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0pvYkFwcGxpY2FudEVkdWNhdGlvblZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJSm9iQXBwbGljYW50RW1wbG95bWVudCc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdKb2JBcHBsaWNhbnRFZHVjYXRpb25WaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUpvYkFwcGxpY2FudExhbmd1YWdlJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0pvYkFwcGxpY2FudExhbmd1YWdlVmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElKb2JBcHBsaWNhbnRMaWNlbnNlJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0pvYkFwcGxpY2FudExpY2Vuc2VWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUpvYkFwcGxpY2FudExvY2F0aW9uJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0pvYkFwcGxpY2FudExpY2Vuc2VWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUpvYkFwcGxpY2FudE1lbWJlcnNoaXAnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnSm9iQXBwbGljYW50TWVtYmVyc2hpcFZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJSm9iQXBwbGljYW50UmVmZXJlbmNlJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0pvYkFwcGxpY2FudFJlZmVyZW5jZVZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJSm9iQXBwbGljYW50U2tpbGwnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnSm9iQXBwbGljYW50U2tpbGxWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUpvYkFwcGxpY2FudCc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdKb2JBcHBsaWNhbnRTa2lsbFZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJSm9iQXBwbGljYXRpb24nOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnSm9iQXBwbGljYXRpb25WaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUpvYlZhY2FuY3knOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnSm9iVmFjYW5jeVZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJQXJlYVBvbGljeSc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdKb2JWYWNhbmN5Vmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElDbGllbnQnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnQ2xpZW50Vmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElDbGllbnRDb250YWN0Jzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0NsaWVudENvbnRhY3RWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUNsaWVudEdyb3VwJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0NsaWVudEdyb3VwVmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElDbGllbnRQYXltZW50Jzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0NsaWVudFBheW1lbnRWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUludm9pY2VEaXN0cmljdCc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdJbnZvaWNlRGlzdHJpY3RWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUludm9pY2UnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnSW52b2ljZVZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJVHJhbnNhY3Rpb24nOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnSW52b2ljZVRyYW5zYWN0aW9uVmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElQYXltZW50R2F0ZXdheSc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdQYXltZW50R2F0ZXdheVZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJUHJvZHVjdEdyb3VwJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1Byb2R1Y3RHcm91cFZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJUHJvZHVjdCc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdQcm9kdWN0Vmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElJbnZvaWNlQ29uZmlnJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0ludm9pY2VDb25maWdWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVNoaXBwaW5nUG9saWN5Jzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1NoaXBwaW5nUG9saWN5Vmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElUYXhQb2xpY3knOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnVGF4UG9saWN5Vmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElDb21wYW55RGVkdWN0aW9uJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0NvbXBhbnlUYXhEZWR1Y3Rpb25WaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVBheVN0dWInOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnUGF5U3R1YlZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJUGF5U3R1YlRyYW5zYWN0aW9uJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1BheVN0dWJUcmFuc2FjdGlvblZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJUGF5U3R1YkVudHJ5Jzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1BheVN0dWJFbnRyeVZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJUGF5U3R1YkFtZW5kbWVudCc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdQYXlTdHViQW1lbmRtZW50Vmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElSZWN1cnJpbmdQYXlTdHViQW1lbmRtZW50Jzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1JlY3VycmluZ1BheVN0dWJBbWVuZG1lbnRWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVVzZXJFeHBlbnNlJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1VzZXJFeHBlbnNlVmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElMZWdhbEVudGl0eSc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdMZWdhbEVudGl0eVZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJUGF5cm9sbFJlbWl0dGFuY2VBZ2VuY3knOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnUGF5cm9sbFJlbWl0dGFuY2VBZ2VuY3lWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVBheXJvbGxSZW1pdHRhbmNlQWdlbmN5RXZlbnQnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnUGF5cm9sbFJlbWl0dGFuY2VBZ2VuY3lWaWV3RXZlbnQnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJQWJzZW5jZVBvbGljeSc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdBYnNlbmNlUG9saWN5Vmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElBY2NydWFsUG9saWN5QWNjb3VudCc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdBY2NydWFsUG9saWN5QWNjb3VudFZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJQWNjcnVhbFBvbGljeSc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdBY2NydWFsUG9saWN5Vmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElBY2NydWFsUG9saWN5VXNlck1vZGlmaWVyJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0FjY3J1YWxQb2xpY3lVc2VyTW9kaWZpZXJWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUJyZWFrUG9saWN5Jzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0JyZWFrUG9saWN5Vmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElFeGNlcHRpb25Qb2xpY3lDb250cm9sJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0V4Y2VwdGlvblBvbGljeUNvbnRyb2xWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUV4cGVuc2VQb2xpY3knOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnRXhwZW5zZVBvbGljeVZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJSG9saWRheSc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdIb2xpZGF5Vmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElIb2xpZGF5UG9saWN5Jzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0hvbGlkYXlQb2xpY3lWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSU1lYWxQb2xpY3knOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnTWVhbFBvbGljeVZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJT3ZlcnRpbWVQb2xpY3knOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnT3ZlcnRpbWVQb2xpY3lWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVBvbGljeUdyb3VwJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1BvbGljeUdyb3VwVmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElQcmVtaXVtUG9saWN5Jzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1ByZW1pdW1Qb2xpY3lWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVJlY3VycmluZ0hvbGlkYXknOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnUmVjdXJyaW5nSG9saWRheVZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJUm91bmRJbnRlcnZhbFBvbGljeSc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdSb3VuZEludGVydmFsUG9saWN5Vmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElTY2hlZHVsZVBvbGljeSc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdTY2hlZHVsZVBvbGljeVZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJVXNlclJlcG9ydERhdGEnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnVXNlclJlcG9ydERhdGFWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUluc3RhbGwnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnSW5zdGFsbFZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdH1cblxuXHRyZXR1cm4gc2NyaXB0X25hbWU7XG59O1xuXG4vKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuXG5HbG9iYWwuaXNPYmplY3QgPSBmdW5jdGlvbiggb2JqICkge1xuXHRpZiAoIG9iaiAhPT0gbnVsbCAmJiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyApIHtcblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXG5cdHJldHVybiBmYWxzZTtcbn07XG5cbkdsb2JhbC5pc0FycmF5ID0gZnVuY3Rpb24oIG9iaiApIHtcblxuXHRpZiAoIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCggb2JqICkgIT09ICdbb2JqZWN0IEFycmF5XScgKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0cmV0dXJuIHRydWU7XG59O1xuXG5HbG9iYWwuaXNTdHJpbmcgPSBmdW5jdGlvbiggb2JqICkge1xuXG5cdGlmICggT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKCBvYmogKSAhPT0gJ1tvYmplY3QgU3RyaW5nXScgKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0cmV0dXJuIHRydWU7XG59O1xuXG5HbG9iYWwuaXNWYWxpZERhdGUgPSBmdW5jdGlvbiggb2JqICkge1xuXHRpZiAoIG9iaiBpbnN0YW5jZW9mIERhdGUgJiYgIWlzTmFOKCBvYmogKSApIHtcblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXG5cdHJldHVybiBmYWxzZTtcbn07XG5cbkdsb2JhbC5kZWNvZGVDZWxsVmFsdWUgPSBmdW5jdGlvbiggdmFsICkge1xuXHRpZiAoICF2YWwgfHwgXy5pc09iamVjdCggdmFsICkgKSB7XG5cdFx0cmV0dXJuIHZhbDtcblx0fVxuXHR2YWwgPSB2YWwudG9TdHJpbmcoKTtcblx0dmFsID0gdmFsLnJlcGxhY2UoIC9cXG58XFxyfChcXHJcXG4pfChcXHUwMDg1KXwoXFx1MjAyOCl8KFxcdTIwMjkpL2csICc8YnI+JyApO1xuXHR2YWwgPSB2YWwucmVwbGFjZSggL1xcbnxcXHJ8KFxcclxcbil8KFxcdTAwODUpfChcXHUyMDI4KXwoXFx1MjAyOSkvZywgJzxicj4nICk7XG5cdHZhbCA9IEdsb2JhbC5odG1sRW5jb2RlKCB2YWwgKTtcblx0dmFsID0gdmFsLnJlcGxhY2UoIC8mbHQ7YnImZ3Q7L2csICc8YnI+JyApO1xuXG5cdHJldHVybiB2YWw7XG59O1xuXG5HbG9iYWwuYnVpbGRUcmVlUmVjb3JkID0gZnVuY3Rpb24oIGFycmF5LCBwYXJlbnRJZCApIHtcblx0dmFyIGZpbmFsQXJyYXkgPSBbXTtcblxuXHQkLmVhY2goIGFycmF5LCBmdW5jdGlvbigga2V5LCBpdGVtICkge1xuXHRcdGl0ZW0uZXhwYW5kZWQgPSB0cnVlO1xuXHRcdGl0ZW0ubG9hZGVkID0gdHJ1ZTtcblxuXHRcdGlmICggR2xvYmFsLmlzU2V0KCBwYXJlbnRJZCApICkge1xuXHRcdFx0aXRlbS5wYXJlbnQgPSBwYXJlbnRJZDtcblx0XHR9XG5cblx0XHRmaW5hbEFycmF5LnB1c2goIGl0ZW0gKTtcblxuXHRcdGlmICggR2xvYmFsLmlzU2V0KCBpdGVtLmNoaWxkcmVuICkgKSB7XG5cdFx0XHR2YXIgY2hpbGRyZW5BcnJheSA9IEdsb2JhbC5idWlsZFRyZWVSZWNvcmQoIGl0ZW0uY2hpbGRyZW4sIGl0ZW0uaWQgKTtcblx0XHRcdGZpbmFsQXJyYXkgPSBmaW5hbEFycmF5LmNvbmNhdCggY2hpbGRyZW5BcnJheSApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRpdGVtLmlzTGVhZiA9IHRydWU7XG5cdFx0fVxuXG5cdH0gKTtcblxuXHRyZXR1cm4gZmluYWxBcnJheTtcbn07XG5cbkdsb2JhbC5nZXRQYXJlbnRJZEJ5VHJlZVJlY29yZCA9IGZ1bmN0aW9uKCBhcnJheSwgc2VsZWN0SWQgKSB7XG5cblx0dmFyIHJldHZhbCA9IFtdO1xuXHRmb3IgKCB2YXIgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKyApIHtcblx0XHR2YXIgaXRlbSA9IGFycmF5W2ldO1xuXHRcdGlmICggaXRlbS5pZC50b1N0cmluZygpID09PSBzZWxlY3RJZC50b1N0cmluZygpICkge1xuXHRcdFx0dmFyIG5ld19yb3cgPSB7fTtcblx0XHRcdGlmICggdHlwZW9mIGl0ZW0ucGFyZW50ICE9ICd1bmRlZmluZWQnICkge1xuXHRcdFx0XHRuZXdfcm93ID0geyBwYXJlbnRfaWQ6IGl0ZW0ucGFyZW50LnRvU3RyaW5nKCksIG5hbWU6IGl0ZW0ubmFtZSB9O1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0bmV3X3JvdyA9IHsgbmFtZTogaXRlbS5uYW1lIH07XG5cdFx0XHR9XG5cblx0XHRcdC8vV2l0aG91dCBjcmVhdGVkIGFuZCB1cGRhdGVkIGluZm8sIGF1ZGl0IHRhYiBzaG93cyBOL0EgZm9yIGJvdGhcblx0XHRcdGlmICggdHlwZW9mIGl0ZW0uY3JlYXRlZF9ieSAhPSAndW5kZWZpbmVkJyApIHtcblx0XHRcdFx0bmV3X3Jvdy5jcmVhdGVkX2J5ID0gaXRlbS5jcmVhdGVkX2J5O1xuXHRcdFx0XHRuZXdfcm93LmNyZWF0ZWRfZGF0ZSA9IGl0ZW0uY3JlYXRlZF9kYXRlO1xuXHRcdFx0XHRuZXdfcm93LnVwZGF0ZWRfYnkgPSBpdGVtLnVwZGF0ZWRfYnk7XG5cdFx0XHRcdG5ld19yb3cudXBkYXRlZF9kYXRlID0gaXRlbS51cGRhdGVkX2RhdGU7XG5cdFx0XHR9XG5cblx0XHRcdHJldHZhbC5wdXNoKCBuZXdfcm93ICk7XG5cdFx0XHRicmVhaztcblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gcmV0dmFsO1xuXG59O1xuXG5HbG9iYWwuYWRkRmlyc3RJdGVtVG9BcnJheSA9IGZ1bmN0aW9uKCBhcnJheSwgZmlyc3RJdGVtVHlwZSwgY3VzdG9tTGFiZWwgKSB7XG5cdC8vRXJyb3I6IFVuYWJsZSB0byBnZXQgcHJvcGVydHkgJ3Vuc2hpZnQnIG9mIHVuZGVmaW5lZCBvciBudWxsIHJlZmVyZW5jZSBpbiAvaW50ZXJmYWNlL2h0bWw1L2dsb2JhbC9HbG9iYWwuanM/dj04LjAuMC0yMDE0MTIzMC0xNTM5NDIgbGluZSA5MDNcblx0dmFyIGxhYmVsO1xuXHRpZiAoIGFycmF5ICkge1xuXHRcdGlmICggZmlyc3RJdGVtVHlwZSA9PT0gJ2FueScgKSB7XG5cdFx0XHRpZiAoIGN1c3RvbUxhYmVsICkge1xuXHRcdFx0XHRsYWJlbCA9IGN1c3RvbUxhYmVsO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0bGFiZWwgPSBHbG9iYWwuYW55X2l0ZW07XG5cdFx0XHR9XG5cdFx0XHQvLyMyMzAxIC0gZG9uJ3QgZHVwbGljYXRlIHRoZSAtLUFueS0tIGNhc2Ugd2hlbiB0aGUgYXJyYXkgaXMgcmVjeWNsZWQuXG5cdFx0XHRpZiAoICFhcnJheVswXSB8fCBhcnJheVswXS52YWx1ZSAhPSBUVFVVSUQubm90X2V4aXN0X2lkICkge1xuXHRcdFx0XHRhcnJheS51bnNoaWZ0KCB7XG5cdFx0XHRcdFx0bGFiZWw6IGxhYmVsLFxuXHRcdFx0XHRcdHZhbHVlOiBUVFVVSUQubm90X2V4aXN0X2lkLFxuXHRcdFx0XHRcdGZ1bGxWYWx1ZTogVFRVVUlELm5vdF9leGlzdF9pZCxcblx0XHRcdFx0XHRvcmRlclZhbHVlOiAnJ1xuXHRcdFx0XHR9ICk7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIGlmICggZmlyc3RJdGVtVHlwZSA9PT0gJ2VtcHR5JyApIHtcblx0XHRcdGlmICggY3VzdG9tTGFiZWwgKSB7XG5cdFx0XHRcdGxhYmVsID0gY3VzdG9tTGFiZWw7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRsYWJlbCA9IEdsb2JhbC5lbXB0eV9pdGVtO1xuXHRcdFx0fVxuXHRcdFx0Ly8jMjMwMSAtIGRvbid0IGR1cGxpY2F0ZSB0aGUgLS1Ob25lLS0gY2FzZSB3aGVuIHRoZSBhcnJheSBpcyByZWN5Y2xlZC5cblx0XHRcdGlmICggIWFycmF5WzBdIHx8IGFycmF5WzBdLnZhbHVlICE9IFRUVVVJRC56ZXJvX2lkICkge1xuXHRcdFx0XHRhcnJheS51bnNoaWZ0KCB7XG5cdFx0XHRcdFx0bGFiZWw6IGxhYmVsLFxuXHRcdFx0XHRcdHZhbHVlOiBUVFVVSUQuemVyb19pZCxcblx0XHRcdFx0XHRmdWxsVmFsdWU6IFRUVVVJRC56ZXJvX2lkLFxuXHRcdFx0XHRcdG9yZGVyVmFsdWU6ICcnXG5cdFx0XHRcdH0gKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gYXJyYXk7XG59O1xuXG4vL0FkZCBpdGVtIG9uIHRvIHRoZSBlbmQgb2YgdGhlIGFycmF5LCBidXQgbWFrZSBzdXJlIGl0cyBub3QgYWxyZWFkeSB0aGVyZSBhbmQgdGhlcmVmb3JlIG5ldmVyIGR1cGxpY2F0ZWQuXG5HbG9iYWwuYWRkTGFzdEl0ZW1Ub0FycmF5ID0gZnVuY3Rpb24oIGFycmF5LCBrZXksIGxhYmVsICkge1xuXHR2YXIgbGFiZWw7XG5cdGlmICggYXJyYXkgKSB7XG5cdFx0dmFyIGxhc3RfYXJyYXlfZWxlbWVudCA9IGFycmF5WyggYXJyYXkubGVuZ3RoIC0gMSApXTtcblx0XHRpZiAoIGxhc3RfYXJyYXlfZWxlbWVudC52YWx1ZSAhPSBrZXkgKSB7XG5cdFx0XHRhcnJheS5wdXNoKCB7XG5cdFx0XHRcdGZ1bGxWYWx1ZToga2V5LFxuXHRcdFx0XHR2YWx1ZToga2V5LFxuXHRcdFx0XHRsYWJlbDogbGFiZWwsXG5cdFx0XHRcdGlkOiAyMDAwXG5cdFx0XHR9ICk7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIGFycmF5O1xufTtcblxuR2xvYmFsLmNvbnZlcnRSZWNvcmRBcnJheVRvT3B0aW9ucyA9IGZ1bmN0aW9uKCBhcnJheSApIHtcblx0dmFyIGxlbiA9IGFycmF5Lmxlbmd0aDtcblx0dmFyIG9wdGlvbnMgPSB7fTtcblxuXHRmb3IgKCB2YXIgaSA9IDA7IGkgPCBsZW47IGkrKyApIHtcblx0XHR2YXIgaXRlbSA9IGFycmF5W2ldO1xuXG5cdFx0b3B0aW9uc1tpdGVtLnZhbHVlXSA9IGl0ZW0ubGFiZWw7XG5cdH1cblxuXHRyZXR1cm4gb3B0aW9ucztcbn07XG5cbkdsb2JhbC5idWlsZENvbHVtbkFycmF5ID0gZnVuY3Rpb24oIGFycmF5ICkge1xuXHR2YXIgY29sdW1ucyA9IFtdO1xuXHR2YXIgaWQgPSAxMDAwO1xuXG5cdGZvciAoIHZhciBrZXkgaW4gYXJyYXkgKSB7XG5cdFx0dmFyIG9yZGVyX3ZhbHVlID0gR2xvYmFsLmdldFNvcnRWYWx1ZSgga2V5LCB0cnVlICk7XG5cdFx0dmFyIGNvbHVtbiA9IHtcblx0XHRcdGxhYmVsOiBhcnJheVtrZXldLFxuXHRcdFx0dmFsdWU6IEdsb2JhbC5yZW1vdmVTb3J0UHJlZml4KCBrZXkgKSxcblx0XHRcdG9yZGVyVmFsdWU6IG9yZGVyX3ZhbHVlLFxuXHRcdFx0aWQ6IGlkXG5cdFx0fTtcblx0XHRjb2x1bW5zLnB1c2goIGNvbHVtbiApO1xuXHRcdGlkID0gaWQgKyAxO1xuXHR9XG5cdHJldHVybiBjb2x1bW5zO1xufTtcblxuR2xvYmFsLnJlbW92ZVNvcnRQcmVmaXhGcm9tQXJyYXkgPSBmdW5jdGlvbiggYXJyYXkgKSB7XG5cdHZhciBmaW5hbEFycmF5ID0ge307XG5cblx0aWYgKCBHbG9iYWwuaXNTZXQoIGFycmF5ICkgKSB7XG5cblx0XHQkLmVhY2goIGFycmF5LCBmdW5jdGlvbigga2V5LCBpdGVtICkge1xuXHRcdFx0ZmluYWxBcnJheVtHbG9iYWwucmVtb3ZlU29ydFByZWZpeCgga2V5ICldID0gaXRlbTtcblx0XHR9ICk7XG5cblx0XHRyZXR1cm4gZmluYWxBcnJheTtcblx0fVxuXG5cdHJldHVybiBhcnJheTtcbn07XG5cbkdsb2JhbC5yZW1vdmVTb3J0UHJlZml4ID0gZnVuY3Rpb24oIGtleSApIHtcblx0aWYgKCB0eXBlb2Yga2V5ID09ICdzdHJpbmcnICYmIGtleS5tYXRjaCggR2xvYmFsLnNvcnRPcmRlclJlZ2V4ICkgKSB7XG5cdFx0a2V5ID0ga2V5LnJlcGxhY2UoIEdsb2JhbC5zb3J0T3JkZXJSZWdleCwgJycgKTtcblx0fVxuXHRyZXR1cm4ga2V5O1xufTtcblxuR2xvYmFsLmdldFNvcnRWYWx1ZSA9IGZ1bmN0aW9uKCBrZXksIHJldHVybl9rZXlfb25fbnVsbCApIHtcblx0dmFyIG9yZGVyX3ZhbHVlID0gOTk5O1xuXHRpZiAoIHR5cGVvZiBrZXkgPT0gJ3N0cmluZycgKSB7XG5cdFx0dmFyIHJlZ2V4X3Jlc3VsdCA9IGtleS5tYXRjaCggR2xvYmFsLnNvcnRPcmRlclJlZ2V4ICk7XG5cdFx0aWYgKCByZWdleF9yZXN1bHQgPT0gbnVsbCApIHtcblx0XHRcdGlmICggcmV0dXJuX2tleV9vbl9udWxsID09PSB0cnVlICkge1xuXHRcdFx0XHRvcmRlcl92YWx1ZSA9IGtleTtcblx0XHRcdH1cblx0XHR9IGVsc2UgaWYgKCByZWdleF9yZXN1bHRbMV0gKSB7XG5cdFx0XHRvcmRlcl92YWx1ZSA9IHJlZ2V4X3Jlc3VsdFsxXTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0RGVidWcuRXJyb3IoICdFcnJvcjogVW5hYmxlIHRvIHBhcnNlIG9yZGVyX3ZhbHVlJywgJ0dsb2JhbCcsICdHbG9iYWwnLCAnYnVpbGRDb2x1bW5BcnJheScsIDEwICk7XG5cdFx0fVxuXHR9XG5cdHJldHVybiBvcmRlcl92YWx1ZTtcbn07XG5cbkdsb2JhbC5jb252ZXJ0VG9OdW1iZXJJZlBvc3NpYmxlID0gZnVuY3Rpb24oIHZhbCApIHtcblx0Ly9pZiB2YWx1ZSBpcyBudW1iZXIgY29udmVydCB0byBudW1iZXIgdHlwZVxuXHR2YXIgcmVnID0gbmV3IFJlZ0V4cCggJ15bMC05XSokJyApO1xuXG5cdGlmICggcmVnLnRlc3QoIHZhbCApICYmIHZhbCAhPT0gJzAwJyApIHtcblx0XHR2YWwgPSBwYXJzZUZsb2F0KCB2YWwgKTtcblx0fVxuXG5cdGlmICggdmFsID09PSAnLTEnIHx8IHZhbCA9PT0gLTEgKSB7XG5cdFx0dmFsID0gLTE7XG5cdH1cblxuXHRyZXR1cm4gdmFsO1xufTtcblxuR2xvYmFsLmJ1aWxkUmVjb3JkQXJyYXkgPSBmdW5jdGlvbiggYXJyYXksIGZpcnN0X2l0ZW0sIG9yZGVyVHlwZSApIHtcblx0dmFyIGZpbmFsQXJyYXkgPSBbXTtcblxuXHRpZiAoIGZpcnN0X2l0ZW0gKSB7XG5cdFx0ZmluYWxBcnJheS5wdXNoKCBmaXJzdF9pdGVtICk7XG5cdH1cblxuXHR2YXIgaWQgPSAxMDAwO1xuXG5cdGlmICggR2xvYmFsLmlzU2V0KCBhcnJheSApICkge1xuXG5cdFx0Zm9yICggdmFyIGtleSBpbiBhcnJheSApIHtcblx0XHRcdHZhciBpdGVtID0gYXJyYXlba2V5XTtcblx0XHRcdHZhciB2YWx1ZSA9IEdsb2JhbC5yZW1vdmVTb3J0UHJlZml4KCBrZXkgKTtcblx0XHRcdHZhciBvcmRlcl92YWx1ZSA9IEdsb2JhbC5nZXRTb3J0VmFsdWUoIGtleSApO1xuXG5cdFx0XHQvLyA2LzQgY2hhbmdlZCBpZCB0byBzYW1lIGFzIHZhbHVlIHRvIG1ha2UgZmxleCBzaG93IGNvcnJlY3QgZGF0YSB3aGVuIHNob3cgc2VhcmNoIHJlc3VsdCBzYXZlZCBpbiBodG1sNSwgZmxleCB1c2UgaWQgaWYgaXQgZXhpc3RlZC5cblx0XHRcdHZhciByZWNvcmQgPSB7IGxhYmVsOiBpdGVtLCB2YWx1ZTogdmFsdWUsIGZ1bGxWYWx1ZToga2V5LCBvcmRlclZhbHVlOiBvcmRlcl92YWx1ZSwgaWQ6IHZhbHVlIH07XG5cblx0XHRcdGlkID0gaWQgKyAxO1xuXG5cdFx0XHRmaW5hbEFycmF5LnB1c2goIHJlY29yZCApO1xuXG5cdFx0fVxuXG5cdH1cblxuXHRyZXR1cm4gZmluYWxBcnJheTtcblxufTtcblxuR2xvYmFsLnRvcENvbnRhaW5lciA9IGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gJCggJyN0b3BDb250YWluZXInICk7XG59O1xuXG5HbG9iYWwub3ZlcmxheSA9IGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gJCggJyNvdmVybGF5JyApO1xufTtcblxuR2xvYmFsLmJvdHRvbUNvbnRhaW5lciA9IGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gJCggJyNib3R0b21Db250YWluZXInICk7XG59O1xuXG5HbG9iYWwuYm90dG9tRmVlZGJhY2tMaW5rQ29udGFpbmVyID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiAkKCAnI2ZlZWRiYWNrTGlua0NvbnRhaW5lcicgKTtcbn07XG5cbkdsb2JhbC5zaG93UG93ZXJlZEJ5ID0gZnVuY3Rpb24oKSB7XG5cdHZhciBwb3dlcmVkX2J5X2ltZyA9ICQoICcjcG93ZXJlZF9ieScgKTtcblx0cG93ZXJlZF9ieV9pbWcuc2hvdygpO1xuXHRwb3dlcmVkX2J5X2ltZy5hdHRyKCAnc3JjJywgU2VydmljZUNhbGxlci5nZXRVUkxCeU9iamVjdFR5cGUoICdjb3B5cmlnaHQnICkgKTtcblx0cG93ZXJlZF9ieV9pbWcuYXR0ciggJ2FsdCcsIExvY2FsQ2FjaGVEYXRhLmxvZ2luRGF0YS5hcHBsaWNhdGlvbl9uYW1lICsgJyBXb3JrZm9yY2UgTWFuYWdlbWVudCBTb2Z0d2FyZScgKTtcblx0dmFyIHBvd2VyZWRfYnlfbGluayA9ICQoICc8YSB0YXJnZXQ9XCJfYmxhbmtcIiBocmVmPVwiaHR0cHM6Ly8nICsgTG9jYWxDYWNoZURhdGEuZ2V0TG9naW5EYXRhKCkub3JnYW5pemF0aW9uX3VybCArICdcIj48L2E+JyApO1xuXHRwb3dlcmVkX2J5X2xpbmsuYWRkQ2xhc3MoICdwb3dlcmVkLWJ5LWltZy1zZW8nICk7XG5cdHBvd2VyZWRfYnlfaW1nLndyYXAoIHBvd2VyZWRfYnlfbGluayApO1xufTtcblxuR2xvYmFsLnNldFNpZ25hbFN0cmVuZ3RoID0gZnVuY3Rpb24oKSB7XG5cdGlmICggR2xvYmFsLnNpZ25hbF90aW1lciApIHtcblx0XHRyZXR1cm47XG5cdH1cblx0JCggJy5zaWduYWwtc3RyZW5ndGgnICkuY3NzKCAnZGlzcGxheScsICdibG9jaycgKTtcblx0dmFyIHN0YXR1cyA9ICcuLi4uLi4nO1xuXHR2YXIgYXZlcmFnZV90aW1lID0gMDtcblx0dmFyIGNoZWNraW5nX2FycmF5ID0gW107XG5cdHZhciBzaW5nbGVfc3RyZW5ndGggPSBudWxsO1xuXHR2YXIgc2luZ2xlX3N0cmVuZ3RoX3Rvb2x0aXAgPSBudWxsO1xuXG5cdHNldFRvb2x0aXAoKTtcblxuXHRzZXRUaW1lb3V0KCBmdW5jdGlvbigpIHtcblx0XHRkb1BpbmcoKTtcblx0fSwgMTAwMDAgKTtcblx0R2xvYmFsLnNpZ25hbF90aW1lciA9IHNldEludGVydmFsKCBmdW5jdGlvbigpIHtcblx0XHRkb1BpbmcoKTtcblx0fSwgNjAwMDAgKTtcblxuXHRmdW5jdGlvbiBkb1BpbmcoKSB7XG5cdFx0aWYgKCAoIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIgJiYgTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlci52aWV3SWQgPT09ICdMb2dpblZpZXcnICkgfHwgR2xvYmFsLmlkbGVfdGltZSA+PSBNYXRoLm1pbiggMTUsIEFQSUdsb2JhbC5wcmVfbG9naW5fZGF0YS5zZXNzaW9uX2lkbGVfdGltZW91dCAvIDYwICkgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0cGluZyggU2VydmljZUNhbGxlci5iYXNlX3VybCArICdpbnRlcmZhY2UvcGluZy5odG1sP3Q9JyArIG5ldyBEYXRlKCkuZ2V0VGltZSgpLCBmdW5jdGlvbiggdGltZSApIHtcblx0XHRcdCQoICcuc2lnbmFsLXN0cmVuZ3RoLWVtcHR5JyApLnJlbW92ZUNsYXNzKCAnc2lnbmFsLXN0cmVuZ3RoLWVtcHR5JyApO1xuXG5cdFx0XHRpZiAoIGNoZWNraW5nX2FycmF5Lmxlbmd0aCA+PSAzICkge1xuXHRcdFx0XHRjaGVja2luZ19hcnJheS5zaGlmdCgpO1xuXHRcdFx0fVxuXHRcdFx0Y2hlY2tpbmdfYXJyYXkucHVzaCggdGltZSApO1xuXHRcdFx0dmFyIHRvdGFsX3RpbWUgPSAwO1xuXHRcdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgY2hlY2tpbmdfYXJyYXkubGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRcdHRvdGFsX3RpbWUgPSBjaGVja2luZ19hcnJheVtpXSArIHRvdGFsX3RpbWU7XG5cdFx0XHR9XG5cdFx0XHRhdmVyYWdlX3RpbWUgPSB0b3RhbF90aW1lIC8gY2hlY2tpbmdfYXJyYXkubGVuZ3RoO1xuXHRcdFx0RGVidWcuVGV4dCggJ0N1cnJlbnQgUGluZzogJyArIHRpbWUgKyAnbXMgQXZlcmFnZTogJyArIGF2ZXJhZ2VfdGltZSArICdtcyBEYXRlOiAnICsgKCBuZXcgRGF0ZSApLnRvSVNPU3RyaW5nKCkucmVwbGFjZSggL3p8dC9naSwgJyAnICksICdHbG9iYWwuanMnLCAnJywgJ2RvUGluZycsIDYgKTtcblx0XHRcdEdsb2JhbC5jdXJyZW50X3BpbmcgPSBhdmVyYWdlX3RpbWU7XG5cdFx0XHRzdGF0dXMgPSAkLmkxOG4uXyggJ0dvb2QnICk7XG5cdFx0XHQvL2RvIG5vdCBhbGxvdyBzaWduYWwgc3RyZW5ndGggdmFyaWF0aW9uIGluIHVuaXQgdGVzdCBtb2RlXG5cdFx0XHRpZiAoIEdsb2JhbC5VTklUX1RFU1RfTU9ERSA9PSBmYWxzZSApIHtcblx0XHRcdFx0aWYgKCBhdmVyYWdlX3RpbWUgPiA0MDAgKSB7XG5cdFx0XHRcdFx0JCggJy5zaWduYWwtc3RyZW5ndGgtcHJldHR5LXN0cm9uZycgKS5hZGRDbGFzcyggJ3NpZ25hbC1zdHJlbmd0aC1lbXB0eScgKTtcblx0XHRcdFx0XHQkKCAnLnNpZ25hbC1zdHJlbmd0aC1zdHJvbmcnICkuYWRkQ2xhc3MoICdzaWduYWwtc3RyZW5ndGgtZW1wdHknICk7XG5cdFx0XHRcdFx0JCggJy5zaWduYWwtc3RyZW5ndGgtd2VhaycgKS5hZGRDbGFzcyggJ3NpZ25hbC1zdHJlbmd0aC1lbXB0eScgKTtcblx0XHRcdFx0XHRzdGF0dXMgPSAkLmkxOG4uXyggJ1Bvb3InICk7XG5cdFx0XHRcdH0gZWxzZSBpZiAoIGF2ZXJhZ2VfdGltZSA+IDI1MCApIHtcblx0XHRcdFx0XHQkKCAnLnNpZ25hbC1zdHJlbmd0aC1wcmV0dHktc3Ryb25nJyApLmFkZENsYXNzKCAnc2lnbmFsLXN0cmVuZ3RoLWVtcHR5JyApO1xuXHRcdFx0XHRcdCQoICcuc2lnbmFsLXN0cmVuZ3RoLXN0cm9uZycgKS5hZGRDbGFzcyggJ3NpZ25hbC1zdHJlbmd0aC1lbXB0eScgKTtcblx0XHRcdFx0XHRzdGF0dXMgPSAkLmkxOG4uXyggJ0JlbG93IEF2ZXJhZ2UnICk7XG5cdFx0XHRcdH0gZWxzZSBpZiAoIGF2ZXJhZ2VfdGltZSA+IDE1MCApIHtcblx0XHRcdFx0XHQkKCAnLnNpZ25hbC1zdHJlbmd0aC1wcmV0dHktc3Ryb25nJyApLmFkZENsYXNzKCAnc2lnbmFsLXN0cmVuZ3RoLWVtcHR5JyApO1xuXHRcdFx0XHRcdHN0YXR1cyA9ICQuaTE4bi5fKCAnQXZlcmFnZScgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRzZXRUb29sdGlwKCk7XG5cblx0XHR9ICk7XG5cdH1cblxuXHRmdW5jdGlvbiBzZXRUb29sdGlwKCkge1xuXHRcdHZhciBodG1sID0gJzxkaXY+JyArICQuaTE4bi5fKCAnWW91ciBOZXR3b3JrIENvbm5lY3Rpb24gaXMnICkgKyAnICcgKyBzdGF0dXMgKyAnICgnICsgJC5pMThuLl8oICdMYXRlbmN5JyApICsgJzogJyArICggYXZlcmFnZV90aW1lID4gMCA/IGF2ZXJhZ2VfdGltZS50b0ZpeGVkKCAwICkgKyAnbXMnIDogJC5pMThuLl8oICdDYWxjdWxhdGluZy4uLicgKSApICsgJyknICsgJzwvZGl2Pic7XG5cdFx0JCggJy5zaWduYWwtc3RyZW5ndGgnICkucXRpcCgge1xuXHRcdFx0aWQ6ICdzaW5nbGVfc3RyZW5ndGgnLFxuXHRcdFx0Y29udGVudDoge1xuXHRcdFx0XHR0ZXh0OiBodG1sXG5cdFx0XHR9LFxuXHRcdFx0cG9zaXRpb246IHtcblx0XHRcdFx0bXk6ICdib3R0b20gbGVmdCcsXG5cdFx0XHRcdGF0OiAndG9wIHJpZ2h0J1xuXHRcdFx0fVxuXHRcdH0gKTtcblx0fVxuXG5cdGZ1bmN0aW9uIHBpbmcoIHVybCwgY2FsbGJhY2sgKSB7XG5cdFx0dmFyIGluVXNlLCBzdGFydCwgaW1nLCB0aW1lcjtcblx0XHRpZiAoICFpblVzZSApIHtcblx0XHRcdGluVXNlID0gdHJ1ZTtcblx0XHRcdGltZyA9IG5ldyBJbWFnZSgpO1xuXHRcdFx0aW1nLm9ubG9hZCA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHR2YXIgZW5kVGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuXHRcdFx0XHRpblVzZSA9IGZhbHNlO1xuXHRcdFx0XHRjYWxsYmFjayggKCBlbmRUaW1lIC0gc3RhcnQgKSApO1xuXG5cdFx0XHR9O1xuXHRcdFx0aW1nLm9uZXJyb3IgPSBmdW5jdGlvbiggZSApIHtcblx0XHRcdFx0aWYgKCBpblVzZSApIHtcblx0XHRcdFx0XHRpblVzZSA9IGZhbHNlO1xuXHRcdFx0XHRcdHZhciBlbmRUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG5cdFx0XHRcdFx0Y2FsbGJhY2soICggZW5kVGltZSAtIHN0YXJ0ICkgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHR9O1xuXHRcdFx0c3RhcnQgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblx0XHRcdGltZy5zcmMgPSB1cmw7XG5cdFx0XHR0aW1lciA9IHNldFRpbWVvdXQoIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoIGluVXNlICkge1xuXHRcdFx0XHRcdHZhciBlbmRUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG5cdFx0XHRcdFx0aW5Vc2UgPSBmYWxzZTtcblx0XHRcdFx0XHRjYWxsYmFjayggKCBlbmRUaW1lIC0gc3RhcnQgKSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9LCA1MDAwICk7XG5cdFx0fVxuXHR9XG59O1xuXG5HbG9iYWwuY29udGVudENvbnRhaW5lciA9IGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gJCggJyNjb250ZW50Q29udGFpbmVyJyApO1xufTtcblxuR2xvYmFsLmJvZHlXaWR0aCA9IGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gJCggd2luZG93ICkud2lkdGgoKTtcbn07XG5cbkdsb2JhbC5ib2R5SGVpZ2h0ID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiAkKCB3aW5kb3cgKS5oZWlnaHQoKTtcbn07XG5cbkdsb2JhbC5oYXNSZXF1aXJlTG9hZGVkID0gZnVuY3Rpb24oIHNjcmlwdF9wYXRoICkge1xuXHR2YXIgc3BsaXRfc2NyaXB0X3BhdGggPSBzY3JpcHRfcGF0aC5zcGxpdCggJy8nICk7XG5cblx0dmFyIGlkID0gc3BsaXRfc2NyaXB0X3BhdGhbc3BsaXRfc2NyaXB0X3BhdGgubGVuZ3RoIC0gMV07XG5cdGlkID0gaWQucmVwbGFjZSggJy5qcycsICcnICk7XG5cblx0Ly9DaGVjayBhbHRlcm5hdGl2ZSBzY3JpcHQgbmFtZXMgKGllOiB3aXRoL3dpdGhvdXQgdGhlIC5qcykgd2hlbiBhIGZ1bGwgcGF0aCBpcyBzcGVjaWZpZWQgdG8gc2VlIGlmIGl0IHdhcyBsb2FkZWQgaW4gZGlmZmVyZW50IHdheXMgd2l0aCByZXF1aXJlSlMgYW5kIG1ha2Ugc3VyZSBpdHMgbm90IGxvYWRlZCB0d2ljZS5cblx0aWYgKCBzY3JpcHRfcGF0aC5pbmRleE9mKCAnLmpzJyApID09IC0xICkge1xuXHRcdHZhciBhbHRlcm5hdGl2ZV9zY3JpcHRfcGF0aCA9IHNjcmlwdF9wYXRoICsgJy5qcyc7XG5cdH0gZWxzZSB7XG5cdFx0dmFyIGFsdGVybmF0aXZlX3NjcmlwdF9wYXRoID0gc2NyaXB0X3BhdGgucmVwbGFjZSggJy5qcycsICcnICk7XG5cdH1cblxuXHQvL01ha2Ugc3VyZSB0aGUgZnVuY3Rpb24gaXMgYm90aCBzcGVjaWZpZWQgYW5kIGRlZmluZWQuIFRoaXMgaGVscHMgY2FzZXMgd2hlcmUgdGhlIHVzZXIgaXMgb24gYSBTbG93IDNHIG5ldHdvcmsgYW5kIGRvdWJsZSBjbGlja3MgQXR0ZW5kYW5jZSAtPiBJbi9PdXQuXG5cdC8vICBJbiB0aGlzIGNhc2UgdGhlIHNhbWUgSW5PdXRWaWV3Q29udHJvbGxlci5qcyBmaWxlIGlzIGluIHRoZSBwcm9jZXNzIG9mIGJlaW5nIGxvYWRlZCwgdGhlbiBpcyBjYW5jZWxsZWQsXG5cdC8vICBhbmQgYW5vdGhlciBvbmUgdHJpZXMgdG8gbG9hZCBhbmQgdGhlIHN1Y2Nlc3MgY2FsbGJhY2sgd2hlcmUgdGhlIGNsYXNzIGlzIGluc3RhbnRpYXRlZCBpcyBjYWxsZWQgYmVmb3JlIGl0IGNhbiBiZSBpbnN0YW50aWF0ZWQsIGNhdXNpbmcgYSBKUyBleGNlcHRpb24gKFJlZmVyZW5jZUVycm9yOiBJbk91dFZpZXdDb250cm9sbGVyIGlzIG5vdCBkZWZpbmVkKS5cblx0Ly8gIEJldHRlciBkb3VibGUtY2xpY2sgcHJldmVudGlvbiB3b3VsZCBhbHNvIGhlbHAuXG5cdC8vIGlmICggdHlwZW9mIHJlcXVpcmUgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIHJlcXVpcmUuc3BlY2lmaWVkID09PSAnZnVuY3Rpb24nICYmICggcmVxdWlyZS5zcGVjaWZpZWQoIGlkICkgfHwgcmVxdWlyZS5zcGVjaWZpZWQoIHNjcmlwdF9wYXRoICkgfHwgcmVxdWlyZS5zcGVjaWZpZWQoIGFsdGVybmF0aXZlX3NjcmlwdF9wYXRoICkgKSApIHtcblx0Ly8gaWYgKCB0eXBlb2YgcmVxdWlyZSA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgcmVxdWlyZS5kZWZpbmVkID09PSAnZnVuY3Rpb24nICYmICggcmVxdWlyZS5kZWZpbmVkKCBpZCApIHx8IHJlcXVpcmUuZGVmaW5lZCggc2NyaXB0X3BhdGggKSB8fCByZXF1aXJlLmRlZmluZWQoIGFsdGVybmF0aXZlX3NjcmlwdF9wYXRoICkgKSApIHtcblx0Ly8gXHRyZXR1cm4gdHJ1ZTtcblx0Ly8gLy99XG5cblx0cmV0dXJuIGZhbHNlO1xufTtcblxuR2xvYmFsLmxvYWRTY3JpcHQgPSBmdW5jdGlvbiggc2NyaXB0UGF0aCwgb25SZXN1bHQgKSB7XG5cdGlmICggdHlwZW9mIHNjcmlwdFBhdGggIT09ICdzdHJpbmcnICkge1xuXHRcdC8vIE5vdCBpZGVhbCBmaXggYnV0IHRoaXMgaXMgdG8gaGFuZGxlIHRoZSBzY3JpcHRQYXRoLnNwbGl0IGlzIG5vdCBhIGZ1bmN0aW9uIGVycm9yIGluICMyNjk2LiBpZiB0aGUgcGF0aCBpcyBub3QgYSBzdHJpbmcsIHNwbGl0IGRvZXMgbm90IGV4aXN0IGFzIGEgZnVuY3Rpb24uXG5cdFx0Ly8gSGFyZCB0byBmaW5kIHJvb3QtY2F1c2UvcmVwcm9kdWNlLCBzbyB0aGlzIGZpeCBpcyB0byByZWR1Y2UgdGhlIG9jY3VyYW5jZXMgb2YgdGhlIEpTIGV4Y2VwdGlvbnMgcmVsYXRlZCB0byBpdC5cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHR2YXIgYXN5bmMgPSB0cnVlO1xuXHRpZiAoIHR5cGVvZiAoIG9uUmVzdWx0ICkgPT09ICd1bmRlZmluZWQnICkge1xuXHRcdGFzeW5jID0gZmFsc2U7XG5cdH1cblxuXHRpZiAoIEdsb2JhbC5oYXNSZXF1aXJlTG9hZGVkKCBzY3JpcHRQYXRoICkgKSB7XG5cdFx0aWYgKCBhc3luYyApIHtcblx0XHRcdG9uUmVzdWx0KCk7XG5cdFx0fVxuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cblx0Ly9FbnN1cmVzIHRoYXQgdGhlIGpzIGNhY2hlZCBzY3JpcHRzIGFyZSBub3QgbG9hZGVkIHR3aWNlXG5cdGlmICggYXN5bmMgKSB7XG5cdFx0aWYgKCBMb2NhbENhY2hlRGF0YS5sb2FkZWRTY3JpcHROYW1lc1tzY3JpcHRQYXRoXSApIHtcblx0XHRcdG9uUmVzdWx0KCk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHR9IGVsc2Uge1xuXHRcdGlmICggTG9jYWxDYWNoZURhdGEubG9hZGVkU2NyaXB0TmFtZXNbc2NyaXB0UGF0aF0gKSB7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cdH1cblxuXHR2YXIgc3VjY2Vzc2ZsYWcgPSBmYWxzZTtcblxuXHR2YXIgcmVhbFBhdGggPSBzY3JpcHRQYXRoO1xuXG5cdC8vIE1haW5seSB1c2VkIGluIHRoZSBhc3luYyBjb2RlLCBidXQgcHV0IGhlcmUgdG8gYWxzbyBjYXRjaCBkdXBsaWNhdGUgZGVjbGFyZWQgY2xhc3NlcyBpbiBib3RoIGFzeW5jIGFuZCBzeW5jaHJvbm91cyBjYWxscy5cblx0dmFyIHNwbGl0X3NjcmlwdF9wYXRoID0gcmVhbFBhdGguc3BsaXQoICcvJyApO1xuXHR2YXIgaW1wb3J0X2ZpbGVfbmFtZSA9IHNwbGl0X3NjcmlwdF9wYXRoW3NwbGl0X3NjcmlwdF9wYXRoLmxlbmd0aCAtIDFdLnJlcGxhY2UoICcuanMnLCAnJyApO1xuXHQvL3ZhciBpbXBvcnRfcGF0aCA9IHJlYWxQYXRoLnJlcGxhY2UoJ3ZpZXdzLycsICcnKTtcblxuXHR2YXIgY2xhc3NfZXhpc3RzID0gZXZhbChcInR5cGVvZiBcIisgaW1wb3J0X2ZpbGVfbmFtZSArXCIgPT09ICdmdW5jdGlvbidcIik7XG5cdGlmICggY2xhc3NfZXhpc3RzICkge1xuXHRcdC8vIFRoaXMgbWVhbnMgY2xhc3MgYWxyZWFkeSBleGlzdHMgb24gdGhlIHdpbmRvdyBvYmplY3QsIHNvIGl0IG11c3QgaGF2ZSBiZWVuIGFscmVhZHkgbG9hZGVkLlxuXHRcdC8vIERFViBOT1RFOiBUaGlzIHNob3VsZCBOT1QgaGFwcGVuLiBJZiBpdCBoYXBwZW5zLCBpdCBtZWFucyBzY3JpcHQgaXMgYmVpbmcgbG9hZGVkIHR3aWNlLiBDaGVjayBtYW51YWwgbG9hZGluZyBjYWxscyBsaWtlIHJlcXVpcmVqcyBvciBXZWJwYWNrIE1lcmdlSW50b1NpbmdsZUZpbGVQbHVnaW4gcGx1Z2luXG5cdFx0Ly8gSW4gYWxsIGxpa2VseWhvb2QsIGl0IGlzIGxpc3RlZCBpbiB0aGUgY29uY2F0ZW5hdGlvbiBhcnJheSBmb3IgTWVyZ2VJbnRvU2luZ2xlRmlsZVBsdWdpbi4gQmVzdCB0byB0cnkgdG8gcmVtb3ZlIGl0IGZyb20gdGhlcmUsIGFzIGxvbmcgYXMgaXRzIGNvcnJlY3RseSBsb2FkZWQgb24gZGVtYW5kIGluIGFsbCByZWxldmFudCBwbGFjZXMuIFNlZSB3aGF0IGVsc2UgdXNlcyB0aGUgY2xhc3MgdG8gYmUgc3VyZS5cblx0XHRHbG9iYWwuc2VuZEFuYWx5dGljc0V2ZW50KCAnZXJyb3I6c2NyaXB0bG9hZDpkdXBsaWNhdGVfY2xhc3MnLCAnbG9hZCcsICdlcnJvcjpzY3JpcHRsb2FkOmR1cGxpY2F0ZTonKyBzY3JpcHRQYXRoICk7XG5cdFx0RGVidWcuRXJyb3IoICdEdXBsaWNhdGUgY2xhc3MgZGVjbGFyYXRpb246ICcrIGltcG9ydF9maWxlX25hbWUsICdHbG9iYWwuanMnLCAnR2xvYmFsJywgJ2xvYWRTY3JpcHQnLCAxICk7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblxuXHRpZiAoIEdsb2JhbC51cmxfb2Zmc2V0ICkge1xuXHRcdHJlYWxQYXRoID0gR2xvYmFsLmdldEJhc2VVUkwoIEdsb2JhbC51cmxfb2Zmc2V0ICsgcmVhbFBhdGggKTtcblx0fVxuXG5cdGlmICggYXN5bmMgKSB7XG5cdFx0RGVidWcuVGV4dCggJ0FTWU5DLUxPQURJTkc6ICcgKyBzY3JpcHRQYXRoLCAnR2xvYmFsLmpzJywgJ0dsb2JhbCcsICdsb2FkU2NyaXB0JywgMTAgKTtcblxuXHRcdHZhciBpbXBvcnRfcGF0aDtcblx0XHRpZiAoIHNjcmlwdFBhdGguaW5kZXhPZigndmlld3MnKSAhPT0gLTEgKXtcblx0XHRcdGltcG9ydF9wYXRoID0gc2NyaXB0UGF0aC5yZXBsYWNlKCd2aWV3cy8nLCAnJyk7IC8vIFRoaXMgaXMgdG8gZW5zdXJlIHRoZSB2YXJpYWJsZSBpbiB0aGUgZHluYW1pYyB3ZWJwYWNrIGltcG9ydCgpIGlzIGEgc2luZ2xlIHZhcmlhYmxlIHJhdGhlciB0aGFuIGEgZnVsbCBwYXRoLlxuXHRcdFx0aW1wb3J0KFxuXHRcdFx0XHQvKiB3ZWJwYWNrQ2h1bmtOYW1lOiBcIltyZXF1ZXN0XVwiICovXG5cdFx0XHRcdC8qIHdlYnBhY2tJbmNsdWRlOiAvXFwuanMkLyAqL1xuXHRcdFx0XHQvKiB3ZWJwYWNrRXhjbHVkZTogL3RyaWdnZXJQYXJzZXJFcnJvclxcLmpzJC8gKi9cblx0XHRcdFx0YEAvdmlld3MvJHtpbXBvcnRfcGF0aH1gXG5cdFx0XHQpLnRoZW4oKG1vZHVsZSkgPT4ge1xuXHRcdFx0XHRpZiAoIG1vZHVsZSAmJiBtb2R1bGVbaW1wb3J0X2ZpbGVfbmFtZV0gKSB7XG5cdFx0XHRcdFx0d2luZG93W2ltcG9ydF9maWxlX25hbWVdID0gbW9kdWxlW2ltcG9ydF9maWxlX25hbWVdOyAvLyBBZnRlciBodG1sMmpzIHRoaXMgbWF5IG5vdCBiZSBuZWVkZWQgYW55bW9yZS4gQnV0IGxlYXZlIGZvciBub3cgYXMgdGhpcyBhbGxvd3MgdGhlIGxlZ2FjeSBodG1sIGZpbGVzIHRvIHRyaWdnZXIgdGhlICduZXcgTXlWaWV3Q29udHJvbGxlcigpJyBjb2RlIGluIHRoZWlyIGh0bWwgZmlsZXMuXG5cblx0XHRcdFx0XHRMb2NhbENhY2hlRGF0YS5sb2FkZWRTY3JpcHROYW1lc1tzY3JpcHRQYXRoXSA9IHRydWU7XG5cdFx0XHRcdFx0b25SZXN1bHQoKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRpZiggaW1wb3J0X2ZpbGVfbmFtZSA9PT0gJ2RlYnVnUGFuZWxDb250cm9sbGVyJykge1xuXHRcdFx0XHRcdFx0Ly8gZGVidWdQYW5lbCBpcyBjb2RlZCBkaWZmZXJlbnQsIHdpdGggbm8gY2xhc3Nlcy9jb25zdHJ1Y3Rvciwgc28gdGhpcyBpcyBub3QgYSBmYWlsLlxuXHRcdFx0XHRcdFx0TG9jYWxDYWNoZURhdGEubG9hZGVkU2NyaXB0TmFtZXNbc2NyaXB0UGF0aF0gPSB0cnVlO1xuXHRcdFx0XHRcdFx0b25SZXN1bHQoKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0Ly8gTG9hZGluZyBjbGFzcyBmYWlsZWQuXG5cdFx0XHRcdFx0XHQvLyBJZiB0aGVyZSBpcyBub3QgYW4gYXR0cmlidXRlIG1hdGNoaW5nIHRoZSBjbGFzcyBvbiB0aGUgbW9kdWxlIHJlc3VsdCwgdGhlbiB0aGlzIHN1Z2dlc3RzIGEgbWlzc2luZyBleHBvcnQgb24gdGhlIGNsYXNzLiBUaGVyZSB3aWxsIGFsc28gYmUgYSBkZWZhdWx0IGF0dHJpYnV0ZSB3aXRoIGFuIGVtcHR5IG9iamVjdCB0byBzaG93IG5vIGRlZmF1bHQgY2xhc3NlcyBleHBvcnRlZC5cblx0XHRcdFx0XHRcdERlYnVnLkVycm9yKCAnTG9hZGluZyB2aWV3IGNsYXNzIGZhaWxlZC4gUG90ZW50aWFsIG1pc3NpbmcgZXhwb3J0IGZvcjogJyArIGltcG9ydF9maWxlX25hbWUsICdHbG9iYWwuanMnLCAnR2xvYmFsJywgJ2xvYWRTY3JpcHQnLCAxICk7XG5cblx0XHRcdFx0XHRcdG9uUmVzdWx0KCk7IC8vIFRvIGFsbG93IGNhbGxiYWNrcyB0byB3b3JrIGZvciBub24tbW9kdWxlIHNjcmlwdHMgbGlrZSBkZWJ1Z1BhbmVsQ29udHJvbGxlci5cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0gKS5jYXRjaCggR2xvYmFsLmltcG9ydEVycm9ySGFuZGxlciApO1xuXHRcdH0gZWxzZSBpZiAoIHNjcmlwdFBhdGguaW5kZXhPZignZ2xvYmFsL3dpZGdldHMnKSAhPT0gLTEgKSB7XG5cdFx0XHRpbXBvcnRfcGF0aCA9IHNjcmlwdFBhdGgucmVwbGFjZSgnZ2xvYmFsL3dpZGdldHMvJywgJycpOyAvLyBUaGlzIGlzIHRvIGVuc3VyZSB0aGUgdmFyaWFibGUgaW4gdGhlIGR5bmFtaWMgd2VicGFjayBpbXBvcnQoKSBpcyBhIHNpbmdsZSB2YXJpYWJsZSByYXRoZXIgdGhhbiBhIGZ1bGwgcGF0aC5cblx0XHRcdGltcG9ydChcblx0XHRcdFx0Lyogd2VicGFja0NodW5rTmFtZTogXCJbcmVxdWVzdF1cIiAqL1xuXHRcdFx0XHQvKiB3ZWJwYWNrSW5jbHVkZTogL1xcLmpzJC8gKi9cblx0XHRcdFx0YEAvZ2xvYmFsL3dpZGdldHMvJHtpbXBvcnRfcGF0aH1gXG5cdFx0XHQpLnRoZW4oKG1vZHVsZSkgPT4ge1xuXHRcdFx0XHRpZiggbW9kdWxlICYmIG1vZHVsZVtpbXBvcnRfZmlsZV9uYW1lXSApIHtcblx0XHRcdFx0XHR3aW5kb3dbaW1wb3J0X2ZpbGVfbmFtZV0gPSBtb2R1bGVbaW1wb3J0X2ZpbGVfbmFtZV07XG5cdFx0XHRcdFx0TG9jYWxDYWNoZURhdGEubG9hZGVkU2NyaXB0TmFtZXNbc2NyaXB0UGF0aF0gPSB0cnVlO1xuXHRcdFx0XHRcdG9uUmVzdWx0KCk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Ly8gTG9hZGluZyBjbGFzcyBmYWlsZWQuXG5cdFx0XHRcdFx0Ly8gSWYgdGhlcmUgaXMgbm90IGFuIGF0dHJpYnV0ZSBtYXRjaGluZyB0aGUgY2xhc3Mgb24gdGhlIG1vZHVsZSByZXN1bHQsIHRoZW4gdGhpcyBzdWdnZXN0cyBhIG1pc3NpbmcgZXhwb3J0IG9uIHRoZSBjbGFzcy4gVGhlcmUgd2lsbCBhbHNvIGJlIGEgZGVmYXVsdCBhdHRyaWJ1dGUgd2l0aCBhbiBlbXB0eSBvYmplY3QgdG8gc2hvdyBubyBkZWZhdWx0IGNsYXNzZXMgZXhwb3J0ZWQuXG5cdFx0XHRcdFx0Ly8gVGhpcyBjb3VsZCBhbHNvIGJlIGEgd2lkZ2V0IHRoYXQgaXMgaGlzdG9yaWNhbGx5IG1lYW50IHRvIGxvYWQgc3luY2hyb25vdXNseSB3aXRoIHRoZSBqUXVlcnkuYWpheCBjb2RlIGZ1cnRoZXIgZG93bi4gSWYgdGhpcyBpcyB0aGUgY2FzZSwgcmVmYWN0b3IgdGhlIGNhbGxiYWNrIHRvIGxvYWQgdGhlIHdpZGdldCBzeW5jcm9ub3VzbHkgaW5zdGVhZC5cblx0XHRcdFx0XHREZWJ1Zy5FcnJvciggJ0xvYWRpbmcgd2lkZ2V0IGNsYXNzIGZhaWxlZC4gUG90ZW50aWFsIG1pc3NpbmcgZXhwb3J0IGZvcjogJysgaW1wb3J0X2ZpbGVfbmFtZSwgJ0dsb2JhbC5qcycsICdHbG9iYWwnLCAnbG9hZFNjcmlwdCcsIDEgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHR9ICkuY2F0Y2goIEdsb2JhbC5pbXBvcnRFcnJvckhhbmRsZXIgKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0RGVidWcuRXJyb3IoICdMb2FkaW5nIGNsYXNzIGZhaWxlZC4gVW5oYW5kbGVkIGZpbGUgdHlwZSBwYXRoIHJlcXVlc3Q6ICcrIHNjcmlwdFBhdGgsICdHbG9iYWwuanMnLCAnR2xvYmFsJywgJ2xvYWRTY3JpcHQnLCAxICk7XG5cdFx0fVxuXG5cdH0gZWxzZSB7XG5cdFx0dmFyIGNhbGxpbmdfc2NyaXB0ID0gJyc7XG5cdFx0aWYgKCBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyICYmIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIudmlld0lkICkge1xuXHRcdFx0Y2FsbGluZ19zY3JpcHQgPSAnIGZyb20gJyArIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIudmlld0lkICsgJ1ZpZXdDb250cm9sbGVyJztcblx0XHR9XG5cdFx0RGVidWcuVGV4dCggJ1NZTkMtTE9BRElORzogJyArIHNjcmlwdFBhdGggKyBjYWxsaW5nX3NjcmlwdCApO1xuXG5cdFx0dmFyIGlkID0gc2NyaXB0UGF0aC5zcGxpdCggJy8nICk7XG5cdFx0dmFyIGlkID0gaWRbaWQubGVuZ3RoIC0gMV07XG5cdFx0aWQgPSBpZC5yZXBsYWNlKCAnLmpzJywgJycgKTtcblx0XHRpZiAoICF3aW5kb3cuYmFkU2NyaXB0cyApIHtcblx0XHRcdHdpbmRvdy5iYWRTY3JpcHRzID0gW107XG5cdFx0fVxuXHRcdHdpbmRvdy5iYWRTY3JpcHRzLnB1c2goIGlkICk7IC8vV2hlbiB0aGUgcGFnZSBpcyBkb25lIGxvYWRpbmcgcHVuY2ggXCJiYWRTY3JpcHRzIGludG8gdGhlIGNvbnNvbGUgdG8gc2VlIGEgbmljZSBhcnJheSBvZiBhbGwgdGhlIHNjcmlwdHMgdGhhdCB3ZXJlIG5vdCBsb2FkZWQgYXN5bmMuXG5cblx0XHQvKipcblx0XHQgKiB0aGlzIHNlZW1zIHRvIHdvcmssIGJ1dCBjYXVzZXMgdGhlIHNjcmlwdCBlcnJvIGF0IGxpbmUgMCBwcm9ibGVtLlxuXHRcdCAqIHRyeSB0byByZWZhY3RvciB0byBub3QgdXNlIGpxdWVyeS5hamF4XG5cdFx0ICovXG5cdFx0alF1ZXJ5LmFqYXgoIHtcblx0XHRcdGFzeW5jOiBmYWxzZSxcblx0XHRcdHR5cGU6ICdHRVQnLFxuXHRcdFx0dXJsOiByZWFsUGF0aCArICc/dj0nICsgQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLmFwcGxpY2F0aW9uX2J1aWxkLFxuXHRcdFx0Y3Jvc3NPcmlnaW46IGZhbHNlLFxuXHRcdFx0ZGF0YTogbnVsbCxcblx0XHRcdGNhY2hlOiB0cnVlLFxuXHRcdFx0c3VjY2VzczogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHN1Y2Nlc3NmbGFnID0gdHJ1ZTtcblx0XHRcdFx0aWYgKCBhc3luYyApIHtcblx0XHRcdFx0XHRMb2NhbENhY2hlRGF0YS5sb2FkZWRTY3JpcHROYW1lc1tzY3JpcHRQYXRoXSA9IHRydWU7XG5cdFx0XHRcdFx0b25SZXN1bHQoKTtcblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdGVycm9yOiBmdW5jdGlvbigganFYSFIsIHRleHRTdGF0dXMsIGVycm9yVGhyb3duICkge1xuXHRcdFx0XHRUQWxlcnRNYW5hZ2VyLnNob3dOZXR3b3JrRXJyb3JBbGVydCgganFYSFIsIHRleHRTdGF0dXMsIGVycm9yVGhyb3duICk7XG5cdFx0XHR9LFxuXHRcdFx0ZGF0YVR5cGU6ICdzY3JpcHQnXG5cdFx0fSApO1xuXHR9XG5cblx0aWYgKCAhYXN5bmMgKSB7XG5cdFx0TG9jYWxDYWNoZURhdGEubG9hZGVkU2NyaXB0TmFtZXNbc2NyaXB0UGF0aF0gPSB0cnVlO1xuXHRcdHJldHVybiAoIHN1Y2Nlc3NmbGFnICk7XG5cdH1cblxufTtcblxuR2xvYmFsLmltcG9ydEVycm9ySGFuZGxlciA9IGZ1bmN0aW9uKCBlcnJvciApIHtcblx0aWYgKCBlcnJvci5uYW1lID09ICdDaHVua0xvYWRFcnJvcicgKSB7XG5cdFx0aWYgKCB3aW5kb3cuc2NyaXB0X2Vycm9yX3Nob3duID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHR3aW5kb3cuc2NyaXB0X2Vycm9yX3Nob3duID0gMTtcblx0XHRcdC8vVGhlcmUgaXMgbm8gcHJldHR5IGVycm9yYm94IGF0IHRoaXMgdGltZS4gWW91IG1heSBvbmx5IGhhdmUgYmFzaWMgamF2YXNjcmlwdC5cblx0XHRcdGlmICggY29uZmlybSggJ1VuYWJsZSB0byBkb3dubG9hZCByZXF1aXJlZCBkYXRhLiBZb3VyIGludGVybmV0IGNvbm5lY3Rpb24gbWF5IGhhdmUgZmFpbGVkIHByZXNzIE9rIHRvIHJlbG9hZC4nICkgKSB7XG5cdFx0XHRcdC8vRm9yIHRlc3RpbmcsIHNvIHRoYXQgdGhlcmUncyB0aW1lIHRvIHR1cm4gaW50ZXJuZXQgYmFjayBvbiBhZnRlciBjb25maXJtIGlzIGNsaWNrZWQuXG5cdFx0XHRcdC8vd2luZG93LnNldFRpbWVvdXQoZnVuY3Rpb24oKSB7d2luZG93LmxvY2F0aW9uLnJlbG9hZCgpfSw1MDAwKTtcblxuXHRcdFx0XHQvL1RoaXMgY2FuIGFsc28gaGFwcGVuIGlmIHRoZSB1c2VyIG1hbnVhbGx5IG1vZGlmaWVzIHRoZSBVUkwgdG8gYmUgYSBib2d1cyBWaWV3SWQgKGllOiAjIW09aG9tZUFCQylcblx0XHRcdFx0Ly9TbyB0cnkgdG8gcmVkaXJlY3QgYmFjayB0byB0aGUgaG9tZSBwYWdlIGZpcnN0LCBvdGhlcndpc2UgdHJ5IHRvIGRvIGEgYnJvd3NlciByZWxvYWQuXG5cdFx0XHRcdGlmICggU2VydmljZUNhbGxlci5yb290X3VybCAmJiBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEuYmFzZV91cmwgKSB7XG5cdFx0XHRcdFx0R2xvYmFsLnNldFVSTFRvQnJvd3NlciggU2VydmljZUNhbGxlci5yb290X3VybCArIEFQSUdsb2JhbC5wcmVfbG9naW5fZGF0YS5iYXNlX3VybCApO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHdpbmRvdy5sb2NhdGlvbi5yZWxvYWQoKTtcblx0XHRcdFx0fVxuXG5cdFx0XHR9XG5cdFx0fVxuXHRcdGNvbnNvbGUuZGVidWcoIGVycm9yLm1lc3NhZ2UgKTtcblx0XHQvL1N0b3AgZXJyb3IgZnJvbSBidWJibGluZyB1cC5cblx0XHQvLyBkZWxldGUgZTsgLy8gY29tbWVudGVkIG91dCBmcm9tIG9sZCBjb2RlIGFzIHdlYnBhY2sgY29tcGxhaW5zIGFib3V0IGRlbGV0aW5nIGxvY2FsIHZhcmlhYmxlIGluIHN0cmljdCBtb2RlLlxuXG5cdH0gZWxzZSB7XG5cdFx0RGVidWcuRXJyb3IoICdFcnJvciBsb2FkaW5nIHNjcmlwdCBkdXJpbmcgaW1wb3J0KCk6ICcgKyBlcnJvciwgJ0dsb2JhbC5qcycsICdHbG9iYWwnLCAnaW1wb3J0RXJyb3JIYW5kbGVyJywgMSApO1xuXHRcdC8vIFRocm93IGdlbmVyYWwgZXJyb3I/XG5cdH1cbn07XG5cbkdsb2JhbC5nZXRSZWFsSW1hZ2VQYXRoID0gZnVuY3Rpb24oIHBhdGggKSB7XG5cblx0dmFyIHJlYWxQYXRoID0gJ3RoZW1lLycgKyBHbG9iYWwudGhlbWUgKyAnLycgKyBwYXRoO1xuXG5cdGlmICggR2xvYmFsLnVybF9vZmZzZXQgKSB7XG5cdFx0cmVhbFBhdGggPSBHbG9iYWwudXJsX29mZnNldCArIHJlYWxQYXRoO1xuXHR9XG5cblx0cmV0dXJuIHJlYWxQYXRoO1xufTtcblxuR2xvYmFsLmdldFJpYmJvbkljb25SZWFsUGF0aCA9IGZ1bmN0aW9uKCBpY29uICkge1xuXHR2YXIgcmVhbFBhdGggPSAndGhlbWUvJyArIEdsb2JhbC50aGVtZSArICcvY3NzL2dsb2JhbC93aWRnZXRzL3JpYmJvbi9pY29ucy8nICsgaWNvbjtcblxuXHRpZiAoIEdsb2JhbC51cmxfb2Zmc2V0ICkge1xuXHRcdHJlYWxQYXRoID0gR2xvYmFsLnVybF9vZmZzZXQgKyByZWFsUGF0aDtcblx0fVxuXG5cdHJldHVybiByZWFsUGF0aDtcbn07XG5cbkdsb2JhbC5sb2FkTGFuZ3VhZ2UgPSBmdW5jdGlvbiggbmFtZSApIHtcblx0dmFyIHN1Y2Nlc3NmbGFnID0gZmFsc2U7XG5cdHZhciBtZXNzYWdlX2lkID0gVFRVVUlELmdlbmVyYXRlVVVJRCgpO1xuXHRQcm9ncmVzc0Jhci5zaG93UHJvZ3Jlc3NCYXIoIG1lc3NhZ2VfaWQgKTtcblx0dmFyIHJlc19kYXRhID0ge307XG5cblx0aWYgKCBMb2NhbENhY2hlRGF0YS5nZXRJMThuRGljKCkgKSB7XG5cdFx0UHJvZ3Jlc3NCYXIucmVtb3ZlUHJvZ3Jlc3NCYXIoIG1lc3NhZ2VfaWQgKTtcblx0XHRyZXR1cm4gTG9jYWxDYWNoZURhdGEuZ2V0STE4bkRpYygpO1xuXHR9XG5cdHZhciByZWFsUGF0aCA9ICcuLi9sb2NhbGUvJyArIG5hbWUgKyAnL0xDX01FU1NBR0VTL21lc3NhZ2VzLmpzb24nICsgJz92PScgKyBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEuYXBwbGljYXRpb25fYnVpbGQ7XG5cblx0aWYgKCBHbG9iYWwudXJsX29mZnNldCApIHtcblx0XHRyZWFsUGF0aCA9IEdsb2JhbC51cmxfb2Zmc2V0ICsgcmVhbFBhdGg7XG5cdH1cblxuXHRqUXVlcnkuYWpheCgge1xuXHRcdGFzeW5jOiBmYWxzZSxcblx0XHR0eXBlOiAnR0VUJyxcblx0XHR1cmw6IHJlYWxQYXRoLFxuXHRcdGRhdGE6IG51bGwsXG5cdFx0Y2FjaGU6IHRydWUsXG5cdFx0Y29udmVydGVyczoge1xuXHRcdFx0Ly9CZWNhdXNlIHRoaXMgaXMgYSBkYXRhVHlwZTogc2NyaXB0LCBhbmQganF1ZXJ5IHdpbGwgYmxpbmR5IHRyeSB0byBldmFsKCkgYW55IHJlc3VsdCByZXR1cm5lZCBieSB0aGUgc2VydmVyLCBpbmNsdWRpbmcgYSBIVE1MIDQwNCBlcnJvciBtZXNzYWdlLlxuXHRcdFx0Ly8gcmVzdWx0aW5nIGluXCIgVW5jYXVnaHQgU3ludGF4RXJyb3I6IFVuZXhwZWN0ZWQgdG9rZW4gPCBpbiAgbGluZSAxXCIgYmVpbmcgdHJpZ2dlcmVkLlxuXHRcdFx0Ly8gSW5zdGVhZCBqdXN0IHJldHVybiB0aGUgcmF3IHJlc3VsdCBhbmQgZXZhbCgpIGl0IGluIHRoZSBzdWNjZXNzIGZ1bmN0aW9uIG91cnNlbHZlcyBpbnN0ZWFkLlxuXHRcdFx0J3RleHQgc2NyaXB0JzogZnVuY3Rpb24oIHRleHQgKSB7XG5cdFx0XHRcdHJldHVybiB0ZXh0O1xuXHRcdFx0fVxuXHRcdH0sXG5cdFx0c3VjY2VzczogZnVuY3Rpb24oIHJlc3VsdCApIHtcblx0XHRcdHN1Y2Nlc3NmbGFnID0gdHJ1ZTtcblx0XHRcdGpRdWVyeS5nbG9iYWxFdmFsKCByZXN1bHQgKTtcblx0XHR9LFxuXHRcdGVycm9yOiBmdW5jdGlvbigganFYSFIsIHRleHRTdGF0dXMsIGVycm9yVGhyb3duICkge1xuXHRcdFx0Ly9VbmFibGUgdG8gbG9hZCBvciBwYXJzZSBpMThuIGRpY3Rpb25hcnkuIENvdWxkIGJlIGR1ZSB0byBhIDQwNCBlcnJvcj9cblx0XHRcdERlYnVnLlRleHQoICdVbmFibGUgdG8gbG9hZCBMb2NhbGU6ICcgKyBlcnJvclRocm93biwgJ0dsb2JhbC5qcycsICcnLCAnbG9hZExhbmd1YWdlJywgMTAgKTtcblx0XHRcdHN1Y2Nlc3NmbGFnID0gZmFsc2U7XG5cdFx0fSxcblx0XHRkYXRhVHlwZTogJ3NjcmlwdCdcblx0fSApO1xuXG5cdFByb2dyZXNzQmFyLnJlbW92ZVByb2dyZXNzQmFyKCBtZXNzYWdlX2lkICk7XG5cblx0aWYgKCBzdWNjZXNzZmxhZyApIHtcblx0XHRMb2NhbENhY2hlRGF0YS5zZXRJMThuRGljKCBpMThuX2RpY3Rpb25hcnkgKTtcblx0fSBlbHNlIHtcblx0XHRMb2NhbENhY2hlRGF0YS5zZXRJMThuRGljKCB7fSApO1xuXHR9XG5cblx0cmV0dXJuIHN1Y2Nlc3NmbGFnO1xufTtcblxuR2xvYmFsLmdldFByb2R1Y3RFZGl0aW9uID0gZnVuY3Rpb24oKSB7XG5cdHZhciBjdXJyZW50X2NvbXBhbnlfZGF0YSA9IExvY2FsQ2FjaGVEYXRhLmdldEN1cnJlbnRDb21wYW55KCk7XG5cblx0aWYgKCBjdXJyZW50X2NvbXBhbnlfZGF0YSAmJiBjdXJyZW50X2NvbXBhbnlfZGF0YS5wcm9kdWN0X2VkaXRpb25faWQgKSB7XG5cdFx0cmV0dXJuIGN1cnJlbnRfY29tcGFueV9kYXRhLnByb2R1Y3RfZWRpdGlvbl9pZDtcblx0fVxuXG5cdHJldHVybiAxMDsgLy9Db21tdW5pdHlcbn07XG5cbkdsb2JhbC5zZXRVUkxUb0Jyb3dzZXIgPSBmdW5jdGlvbiggbmV3X3VybCApIHtcblx0aWYgKCBuZXdfdXJsICE9IHdpbmRvdy5sb2NhdGlvbi5ocmVmICkge1xuXHRcdERlYnVnLlRleHQoICdDaGFuZ2luZyBVUkwgdG86ICcgKyBuZXdfdXJsLCAnR2xvYmFsLmpzJywgJ0dsb2JhbCcsICdzZXRVUkxUb0Jyb3dzZXInLCA5ICk7XG5cdFx0d2luZG93LmxvY2F0aW9uID0gbmV3X3VybDtcblx0fVxufTtcblxuR2xvYmFsLmNsb25lID0gZnVuY3Rpb24oIG9iaiApIHtcblx0cmV0dXJuIGpRdWVyeS5leHRlbmQoIHRydWUsIHt9LCBvYmogKTsgLy8gdHJ1ZSBtZWFucyBkZWVwIGNsb25lLCBvbWl0IGZvciBzaGFsbG93LCBmYWxzZSBpcyBub3QgYW4gb3B0aW9uXG59O1xuXG5HbG9iYWwuZ2V0Rmlyc3RLZXlGcm9tT2JqZWN0ID0gZnVuY3Rpb24oIG9iaiApIHtcblx0Zm9yICggdmFyIGtleSBpbiBvYmogKSB7XG5cblx0XHRpZiAoIG9iai5oYXNPd25Qcm9wZXJ0eSgga2V5ICkgKSB7XG5cdFx0XHRyZXR1cm4ga2V5O1xuXHRcdH1cblxuXHR9XG59O1xuXG5HbG9iYWwuZ2V0RnVuY05hbWUgPSBmdW5jdGlvbiggX2NhbGxlZSApIHtcblx0dmFyIF90ZXh0ID0gX2NhbGxlZS50b1N0cmluZygpO1xuXHR2YXIgX3NjcmlwdEFyciA9IGRvY3VtZW50LnNjcmlwdHM7XG5cdGZvciAoIHZhciBpID0gMDsgaSA8IF9zY3JpcHRBcnIubGVuZ3RoOyBpKysgKSB7XG5cdFx0dmFyIF9zdGFydCA9IF9zY3JpcHRBcnJbaV0udGV4dC5pbmRleE9mKCBfdGV4dCApO1xuXHRcdGlmICggX3N0YXJ0ICE9PSAtMSApIHtcblx0XHRcdGlmICggL15mdW5jdGlvblxccypcXCguKlxcKS4qXFxyXFxuLy50ZXN0KCBfdGV4dCApICkge1xuXHRcdFx0XHR2YXIgX3RlbXBBcnIgPSBfc2NyaXB0QXJyW2ldLnRleHQuc3Vic3RyKCAwLCBfc3RhcnQgKS5zcGxpdCggJ1xcclxcbicgKTtcblx0XHRcdFx0cmV0dXJuIF90ZW1wQXJyWyggX3RlbXBBcnIubGVuZ3RoIC0gMSApXS5yZXBsYWNlKCAvKHZhcil8KFxccyopL2csICcnICkucmVwbGFjZSggLz0vZywgJycgKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHJldHVybiBfdGV4dC5tYXRjaCggL15mdW5jdGlvblxccyooW15cXChdKykuKlxcclxcbi8gKVsxXTtcblx0XHRcdH1cblx0XHR9XG5cdH1cbn07XG5cbkdsb2JhbC5jb25jYXRBcnJheXNVbmlxdWVXaXRoU29ydCA9IGZ1bmN0aW9uKCB0aGlzQXJyYXksIG90aGVyQXJyYXkgKSB7XG5cdHZhciBuZXdBcnJheSA9IHRoaXNBcnJheS5jb25jYXQoIG90aGVyQXJyYXkgKS5zb3J0KCBmdW5jdGlvbiggYSwgYiApIHtcblx0XHRyZXR1cm4gYSA+IGIgPyAxIDogYSA8IGIgPyAtMSA6IDA7XG5cdH0gKTtcblxuXHRyZXR1cm4gbmV3QXJyYXkuZmlsdGVyKCBmdW5jdGlvbiggaXRlbSwgaW5kZXggKSB7XG5cdFx0cmV0dXJuIG5ld0FycmF5LmluZGV4T2YoIGl0ZW0gKSA9PT0gaW5kZXg7XG5cdH0gKTtcbn07XG5cbkdsb2JhbC5hZGRDc3MgPSBmdW5jdGlvbiggcGF0aCwgY2FsbGJhY2sgKSB7XG5cdGlmICggTG9jYWxDYWNoZURhdGEubG9hZGVkU2NyaXB0TmFtZXNbcGF0aF0gKSB7XG5cdFx0aWYgKCBjYWxsYmFjayApIHtcblx0XHRcdGNhbGxiYWNrKCk7XG5cdFx0fVxuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cdExvY2FsQ2FjaGVEYXRhLmxvYWRlZFNjcmlwdE5hbWVzW3BhdGhdID0gdHJ1ZTtcblx0dmFyIHJlYWxQYXRoID0gJ3RoZW1lLycgKyBHbG9iYWwudGhlbWUgKyAnL2Nzcy8nICsgcGF0aDtcblx0aWYgKCBHbG9iYWwudXJsX29mZnNldCApIHtcblx0XHRyZWFsUGF0aCA9IEdsb2JhbC51cmxfb2Zmc2V0ICsgcmVhbFBhdGg7XG5cdH1cblx0cmVhbFBhdGggPSByZWFsUGF0aCArICc/dj0nICsgQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLmFwcGxpY2F0aW9uX2J1aWxkO1xuXHRHbG9iYWwubG9hZFN0eWxlU2hlZXQoIHJlYWxQYXRoLCBjYWxsYmFjayApO1xufTtcblxuLy9KUyB0aGluayAwIGlzIGZhbHNlLCBzbyB1c2UgdGhpcyB0byBnZXQgMCBjb3JyZWN0bHkuXG5HbG9iYWwuaXNGYWxzZU9yTnVsbCA9IGZ1bmN0aW9uKCBvYmplY3QgKSB7XG5cblx0aWYgKCBvYmplY3QgPT09IGZhbHNlIHx8IG9iamVjdCA9PT0gbnVsbCB8fCBvYmplY3QgPT09IDAgfHwgb2JqZWN0ID09PSAnMCcgfHwgb2JqZWN0ID09IFRUVVVJRC56ZXJvX2lkICkge1xuXHRcdHJldHVybiB0cnVlO1xuXHR9IGVsc2Uge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG59O1xuXG5HbG9iYWwuaXNTZXQgPSBmdW5jdGlvbiggb2JqZWN0ICkge1xuXG5cdGlmICggXy5pc1VuZGVmaW5lZCggb2JqZWN0ICkgfHwgXy5pc051bGwoIG9iamVjdCApICkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fSBlbHNlIHtcblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXG59O1xuXG5HbG9iYWwuZ2V0SWNvblBhdGhCeUNvbnRleHROYW1lID0gZnVuY3Rpb24oIGlkICkge1xuXG5cdHN3aXRjaCAoIGlkICkge1xuXHRcdGNhc2UgJ2FkZCc6XG5cdFx0XHRyZXR1cm4gR2xvYmFsLmdldFJlYWxJbWFnZVBhdGgoICdjc3MvZ2xvYmFsL3dpZGdldHMvcmliYm9uL2ljb25zL2NvcHktMzV4MzUucG5nJyApO1xuXHR9XG59O1xuXG5HbG9iYWwuaXNFbXB0eSA9IGZ1bmN0aW9uKCBvYmogKSB7XG5cblx0Ly8gbnVsbCBhbmQgdW5kZWZpbmVkIGFyZSBcImVtcHR5XCJcblx0aWYgKCBvYmogPT09IG51bGwgKSB7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblxuXHQvLyBBc3N1bWUgaWYgaXQgaGFzIGEgbGVuZ3RoIHByb3BlcnR5IHdpdGggYSBub24temVybyB2YWx1ZVxuXHQvLyB0aGF0IHRoYXQgcHJvcGVydHkgaXMgY29ycmVjdC5cblx0aWYgKCBvYmoubGVuZ3RoID4gMCApIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblx0aWYgKCBvYmoubGVuZ3RoID09PSAwICkge1xuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cblx0Ly8gT3RoZXJ3aXNlLCBkb2VzIGl0IGhhdmUgYW55IHByb3BlcnRpZXMgb2YgaXRzIG93bj9cblx0Ly8gTm90ZSB0aGF0IHRoaXMgZG9lc24ndCBoYW5kbGVcblx0Ly8gdG9TdHJpbmcgYW5kIHZhbHVlT2YgZW51bWVyYXRpb24gYnVncyBpbiBJRSA8IDlcblx0Zm9yICggdmFyIGtleSBpbiBvYmogKSB7XG5cdFx0aWYgKCBoYXNPd25Qcm9wZXJ0eS5jYWxsKCBvYmosIGtleSApICkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiB0cnVlO1xuXG59O1xuXG5HbG9iYWwuY29udmVydENvbHVtbnNUb2pHcmlkRm9ybWF0ID0gZnVuY3Rpb24oIGNvbHVtbnMsIGxheW91dF9uYW1lLCBzZXRXaWR0aENhbGxCYWNrICkge1xuXHR2YXIgY29sdW1uX2luZm9fYXJyYXkgPSBbXTtcblx0dmFyIGxlbiA9IGNvbHVtbnMubGVuZ3RoO1xuXG5cdHZhciB0b3RhbF93aWR0aCA9IDA7XG5cdGZvciAoIHZhciBpID0gMDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdHZhciB2aWV3X2NvbHVtbl9kYXRhID0gY29sdW1uc1tpXTtcblx0XHR2YXIgY29sdW1uX2luZm87XG5cblx0XHR2YXIgdGV4dF93aWR0aCA9IEdsb2JhbC5jYWxjdWxhdGVUZXh0V2lkdGgoIHZpZXdfY29sdW1uX2RhdGEubGFiZWwgKTtcblxuXHRcdHRvdGFsX3dpZHRoID0gdG90YWxfd2lkdGggKyB0ZXh0X3dpZHRoO1xuXG5cdFx0aWYgKCB2aWV3X2NvbHVtbl9kYXRhLmxhYmVsID09PSAnJyApIHtcblx0XHRcdGNvbHVtbl9pbmZvID0ge1xuXHRcdFx0XHRuYW1lOiB2aWV3X2NvbHVtbl9kYXRhLnZhbHVlLFxuXHRcdFx0XHRpbmRleDogdmlld19jb2x1bW5fZGF0YS52YWx1ZSxcblx0XHRcdFx0bGFiZWw6IHZpZXdfY29sdW1uX2RhdGEubGFiZWwsXG5cdFx0XHRcdGtleTogdHJ1ZSxcblx0XHRcdFx0d2lkdGg6IDEwMCxcblx0XHRcdFx0c29ydGFibGU6IGZhbHNlLFxuXHRcdFx0XHRoaWRkZW46IHRydWUsXG5cdFx0XHRcdHRpdGxlOiBmYWxzZVxuXHRcdFx0fTtcblx0XHR9IGVsc2UgaWYgKCBsYXlvdXRfbmFtZSA9PT0gJ2dsb2JhbF9zb3J0X2NvbHVtbnMnICkge1xuXG5cdFx0XHRpZiAoIHZpZXdfY29sdW1uX2RhdGEudmFsdWUgPT09ICdzb3J0JyApIHtcblx0XHRcdFx0Y29sdW1uX2luZm8gPSB7XG5cdFx0XHRcdFx0bmFtZTogdmlld19jb2x1bW5fZGF0YS52YWx1ZSxcblx0XHRcdFx0XHRpbmRleDogdmlld19jb2x1bW5fZGF0YS52YWx1ZSxcblx0XHRcdFx0XHRsYWJlbDogdmlld19jb2x1bW5fZGF0YS5sYWJlbCxcblx0XHRcdFx0XHR3aWR0aDogMTAwLFxuXHRcdFx0XHRcdHNvcnRhYmxlOiBmYWxzZSxcblx0XHRcdFx0XHRmb3JtYXR0ZXI6ICdzZWxlY3QnLFxuXHRcdFx0XHRcdGVkaXRhYmxlOiB0cnVlLFxuXHRcdFx0XHRcdHRpdGxlOiBmYWxzZSxcblx0XHRcdFx0XHRlZGl0dHlwZTogJ3NlbGVjdCcsXG5cdFx0XHRcdFx0ZWRpdG9wdGlvbnM6IHsgdmFsdWU6ICdhc2M6QVNDO2Rlc2M6REVTQycgfVxuXHRcdFx0XHR9O1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y29sdW1uX2luZm8gPSB7XG5cdFx0XHRcdFx0bmFtZTogdmlld19jb2x1bW5fZGF0YS52YWx1ZSxcblx0XHRcdFx0XHRpbmRleDogdmlld19jb2x1bW5fZGF0YS52YWx1ZSxcblx0XHRcdFx0XHRsYWJlbDogdmlld19jb2x1bW5fZGF0YS5sYWJlbCxcblx0XHRcdFx0XHR3aWR0aDogMTAwLFxuXHRcdFx0XHRcdHNvcnRhYmxlOiBmYWxzZSxcblx0XHRcdFx0XHR0aXRsZTogZmFsc2Vcblx0XHRcdFx0fTtcblx0XHRcdH1cblxuXHRcdH0gZWxzZSB7XG5cdFx0XHRjb2x1bW5faW5mbyA9IHtcblx0XHRcdFx0bmFtZTogdmlld19jb2x1bW5fZGF0YS52YWx1ZSxcblx0XHRcdFx0aW5kZXg6IHZpZXdfY29sdW1uX2RhdGEudmFsdWUsXG5cdFx0XHRcdGxhYmVsOiB2aWV3X2NvbHVtbl9kYXRhLmxhYmVsLFxuXHRcdFx0XHR3aWR0aDogMTAwLFxuXHRcdFx0XHRzb3J0YWJsZTogZmFsc2UsXG5cdFx0XHRcdHRpdGxlOiBmYWxzZVxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRjb2x1bW5faW5mb19hcnJheS5wdXNoKCBjb2x1bW5faW5mbyApO1xuXHR9XG5cblx0aWYgKCBzZXRXaWR0aENhbGxCYWNrICkge1xuXHRcdHNldFdpZHRoQ2FsbEJhY2soIHRvdGFsX3dpZHRoICk7XG5cdH1cblxuXHRyZXR1cm4gY29sdW1uX2luZm9fYXJyYXk7XG59O1xuLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuR2xvYmFsLmxvYWRXaWRnZXRCeU5hbWUgPSBmdW5jdGlvbiggd2lkZ2V0TmFtZSwgcmF3X3RleHQgKSB7XG5cdHZhciBpbnB1dCA9IGZhbHNlO1xuXHR2YXIgd2lkZ2V0X3BhdGggPSBmYWxzZTtcblx0dmFyIHdpZGdldF9jb25zdHJ1Y3RvciA9IGZhbHNlO1xuXHR2YXIgcmF3X3RleHQgPSBmYWxzZTtcblx0c3dpdGNoICggd2lkZ2V0TmFtZSApIHtcblx0XHRjYXNlIEZvcm1JdGVtVHlwZS5DT0xPUl9QSUNLRVI6XG5cdFx0XHRpbnB1dCA9ICQuZm4uVENvbG9yUGlja2VyLmh0bWxfdGVtcGxhdGU7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIEZvcm1JdGVtVHlwZS5GT1JNVUxBX0JVSUxERVI6XG5cdFx0XHRpbnB1dCA9ICQuZm4uRm9ybXVsYUJ1aWxkZXIuaHRtbF90ZW1wbGF0ZTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgRm9ybUl0ZW1UeXBlLkFXRVNPTUVfQk9YOlxuXHRcdFx0aW5wdXQgPSAkLmZuLkFDb21ib0JveC5odG1sX3RlbXBsYXRlO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBGb3JtSXRlbVR5cGUuQVdFU09NRV9EUk9QRE9XTjpcblx0XHRcdGlucHV0ID0gJC5mbi5BRHJvcERvd24uaHRtbF90ZW1wbGF0ZTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgRm9ybUl0ZW1UeXBlLlRFWFRfSU5QVVQ6XG5cdFx0XHRpbnB1dCA9ICQuZm4uVFRleHRJbnB1dC5odG1sX3RlbXBsYXRlO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBGb3JtSXRlbVR5cGUuUEFTU1dPUkRfSU5QVVQ6XG5cdFx0XHRpbnB1dCA9ICQuZm4uVFBhc3N3b3JkSW5wdXQuaHRtbF90ZW1wbGF0ZTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgRm9ybUl0ZW1UeXBlLlRFWFQ6XG5cdFx0XHRpbnB1dCA9ICQuZm4uVFRleHQuaHRtbF90ZW1wbGF0ZTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgRm9ybUl0ZW1UeXBlLkNIRUNLQk9YOlxuXHRcdFx0aW5wdXQgPSAkLmZuLlRDaGVja2JveC5odG1sX3RlbXBsYXRlO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBGb3JtSXRlbVR5cGUuQ09NQk9fQk9YOlxuXHRcdFx0aW5wdXQgPSAkLmZuLlRDb21ib0JveC5odG1sX3RlbXBsYXRlO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBGb3JtSXRlbVR5cGUuTElTVDogLy9Eb2VzIG5vdCBzZWVtIHRvIGJlIHVzZWQgYW55d2hlcmUuXG5cdFx0XHRpbnB1dCA9ICQuZm4uVExpc3QuaHRtbF90ZW1wbGF0ZTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgRm9ybUl0ZW1UeXBlLlRBR19JTlBVVDpcblx0XHRcdGlucHV0ID0gJC5mbi5UVGFnSW5wdXQuaHRtbF90ZW1wbGF0ZTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgRm9ybUl0ZW1UeXBlLkRBVEVfUElDS0VSOlxuXHRcdGNhc2UgRm9ybUl0ZW1UeXBlLlJBTkdFX1BJQ0tFUjpcblx0XHRcdGlucHV0ID0gJC5mbi5URGF0ZVBpY2tlci5odG1sX3RlbXBsYXRlO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBGb3JtSXRlbVR5cGUuVElNRV9QSUNLRVI6XG5cdFx0XHRpbnB1dCA9ICQuZm4uVFRpbWVQaWNrZXIuaHRtbF90ZW1wbGF0ZTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgRm9ybUl0ZW1UeXBlLlRFWFRfQVJFQTpcblx0XHRcdGlucHV0ID0gJC5mbi5UVGV4dEFyZWEuaHRtbF90ZW1wbGF0ZTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgRm9ybUl0ZW1UeXBlLlRJTllNQ0VfVEVYVF9BUkVBOlxuXHRcdFx0aW5wdXQgPSAkLmZuLlRUZXh0QXJlYS50aW55bWNlX2h0bWxfdGVtcGxhdGU7XG5cdFx0XHRyYXdfdGV4dCA9IHRydWU7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIEZvcm1JdGVtVHlwZS5TRVBBUkFURURfQk9YOlxuXHRcdFx0aW5wdXQgPSAkLmZuLlNlcGFyYXRlZEJveC5odG1sX3RlbXBsYXRlO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBGb3JtSXRlbVR5cGUuSU1BR0VfQlJPV1NFUjpcblx0XHRcdGlucHV0ID0gJC5mbi5USW1hZ2VCcm93c2VyLmh0bWxfdGVtcGxhdGU7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIEZvcm1JdGVtVHlwZS5GSUxFX0JST1dTRVI6IC8vVGhlcmUgaXMgbm8gZmlsZSBicm93c2VyIEpTIGZpbGUgZm9yIHRoaXMgd2lkZ2V0LlxuXHRcdFx0aW5wdXQgPSBgPGRpdiBjbGFzcz1cImZpbGUtYnJvd3NlclwiPlxuXHRcdFx0XHRcdFx0PGZvcm0gZW5jdHlwZT1cIm11bHRpcGFydC9mb3JtLWRhdGFcIiBjbGFzcz1cImJyb3dzZXItZm9ybVwiPlxuXHRcdFx0XHRcdFx0XHQ8aW5wdXQgbmFtZT1cImZpbGVkYXRhXCIgY2xhc3M9XCJicm93c2VyXCIgdHlwZT1cImZpbGVcIi8+XG5cdFx0XHRcdFx0XHQ8L2Zvcm0+XG5cdFx0XHRcdFx0PC9kaXY+YDtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgRm9ybUl0ZW1UeXBlLklNQUdFX0FWRF9CUk9XU0VSOlxuXHRcdFx0aW5wdXQgPSAkLmZuLlRJbWFnZUFkdkJyb3dzZXIuaHRtbF90ZW1wbGF0ZTtcblx0XHRcdHdpZGdldF9jb25zdHJ1Y3RvciA9ICdUSW1hZ2VBZHZCcm93c2VyJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgRm9ybUl0ZW1UeXBlLkNBTUVSQV9CUk9XU0VSOlxuXHRcdFx0aW5wdXQgPSAkLmZuLkNhbWVyYUJyb3dzZXIuaHRtbF90ZW1wbGF0ZTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgRm9ybUl0ZW1UeXBlLklNQUdFX0NVVDpcblx0XHRcdGlucHV0ID0gJC5mbi5USW1hZ2VDdXRBcmVhLmh0bWxfdGVtcGxhdGU7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIEZvcm1JdGVtVHlwZS5JTUFHRTpcblx0XHRcdGlucHV0ID0gJzxpbWcgY2xhc3M9XFwndC1pbWFnZVxcJz4nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBGb3JtSXRlbVR5cGUuSU5TSURFX0VESVRPUjpcblx0XHRcdGlucHV0ID0gJC5mbi5JbnNpZGVFZGl0b3IuaHRtbF90ZW1wbGF0ZTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgV2lkZ2V0TmFtZXNEaWMuUEFHSU5HOlxuXHRcdFx0Ly8gd2lkZ2V0X3BhdGggPSAnZ2xvYmFsL3dpZGdldHMvcGFnaW5nL1BhZ2luZy5odG1sJzsgLy8gVE9ETzogIzMwMjM6IERlbGV0ZSB0aGlzIGxpbmUgb25jZSBhbGwgd2lkZ2V0IGh0bWwgY29udmVydGVkIGFuZCBubyBsb25nZXIgbmVlZCB0aGlzIHF1aWNrIHJlZmVyZW5jZSBmb3IgdGhlIG9sZCBmb3JtYXQuXG5cdFx0XHRpbnB1dCA9ICQuZm4uUGFnaW5nMi5odG1sLnBhZ2luZztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgV2lkZ2V0TmFtZXNEaWMuUEFHSU5HXzI6XG5cdFx0XHQvLyB3aWRnZXRfcGF0aCA9ICdnbG9iYWwvd2lkZ2V0cy9wYWdpbmcvUGFnaW5nMi5odG1sJzsgLy8gVE9ETzogIzMwMjM6IERlbGV0ZSB0aGlzIGxpbmUgb25jZSBhbGwgd2lkZ2V0IGh0bWwgY29udmVydGVkIGFuZCBubyBsb25nZXIgbmVlZCB0aGlzIHF1aWNrIHJlZmVyZW5jZSBmb3IgdGhlIG9sZCBmb3JtYXQuXG5cdFx0XHRpbnB1dCA9ICQuZm4uUGFnaW5nMi5odG1sLnBhZ2luZzI7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIFdpZGdldE5hbWVzRGljLkVSUk9SX1RPT0xUSVA6XG5cdFx0XHRpbnB1dCA9ICQuZm4uRXJyb3JUaXBCb3guaHRtbF90ZW1wbGF0ZTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgRm9ybUl0ZW1UeXBlLkZFRURCQUNLX0JPWDpcblx0XHRcdGlucHV0ID0gJC5mbi5URmVlZGJhY2suaHRtbF90ZW1wbGF0ZTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgV2lkZ2V0TmFtZXNEaWMuRURJVF9WSUVXX0ZPUk1fSVRFTTogLy9UaGVyZSBpcyBubyBmaWxlIGJyb3dzZXIgSlMgZmlsZSBmb3IgdGhpcyB3aWRnZXQuXG5cdFx0XHRpbnB1dCA9IGBcblx0XHRcdDxkaXYgY2xhc3M9XCJlZGl0LXZpZXctZm9ybS1pdGVtLWRpdlwiPlxuXHRcdFx0XHQ8ZGl2IGNsYXNzPVwiZWRpdC12aWV3LWZvcm0taXRlbS1sYWJlbC1kaXZcIj48c3BhbiBjbGFzcz1cImVkaXQtdmlldy1mb3JtLWl0ZW0tbGFiZWxcIj48L3NwYW4+PC9kaXY+XG5cdFx0XHRcdDxkaXYgY2xhc3M9XCJlZGl0LXZpZXctZm9ybS1pdGVtLWlucHV0LWRpdlwiPjwvZGl2PlxuXHRcdFx0PC9kaXY+YDtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgV2lkZ2V0TmFtZXNEaWMuRURJVF9WSUVXX1NVQl9GT1JNX0lURU06IC8vVGhlcmUgaXMgbm8gZmlsZSBicm93c2VyIEpTIGZpbGUgZm9yIHRoaXMgd2lkZ2V0LlxuXHRcdFx0aW5wdXQgPSBgXG5cdFx0XHQ8ZGl2IGNsYXNzPVwiZWRpdC12aWV3LWZvcm0taXRlbS1kaXZcIj5cblx0XHRcdFx0PGRpdiBjbGFzcz1cImVkaXQtdmlldy1mb3JtLWl0ZW0tc3ViLWxhYmVsLWRpdlwiPjxzcGFuIGNsYXNzPVwiZWRpdC12aWV3LWZvcm0taXRlbS1sYWJlbFwiPjwvc3Bhbj48L2Rpdj5cblx0XHRcdFx0PGRpdiBjbGFzcz1cImVkaXQtdmlldy1mb3JtLWl0ZW0taW5wdXQtZGl2XCI+PC9kaXY+XG5cdFx0XHQ8L2Rpdj5gO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBXaWRnZXROYW1lc0RpYy5OT19SRVNVTFRfQk9YOlxuXHRcdFx0aW5wdXQgPSAkLmZuLk5vUmVzdWx0Qm94Lmh0bWxfdGVtcGxhdGU7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIFdpZGdldE5hbWVzRGljLlZJRVdfTUlOX1RBQjpcblx0XHRcdGlucHV0ID0gJC5mbi5WaWV3TWluVGFiQmFyLmh0bWwudGFiO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBXaWRnZXROYW1lc0RpYy5WSUVXX01JTl9UQUJfQkFSOlxuXHRcdFx0aW5wdXQgPSAkLmZuLlZpZXdNaW5UYWJCYXIuaHRtbC50YWJfYmFyO1xuXHRcdFx0YnJlYWs7XG5cdH1cblxuXHRpZiAoIHdpZGdldF9wYXRoICE9IGZhbHNlICkge1xuXHRcdGlucHV0ID0gR2xvYmFsLmxvYWRXaWRnZXQoIHdpZGdldF9wYXRoICk7XG5cdH1cblxuXHRpZiAoIGlucHV0ICYmIHJhd190ZXh0ID09IHRydWUgKSB7XG5cdFx0cmV0dXJuIGlucHV0O1xuXHR9IGVsc2Uge1xuXHRcdC8vIzI1NzEgLSBFcnJvcjogVW5hYmxlIHRvIGdldCBwcm9wZXJ0eSAnaW5kZXhPZicgb2YgdW5kZWZpbmVkIG9yIG51bGwgcmVmZXJlbmNlXG5cdFx0aWYgKCBpbnB1dCAmJiBpbnB1dC5pbmRleE9mKCAnPCcgKSAhPSAtMSApIHtcblx0XHRcdGlmICggIXJhd190ZXh0ICkge1xuXHRcdFx0XHRpbnB1dCA9ICQoIGlucHV0ICk7XG5cblx0XHRcdFx0aWYgKCB3aWRnZXRfY29uc3RydWN0b3IgJiYgIWlucHV0W3dpZGdldF9jb25zdHJ1Y3Rvcl0gKSB7XG5cdFx0XHRcdFx0dmFyIGVycm9yX3N0cmluZyA9ICQuaTE4bi5fKCAnQ2xhc3MgY291bGQgbm90IGJlIGZvdW5kIGZvcicgKSArICc6ICcgKyB3aWRnZXROYW1lICsgJy4gJyArICQuaTE4bi5fKCAnQ2hlY2sgdGhhdCBjbGFzcyBpcyBwcm9wZXJseSByZXF1aXJlZC4nICk7XG5cdFx0XHRcdFx0dGhyb3coIG5ldyBFcnJvciggZXJyb3Jfc3RyaW5nICkgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHQvL1NlZSBjb21tZW50IGluIEdsb2JhbC5sb2FkV2lkZ2V0KCkgcmVnYXJkaW5nIHJldHVybiBudWxsIHJldHVybiB2YWx1ZXMuXG5cdFx0XHR2YXIgZXJyb3Jfc3RyaW5nID0gJC5pMThuLl8oICdOZXR3b3JrIGVycm9yLCBmYWlsZWQgdG8gbG9hZCcgKSArICc6ICcgKyB3aWRnZXROYW1lICsgJyAnICsgJC5pMThuLl8oICdSZXN1bHQnICkgKyAnOiBcIicgKyBpbnB1dCArICdcIic7XG5cdFx0XHRUQWxlcnRNYW5hZ2VyLnNob3dOZXR3b3JrRXJyb3JBbGVydCggeyBzdGF0dXM6IDk5OSB9LCBlcnJvcl9zdHJpbmcsIG51bGwgKTsgLy9TaG93IHRoZSB1c2VyIGFuIGVycm9yIHBvcG91cC5cblx0XHRcdHRocm93KCBuZXcgRXJyb3IoIGVycm9yX3N0cmluZyApICk7IC8vSGFsdCBleGVjdXRpb24gYW5kIGVuc3VyZSB0aGF0IHRoZSBlbWFpbCBoYXMgYSBnb29kIGVycm9yIG1lc3NhZ2UgYmVjYXVzZSBvZiBmYWlsdXJlIG9mIHdlYiBzZXJ2ZXIgdG8gcHJvdmlkZSB0aGUgcmVxdWVzdGVkIGZpbGUuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIGlucHV0O1xuXHR9XG59O1xuXG4vKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuXG5HbG9iYWwubG9hZFdpZGdldCA9IGZ1bmN0aW9uKCB1cmwgKSB7XG5cdGlmICggTG9jYWxDYWNoZURhdGEubG9hZGVkV2lkZ2V0Q2FjaGVbdXJsXSApIHtcblx0XHRyZXR1cm4gKCBMb2NhbENhY2hlRGF0YS5sb2FkZWRXaWRnZXRDYWNoZVt1cmxdICk7XG5cdH1cblxuXHR2YXIgcmVhbFBhdGggPSB1cmwgKyAnP3Y9JyArIEFQSUdsb2JhbC5wcmVfbG9naW5fZGF0YS5hcHBsaWNhdGlvbl9idWlsZDtcblxuXHRpZiAoIEdsb2JhbC51cmxfb2Zmc2V0ICkge1xuXHRcdHJlYWxQYXRoID0gR2xvYmFsLnVybF9vZmZzZXQgKyByZWFsUGF0aDtcblx0fVxuXG5cdHZhciBtZXNzYWdlX2lkID0gVFRVVUlELmdlbmVyYXRlVVVJRCgpO1xuXHRQcm9ncmVzc0Jhci5zaG93UHJvZ3Jlc3NCYXIoIG1lc3NhZ2VfaWQgKTtcblx0dmFyIHN1Y2Nlc3NmbGFnID0gZmFsc2U7XG5cdHZhciByZXNwb25zZURhdGEgPSAkLmFqYXgoIHtcblx0XHRhc3luYzogZmFsc2UsXG5cdFx0dHlwZTogJ0dFVCcsXG5cdFx0dXJsOiByZWFsUGF0aCxcblx0XHRkYXRhOiBudWxsLFxuXHRcdGNhY2hlOiB0cnVlLFxuXHRcdHN1Y2Nlc3M6IGZ1bmN0aW9uKCkge1xuXHRcdFx0c3VjY2Vzc2ZsYWcgPSB0cnVlO1xuXHRcdH0sXG5cdFx0ZXJyb3I6IGZ1bmN0aW9uKCBqcVhIUiwgdGV4dFN0YXR1cywgZXJyb3JUaHJvd24gKSB7XG5cdFx0XHRUQWxlcnRNYW5hZ2VyLnNob3dOZXR3b3JrRXJyb3JBbGVydCgganFYSFIsIHRleHRTdGF0dXMsIGVycm9yVGhyb3duICk7XG5cdFx0fVxuXHR9ICk7XG5cblx0UHJvZ3Jlc3NCYXIucmVtb3ZlUHJvZ3Jlc3NCYXIoIG1lc3NhZ2VfaWQgKTtcblx0Ly9FcnJvcjogVW5jYXVnaHQgUmVmZXJlbmNlRXJyb3I6IHJlc3BvbnNlVGV4dCBpcyBub3QgZGVmaW5lZCBpbiBpbnRlcmZhY2UvaHRtbDUvZ2xvYmFsL0dsb2JhbC5qcz92PTkuMC4yLTIwMTUxMTA2LTA5MjE0NyBsaW5lIDE3NDdcblx0Ly8gIFVwb24gZnVydGhlciBpbnZlc3RpZ2F0aW9uIChJUkMgZGlzY3Vzc2lvbnMgb24gI2pRdWVyeSkgaXQgd2FzIHN1Z2dlc3RlZCB0byBzdG9wIHVzaW5nICdhc3luYzogZmFsc2UnIGFzIHRoYXQgY291bGQgYmUgd2hhdHMgY2F1c2luZyBhIG51bGwgcmV0dXJuIHZhbHVlIHdoZW4gd2UgYXJlIGV4cGVjdGluZyBhIGpxWEhSIG9iamVjdC5cblx0Ly8gIFNpbmNlIHRoZSB1bHRpbWF0ZSBnb2FsIGlzIHRvIHJlZmFjdG9yIHRoaW5ncyBzbyAuaHRtbCBpcyBlbWJlZGRlZCBpbiB0aGUgLmpzIGZpbGVzIGFueXdheXMsIG1heSBhcyB3ZWxsIGp1c3Qgd2FpdCBmb3IgdGhhdC5cblx0aWYgKCAhcmVzcG9uc2VEYXRhICkge1xuXHRcdHJldHVybiBudWxsO1xuXHR9IGVsc2Uge1xuXHRcdExvY2FsQ2FjaGVEYXRhLmxvYWRlZFdpZGdldENhY2hlW3VybF0gPSByZXNwb25zZURhdGEucmVzcG9uc2VUZXh0O1xuXHRcdHJldHVybiAoIHJlc3BvbnNlRGF0YS5yZXNwb25zZVRleHQgKTtcblx0fVxuXG59O1xuXG5HbG9iYWwucmVtb3ZlQ3NzID0gZnVuY3Rpb24oIHBhdGggKSB7XG5cdHZhciByZWFsUGF0aCA9ICd0aGVtZS8nICsgR2xvYmFsLnRoZW1lICsgJy9jc3MvJyArIHBhdGg7XG5cblx0aWYgKCBHbG9iYWwudXJsX29mZnNldCApIHtcblx0XHRyZWFsUGF0aCA9IEdsb2JhbC51cmxfb2Zmc2V0ICsgcmVhbFBhdGg7XG5cdH1cblxuXHQkKCAnbGlua1tocmVmPVxcJ1xcJyArIHJlYWxQYXRoICsgXFwnP3Y9XFwnICsgQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLmFwcGxpY2F0aW9uX2J1aWxkICsgXFwnXFwnXScgKS5yZW1vdmUoKTtcbn07XG5cbi8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cblxuR2xvYmFsLmdldFZpZXdQYXRoQnlWaWV3SWQgPSBmdW5jdGlvbiggdmlld0lkICkge1xuXHR2YXIgcGF0aDtcblx0c3dpdGNoICggdmlld0lkICkge1xuXHRcdC8vUmVjcnVpdG1lbnQgUG9ydGFsXG5cdFx0Y2FzZSAnR3JpZFRlc3QnOlxuXHRcdGNhc2UgJ1dpZGdldFRlc3QnOlxuXHRcdGNhc2UgJ0F3ZXNvbWVib3hUZXN0Jzpcblx0XHRcdHBhdGggPSAndmlld3MvZGV2ZWxvcGVyX3Rvb2xzLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdNeVByb2ZpbGUnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9wb3J0YWwvaHIvbXlfcHJvZmlsZS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnTXlKb2JBcHBsaWNhdGlvbic6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3BvcnRhbC9oci9teV9qb2JhcHBsaWNhdGlvbi8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnTXlQcm9maWxlRW1wbG95bWVudCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3BvcnRhbC9oci9teV9wcm9maWxlLyc7XG5cdFx0XHRicmVhaztcblxuXHRcdGNhc2UgJ01hcCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2F0dGVuZGFuY2UvbWFwLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdNYW51YWxUaW1lU2hlZXQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9hdHRlbmRhbmNlL21hbnVhbF90aW1lc2hlZXQvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0hvbWUnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9ob21lL2Rhc2hib2FyZC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUG9ydGFsSm9iVmFjYW5jeURldGFpbCc6XG5cdFx0Y2FzZSAnUG9ydGFsSm9iVmFjYW5jeSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3BvcnRhbC9oci9yZWNydWl0bWVudC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUG9ydGFsTG9naW4nOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9wb3J0YWwvbG9naW4vJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1F1aWNrUHVuY2hMb2dpbic6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3F1aWNrX3B1bmNoL2xvZ2luLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdRdWlja1B1bmNoJzpcblx0XHRcdHBhdGggPSAndmlld3MvcXVpY2tfcHVuY2gvcHVuY2gvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1VzZXJEYXRlVG90YWxQYXJlbnQnOlxuXHRcdGNhc2UgJ1VzZXJEYXRlVG90YWwnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9hdHRlbmRhbmNlL3RpbWVzaGVldC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUHJvZHVjdCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2ludm9pY2UvcHJvZHVjdHMvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0ludm9pY2VEaXN0cmljdCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2ludm9pY2UvZGlzdHJpY3QvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1BheW1lbnRHYXRld2F5Jzpcblx0XHRcdHBhdGggPSAndmlld3MvaW52b2ljZS9wYXltZW50X2dhdGV3YXkvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0ludm9pY2VDb25maWcnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9pbnZvaWNlL3NldHRpbmdzLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdTaGlwcGluZ1BvbGljeSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2ludm9pY2Uvc2hpcHBpbmdfcG9saWN5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBcmVhUG9saWN5Jzpcblx0XHRcdHBhdGggPSAndmlld3MvaW52b2ljZS9hcmVhX3BvbGljeS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnVGF4UG9saWN5Jzpcblx0XHRcdHBhdGggPSAndmlld3MvaW52b2ljZS90YXhfcG9saWN5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdDbGllbnRHcm91cCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2ludm9pY2UvY2xpZW50X2dyb3VwLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdQcm9kdWN0R3JvdXAnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9pbnZvaWNlL3Byb2R1Y3RfZ3JvdXAvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0V4Y2VwdGlvbic6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2F0dGVuZGFuY2UvZXhjZXB0aW9ucy8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnRW1wbG95ZWUnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9lbXBsb3llZXMvZW1wbG95ZWUvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1JlbWl0dGFuY2VEZXN0aW5hdGlvbkFjY291bnQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9lbXBsb3llZXMvcmVtaXR0YW5jZV9kZXN0aW5hdGlvbl9hY2NvdW50Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdXYWdlJzpcblx0XHRcdHBhdGggPSAndmlld3MvY29tcGFueS93YWdlLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdMb2dpbic6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2xvZ2luLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdUaW1lU2hlZXQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9hdHRlbmRhbmNlL3RpbWVzaGVldC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnSW5PdXQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9hdHRlbmRhbmNlL2luX291dC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUmVjdXJyaW5nU2NoZWR1bGVDb250cm9sJzpcblx0XHRcdHBhdGggPSAndmlld3MvYXR0ZW5kYW5jZS9yZWN1cnJpbmdfc2NoZWR1bGVfY29udHJvbC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUmVjdXJyaW5nU2NoZWR1bGVUZW1wbGF0ZUNvbnRyb2wnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9hdHRlbmRhbmNlL3JlY3VycmluZ19zY2hlZHVsZV90ZW1wbGF0ZV9jb250cm9sLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdTY2hlZHVsZVNoaWZ0Jzpcblx0XHRjYXNlICdTY2hlZHVsZSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2F0dGVuZGFuY2Uvc2NoZWR1bGUvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FjY3J1YWwnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9hdHRlbmRhbmNlL2FjY3J1YWwvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FjY3J1YWxCYWxhbmNlJzpcblx0XHRcdHBhdGggPSAndmlld3MvYXR0ZW5kYW5jZS9hY2NydWFsX2JhbGFuY2UvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1B1bmNoZXMnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9hdHRlbmRhbmNlL3B1bmNoZXMvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1B1bmNoVGFnR3JvdXAnOlxuXHRcdGNhc2UgJ1B1bmNoVGFnJzpcblx0XHRcdHBhdGggPSAndmlld3MvYXR0ZW5kYW5jZS9wdW5jaF90YWcvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0pvYkdyb3VwJzpcblx0XHRjYXNlICdKb2InOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9hdHRlbmRhbmNlL2pvYi8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnSm9iSXRlbUdyb3VwJzpcblx0XHRjYXNlICdKb2JJdGVtJzpcblx0XHRcdHBhdGggPSAndmlld3MvYXR0ZW5kYW5jZS9qb2JfaXRlbS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnSm9iSXRlbUFtZW5kbWVudCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2F0dGVuZGFuY2Uvam9iX2l0ZW1fYW1lbmRtZW50Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdVc2VyVGl0bGUnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9lbXBsb3llZXMvdXNlcl90aXRsZS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnVXNlckNvbnRhY3QnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9lbXBsb3llZXMvdXNlcl9jb250YWN0Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdVc2VyUHJlZmVyZW5jZSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2VtcGxveWVlcy91c2VyX3ByZWZlcmVuY2UvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1VzZXJHcm91cCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2VtcGxveWVlcy91c2VyX2dyb3VwLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdMb2cnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9jb3JlL2xvZy8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnVXNlckRlZmF1bHQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9lbXBsb3llZXMvdXNlcl9kZWZhdWx0Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdST0UnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9lbXBsb3llZXMvcm9lLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdDb21wYW55Jzpcblx0XHRcdHBhdGggPSAndmlld3MvY29tcGFueS9jb21wYW55Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdDb21wYW5pZXMnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9jb21wYW55L2NvbXBhbmllcy8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUGF5UGVyaW9kU2NoZWR1bGUnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9wYXlwZXJpb2QvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1BheVBlcmlvZHMnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9wYXlyb2xsL3BheV9wZXJpb2RzLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdMZWdhbEVudGl0eSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2NvbXBhbnkvbGVnYWxfZW50aXR5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdQYXlyb2xsUmVtaXR0YW5jZUFnZW5jeUV2ZW50Jzpcblx0XHRjYXNlICdQYXlyb2xsUmVtaXR0YW5jZUFnZW5jeSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2NvbXBhbnkvcGF5cm9sbF9yZW1pdHRhbmNlX2FnZW5jeS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUmVtaXR0YW5jZVNvdXJjZUFjY291bnQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9jb21wYW55L3JlbWl0dGFuY2Vfc291cmNlX2FjY291bnQvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0JyYW5jaCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2NvbXBhbnkvYnJhbmNoLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdHRU9GZW5jZSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2NvbXBhbnkvZ2VvX2ZlbmNlLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdEZXBhcnRtZW50Jzpcblx0XHRcdHBhdGggPSAndmlld3MvY29tcGFueS9kZXBhcnRtZW50Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdIaWVyYXJjaHlDb250cm9sJzpcblx0XHRcdHBhdGggPSAndmlld3MvY29tcGFueS9oaWVyYXJjaHlfY29udHJvbC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnV2FnZUdyb3VwJzpcblx0XHRcdHBhdGggPSAndmlld3MvY29tcGFueS93YWdlX2dyb3VwLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdFdGhuaWNHcm91cCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2NvbXBhbnkvZXRobmljX2dyb3VwLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdDdXJyZW5jeSc6XG5cdFx0Y2FzZSAnQ3VycmVuY3lSYXRlJzpcblx0XHRcdHBhdGggPSAndmlld3MvY29tcGFueS9jdXJyZW5jeS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUGVybWlzc2lvbkNvbnRyb2wnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9jb21wYW55L3Blcm1pc3Npb25fY29udHJvbC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQ3VzdG9tRmllbGQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9jb21wYW55L2N1c3RvbV9maWVsZC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnU3RhdGlvbic6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2NvbXBhbnkvc3RhdGlvbi8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUGF5U3R1Yic6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3BheXJvbGwvcGF5X3N0dWIvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1BheVN0dWJUcmFuc2FjdGlvbic6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3BheXJvbGwvcGF5X3N0dWJfdHJhbnNhY3Rpb24vJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0dvdmVybm1lbnREb2N1bWVudCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3BheXJvbGwvZ292ZXJubWVudF9kb2N1bWVudC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUmVxdWVzdCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL215X2FjY291bnQvcmVxdWVzdC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQ2hhbmdlUGFzc3dvcmQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9teV9hY2NvdW50L3Bhc3N3b3JkLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdSZXF1ZXN0QXV0aG9yaXphdGlvbic6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL215X2FjY291bnQvcmVxdWVzdF9hdXRob3JpemF0aW9uLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdUaW1lU2hlZXRBdXRob3JpemF0aW9uJzpcblx0XHRcdHBhdGggPSAndmlld3MvbXlfYWNjb3VudC90aW1lc2hlZXRfYXV0aG9yaXphdGlvbi8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnTWVzc2FnZUNvbnRyb2wnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9teV9hY2NvdW50L21lc3NhZ2VfY29udHJvbC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnTm90aWZpY2F0aW9uJzpcblx0XHRcdHBhdGggPSAndmlld3MvbXlfYWNjb3VudC9ub3RpZmljYXRpb24vJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0xvZ2luVXNlckNvbnRhY3QnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9teV9hY2NvdW50L3VzZXJfY29udGFjdC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnTG9naW5Vc2VyUHJlZmVyZW5jZSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL215X2FjY291bnQvdXNlcl9wcmVmZXJlbmNlLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdMb2dpblVzZXJFeHBlbnNlJzpcblx0XHRjYXNlICdFeHBlbnNlQXV0aG9yaXphdGlvbic6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL215X2FjY291bnQvZXhwZW5zZS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUGF5U3R1YkFtZW5kbWVudCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3BheXJvbGwvcGF5X3N0dWJfYW1lbmRtZW50Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdSZWN1cnJpbmdQYXlTdHViQW1lbmRtZW50Jzpcblx0XHRcdHBhdGggPSAndmlld3MvcGF5cm9sbC9yZWN1cnJpbmdfcGF5X3N0dWJfYW1lbmRtZW50Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdQYXlTdHViRW50cnlBY2NvdW50Jzpcblx0XHRcdHBhdGggPSAndmlld3MvcGF5cm9sbC9wYXlfc3R1Yl9lbnRyeV9hY2NvdW50Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdDb21wYW55VGF4RGVkdWN0aW9uJzpcblx0XHRcdHBhdGggPSAndmlld3MvcGF5cm9sbC9jb21wYW55X3RheF9kZWR1Y3Rpb24vJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1VzZXJFeHBlbnNlJzpcblx0XHRcdHBhdGggPSAndmlld3MvcGF5cm9sbC91c2VyX2V4cGVuc2UvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1BvbGljeUdyb3VwJzpcblx0XHRcdHBhdGggPSAndmlld3MvcG9saWN5L3BvbGljeV9ncm91cC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUGF5Q29kZSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3BvbGljeS9wYXlfY29kZS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUGF5Rm9ybXVsYVBvbGljeSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3BvbGljeS9wYXlfZm9ybXVsYV9wb2xpY3kvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0NvbnRyaWJ1dGluZ1BheUNvZGVQb2xpY3knOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9wb2xpY3kvY29udHJpYnV0aW5nX3BheV9jb2RlX3BvbGljeS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQ29udHJpYnV0aW5nU2hpZnRQb2xpY3knOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9wb2xpY3kvY29udHJpYnV0aW5nX3NoaWZ0X3BvbGljeS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUm91bmRJbnRlcnZhbFBvbGljeSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3BvbGljeS9yb3VuZF9pbnRlcnZhbF9wb2xpY3kvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ01lYWxQb2xpY3knOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9wb2xpY3kvbWVhbF9wb2xpY3kvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0JyZWFrUG9saWN5Jzpcblx0XHRcdHBhdGggPSAndmlld3MvcG9saWN5L2JyZWFrX3BvbGljeS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUmVndWxhclRpbWVQb2xpY3knOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9wb2xpY3kvcmVndWxhcl90aW1lX3BvbGljeS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnRXhwZW5zZVBvbGljeSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3BvbGljeS9leHBlbnNlX3BvbGljeS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnT3ZlcnRpbWVQb2xpY3knOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9wb2xpY3kvb3ZlcnRpbWVfcG9saWN5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBYnNlbmNlUG9saWN5Jzpcblx0XHRcdHBhdGggPSAndmlld3MvcG9saWN5L2Fic2VuY2VfcG9saWN5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdQcmVtaXVtUG9saWN5Jzpcblx0XHRcdHBhdGggPSAndmlld3MvcG9saWN5L3ByZW1pdW1fcG9saWN5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdFeGNlcHRpb25Qb2xpY3lDb250cm9sJzpcblx0XHRcdHBhdGggPSAndmlld3MvcG9saWN5L2V4Y2VwdGlvbl9wb2xpY3kvJztcblx0XHRcdGJyZWFrO1xuXG5cdFx0Y2FzZSAnUmVjdXJyaW5nSG9saWRheSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3BvbGljeS9yZWN1cnJpbmdfaG9saWRheS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnSG9saWRheVBvbGljeSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3BvbGljeS9ob2xpZGF5X3BvbGljeS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnSG9saWRheSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3BvbGljeS9ob2xpZGF5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdTY2hlZHVsZVBvbGljeSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3BvbGljeS9zY2hlZHVsZV9wb2xpY3kvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FjY3J1YWxQb2xpY3knOlxuXHRcdGNhc2UgJ0FjY3J1YWxQb2xpY3lBY2NvdW50Jzpcblx0XHRjYXNlICdBY2NydWFsUG9saWN5VXNlck1vZGlmaWVyJzpcblx0XHRcdHBhdGggPSAndmlld3MvcG9saWN5L2FjY3J1YWxfcG9saWN5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdEb2N1bWVudFJldmlzaW9uJzpcblx0XHRjYXNlICdEb2N1bWVudCc6XG5cdFx0Y2FzZSAnRG9jdW1lbnRHcm91cCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2RvY3VtZW50Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBYm91dCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2hlbHAvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FjdGl2ZVNoaWZ0UmVwb3J0Jzpcblx0XHRcdHBhdGggPSAndmlld3MvcmVwb3J0cy93aG9zX2luX3N1bW1hcnkvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1VzZXJTdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdHBhdGggPSAndmlld3MvcmVwb3J0cy9lbXBsb3llZV9pbmZvcm1hdGlvbi8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnU2F2ZWRSZXBvcnQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9yZXBvcnRzL3NhdmVkX3JlcG9ydC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUmVwb3J0U2NoZWR1bGUnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9yZXBvcnRzL3JlcG9ydF9zY2hlZHVsZS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnU2NoZWR1bGVTdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdHBhdGggPSAndmlld3MvcmVwb3J0cy9zY2hlZHVsZV9zdW1tYXJ5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdUaW1lc2hlZXRTdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdHBhdGggPSAndmlld3MvcmVwb3J0cy90aW1lc2hlZXRfc3VtbWFyeS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnVGltZXNoZWV0RGV0YWlsUmVwb3J0Jzpcblx0XHRcdHBhdGggPSAndmlld3MvcmVwb3J0cy90aW1lc2hlZXRfZGV0YWlsLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdQdW5jaFN1bW1hcnlSZXBvcnQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9yZXBvcnRzL3B1bmNoX3N1bW1hcnkvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0V4Y2VwdGlvblN1bW1hcnlSZXBvcnQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9yZXBvcnRzL2V4Y2VwdGlvbl9zdW1tYXJ5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdQYXlTdHViVHJhbnNhY3Rpb25TdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdHBhdGggPSAndmlld3MvcmVwb3J0cy9wYXlfc3R1Yl90cmFuc2FjdGlvbl9zdW1tYXJ5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdQYXlTdHViU3VtbWFyeVJlcG9ydCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3JlcG9ydHMvcGF5X3N0dWJfc3VtbWFyeS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnS1BJJzpcblx0XHRjYXNlICdLUElHcm91cCc6XG5cdFx0Y2FzZSAnVXNlclJldmlld0NvbnRyb2wnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9oci9rcGkvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1F1YWxpZmljYXRpb25Hcm91cCc6XG5cdFx0Y2FzZSAnUXVhbGlmaWNhdGlvbic6XG5cdFx0Y2FzZSAnVXNlclNraWxsJzpcblx0XHRjYXNlICdVc2VyRWR1Y2F0aW9uJzpcblx0XHRjYXNlICdVc2VyTWVtYmVyc2hpcCc6XG5cdFx0Y2FzZSAnVXNlckxpY2Vuc2UnOlxuXHRcdGNhc2UgJ1VzZXJMYW5ndWFnZSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2hyL3F1YWxpZmljYXRpb24vJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0pvYkFwcGxpY2F0aW9uJzpcblx0XHRjYXNlICdKb2JWYWNhbmN5Jzpcblx0XHRjYXNlICdKb2JBcHBsaWNhbnQnOlxuXHRcdGNhc2UgJ0pvYkFwcGxpY2FudEVtcGxveW1lbnQnOlxuXHRcdGNhc2UgJ0pvYkFwcGxpY2FudFJlZmVyZW5jZSc6XG5cdFx0Y2FzZSAnSm9iQXBwbGljYW50TG9jYXRpb24nOlxuXHRcdGNhc2UgJ0pvYkFwcGxpY2FudFNraWxsJzpcblx0XHRjYXNlICdKb2JBcHBsaWNhbnRFZHVjYXRpb24nOlxuXHRcdGNhc2UgJ0pvYkFwcGxpY2FudE1lbWJlcnNoaXAnOlxuXHRcdGNhc2UgJ0pvYkFwcGxpY2FudExpY2Vuc2UnOlxuXHRcdGNhc2UgJ0pvYkFwcGxpY2FudExhbmd1YWdlJzpcblx0XHRjYXNlICdSZWNydWl0bWVudFBvcnRhbENvbmZpZyc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2hyL3JlY3J1aXRtZW50Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdQYXlyb2xsRXhwb3J0UmVwb3J0Jzpcblx0XHRcdHBhdGggPSAndmlld3MvcmVwb3J0cy9wYXlyb2xsX2V4cG9ydC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnR2VuZXJhbExlZGdlclN1bW1hcnlSZXBvcnQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9yZXBvcnRzL2dlbmVyYWxfbGVkZ2VyX3N1bW1hcnkvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0V4cGVuc2VTdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdHBhdGggPSAndmlld3MvcmVwb3J0cy9leHBlbnNlX3N1bW1hcnkvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FjY3J1YWxCYWxhbmNlU3VtbWFyeVJlcG9ydCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3JlcG9ydHMvYWNjcnVhbF9iYWxhbmNlX3N1bW1hcnkvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0pvYlN1bW1hcnlSZXBvcnQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9yZXBvcnRzL2pvYl9zdW1tYXJ5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdKb2JBbmFseXNpc1JlcG9ydCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3JlcG9ydHMvam9iX2FuYWx5c2lzLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdKb2JJbmZvcm1hdGlvblJlcG9ydCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3JlcG9ydHMvam9iX2luZm8vJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0pvYkl0ZW1JbmZvcm1hdGlvblJlcG9ydCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3JlcG9ydHMvam9iX2l0ZW1faW5mby8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnSW52b2ljZVRyYW5zYWN0aW9uU3VtbWFyeVJlcG9ydCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3JlcG9ydHMvaW52b2ljZV90cmFuc2FjdGlvbl9zdW1tYXJ5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdSZW1pdHRhbmNlU3VtbWFyeVJlcG9ydCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3JlcG9ydHMvcmVtaXR0YW5jZV9zdW1tYXJ5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdUNFN1bW1hcnlSZXBvcnQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9yZXBvcnRzL3Q0X3N1bW1hcnkvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1Q0QVN1bW1hcnlSZXBvcnQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9yZXBvcnRzL3Q0YV9zdW1tYXJ5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdUYXhTdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdHBhdGggPSAndmlld3MvcmVwb3J0cy90YXhfc3VtbWFyeS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnRm9ybTk0MFJlcG9ydCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3JlcG9ydHMvZm9ybTk0MC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnRm9ybTk0MVJlcG9ydCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3JlcG9ydHMvZm9ybTk0MS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnRm9ybTEwOTlOZWNSZXBvcnQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9yZXBvcnRzL2Zvcm0xMDk5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdGb3JtVzJSZXBvcnQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9yZXBvcnRzL2Zvcm13Mi8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnVVNTdGF0ZVVuZW1wbG95bWVudFJlcG9ydCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3JlcG9ydHMvdXNfc3RhdGVfdW5lbXBsb3ltZW50Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBZmZvcmRhYmxlQ2FyZVJlcG9ydCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3JlcG9ydHMvYWZmb3JkYWJsZV9jYXJlLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdVc2VyUXVhbGlmaWNhdGlvblJlcG9ydCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3JlcG9ydHMvcXVhbGlmaWNhdGlvbl9zdW1tYXJ5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdLUElSZXBvcnQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9yZXBvcnRzL3Jldmlld19zdW1tYXJ5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdVc2VyUmVjcnVpdG1lbnRTdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdHBhdGggPSAndmlld3MvcmVwb3J0cy9yZWNydWl0bWVudF9zdW1tYXJ5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdVc2VyUmVjcnVpdG1lbnREZXRhaWxSZXBvcnQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9yZXBvcnRzL3JlY3J1aXRtZW50X2RldGFpbC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQ2xpZW50Jzpcblx0XHRcdHBhdGggPSAndmlld3MvaW52b2ljZS9jbGllbnQvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0NsaWVudENvbnRhY3QnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9pbnZvaWNlL2NsaWVudF9jb250YWN0Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdDbGllbnRQYXltZW50Jzpcblx0XHRcdHBhdGggPSAndmlld3MvaW52b2ljZS9jbGllbnRfcGF5bWVudC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnSW52b2ljZVRyYW5zYWN0aW9uJzpcblx0XHRcdHBhdGggPSAndmlld3MvaW52b2ljZS9pbnZvaWNlX3RyYW5zYWN0aW9uLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdJbnZvaWNlJzpcblx0XHRcdHBhdGggPSAndmlld3MvaW52b2ljZS9pbnZvaWNlLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdDdXN0b21Db2x1bW4nOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9yZXBvcnRzL2N1c3RvbV9jb2x1bW4vJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0F1ZGl0VHJhaWxSZXBvcnQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9yZXBvcnRzL2F1ZGl0dHJhaWwvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1JlQ2FsY3VsYXRlVGltZVNoZWV0V2l6YXJkJzpcblx0XHRcdHBhdGggPSAndmlld3Mvd2l6YXJkL3JlX2NhbGN1bGF0ZV90aW1lc2hlZXQvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0dlbmVyYXRlUGF5U3R1YldpemFyZCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3dpemFyZC9nZW5lcmF0ZV9wYXlfc3R1Yi8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnVXNlckdlbmVyaWNTdGF0dXMnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy93aXphcmQvdXNlcl9nZW5lcmljX2RhdGFfc3RhdHVzLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdQcm9jZXNzUGF5cm9sbFdpemFyZCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3dpemFyZC9wcm9jZXNzX3BheXJvbGwvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1BheXJvbGxSZW1pdHRhbmNlQWdlbmN5RXZlbnRXaXphcmRDb250cm9sbGVyJzpcblx0XHRcdHBhdGggPSAndmlld3MvcGF5cm9sbC9yZW1pdHRhbmNlX3dpemFyZC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUHJvY2Vzc1RyYW5zYWN0aW9uc1dpemFyZENvbnRyb2xsZXInOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9wYXlyb2xsL3Byb2Nlc3NfdHJhbnNhY3Rpb25zX3dpemFyZC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnSW1wb3J0Q1NWV2l6YXJkJzpcblx0XHRcdHBhdGggPSAndmlld3Mvd2l6YXJkL2ltcG9ydF9jc3YvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0pvYkludm9pY2VXaXphcmQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy93aXphcmQvam9iX2ludm9pY2UvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0xvZ2luVXNlcldpemFyZCc6XG5cdFx0Y2FzZSAnTG9naW5Vc2VyJzpcblx0XHRcdHBhdGggPSAndmlld3Mvd2l6YXJkL2xvZ2luX3VzZXIvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1F1aWNrU3RhcnRXaXphcmQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy93aXphcmQvcXVpY2tfc3RhcnQvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1VzZXJQaG90b1dpemFyZCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3dpemFyZC91c2VyX3Bob3RvLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdGaW5kQXZhaWxhYmxlV2l6YXJkJzpcblx0XHRjYXNlICdGaW5kQXZhaWxhYmxlJzpcblx0XHRcdHBhdGggPSAndmlld3Mvd2l6YXJkL2ZpbmRfYXZhaWxhYmxlLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdQZXJtaXNzaW9uV2l6YXJkJzpcblx0XHRcdHBhdGggPSAndmlld3Mvd2l6YXJkL3Blcm1pc3Npb25fd2l6YXJkLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdGb3JtdWxhQnVpbGRlcldpemFyZCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3dpemFyZC9mb3JtdWxhX2J1aWxkZXJfd2l6YXJkLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdSZUNhbGN1bGF0ZUFjY3J1YWxXaXphcmQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy93aXphcmQvcmVfY2FsY3VsYXRlX2FjY3J1YWwvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1Jlc2V0UGFzc3dvcmRXaXphcmQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy93aXphcmQvcmVzZXRfcGFzc3dvcmQvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1NoYXJlUmVwb3J0V2l6YXJkJzpcblx0XHRcdHBhdGggPSAndmlld3Mvd2l6YXJkL3NoYXJlX3JlcG9ydC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUGF5Q29kZVdpemFyZCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3dpemFyZC9wYXlfY29kZS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnSW5zdGFsbFdpemFyZCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3dpemFyZC9pbnN0YWxsLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdQYXlTdHViQWNjb3VudFdpemFyZCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3dpemFyZC9wYXlfc3R1Yl9hY2NvdW50Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdEYXNobGV0V2l6YXJkJzpcblx0XHRcdHBhdGggPSAndmlld3Mvd2l6YXJkL2Rhc2hsZXQvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1JlcG9ydFZpZXdXaXphcmQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy93aXphcmQvcmVwb3J0X3ZpZXcvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1BvcnRhbEFwcGx5Sm9iV2l6YXJkJzpcblx0XHRcdHBhdGggPSAndmlld3Mvd2l6YXJkL3BvcnRhbF9hcHBseV9qb2IvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0ZvcmdvdFBhc3N3b3JkV2l6YXJkJzpcblx0XHRcdHBhdGggPSAndmlld3Mvd2l6YXJkL2ZvcmdvdF9wYXNzd29yZC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUmVzZXRGb3Jnb3RQYXNzd29yZFdpemFyZCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3dpemFyZC9yZXNldF9mb3Jnb3RfcGFzc3dvcmQvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0RldmVsb3BlclRvb2xzJzpcblx0XHRcdHBhdGggPSAndmlld3MvZGV2ZWxvcGVyX3Rvb2xzLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdVSUtpdFNhbXBsZSc6XG5cdFx0Y2FzZSAnVUlLaXRDaGlsZFNhbXBsZSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3VpX2tpdF9zYW1wbGUvJztcblx0XHRcdGJyZWFrO1xuXHR9XG5cdHJldHVybiBwYXRoO1xufTtcbi8qIGpzaGludCBpZ25vcmU6ZW5kICovXG5cbi8vcmV0dXJucyBleGFjdCBmaWxlcGF0aHMgZm9yIGNsYXNzIGRlcGVuZGVuY2llc1xuR2xvYmFsLmdldFZpZXdQcmVsb2FkUGF0aEJ5Vmlld0lkID0gZnVuY3Rpb24oIHZpZXdJZCApIHtcblx0Ly8gREVQUkVDQVRFRDogTW92ZWQgdGhlIGxvYWRpbmcgb2YgdGhlc2UgcHJlbG9hZHMgdG8gcG9zdC1sb2dpbi1tYWluX3VpLWRlcGVuZGFuY2llcy5qc1xuXG5cdHZhciBwcmVsb2FkcyA9IFtdO1xuXHQvLyBzd2l0Y2ggKCB2aWV3SWQgKSB7XG5cdC8vIFx0Y2FzZSAnUmVxdWVzdCc6XG5cdC8vIFx0Y2FzZSAnUmVxdWVzdEF1dGhvcml6YXRpb24nOlxuXHQvLyBcdFx0cHJlbG9hZHMgPSBbJ3ZpZXdzL2NvbW1vbi9BdXRob3JpemF0aW9uSGlzdG9yeUNvbW1vbi5qcycsICd2aWV3cy9jb21tb24vUmVxdWVzdFZpZXdDb21tb25Db250cm9sbGVyLmpzJywgJ3ZpZXdzL2NvbW1vbi9FbWJlZGRlZE1lc3NhZ2VDb21tb24uanMnXTtcblx0Ly8gXHRcdGJyZWFrO1xuXHQvLyBcdGNhc2UgJ0V4cGVuc2VBdXRob3JpemF0aW9uJzpcblx0Ly8gXHRjYXNlICdVc2VyRXhwZW5zZSc6XG5cdC8vIFx0Y2FzZSAnTG9naW5Vc2VyRXhwZW5zZSc6XG5cdC8vIFx0Y2FzZSAnVGltZVNoZWV0QXV0aG9yaXphdGlvbic6XG5cdC8vIFx0XHRwcmVsb2FkcyA9IFsndmlld3MvY29tbW9uL0F1dGhvcml6YXRpb25IaXN0b3J5Q29tbW9uLmpzJ107XG5cdC8vIFx0XHRicmVhaztcblx0Ly8gfVxuXHRyZXR1cm4gcHJlbG9hZHM7XG59O1xuXG5HbG9iYWwucmVtb3ZlVmlld0NzcyA9IGZ1bmN0aW9uKCB2aWV3SWQsIGZpbGVOYW1lICkge1xuXHRHbG9iYWwucmVtb3ZlQ3NzKCBHbG9iYWwuZ2V0Vmlld1BhdGhCeVZpZXdJZCggdmlld0lkICkgKyBmaWxlTmFtZSApO1xufTtcblxuR2xvYmFsLnNhbml0aXplVmlld0lkID0gZnVuY3Rpb24oIHZpZXdJZCApIHtcblx0aWYgKCB0eXBlb2Ygdmlld0lkID09PSAnc3RyaW5nJyB8fCB2aWV3SWQgaW5zdGFuY2VvZiBTdHJpbmcgKSB7XG5cdFx0cmV0dXJuIHZpZXdJZC5yZXBsYWNlKCAnLycsICcnICkucmVwbGFjZSggJ1xcXFwnLCAnJyApO1xuXHR9XG5cblx0cmV0dXJuIHZpZXdJZDtcbn07XG5cbkdsb2JhbC5sb2FkVmlld1NvdXJjZSA9IGZ1bmN0aW9uKCB2aWV3SWQsIGZpbGVOYW1lLCBvblJlc3VsdCwgc3luYyApIHtcblx0dmFyIHZpZXdJZCA9IEdsb2JhbC5zYW5pdGl6ZVZpZXdJZCggdmlld0lkICk7XG5cdHZhciBwYXRoID0gR2xvYmFsLmdldFZpZXdQYXRoQnlWaWV3SWQoIHZpZXdJZCApO1xuXG5cdGlmICggZmlsZU5hbWUuaW5kZXhPZiggJy5qcycgKSA+IDAgKSB7XG5cdFx0dmFyIHByZWxvYWRzID0gR2xvYmFsLmdldFZpZXdQcmVsb2FkUGF0aEJ5Vmlld0lkKCB2aWV3SWQgKTtcblx0XHRpZiAoIHByZWxvYWRzLmxlbmd0aCA+IDAgKSB7XG5cdFx0XHRmb3IgKCB2YXIgcCBpbiBwcmVsb2FkcyApIHtcblx0XHRcdFx0R2xvYmFsLmxvYWRTY3JpcHQoIHByZWxvYWRzW3BdICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKCBwYXRoICkge1xuXHRcdFx0aWYgKCBzeW5jICkge1xuXHRcdFx0XHRyZXR1cm4gR2xvYmFsLmxvYWRTY3JpcHQoIHBhdGggKyBmaWxlTmFtZSApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0R2xvYmFsLmxvYWRTY3JpcHQoIHBhdGggKyBmaWxlTmFtZSwgb25SZXN1bHQgKTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly9JbnZhbGlkIHZpZXdJZCwgcmVkaXJlY3QgdG8gaG9tZSBwYWdlP1xuXHRcdFx0Y29uc29sZS5kZWJ1ZyggJ1ZpZXcgZG9lcyBub3QgZXhpc3QhIFZpZXdJZDogJyArIHZpZXdJZCArICcgRmlsZSBOYW1lOiAnICsgZmlsZU5hbWUgKTtcblx0XHRcdGlmICggU2VydmljZUNhbGxlci5yb290X3VybCAmJiBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEuYmFzZV91cmwgKSB7XG5cdFx0XHRcdEdsb2JhbC5zZXRVUkxUb0Jyb3dzZXIoIFNlcnZpY2VDYWxsZXIucm9vdF91cmwgKyBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEuYmFzZV91cmwgKTtcblx0XHRcdH1cblx0XHR9XG5cblx0fSBlbHNlIGlmICggZmlsZU5hbWUuaW5kZXhPZiggJy5jc3MnICkgPiAwICkge1xuXHRcdEdsb2JhbC5hZGRDc3MoIHBhdGggKyBmaWxlTmFtZSApO1xuXHR9IGVsc2Uge1xuXHRcdGlmICggcGF0aCApIHtcblx0XHRcdC8vIEhUTUwySlNcblx0XHRcdHZhciB0ZW1wbGF0ZV90eXBlID0gSHRtbFRlbXBsYXRlc0dsb2JhbC5nZXRUZW1wbGF0ZVR5cGVGcm9tRmlsZW5hbWUoIGZpbGVOYW1lICk7XG5cdFx0XHR2YXIgdGVtcGxhdGVfb3B0aW9ucyA9IEh0bWxUZW1wbGF0ZXNHbG9iYWwuZ2V0VGVtcGxhdGVPcHRpb25zRnJvbVZpZXdJZCggdmlld0lkICk7XG5cblx0XHRcdGlmKCB0ZW1wbGF0ZV90eXBlID09PSBUZW1wbGF0ZVR5cGUuSU5MSU5FX0hUTUwgKSB7XG5cdFx0XHRcdHRlbXBsYXRlX29wdGlvbnMuZmlsZW5hbWUgPSBmaWxlTmFtZTsgLy8gTmVlZGVkIGJ5IEh0bWxUZW1wbGF0ZXMuY2hlY2tWaWV3Q2xhc3NGb3JJbmxpbmVIdG1sYnlGaWxlbmFtZSgpIHdoaWNoIHVzZXMgZmlsZW5hbWUsIG5vdCB2aWV3IGlkLlxuXHRcdFx0fVxuXHRcdFx0aWYgKCBzeW5jICkge1xuXHRcdFx0XHQvLyBOb3RlOiBmb3IgI0hUTUwySlMgVGhpcyBwYXRoIGlzIHRha2VuIGZvciB0aGluZ3Mgc3VjaCBhczogQ29tcGFueUluZm9ybWF0aW9uLCBDb21wYW55RWRpdFZpZXcuaHRtbCwgYW5kIGdlbmVyYWwgZWRpdCB2aWV3cy5cblxuXHRcdFx0XHQvLyBDaGVjayBpZiB3ZSBzaG91bGQgdXNlIHRoZSBuZXcgdGVtcGxhdGluZyBsb2dpYywgb3IgbGVnYWN5IGh0bWwgbG9hZC5cblx0XHRcdFx0aWYoIHRlbXBsYXRlX3R5cGUgIT09IFRlbXBsYXRlVHlwZS5MRUdBQ1lfSFRNTCApIHtcblx0XHRcdFx0XHQvLyBVc2UgbmV3IEhUTUwySlMgdGVtcGxhdGUgY2xhc3Ncblx0XHRcdFx0XHRyZXR1cm4gSHRtbFRlbXBsYXRlc0dsb2JhbC5nZXRUZW1wbGF0ZSggdGVtcGxhdGVfdHlwZSwgdGVtcGxhdGVfb3B0aW9ucywgbnVsbCApOyAvLyBubyBvblJlc3VsdCwgYXMgaXRzIHN5bmNyb25vdXMuXG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Ly8gTGVnYWN5IGh0bWwgZmlsZSBsb2FkIGZvciBzeW5jcm9ub3VzIGZpbGVzLlxuXHRcdFx0XHRcdHJldHVybiBHbG9iYWwubG9hZFBhZ2VTeW5jKCBwYXRoICsgZmlsZU5hbWUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Ly8gQ2hlY2sgaWYgd2Ugc2hvdWxkIHVzZSB0aGUgbmV3IHRlbXBsYXRpbmcgbG9naWMsIG9yIGxlZ2FjeSBodG1sIGxvYWQuXG5cdFx0XHRcdGlmKCB0ZW1wbGF0ZV90eXBlICE9PSBUZW1wbGF0ZVR5cGUuTEVHQUNZX0hUTUwgKSB7XG5cdFx0XHRcdFx0Ly8gVXNlIG5ldyBIVE1MMkpTIHRlbXBsYXRlIGNsYXNzXG5cdFx0XHRcdFx0SHRtbFRlbXBsYXRlc0dsb2JhbC5nZXRUZW1wbGF0ZSggdGVtcGxhdGVfdHlwZSwgdGVtcGxhdGVfb3B0aW9ucywgb25SZXN1bHQgKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHQvLyBMZWdhY3kgaHRtbCBmaWxlIGxvYWRcblx0XHRcdFx0XHRHbG9iYWwubG9hZFBhZ2UoIHBhdGggKyBmaWxlTmFtZSwgb25SZXN1bHQgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHQvL0ludmFsaWQgdmlld0lkLCByZWRpcmVjdCB0byBob21lIHBhZ2U/XG5cdFx0XHRjb25zb2xlLmRlYnVnKCAnVmlldyBkb2VzIG5vdCBleGlzdCEgVmlld0lkOiAnICsgdmlld0lkICsgJyBGaWxlIE5hbWU6ICcgKyBmaWxlTmFtZSApO1xuXHRcdFx0aWYgKCBTZXJ2aWNlQ2FsbGVyLnJvb3RfdXJsICYmIEFQSUdsb2JhbC5wcmVfbG9naW5fZGF0YS5iYXNlX3VybCApIHtcblx0XHRcdFx0R2xvYmFsLnNldFVSTFRvQnJvd3NlciggU2VydmljZUNhbGxlci5yb290X3VybCArIEFQSUdsb2JhbC5wcmVfbG9naW5fZGF0YS5iYXNlX3VybCApO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxufTtcblxuR2xvYmFsLmxvYWRQYWdlU3luYyA9IGZ1bmN0aW9uKCB1cmwgKSB7XG5cblx0dmFyIHJlYWxQYXRoID0gdXJsICsgJz92PScgKyBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEuYXBwbGljYXRpb25fYnVpbGQ7XG5cblx0aWYgKCBHbG9iYWwudXJsX29mZnNldCApIHtcblx0XHRyZWFsUGF0aCA9IEdsb2JhbC51cmxfb2Zmc2V0ICsgcmVhbFBhdGg7XG5cdH1cblx0dmFyIG1lc3NhZ2VfaWQgPSBUVFVVSUQuZ2VuZXJhdGVVVUlEKCk7XG5cdFByb2dyZXNzQmFyLnNob3dQcm9ncmVzc0JhciggbWVzc2FnZV9pZCApO1xuXHR2YXIgc3VjY2Vzc2ZsYWcgPSBmYWxzZTtcblx0dmFyIHJlc3BvbnNlRGF0YSA9ICQuYWpheCgge1xuXHRcdGFzeW5jOiBmYWxzZSxcblx0XHR0eXBlOiAnR0VUJyxcblx0XHR1cmw6IHJlYWxQYXRoLFxuXHRcdGRhdGE6IG51bGwsXG5cdFx0Y2FjaGU6IHRydWUsXG5cdFx0c3VjY2VzczogZnVuY3Rpb24oKSB7XG5cdFx0XHRzdWNjZXNzZmxhZyA9IHRydWU7XG5cdFx0fSxcblxuXHRcdGVycm9yOiBmdW5jdGlvbigganFYSFIsIHRleHRTdGF0dXMsIGVycm9yVGhyb3duICkge1xuXHRcdFx0VEFsZXJ0TWFuYWdlci5zaG93TmV0d29ya0Vycm9yQWxlcnQoIGpxWEhSLCB0ZXh0U3RhdHVzLCBlcnJvclRocm93biApO1xuXHRcdH1cblx0fSApO1xuXG5cdFByb2dyZXNzQmFyLnJlbW92ZVByb2dyZXNzQmFyKCBtZXNzYWdlX2lkICk7XG5cblx0cmV0dXJuICggcmVzcG9uc2VEYXRhLnJlc3BvbnNlVGV4dCApO1xuXG59O1xuXG5HbG9iYWwubG9hZFBhZ2UgPSBmdW5jdGlvbiggdXJsLCBvblJlc3VsdCApIHtcblxuXHR2YXIgcmVhbFBhdGggPSB1cmwgKyAnP3Y9JyArIEFQSUdsb2JhbC5wcmVfbG9naW5fZGF0YS5hcHBsaWNhdGlvbl9idWlsZDtcblx0dmFyIG1lc3NhZ2VfaWQgPSBUVFVVSUQuZ2VuZXJhdGVVVUlEKCk7XG5cdGlmICggR2xvYmFsLnVybF9vZmZzZXQgKSB7XG5cdFx0cmVhbFBhdGggPSBHbG9iYWwudXJsX29mZnNldCArIHJlYWxQYXRoO1xuXHR9XG5cblx0UHJvZ3Jlc3NCYXIuc2hvd1Byb2dyZXNzQmFyKCBtZXNzYWdlX2lkICk7XG5cdCQuYWpheCgge1xuXHRcdGFzeW5jOiB0cnVlLFxuXHRcdHR5cGU6ICdHRVQnLFxuXHRcdHVybDogcmVhbFBhdGgsXG5cdFx0ZGF0YTogbnVsbCxcblx0XHRjYWNoZTogdHJ1ZSxcblx0XHRzdWNjZXNzOiBmdW5jdGlvbiggcmVzdWx0ICkge1xuXHRcdFx0UHJvZ3Jlc3NCYXIucmVtb3ZlUHJvZ3Jlc3NCYXIoIG1lc3NhZ2VfaWQgKTtcblx0XHRcdG9uUmVzdWx0KCByZXN1bHQgKTtcblx0XHR9LFxuXHRcdGVycm9yOiBmdW5jdGlvbigganFYSFIsIHRleHRTdGF0dXMsIGVycm9yVGhyb3duICkge1xuXHRcdFx0VEFsZXJ0TWFuYWdlci5zaG93TmV0d29ya0Vycm9yQWxlcnQoIGpxWEhSLCB0ZXh0U3RhdHVzLCBlcnJvclRocm93biApO1xuXHRcdH1cblx0fSApO1xuXG59O1xuXG5HbG9iYWwuZ2V0Um9vdFVSTCA9IGZ1bmN0aW9uKCB1cmwgKSB7XG5cdGlmICggIXVybCApIHtcblx0XHR1cmwgPSBsb2NhdGlvbi5ocmVmO1xuXHR9XG5cblx0Ly9SYXRoZXIgdGhhbiBwYXJzZSB0aGUgVVJMIG91cnNlbHZlcywgbGV0cyB1c2UgdGhlIFVSTCBBUEkgYW5kIGJ1aWxkIGl0IGJhY2sgdXAgZnJvbSBpdHMgY29tcG9uZW50cy5cblx0dmFyIHVybF9vYmogPSBuZXcgVVJMKCB1cmwgKTtcblx0dmFyIHJldHZhbCA9IHVybF9vYmoucHJvdG9jb2wgKyAnLy8nICsgdXJsX29iai5ob3N0O1xuXG5cdHJldHVybiByZXR2YWw7XG59O1xuXG5HbG9iYWwuZ2V0QmFzZVVSTCA9IGZ1bmN0aW9uKCB1cmxfcmVsYXRpdmVfcGF0aCwgaW5jbHVkZV9zZWFyY2ggPSB0cnVlICkge1xuXHQvL1JhdGhlciB0aGFuIHBhcnNlIHRoZSBVUkwgb3Vyc2VsdmVzLCBsZXRzIHVzZSB0aGUgVVJMIEFQSSBhbmQgYnVpbGQgaXQgYmFjayB1cCBmcm9tIGl0cyBjb21wb25lbnRzLlxuXHR2YXIgdXJsX29iaiA9IG5ldyBVUkwoIGxvY2F0aW9uLmhyZWYgKTtcblx0dmFyIHJldHZhbCA9IHVybF9vYmoucHJvdG9jb2wgKyAnLy8nICsgdXJsX29iai5ob3N0ICsgdXJsX29iai5wYXRobmFtZTtcblxuXHQvL1Jlc29sdmUgYW55IHNwZWNpZmllZCByZWxhdGl2ZSBwYXRoIGhlcmUsIHNvIHdlIGNhbiBhcHBlbmQgdGhlIHNlYXJjaCBjb21wb25lbnQgb2YgdGhlIFVSTCBhZnRlci5cblx0Ly8gIFRoaXMgaXMgbmVlZGVkIGZvciB0aGUgcmVjcnVpdG1lbnQgcG9ydGFsIHRvIHdvcmsgaWYgRmFjZWJvb2sgb3Igc29tZSBvdGhlciAzcmQgcGFydHkgYXBwZW5kcyBzZWFyY2ggY29tcG9uZW50cyBvbiB0aGUgVVJMLCBpZTogP3Rlc3Q9MSMhbT1Qb3J0YWxKb2JWYWNhbmN5RGV0YWlsJmlkPTA1YTQ1ZDBiLWI5ODItMmExZi0yMDAzLTIxZWE2NTUyMmJmMyZjb21wYW55X2lkPUFCQ1xuXHRpZiAoIHVybF9yZWxhdGl2ZV9wYXRoICkge1xuXHRcdHJldHZhbCA9IG5ldyBVUkwoIHVybF9yZWxhdGl2ZV9wYXRoLCByZXR2YWwgKS5ocmVmO1xuXHR9XG5cblx0aWYgKCBpbmNsdWRlX3NlYXJjaCA9PSB0cnVlICkge1xuXHRcdHJldHZhbCArPSB1cmxfb2JqLnNlYXJjaDsgLy9DYW4ndCBwdXQgdGhlIHNlYXJjaCBjb21wb25lbnQgYmFjayBvbiB3aGVuIGdldHRpbmcgQmFzZVVSTC5cblx0fVxuXG5cdHJldHVybiByZXR2YWw7XG59O1xuXG5HbG9iYWwuaXNBcnJheUFuZEhhc0l0ZW1zID0gZnVuY3Rpb24oIG9iamVjdCApIHtcblxuXHRpZiAoICQudHlwZSggb2JqZWN0ICkgPT09ICdhcnJheScgJiYgb2JqZWN0Lmxlbmd0aCA+IDAgKSB7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblxuXHRyZXR1cm4gZmFsc2U7XG5cbn07XG5cbkdsb2JhbC5pc1ZhbGlkSW5wdXRDb2RlcyA9IGZ1bmN0aW9uKCBrZXlDb2RlICkge1xuXHR2YXIgcmVzdWx0ID0gdHJ1ZTtcblx0c3dpdGNoICgga2V5Q29kZSApIHtcblx0XHRjYXNlIDk6XG5cdFx0Y2FzZSAxNjpcblx0XHRjYXNlIDE3OlxuXHRcdGNhc2UgMTg6XG5cdFx0Y2FzZSAxOTpcblx0XHRjYXNlIDIwOlxuXHRcdGNhc2UgMzM6XG5cdFx0Y2FzZSAzNDpcblx0XHQvLyBjYXNlIDM3OlxuXHRcdC8vIGNhc2UgMzg6XG5cdFx0Ly8gY2FzZSAzOTpcblx0XHQvLyBjYXNlIDQwOlxuXHRcdGNhc2UgNDU6XG5cdFx0Y2FzZSA5MTpcblx0XHRjYXNlIDkyOlxuXHRcdGNhc2UgOTM6XG5cdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdGJyZWFrO1xuXHRcdGRlZmF1bHQ6XG5cdFx0XHRpZiAoIGtleUNvZGUgPj0gMTEyICYmIGtleUNvZGUgPD0gMTIzICkge1xuXHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdH1cblx0fVxuXHRyZXR1cm4gcmVzdWx0O1xufTtcblxuLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuR2xvYmFsLmNvbnZlcnRMYXlvdXRGaWx0ZXJUb0FQSUZpbHRlciA9IGZ1bmN0aW9uKCBsYXlvdXQgKSB7XG5cdHZhciBjb252ZXJ0X2ZpbHRlcl9kYXRhID0ge307XG5cblx0aWYgKCAhbGF5b3V0ICkge1xuXHRcdHJldHVybiBudWxsO1xuXHR9XG5cblx0dmFyIGZpbHRlcl9kYXRhID0gbGF5b3V0LmRhdGEuZmlsdGVyX2RhdGE7XG5cblx0aWYgKCAhZmlsdGVyX2RhdGEgKSB7XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblxuXHQkLmVhY2goIGZpbHRlcl9kYXRhLCBmdW5jdGlvbigga2V5LCBjb250ZW50ICkge1xuXHRcdC8vIENhbm5vdCByZWFkIHByb3BlcnR5ICd2YWx1ZScgb2YgdW5kZWZpbmVkXG5cdFx0aWYgKCAhY29udGVudCApIHtcblx0XHRcdHJldHVybjsvL2NvbnRpbnVlO1xuXHRcdH1cblx0XHRpZiAoICggY29udGVudC52YWx1ZSBpbnN0YW5jZW9mIEFycmF5ICYmIGNvbnRlbnQudmFsdWUubGVuZ3RoID4gMCApIHx8ICggY29udGVudC52YWx1ZSBpbnN0YW5jZW9mIE9iamVjdCApICkge1xuXHRcdFx0dmFyIHZhbHVlcyA9IFtdO1xuXHRcdFx0dmFyIG9iaiA9IGNvbnRlbnQudmFsdWU7XG5cdFx0XHRpZiAoIGNvbnRlbnQudmFsdWUgaW5zdGFuY2VvZiBBcnJheSApIHtcblxuXHRcdFx0XHR2YXIgbGVuID0gY29udGVudC52YWx1ZS5sZW5ndGg7XG5cdFx0XHRcdGZvciAoIHZhciBpID0gMDsgaSA8IGxlbjsgaSsrICkge1xuXG5cdFx0XHRcdFx0aWYgKCBHbG9iYWwuaXNTZXQoIGNvbnRlbnQudmFsdWVbaV0udmFsdWUgKSApIHtcblx0XHRcdFx0XHRcdHZhbHVlcy5wdXNoKCBjb250ZW50LnZhbHVlW2ldLnZhbHVlICk7IC8vT3B0aW9ucyxcblx0XHRcdFx0XHR9IGVsc2UgaWYgKCBjb250ZW50LnZhbHVlW2ldLmlkIHx8IGNvbnRlbnQudmFsdWVbaV0uaWQgPT09IDAgfHwgY29udGVudC52YWx1ZVtpXS5pZCA9PT0gJzAnICkge1xuXHRcdFx0XHRcdFx0dmFsdWVzLnB1c2goIGNvbnRlbnQudmFsdWVbaV0uaWQgKTsgLy9Bd2Vzb21lYm94XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdHZhbHVlcy5wdXNoKCBjb250ZW50LnZhbHVlW2ldICk7IC8vIGRlZmF1bHRfZmlsdGVyX2RhdGFfZm9yX25leHRfdmlld1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHR9XG5cblx0XHRcdFx0Y29udmVydF9maWx0ZXJfZGF0YVtrZXldID0gdmFsdWVzO1xuXHRcdFx0XHQvL29ubHkgYWRkIHNlYXJjaCBmaWx0ZXIgd2hpY2ggbm90IGVxdWFsIHRvIGZhbHNlLCBzZWUgaWYgdGhpcyBjYXVzZSBhbnkgYnVnc1xuXHRcdFx0fSBlbHNlIGlmICggY29udGVudC52YWx1ZSBpbnN0YW5jZW9mIE9iamVjdCApIHtcblx0XHRcdFx0dmFyIGZpbmFsX3ZhbHVlID0gJyc7XG5cdFx0XHRcdGlmICggR2xvYmFsLmlzU2V0KCBjb250ZW50LnZhbHVlLnZhbHVlICkgKSB7XG5cdFx0XHRcdFx0ZmluYWxfdmFsdWUgPSBjb250ZW50LnZhbHVlLnZhbHVlOyAvL09wdGlvbnMsXG5cdFx0XHRcdH0gZWxzZSBpZiAoIGNvbnRlbnQudmFsdWUuaWQgfHwgY29udGVudC52YWx1ZS5pZCA9PT0gMCB8fCBjb250ZW50LnZhbHVlLmlkID09PSAnMCcgKSB7XG5cdFx0XHRcdFx0ZmluYWxfdmFsdWUgPSBjb250ZW50LnZhbHVlLmlkOyAvL0F3ZXNvbWVib3hcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRmaW5hbF92YWx1ZSA9IGNvbnRlbnQudmFsdWU7IC8vIGRlZmF1bHRfZmlsdGVyX2RhdGFfZm9yX25leHRfdmlld1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Y29udmVydF9maWx0ZXJfZGF0YVtrZXldID0gZmluYWxfdmFsdWU7XG5cblx0XHRcdH0gZWxzZSBpZiAoIG9iai52YWx1ZSA9PT0gZmFsc2UgKSB7XG5cdFx0XHRcdHJldHVybjsvL2NvbnRpbnVlO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCBHbG9iYWwuaXNTZXQoIG9iai52YWx1ZSApICkge1xuXG5cdFx0XHRcdFx0Y29udmVydF9maWx0ZXJfZGF0YVtrZXldID0gb2JqLnZhbHVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHR9IGVsc2UgaWYgKCBmaWx0ZXJfZGF0YVtrZXldLnZhbHVlID09PSBmYWxzZSApIHtcblx0XHRcdHJldHVybjsgLy9jb250aW51ZTtcblx0XHR9IGVsc2UgaWYgKCBHbG9iYWwuaXNTZXQoIGZpbHRlcl9kYXRhW2tleV0udmFsdWUgKSApIHtcblx0XHRcdGNvbnZlcnRfZmlsdGVyX2RhdGFba2V5XSA9IGZpbHRlcl9kYXRhW2tleV0udmFsdWU7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGNvbnZlcnRfZmlsdGVyX2RhdGFba2V5XSA9IGZpbHRlcl9kYXRhW2tleV07XG5cdFx0fVxuXHR9ICk7XG5cblx0aWYgKCBMb2NhbENhY2hlRGF0YS5leHRyYV9maWx0ZXJfZm9yX25leHRfb3Blbl92aWV3ICkgeyAvL01VU1QgcmVtb3ZlZCB0aGlzIHdoZW4gY2xvc2UgdGhlIHZpZXcgd2hpY2ggdXNlZCB0aGlzIGF0dHJpYnV0ZS5cblxuXHRcdGZvciAoIHZhciBrZXkgaW4gTG9jYWxDYWNoZURhdGEuZXh0cmFfZmlsdGVyX2Zvcl9uZXh0X29wZW5fdmlldy5maWx0ZXJfZGF0YSApIHtcblx0XHRcdGNvbnZlcnRfZmlsdGVyX2RhdGFba2V5XSA9IExvY2FsQ2FjaGVEYXRhLmV4dHJhX2ZpbHRlcl9mb3JfbmV4dF9vcGVuX3ZpZXcuZmlsdGVyX2RhdGFba2V5XTtcblx0XHR9XG5cblx0fVxuXG5cdHJldHVybiBjb252ZXJ0X2ZpbHRlcl9kYXRhO1xuXG59O1xuLyoganNoaW50IGlnbm9yZTplbmQgKi9cblxuLy9BU0Ncbkdsb2JhbC5jb21wYXJlID0gZnVuY3Rpb24oIGEsIGIsIG9yZGVyS2V5LCBvcmRlcl90eXBlICkge1xuXG5cdGlmICggIUdsb2JhbC5pc1NldCggb3JkZXJfdHlwZSApICkge1xuXHRcdG9yZGVyX3R5cGUgPSAnYXNjJztcblx0fVxuXG5cdGlmICggb3JkZXJfdHlwZSA9PT0gJ2FzYycgKSB7XG5cdFx0aWYgKCBhW29yZGVyS2V5XSA8IGJbb3JkZXJLZXldICkge1xuXHRcdFx0cmV0dXJuIC0xO1xuXHRcdH1cblx0XHRpZiAoIGFbb3JkZXJLZXldID4gYltvcmRlcktleV0gKSB7XG5cdFx0XHRyZXR1cm4gMTtcblx0XHR9XG5cdFx0cmV0dXJuIDA7XG5cdH0gZWxzZSB7XG5cdFx0aWYgKCBhW29yZGVyS2V5XSA8IGJbb3JkZXJLZXldICkge1xuXHRcdFx0cmV0dXJuIDE7XG5cdFx0fVxuXHRcdGlmICggYVtvcmRlcktleV0gPiBiW29yZGVyS2V5XSApIHtcblx0XHRcdHJldHVybiAtMTtcblx0XHR9XG5cdFx0cmV0dXJuIDA7XG5cdH1cblxufTtcblxuR2xvYmFsLmJ1aWxkRmlsdGVyID0gZnVuY3Rpb24oKSB7XG5cdHZhciBmaWx0ZXJDb25kaXRpb24gPSBhcmd1bWVudHNbMF07XG5cdHZhciBmaWx0ZXIgPSBbXTtcblxuXHRpZiAoIGZpbHRlckNvbmRpdGlvbiApIHtcblxuXHRcdGZvciAoIHZhciBrZXkgaW4gZmlsdGVyQ29uZGl0aW9uICkge1xuXHRcdFx0ZmlsdGVyW2tleV0gPSBmaWx0ZXJDb25kaXRpb25ba2V5XTtcblx0XHR9XG5cblx0fVxuXG5cdHJldHVybiBmaWx0ZXI7XG5cbn07XG5cbkdsb2JhbC5nZXRMb2dpblVzZXJEYXRlRm9ybWF0ID0gZnVuY3Rpb24oKSB7XG5cdHZhciBmb3JtYXQgPSAnREQtTU1NLVlZJztcblxuXHRpZiAoIExvY2FsQ2FjaGVEYXRhLmdldExvZ2luVXNlclByZWZlcmVuY2UoKSApIHtcblx0XHRmb3JtYXQgPSBMb2NhbENhY2hlRGF0YS5nZXRMb2dpblVzZXJQcmVmZXJlbmNlKCkuZGF0ZV9mb3JtYXQ7XG5cdH1cblxuXHRyZXR1cm4gZm9ybWF0O1xufTtcbi8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cbkdsb2JhbC5mb3JtYXRHcmlkRGF0YSA9IGZ1bmN0aW9uKCBncmlkX2RhdGEsIGtleV9uYW1lICkge1xuXG5cdGlmICggJC50eXBlKCBncmlkX2RhdGEgKSAhPT0gJ2FycmF5JyApIHtcblx0XHRyZXR1cm4gZ3JpZF9kYXRhO1xuXHR9XG5cblx0Zm9yICggdmFyIGkgPSAwOyBpIDwgZ3JpZF9kYXRhLmxlbmd0aDsgaSsrICkge1xuXHRcdGZvciAoIHZhciBrZXkgaW4gZ3JpZF9kYXRhW2ldICkge1xuXG5cdFx0XHRpZiAoICFncmlkX2RhdGFbaV0uaGFzT3duUHJvcGVydHkoIGtleSApICkge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdC8vTmVlZCB0byBjb252ZXJ0IGN1c3RvbSBmaWVsZHMgdGltZV91bml0IHRvIHN0cmluZ1xuXHRcdFx0aWYgKCBrZXkuaW5kZXhPZiggJ2N1c3RvbV9maWVsZCcgKSA9PT0gMCAmJiBBcnJheS5pc0FycmF5KCBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyLmN1c3RvbV9maWVsZHMgKSApIHtcblx0XHRcdFx0bGV0IGN1c3RvbV9maWVsZCA9IExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIuY3VzdG9tX2ZpZWxkcy5maW5kKCAoIGZpZWxkICkgPT4ge1xuXHRcdFx0XHRcdHJldHVybiBmaWVsZC5pZCA9PT0ga2V5LnJlcGxhY2UoICdjdXN0b21fZmllbGQtJywgJycgKTtcblx0XHRcdFx0fSApO1xuXG5cdFx0XHRcdGlmICggY3VzdG9tX2ZpZWxkICYmIGN1c3RvbV9maWVsZC50eXBlX2lkID09IDEzMDAgKSB7XG5cdFx0XHRcdFx0aWYgKCBHbG9iYWwuaXNOdW1lcmljKCBncmlkX2RhdGFbaV1ba2V5XSApICkge1xuXHRcdFx0XHRcdFx0Z3JpZF9kYXRhW2ldW2tleV0gPSBHbG9iYWwuZ2V0VGltZVVuaXQoIGdyaWRfZGF0YVtpXVtrZXldICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIFRoZSBzYW1lIGZvcm1hdCBmb3IgYWxsIHZpZXdzLlxuXHRcdFx0c3dpdGNoICgga2V5ICkge1xuXHRcdFx0XHRjYXNlICdtYXhpbXVtX3NoaWZ0X3RpbWUnOlxuXHRcdFx0XHRjYXNlICduZXdfZGF5X3RyaWdnZXJfdGltZSc6XG5cdFx0XHRcdGNhc2UgJ3RyaWdnZXJfdGltZSc6XG5cdFx0XHRcdGNhc2UgJ21pbmltdW1fcHVuY2hfdGltZSc6XG5cdFx0XHRcdGNhc2UgJ21heGltdW1fcHVuY2hfdGltZSc6XG5cdFx0XHRcdGNhc2UgJ3dpbmRvd19sZW5ndGgnOlxuXHRcdFx0XHRjYXNlICdzdGFydF93aW5kb3cnOlxuXHRcdFx0XHRjYXNlICdyb3VuZF9pbnRlcnZhbCc6XG5cdFx0XHRcdGNhc2UgJ2dyYWNlJzpcblx0XHRcdFx0Y2FzZSAnZXN0aW1hdGVfdGltZSc6XG5cdFx0XHRcdGNhc2UgJ21pbmltdW1fdGltZSc6XG5cdFx0XHRcdGNhc2UgJ21heGltdW1fdGltZSc6XG5cdFx0XHRcdGNhc2UgJ3RvdGFsX3RpbWUnOlxuXHRcdFx0XHRjYXNlICdzdGFydF9zdG9wX3dpbmRvdyc6XG5cdFx0XHRcdFx0aWYgKCBHbG9iYWwuaXNOdW1lcmljKCBncmlkX2RhdGFbaV1ba2V5XSApICkge1xuXHRcdFx0XHRcdFx0Z3JpZF9kYXRhW2ldW2tleV0gPSBHbG9iYWwuZ2V0VGltZVVuaXQoIGdyaWRfZGF0YVtpXVtrZXldICk7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdGdyaWRfZGF0YVtpXVtrZXldID0gbnVsbDsgLy9QcmV2ZW50IHN0cmluZyBcImZhbHNlXCIgZnJvbSBiZWluZyByZXR1cm5lZCB3aGVuIHRoZSBjb2x1bW4gaXNuJ3QgZGVmaW5lZCBvbiB0aGUgc2VydmVyIHNpZGUuXG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlICdpbmNsdWRlX2JyZWFrX3B1bmNoX3RpbWUnOlxuXHRcdFx0XHRjYXNlICdpbmNsdWRlX211bHRpcGxlX2JyZWFrcyc6XG5cdFx0XHRcdGNhc2UgJ2luY2x1ZGVfbHVuY2hfcHVuY2hfdGltZSc6XG5cdFx0XHRcdGNhc2UgJ2lzX2RlZmF1bHQnOlxuXHRcdFx0XHRjYXNlICdpc19iYXNlJzpcblx0XHRcdFx0Y2FzZSAnYXV0b191cGRhdGUnOlxuXHRcdFx0XHRjYXNlICdjdXJyZW50bHlfZW1wbG95ZWQnOlxuXHRcdFx0XHRjYXNlICdjcmltaW5hbF9yZWNvcmQnOlxuXHRcdFx0XHRjYXNlICdpbW1lZGlhdGVfZHJ1Z190ZXN0Jzpcblx0XHRcdFx0Y2FzZSAnaXNfY3VycmVudF9lbXBsb3llcic6XG5cdFx0XHRcdGNhc2UgJ2lzX2NvbnRhY3RfYXZhaWxhYmxlJzpcblx0XHRcdFx0Y2FzZSAnZW5hYmxlX3BheV9zdHViX2JhbGFuY2VfZGlzcGxheSc6XG5cdFx0XHRcdGNhc2UgJ2VuYWJsZV9sb2dpbic6XG5cdFx0XHRcdGNhc2UgJ3l0ZF9hZGp1c3RtZW50Jzpcblx0XHRcdFx0Y2FzZSAnYXV0aG9yaXplZCc6XG5cdFx0XHRcdGNhc2UgJ2lzX3JlaW1idXJzYWJsZSc6XG5cdFx0XHRcdGNhc2UgJ3JlaW1idXJzYWJsZSc6XG5cdFx0XHRcdGNhc2UgJ3RhaW50ZWQnOlxuXHRcdFx0XHRjYXNlICdhdXRvX2ZpbGwnOlxuXHRcdFx0XHRjYXNlICdwcml2YXRlJzpcblx0XHRcdFx0XHRpZiAoIGdyaWRfZGF0YVtpXVtrZXldID09PSB0cnVlICkge1xuXHRcdFx0XHRcdFx0Z3JpZF9kYXRhW2ldW2tleV0gPSAkLmkxOG4uXyggJ1llcycgKTtcblx0XHRcdFx0XHR9IGVsc2UgaWYgKCBncmlkX2RhdGFbaV1ba2V5XSA9PT0gZmFsc2UgKSB7XG5cdFx0XHRcdFx0XHRncmlkX2RhdGFbaV1ba2V5XSA9ICQuaTE4bi5fKCAnTm8nICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlICdvdmVycmlkZSc6XG5cdFx0XHRcdFx0aWYgKCBncmlkX2RhdGFbaV1ba2V5XSA9PT0gdHJ1ZSApIHtcblx0XHRcdFx0XHRcdGdyaWRfZGF0YVtpXVtrZXldID0gJC5pMThuLl8oICdZZXMnICk7XG5cdFx0XHRcdFx0XHRncmlkX2RhdGFbaV1bJ2lzX292ZXJyaWRlJ10gPSB0cnVlO1xuXHRcdFx0XHRcdH0gZWxzZSBpZiAoIGdyaWRfZGF0YVtpXVtrZXldID09PSBmYWxzZSApIHtcblx0XHRcdFx0XHRcdGdyaWRfZGF0YVtpXVtrZXldID0gJC5pMThuLl8oICdObycgKTtcblx0XHRcdFx0XHRcdGdyaWRfZGF0YVtpXVsnaXNfb3ZlcnJpZGUnXSA9IGZhbHNlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSAnaXNfc2NoZWR1bGVkJzpcblx0XHRcdFx0XHRpZiAoIGdyaWRfZGF0YVtpXVtrZXldID09PSAnMScgKSB7XG5cdFx0XHRcdFx0XHRncmlkX2RhdGFbaV1ba2V5XSA9ICQuaTE4bi5fKCAnWWVzJyApO1xuXHRcdFx0XHRcdH0gZWxzZSBpZiAoIGdyaWRfZGF0YVtpXVtrZXldID09PSAnMCcgKSB7XG5cdFx0XHRcdFx0XHRncmlkX2RhdGFbaV1ba2V5XSA9ICQuaTE4bi5fKCAnTm8nICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlICdpbl91c2UnOlxuXHRcdFx0XHRcdGlmICggZ3JpZF9kYXRhW2ldW2tleV0gPT09ICcxJyApIHtcblx0XHRcdFx0XHRcdGdyaWRfZGF0YVtpXVtrZXldID0gJC5pMThuLl8oICdZZXMnICk7XG5cdFx0XHRcdFx0XHRncmlkX2RhdGFbaV1bJ2lzX2luX3VzZSddID0gdHJ1ZTtcblx0XHRcdFx0XHR9IGVsc2UgaWYgKCBncmlkX2RhdGFbaV1ba2V5XSA9PT0gJzAnICkge1xuXHRcdFx0XHRcdFx0Z3JpZF9kYXRhW2ldW2tleV0gPSAkLmkxOG4uXyggJ05vJyApO1xuXHRcdFx0XHRcdFx0Z3JpZF9kYXRhW2ldWydpc19pbl91c2UnXSA9IGZhbHNlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0XHRpZiAoIGdyaWRfZGF0YVtpXVtrZXldID09PSBmYWxzZSApIHtcblx0XHRcdFx0XHRcdGdyaWRfZGF0YVtpXVtrZXldID0gJyc7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBIYW5kbGUgdGhlIHNwZWNpYWxseSBmb3JtYXQgY29sdW1ucyB3aGljaCBhcmUgbm90IGRpZmZlcmVudCB3aXRoIG90aGVycy5cblx0XHRcdHN3aXRjaCAoIGtleV9uYW1lICkge1xuXHRcdFx0XHRjYXNlICdBY2NydWFsUG9saWN5VXNlck1vZGlmaWVyJzpcblx0XHRcdFx0XHRzd2l0Y2ggKCBrZXkgKSB7XG5cdFx0XHRcdFx0XHRjYXNlICdhbm51YWxfbWF4aW11bV90aW1lX21vZGlmaWVyJzpcblx0XHRcdFx0XHRcdFx0aWYgKCBncmlkX2RhdGFbaV1bJ3R5cGVfaWQnXSA9PT0gMjAgKSB7XG5cdFx0XHRcdFx0XHRcdFx0Z3JpZF9kYXRhW2ldW2tleV0gPSAkLmkxOG4uXyggJ04vQScgKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgJ0JyZWFrUG9saWN5Jzpcblx0XHRcdFx0Y2FzZSAnTWVhbFBvbGljeSc6XG5cdFx0XHRcdGNhc2UgJ0FjY3J1YWwnOlxuXHRcdFx0XHRcdHN3aXRjaCAoIGtleSApIHtcblx0XHRcdFx0XHRcdGNhc2UgJ2Ftb3VudCc6XG5cdFx0XHRcdFx0XHRcdGlmICggR2xvYmFsLmlzTnVtZXJpYyggZ3JpZF9kYXRhW2ldW2tleV0gKSApIHtcblx0XHRcdFx0XHRcdFx0XHRncmlkX2RhdGFbaV1ba2V5XSA9IEdsb2JhbC5nZXRUaW1lVW5pdCggZ3JpZF9kYXRhW2ldW2tleV0gKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSAnYWNjcnVhbF9iYWxhbmNlX3N1bW1hcnknOlxuXHRcdFx0XHRjYXNlICdBY2NydWFsQmFsYW5jZSc6XG5cdFx0XHRcdFx0c3dpdGNoICgga2V5ICkge1xuXHRcdFx0XHRcdFx0Y2FzZSAnYmFsYW5jZSc6XG5cdFx0XHRcdFx0XHRcdGlmICggR2xvYmFsLmlzTnVtZXJpYyggZ3JpZF9kYXRhW2ldW2tleV0gKSApIHtcblx0XHRcdFx0XHRcdFx0XHRncmlkX2RhdGFbaV1ba2V5XSA9IEdsb2JhbC5nZXRUaW1lVW5pdCggZ3JpZF9kYXRhW2ldW2tleV0gKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSAnUmVjdXJyaW5nU2NoZWR1bGVDb250cm9sJzpcblx0XHRcdFx0XHRzd2l0Y2ggKCBrZXkgKSB7XG5cdFx0XHRcdFx0XHRjYXNlICdlbmRfZGF0ZSc6XG5cdFx0XHRcdFx0XHRcdGlmICggZ3JpZF9kYXRhW2ldW2tleV0gPT09ICcnICkge1xuXHRcdFx0XHRcdFx0XHRcdGdyaWRfZGF0YVtpXVtrZXldID0gJ05ldmVyJztcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gZ3JpZF9kYXRhO1xuXG59O1xuLyoganNoaW50IGlnbm9yZTplbmQgKi9cblxuLy8gQ29tbWVudGVkIG91dCBhcyB3ZSBoYXZlIG5vdyBmdWxseSByZWZhY3RvcmVkIHRoZSBvbGQgX3N1cGVyIGFuZCBfX3N1cGVyIHJlZmVyZW5jZXMgaW4gdGhlIG5ldyBFUzYgY29kZS5cbi8vIC8vbWFrZSBiYWNrb25lIHN1cHBvcnQgYSBzaW1wbGUgc3VwZXIgZnVuY2l0b25cbi8vIEJhY2tib25lLk1vZGVsLnByb3RvdHlwZS5fc3VwZXIgPSBmdW5jdGlvbiggZnVuY05hbWUgKSB7XG4vLyBcdHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLl9fc3VwZXJfX1tmdW5jTmFtZV0uYXBwbHkoIHRoaXMsIF8ucmVzdCggYXJndW1lbnRzICkgKTtcbi8vIH07XG4vL1xuLy8gLy9tYWtlIGJhY2tvbmUgc3VwcG9ydCBhIHNpbXBsZSBzdXBlciBmdW5jdGlvblxuLy8gQmFja2JvbmUuVmlldy5wcm90b3R5cGUuX3N1cGVyID0gZnVuY3Rpb24oIGZ1bmNOYW1lICkge1xuLy8gXHQvLyBOb3RlOiBJZiAnTWF4aW11bSBjYWxsIHN0YWNrIHNpemUgZXhjZWVkZWQnIGVycm9yIGVuY291bnRlcmVkLCBhbmQgdmlldyBpcyBleHRlbmRpbmcgdHdpY2UgKEJhc2VWaWV3LT5SZXBvcnRCYXNlVmlldy0+U29tZVJhbmRvbVZpZXcpLCB0aGVuIG1ha2Ugc3VyZSB5b3UgZGVmaW5lIGB0aGlzLnJlYWxfdGhpc2AgYXQgdGhlIDJuZCBsZXZlbCBleHRlbmQuIFNlZSByZXBvcnRCYXNlVmlld0NvbnRyb2xsZXIgaW5pdCBmb3IgZXhhbXBsZS5cbi8vIFx0aWYgKCB0aGlzLnJlYWxfdGhpcyAmJiB0aGlzLnJlYWxfdGhpcy5jb25zdHJ1Y3Rvci5fX3N1cGVyX19bZnVuY05hbWVdICkge1xuLy8gXHRcdHJldHVybiB0aGlzLnJlYWxfdGhpcy5jb25zdHJ1Y3Rvci5fX3N1cGVyX19bZnVuY05hbWVdLmFwcGx5KCB0aGlzLCBfLnJlc3QoIGFyZ3VtZW50cyApICk7XG4vLyBcdH0gZWxzZSB7XG4vLyBcdFx0cmV0dXJuIHRoaXMuY29uc3RydWN0b3IuX19zdXBlcl9fW2Z1bmNOYW1lXS5hcHBseSggdGhpcywgXy5yZXN0KCBhcmd1bWVudHMgKSApO1xuLy8gXHR9XG4vL1xuLy8gfTtcbi8vXG4vLyAvL21ha2UgYmFja29uZSBzdXBwb3J0IGEgc2ltcGxlIHN1cGVyIGZ1bmNpdG9uIGZvciBzZWNvbmQgbGV2ZWwgY2xhc3Ncbi8vIEJhY2tib25lLlZpZXcucHJvdG90eXBlLl9fc3VwZXIgPSBmdW5jdGlvbiggZnVuY05hbWUgKSB7XG4vLyBcdGlmICggIXRoaXMucmVhbF90aGlzICkge1xuLy8gXHRcdHRoaXMucmVhbF90aGlzID0gdGhpcy5jb25zdHJ1Y3Rvci5fX3N1cGVyX187XG4vLyBcdH1cbi8vXG4vLyBcdHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLl9fc3VwZXJfX1tmdW5jTmFtZV0uYXBwbHkoIHRoaXMsIF8ucmVzdCggYXJndW1lbnRzICkgKTtcbi8vXG4vLyB9O1xuXG4vKlxuICogRGF0ZSBGb3JtYXQgMS4yLjNcbiAqIChjKSAyMDA3LTIwMDkgU3RldmVuIExldml0aGFuIDxzdGV2ZW5sZXZpdGhhbi5jb20+XG4gKiBNSVQgbGljZW5zZVxuICpcbiAqIEluY2x1ZGVzIGVuaGFuY2VtZW50cyBieSBTY290dCBUcmVuZGEgPHNjb3R0LnRyZW5kYS5uZXQ+XG4gKiBhbmQgS3JpcyBLb3dhbCA8Y2l4YXIuY29tL35rcmlzLmtvd2FsPlxuICpcbiAqIEFjY2VwdHMgYSBkYXRlLCBhIG1hc2ssIG9yIGEgZGF0ZSBhbmQgYSBtYXNrLlxuICogUmV0dXJucyBhIGZvcm1hdHRlZCB2ZXJzaW9uIG9mIHRoZSBnaXZlbiBkYXRlLlxuICogVGhlIGRhdGUgZGVmYXVsdHMgdG8gdGhlIGN1cnJlbnQgZGF0ZS90aW1lLlxuICogVGhlIG1hc2sgZGVmYXVsdHMgdG8gZGF0ZUZvcm1hdC5tYXNrcy5kZWZhdWx0LlxuICovXG5cbnZhciBkYXRlRm9ybWF0ID0gZnVuY3Rpb24oKSB7XG5cdHZhciB0b2tlbiA9IC9kezEsNH18bXsxLDR9fHl5KD86eXkpP3woW0hoTXNUdF0pXFwxP3xbTGxvU1pdfCdbXiddKlwifCdbXiddKicvZyxcblx0XHR0aW1lem9uZSA9IC9cXGIoPzpbUE1DRUFdW1NEUF1UfCg/OlBhY2lmaWN8TW91bnRhaW58Q2VudHJhbHxFYXN0ZXJufEF0bGFudGljKSAoPzpTdGFuZGFyZHxEYXlsaWdodHxQcmV2YWlsaW5nKSBUaW1lfCg/OkdNVHxVVEMpKD86Wy0rXVxcZHs0fSk/KVxcYi9nLFxuXHRcdHRpbWV6b25lQ2xpcCA9IC9bXi0rXFxkQS1aXS9nLFxuXHRcdHBhZCA9IGZ1bmN0aW9uKCB2YWwsIGxlbiApIHtcblx0XHRcdHZhbCA9IFN0cmluZyggdmFsICk7XG5cdFx0XHRsZW4gPSBsZW4gfHwgMjtcblx0XHRcdHdoaWxlICggdmFsLmxlbmd0aCA8IGxlbiApIHtcblx0XHRcdFx0dmFsID0gJzAnICsgdmFsO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHZhbDtcblx0XHR9O1xuXG5cdC8vIFJlZ2V4ZXMgYW5kIHN1cHBvcnRpbmcgZnVuY3Rpb25zIGFyZSBjYWNoZWQgdGhyb3VnaCBjbG9zdXJlXG5cblx0LyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuXHRyZXR1cm4gZnVuY3Rpb24oIGRhdGUsIG1hc2ssIHV0YyApIHtcblx0XHR2YXIgZEYgPSBkYXRlRm9ybWF0O1xuXG5cdFx0Ly8gWW91IGNhbid0IHByb3ZpZGUgdXRjIGlmIHlvdSBza2lwIG90aGVyIGFyZ3MgKHVzZSB0aGUgJ1VUQzonIG1hc2sgcHJlZml4KVxuXHRcdGlmICggYXJndW1lbnRzLmxlbmd0aCA9PT0gMSAmJiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoIGRhdGUgKSA9PT0gJ1tvYmplY3QgU3RyaW5nXScgJiYgIS9cXGQvLnRlc3QoIGRhdGUgKSApIHtcblx0XHRcdG1hc2sgPSBkYXRlO1xuXHRcdFx0ZGF0ZSA9IHVuZGVmaW5lZDtcblx0XHR9XG5cblx0XHQvLyBQYXNzaW5nIGRhdGUgdGhyb3VnaCBEYXRlIGFwcGxpZXMgRGF0ZS5wYXJzZSwgaWYgbmVjZXNzYXJ5XG5cdFx0ZGF0ZSA9IGRhdGUgPyBuZXcgRGF0ZSggZGF0ZSApIDogbmV3IERhdGUoKTtcblx0XHRpZiAoIGlzTmFOKCBkYXRlICkgKSB7XG5cdFx0XHR0aHJvdyBTeW50YXhFcnJvciggJ2ludmFsaWQgZGF0ZScgKTtcblx0XHR9XG5cblx0XHRtYXNrID0gU3RyaW5nKCBkRi5tYXNrc1ttYXNrXSB8fCBtYXNrIHx8IGRGLm1hc2tzWydkZWZhdWx0J10gKTtcblxuXHRcdC8vIEFsbG93IHNldHRpbmcgdGhlIHV0YyBhcmd1bWVudCB2aWEgdGhlIG1hc2tcblx0XHRpZiAoIG1hc2suc2xpY2UoIDAsIDQgKSA9PT0gJ1VUQzonICkge1xuXHRcdFx0bWFzayA9IG1hc2suc2xpY2UoIDQgKTtcblx0XHRcdHV0YyA9IHRydWU7XG5cdFx0fVxuXG5cdFx0dmFyIF8gPSB1dGMgPyAnZ2V0VVRDJyA6ICdnZXQnLFxuXHRcdFx0ZCA9IGRhdGVbXyArICdEYXRlJ10oKSxcblx0XHRcdEQgPSBkYXRlW18gKyAnRGF5J10oKSxcblx0XHRcdG0gPSBkYXRlW18gKyAnTW9udGgnXSgpLFxuXHRcdFx0eSA9IGRhdGVbXyArICdGdWxsWWVhciddKCksXG5cdFx0XHRIID0gZGF0ZVtfICsgJ0hvdXJzJ10oKSxcblx0XHRcdE0gPSBkYXRlW18gKyAnTWludXRlcyddKCksXG5cdFx0XHRzID0gZGF0ZVtfICsgJ1NlY29uZHMnXSgpLFxuXHRcdFx0TCA9IGRhdGVbXyArICdNaWxsaXNlY29uZHMnXSgpLFxuXHRcdFx0byA9IHV0YyA/IDAgOiBkYXRlLmdldFRpbWV6b25lT2Zmc2V0KCksXG5cdFx0XHRmbGFncyA9IHtcblx0XHRcdFx0ZDogZCxcblx0XHRcdFx0ZGQ6IHBhZCggZCApLFxuXHRcdFx0XHRkZGQ6IGRGLmkxOG4uZGF5TmFtZXNbRF0sXG5cdFx0XHRcdGRkZGQ6IGRGLmkxOG4uZGF5TmFtZXNbRCArIDddLFxuXHRcdFx0XHRtOiBtICsgMSxcblx0XHRcdFx0bW06IHBhZCggbSArIDEgKSxcblx0XHRcdFx0bW1tOiBkRi5pMThuLm1vbnRoTmFtZXNbbV0sXG5cdFx0XHRcdG1tbW06IGRGLmkxOG4ubW9udGhOYW1lc1ttICsgMTJdLFxuXHRcdFx0XHR5eTogU3RyaW5nKCB5ICkuc2xpY2UoIDIgKSxcblx0XHRcdFx0eXl5eTogeSxcblx0XHRcdFx0aDogSCAlIDEyIHx8IDEyLFxuXHRcdFx0XHRoaDogcGFkKCBIICUgMTIgfHwgMTIgKSxcblx0XHRcdFx0SDogSCxcblx0XHRcdFx0SEg6IHBhZCggSCApLFxuXHRcdFx0XHRNOiBNLFxuXHRcdFx0XHRNTTogcGFkKCBNICksXG5cdFx0XHRcdHM6IHMsXG5cdFx0XHRcdHNzOiBwYWQoIHMgKSxcblx0XHRcdFx0bDogcGFkKCBMLCAzICksXG5cdFx0XHRcdEw6IHBhZCggTCA+IDk5ID8gTWF0aC5yb3VuZCggTCAvIDEwICkgOiBMICksXG5cdFx0XHRcdHQ6IEggPCAxMiA/ICdhJyA6ICdwJyxcblx0XHRcdFx0dHQ6IEggPCAxMiA/ICdhbScgOiAncG0nLFxuXHRcdFx0XHRUOiBIIDwgMTIgPyAnQScgOiAnUCcsXG5cdFx0XHRcdFRUOiBIIDwgMTIgPyAnQU0nIDogJ1BNJyxcblx0XHRcdFx0WjogdXRjID8gJ1VUQycgOiAoIFN0cmluZyggZGF0ZSApLm1hdGNoKCB0aW1lem9uZSApIHx8IFsnJ10gKS5wb3AoKS5yZXBsYWNlKCB0aW1lem9uZUNsaXAsICcnICksXG5cdFx0XHRcdG86ICggbyA+IDAgPyAnLScgOiAnKycgKSArIHBhZCggTWF0aC5mbG9vciggTWF0aC5hYnMoIG8gKSAvIDYwICkgKiAxMDAgKyBNYXRoLmFicyggbyApICUgNjAsIDQgKSxcblx0XHRcdFx0UzogWyd0aCcsICdzdCcsICduZCcsICdyZCddW2QgJSAxMCA+IDMgPyAwIDogKCBkICUgMTAwIC0gZCAlIDEwICE9PSAxMCApICogZCAlIDEwXVxuXHRcdFx0fTtcblxuXHRcdHJldHVybiBtYXNrLnJlcGxhY2UoIHRva2VuLCBmdW5jdGlvbiggJDAgKSB7XG5cdFx0XHRyZXR1cm4gJDAgaW4gZmxhZ3MgPyBmbGFnc1skMF0gOiAkMC5zbGljZSggMSwgJDAubGVuZ3RoIC0gMSApO1xuXHRcdH0gKTtcblx0fTtcblx0LyoganNoaW50IGlnbm9yZTplbmQgKi9cbn0oKTtcblxuLy8gU29tZSBjb21tb24gZm9ybWF0IHN0cmluZ3NcbmRhdGVGb3JtYXQubWFza3MgPSB7XG5cdCdkZWZhdWx0JzogJ2RkZCBtbW0gZGQgeXl5eSBISDpNTTpzcycsXG5cdHNob3J0RGF0ZTogJ20vZC95eScsXG5cdG1lZGl1bURhdGU6ICdtbW0gZCwgeXl5eScsXG5cdGxvbmdEYXRlOiAnbW1tbSBkLCB5eXl5Jyxcblx0ZnVsbERhdGU6ICdkZGRkLCBtbW1tIGQsIHl5eXknLFxuXHRzaG9ydFRpbWU6ICdoOk1NIFRUJyxcblx0bWVkaXVtVGltZTogJ2g6TU06c3MgVFQnLFxuXHRsb25nVGltZTogJ2g6TU06c3MgVFQgWicsXG5cdGlzb0RhdGU6ICd5eXl5LW1tLWRkJyxcblx0aXNvVGltZTogJ0hIOk1NOnNzJyxcblx0aXNvRGF0ZVRpbWU6ICd5eXl5LW1tLWRkXFwnVFxcJ0hIOk1NOnNzJyxcblx0aXNvVXRjRGF0ZVRpbWU6ICdVVEM6eXl5eS1tbS1kZFxcJ1RcXCdISDpNTTpzc1xcJ1pcXCcnXG59O1xuXG4vLyBJbnRlcm5hdGlvbmFsaXphdGlvbiBzdHJpbmdzXG5kYXRlRm9ybWF0LmkxOG4gPSB7XG5cdGRheU5hbWVzOiBbXG5cdFx0J1N1bicsICdNb24nLCAnVHVlJywgJ1dlZCcsICdUaHUnLCAnRnJpJywgJ1NhdCcsXG5cdFx0J1N1bmRheScsICdNb25kYXknLCAnVHVlc2RheScsICdXZWRuZXNkYXknLCAnVGh1cnNkYXknLCAnRnJpZGF5JywgJ1NhdHVyZGF5J1xuXHRdLFxuXHRtb250aE5hbWVzOiBbXG5cdFx0J0phbicsICdGZWInLCAnTWFyJywgJ0FwcicsICdNYXknLCAnSnVuJywgJ0p1bCcsICdBdWcnLCAnU2VwJywgJ09jdCcsICdOb3YnLCAnRGVjJyxcblx0XHQnSmFudWFyeScsICdGZWJydWFyeScsICdNYXJjaCcsICdBcHJpbCcsICdNYXknLCAnSnVuZScsICdKdWx5JywgJ0F1Z3VzdCcsICdTZXB0ZW1iZXInLCAnT2N0b2JlcicsICdOb3ZlbWJlcicsICdEZWNlbWJlcidcblx0XVxufTtcblxuLy8gRm9yIGNvbnZlbmllbmNlLi4uXG5EYXRlLnByb3RvdHlwZS5mb3JtYXQgPSBmdW5jdGlvbiggbWFzaywgdXRjICkge1xuXHQvL0pTIEV4Y2VwdGlvbjogVW5jYXVnaHQgVHlwZUVycm9yOiBDYW5ub3QgcmVhZCBwcm9wZXJ0aWVzIG9mIHVuZGVmaW5lZCAocmVhZGluZyAnZGF0ZV9mb3JtYXQnKVxuXHRpZiAoICFHbG9iYWwuaXNTZXQoIG1hc2sgKSAmJiBMb2NhbENhY2hlRGF0YS5nZXRMb2dpblVzZXJQcmVmZXJlbmNlKCkgKSB7XG5cdFx0bWFzayA9IExvY2FsQ2FjaGVEYXRhLmdldExvZ2luVXNlclByZWZlcmVuY2UoKS5kYXRlX2Zvcm1hdDtcblx0fVxuXG5cdGlmICggIW1hc2sgKSB7XG5cdFx0bWFzayA9ICdERC1NTU0tWVknO1xuXHR9XG5cblx0dmFyIGZvcm1hdF9zdHIgPSBtb21lbnQoIHRoaXMgKS5mb3JtYXQoIG1hc2sgKTtcblxuXHRyZXR1cm4gZm9ybWF0X3N0cjtcbn07XG5cbndpbmRvdy5SaWdodENsaWNrTWVudVR5cGUgPSBmdW5jdGlvbigpIHtcblxufTtcblxuUmlnaHRDbGlja01lbnVUeXBlLkxJU1RWSUVXID0gJzEnO1xuUmlnaHRDbGlja01lbnVUeXBlLkVESVRWSUVXID0gJzInO1xuUmlnaHRDbGlja01lbnVUeXBlLk5PUkVTVUxUQk9YID0gJzMnO1xuUmlnaHRDbGlja01lbnVUeXBlLkFCU0VOQ0VfR1JJRCA9ICc0JztcblJpZ2h0Q2xpY2tNZW51VHlwZS5WSUVXX0lDT04gPSAnNSc7XG5cbi8qKlxuICogRGVjb2RpbmcgZW5jb2RlZCBodG1sIGVuaXRpdGllcyAoaWU6IFwiJmd0O1wiKVxuICogdG8gYXZvaWQgWFNTIHZ1bG5lcmFiaWxpdGllcyBkbyBub3QgZXZhbCBhbnl0aGluZyB0aGF0IGhhcyBnb25lIHRocm91Z2ggdGhpcyBmdW5jdGlvblxuICpcbiAqIEBwYXJhbSBzdHJcbiAqIEByZXR1cm5zIHsqfGpRdWVyeX1cbiAqL1xuR2xvYmFsLmh0bWxEZWNvZGUgPSBmdW5jdGlvbiggc3RyICkge1xuXHRyZXR1cm4gJCggJzx0ZXh0YXJlYT48L3RleHRhcmVhPicgKS5odG1sKCBzdHIgKS50ZXh0KCk7XG59O1xuXG5HbG9iYWwuaHRtbEVuY29kZSA9IGZ1bmN0aW9uKCBzdHIgKSB7XG5cdHZhciBlbmNvZGVkU3RyID0gc3RyO1xuXG5cdGlmICggZW5jb2RlZFN0ciApIHtcblx0XHQvLyBUaGlzIHJlcGxhY2VzICdTJyBpbiAnTVNUJyB3aXRoIHRoZSBlbmNvZGVkIHZhbHVlLCB3aGljaCBpcyBpbnZhbGlkLlxuXHRcdC8vIGVuY29kZWRTdHIgPSBzdHIucmVwbGFjZSggL1tcXHUwMEEwLVxcdTk5OTk8PlxcJ1wiXFwmXS9naW0sIGZ1bmN0aW9uKCBpICkge1xuXHRcdC8vIFx0cmV0dXJuICcmIycgKyBpLmNoYXJDb2RlQXQoIDAgKSArICc7Jztcblx0XHQvLyB9ICk7XG5cdFx0Ly8gZW5jb2RlZFN0ciA9IGVuY29kZWRTdHIucmVwbGFjZSggLyYjNjA7YnImIzYyOy9nLCAnPGJyPicgKTtcblx0XHQvLyByZXR1cm4gZW5jb2RlZFN0cjtcblxuXHRcdHZhciB0bXAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCAnZGl2JyApO1xuXHRcdHRtcC50ZXh0Q29udGVudCA9IGVuY29kZWRTdHI7XG5cblx0XHRyZXR1cm4gdG1wLmlubmVySFRNTDtcblx0fSBlbHNlIHtcblx0XHRyZXR1cm4gZW5jb2RlZFN0cjtcblx0fVxufTtcblxuLy9Tb3J0IGJ5IG1vZHVsZVxuXG5HbG9iYWwubV9zb3J0X2J5ID0gKCBmdW5jdGlvbigpIHtcblx0Ly8gdXRpbGl0eSBmdW5jdGlvbnNcblxuXHR2YXIgZGVmYXVsdF9jbXAgPSBmdW5jdGlvbiggYSwgYiApIHtcblxuXHRcdFx0aWYgKCBhID09PSBiICkge1xuXHRcdFx0XHRyZXR1cm4gMDtcblx0XHRcdH1cblxuXHRcdFx0Ly9TcGVpY2FsIGhhbmRsZSBPUEVOIG9wdGlvbiB0byBtYWtlIGl0IGFsd2F5cyBzdGF5IHRvZ2V0aGVyXG5cdFx0XHRpZiAoIGEgPT09IGZhbHNlIHx8IGEgPT09ICdPUEVOJyApIHtcblx0XHRcdFx0cmV0dXJuIC0xO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIGIgPT09IGZhbHNlIHx8IGIgPT09ICdPUEVOJyApIHtcblx0XHRcdFx0cmV0dXJuIDE7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBhIDwgYiA/IC0xIDogMTtcblx0XHR9LFxuXHRcdGdldENtcEZ1bmMgPSBmdW5jdGlvbiggcHJpbWVyLCByZXZlcnNlICkge1xuXHRcdFx0dmFyIGNtcCA9IGRlZmF1bHRfY21wO1xuXHRcdFx0aWYgKCBwcmltZXIgKSB7XG5cdFx0XHRcdGNtcCA9IGZ1bmN0aW9uKCBhLCBiICkge1xuXHRcdFx0XHRcdHJldHVybiBkZWZhdWx0X2NtcCggcHJpbWVyKCBhICksIHByaW1lciggYiApICk7XG5cdFx0XHRcdH07XG5cdFx0XHR9XG5cdFx0XHRpZiAoIHJldmVyc2UgKSB7XG5cdFx0XHRcdHJldHVybiBmdW5jdGlvbiggYSwgYiApIHtcblx0XHRcdFx0XHRyZXR1cm4gLTEgKiBjbXAoIGEsIGIgKTtcblx0XHRcdFx0fTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBjbXA7XG5cdFx0fTtcblxuXHQvLyBhY3R1YWwgaW1wbGVtZW50YXRpb25cblx0dmFyIHNvcnRfYnkgPSBmdW5jdGlvbiggc29ydF9ieV9hcnJheSApIHtcblx0XHR2YXIgZmllbGRzID0gW10sXG5cdFx0XHRuX2ZpZWxkcyA9IHNvcnRfYnlfYXJyYXkubGVuZ3RoLFxuXHRcdFx0ZmllbGQsIG5hbWUsIHJldmVyc2UsIGNtcDtcblxuXHRcdC8vIHByZXByb2Nlc3Mgc29ydGluZyBvcHRpb25zXG5cdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgbl9maWVsZHM7IGkrKyApIHtcblx0XHRcdGZpZWxkID0gc29ydF9ieV9hcnJheVtpXTtcblx0XHRcdGlmICggdHlwZW9mIGZpZWxkID09PSAnc3RyaW5nJyApIHtcblx0XHRcdFx0bmFtZSA9IGZpZWxkO1xuXHRcdFx0XHRjbXAgPSBkZWZhdWx0X2NtcDtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdG5hbWUgPSBmaWVsZC5uYW1lO1xuXHRcdFx0XHRjbXAgPSBnZXRDbXBGdW5jKCBmaWVsZC5wcmltZXIsIGZpZWxkLnJldmVyc2UgKTtcblx0XHRcdH1cblx0XHRcdGZpZWxkcy5wdXNoKCB7XG5cdFx0XHRcdG5hbWU6IG5hbWUsXG5cdFx0XHRcdGNtcDogY21wXG5cdFx0XHR9ICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGZ1bmN0aW9uKCBBLCBCICkge1xuXHRcdFx0dmFyIGEsIGIsIG5hbWUsIGNtcCwgcmVzdWx0O1xuXHRcdFx0Zm9yICggdmFyIGkgPSAwLCBsID0gbl9maWVsZHM7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRcdHJlc3VsdCA9IDA7XG5cdFx0XHRcdGZpZWxkID0gZmllbGRzW2ldO1xuXHRcdFx0XHRuYW1lID0gZmllbGQubmFtZTtcblx0XHRcdFx0Y21wID0gZmllbGQuY21wO1xuXG5cdFx0XHRcdHJlc3VsdCA9IGNtcCggQVtuYW1lXSwgQltuYW1lXSApO1xuXHRcdFx0XHRpZiAoIHJlc3VsdCAhPT0gMCApIHtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHR9O1xuXHR9O1xuXG5cdHJldHVybiBzb3J0X2J5O1xuXG59KCkgKTtcblxuJC5mbi5pbnZpc2libGUgPSBmdW5jdGlvbigpIHtcblx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0JCggdGhpcyApLmNzcyggJ29wYWNpdHknLCAnMCcgKTtcblx0fSApO1xufTtcbiQuZm4udmlzaWJsZSA9IGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHQkKCB0aGlzICkuY3NzKCAnb3BhY2l0eScsICcxJyApO1xuXHR9ICk7XG59O1xuXG5HbG9iYWwudHJhY2tWaWV3ID0gZnVuY3Rpb24oIG5hbWUsIGFjdGlvbiApIHtcblx0aWYgKCBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEuYW5hbHl0aWNzX2VuYWJsZWQgPT09IHRydWUgKSB7XG5cdFx0dmFyIHRyYWNrX2FkZHJlc3M7XG5cblx0XHQvL0hvc3RuYW1lIGlzIGFscmVhZHkgc2VudCBzZXBhcmF0ZWx5LCBzbyB0aGlzIHNob3VsZCBqdXN0IGJlIHRoZSB2aWV3L2FjdGlvbiBpbiBmb3JtYXQ6XG5cdFx0Ly8gJyMhbT0nICsgbmFtZSArICcmYT0nICsgYWN0aW9uXG5cdFx0aWYgKCBuYW1lICkge1xuXHRcdFx0dHJhY2tfYWRkcmVzcyA9ICcjIW09JyArIG5hbWU7XG5cblx0XHRcdGlmICggYWN0aW9uICkge1xuXHRcdFx0XHR0cmFja19hZGRyZXNzICs9ICcmYT0nICsgYWN0aW9uO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHQvL0RlZmF1bHQgdG8gb25seSBkYXRhIGFmdGVyIChhbmQgaW5jbHVkaW5nKSB0aGUgIy5cblx0XHRcdHRyYWNrX2FkZHJlc3MgPSB3aW5kb3cubG9jYXRpb24uaGFzaC5zdWJzdHJpbmcoIDEgKTtcblx0XHR9XG5cblx0XHQvL1RyYWNrIGFkZHJlc3MgaXMgc2VudCBpbiBzZW5kQW5hbHl0aWNzIGFzIHRoZSAzcmQgcGFyYW1ldGVyLlxuXHRcdEdsb2JhbC5zZW5kQW5hbHl0aWNzUGFnZXZpZXcoIHRyYWNrX2FkZHJlc3MgKTtcblx0fVxufTtcblxuR2xvYmFsLnNldEFuYWx5dGljRGltZW5zaW9ucyA9IGZ1bmN0aW9uKCB1c2VyX25hbWUsIGNvbXBhbnlfbmFtZSApIHtcblx0aWYgKCBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEuYW5hbHl0aWNzX2VuYWJsZWQgPT09IHRydWUgKSB7XG5cdFx0aWYgKCB0eXBlb2YgKCBndGFnICkgIT09ICd1bmRlZmluZWQnICkge1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0Ly9BbGwgbmFtZXMgbXVzdCBiZSBtYXBwZWQgaW4gbWFpbi5qcyAnY3VzdG9tX21hcCdcblx0XHRcdFx0dmFyIHVzZXJfcHJvcGVydGllcyA9IHtcblx0XHRcdFx0XHQnYXBwbGljYXRpb25fdmVyc2lvbic6IEFQSUdsb2JhbC5wcmVfbG9naW5fZGF0YS5hcHBsaWNhdGlvbl92ZXJzaW9uLFxuXHRcdFx0XHRcdCdodHRwX2hvc3QnOiBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEuaHR0cF9ob3N0LFxuXHRcdFx0XHRcdCdwcm9kdWN0X2VkaXRpb25fbmFtZSc6IEFQSUdsb2JhbC5wcmVfbG9naW5fZGF0YS5wcm9kdWN0X2VkaXRpb25fbmFtZSxcblx0XHRcdFx0XHQncmVnaXN0cmF0aW9uX2tleSc6IEFQSUdsb2JhbC5wcmVfbG9naW5fZGF0YS5yZWdpc3RyYXRpb25fa2V5LFxuXHRcdFx0XHRcdCdwcmltYXJ5X2NvbXBhbnlfbmFtZSc6IEFQSUdsb2JhbC5wcmVfbG9naW5fZGF0YS5wcmltYXJ5X2NvbXBhbnlfbmFtZSxcblx0XHRcdFx0fTtcblxuXHRcdFx0XHRpZiAoIHVzZXJfbmFtZSAhPT0gJ3VuZGVmaW5lZCcgJiYgdXNlcl9uYW1lICE9PSBudWxsICkge1xuXHRcdFx0XHRcdGlmICggQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLnByb2R1Y3Rpb24gIT09IHRydWUgKSB7XG5cdFx0XHRcdFx0XHREZWJ1Zy5UZXh0KCAnQW5hbHl0aWNzIFVzZXI6ICcgKyB1c2VyX25hbWUsICdHbG9iYWwuanMnLCAnJywgJ2RvUGluZycsIDEgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0dXNlcl9wcm9wZXJ0aWVzLnVzZXJfbmFtZSA9IHVzZXJfbmFtZTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmICggY29tcGFueV9uYW1lICE9PSAndW5kZWZpbmVkJyAmJiBjb21wYW55X25hbWUgIT09IG51bGwgKSB7XG5cdFx0XHRcdFx0aWYgKCBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEucHJvZHVjdGlvbiAhPT0gdHJ1ZSApIHtcblx0XHRcdFx0XHRcdERlYnVnLlRleHQoICdBbmFseXRpY3MgQ29tcGFueTogJyArIGNvbXBhbnlfbmFtZSwgJ0dsb2JhbC5qcycsICcnLCAnc2V0QW5hbHl0aWNEaW1lbnNpb25zJywgMSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHR1c2VyX3Byb3BlcnRpZXMuY29tcGFueV9uYW1lID0gY29tcGFueV9uYW1lO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Z3RhZyggJ3NldCcsICd1c2VyX3Byb3BlcnRpZXMnLCB1c2VyX3Byb3BlcnRpZXMgKTtcblx0XHRcdH0gY2F0Y2ggKCBlICkge1xuXHRcdFx0XHR0aHJvdyBlOyAvL0F0dGVtcHQgdG8gY2F0Y2ggYW55IGVycm9ycyB0aHJvd24gYnkgR29vZ2xlIEFuYWx5dGljcy5cblx0XHRcdH1cblx0XHR9XG5cdH1cbn07XG5cbkdsb2JhbC5zZW5kQW5hbHl0aWNzUGFnZXZpZXcgPSBmdW5jdGlvbiggdHJhY2tfYWRkcmVzcyApIHtcblx0aWYgKCBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEuYW5hbHl0aWNzX2VuYWJsZWQgPT09IHRydWUgKSB7XG5cdFx0Ly8gQ2FsbCB0aGlzIGRlbGF5IHNvIHZpZXcgbG9hZCBnb2VzIGZpcnN0XG5cdFx0aWYgKCB0eXBlb2YgKCBndGFnICkgIT09ICd1bmRlZmluZWQnICkge1xuXHRcdFx0c2V0VGltZW91dCggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0Z3RhZyggJ2V2ZW50JywgJ3BhZ2VfdmlldycsIHsgcGFnZV9wYXRoOiB0cmFja19hZGRyZXNzIH0gKVxuXHRcdFx0XHR9IGNhdGNoICggZSApIHtcblx0XHRcdFx0XHR0aHJvdyBlO1xuXHRcdFx0XHR9XG5cdFx0XHR9LCA1MDAgKTtcblx0XHR9XG5cblx0fVxufTtcblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gYWN0dWFsbHkgc3VibWl0IHRoZSBhbmFseXRpY3MgcmVxdWVzdCB0byBnb29nbGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRfY2F0ZWdvcnkgLSBDYXRlZ29yeSByZWxhdGluZyB0byB0aGUgZXZlbnQgdHJhY2tlZCwgZS5nLiBmZWVkYmFjayBvciBjb250ZXh0X21lbnVcbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudF9hY3Rpb24gLSBXaGF0IHRyaWdnZXJlZCB0aGUgZXZlbnQuIEUuZy4gY2xpY2ssIGNhbmNlbC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudF9sYWJlbCAtIFRoaXMgaXMgb2Z0ZW4gYSBjb21ibyBvZiB0aGUgYWN0dWFsIHZhbHVlIHN0cmluZyBjb21iaW5lZCB3aXRoIHNvbWUgb2YgdGhlIGFib3ZlIGZpZWxkcywgZm9yIGNsYXJpdHkuIGUuZy4gc3VibWl0OmZlZWRiYWNrOnNhZFxuICovXG5HbG9iYWwuc2VuZEFuYWx5dGljc0V2ZW50ID0gZnVuY3Rpb24oIGV2ZW50X2NhdGVnb3J5LCBldmVudF9hY3Rpb24sIGV2ZW50X2xhYmVsICkge1xuXHRpZiAoIHR5cGVvZiAoIGd0YWcgKSAhPT0gJ3VuZGVmaW5lZCcgJiYgQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLmFuYWx5dGljc19lbmFibGVkID09PSB0cnVlICkge1xuXHRcdC8vRGVidWcuQXJyKCBmaWVsZHNPYmplY3QsICdTZW5kaW5nIGFuYWx5dGljcyBldmVudCBwYXlsb2FkLiBFdmVudDogJyArIGV2ZW50X2NhdGVnb3J5ICsgJywgQWN0aW9uOiAnICsgZXZlbnRfYWN0aW9uICsgJywgTGFiZWw6ICcgKyBldmVudF9sYWJlbCwgJ0dsb2JhbC5qcycsICdHbG9iYWwnLCAnc2VuZEFuYWx5dGljc0V2ZW50JywgMTEgKTtcblx0XHR0cnkge1xuXHRcdFx0Z3RhZyggJ2V2ZW50JywgZXZlbnRfY2F0ZWdvcnksIHsgYWN0aW9uOiBldmVudF9hY3Rpb24sIGxhYmVsOiBldmVudF9sYWJlbCB9IClcblx0XHR9IGNhdGNoICggZSApIHtcblx0XHRcdHRocm93IGU7XG5cdFx0fVxuXHR9XG59O1xuXG4vKipcbiAqXG4gKiBAcGFyYW0gY29udGV4dF9idG4gLSB0aGUgalF1ZXJ5IGVsZW1lbnQgdGhhdCB0cmlnZ2VyZWQgdGhlIGNsaWNrIGV2ZW50IG9uIHRoZSBjb250ZXh0IG1lbnVcbiAqIEBwYXJhbSB7c3RyaW5nfSBtZW51X25hbWUgLSB0aGUgbmFtZSBvZiB0aGUgaWNvbiBpZiB0aGUgY2xpY2sgZXZlbnQgd2FzIHRyaWdnZXJlZCBieSB0aGUgcmlnaHQgY2xpY2sgY29udGV4dCBtZW51XG4gKi9cbkdsb2JhbC50cmlnZ2VyQW5hbHl0aWNzQ29udGV4dE1lbnVDbGljayA9IGZ1bmN0aW9uKCBjb250ZXh0X2J0biwgbWVudV9uYW1lICkge1xuXHQvLyBJZiBtb3JlIGRldGFpbCBpcyBuZWVkZWQgYWJvdmUgYW5kIGJleW9uZCBjb250ZXh0bWVudSBuYW1lLCB0aGVuIHVzZSAnTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ZpZXdfaWQnIGluIGFkZGl0aW9uLCBidXQgbm90IGluc3RlYWQgb2YsIGFzIHRoZXkgYXJlIGRpZmZlcmVudC5cblx0dmFyIGRvbV9jb250ZXh0X21lbnUgPSBMb2NhbENhY2hlRGF0YS5jdXJyZW50U2hvd25Db250ZXh0TWVudU5hbWUgfHwgJ2Vycm9yLXdpdGgtY29udGV4dC1tZW51JzsgLy8gJ3x8JyBpcyBmb3IgZ3JhY2VmdWwgZmFpbC4gaWRlbnRpZnkgY29ycmVjdCBjb250ZXh0IG1lbnUgKHZzIERPTSBzZWFyY2gsIHdoZXJlIHRoZXJlIGNvdWxkIGJlIG11bHRpcGxlIGluYWN0aXZlIGNvbnRleHQgbWVudXMpXG5cdHZhciBkb21fY29udGV4dF9tZW51X2dyb3VwO1xuXHR2YXIgYnV0dG9uX2lkO1xuXHR2YXIgZXZlbnRfY2F0ZWdvcnk7XG5cdHZhciBldmVudF9hY3Rpb247XG5cdHZhciBldmVudF9sYWJlbDtcblxuXHRpZiAoIGNvbnRleHRfYnRuICkge1xuXHRcdGlmICggY29udGV4dF9idG4uZ3JvdXAgJiYgY29udGV4dF9idG4uZ3JvdXAubGFiZWwgKSB7XG5cdFx0XHRkb21fY29udGV4dF9tZW51X2dyb3VwID0gY29udGV4dF9idG4uZ3JvdXAubGFiZWw7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGRvbV9jb250ZXh0X21lbnVfZ3JvdXAgPSBjb250ZXh0X2J0bi5hY3Rpb25fZ3JvdXA7XG5cdFx0fVxuXHRcdGV2ZW50X2NhdGVnb3J5ID0gJ25hdmlnYXRpb246Y29udGV4dF9tZW51Jztcblx0XHRidXR0b25faWQgPSBjb250ZXh0X2J0bi5pZCB8fCAnZXJyb3Itd2l0aC1pY29uJztcblx0fSBlbHNlIHtcblx0XHQvLyBJZiBjb250ZXh0X2J0biBpcyBudWxsLCB0aGVuIHRoaXMgaXMgbGlrZWx5IGEgcmlnaHQgY2xpY2sgY29udGV4dCBtZW51IGNhbGwuXG5cdFx0ZXZlbnRfY2F0ZWdvcnkgPSAnbmF2aWdhdGlvbjpyaWdodF9jbGlja19tZW51Jztcblx0XHRkb21fY29udGV4dF9tZW51X2dyb3VwID0gJ3JpZ2h0X2NsaWNrJztcblx0XHRidXR0b25faWQgPSBtZW51X25hbWUgfHwgJ2Vycm9yLXdpdGgtcmlnaHRjbGljay1pY29uJztcblx0fVxuXG5cdC8vIEJlYXV0aWZ5IG91dHB1dFxuXHRkb21fY29udGV4dF9tZW51ID0gZG9tX2NvbnRleHRfbWVudS5yZXBsYWNlKCAnQ29udGV4dE1lbnUnLCAnJyApO1xuXHRidXR0b25faWQgPSBidXR0b25faWQucmVwbGFjZSggJ0ljb24nLCAnJyApOyAvL1JlbW92ZSBcImljb25cIiBmcm9tIGJ1dHRvbl9pZC5cblxuXHRldmVudF9hY3Rpb24gPSAnY2xpY2snO1xuXHRldmVudF9sYWJlbCA9IGRvbV9jb250ZXh0X21lbnUgKyAnOicgKyBkb21fY29udGV4dF9tZW51X2dyb3VwICsgJ3wnICsgYnV0dG9uX2lkO1xuXG5cdC8vIERlYnVnLlRleHQoICdDb250ZXh0IE1lbnU6IENhdGVnb3J5OiBuYXZpZ2F0aW9uX2NvbnRleHRfbWVudSBBY3Rpb246ICcgKyBldmVudF9hY3Rpb24gKyAnIExhYmVsOiAnICsgZXZlbnRfbGFiZWwsICdHbG9iYWwuanMnLCAnR2xvYmFsJywgJ3RyaWdnZXJBbmFseXRpY3NDb250ZXh0TWVudUNsaWNrJywgMTAgKTtcblx0R2xvYmFsLnNlbmRBbmFseXRpY3NFdmVudCggZXZlbnRfY2F0ZWdvcnksIGV2ZW50X2FjdGlvbiwgZXZlbnRfbGFiZWwgKTtcbn07XG5cbi8qKlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBjb250ZXh0IC0gRXhwbGFpbnMgd2hhdCBlbGVtZW50IHRyaWdnZXJlZCB0aGUgZXZlbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSB2aWV3X2lkIC0gTmFtZSBvZiB0aGUgY3VycmVudCB2aWV3IGluIHdoaWNoIGVsZW1lbnQgd2FzIHRyaWdnZXJlZFxuICovXG5HbG9iYWwudHJpZ2dlckFuYWx5dGljc0VkaXRWaWV3TmF2aWdhdGlvbiA9IGZ1bmN0aW9uKCBjb250ZXh0LCB2aWV3X2lkICkge1xuXHQvLyBjb250ZXh0IGluIHRoaXMgY2FzZSBjYW4gYmUgJ2xlZnQtYXJyb3cnLCAncmlnaHQtYXJyb3cnLCBvciAnYXdlc29tZWJveCdcblx0dmFyIGV2ZW50X2FjdGlvbiA9ICdjbGljayc7XG5cdHZhciBldmVudF9sYWJlbCA9IHZpZXdfaWQgKyAnOicgKyBjb250ZXh0O1xuXG5cdC8vIERlYnVnLlRleHQoICdDb250ZXh0IE1lbnU6IENhdGVnb3J5OiBuYXZpZ2F0aW9uX2VkaXRfdmlld19uYXZpZ2F0aW9uIEFjdGlvbjogJyArIGV2ZW50X2FjdGlvbiArICcgTGFiZWw6ICcgKyBldmVudF9sYWJlbCwgJ0dsb2JhbC5qcycsICdHbG9iYWwnLCAndHJpZ2dlckFuYWx5dGljc0NvbnRleHRNZW51Q2xpY2snLCAxMCApO1xuXHRHbG9iYWwuc2VuZEFuYWx5dGljc0V2ZW50KCAnbmF2aWdhdGlvbjplZGl0X3ZpZXdfbmF2aWdhdGlvbicsIGV2ZW50X2FjdGlvbiwgZXZlbnRfbGFiZWwgKTtcbn07XG5cbi8qKlxuICpcbiAqIEBwYXJhbSBldmVudCAtIHRoZSBldmVudCBvYmplY3QgZnJvbSB0aGUgalF1ZXJ5IFVJIHRhYnMuIEN1cnJlbnRseSBleHBlY3RpbmcgaXQgdG8gYmUgdHJpZ2dlcmVkIGJ5IHRoZSBhY3RpdmF0ZSBldmVudFxuICogQHBhcmFtIHVpIC0gdGhlIHVpIG9iamVjdCBmcm9tIGpRdWVyeSBVSSB0YWJzLCBjb250YWlucyBwcmV2IGFuZCB0YXJnZXQgdGFiIGluZm9cbiAqL1xuR2xvYmFsLnRyaWdnZXJBbmFseXRpY3NUYWJzID0gZnVuY3Rpb24oIGV2ZW50LCB1aSApIHtcblx0Ly8gYWN0aXZhdGUgZXZlbnQgdHJpZ2dlcmVkLCBlbnN1cmUgYWxsIHJlcXVpcmVkIHZhbHVlcyBhcmUgc2V0XG5cdGlmICggZXZlbnQgJiYgZXZlbnQudHlwZSAmJiB1aSAmJiB1aS5uZXdUYWIgKSB7XG5cdFx0dmFyIHRhYl90YXJnZXQgPSB1aS5uZXdUYWIuZmluZCggJy51aS10YWJzLWFuY2hvcicgKS5hdHRyKCAncmVmJyApIHx8ICd0YWItdGFyZ2V0LWVycm9yJzsgLy8gJ3x8JyBpcyBmb3IgZ3JhY2Z1bCBmYWlsXG5cdFx0dmFyIHZpZXdJZCA9IExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl92aWV3X2lkIHx8ICdlcnJvci12aWV3aWQnOyAvLyAnfHwnIGlzIGZvciBncmFjZWZ1bCBmYWlsXG5cblx0XHQvLyBCZWF1dGlmeSBvdXRwdXRcblx0XHR0YWJfdGFyZ2V0ID0gdGFiX3RhcmdldC5yZXBsYWNlKCAndGFiXycsICcnICk7XG5cblx0XHR2YXIgZXZlbnRfYWN0aW9uID0gJ2NsaWNrJztcblx0XHR2YXIgZXZlbnRfbGFiZWwgPSB2aWV3SWQgKyAnOnRhYnM6JyArIHRhYl90YXJnZXQ7XG5cblx0XHQvLyBEZWJ1Zy5UZXh0KCAnQ29udGV4dCBNZW51OiBDYXRlZ29yeTogbmF2aWdhdGlvbl90YWJzIEFjdGlvbjogJyArIGV2ZW50X2FjdGlvbiArICcgTGFiZWw6ICcgKyBldmVudF9sYWJlbCwgJ0dsb2JhbC5qcycsICdHbG9iYWwnLCAndHJpZ2dlckFuYWx5dGljc0NvbnRleHRNZW51Q2xpY2snLCAxMCApO1xuXHRcdEdsb2JhbC5zZW5kQW5hbHl0aWNzRXZlbnQoICduYXZpZ2F0aW9uOnRhYnMnLCBldmVudF9hY3Rpb24sIGV2ZW50X2xhYmVsICk7XG5cdH0gZWxzZSB7XG5cdFx0R2xvYmFsLnNlbmRBbmFseXRpY3NFdmVudCggJ2Vycm9yOm5hdmlnYXRpb246dGFicycsICdlcnJvci10YWJzJywgJ2Vycm9yJyApOyAvLyBTaG91bGQgbmV2ZXIgYmUgdHJpZ2dlcmVkLiBJZiB0aGlzIGFwcGVhcnMgaW4gYW5hbHl0aWNzIHJlc3VsdHMsIGludmVzdGlnYXRlLlxuXHR9XG59O1xuXG4vKipcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gY29udGV4dCAtIHRoZSBsYWJlbCBvZiB0aGUgb2JqZWN0IGludm9sdmVkIGluIHRoZSBldmVudC4gRS5nLiBjbG9zZSBidXR0b24gZm9yIGNsaWNrIGV2ZW50XG4gKiBAcGFyYW0ge3N0cmluZ30gYWN0aW9uIC0gdGhlIGFjdGlvbiB0eXBlIG9mIHRoZSBldmVudC4gRS5nLiBjbGljay5cbiAqIEBwYXJhbSB7c3RyaW5nfSB2aWV3X2lkIC0gdGhlIHZpZXdJZCBpbiB3aGljaCB0aGUgZXZlbnQgb2NjdXJyZWQuIEUuZy4gVGltZVNoZWV0LlxuICovXG5HbG9iYWwudHJpZ2dlckFuYWx5dGljc05hdmlnYXRpb25PdGhlciA9IGZ1bmN0aW9uKCBjb250ZXh0LCBhY3Rpb24sIHZpZXdfaWQgKSB7XG5cdHZhciBldmVudF9hY3Rpb24gPSBhY3Rpb247XG5cdHZhciBldmVudF9sYWJlbCA9IHZpZXdfaWQgKyAnOicgKyBjb250ZXh0O1xuXG5cdC8vIERlYnVnLlRleHQoICdDb250ZXh0IE1lbnU6IENhdGVnb3J5OiBuYXZpZ2F0aW9uX290aGVyIEFjdGlvbjogJyArIGV2ZW50X2FjdGlvbiArICcgTGFiZWw6ICcgKyBldmVudF9sYWJlbCwgJ0dsb2JhbC5qcycsICdHbG9iYWwnLCAndHJpZ2dlckFuYWx5dGljc0NvbnRleHRNZW51Q2xpY2snLCAxMCApO1xuXHRHbG9iYWwuc2VuZEFuYWx5dGljc0V2ZW50KCAnbmF2aWdhdGlvbjpvdGhlcicsIGV2ZW50X2FjdGlvbiwgZXZlbnRfbGFiZWwgKTtcbn07XG5cbkdsb2JhbC5nZXRTZXNzaW9uSURLZXkgPSBmdW5jdGlvbigpIHtcblx0aWYgKCBMb2NhbENhY2hlRGF0YS5nZXRBbGxVUkxBcmdzKCkgKSB7XG5cdFx0aWYgKCBMb2NhbENhY2hlRGF0YS5nZXRBbGxVUkxBcmdzKCkuaGFzT3duUHJvcGVydHkoICdjb21wYW55X2lkJyApICkge1xuXHRcdFx0cmV0dXJuICdTZXNzaW9uSUQtSkEnO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gJ1Nlc3Npb25JRCc7XG59O1xuXG5HbG9iYWwubG9hZFN0eWxlU2hlZXQgPSBmdW5jdGlvbiggcGF0aCwgZm4sIHNjb3BlICkge1xuXHR2YXIgaGVhZCA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCAnaGVhZCcgKVswXSwgLy8gcmVmZXJlbmNlIHRvIGRvY3VtZW50LmhlYWQgZm9yIGFwcGVuZGluZy8gcmVtb3ZpbmcgbGluayBub2Rlc1xuXHRcdGxpbmsgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCAnbGluaycgKTsgICAgICAgICAgIC8vIGNyZWF0ZSB0aGUgbGluayBub2RlXG5cdGxpbmsuc2V0QXR0cmlidXRlKCAnaHJlZicsIHBhdGggKTtcblx0bGluay5zZXRBdHRyaWJ1dGUoICdyZWwnLCAnc3R5bGVzaGVldCcgKTtcblx0bGluay5zZXRBdHRyaWJ1dGUoICd0eXBlJywgJ3RleHQvY3NzJyApO1xuXHR2YXIgc2hlZXQsIGNzc1J1bGVzO1xuXHQvLyBnZXQgdGhlIGNvcnJlY3QgcHJvcGVydGllcyB0byBjaGVjayBmb3IgZGVwZW5kaW5nIG9uIHRoZSBicm93c2VyXG5cdGlmICggJ3NoZWV0JyBpbiBsaW5rICkge1xuXHRcdHNoZWV0ID0gJ3NoZWV0Jztcblx0XHRjc3NSdWxlcyA9ICdjc3NSdWxlcyc7XG5cdH0gZWxzZSB7XG5cdFx0c2hlZXQgPSAnc3R5bGVTaGVldCc7XG5cdFx0Y3NzUnVsZXMgPSAncnVsZXMnO1xuXHR9XG5cdHZhciBpbnRlcnZhbF9pZCA9IHNldEludGVydmFsKCBmdW5jdGlvbigpIHsgICAgICAgICAgICAgICAgICAgICAvLyBzdGFydCBjaGVja2luZyB3aGV0aGVyIHRoZSBzdHlsZSBzaGVldCBoYXMgc3VjY2Vzc2Z1bGx5IGxvYWRlZFxuXHRcdFx0dHJ5IHtcblx0XHRcdFx0aWYgKCBsaW5rW3NoZWV0XSAmJiBsaW5rW3NoZWV0XVtjc3NSdWxlc10ubGVuZ3RoICkgeyAvLyBTVUNDRVNTISBvdXIgc3R5bGUgc2hlZXQgaGFzIGxvYWRlZFxuXHRcdFx0XHRcdGNsZWFySW50ZXJ2YWwoIGludGVydmFsX2lkICk7ICAgICAgICAgICAgICAgICAgICAgIC8vIGNsZWFyIHRoZSBjb3VudGVyc1xuXHRcdFx0XHRcdGNsZWFyVGltZW91dCggdGltZW91dF9pZCApO1xuXHRcdFx0XHRcdGlmICggdHlwZW9mIGZuID09ICdmdW5jdGlvbicgKSB7XG5cdFx0XHRcdFx0XHRmbi5jYWxsKCBzY29wZSB8fCB3aW5kb3csIHRydWUsIGxpbmsgKTsgICAgICAgICAgIC8vIGZpcmUgdGhlIGNhbGxiYWNrIHdpdGggc3VjY2VzcyA9PSB0cnVlXG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9IGNhdGNoICggZSApIHtcblx0XHRcdH0gZmluYWxseSB7XG5cdFx0XHR9XG5cdFx0fSwgMTAgKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBob3cgb2Z0ZW4gdG8gY2hlY2sgaWYgdGhlIHN0eWxlc2hlZXQgaXMgbG9hZGVkXG5cdFx0dGltZW91dF9pZCA9IHNldFRpbWVvdXQoIGZ1bmN0aW9uKCkgeyAgICAgICAvLyBzdGFydCBjb3VudGluZyBkb3duIHRpbGwgZmFpbFxuXHRcdFx0Y2xlYXJJbnRlcnZhbCggdGltZW91dF9pZCApOyAgICAgICAgICAgICAvLyBjbGVhciB0aGUgY291bnRlcnNcblx0XHRcdGNsZWFyVGltZW91dCggdGltZW91dF9pZCApO1xuXHRcdFx0aGVhZC5yZW1vdmVDaGlsZCggbGluayApOyAgICAgICAgICAgICAgICAvLyBzaW5jZSB0aGUgc3R5bGUgc2hlZXQgZGlkbid0IGxvYWQsIHJlbW92ZSB0aGUgbGluayBub2RlIGZyb20gdGhlIERPTVxuXHRcdFx0aWYgKCB0eXBlb2YgZm4gPT0gJ2Z1bmN0aW9uJyApIHtcblx0XHRcdFx0Zm4uY2FsbCggc2NvcGUgfHwgd2luZG93LCBmYWxzZSwgbGluayApOyAvLyBmaXJlIHRoZSBjYWxsYmFjayB3aXRoIHN1Y2Nlc3MgPT0gZmFsc2Vcblx0XHRcdH1cblx0XHR9LCAxNTAwMCApOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGhvdyBsb25nIHRvIHdhaXQgYmVmb3JlIGZhaWxpbmdcblx0aGVhZC5hcHBlbmRDaGlsZCggbGluayApOyAgLy8gaW5zZXJ0IHRoZSBsaW5rIG5vZGUgaW50byB0aGUgRE9NIGFuZCBzdGFydCBsb2FkaW5nIHRoZSBzdHlsZSBzaGVldFxuXHRyZXR1cm4gbGluazsgLy8gcmV0dXJuIHRoZSBsaW5rIG5vZGU7XG59O1xuXG5HbG9iYWwuZ2V0U2Vzc2lvbklES2V5ID0gZnVuY3Rpb24oKSB7XG5cdGlmICggTG9jYWxDYWNoZURhdGEuZ2V0QWxsVVJMQXJncygpICkge1xuXHRcdGlmICggTG9jYWxDYWNoZURhdGEuZ2V0QWxsVVJMQXJncygpLmhhc093blByb3BlcnR5KCAnY29tcGFueV9pZCcgKSApIHtcblx0XHRcdHJldHVybiAnU2Vzc2lvbklELUpBJztcblx0XHR9XG5cdFx0aWYgKCBMb2NhbENhY2hlRGF0YS5nZXRBbGxVUkxBcmdzKCkuaGFzT3duUHJvcGVydHkoICdwdW5jaF91c2VyX2lkJyApICkge1xuXHRcdFx0cmV0dXJuICdTZXNzaW9uSUQtUVAnO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gJ1Nlc3Npb25JRCc7XG59O1xuXG4vL2Rvbid0IGxldCB0aGUgdXNlciBsZWF2ZSB3aXRob3V0IGNsaWNraW5nIE9LLlxuLy91c2VzIGxvY2FsY2FjaGVkYXRhIHNvIHRoYXQgaXQgd2lsbCB3b3JrIGluIHRoZSByaWJib25cbkdsb2JhbC5jaGVja0JlZm9yZUV4aXQgPSBmdW5jdGlvbiggZnVuY3Rpb25Ub0V4ZWN1dGUgKSB7XG5cdHZhciBhbGVydF9tZXNzYWdlID0gR2xvYmFsLm1vZGlmeV9hbGVydF9tZXNzYWdlO1xuXHRpZiAoIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9lZGl0X29ubHlfY29udHJvbGxlciAmJiBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fZWRpdF9vbmx5X2NvbnRyb2xsZXIuY29uZmlybV9vbl9leGl0ICYmIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9lZGl0X29ubHlfY29udHJvbGxlci5pc19jaGFuZ2VkID09PSBmYWxzZSApIHtcblx0XHRhbGVydF9tZXNzYWdlID0gR2xvYmFsLmNvbmZpcm1fb25fZXhpdF9tZXNzYWdlO1xuXHR9XG5cblx0VEFsZXJ0TWFuYWdlci5zaG93Q29uZmlybUFsZXJ0KCBhbGVydF9tZXNzYWdlLCBudWxsLCBmdW5jdGlvbiggY2xpY2tlZF95ZXMgKSB7XG5cdFx0aWYgKCBjbGlja2VkX3llcyA9PT0gdHJ1ZSApIHtcblx0XHRcdGZ1bmN0aW9uVG9FeGVjdXRlKCBjbGlja2VkX3llcyApO1xuXHRcdH1cblx0fSApO1xufTtcblxuR2xvYmFsLmRldGVjdE1vYmlsZUJyb3dzZXIgPSBmdW5jdGlvbigpIHtcblx0cmV0dXJuIC9BbmRyb2lkfHdlYk9TfGlQaG9uZXxpUGFkfGlQb2R8QmxhY2tCZXJyeS9pLnRlc3QoIG5hdmlnYXRvci51c2VyQWdlbnQgKTtcbn07XG5cbkdsb2JhbC5nZXRCcm93c2VyVmVuZG9yID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEudXNlcl9hZ2VudF9kYXRhLmJyb3dzZXI7XG59O1xuLyoqXG4gKiBBbGxvd2luZyBkZWVwIGxpbmtpbmdcbiAqIEB0eXBlIHtib29sZWFufVxuICovXG5HbG9iYWwuZGVlcGxpbmsgPSBmYWxzZTtcblxuR2xvYmFsLmdldERlZXBMaW5rID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiBHbG9iYWwuZGVlcGxpbms7XG59O1xuXG4vKipcbiAqIFJldHJpZXZlcyB0aGUgZGVlcGxpbmsgZnJvbSB0aGUgY3VycmVudCB1cmwuXG4gKi9cbkdsb2JhbC5zZXREZWVwTGluayA9IGZ1bmN0aW9uKCkge1xuXHR2YXIgbmV3RGVlcExpbmsgPSB3aW5kb3cubG9jYXRpb24uaHJlZi5zcGxpdCggJyMhbT0nIClbMV07XG5cblx0Ly9CZWNhdXNlIHdlIGFkZCBzdGVwIHRvIGJyb3dzZXIgZHVyaW5nIGxvZ2luIG5vdyBzbyB0aGF0IHRoZSBicm93c2VyIGJhY2sgYnV0dG9uIHdvcmtzLCB3ZSBuZWVkIHRvIGNoZWNrIGZvciB0aGF0IG9yIGxvZ2luIGNhbiBmYWlsIGxlYXZpbmcgdGhlIHVzZXIgc3R1Y2suXG5cdGlmICggbmV3RGVlcExpbmsgPT0gJ0xvZ2luJyB8fCAoIG5ld0RlZXBMaW5rICYmIG5ld0RlZXBMaW5rLnN0YXJ0c1dpdGgoICdMb2dpbiYnICkgPT0gdHJ1ZSApICkgeyAvL1dlIGFyZSBub3QganVzdCBjaGVja2luZyBzdGFydHNXaXRoIGJlY2F1c2UgcG90ZW50aWFsIG90aGVyIHZpZXdzIHN0YXJ0IHdpdGggXCJMb2dpblwiIGluIHRoZSBmdXR1cmVcblx0XHR2YXIgYWx0ZXJuYXRlX3Nlc3Npb25fZGF0YSA9IGdldENvb2tpZSggJ0FsdGVybmF0ZVNlc3Npb25EYXRhJyApO1xuXHRcdGlmICggYWx0ZXJuYXRlX3Nlc3Npb25fZGF0YSApIHtcblx0XHRcdHRyeSB7IC8vUHJldmVudCBKUyBleGNlcHRpb24gaWYgd2UgY2FuJ3QgcGFyc2UgYWx0ZXJuYXRlX3Nlc3Npb25fZGF0YSBmb3Igc29tZSByZWFzb24uXG5cdFx0XHRcdGFsdGVybmF0ZV9zZXNzaW9uX2RhdGEgPSBKU09OLnBhcnNlKCBhbHRlcm5hdGVfc2Vzc2lvbl9kYXRhICk7XG5cdFx0XHRcdGlmICggYWx0ZXJuYXRlX3Nlc3Npb25fZGF0YSAmJiBhbHRlcm5hdGVfc2Vzc2lvbl9kYXRhLnByZXZpb3VzX3Nlc3Npb25fdmlldyApIHtcblx0XHRcdFx0XHRHbG9iYWwuZGVlcGxpbmsgPSBhbHRlcm5hdGVfc2Vzc2lvbl9kYXRhLnByZXZpb3VzX3Nlc3Npb25fdmlldztcblx0XHRcdFx0fVxuXHRcdFx0fSBjYXRjaCAoIGUgKSB7XG5cdFx0XHRcdERlYnVnLlRleHQoIGUubWVzc2FnZSwgJ0dsb2JhbC5qcycsICdHbG9iYWwnLCAnc2V0RGVlcExpbmsnLCAxMCApO1xuXHRcdFx0fVxuXHRcdH1cblx0fSBlbHNlIGlmICggbmV3RGVlcExpbmsgIT0gdW5kZWZpbmVkICkge1xuXHRcdEdsb2JhbC5kZWVwbGluayA9IG5ld0RlZXBMaW5rO1xuXHR9XG59O1xuXG4vKipcbiBzb3J0cyBpdGVtcyBmb3IgdGhlIHJpYmJvbiBtZW51XG4gKiovXG5HbG9iYWwuY29tcGFyZU1lbnVJdGVtcyA9IGZ1bmN0aW9uKCBhLCBiICkge1xuXHRpZiAoIGEuYXR0cmlidXRlcy5zb3J0X29yZGVyID09IHVuZGVmaW5lZCApIHtcblx0XHRhLmF0dHJpYnV0ZXMuc29ydF9vcmRlciA9IDEwMDA7XG5cdH1cblx0aWYgKCBiLmF0dHJpYnV0ZXMuc29ydF9vcmRlciA9PSB1bmRlZmluZWQgKSB7XG5cdFx0Yi5hdHRyaWJ1dGVzLnNvcnRfb3JkZXIgPSAxMDAwO1xuXHR9XG5cblx0aWYgKCBhLmF0dHJpYnV0ZXMuc29ydF9vcmRlciA8IGIuYXR0cmlidXRlcy5zb3J0X29yZGVyICkge1xuXHRcdHJldHVybiAtMTtcblx0fVxuXG5cdGlmICggYS5hdHRyaWJ1dGVzLnNvcnRfb3JkZXIgPiBiLmF0dHJpYnV0ZXMuc29ydF9vcmRlciApIHtcblx0XHRyZXR1cm4gMTtcblx0fVxuXG5cdGlmICggYS5hdHRyaWJ1dGVzLnNvcnRfb3JkZXIgPT0gYi5hdHRyaWJ1dGVzLnNvcnRfb3JkZXIgKSB7XG5cdFx0aWYgKCBhLmF0dHJpYnV0ZXMuYWRkX29yZGVyIDwgYi5hdHRyaWJ1dGVzLmFkZF9vcmRlciApIHtcblx0XHRcdHJldHVybiAtMTtcblx0XHR9XG5cdFx0aWYgKCBhLmF0dHJpYnV0ZXMuYWRkX29yZGVyID4gYi5hdHRyaWJ1dGVzLmFkZF9vcmRlciApIHtcblx0XHRcdHJldHVybiAxO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiAwO1xufTtcblxuR2xvYmFsLmdldERheXNJblNwYW4gPSBmdW5jdGlvbiggc3RhcnRfZGF0ZSwgZW5kX2RhdGUsIHN1biwgbW9uLCB0dWUsIHdlZCwgdGh1LCBmcmksIHNhdCApIHtcblx0dmFyIHN0YXJ0X2RhdGVfb2JqID0gR2xvYmFsLnN0clRvRGF0ZSggc3RhcnRfZGF0ZSApO1xuXHR2YXIgZW5kX2RhdGVfb2JqID0gR2xvYmFsLnN0clRvRGF0ZSggZW5kX2RhdGUgKTtcblxuXHRpZiAoIHN0YXJ0X2RhdGVfb2JqID09IG51bGwgKSB7XG5cdFx0cmV0dXJuIDA7XG5cdH1cblxuXHRpZiAoIGVuZF9kYXRlX29iaiA9PSBudWxsICkge1xuXHRcdHJldHVybiAwO1xuXHR9XG5cblx0dmFyIGRheXMgPSBNYXRoLnJvdW5kKCBNYXRoLmFicyggKCBzdGFydF9kYXRlX29iai5nZXRUaW1lKCkgLSBlbmRfZGF0ZV9vYmouZ2V0VGltZSgpICkgLyAoIDg2NDAwICogMTAwMCApICkgKSArIDE7XG5cblx0Ly9OZWVkIHRvIGxvb3Agb3ZlciB0aGUgd2hvbGUgcmFuZ2UgdG8gZW5zdXJlIHByb3BlciBjb3VudGluZyBvZiBlZmZlY3RpdmUgZGF5cyBvbiByYW5nZXMgdGhhdCBzcGFuIG11bHRpcGxlIHdlZWtzLlxuXHR3aGlsZSAoIHN0YXJ0X2RhdGVfb2JqIDw9IGVuZF9kYXRlX29iaiApIHtcblx0XHRzd2l0Y2ggKCBzdGFydF9kYXRlX29iai5nZXREYXkoKSApIHtcblx0XHRcdGNhc2UgMDpcblx0XHRcdFx0aWYgKCAhc3VuICkge1xuXHRcdFx0XHRcdGRheXMgLT0gMTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgMTpcblx0XHRcdFx0aWYgKCAhbW9uICkge1xuXHRcdFx0XHRcdGRheXMgLT0gMTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgMjpcblx0XHRcdFx0aWYgKCAhdHVlICkge1xuXHRcdFx0XHRcdGRheXMgLT0gMTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgMzpcblx0XHRcdFx0aWYgKCAhd2VkICkge1xuXHRcdFx0XHRcdGRheXMgLT0gMTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgNDpcblx0XHRcdFx0aWYgKCAhdGh1ICkge1xuXHRcdFx0XHRcdGRheXMgLT0gMTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgNTpcblx0XHRcdFx0aWYgKCAhZnJpICkge1xuXHRcdFx0XHRcdGRheXMgLT0gMTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgNjpcblx0XHRcdFx0aWYgKCAhc2F0ICkge1xuXHRcdFx0XHRcdGRheXMgLT0gMTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHR9XG5cblx0XHRzdGFydF9kYXRlX29iai5zZXREYXRlKCBzdGFydF9kYXRlX29iai5nZXREYXRlKCkgKyAxICk7IC8vSW5jcmVtZW50IHRvIG5leHQgZGF5IGFuZCBjb250aW51ZSB0aGUgbG9vcC5cblx0fVxuXG5cdHJldHVybiBkYXlzO1xufTtcblxuLyoqXG4gKiBTZXRzIHRoZSBsYW5ndWFnZSBjb29raWUgdG8gcm9vdCBjb29raWUgdXJsXG4gKiBAcGFyYW0gbGFuZ1xuICovXG5HbG9iYWwuc2V0TGFuZ3VhZ2VDb29raWUgPSBmdW5jdGlvbiggbGFuZyApIHtcblx0c2V0Q29va2llKCAnbGFuZ3VhZ2UnLCBsYW5nLCAxMDAwMCwgQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLmNvb2tpZV9iYXNlX3VybCApO1xufTtcblxuLyoqXG4gKiBSZW1vdmVzIGNvb2tpZXMgZnJvbSBhbGwgcGF0aHMuIFB1dCBpbiBzcGVjaWZpY2FsbHkgdG8gbW92ZSB0aGUgbGFuZ3VhZ2UgY29va2llcyB0byByb290LlxuICogQHBhcmFtIG5hbWVcbiAqL1xuR2xvYmFsLmVyYXNlQ29va2llRnJvbUFsbFBhdGhzID0gZnVuY3Rpb24oIG5hbWUgKSB7XG5cdHZhciB2YWx1ZSA9IGdldENvb2tpZSggbmFtZSApO1xuXG5cdC8vIFRoaXMgZnVuY3Rpb24gd2lsbCBhdHRlbXB0IHRvIHJlbW92ZSBhIGNvb2tpZSBmcm9tIGFsbCBwYXRoc1xuXHR2YXIgcGF0aF9iaXRzID0gbG9jYXRpb24ucGF0aG5hbWUuc3BsaXQoICcvJyApO1xuXHR2YXIgcGF0aF9jdXJyZW50ID0gJyBwYXRoPSc7XG5cblx0Ly8gRG8gYSBzaW1wbGUgcGF0aGxlc3MgZGVsZXRlIGZpcnN0XG5cdGRvY3VtZW50LmNvb2tpZSA9IG5hbWUgKyAnPTsgZXhwaXJlcz1UaHUsIDAxLUphbi0xOTcwIDAwOjAwOjAxIEdNVDsnO1xuXHRmb3IgKCB2YXIgaSA9IDA7IGkgPCBwYXRoX2JpdHMubGVuZ3RoOyBpKysgKSB7XG5cdFx0cGF0aF9jdXJyZW50ICs9ICggKCBwYXRoX2N1cnJlbnQuc3Vic3RyKCAtMSApICE9ICcvJyApID8gJy8nIDogJycgKSArIHBhdGhfYml0c1tpXTtcblx0XHREZWJ1Zy5UZXh0KCAnLS0tJyArIGkgKyAnLiBEZWxldGluZyBjb29raWU6ICcgKyBuYW1lICsgJyB3aXRoIHZhbHVlOiAnICsgdmFsdWUgKyAnIGFuZCBwYXRoOiAnICsgcGF0aF9jdXJyZW50LCAnR2xvYmFsLmpzJywgJ0dsb2JhbCcsICdlcmFzZUNvb2tpZUZyb21BbGxQYXRocycsIDEwICk7XG5cdFx0ZG9jdW1lbnQuY29va2llID0gbmFtZSArICc9OyBleHBpcmVzPVRodSwgMDEtSmFuLTE5NzAgMDA6MDA6MDEgR01UOyAnICsgcGF0aF9jdXJyZW50ICsgJy87Jztcblx0XHRkb2N1bWVudC5jb29raWUgPSBuYW1lICsgJz07IGV4cGlyZXM9VGh1LCAwMS1KYW4tMTk3MCAwMDowMDowMSBHTVQ7ICcgKyBwYXRoX2N1cnJlbnQgKyAnOyc7XG5cdH1cblxuXHREZWJ1Zy5UZXh0KCAnRGVsZXRpbmcgY29va2llOiAnICsgbmFtZSArICcgd2l0aCB2YWx1ZTonICsgdmFsdWUgKyAnIGFuZCBwYXRoOicgKyBwYXRoX2N1cnJlbnQsICdHbG9iYWwuanMnLCAnR2xvYmFsJywgJ2VyYXNlQ29va2llRnJvbUFsbFBhdGhzJywgMTAgKTtcblx0cmV0dXJuIHZhbHVlO1xufTtcblxuLyoqXG4gKiBNb3ZlcyBzcGVjaWZpYyBhcHAgY29va2llcyBmcm9tIGFsbCBvdmVyIHRvIHRoZSByb290IGNvb2tpZSBwYXRoIHNvIHRoYXQgdGhleSB3aWxsIGJlIGFjY2Vzc2libGUgZnJvbSBldmVyeXdoZXJlXG4gKi9cbkdsb2JhbC5tb3ZlQ29va2llc1RvTmV3UGF0aCA9IGZ1bmN0aW9uKCkge1xuXHREZWJ1Zy5BcnIoIGRvY3VtZW50LmNvb2tpZSwgJ0NPT0tJRSBCRUZPUkUgQ09OVEVOVDogJywgJ0dsb2JhbC5qcycsICdHbG9iYWwnLCAnbW92ZUNvb2tpZXNUb05ld1BhdGgnLCAxMCApO1xuXHR2YXIgY29va2llcyA9IFsnbGFuZ3VhZ2UnLCAnU3RhdGlvbklEJywgJ1Nlc3Npb25JRCddO1xuXHR2YXIgeWVhciA9IG5ldyBEYXRlKCkuZ2V0RnVsbFllYXIoKTtcblx0Zm9yICggdmFyIGkgPSAwOyBpIDwgY29va2llcy5sZW5ndGg7IGkrKyApIHtcblx0XHR2YXIgdmFsID0gR2xvYmFsLmVyYXNlQ29va2llRnJvbUFsbFBhdGhzKCBjb29raWVzW2ldICk7XG5cdFx0aWYgKCB2YWwgJiYgdmFsLmxlbmd0aCA+IDAgKSB7XG5cdFx0XHREZWJ1Zy5UZXh0KCAnU2V0dGluZyBjb29raWU6JyArIGNvb2tpZXNbaV0gKyAnIHdpdGggdmFsdWU6JyArIHZhbCArICcgYW5kIHBhdGg6JyArIEFQSUdsb2JhbC5wcmVfbG9naW5fZGF0YS5jb29raWVfYmFzZV91cmwsICdHbG9iYWwuanMnLCAnR2xvYmFsJywgJ21vdmVDb29raWVzVG9OZXdQYXRoJywgMTAgKTtcblx0XHRcdGRvY3VtZW50LmNvb2tpZSA9IGNvb2tpZXNbaV0gKyAnPScgKyB2YWwgKyAnOyBleHBpcmVzPVRodSwgMDEtSmFuLScgKyAoIHllYXIgKyAxMCApICsgJyAwMDowMDowMSBHTVQ7IHBhdGg9JyArIEFQSUdsb2JhbC5wcmVfbG9naW5fZGF0YS5jb29raWVfYmFzZV91cmwgKyAnOyc7XG5cdFx0fSBlbHNlIHtcblx0XHRcdERlYnVnLlRleHQoICdOT1QgU2V0dGluZyBjb29raWU6JyArIGNvb2tpZXNbaV0gKyAnIHdpdGggdmFsdWU6JyArIHZhbCArICcgYW5kIHBhdGg6JyArIEFQSUdsb2JhbC5wcmVfbG9naW5fZGF0YS5jb29raWVfYmFzZV91cmwsICdHbG9iYWwuanMnLCAnR2xvYmFsJywgJ21vdmVDb29raWVzVG9OZXdQYXRoJywgMTAgKTtcblx0XHR9XG5cdH1cblx0RGVidWcuQXJyKCBkb2N1bWVudC5jb29raWUsICdDT09LSUUgQUZURVIgQ09OVEVOVDogJywgJ0dsb2JhbC5qcycsICdHbG9iYWwnLCAnbW92ZUNvb2tpZXNUb05ld1BhdGgnLCAxMCApO1xufTtcblxuR2xvYmFsLmNsZWFyU2Vzc2lvbkNvb2tpZSA9IGZ1bmN0aW9uKCkge1xuXHRHbG9iYWwubW92ZUNvb2tpZXNUb05ld1BhdGgoKTtcblx0ZGVsZXRlQ29va2llKCBHbG9iYWwuZ2V0U2Vzc2lvbklES2V5KCkgKTtcbn07XG5HbG9iYWwuYXJyYXlfdW5pcXVlID0gZnVuY3Rpb24oIGFyciApIHtcblx0aWYgKCBHbG9iYWwuaXNBcnJheSggYXJyICkgPT0gZmFsc2UgKSB7XG5cdFx0cmV0dXJuIGFycjtcblx0fVxuXHR2YXIgY2xlYW5fYXJyID0gW107XG5cdGZvciAoIHZhciBuIGluIGFyciApIHtcblx0XHRpZiAoIGNsZWFuX2Fyci5pbmRleE9mKCBhcnJbbl0gKSA9PSAtMSApIHtcblx0XHRcdGNsZWFuX2Fyci5wdXNoKCBhcnJbbl0gKTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIGNsZWFuX2Fycjtcbn07XG5cbi8vUmV0dXJucyBwcm9wZXJ0eSBrZXlzIHRoYXQgaGF2ZSBkaWZmZXJlbnQgdmFsdWVzIG9yIHRoYXQgZG9uJ3QgZXhpc3QuIFNpbWlsYXIgdG8gUEhQJ3MgYXJyYXlfZGlmZl9hc3NvYygpIGZ1bmN0aW9uLlxuR2xvYmFsLkFycmF5RGlmZkFzc29jID0gZnVuY3Rpb24oIGFycjEgKSB7XG5cdGNvbnN0IHJldGFyciA9IHt9O1xuXHRjb25zdCBhcmdsID0gYXJndW1lbnRzLmxlbmd0aDtcblx0bGV0IGsxID0gJyc7XG5cdGxldCBpID0gMTtcblx0bGV0IGsgPSAnJztcblx0bGV0IGFyciA9IHt9O1xuXG5cdGFycjFfa2V5czogZm9yICggazEgaW4gYXJyMSApIHtcblx0XHRmb3IgKCBpID0gMTsgaSA8IGFyZ2w7IGkrKyApIHtcblx0XHRcdGFyciA9IGFyZ3VtZW50c1tpXTtcblxuXHRcdFx0Zm9yICggayBpbiBhcnIgKSB7XG5cdFx0XHRcdGlmICggYXJyW2tdID09PSBhcnIxW2sxXSAmJiBrID09PSBrMSApIHtcblx0XHRcdFx0XHQvLyBJZiBpdCByZWFjaGVzIGhlcmUsIGl0IHdhcyBmb3VuZCBpbiBhdCBsZWFzdCBvbmUgYXJyYXksIHNvIHRyeSBuZXh0IHZhbHVlXG5cdFx0XHRcdFx0Y29udGludWUgYXJyMV9rZXlzO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdHJldGFycltrMV0gPSBhcnIxW2sxXTtcblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gcmV0YXJyO1xufTtcblxuLy9TcGVjaWFsIHJvdW5kaW5nIGZ1bmN0aW9uIHRoYXQgaGFuZGxlcyB2YWx1ZXMgbGlrZSAxLjAwNSBvciAxLjAwNDk5OTk5OTk5OTk5OTkgcHJvcGVybHksIHNlZTogaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8xMTgzMjkxNC9yb3VuZC10by1hdC1tb3N0LTItZGVjaW1hbC1wbGFjZXNcbkdsb2JhbC5Nb25leVJvdW5kID0gZnVuY3Rpb24oIG51bWJlciwgZGVjaW1hbHMgKSB7XG5cdGlmICggaXNOYU4oIG51bWJlciApICkge1xuXHRcdG51bWJlciA9IDA7XG5cdH1cblxuXHRpZiAoICFkZWNpbWFscyApIHtcblx0XHRkZWNpbWFscyA9IDI7XG5cdH1cblxuXHQvLyMyMjk0IC0gV2UgbXVzdCByb3VuZCB0aGUgYWJzb2x1dGUgdmFsdWUgb3IgbmVnYXRpdmUgbnVtYmVycyB3aWxsIHJvdW5kIHRvd2FyZCB6ZXJvLlxuXHR2YXIgbmVnYXRpdmUgPSBmYWxzZTtcblx0aWYgKCBudW1iZXIgPCAwICkge1xuXHRcdG5lZ2F0aXZlID0gdHJ1ZTtcblx0fVxuXHRudW1iZXIgPSBNYXRoLmFicyggbnVtYmVyICk7XG5cblx0dmFyIHJldHZhbCA9ICsoIE1hdGgucm91bmQoIG51bWJlciArICdlKycgKyBkZWNpbWFscyApICsgJ2UtJyArIGRlY2ltYWxzICk7XG5cblx0aWYgKCBuZWdhdGl2ZSApIHtcblx0XHRyZXR2YWwgPSByZXR2YWwgKiAtMTtcblx0fVxuXG5cdHJldHVybiByZXR2YWwudG9GaXhlZCggZGVjaW1hbHMgKTtcbn07XG5cbkdsb2JhbC5nZXRVSVJlYWR5U3RhdHVzID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiBHbG9iYWwuVUlSZWFkeVN0YXR1cztcbn07XG5HbG9iYWwuc2V0VUlOb3RyZWFkeSA9IGZ1bmN0aW9uKCkge1xuXHRHbG9iYWwuVUlSZWFkeVN0YXR1cyA9IDA7XG5cdERlYnVnLlRleHQoICdHbG9iYWwgcmVhZHkgc3RhdHVzIGNoYW5nZWQ6IDAnLCAnR2xvYmFsLmpzJywgJ0dsb2JhbCcsICdzZXRVSVJlYWR5U3RhdHVzJywgMTAgKTtcbn07XG5HbG9iYWwuc2V0VUlSZWFkeSA9IGZ1bmN0aW9uKCkge1xuXHQvL25lZWQgdG8gY2hlY2sgdGhlIGRvY3VtZW50IGlzbid0IGFscmVhZHkgY29tcGxldGUgYW5kIHJlYWR5IGZvciBhIHNjcmVlbnNob3QuJ1xuXHRpZiAoIEdsb2JhbC5VSVJlYWR5U3RhdHVzID09IDAgKSB7XG5cdFx0R2xvYmFsLlVJUmVhZHlTdGF0dXMgPSAxO1xuXHRcdERlYnVnLlRleHQoICdHbG9iYWwgcmVhZHkgc3RhdHVzIGNoYW5nZWQ6IDEnLCAnR2xvYmFsLmpzJywgJ0dsb2JhbCcsICdzZXRVSVJlYWR5JywgMTAgKTtcblx0fVxufTtcbkdsb2JhbC5zZXRVSUluaXRDb21wbGV0ZSA9IGZ1bmN0aW9uKCkge1xuXHRHbG9iYWwuVUlSZWFkeVN0YXR1cyA9IDI7XG5cdERlYnVnLlRleHQoICdHbG9iYWwgcmVhZHkgc3RhdHVzIGNoYW5nZWQ6IDInLCAnR2xvYmFsLmpzJywgJ0dsb2JhbCcsICdzZXRVSVJlYWR5U3RhdHVzJywgMTAgKTtcbn07XG5cbkdsb2JhbC5zZXRVbml0VGVzdE1vZGUgPSBmdW5jdGlvbigpIHtcblx0R2xvYmFsLlVOSVRfVEVTVF9NT0RFID0gdHJ1ZTtcblx0JCggJ2JvZHknICkuYWRkQ2xhc3MoICdVTklUX1RFU1RfTU9ERScgKTtcblx0RGVidWcuc2V0RW5hYmxlKCB0cnVlICk7XG5cdERlYnVnLnNldFZlcmJvc2l0eSggMTEgKTtcbn07XG5cbkdsb2JhbC5jb252ZXJ0VmFsaWRhdGlvbkVycm9yVG9TdHJpbmcgPSBmdW5jdGlvbiggb2JqZWN0ICkge1xuXHQvL0RlYnVnLkFycihvYmplY3QsJ0NvbnZlcnRpbmcgRXJyb3IgdG8gU3RyaW5nOiAnLCdHbG9iYWwuanMnLCAnR2xvYmFsJywgJ2NvbnZlcnRWYWxpZGF0aW9uRXJyb3JUb1N0cmluZycsIDEwKTtcblx0dmFyIHJldHZhbCA9ICcnO1xuXG5cdC8vICMyMjg4IC0gSWYgeW91IGFyZSBkZWxldGluZyBzZXZlcmFsIHJlY29yZHMgYW5kIHJlY29yZHMgMiBhbmQgNCBjb250YWluIGVycm9ycywgdGhvc2UgYXJlIHRoZSBvYmplY3Qga2V5cyB0aGF0IHdpbGwgbmVlZCB0byBiZSByZWZlcmVuY2VkIGhlcmUuXG5cdC8vIFRvIGZpeCB0aGlzIHdlIG5lZWQgdG8gZ3JhYiB0aGUgZmlyc3QgZWxlbWVudCBpbmRlcGVuZGVudCBvZiB0aGUgaW5kZXggbnVtYmVyLlxuXHRpZiAoIE9iamVjdC5rZXlzKCBvYmplY3QgKS5sZW5ndGggPiAwICkge1xuXHRcdGZvciAoIHZhciBmaXJzdCBpbiBvYmplY3QgKSB7XG5cdFx0XHRvYmplY3QgPSBvYmplY3RbZmlyc3RdO1xuXHRcdFx0YnJlYWs7XG5cdFx0fVxuXHR9XG5cblx0dmFyIGVycm9yX3N0cmluZ3MgPSBbXTtcblx0aWYgKCB0eXBlb2Ygb2JqZWN0ID09ICdzdHJpbmcnICkge1xuXHRcdC8vIzIyOTAgLSBlcnJvciBvYmplY3RzIGFyZSBub3QgYWx3YXlzIHVuaWZvcm0gYW5kIGNhbiBzb21ldGltZXMgY2F1c2UgbWFsZm9ybWVkIGVycm9yIHRpcHMgKHNlZSBzY3JlZW5zaG90KSBpZiB3ZSBkbyBub3QgY2hlY2sgZWFjaCBsZXZlbCBmb3Igc3RyaW5nIHR5cGVcblx0XHRlcnJvcl9zdHJpbmdzLnB1c2goIG9iamVjdCApO1xuXHR9IGVsc2Uge1xuXHRcdGZvciAoIHZhciBpbmRleCBpbiBvYmplY3QgKSB7XG5cdFx0XHRpZiAoIHR5cGVvZiBvYmplY3RbaW5kZXhdID09ICdzdHJpbmcnICkge1xuXHRcdFx0XHRlcnJvcl9zdHJpbmdzLnB1c2goIG9iamVjdFtpbmRleF0gKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGZvciAoIHZhciBrZXkgaW4gb2JqZWN0W2luZGV4XSApIHtcblx0XHRcdFx0XHRpZiAoIHR5cGVvZiAoIG9iamVjdFtpbmRleF1ba2V5XSApID09ICdzdHJpbmcnICkge1xuXHRcdFx0XHRcdFx0ZXJyb3Jfc3RyaW5ncy5wdXNoKCBvYmplY3RbaW5kZXhdW2tleV0gKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0Zm9yICggdmFyIGkgaW4gb2JqZWN0W2luZGV4XVtrZXldICkge1xuXHRcdFx0XHRcdFx0XHRlcnJvcl9zdHJpbmdzLnB1c2goIG9iamVjdFtpbmRleF1ba2V5XVtpXSApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdGlmICggZXJyb3Jfc3RyaW5ncy5sZW5ndGggPiAxICkge1xuXHRcdHZhciBlcnJvcl9jb3VudCA9IDE7XG5cdFx0Zm9yICggdmFyIGluZGV4IGluIGVycm9yX3N0cmluZ3MgKSB7XG5cdFx0XHRyZXR2YWwgKz0gZXJyb3JfY291bnQgKyAnLiAnICsgZXJyb3Jfc3RyaW5nc1tpbmRleF0gKyAnLjxicj4nO1xuXHRcdFx0ZXJyb3JfY291bnQrKztcblx0XHR9XG5cdH0gZWxzZSBpZiAoIHR5cGVvZiBlcnJvcl9zdHJpbmdzWzBdID09ICdzdHJpbmcnICkge1xuXHRcdHJldHZhbCA9IGVycm9yX3N0cmluZ3NbMF0gKyAnLic7XG5cdH1cblxuXHRyZXR1cm4gcmV0dmFsO1xufTtcblxuR2xvYmFsLkFQSUZpbGVEb3dubG9hZCA9IGZ1bmN0aW9uKCBjbGFzc19uYW1lLCBtZXRob2QsIHBvc3RfZGF0YSwgdXJsICkge1xuXHRpZiAoIHVybCA9PSB1bmRlZmluZWQgKSB7XG5cdFx0dXJsID0gU2VydmljZUNhbGxlci5nZXRBUElVUkwoICdDbGFzcz0nICsgY2xhc3NfbmFtZSArICcmTWV0aG9kPScgKyBtZXRob2QgKTtcblx0fVxuXG5cdHZhciBtZXNzYWdlX2lkID0gVFRVVUlELmdlbmVyYXRlVVVJRCgpO1xuXHR1cmwgPSB1cmwgKyAnJk1lc3NhZ2VJRD0nICsgbWVzc2FnZV9pZDtcblxuXHR2YXIgdGVtcEZvcm0gPSAkKCAnPGZvcm0+PC9mb3JtPicgKTtcblx0dGVtcEZvcm0uYXR0ciggJ2lkJywgJ3RlbXBfZm9ybScgKTtcblx0dGVtcEZvcm0uYXR0ciggJ21ldGhvZCcsICdQT1NUJyApO1xuXHR0ZW1wRm9ybS5hdHRyKCAnYWN0aW9uJywgdXJsICk7XG5cblx0dGVtcEZvcm0uYXR0ciggJ3RhcmdldCcsIGlzX2Jyb3dzZXJfaU9TID8gJ19ibGFuaycgOiAnaGlkZVJlcG9ydElGcmFtZScgKTsgLy9oaWRlUmVwb3J0SUZyYW1lXG5cblx0dGVtcEZvcm0uYXBwZW5kKCAkKCAnPGlucHV0IHR5cGU9XFwnaGlkZGVuXFwnIG5hbWU9XFwnWC1DbGllbnQtSURcXCcgdmFsdWU9XFwnQnJvd3Nlci1UaW1lVHJleFxcJz4nICkgKTtcblx0dGVtcEZvcm0uYXBwZW5kKCAkKCAnPGlucHV0IHR5cGU9XFwnaGlkZGVuXFwnIG5hbWU9XFwnWC1DU1JGLVRva2VuXFwnIHZhbHVlPVxcJycgKyBnZXRDb29raWUoICdDU1JGLVRva2VuJyApICsgJ1xcJz4nICkgKTtcblxuXHR0ZW1wRm9ybS5jc3MoICdkaXNwbGF5JywgJ25vbmUnICk7XG5cdGlmICggcG9zdF9kYXRhICkge1xuXHRcdHZhciBoaWRlSW5wdXQgPSAkKCAnPGlucHV0IHR5cGU9XFwnaGlkZGVuXFwnIG5hbWU9XFwnanNvblxcJz4nICk7XG5cdFx0aGlkZUlucHV0LnZhbCggSlNPTi5zdHJpbmdpZnkoIHBvc3RfZGF0YSApICk7XG5cdFx0dGVtcEZvcm0uYXBwZW5kKCBoaWRlSW5wdXQgKTtcblx0fVxuXHR0ZW1wRm9ybS5hcHBlbmRUbyggJ2JvZHknICk7XG5cdHRlbXBGb3JtLmNzcyggJ2Rpc3BsYXknLCAnbm9uZScgKTtcblx0dGVtcEZvcm0uc3VibWl0KCk7XG5cdHRlbXBGb3JtLnJlbW92ZSgpO1xuXG5cdGlmICggIWlzX2Jyb3dzZXJfaU9TICkge1xuXHRcdFByb2dyZXNzQmFyLnNob3dQcm9ncmVzc0JhciggbWVzc2FnZV9pZCwgdHJ1ZSApO1xuXHR9XG59O1xuXG5HbG9iYWwuSlNGaWxlRG93bmxvYWQgPSBmdW5jdGlvbiggZmlsZV9uYW1lLCBjb250ZW50LCBtaW1lX3R5cGUgKSB7XG5cdHZhciBhID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggJ2EnICk7XG5cdG1pbWVfdHlwZSA9IG1pbWVfdHlwZSB8fCAnYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtJztcblxuXHRpZiAoIFVSTCAmJiAnZG93bmxvYWQnIGluIGEgKSB7IC8vaHRtbDUgQVtkb3dubG9hZF1cblx0XHRhLmhyZWYgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKCBuZXcgQmxvYiggW2NvbnRlbnRdLCB7XG5cdFx0XHR0eXBlOiBtaW1lX3R5cGVcblx0XHR9ICkgKTtcblx0XHRhLnNldEF0dHJpYnV0ZSggJ2Rvd25sb2FkJywgZmlsZV9uYW1lICk7XG5cdFx0ZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCggYSApO1xuXHRcdGEuY2xpY2soKTtcblx0XHRkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKCBhICk7XG5cdH0gZWxzZSB7XG5cdFx0bG9jYXRpb24uaHJlZiA9ICdkYXRhOmFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSwnICsgZW5jb2RlVVJJQ29tcG9uZW50KCBjb250ZW50ICk7IC8vIG9ubHkgdGhpcyBtaW1lIHR5cGUgaXMgc3VwcG9ydGVkXG5cdH1cbn07XG5cbi8vR2V0IGEgcmVmcmVzaGVkIENTUkYgdG9rZW4gY29va2llIGluIGNhc2UgaXQgZXhwaXJlcyBwcmlvciB0byB0aGUgdXNlciBjbGlja2luZyB0aGUgbG9naW4gYnV0dG9uLiBUaGlzIGhlbHBzIGF2b2lkIHNob3dpbmcgYW4gZXJyb3IgbWVzc2FnZSBhbmQgdHJpZ2dlcmluZyBhIGZ1bGwgYnJvd3NlciByZWZyZXNoLlxuR2xvYmFsLnJlZnJlc2hDU1JGVG9rZW4gPSBmdW5jdGlvbiggY2FsbGJhY2sgKSB7XG5cdGlmICggZ2V0Q29va2llKCAnQ1NSRi1Ub2tlbicgKSA9PSAnJyApIHtcblx0XHREZWJ1Zy5UZXh0KCAnQ1NSRiBUb2tlbiBjb29raWUgZG9lcyBub3QgZXhpc3QsIHJlZnJlc2hpbmcuLi4nLCAnR2xvYmFsLmpzJywgJycsICdyZWZyZXNoQ1NSRlRva2VuJywgMTAgKTtcblx0XHR0aGlzLmF1dGhlbnRpY2F0aW9uX2FwaSA9IFRUQVBJLkFQSUF1dGhlbnRpY2F0aW9uO1xuXHRcdHRoaXMuYXV0aGVudGljYXRpb25fYXBpLnNlbmRDU1JGVG9rZW5Db29raWUoIHtcblx0XHRcdFx0b25SZXN1bHQ6IGZ1bmN0aW9uKCBlICkge1xuXHRcdFx0XHRcdERlYnVnLlRleHQoICdDU1JGIFJlZnJlc2ggc3VjY2VzcyEuLi4nLCBudWxsLCBudWxsLCAncmVmcmVzaENTUkZUb2tlbicsIDEwICk7XG5cdFx0XHRcdFx0Y2FsbGJhY2soKTtcblx0XHRcdFx0fSxcblx0XHRcdFx0b25FcnJvcjogZnVuY3Rpb24oIGUgKSB7XG5cdFx0XHRcdFx0RGVidWcuVGV4dCggJ0NTUkYgUmVmcmVzaCBFcnJvci4uLicsIG51bGwsIG51bGwsICdyZWZyZXNoQ1NSRlRva2VuJywgMTAgKTtcblx0XHRcdFx0XHRjYWxsYmFjaygpO1xuXHRcdFx0XHR9LFxuXHRcdFx0fSk7XG5cdH0gZWxzZSB7XG5cdFx0Y2FsbGJhY2soKTtcblx0fVxuXG5cdHJldHVybiB0cnVlO1xufTtcblxuR2xvYmFsLnJlZnJlc2hQZXJtaXNzaW9ucyA9IGZ1bmN0aW9uKCkge1xuXHR0aGlzLmF1dGhlbnRpY2F0aW9uX2FwaSA9IFRUQVBJLkFQSVBlcm1pc3Npb247XG5cdHRoaXMuYXV0aGVudGljYXRpb25fYXBpLmdldFBlcm1pc3Npb25zKCB7XG5cdFx0b25SZXN1bHQ6IGZ1bmN0aW9uKCByZXNwb25zZSApIHtcblx0XHRcdGxldCByZXN1bHQgPSByZXNwb25zZS5nZXRSZXN1bHQoKTtcblx0XHRcdGlmICggcmVzdWx0ICE9PSBmYWxzZSApIHtcblx0XHRcdFx0TG9jYWxDYWNoZURhdGEuc2V0UGVybWlzc2lvbkRhdGEoIHJlc3VsdCApO1xuXHRcdFx0XHREZWJ1Zy5UZXh0KCAnUGVybWlzc2lvbnMgUmVmcmVzaGVkIScsICdHbG9iYWwuanMnLCBudWxsLCAncmVmcmVzaFBlcm1pc3Npb25zJywgMTAgKTtcblx0XHRcdH1cblx0XHR9LFxuXHR9KTtcbn07XG5cbkdsb2JhbC5zZXRTdGF0aW9uSUQgPSBmdW5jdGlvbiggdmFsICkge1xuXHRzZXRDb29raWUoICdTdGF0aW9uSUQnLCB2YWwsIDEwMDAwICk7XG59O1xuXG5HbG9iYWwuZ2V0U3RhdGlvbklEID0gZnVuY3Rpb24oKSB7XG5cdHZhciByZXR2YWwgPSBnZXRDb29raWUoICdTdGF0aW9uSUQnICk7XG5cblx0Ly9DaGVjayB0byBzZWUgaWYgdGhlcmUgaXMgYSBcInN0aWNreVwiIHVzZXIgYWdlbnQgYmFzZWQgU3RhdGlvbiBJRCBkZWZpbmVkLlxuXHRpZiAoIG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZiggJ1N0YXRpb25JRDonICkgIT0gLTEgKSB7XG5cdFx0dmFyIHJlZ2V4ID0gL1N0YXRpb25JRDpcXHM/KFthLXpBLVowLTldezMwLDY0fSkvaTtcblx0XHR2YXIgbWF0Y2hlcyA9IHJlZ2V4LmV4ZWMoIG5hdmlnYXRvci51c2VyQWdlbnQgKTtcblx0XHRpZiAoIG1hdGNoZXNbMV0gKSB7XG5cdFx0XHREZWJ1Zy5UZXh0KCAnRm91bmQgU3RhdGlvbklEIGluIHVzZXIgYWdlbnQsIGZvcmNpbmcgdG8gdGhhdCBpbnN0ZWFkIScsICdHbG9iYWwuanMnLCAnJywgJ2dldFN0YXRpb25JRCcsIDExICk7XG5cdFx0XHRyZXR2YWwgPSBtYXRjaGVzWzFdO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiByZXR2YWw7XG59O1xuXG4vLyMyMzQyIC0gQ2xvc2UgYWxsIG9wZW4gZWRpdCB2aWV3cyBmcm9tIG9uZSBwbGFjZS5cbkdsb2JhbC5jbG9zZUVkaXRWaWV3cyA9IGZ1bmN0aW9uKCBjYWxsYmFjayApIHtcblx0Ly9Eb24ndCBjaGVjayB0aGUgLmlzX2NoYW5nZWQgZmxhZywgYXMgdGhhdCB3aWxsIHByZXZlbnQgZWRpdCB2aWV3cyBmcm9tIGJlaW5nIGNsb3NlZCBpZiBubyBkYXRhIGhhcyBiZWVuIGNoYW5nZWQuXG5cdC8vICBGb3IgZXhhbXBsZSBpZiB5b3UgZ28gdG8gTXlBY2NvdW50IC0+IFJlcXVlc3QgQXV0aG9yaXphdGlvbiwgVmlldyBhbnkgcmVxdWVzdCwgY2xpY2sgdGhlIFwiVGltZVNoZWV0XCIgaWNvbiwgdGhlbiBjbGljayB0aGUgUmVxdWVzdCB0aW1lc2hlZXQgY2VsbCAoanVzdCBiZWxvdyB0aGUgcHVuY2hlcykgdG8gbmF2aWdhdGUgYmFjayB0byB0aGUgcmVxdWVzdHMuXG5cdGlmICggTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3JlcG9ydF9jb250cm9sbGVyICkgeyAvLyYmIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9yZXBvcnRfY29udHJvbGxlci5pc19jaGFuZ2VkID09IHRydWUgKSB7XG5cdFx0TG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3JlcG9ydF9jb250cm9sbGVyLm9uQ2FuY2VsQ2xpY2soIG51bGwsIG51bGwsIGZ1bmN0aW9uKCkge1xuXHRcdFx0R2xvYmFsLmNsb3NlRWRpdFZpZXdzKCBjYWxsYmFjayApO1xuXHRcdH0gKTtcblx0fSBlbHNlIGlmICggTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX2VkaXRfb25seV9jb250cm9sbGVyICkgeyAvLyYmIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9lZGl0X29ubHlfY29udHJvbGxlci5pc19jaGFuZ2VkID09IHRydWUgKSB7XG5cdFx0TG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX2VkaXRfb25seV9jb250cm9sbGVyLm9uQ2FuY2VsQ2xpY2soIG51bGwsIG51bGwsIGZ1bmN0aW9uKCkge1xuXHRcdFx0R2xvYmFsLmNsb3NlRWRpdFZpZXdzKCBjYWxsYmFjayApO1xuXHRcdH0gKTtcblx0fSBlbHNlIGlmICggTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3N1Yl9jb250cm9sbGVyICYmIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9zdWJfY29udHJvbGxlci5lZGl0X3ZpZXcgKSB7IC8vJiYgTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3N1Yl9jb250cm9sbGVyLmlzX2NoYW5nZWQgPT0gdHJ1ZSApIHtcblx0XHRMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fc3ViX2NvbnRyb2xsZXIub25DYW5jZWxDbGljayggbnVsbCwgbnVsbCwgZnVuY3Rpb24oKSB7XG5cdFx0XHRHbG9iYWwuY2xvc2VFZGl0Vmlld3MoIGNhbGxiYWNrICk7XG5cdFx0fSApO1xuXHR9IGVsc2UgaWYgKCBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyICYmIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIuZWRpdF92aWV3ICkgeyAvLyYmIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIuaXNfY2hhbmdlZCA9PSB0cnVlICkge1xuXHRcdExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIub25DYW5jZWxDbGljayggbnVsbCwgbnVsbCwgZnVuY3Rpb24oKSB7XG5cdFx0XHRHbG9iYWwuY2xvc2VFZGl0Vmlld3MoIGNhbGxiYWNrICk7XG5cdFx0fSApO1xuXHR9IGVsc2UgaWYgKCBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyICYmXG5cdFx0TG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlci52aWV3SWQgPT09ICdUaW1lU2hlZXQnICYmXG5cdFx0TG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlci5nZXRQdW5jaE1vZGUoKSA9PT0gJ21hbnVhbCcgKSB7XG5cdFx0TG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlci5kb05leHRJZk5vVmFsdWVDaGFuZ2VJbk1hbnVhbEdyaWQoIGZ1bmN0aW9uKCkge1xuXHRcdFx0Ly8jMjU2NyBNdXN0IGNvbmNsdWRlIGhlcmUuIFJlY3Vyc2lvbiB3b3VsZCBiZSBpbmZpbml0ZVxuXHRcdFx0aWYgKCBjYWxsYmFjayApIHtcblx0XHRcdFx0Y2FsbGJhY2soKTtcblx0XHRcdH1cblx0XHR9ICk7XG5cdH0gZWxzZSB7XG5cdFx0aWYgKCBjYWxsYmFjayApIHtcblx0XHRcdGNhbGxiYWNrKCk7XG5cdFx0fVxuXHR9XG59O1xuXG4vLyMyMzUxIC0gcmVkIGJvcmRlciBmb3Igc2FuZGJveCBtb2RlXG5HbG9iYWwuc3R5bGVTYW5kYm94ID0gZnVuY3Rpb24oKSB7XG5cdGlmICggQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhWydzYW5kYm94J10gJiYgQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhWydzYW5kYm94J10gPT0gdHJ1ZSApIHtcblx0XHQkKCAnYm9keScgKS5hZGRDbGFzcyggJ3NhbmRib3hfY29udGFpbmVyJyApO1xuXHR9XG59O1xuXG4vLyMyMzUxIC0gVXNlZCBmb3IgbG9nZ2luZyBpbiBhcyBlbXBsb3llZS9jbGllbnQgb3Igc3dpdGNoaW5nIHRvIHNhbmRib3ggbW9kZS5cbkdsb2JhbC5OZXdTZXNzaW9uID0gZnVuY3Rpb24oIHVzZXJfaWQsIGNsaWVudF9pZCApIHtcblx0dmFyIGFwaV9hdXRoID0gVFRBUEkuQVBJQXV0aGVudGljYXRpb247XG5cdGFwaV9hdXRoLm5ld1Nlc3Npb24oIHVzZXJfaWQsIGNsaWVudF9pZCwge1xuXHRcdG9uUmVzdWx0OiBmdW5jdGlvbiggcmVzdWx0ICkge1xuXHRcdFx0aWYgKCAhcmVzdWx0LmlzVmFsaWQoKSApIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHR2YXIgcmVzdWx0X2RhdGEgPSByZXN1bHQuZ2V0UmVzdWx0KCk7XG5cdFx0XHRpZiAoIHJlc3VsdF9kYXRhICYmIHJlc3VsdF9kYXRhLnVybCApIHtcblx0XHRcdFx0dmFyIHVybCA9IHJlc3VsdF9kYXRhLnVybDtcblx0XHRcdFx0aWYgKCB1cmwuaW5kZXhPZiggJ2h0dHAnICkgPT09IC0xICkge1xuXHRcdFx0XHRcdHVybCA9IHdpbmRvdy5sb2NhdGlvbi5wcm90b2NvbCArICcvLycgKyB1cmw7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHR2YXIgYWx0ZXJuYXRlX3Nlc3Npb25fZGF0YSA9IHtcblx0XHRcdFx0XHRuZXdfc2Vzc2lvbl9pZDogcmVzdWx0X2RhdGEuc2Vzc2lvbl9pZCxcblx0XHRcdFx0XHRwcmV2aW91c19zZXNzaW9uX2lkOiBnZXRDb29raWUoIEdsb2JhbC5nZXRTZXNzaW9uSURLZXkoKSApLFxuXHRcdFx0XHRcdHByZXZpb3VzX3Nlc3Npb25fdXJsOiBHbG9iYWwuZ2V0QmFzZVVSTCgpLFxuXHRcdFx0XHRcdHByZXZpb3VzX3Nlc3Npb25fdmlldzogd2luZG93LmxvY2F0aW9uLmhyZWYuc3BsaXQoICcjIW09JyApWzFdLFxuXHRcdFx0XHRcdHByZXZpb3VzX2Nvb2tpZV9wYXRoOiBMb2NhbENhY2hlRGF0YS5jb29raWVfcGF0aFxuXHRcdFx0XHR9O1xuXG5cdFx0XHRcdHNldENvb2tpZSggJ0FsdGVybmF0ZVNlc3Npb25EYXRhJywgSlNPTi5zdHJpbmdpZnkoIGFsdGVybmF0ZV9zZXNzaW9uX2RhdGEgKSwgMSwgcmVzdWx0X2RhdGEuY29va2llX2Jhc2VfdXJsLCBHbG9iYWwuZ2V0SG9zdCgpICk7XG5cblx0XHRcdFx0R2xvYmFsLnNldFVSTFRvQnJvd3NlciggdXJsICsgJ2h0bWw1LyMhbT1Mb2dpbicgKTtcblx0XHRcdFx0R2xvYmFsLm5lZWRSZWxvYWRCcm93c2VyID0gdHJ1ZTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFRBbGVydE1hbmFnZXIuc2hvd0FsZXJ0KCAkLmkxOG4uXyggJ0VSUk9SOiBVbmFibGUgdG8gcGVyZm9ybSBhY3Rpb24sIHBsZWFzZSBjb250YWN0IHlvdXIgJXMgYWRtaW5pc3RyYXRvciBpbW1lZGlhdGVseS4nLCBMb2NhbENhY2hlRGF0YS5nZXRBcHBsaWNhdGlvbk5hbWUoKSApLCAkLmkxOG4uXyggJ0VSUk9SJyApICk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9ICk7XG5cbn07XG5cbkdsb2JhbC5pc051bWVyaWMgPSBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdHZhciByZXR2YWwgPSBmYWxzZTtcblxuXHR2YWx1ZSA9IHBhcnNlRmxvYXQoIHZhbHVlICk7XG5cdGlmICggdHlwZW9mIHZhbHVlID09ICdudW1iZXInICYmICFpc05hTiggdmFsdWUgKSApIHtcblx0XHRyZXR2YWwgPSB0cnVlO1xuXHR9XG5cblx0cmV0dXJuIHJldHZhbDtcbn07XG5cbi8vQ2FsY3VsYXRlcyBhIFwic21hcnRcIiBkZWJvdW5jZSB0aW1lIGJhc2VkIG9uIHRoZSBuZXR3b3JrIHBpbmcgdGltZS5cbi8vRGVib3VuY2Ugb24gYXQgbGVhc3QgMS41eCB0aGUgcm91bmQtdHJpcCBwaW5nIHRpbWUuICggMzMzICogMS41ID0gNTAwbXMuIClcbi8vQmVjYXVzZSBhIHVzZXIgb24gYSByZWFsbHkgc2xvdyBjb25uZWN0aW9uIGNvdWxkIGNsaWNrIFNhdmUgMXMgYXBhcnQgYW5kIHRoZSBwYWNrZXRzIGNvdWxkIGFycml2ZSBjbG9zZSB0byBlYWNoIG90aGVyIGFuZCBjYXVzZSBkdXBsaWNhdGUgcmVxdWVzdCBlcnJvcnMgc3RpbGwuXG5HbG9iYWwuY2FsY0RlYm91bmNlV2FpdFRpbWVCYXNlZE9uTmV0d29yayA9IGZ1bmN0aW9uKCBtaW5fdGltZSA9IG51bGwsIG1heF90aW1lID0gbnVsbCApIHtcblx0dmFyIHBpbmcgPSBHbG9iYWwuY3VycmVudF9waW5nO1xuXG5cdGlmICggIW1pbl90aW1lICkge1xuXHRcdHZhciBtaW5fdGltZSA9IDUwMDsgLy9UdXJucyBpbnRvIDUwMG1zIGFmdGVyIDEuNXhcblx0fVxuXG5cdGlmICggIW1heF90aW1lICkge1xuXHRcdHZhciBtYXhfdGltZSA9IDEwMDAwOyAvL1R1cm5zIGludG8gMTBzIGFmdGVyIDEuNXhcblx0fVxuXG5cdHZhciByZXR2YWwgPSAoIHBpbmcgKiAxLjUgKTtcblxuXHRpZiAoIHJldHZhbCA8IG1pbl90aW1lICkge1xuXHRcdHJldHZhbCA9IG1pbl90aW1lO1xuXHR9XG5cblx0aWYgKCByZXR2YWwgPiBtYXhfdGltZSApIHtcblx0XHRyZXR2YWwgPSBtYXhfdGltZTtcblx0fVxuXG5cdHJldHVybiByZXR2YWw7XG59XG5cbi8vIFJldHVybnMgYSBmdW5jdGlvbiwgdGhhdCwgYXMgbG9uZyBhcyBpdCBjb250aW51ZXMgdG8gYmUgaW52b2tlZCwgd2lsbCBub3QgYmUgdHJpZ2dlcmVkLiBUaGUgZnVuY3Rpb24gd2lsbCBiZSBjYWxsZWQgYWZ0ZXIgaXQgc3RvcHMgYmVpbmcgY2FsbGVkIGZvciBOIG1pbGxpc2Vjb25kcy5cbi8vIElmIGBpbW1lZGlhdGVgIGlzIHBhc3NlZCwgdHJpZ2dlciB0aGUgZnVuY3Rpb24gb24gdGhlIGxlYWRpbmcgZWRnZSwgaW5zdGVhZCBvZiB0aGUgdHJhaWxpbmcuXG5HbG9iYWwuZGVib3VuY2UgPSBmdW5jdGlvbiggY2FsbGJhY2ssIHdhaXQsIGltbWVkaWF0ZSApIHtcblx0dmFyIHRpbWVvdXQ7XG5cblx0cmV0dXJuIGZ1bmN0aW9uKCkge1xuXHRcdHZhciBjb250ZXh0ID0gdGhpcztcblx0XHR2YXIgYXJncyA9IGFyZ3VtZW50cztcblxuXHRcdHZhciBjYWxsYmFja19uYW1lID0gKCBjYWxsYmFjay5uYW1lICkgPyBjYWxsYmFjay5uYW1lIDogJ04vQSc7XG5cblx0XHR2YXIgbGF0ZXIgPSBmdW5jdGlvbigpIHtcblx0XHRcdHRpbWVvdXQgPSBudWxsO1xuXHRcdFx0aWYgKCAhaW1tZWRpYXRlICkge1xuXHRcdFx0XHREZWJ1Zy5UZXh0KCAnQ2FsbGluZyBhZnRlciBkZWJvdW5jZSB3YWl0OiAnICsgY2FsbGJhY2tfbmFtZSArICcgV2FpdCBUaW1lOiAnICsgd2FpdCwgJ0dsb2JhbC5qcycsICdHbG9iYWwnLCAnZGVib3VuY2UnLCAxMCApO1xuXHRcdFx0XHRjYWxsYmFjay5hcHBseSggY29udGV4dCwgYXJncyApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0RGVidWcuVGV4dCggJ1NraXBwaW5nIGR1ZSB0byBkZWJvdW5jZTogJyArIGNhbGxiYWNrX25hbWUgKyAnIFdhaXQgVGltZTogJyArIHdhaXQsICdHbG9iYWwuanMnLCAnR2xvYmFsJywgJ2RlYm91bmNlJywgMTEgKTtcblx0XHRcdH1cblx0XHR9O1xuXG5cdFx0dmFyIGNhbGxfbm93ID0gaW1tZWRpYXRlICYmICF0aW1lb3V0O1xuXG5cdFx0Y2xlYXJUaW1lb3V0KCB0aW1lb3V0ICk7XG5cblx0XHR0aW1lb3V0ID0gc2V0VGltZW91dCggbGF0ZXIsIHdhaXQgKTtcblxuXHRcdGlmICggY2FsbF9ub3cgKSB7XG5cdFx0XHREZWJ1Zy5UZXh0KCAnQ2FsbGluZyBpbW1lZGlhdGUgZGVib3VuY2U6ICcgKyBjYWxsYmFja19uYW1lICsgJyBXYWl0IFRpbWU6ICcgKyB3YWl0LCAnR2xvYmFsLmpzJywgJ0dsb2JhbCcsICdkZWJvdW5jZScsIDEwICk7XG5cdFx0XHRjYWxsYmFjay5hcHBseSggY29udGV4dCwgYXJncyApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHREZWJ1Zy5UZXh0KCAnU2tpcHBpbmcgZHVlIHRvIGRlYm91bmNlOiAnICsgY2FsbGJhY2tfbmFtZSArICcgV2FpdCBUaW1lOiAnICsgd2FpdCwgJ0dsb2JhbC5qcycsICdHbG9iYWwnLCAnZGVib3VuY2UnLCAxMSApO1xuXHRcdH1cblx0fTtcbn07XG5cbi8qKlxuICogRmlsdGVyIG91dHB1dCB0byBwcmV2ZW50IHRoZSB1c2VyIGZyb20gc2VlaW5nIHN0cmluZ3Mgc3VjaCBhcyB1bmRlZmluZWQsIGZhbHNlIG9yIG51bGwuXG4gKiBAcGFyYW0ge3N0cmluZ30gZW50cnkgdGhlIHN0cmluZyB0aGF0IG5lZWRzIHRvIGJlIHNhbml0aXplZC5cbiAqIEBwYXJhbSB7QXJyYXl9IFtmaWx0ZXJzXSBvcHRpb25hbCBhcnJheSBvZiBmaWx0ZXJzLiBJZiBub25lIGlzIHN1cHBsaWVkLCBkZWZhdWx0cyB3aWxsIGJlIHVzZWQuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSByZXR1cm5zIHRoZSBzYW5pdGl6ZWQgc3RyaW5nIHJlc3VsdFxuICovXG5HbG9iYWwuZmlsdGVyT3V0cHV0ID0gZnVuY3Rpb24oIGVudHJ5LCBmaWx0ZXJzICkge1xuXHQvLyBkZWZhdWx0IGZpbHRlcnMgY2FuIGJlIG92ZXJyaWRkZW4gYnkgcGFzc2luZyBpbiBhIHNlY29uZCBwYXJhbVxuXG5cdGlmICggIWZpbHRlcnMgKSB7XG5cdFx0ZmlsdGVycyA9IFtmYWxzZSwgdW5kZWZpbmVkLCBudWxsLCAnZmFsc2UnLCAndW5kZWZpbmVkJywgJ251bGwnXTtcblx0fVxuXG5cdC8vIGlmIGZpbHRlciBtYXRjaGVzLCByZXBsYWNlIGNvbnRlbnRzIHdpdGggZW1wdHkgc3RyaW5nXG5cdGlmICggKCBmaWx0ZXJzLmluZGV4T2YoIGVudHJ5ICkgIT09IC0xICkgKSB7XG5cdFx0cmV0dXJuICcnO1xuXHR9IGVsc2Uge1xuXHRcdHJldHVybiBlbnRyeTtcblx0fVxufTtcblxuLyoqXG4gKiBncm91cEFycmF5RGF0YUJ5S2V5IC0gVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIGdyb3VwIGRhdGEgYnkgb2JqZWN0IGtleSAtIHVzZWQgKHNvIGZhcikgZm9yIHRoZSBnZW9mZW5jZSBmaWx0ZXJzXG4gKiBAcGFyYW0ge09iamVjdFtdfSBkYXRhIC0gdGhlIGFycmF5IGRhdGFzZXRcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW21ha2VVbmlxdWVdIC0gdHJ1ZSB3aWxsIG9ubHkgb3V0cHV0IG9uZSBvY2N1cmFuY2UgcGVyIGtleS4gZmFsc2Ugb3Igb21taXRpbmcgd2lsbCByZXR1cm4gYWxsIG9jY3VyYW5jZXNcbiAqIEByZXR1cm5zIHsqfVxuICovXG5HbG9iYWwuZ3JvdXBBcnJheURhdGFCeUtleSA9IGZ1bmN0aW9uKCBkYXRhLCBtYWtlVW5pcXVlICkge1xuXG5cdHJldHVybiBkYXRhLnJlZHVjZSggZnVuY3Rpb24oIGFjY3VtdWxhdG9yLCBjdXJyZW50VmFsdWUgKSB7XG5cdFx0Ly8gZ2V0IGEgbGlzdCBvZiBhbGwgb2JqZWN0IGtleXMgZm9yIGRhdGEgb2JqZWN0LCB0aGVuIGl0ZXJhdGUgdGhyb3VnaCBlYWNoXG5cdFx0T2JqZWN0LmVudHJpZXMoIGN1cnJlbnRWYWx1ZSApLmZvckVhY2goIGZ1bmN0aW9uKCBrZXkgKSB7XG5cdFx0XHRhY2N1bXVsYXRvcltrZXlbMF1dID0gYWNjdW11bGF0b3Jba2V5WzBdXSB8fCBbXTtcblxuXHRcdFx0Ly8gY2hlY2sgaWYgdmFsdWUgZXhpc3RzIG9yIGFkZCBhbnl3YXkgaWYgbWFrZVVuaXF1ZSBpcyBmYWxzZVxuXHRcdFx0aWYgKCBhY2N1bXVsYXRvcltrZXlbMF1dLmluZGV4T2YoIGtleVsxXSApID09PSAtMSB8fCAhbWFrZVVuaXF1ZSApIHtcblx0XHRcdFx0YWNjdW11bGF0b3Jba2V5WzBdXS5wdXNoKCBrZXlbMV0gKTtcblx0XHRcdH1cblx0XHR9ICk7XG5cdFx0cmV0dXJuIGFjY3VtdWxhdG9yO1xuXHR9LCB7fSApO1xufTtcblxuLyoqXG4gKiBVc2VkIHRvIG1vZGlmeSB0aGUgdmlld3BvcnQgbWV0YSB0YWcgaW4gdGhlIGluZGV4LnBocCBoZWFkIHNlY3Rpb24uIFRoaXMgY29udHJvbHMgdGhlICd2aXJ0dWFsJyBkZXZpY2Ugdmlld3BvcnQgb24gbW9iaWxlIGRldmljZXMuXG4gKiBNb3JlIGluZm86IGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3dlYi91cGRhdGVzLzIwMTUvMDEvV2hhdC10aGUtVmlld3BvcnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBzZXR0aW5nIC0gbmFtZSBvZiBwcmUtZGVmaW5lZCB2aWV3cG9ydCBzZXR0aW5nXG4gKiBAcmV0dXJucyB7c3RyaW5nfSByZXR1cm5zIHRoZSBuZXcgY29udGVudCB2YWx1ZSBmb3IgdGhlIHZpZXdwb3J0IG1ldGEgdGFnXG4gKiBAZXhhbXBsZSBBIHVzZSBjYXNlIGlzIFNldHRpbmcgbW9iaWxlIHZpZXcgb24gbG9naW4sIHRoZW4gYmFjayB0byBkZXNrdG9wICg5OTBweCB2aXJ0dWFsKSBhZnRlciBsb2dpbiwgdG8gYWxsb3cgcGFuICYgem9vbSwgYXMgbm90IHdob2xlIGFwcCBpcyBtb2JpbGUgb3B0aW1pemVkLlxuICovXG5HbG9iYWwuc2V0VmlydHVhbERldmljZVZpZXdwb3J0ID0gZnVuY3Rpb24oIHNldHRpbmcgKSB7XG5cdHZhciB3aWR0aDtcblx0dmFyIHNjYWxlO1xuXHR2YXIgbWV0YV90YWdfdmlld3BvcnQgPSAkKCAnbWV0YVtuYW1lPXZpZXdwb3J0XScgKTtcblxuXHRpZiAoICFzZXR0aW5nIHx8ICFtZXRhX3RhZ192aWV3cG9ydCB8fCBtZXRhX3RhZ192aWV3cG9ydC5sZW5ndGggIT09IDEgKSB7XG5cdFx0RGVidWcuVGV4dCggJ0Vycm9yOiBNaXNzaW5nIHBhcmFtcyBpbiBmdW5jdGlvbiBjYWxsJywgJ0dsb2JhbC5qcycsICdHbG9iYWwnLCAnc2V0VmlydHVhbERldmljZVZpZXdwb3J0JywgMSApO1xuXHRcdHJldHVybiB1bmRlZmluZWQ7XG5cdH1cblx0aWYgKCBzZXR0aW5nID09PSAnbW9iaWxlJyApIHtcblx0XHR3aWR0aCA9ICdkZXZpY2Utd2lkdGgnO1xuXHRcdHNjYWxlID0gMTtcblx0fSBlbHNlIGlmICggc2V0dGluZyA9PT0gJ2Rlc2t0b3AnICkge1xuXHRcdHdpZHRoID0gOTkwOyAvLyBNaW5pdW0gYXBwbGljYXRpb24gd2lkdGggd2hpY2ggd2FzIHByZXZpb3VzbHkgdXNlZCBlbHNld2hlcmUuXG5cdFx0c2NhbGUgPSAwLjU7XG5cdH0gZWxzZSB7XG5cdFx0RGVidWcuVGV4dCggJ0Vycm9yOiBJbnZhbGlkIHNldHRpbmcgcGFzc2VkIHRvIGZ1bmN0aW9uJywgJ0dsb2JhbC5qcycsICdHbG9iYWwnLCAnc2V0VmlydHVhbERldmljZVZpZXdwb3J0JywgMSApO1xuXHRcdHJldHVybiB1bmRlZmluZWQ7XG5cdH1cblx0aWYgKCB3aWR0aCAmJiBzY2FsZSApIHtcblx0XHRtZXRhX3RhZ192aWV3cG9ydC5hdHRyKCAnY29udGVudCcsICd3aWR0aD0nICsgd2lkdGggKyAnLCBpbml0aWFsLXNjYWxlPScgKyBzY2FsZSApO1xuXHRcdHJldHVybiBtZXRhX3RhZ192aWV3cG9ydC5hdHRyKCAnY29udGVudCcgKTtcblx0fSBlbHNlIHtcblx0XHREZWJ1Zy5UZXh0KCAnRXJyb3I6IEludmFsaWQgZGV2aWNlIHNldHRpbmdzLiBFaXRoZXIgd2lkdGggb3Igc2NhbGUgaXMgaW52YWxpZCcsICdHbG9iYWwuanMnLCAnR2xvYmFsJywgJ3NldFZpcnR1YWxEZXZpY2VWaWV3cG9ydCcsIDEgKTtcblx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHR9XG59O1xuXG4vL0NsZWFyIGFsbCBzZXNzaW9uIGFuZCBsb2NhbCBjYWNoZSBkYXRhIGZvciBsb2dvdXQuXG5HbG9iYWwuTG9nb3V0ID0gZnVuY3Rpb24oKSB7XG5cdFNlcnZpY2VDYWxsZXIuYWJvcnRBbGwoKTsgLy9BYm9ydCBhbnkgcGVuZGluZyBBSkFYIHJlcXVlc3RzIHNvIHRoZWlyIGNhbGxiYWNrcyBkb24ndCBnZXQgdHJpZ2dlcmVkIGFuZCBjYXVzZSBhbGwga2luZCBvZiB3ZWlyZG5lc3MuXG5cdExvY2FsQ2FjaGVEYXRhLmNsZWFuTmVjZXNzYXJ5Q2FjaGUoKTsgLy9CZWNhdXNlIHRoaXMgY2xvc2VzIFdpemFyZHMsIHdoaWNoIHRoZXkgY291bGQgcmVxdWlyZSBjYWNoZWQgZGF0YSB0byBtYWtlIEFQSSBjYWxscywgaXQgc2hvdWxkIHJ1biBiZWZvcmUgYW55IHRoaW5nIGlzIGFjdHVhbGx5IGNsZWFyZWQgZmlyc3QuXG5cdEdsb2JhbC5jbGVhclNlc3Npb25Db29raWUoKTtcblx0TG9jYWxDYWNoZURhdGEuc2V0U2Vzc2lvbklEKCAnJyApO1xuXHRMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fdmlld19pZCA9ICcnOyAvLyMxNTI4ICAtICBMb2dvdXQgaWNvbiBub3Qgd29ya2luZy5cblx0Ly9Mb2NhbENhY2hlRGF0YS5zZXRMb2dpbkRhdGEoIG51bGwgKTsgIC8vVGhpcyBpcyBjb21tb24gZGF0YSB0byB0aGUgVFQgaW5zdGFuY2UgKGllOiBhcHBsaWNhdGlvbl9uYW1lKSBhbmQgZG9lc24ndCByZWFsbHkgbmVlZCB0byBnZXQgcmVzZXQgb24gbG9nb3V0LlxuXHRMb2NhbENhY2hlRGF0YS5zZXRMb2dpblVzZXIoIG51bGwgKTtcblx0TG9jYWxDYWNoZURhdGEuc2V0TG9naW5Vc2VyUHJlZmVyZW5jZSggbnVsbCApO1xuXHRMb2NhbENhY2hlRGF0YS5zZXRQZXJtaXNzaW9uRGF0YSggbnVsbCApO1xuXHRMb2NhbENhY2hlRGF0YS5zZXRDdXJyZW50Q29tcGFueSggbnVsbCApO1xuXHRMb2NhbENhY2hlRGF0YS5zZXRMYXN0UHVuY2hUaW1lKCBudWxsICk7XG5cdExvY2FsQ2FjaGVEYXRhLnNldEpvYlF1ZXVlUHVuY2hEYXRhKCBudWxsICk7XG5cdHNlc3Npb25TdG9yYWdlLmNsZWFyKCk7XG5cblx0R2xvYmFsLmV2ZW50X2J1cy5lbWl0KCAnZ2xvYmFsJywgJ3Jlc2V0X3Z1ZV9kYXRhJyApOyAvLyBSZXNldCB2dWUgZGF0YSB0byBkZWZhdWx0IHZhbHVlcy4gT3RoZXJ3aXNlIHVzZXIgZGF0YSBmcm9tIHByZXZpb3VzIHNlc3Npb24gd2lsbCByZW1haW4uXG5cblx0Ly9Eb24ndCByZWxvYWQgb3IgY2hhbmdlIHZpZXdzLCBhbGxvdyB0aGF0IHRvIGJlIGRvbmUgYnkgdGhlIGNhbGxlci5cblxuXHRyZXR1cm4gdHJ1ZTtcbn07XG5cbkdsb2JhbC5nbG93QW5pbWF0aW9uID0ge1xuXHRzdGFydDogZnVuY3Rpb24oIGVsZW1lbnQsIGNvbG9yICkge1xuXHRcdGlmICggIWVsZW1lbnQgKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHRcdGlmICggIWNvbG9yICkge1xuXHRcdFx0Ly8gU2V0IGRlZmF1bHQgY29sb3IgdG8gZ3JlZW4uIFJlbWVtYmVyIHRoaXMgYWZmZWN0cyB0aGUgdGV4dCBjb2xvciBvZiB0aGUgZWxlbWVudCB0b28uIE1pZ2h0IHdhbnQgdG8gZGlzYWJsZSB0aGlzIGRlZmF1bHQgaW4gZnV0dXJlIGlmIHdlIHdhbnQgdG8gc2V0IGNvbG9yIHNlcGFyYXRlbHkgb3IgdXNlIGluaGVyaXRlZC9leGlzdGluZy5cblx0XHRcdGNvbG9yID0gJyMwMGZmMDAnO1xuXHRcdH1cblx0XHRyZXR1cm4gZWxlbWVudFxuXHRcdFx0LmNzcyggJ2NvbG9yJywgY29sb3IgKSAvLyBzZXRzIHRoZSBmb250IGNvbG9yIG9mIHRoZSBlbGVtZW50LiBUaGUgZ2xvdyB0aGVuIHVzZXMgdGhpcyB2YWx1ZSB2aWEgJ2N1cnJlbnRDb2xvcidcblx0XHRcdC5hZGRDbGFzcyggJ2FuaW1hdGUtZ2xvdycgKTtcblx0fSxcblx0c3RvcDogZnVuY3Rpb24oIGVsZW1lbnQgKSB7XG5cdFx0aWYgKCAhZWxlbWVudCApIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuIGVsZW1lbnQucmVtb3ZlQ2xhc3MoICdhbmltYXRlLWdsb3cnICk7XG5cdH1cbn07XG5cbkdsb2JhbC5idWlsZEFyZ0RpYyA9IGZ1bmN0aW9uKCBhcnJheSApIHtcblx0dmFyIGxlbiA9IGFycmF5Lmxlbmd0aDtcblx0dmFyIHJlc3VsdCA9IHt9O1xuXHRmb3IgKCB2YXIgaSA9IDA7IGkgPCBsZW47IGkrKyApIHtcblx0XHR2YXIgaXRlbSA9IGFycmF5W2ldO1xuXHRcdGl0ZW0gPSBpdGVtLnNwbGl0KCAnPScgKTtcblx0XHRyZXN1bHRbaXRlbVswXV0gPSBpdGVtWzFdO1xuXHR9XG5cblx0cmV0dXJuIHJlc3VsdDtcbn07XG5cbkdsb2JhbC5nZXRGZWF0dXJlRmxhZyA9IGZ1bmN0aW9uKCBmbGFnLCBkZWZhdWx0X3ZhbHVlICkge1xuXHRsZXQgZmVhdHVyZV9mbGFncyA9IExvY2FsQ2FjaGVEYXRhLmdldEZlYXR1cmVGbGFnRGF0YSgpO1xuXG5cdC8vUG9zdCBsb2dpbiBoYXMgdXBkYXRlZCBmZWF0dXJlIGZsYWdzIGFuZCBhcmUgc3BlY2lmaWMgdG8gdGhlIGN1cnJlbnQgY29tcGFueS5cblx0aWYgKCBmZWF0dXJlX2ZsYWdzICYmIGZlYXR1cmVfZmxhZ3MuaGFzT3duUHJvcGVydHkoIGZsYWcgKSApIHtcblx0XHRyZXR1cm4gZmVhdHVyZV9mbGFnc1tmbGFnXTtcblx0fVxuXG5cdC8vSWYgd2Ugb25seSBoYXZlIHByZS1sb2dpbiBkcXRhLCB1c2UgdGhlIGZlYXR1cmUgZmxhZ3MgZm9yIHRoZSBpbnN0YWxsZWQgY29tcGFueS5cblx0aWYgKCBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEgJiYgQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLmZlYXR1cmVfZmxhZ3MgJiYgQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLmZlYXR1cmVfZmxhZ3MuaGFzT3duUHJvcGVydHkoIGZsYWcgKSApIHtcblx0XHRyZXR1cm4gQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLmZlYXR1cmVfZmxhZ3NbZmxhZ107XG5cdH1cblxuXHRyZXR1cm4gZGVmYXVsdF92YWx1ZTtcbn07XG5cbkdsb2JhbC5zaG93QXV0aGVudGljYXRpb25Nb2RhbCA9IGZ1bmN0aW9uKCB2aWV3X2lkLCBzZXNzaW9uX3R5cGUsIG1mYV9kYXRhLCBpc19yZWF1dGhlbnRpY2F0aW9uLCBhdXRoZW50aWNhdGVfY2FsbGJhY2ssIGVycm9yX3N0cmluZyA9ICcnLCBtb3VudF9pZCA9ICd0dF9hdXRoZW50aWNhdGVfdWknICkge1xuXHRUVFZ1ZVV0aWxzLm1vdW50Q29tcG9uZW50KCBtb3VudF9pZCwgVFRNdWx0aUZhY3RvckF1dGhlbnRpY2F0aW9uLCB7XG5cdFx0dmlld19pZDogdmlld19pZCxcblx0XHRzZXNzaW9uX3R5cGU6IHNlc3Npb25fdHlwZSxcblx0XHRjb21wb25lbnRfaWQ6IG1vdW50X2lkLFxuXHRcdG1mYV9kYXRhOiBtZmFfZGF0YSxcblx0XHR1c2VyX25hbWU6IExvY2FsQ2FjaGVEYXRhLmdldExvZ2luVXNlcigpID8gTG9jYWxDYWNoZURhdGEuZ2V0TG9naW5Vc2VyKCkudXNlcl9uYW1lIDogJycsXG5cdFx0ZXJyb3Jfc3RyaW5nOiBMb2NhbENhY2hlRGF0YS5sb2dpbl9lcnJvcl9zdHJpbmcgfHwgZXJyb3Jfc3RyaW5nLFxuXHRcdGF1dGhlbnRpY2F0ZV9jYWxsYmFjazogYXV0aGVudGljYXRlX2NhbGxiYWNrIHx8IGZ1bmN0aW9uKCBzdWNjZXNzICkge1xuXHRcdFx0R2xvYmFsLmhpZGVBdXRoZW50aWNhdGlvbk1vZGFsKCk7XG5cdFx0XHRyZXR1cm4gc3VjY2Vzcztcblx0XHR9LFxuXHRcdGlzX3JlYXV0aGVudGljYXRpb246IGlzX3JlYXV0aGVudGljYXRpb25cblx0fSApO1xufTtcblxuR2xvYmFsLmhpZGVBdXRoZW50aWNhdGlvbk1vZGFsID0gZnVuY3Rpb24oIG1vdW50X2lkID0gJ3R0X2F1dGhlbnRpY2F0ZV91aScgKSB7XG5cdFRUVnVlVXRpbHMudW5tb3VudENvbXBvbmVudCggbW91bnRfaWQgKTtcbn07XG5cbkdsb2JhbC5nZXRTZXNzaW9uVHlwZUZvckxvZ2luID0gZnVuY3Rpb24oIHVzZXJfbmFtZSwgY2FsbGJhY2sgKSB7XG5cdFRUQVBJLkFQSUF1dGhlbnRpY2F0aW9uLmdldFNlc3Npb25UeXBlRm9yTG9naW4oIHVzZXJfbmFtZSwge1xuXHRcdG9uUmVzdWx0OiAoIHJlc3VsdCApID0+IHtcblx0XHRcdGlmICggcmVzdWx0LmlzVmFsaWQoKSApIHtcblx0XHRcdFx0Y2FsbGJhY2soIHJlc3VsdC5nZXRSZXN1bHQoKSApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y2FsbGJhY2soIGZhbHNlICk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9ICk7XG59O1xuXG5HbG9iYWwubG9naW4gPSBmdW5jdGlvbiggdXNlcl9uYW1lLCB1c2VyX3Bhc3N3b3JkLCBzZXNzaW9uX3R5cGUsIGlzX3JlYXV0aGVudGljYXRpb24sIGNhbGxiYWNrICkge1xuXHQvL0NhdGNoIGJsYW5rIHVzZXJuYW1lL3Bhc3N3b3JkcyBhcyBlYXJseSBhcyBwb3NzaWJsZS4gVGhpcyBtYXkgY2F0Y2ggc29tZSBib3RzIGZyb20gYXR0ZW1wdGluZyB0byBsb2dpbiBhcyB3ZWxsLlxuXHRpZiAoIHVzZXJfbmFtZSA9PSAnJyB8fCB1c2VyX3Bhc3N3b3JkID09ICcnICkge1xuXHRcdFRBbGVydE1hbmFnZXIuc2hvd0FsZXJ0KCAkLmkxOG4uXyggJ1BsZWFzZSBlbnRlciBhIHVzZXIgbmFtZSBhbmQgcGFzc3dvcmQuJyApICk7XG5cdFx0Y2FsbGJhY2soIGZhbHNlICk7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0aWYgKCBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyLnZpZXdJZCA9PSAnTG9naW5WaWV3JyApIHtcblx0XHR2YXIgY3JfdGV4dCA9ICQoIFwiXFx4MjNcXHg2Q1xceDZGXFx4NjdcXHg2OVxceDZFXFx4NUZcXHg2M1xceDZGXFx4NzBcXHg3OVxceDVGXFx4NzJcXHg2OVxceDY3XFx4NjhcXHg3NFxceDVGXFx4NjlcXHg2RVxceDY2XFx4NkZcIiApLnRleHQoKTtcblx0XHR2YXIgXzB4ZWU5MyA9IFtcIlxceDZGXFx4NkVcXHg2Q1xceDZGXFx4NjFcXHg2NFwiLCBcIlxceDc0XFx4NkZcXHg3NFxceDYxXFx4NkNcIiwgXCJcXHg0M1xceDZGXFx4NzBcXHg3OVxceDcyXFx4NjlcXHg2N1xceDY4XFx4NzRcXHgyMFwiLCBcIlxceDY5XFx4NkVcXHg2NFxceDY1XFx4NzhcXHg0RlxceDY2XCIsIFwiXFx4NkZcXHg3MlxceDY3XFx4NjFcXHg2RVxceDY5XFx4N0FcXHg2MVxceDc0XFx4NjlcXHg2RlxceDZFXFx4NUZcXHg2RVxceDYxXFx4NkRcXHg2NVwiLCBcIlxceDZDXFx4NkZcXHg2N1xceDY5XFx4NkVcXHg0NFxceDYxXFx4NzRcXHg2MVwiLCBcIlxceDQxXFx4NkNcXHg2Q1xceDIwXFx4NTJcXHg2OVxceDY3XFx4NjhcXHg3NFxceDczXFx4MjBcXHg1MlxceDY1XFx4NzNcXHg2NVxceDcyXFx4NzZcXHg2NVxceDY0XCIsIFwiXFx4NDVcXHg1MlxceDUyXFx4NEZcXHg1MlxceDNBXFx4MjBcXHg1NFxceDY4XFx4NjlcXHg3M1xceDIwXFx4NjlcXHg2RVxceDczXFx4NzRcXHg2MVxceDZDXFx4NkNcXHg2MVxceDc0XFx4NjlcXHg2RlxceDZFXFx4MjBcXHg2RlxceDY2XFx4MjBcIiwgXCJcXHg2MVxceDcwXFx4NzBcXHg2Q1xceDY5XFx4NjNcXHg2MVxceDc0XFx4NjlcXHg2RlxceDZFXFx4NUZcXHg2RVxceDYxXFx4NkRcXHg2NVwiLCBcIlxceDIwXFx4NjlcXHg3M1xceDIwXFx4NjlcXHg2RVxceDIwXFx4NzZcXHg2OVxceDZGXFx4NkNcXHg2MVxceDc0XFx4NjlcXHg2RlxceDZFXFx4MjBcXHg2RlxceDY2XFx4MjBcXHg3NFxceDY4XFx4NjVcXHgyMFxceDZDXFx4NjlcXHg2M1xceDY1XFx4NkVcXHg3M1xceDY1XFx4MjBcXHg2MVxceDY3XFx4NzJcXHg2NVxceDY1XFx4NkRcXHg2NVxceDZFXFx4NzRcXHgyMVwiLCBcIlxceDczXFx4NjhcXHg2RlxceDc3XFx4NDFcXHg2Q1xceDY1XFx4NzJcXHg3NFwiLCBcIlxceDY3XFx4NjVcXHg3NFxceDUyXFx4NjVcXHg3M1xceDcwXFx4NmZcXHg2ZVxceDczXFx4NjVcXHg0OFxceDY1XFx4NjFcXHg2NFxceDY1XFx4NzJcIiwgXCJcXHg0M1xceDZmXFx4NmVcXHg3NFxceDY1XFx4NmVcXHg3NFxceDJkXFx4NGNcXHg2NVxceDZlXFx4NjdcXHg3NFxceDY4XCIsIFwiXFx4NTRcXHg2OVxceDZEXFx4NjVcXHg1NFxceDcyXFx4NjVcXHg3OFwiLCBcIlxceDIzXFx4NzBcXHg2RlxceDc3XFx4NjVcXHg3MlxceDY1XFx4NjRcXHg1RlxceDYyXFx4NzlcIiwgXCJcXHg2RVxceDYxXFx4NzRcXHg3NVxceDcyXFx4NjFcXHg2Q1xceDU3XFx4NjlcXHg2NFxceDc0XFx4NjhcIiwgXCJcXHg2RVxceDYxXFx4NzRcXHg3NVxceDcyXFx4NjFcXHg2Q1xceDQ4XFx4NjVcXHg2OVxceDY3XFx4NjhcXHg3NFwiXTtcblx0XHRpZiAoICggISQoIF8weGVlOTNbMTRdIClbMF0gfHwgKCAkKCBfMHhlZTkzWzE0XSApWzBdICYmICggKCAkKCBfMHhlZTkzWzE0XSApWzBdW18weGVlOTNbMTVdXSA+IDAgJiYgJCggXzB4ZWU5M1sxNF0gKVswXVtfMHhlZTkzWzE1XV0gIT0gMTQ1ICkgfHwgKCAkKCBfMHhlZTkzWzE0XSApWzBdW18weGVlOTNbMTZdXSA+IDAgJiYgJCggXzB4ZWU5M1sxNF0gKVswXVtfMHhlZTkzWzE2XV0gIT0gNDAgKSApICkgKSB8fCBjcl90ZXh0W18weGVlOTNbM11dKCBfMHhlZTkzWzJdICkgIT09IDAgfHwgTG9jYWxDYWNoZURhdGFbXzB4ZWU5M1s1XV1bXzB4ZWU5M1s4XV1bXzB4ZWU5M1szXV0oIF8weGVlOTNbMTNdICkgIT09IDAgfHwgY3JfdGV4dFtfMHhlZTkzWzNdXSggXzB4ZWU5M1sxM10gKSAhPT0gMTcgKSB7XG5cdFx0XHRHbG9iYWwuc2VuZEVycm9yUmVwb3J0KCAoIF8weGVlOTNbN10gKyBMb2NhbENhY2hlRGF0YVtfMHhlZTkzWzVdXVtfMHhlZTkzWzhdXSArIF8weGVlOTNbOV0gKyAnIGl3OiAnICsgKCAoICQoIF8weGVlOTNbMTRdIClbMF0gKSA/ICQoIF8weGVlOTNbMTRdIClbMF1bXzB4ZWU5M1sxNV1dIDogMCApICsgJyBpaDogJyArICggKCAkKCBfMHhlZTkzWzE0XSApWzBdICkgPyAkKCBfMHhlZTkzWzE0XSApWzBdW18weGVlOTNbMTZdXSA6IDAgKSArICcgYzogJyArIGNyX3RleHRbXzB4ZWU5M1szXV0oIF8weGVlOTNbMl0gKSArICcgJyArIGNyX3RleHRbXzB4ZWU5M1szXV0oIExvY2FsQ2FjaGVEYXRhW18weGVlOTNbNV1dW18weGVlOTNbNF1dICkgKSwgU2VydmljZUNhbGxlci5yb290X3VybCwgJycsICcnLCAnJyApO1xuXHRcdH1cblx0fVxuXG5cdC8vQ2hlY2sgdG8gbWFrZSBzdXJlIGEgQ1NSRiB0b2tlbiBjb29raWUgZXhpc3RzLCBpZiBub3QgcmVmcmVzaCBpdC5cblx0R2xvYmFsLnJlZnJlc2hDU1JGVG9rZW4oICgpID0+IHtcblx0XHRUVEFQSS5BUElBdXRoZW50aWNhdGlvbi5sb2dpbiggdXNlcl9uYW1lLCB1c2VyX3Bhc3N3b3JkLCBzZXNzaW9uX3R5cGUsIGlzX3JlYXV0aGVudGljYXRpb24sIHtcblx0XHRcdG9uUmVzdWx0OiAoIHJlc3VsdCApID0+IHtcblx0XHRcdFx0aWYgKCByZXN1bHQuaXNWYWxpZCgpICkge1xuXHRcdFx0XHRcdGxldCBzZXNzaW9uX3Jlc3VsdCA9IHJlc3VsdC5nZXRSZXN1bHQoKTtcblx0XHRcdFx0XHRsZXQgc2Vzc2lvbl9pZCA9IHNlc3Npb25fcmVzdWx0LnNlc3Npb25faWQ7XG5cdFx0XHRcdFx0TG9jYWxDYWNoZURhdGEuc2V0U2Vzc2lvbklEKCBzZXNzaW9uX2lkICk7XG5cdFx0XHRcdFx0c2V0Q29va2llKCBHbG9iYWwuZ2V0U2Vzc2lvbklES2V5KCksIHNlc3Npb25faWQgKTtcblx0XHRcdFx0XHRpZiAoIExvY2FsQ2FjaGVEYXRhLmxvYWRWaWV3UmVxdWlyZWRKU1JlYWR5ICkge1xuXHRcdFx0XHRcdFx0RGVidWcuVGV4dCggJ0xvZ2luIFN1Y2Nlc3MgKGZpcnN0IHRyeSknLCBudWxsLCBudWxsLCAnb25Mb2dpbkJ0bkNsaWNrJywgMTAgKTtcblx0XHRcdFx0XHRcdGlmICggc2Vzc2lvbl9yZXN1bHQubWZhICYmIHNlc3Npb25fcmVzdWx0Lm1mYS5zdGVwICE9IGZhbHNlICYmIGlzX3JlYXV0aGVudGljYXRpb24gPT0gZmFsc2UgKSB7XG5cdFx0XHRcdFx0XHRcdEdsb2JhbC5zaG93QXV0aGVudGljYXRpb25Nb2RhbCggdGhpcy52aWV3SWQsIHNlc3Npb25fcmVzdWx0LnNlc3Npb25fdHlwZSwgc2Vzc2lvbl9yZXN1bHQubWZhLCBmYWxzZSwoIHN1Y2Nlc3MgKSA9PiB7XG5cdFx0XHRcdFx0XHRcdFx0Y2FsbGJhY2soIHJlc3VsdCApO1xuXHRcdFx0XHRcdFx0XHR9LCApO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0Y2FsbGJhY2soIHJlc3VsdCApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHR2YXIgdGltZW91dF9jb3VudCA9IDA7XG5cdFx0XHRcdFx0XHR2YXIgYXV0b19sb2dpbl90aW1lciA9IHNldEludGVydmFsKCAoKSA9PiB7XG5cdFx0XHRcdFx0XHRcdGlmICggdGltZW91dF9jb3VudCA9PSAxMDAgKSB7XG5cdFx0XHRcdFx0XHRcdFx0Y2xlYXJJbnRlcnZhbCggYXV0b19sb2dpbl90aW1lciApO1xuXHRcdFx0XHRcdFx0XHRcdFRBbGVydE1hbmFnZXIuc2hvd0FsZXJ0KCAkLmkxOG4uXyggJ1RoZSBuZXR3b3JrIGNvbm5lY3Rpb24gd2FzIGxvc3QuIFBsZWFzZSBjaGVjayB5b3VyIG5ldHdvcmsgY29ubmVjdGlvbiB0aGVuIHRyeSBhZ2Fpbi4nICkgKTtcblx0XHRcdFx0XHRcdFx0XHREZWJ1Zy5UZXh0KCAnTG9naW4gRmFpbHVyZScsICdHbG9iYWwuanMnLCAnJywgJ2xvZ2luJywgMTAgKTtcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0dGltZW91dF9jb3VudCA9IHRpbWVvdXRfY291bnQgKyAxO1xuXHRcdFx0XHRcdFx0XHRpZiAoIExvY2FsQ2FjaGVEYXRhLmxvYWRWaWV3UmVxdWlyZWRKU1JlYWR5ICkge1xuXHRcdFx0XHRcdFx0XHRcdGlmICggc2Vzc2lvbl9yZXN1bHQubWZhICYmIHNlc3Npb25fcmVzdWx0Lm1mYS5zdGVwICE9IGZhbHNlICYmIGlzX3JlYXV0aGVudGljYXRpb24gPT0gZmFsc2UgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRHbG9iYWwuc2hvd0F1dGhlbnRpY2F0aW9uTW9kYWwoIHRoaXMudmlld0lkLCBzZXNzaW9uX3Jlc3VsdC5zZXNzaW9uX3R5cGUsIHNlc3Npb25fcmVzdWx0Lm1mYSwgZmFsc2UsICggc3VjY2VzcyApID0+IHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0Y2FsbGJhY2soIHJlc3VsdCApO1xuXHRcdFx0XHRcdFx0XHRcdFx0fSApO1xuXHRcdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRjYWxsYmFjayggcmVzdWx0ICk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdERlYnVnLlRleHQoICdMb2dpbiBTdWNjZXNzIGFmdGVyIHJldHJ5OiAnICsgdGltZW91dF9jb3VudCwgJ0dsb2JhbC5qcycsICcnLCAnbG9naW4nLCAxMCApO1xuXHRcdFx0XHRcdFx0XHRcdGNsZWFySW50ZXJ2YWwoIGF1dG9fbG9naW5fdGltZXIgKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fSwgNjAwICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGlmICggcmVzdWx0LmdldERldGFpbHMoKVswXSAmJiByZXN1bHQuZ2V0RGV0YWlscygpWzBdLmhhc093blByb3BlcnR5KCAncGFzc3dvcmQnICkgKSB7XG5cdFx0XHRcdFx0XHRHbG9iYWwuc2hvd0NvbXByb21pc2VkUGFzc3dvcmRNb2RhbCggdXNlcl9uYW1lLCByZXN1bHQuZ2V0RGV0YWlsc0FzU3RyaW5nKCkgKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0VEFsZXJ0TWFuYWdlci5zaG93RXJyb3JBbGVydCggcmVzdWx0ICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGNhbGxiYWNrKCByZXN1bHQgKTtcblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdG9uRXJyb3I6ICggZSApID0+IHtcblx0XHRcdFx0RGVidWcuVGV4dCggJ0xvZ2luIEVycm9yLi4uJywgJ0dsb2JhbC5qcycsICcnLCAnbG9naW4nLCAxMCApO1xuXHRcdFx0XHRjYWxsYmFjayggZmFsc2UgKTtcblx0XHRcdH0sXG5cdFx0fSApO1xuXHR9ICk7XG5cblx0R2xvYmFsLnNob3dDb21wcm9taXNlZFBhc3N3b3JkTW9kYWwgPSBmdW5jdGlvbiggdXNlcl9uYW1lLCBtZXNzYWdlLCBjYWxsYmFjayApIHtcblx0XHRHbG9iYWwuZ2V0U2Vzc2lvblR5cGVGb3JMb2dpbiggdXNlcl9uYW1lLCAoIHJlc3VsdCApID0+IHtcblx0XHRcdGlmICggcmVzdWx0Lm1mYV90eXBlX2lkID4gMCApIHtcblx0XHRcdFx0Ly9NRkEgdXNlcnMgbXVzdCByZXNldCBwYXNzd29yZCBiZWZvcmUgbG9naW4sIG90aGVyd2lzZSBzaW1wbHkgaGF2aW5nIHRoZSBwYXNzd29yZCB3b3VsZCBieXBhc3MgTUZBLlxuXHRcdFx0XHRJbmRleFZpZXdDb250cm9sbGVyLm9wZW5XaXphcmQoICdGb3Jnb3RQYXNzd29yZFdpemFyZCcsIHsgbWVzc2FnZTogbWVzc2FnZSB9LCBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRUQWxlcnRNYW5hZ2VyLnNob3dBbGVydCggJC5pMThuLl8oICdBbiBlbWFpbCBoYXMgYmVlbiBzZW50IHRvIHlvdSB3aXRoIGluc3RydWN0aW9ucyBvbiBob3cgdG8gY2hhbmdlIHlvdXIgcGFzc3dvcmQuJyApICk7XG5cdFx0XHRcdH0gKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdC8vTm9uZSBNRkEgdXNlcnMgY2FuIGNoYW5nZSBwYXNzd29yZCBieSBzdXBwbHlpbmcgdGhlaXIgdXNlcm5hbWUsIGN1cnJlbnQgcGFzc3dvcmQgYW5kIG5ldyBwYXNzd29yZC5cblx0XHRcdFx0SW5kZXhWaWV3Q29udHJvbGxlci5vcGVuV2l6YXJkKCAnUmVzZXRQYXNzd29yZFdpemFyZCcsIHtcblx0XHRcdFx0XHR1c2VyX25hbWU6IHVzZXJfbmFtZSxcblx0XHRcdFx0XHRtZXNzYWdlOiBtZXNzYWdlXG5cdFx0XHRcdH0sIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFRBbGVydE1hbmFnZXIuc2hvd0FsZXJ0KCAkLmkxOG4uXyggJ1Bhc3N3b3JkIGhhcyBiZWVuIGNoYW5nZWQgc3VjY2Vzc2Z1bGx5LCB5b3UgbWF5IG5vdyBsb2dpbi4nICkgKTtcblx0XHRcdFx0fSApO1xuXHRcdFx0fVxuXHRcdH0gKTtcblx0fVxufTsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///9490\n")},9563:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval("/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"B\": () => (/* binding */ LocalCacheData)\n/* harmony export */ });\nvar LocalCacheData = function() {\n\n};\n\nLocalCacheData.view_layout_cache = {};\n\nLocalCacheData.i18nDic = null;\n\nLocalCacheData.ui_click_stack = [];\n\nLocalCacheData.api_stack = [];\n\nLocalCacheData.last_timesheet_selected_date = null;\n\nLocalCacheData.last_timesheet_selected_user = null;\n\nLocalCacheData.last_schedule_selected_date = null;\n\nLocalCacheData.current_open_wizard_controllers = []; //Multiple wizards can be open at once such as tax wizard and report wizard\n\nLocalCacheData.default_filter_for_next_open_view = null;\n\nLocalCacheData.extra_filter_for_next_open_view = null;\n\nLocalCacheData.default_edit_id_for_next_open_edit_view = null; //First use in save report jump to report\n\nLocalCacheData.current_open_view_id = ''; // Save current open view's id. set in BaseViewController.loadView\n\nLocalCacheData.login_error_string = ''; //Error message show on Login Screen\n\nLocalCacheData.all_url_args = {}; //All args from URL\n\nLocalCacheData.current_open_primary_controller = null; // Save current open view's id. set in BaseViewController.loadView\n\nLocalCacheData.current_open_sub_controller = null; // Save current open view's id. set in BaseViewController.loadView\n\nLocalCacheData.current_open_edit_only_controller = null; // Save current open view's id. set in BaseViewController.loadView\n\nLocalCacheData.current_open_report_controller = null; //save open report view controller\n\nLocalCacheData.current_doing_context_action = ''; //Save what context action is doing right now\n\nLocalCacheData.current_select_date = ''; // Save\n\nLocalCacheData.edit_id_for_next_open_view = '';\n\nLocalCacheData.url_args = null;\n\nLocalCacheData.result_cache = {};\n\nLocalCacheData.paging_type = 10; //0 is CLick to show more, 10 is normal paging\n\nLocalCacheData.currentShownContextMenuName = '';\n\nLocalCacheData.isSupportHTML5LocalCache = false;\n\nLocalCacheData.loginData = null;\n\nLocalCacheData.currentLanguage = 'en_us';\n\nLocalCacheData.currentLanguageDic = {};\n\nLocalCacheData.deployment_on_demand = null;\n\nLocalCacheData.productEditionId = null;\n\nLocalCacheData.applicationName = null;\n\nLocalCacheData.loginUser = null;\n\nLocalCacheData.loginUserPreference = null;\n\nLocalCacheData.openAwesomeBox = null; //To help make sure only one Awesomebox is shown at one time. Do mouse click outside job\n\nLocalCacheData.openAwesomeBoxColumnEditor = null; //To Make sure only one column editor of Awesomebox is shown at one time Do mouse click outside job\n\nLocalCacheData.openRibbonNaviMenu = null;\n\nLocalCacheData.loadedWidgetCache = {};\n\nLocalCacheData.loadedScriptNames = {}; //Save load javascript, prevent multiple load\n\nLocalCacheData.permissionData = null;\n\nLocalCacheData.uniqueCountryArray = null;\n\nLocalCacheData.custom_field_data = [];\n\nLocalCacheData.currentSelectMenuId = null;\n\nLocalCacheData.currentSelectSubMenuId = null;\n\nLocalCacheData.timesheet_sub_grid_expended_dic = {};\n\nLocalCacheData.view_min_map = {};\n\nLocalCacheData.view_min_tab_bar = null;\n\nLocalCacheData.cookie_path = APIGlobal.pre_login_data.cookie_base_url;\n\nLocalCacheData.domain_name = '';\n\nLocalCacheData.fullUrlParameterStr = '';\n\nLocalCacheData.PayrollRemittanceAgencyEventWizardController = null;\n\nLocalCacheData.resizeable_grids = [];\n\nLocalCacheData.auto_fill_data = null;\n\nLocalCacheData.scroll_bar_width = 0;\nLocalCacheData.scroll_bar_height = 0;\n\nLocalCacheData.last_punch_time = null;\nLocalCacheData.job_queue_punch_data = null;\n\nLocalCacheData.feature_flag_data = {};\n\nLocalCacheData.isStorageAvailable = function() {\n\t//Turn off sessionStorage as its not required and just slows things down anyways. We can store things in memory instead.\n\t// It also has space limitations which can be hit like: QuotaExceededError: DOM Exception 22: An attempt was made to add something to storage that exceeded the quota\n\tLocalCacheData.isSupportHTML5LocalCache = false;\n\n\t// if ( window.sessionStorage ) {\n\t// \ttry {\n\t// \t\t//Test to make sure we can actually store some data. This should help avoid JS exceptions such as: QuotaExceededError: DOM Exception 22: An attempt was made to add something to storage that exceeded the quota\n\t// \t\tvar storage = window['sessionStorage'];\n\t// \t\tvar x = '__storage_test__';\n\t// \t\tstorage.setItem(x, x);\n\t// \t\tstorage.removeItem(x);\n\t//\n\t// \t\tLocalCacheData.isSupportHTML5LocalCache = true;\n\t// \t} catch(e) {\n\t// \t\tLocalCacheData.isSupportHTML5LocalCache = false;\n\t// \t}\n\t// } else {\n\t// \tLocalCacheData.isSupportHTML5LocalCache = false;\n\t// }\n\t//Debug.Text( 'Is sessionStorage available: '+ LocalCacheData.isSupportHTML5LocalCache, 'LocalCacheData.js', 'LocalCacheData', 'isStorageAvailable', 10 );\n\n\treturn LocalCacheData.isSupportHTML5LocalCache;\n};\n\nLocalCacheData.isLocalCacheExists = function( key ) {\n\tif ( LocalCacheData.getLocalCache( key ) !== null ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n};\n\nLocalCacheData.getLocalCache = function( key, format ) {\n\t//BUG#2066 - For testing bad cache. See getRequiredLocalCache()\n\t//if ( key == 'current_company' ){ return null; }\n\tif ( LocalCacheData[key] ) {\n\t\treturn LocalCacheData[key];\n\t} else if ( LocalCacheData.isSupportHTML5LocalCache == true && sessionStorage[key] ) { //Fall back to sessionStorage if available and data exists.\n\t\tvar result = sessionStorage.getItem( key );\n\n\t\tif ( result !== 'undefined' && format === 'JSON' ) {\n\t\t\tresult = JSON.parse( result );\n\t\t}\n\n\t\tif ( result === 'true' ) {\n\t\t\tresult = true;\n\t\t} else if ( result === 'false' ) {\n\t\t\tresult = false;\n\t\t}\n\n\t\tLocalCacheData[key] = result;\n\n\t\treturn LocalCacheData[key];\n\t}\n\n\treturn null;\n};\n\nLocalCacheData.setLocalCache = function( key, val, format ) {\n\tif ( LocalCacheData.isSupportHTML5LocalCache ) {\n\t\tif ( format === 'JSON' ) {\n\t\t\tsessionStorage.setItem( key, JSON.stringify( val ) );\n\t\t} else {\n\t\t\tsessionStorage.setItem( key, val );\n\t\t}\n\t}\n\n\tLocalCacheData[key] = val; //Always set in memory as well.\n\n\treturn true;\n};\n\n/**\n * BUG#2066\n * JavaScript was reporting: TypeError: Cannot read property 'product_edition_id' of null\n *\n * This appears to be caused by a person closing the browser and reopening it with a \"return to where I was\" option active.\n * The browser is trying to load local cache data and it may be incomplete in this scenario, which generates the error. We could not reproduce this reliably.\n * To fix it, we created LocalCacheData.getRequiredLocalCache(), and called it for mission critical cache chunks instead of LocalCacheData.getLocalCache()\n */\nLocalCacheData.getRequiredLocalCache = function( key, format ) {\n\tvar result = LocalCacheData.getLocalCache( key, format );\n\tif ( result == null ) {\n\t\t//There are 2 cases where result can be null.\n\t\t// First is the cache going dead.\n\t\t// Second is that a required local cache item is not yet loaded because most of the required data isn't set yet.\n\t\t// In the second case we need to fail gracefully to show the error and stack trace on the console.\n\t\ttry {\n\t\t\t//If we aren't logged in, there isn't any required data to have, so ignore sending this error.\n\t\t\t// This can be triggered by setting browser to Fast 3G network speeds, logging in, then going to MyAccount->Logout as soon as possible while API requests are in-flight.\n\t\t\tif ( LocalCacheData.getSessionID() != '' ) {\n\t\t\t\tGlobal.sendErrorReport( 'ERROR: Unable to get required local cache data: ' + key ); //Send error as soon as possible, before any data gets cleared.\n\t\t\t}\n\t\t\tGlobal.Logout();\n\t\t\twindow.location.reload();\n\t\t} catch ( e ) {\n\t\t\t// Early page loads won't have Global or TAlertManager\n\t\t\tconsole.debug( 'ERROR: Unable to get required local cache data: ' + key );\n\t\t\tconsole.debug( 'ERROR: Unable to report error to server: ' + key );\n\t\t\tconsole.debug( e.stack );\n\t\t\tif ( confirm( 'Local cache has expired. Click OK to reload.' ) ) {\n\t\t\t\twindow.location.reload();\n\t\t\t}\n\t\t}\n\n\t\treturn;\n\t}\n\n\treturn result;\n};\n\nLocalCacheData.getI18nDic = function() {\n\treturn LocalCacheData.getLocalCache( 'i18nDic', 'JSON' );\n};\n\nLocalCacheData.setI18nDic = function( val ) {\n\tLocalCacheData.setLocalCache( 'i18nDic', val, 'JSON' );\n};\n\nLocalCacheData.getViewMinMap = function() {\n\treturn LocalCacheData.getLocalCache( 'viewMinMap', 'JSON' );\n};\n\nLocalCacheData.setViewMinMap = function( val ) {\n\tLocalCacheData.setLocalCache( 'viewMinMap', val, 'JSON' );\n};\n\nLocalCacheData.getCopyRightInfo = function() {\n\treturn LocalCacheData.getLocalCache( 'copyRightInfo' );\n};\n\nLocalCacheData.setCopyRightInfo = function( val ) {\n\tLocalCacheData.setLocalCache( 'copyRightInfo', val );\n};\n\nLocalCacheData.getApplicationName = function() {\n\t//return LocalCacheData.getRequiredLocalCache( 'applicationName' );\n\treturn LocalCacheData.getLoginData().application_name;\n};\n\n// LocalCacheData.setApplicationName = function( val ) {\n// \tLocalCacheData.setLocalCache( 'applicationName', val );\n// };\n\nLocalCacheData.getCurrentCompany = function() {\n\treturn LocalCacheData.getRequiredLocalCache( 'current_company', 'JSON' );\n};\n\nLocalCacheData.setCurrentCompany = function( val ) {\n\tLocalCacheData.setLocalCache( 'current_company', val, 'JSON' );\n};\n\nLocalCacheData.getLoginUser = function() {\n\t//Can't be set to required as the data is chekced for null to trigger cache load.\n\t//See loginViewController.onLoginSuccess()\n\treturn LocalCacheData.getLocalCache( 'loginUser', 'JSON' );\n};\n\nLocalCacheData.getPortalLoginUser = function() {\n\t//Can't be set to required as the data is chekced for null to trigger cache load.\n\t//See loginViewController.onLoginSuccess()\n\treturn LocalCacheData.getLocalCache( 'portalLoginUser', 'JSON' );\n};\n\nLocalCacheData.setLoginUser = function( val ) {\n\tLocalCacheData.setLocalCache( 'loginUser', val, 'JSON' );\n};\nLocalCacheData.setPunchLoginUser = function( val ) {\n\tLocalCacheData.setLocalCache( 'punchLoginUser', val, 'JSON' );\n};\n\nLocalCacheData.getPunchLoginUser = function() {\n\treturn LocalCacheData.getLocalCache( 'punchLoginUser', 'JSON' );\n};\n\nLocalCacheData.setPortalLoginUser = function( val ) {\n\tLocalCacheData.setLocalCache( 'portalLoginUser', val, 'JSON' );\n};\n\nLocalCacheData.setPortalLoginUser = function( val ) {\n\tLocalCacheData.setLocalCache( 'portalLoginUser', val, 'JSON' );\n};\n\nLocalCacheData.getCurrentCurrencySymbol = function() {\n\treturn LocalCacheData.getLocalCache( 'currentCurrencySymbol' );\n};\n\nLocalCacheData.setCurrentCurrencySymbol = function( val ) {\n\tLocalCacheData.setLocalCache( 'currentCurrencySymbol', val );\n};\n\nLocalCacheData.getLoginUserPreference = function() {\n\treturn LocalCacheData.getRequiredLocalCache( 'loginUserPreference', 'JSON' );\n};\n\nLocalCacheData.setLoginUserPreference = function( val ) {\n\tLocalCacheData.setLocalCache( 'loginUserPreference', val, 'JSON' );\n};\n\nLocalCacheData.getPermissionData = function() {\n\treturn LocalCacheData.getRequiredLocalCache( 'permissionData', 'JSON' );\n};\n\nLocalCacheData.setPermissionData = function( val ) {\n\tLocalCacheData.setLocalCache( 'permissionData', val, 'JSON' );\n};\n\nLocalCacheData.getUniqueCountryArray = function() {\n\treturn LocalCacheData.getRequiredLocalCache( 'uniqueCountryArray', 'JSON' );\n};\n\nLocalCacheData.setUniqueCountryArray = function( val ) {\n\tLocalCacheData.setLocalCache( 'uniqueCountryArray', val, 'JSON' );\n};\n\nLocalCacheData.getCustomFieldData = function() {\n\treturn LocalCacheData.getRequiredLocalCache( 'custom_field_data', 'JSON' );\n};\n\nLocalCacheData.setCustomFieldData = function( val ) {\n\tLocalCacheData.setLocalCache( 'custom_field_data', val, 'JSON' );\n};\n\nLocalCacheData.getSessionID = function() {\n\tvar result = LocalCacheData.getLocalCache( Global.getSessionIDKey() );\n\tif ( !result ) {\n\t\tresult = '';\n\t}\n\n\treturn result;\n};\n\nLocalCacheData.setSessionID = function( val ) {\n\tLocalCacheData.setLocalCache( Global.getSessionIDKey(), val );\n};\n\nLocalCacheData.getLoginData = function() {\n\treturn LocalCacheData.getRequiredLocalCache( 'loginData', 'JSON' );\n};\n\nLocalCacheData.setLoginData = function( val ) {\n\tLocalCacheData.setLocalCache( 'loginData', val, 'JSON' );\n};\n\nLocalCacheData.getCurrentSelectMenuId = function() {\n\treturn LocalCacheData.getLocalCache( 'currentSelectMenuId' );\n};\n\nLocalCacheData.setCurrentSelectMenuId = function( val ) {\n\tLocalCacheData.setLocalCache( 'currentSelectMenuId', val );\n};\n\nLocalCacheData.getCurrentSelectSubMenuId = function() {\n\treturn LocalCacheData.getLocalCache( 'currentSelectSubMenuId' );\n};\n\nLocalCacheData.setCurrentSelectSubMenuId = function( val ) {\n\tLocalCacheData.setLocalCache( 'currentSelectSubMenuId', val );\n};\n\nLocalCacheData.getAutoFillData = function() {\n\treturn LocalCacheData.getLocalCache( 'auto_fill_data', 'JSON' );\n};\n\nLocalCacheData.setAutoFillData = function( val ) {\n\tLocalCacheData.setLocalCache( 'auto_fill_data', val, 'JSON' );\n};\n\nLocalCacheData.setAllURLArgs = function( val ) {\n\tlet sanitized_val = {};\n\t// Only allow objects to be passed in, note that null is recognized as an object and we ignore it.\n\tif ( typeof val === 'object' && val !== null ) {\n\t\tfor ( var key in val ) {\n\t\t\tif ( val.hasOwnProperty( key ) && val[key] !== undefined ) {\n\t\t\t\t// Sanitize values to help prevent against XSS with htmlEncode plus some extra characters: ' \" :\n\t\t\t\tsanitized_val[key] = Global.htmlEncode( val[key] ).replace( /\"/g, '"' )\n\t\t\t\t\t.replace( /'/g, ''' )\n\t\t\t\t\t.replace( /:/g, ':' );\n\t\t\t}\n\t\t}\n\t}\n\tLocalCacheData.setLocalCache( 'all_url_args', sanitized_val, 'JSON' );\n};\n\nLocalCacheData.getAllURLArgs = function() {\n\treturn LocalCacheData.getLocalCache( 'all_url_args', 'JSON' );\n};\n\nLocalCacheData.cleanNecessaryCache = function() {\n\tDebug.Text( 'Clearing Cache', 'LocalCacheData.js', 'LocalCacheData', 'cleanNecessaryCache', 10 );\n\tLocalCacheData.last_timesheet_selected_user = null;\n\tLocalCacheData.last_timesheet_selected_date = null;\n\t//JS load Optimize\n\tif ( LocalCacheData.loadViewRequiredJSReady ) {\n\t\tif ( typeof ALayoutCache !== 'undefined' ) {\n\t\t\tALayoutCache.layout_dic = {};\n\t\t}\n\t}\n\tLocalCacheData.view_layout_cache = {};\n\tLocalCacheData.result_cache = {};\n\t//Close any open wizards.\n\tif ( LocalCacheData.current_open_wizard_controllers.length > 0 ) {\n for ( var i = 0; i < LocalCacheData.current_open_wizard_controllers.length; i++ ) {\n LocalCacheData.current_open_wizard_controllers[i].onCloseClick();\n }\n }\n\tLocalCacheData.current_open_wizard_controllers = [];\n\tGlobal.cleanViewTab();\n};\n\nLocalCacheData.getScrollbarWidth = function() {\n\treturn LocalCacheData.getLocalCache( 'scroll_bar_width' );\n};\n\nLocalCacheData.setScrollBarWidth = function( val ) {\n\tLocalCacheData.setLocalCache( 'scroll_bar_width', val );\n};\n\nLocalCacheData.getScrollbarHeight = function() {\n\treturn LocalCacheData.getLocalCache( 'scroll_bar_height' );\n};\n\nLocalCacheData.setScrollBarHeight = function( val ) {\n\tLocalCacheData.setLocalCache( 'scroll_bar_height', val );\n};\n\nLocalCacheData.getLastPunchTime = function() {\n\treturn LocalCacheData.getLocalCache( 'last_punch_time' );\n};\n\nLocalCacheData.setLastPunchTime = function( val ) {\n\tLocalCacheData.setLocalCache( 'last_punch_time', val );\n};\n\nLocalCacheData.getJobQueuePunchData = function() {\n\treturn LocalCacheData.getLocalCache( 'job_queue_punch_data', 'JSON' );\n};\n\nLocalCacheData.setJobQueuePunchData = function( val ) {\n\tLocalCacheData.setLocalCache( 'job_queue_punch_data', val, 'JSON' );\n};\n\nLocalCacheData.getFeatureFlagData = function() {\n\treturn LocalCacheData.getLocalCache( 'feature_flag_data', 'JSON' );\n};\n\nLocalCacheData.setFeatureFlagData = function( val ) {\n\tLocalCacheData.setLocalCache( 'feature_flag_data', val, 'JSON' );\n};\n\n//Check to see if local storage is actually available.\nLocalCacheData.isStorageAvailable();//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTU2My5qcyIsIm1hcHBpbmdzIjoiOzs7QUFBTzs7QUFFUDs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQSxxREFBcUQ7O0FBRXJEOztBQUVBOztBQUVBLCtEQUErRDs7QUFFL0QsMENBQTBDOztBQUUxQyx3Q0FBd0M7O0FBRXhDLGtDQUFrQzs7QUFFbEMsdURBQXVEOztBQUV2RCxtREFBbUQ7O0FBRW5ELHlEQUF5RDs7QUFFekQsc0RBQXNEOztBQUV0RCxrREFBa0Q7O0FBRWxELHlDQUF5Qzs7QUFFekM7O0FBRUE7O0FBRUE7O0FBRUEsa0NBQWtDOztBQUVsQzs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQSxzQ0FBc0M7O0FBRXRDLGtEQUFrRDs7QUFFbEQ7O0FBRUE7O0FBRUEsdUNBQXVDOztBQUV2Qzs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esb0NBQW9DO0FBQ3BDO0FBQ0E7QUFDQSxHQUFHLHFGQUFxRjtBQUN4Rjs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7O0FBRUEsNEJBQTRCOztBQUU1QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0ZBQXdGO0FBQ3hGO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2RUFBNkU7QUFDN0UsNEJBQTRCO0FBQzVCLDJCQUEyQjtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCLDJEQUEyRDtBQUNwRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9pbnRlcmZhY2UvaHRtbDUvZ2xvYmFsL0xvY2FsQ2FjaGVEYXRhLmpzPzJiOWMiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IHZhciBMb2NhbENhY2hlRGF0YSA9IGZ1bmN0aW9uKCkge1xuXG59O1xuXG5Mb2NhbENhY2hlRGF0YS52aWV3X2xheW91dF9jYWNoZSA9IHt9O1xuXG5Mb2NhbENhY2hlRGF0YS5pMThuRGljID0gbnVsbDtcblxuTG9jYWxDYWNoZURhdGEudWlfY2xpY2tfc3RhY2sgPSBbXTtcblxuTG9jYWxDYWNoZURhdGEuYXBpX3N0YWNrID0gW107XG5cbkxvY2FsQ2FjaGVEYXRhLmxhc3RfdGltZXNoZWV0X3NlbGVjdGVkX2RhdGUgPSBudWxsO1xuXG5Mb2NhbENhY2hlRGF0YS5sYXN0X3RpbWVzaGVldF9zZWxlY3RlZF91c2VyID0gbnVsbDtcblxuTG9jYWxDYWNoZURhdGEubGFzdF9zY2hlZHVsZV9zZWxlY3RlZF9kYXRlID0gbnVsbDtcblxuTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3dpemFyZF9jb250cm9sbGVycyA9IFtdOyAvL011bHRpcGxlIHdpemFyZHMgY2FuIGJlIG9wZW4gYXQgb25jZSBzdWNoIGFzIHRheCB3aXphcmQgYW5kIHJlcG9ydCB3aXphcmRcblxuTG9jYWxDYWNoZURhdGEuZGVmYXVsdF9maWx0ZXJfZm9yX25leHRfb3Blbl92aWV3ID0gbnVsbDtcblxuTG9jYWxDYWNoZURhdGEuZXh0cmFfZmlsdGVyX2Zvcl9uZXh0X29wZW5fdmlldyA9IG51bGw7XG5cbkxvY2FsQ2FjaGVEYXRhLmRlZmF1bHRfZWRpdF9pZF9mb3JfbmV4dF9vcGVuX2VkaXRfdmlldyA9IG51bGw7IC8vRmlyc3QgdXNlIGluIHNhdmUgcmVwb3J0IGp1bXAgdG8gcmVwb3J0XG5cbkxvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl92aWV3X2lkID0gJyc7IC8vIFNhdmUgY3VycmVudCBvcGVuIHZpZXcncyBpZC4gc2V0IGluIEJhc2VWaWV3Q29udHJvbGxlci5sb2FkVmlld1xuXG5Mb2NhbENhY2hlRGF0YS5sb2dpbl9lcnJvcl9zdHJpbmcgPSAnJzsgLy9FcnJvciBtZXNzYWdlIHNob3cgb24gTG9naW4gU2NyZWVuXG5cbkxvY2FsQ2FjaGVEYXRhLmFsbF91cmxfYXJncyA9IHt9OyAvL0FsbCBhcmdzIGZyb20gVVJMXG5cbkxvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIgPSBudWxsOyAvLyBTYXZlIGN1cnJlbnQgb3BlbiB2aWV3J3MgaWQuIHNldCBpbiBCYXNlVmlld0NvbnRyb2xsZXIubG9hZFZpZXdcblxuTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3N1Yl9jb250cm9sbGVyID0gbnVsbDsgLy8gU2F2ZSBjdXJyZW50IG9wZW4gdmlldydzIGlkLiBzZXQgaW4gQmFzZVZpZXdDb250cm9sbGVyLmxvYWRWaWV3XG5cbkxvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9lZGl0X29ubHlfY29udHJvbGxlciA9IG51bGw7IC8vIFNhdmUgY3VycmVudCBvcGVuIHZpZXcncyBpZC4gc2V0IGluIEJhc2VWaWV3Q29udHJvbGxlci5sb2FkVmlld1xuXG5Mb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcmVwb3J0X2NvbnRyb2xsZXIgPSBudWxsOyAvL3NhdmUgb3BlbiByZXBvcnQgdmlldyBjb250cm9sbGVyXG5cbkxvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfZG9pbmdfY29udGV4dF9hY3Rpb24gPSAnJzsgLy9TYXZlIHdoYXQgY29udGV4dCBhY3Rpb24gaXMgZG9pbmcgcmlnaHQgbm93XG5cbkxvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfc2VsZWN0X2RhdGUgPSAnJzsgLy8gU2F2ZVxuXG5Mb2NhbENhY2hlRGF0YS5lZGl0X2lkX2Zvcl9uZXh0X29wZW5fdmlldyA9ICcnO1xuXG5Mb2NhbENhY2hlRGF0YS51cmxfYXJncyA9IG51bGw7XG5cbkxvY2FsQ2FjaGVEYXRhLnJlc3VsdF9jYWNoZSA9IHt9O1xuXG5Mb2NhbENhY2hlRGF0YS5wYWdpbmdfdHlwZSA9IDEwOyAgLy8wIGlzIENMaWNrIHRvIHNob3cgbW9yZSwgMTAgaXMgbm9ybWFsIHBhZ2luZ1xuXG5Mb2NhbENhY2hlRGF0YS5jdXJyZW50U2hvd25Db250ZXh0TWVudU5hbWUgPSAnJztcblxuTG9jYWxDYWNoZURhdGEuaXNTdXBwb3J0SFRNTDVMb2NhbENhY2hlID0gZmFsc2U7XG5cbkxvY2FsQ2FjaGVEYXRhLmxvZ2luRGF0YSA9IG51bGw7XG5cbkxvY2FsQ2FjaGVEYXRhLmN1cnJlbnRMYW5ndWFnZSA9ICdlbl91cyc7XG5cbkxvY2FsQ2FjaGVEYXRhLmN1cnJlbnRMYW5ndWFnZURpYyA9IHt9O1xuXG5Mb2NhbENhY2hlRGF0YS5kZXBsb3ltZW50X29uX2RlbWFuZCA9IG51bGw7XG5cbkxvY2FsQ2FjaGVEYXRhLnByb2R1Y3RFZGl0aW9uSWQgPSBudWxsO1xuXG5Mb2NhbENhY2hlRGF0YS5hcHBsaWNhdGlvbk5hbWUgPSBudWxsO1xuXG5Mb2NhbENhY2hlRGF0YS5sb2dpblVzZXIgPSBudWxsO1xuXG5Mb2NhbENhY2hlRGF0YS5sb2dpblVzZXJQcmVmZXJlbmNlID0gbnVsbDtcblxuTG9jYWxDYWNoZURhdGEub3BlbkF3ZXNvbWVCb3ggPSBudWxsOyAvL1RvIGhlbHAgbWFrZSBzdXJlIG9ubHkgb25lIEF3ZXNvbWVib3ggaXMgc2hvd24gYXQgb25lIHRpbWUuIERvIG1vdXNlIGNsaWNrIG91dHNpZGUgam9iXG5cbkxvY2FsQ2FjaGVEYXRhLm9wZW5Bd2Vzb21lQm94Q29sdW1uRWRpdG9yID0gbnVsbDsgLy9UbyBNYWtlIHN1cmUgb25seSBvbmUgY29sdW1uIGVkaXRvciBvZiBBd2Vzb21lYm94IGlzIHNob3duIGF0IG9uZSB0aW1lIERvIG1vdXNlIGNsaWNrIG91dHNpZGUgam9iXG5cbkxvY2FsQ2FjaGVEYXRhLm9wZW5SaWJib25OYXZpTWVudSA9IG51bGw7XG5cbkxvY2FsQ2FjaGVEYXRhLmxvYWRlZFdpZGdldENhY2hlID0ge307XG5cbkxvY2FsQ2FjaGVEYXRhLmxvYWRlZFNjcmlwdE5hbWVzID0ge307IC8vU2F2ZSBsb2FkIGphdmFzY3JpcHQsIHByZXZlbnQgbXVsdGlwbGUgbG9hZFxuXG5Mb2NhbENhY2hlRGF0YS5wZXJtaXNzaW9uRGF0YSA9IG51bGw7XG5cbkxvY2FsQ2FjaGVEYXRhLnVuaXF1ZUNvdW50cnlBcnJheSA9IG51bGw7XG5cbkxvY2FsQ2FjaGVEYXRhLmN1c3RvbV9maWVsZF9kYXRhID0gW107XG5cbkxvY2FsQ2FjaGVEYXRhLmN1cnJlbnRTZWxlY3RNZW51SWQgPSBudWxsO1xuXG5Mb2NhbENhY2hlRGF0YS5jdXJyZW50U2VsZWN0U3ViTWVudUlkID0gbnVsbDtcblxuTG9jYWxDYWNoZURhdGEudGltZXNoZWV0X3N1Yl9ncmlkX2V4cGVuZGVkX2RpYyA9IHt9O1xuXG5Mb2NhbENhY2hlRGF0YS52aWV3X21pbl9tYXAgPSB7fTtcblxuTG9jYWxDYWNoZURhdGEudmlld19taW5fdGFiX2JhciA9IG51bGw7XG5cbkxvY2FsQ2FjaGVEYXRhLmNvb2tpZV9wYXRoID0gQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLmNvb2tpZV9iYXNlX3VybDtcblxuTG9jYWxDYWNoZURhdGEuZG9tYWluX25hbWUgPSAnJztcblxuTG9jYWxDYWNoZURhdGEuZnVsbFVybFBhcmFtZXRlclN0ciA9ICcnO1xuXG5Mb2NhbENhY2hlRGF0YS5QYXlyb2xsUmVtaXR0YW5jZUFnZW5jeUV2ZW50V2l6YXJkQ29udHJvbGxlciA9IG51bGw7XG5cbkxvY2FsQ2FjaGVEYXRhLnJlc2l6ZWFibGVfZ3JpZHMgPSBbXTtcblxuTG9jYWxDYWNoZURhdGEuYXV0b19maWxsX2RhdGEgPSBudWxsO1xuXG5Mb2NhbENhY2hlRGF0YS5zY3JvbGxfYmFyX3dpZHRoID0gMDtcbkxvY2FsQ2FjaGVEYXRhLnNjcm9sbF9iYXJfaGVpZ2h0ID0gMDtcblxuTG9jYWxDYWNoZURhdGEubGFzdF9wdW5jaF90aW1lID0gbnVsbDtcbkxvY2FsQ2FjaGVEYXRhLmpvYl9xdWV1ZV9wdW5jaF9kYXRhID0gbnVsbDtcblxuTG9jYWxDYWNoZURhdGEuZmVhdHVyZV9mbGFnX2RhdGEgPSB7fTtcblxuTG9jYWxDYWNoZURhdGEuaXNTdG9yYWdlQXZhaWxhYmxlID0gZnVuY3Rpb24oKSB7XG5cdC8vVHVybiBvZmYgc2Vzc2lvblN0b3JhZ2UgYXMgaXRzIG5vdCByZXF1aXJlZCBhbmQganVzdCBzbG93cyB0aGluZ3MgZG93biBhbnl3YXlzLiBXZSBjYW4gc3RvcmUgdGhpbmdzIGluIG1lbW9yeSBpbnN0ZWFkLlxuXHQvLyBJdCBhbHNvIGhhcyBzcGFjZSBsaW1pdGF0aW9ucyB3aGljaCBjYW4gYmUgaGl0IGxpa2U6IFF1b3RhRXhjZWVkZWRFcnJvcjogRE9NIEV4Y2VwdGlvbiAyMjogQW4gYXR0ZW1wdCB3YXMgbWFkZSB0byBhZGQgc29tZXRoaW5nIHRvIHN0b3JhZ2UgdGhhdCBleGNlZWRlZCB0aGUgcXVvdGFcblx0TG9jYWxDYWNoZURhdGEuaXNTdXBwb3J0SFRNTDVMb2NhbENhY2hlID0gZmFsc2U7XG5cblx0Ly8gaWYgKCB3aW5kb3cuc2Vzc2lvblN0b3JhZ2UgKSB7XG5cdC8vIFx0dHJ5IHtcblx0Ly8gXHRcdC8vVGVzdCB0byBtYWtlIHN1cmUgd2UgY2FuIGFjdHVhbGx5IHN0b3JlIHNvbWUgZGF0YS4gVGhpcyBzaG91bGQgaGVscCBhdm9pZCBKUyBleGNlcHRpb25zIHN1Y2ggYXM6IFF1b3RhRXhjZWVkZWRFcnJvcjogRE9NIEV4Y2VwdGlvbiAyMjogQW4gYXR0ZW1wdCB3YXMgbWFkZSB0byBhZGQgc29tZXRoaW5nIHRvIHN0b3JhZ2UgdGhhdCBleGNlZWRlZCB0aGUgcXVvdGFcblx0Ly8gXHRcdHZhciBzdG9yYWdlID0gd2luZG93WydzZXNzaW9uU3RvcmFnZSddO1xuXHQvLyBcdFx0dmFyIHggPSAnX19zdG9yYWdlX3Rlc3RfXyc7XG5cdC8vIFx0XHRzdG9yYWdlLnNldEl0ZW0oeCwgeCk7XG5cdC8vIFx0XHRzdG9yYWdlLnJlbW92ZUl0ZW0oeCk7XG5cdC8vXG5cdC8vIFx0XHRMb2NhbENhY2hlRGF0YS5pc1N1cHBvcnRIVE1MNUxvY2FsQ2FjaGUgPSB0cnVlO1xuXHQvLyBcdH0gY2F0Y2goZSkge1xuXHQvLyBcdFx0TG9jYWxDYWNoZURhdGEuaXNTdXBwb3J0SFRNTDVMb2NhbENhY2hlID0gZmFsc2U7XG5cdC8vIFx0fVxuXHQvLyB9IGVsc2Uge1xuXHQvLyBcdExvY2FsQ2FjaGVEYXRhLmlzU3VwcG9ydEhUTUw1TG9jYWxDYWNoZSA9IGZhbHNlO1xuXHQvLyB9XG5cdC8vRGVidWcuVGV4dCggJ0lzIHNlc3Npb25TdG9yYWdlIGF2YWlsYWJsZTogJysgTG9jYWxDYWNoZURhdGEuaXNTdXBwb3J0SFRNTDVMb2NhbENhY2hlLCAnTG9jYWxDYWNoZURhdGEuanMnLCAnTG9jYWxDYWNoZURhdGEnLCAnaXNTdG9yYWdlQXZhaWxhYmxlJywgMTAgKTtcblxuXHRyZXR1cm4gTG9jYWxDYWNoZURhdGEuaXNTdXBwb3J0SFRNTDVMb2NhbENhY2hlO1xufTtcblxuTG9jYWxDYWNoZURhdGEuaXNMb2NhbENhY2hlRXhpc3RzID0gZnVuY3Rpb24oIGtleSApIHtcblx0aWYgKCBMb2NhbENhY2hlRGF0YS5nZXRMb2NhbENhY2hlKCBrZXkgKSAhPT0gbnVsbCApIHtcblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXG5cdHJldHVybiBmYWxzZTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLmdldExvY2FsQ2FjaGUgPSBmdW5jdGlvbigga2V5LCBmb3JtYXQgKSB7XG5cdC8vQlVHIzIwNjYgLSBGb3IgdGVzdGluZyBiYWQgY2FjaGUuIFNlZSBnZXRSZXF1aXJlZExvY2FsQ2FjaGUoKVxuXHQvL2lmICgga2V5ID09ICdjdXJyZW50X2NvbXBhbnknICl7IHJldHVybiBudWxsOyB9XG5cdGlmICggTG9jYWxDYWNoZURhdGFba2V5XSApIHtcblx0XHRyZXR1cm4gTG9jYWxDYWNoZURhdGFba2V5XTtcblx0fSBlbHNlIGlmICggTG9jYWxDYWNoZURhdGEuaXNTdXBwb3J0SFRNTDVMb2NhbENhY2hlID09IHRydWUgJiYgc2Vzc2lvblN0b3JhZ2Vba2V5XSApIHsgLy9GYWxsIGJhY2sgdG8gc2Vzc2lvblN0b3JhZ2UgaWYgYXZhaWxhYmxlIGFuZCBkYXRhIGV4aXN0cy5cblx0XHR2YXIgcmVzdWx0ID0gc2Vzc2lvblN0b3JhZ2UuZ2V0SXRlbSgga2V5ICk7XG5cblx0XHRpZiAoIHJlc3VsdCAhPT0gJ3VuZGVmaW5lZCcgJiYgZm9ybWF0ID09PSAnSlNPTicgKSB7XG5cdFx0XHRyZXN1bHQgPSBKU09OLnBhcnNlKCByZXN1bHQgKTtcblx0XHR9XG5cblx0XHRpZiAoIHJlc3VsdCA9PT0gJ3RydWUnICkge1xuXHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHR9IGVsc2UgaWYgKCByZXN1bHQgPT09ICdmYWxzZScgKSB7XG5cdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHR9XG5cblx0XHRMb2NhbENhY2hlRGF0YVtrZXldID0gcmVzdWx0O1xuXG5cdFx0cmV0dXJuIExvY2FsQ2FjaGVEYXRhW2tleV07XG5cdH1cblxuXHRyZXR1cm4gbnVsbDtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLnNldExvY2FsQ2FjaGUgPSBmdW5jdGlvbigga2V5LCB2YWwsIGZvcm1hdCApIHtcblx0aWYgKCBMb2NhbENhY2hlRGF0YS5pc1N1cHBvcnRIVE1MNUxvY2FsQ2FjaGUgKSB7XG5cdFx0aWYgKCBmb3JtYXQgPT09ICdKU09OJyApIHtcblx0XHRcdHNlc3Npb25TdG9yYWdlLnNldEl0ZW0oIGtleSwgSlNPTi5zdHJpbmdpZnkoIHZhbCApICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHNlc3Npb25TdG9yYWdlLnNldEl0ZW0oIGtleSwgdmFsICk7XG5cdFx0fVxuXHR9XG5cblx0TG9jYWxDYWNoZURhdGFba2V5XSA9IHZhbDsgLy9BbHdheXMgc2V0IGluIG1lbW9yeSBhcyB3ZWxsLlxuXG5cdHJldHVybiB0cnVlO1xufTtcblxuLyoqXG4gKiBCVUcjMjA2NlxuICogSmF2YVNjcmlwdCB3YXMgcmVwb3J0aW5nOiBUeXBlRXJyb3I6IENhbm5vdCByZWFkIHByb3BlcnR5ICdwcm9kdWN0X2VkaXRpb25faWQnIG9mIG51bGxcbiAqXG4gKiBUaGlzIGFwcGVhcnMgdG8gYmUgY2F1c2VkIGJ5IGEgcGVyc29uIGNsb3NpbmcgdGhlIGJyb3dzZXIgYW5kIHJlb3BlbmluZyBpdCB3aXRoIGEgXCJyZXR1cm4gdG8gd2hlcmUgSSB3YXNcIiBvcHRpb24gYWN0aXZlLlxuICogVGhlIGJyb3dzZXIgaXMgdHJ5aW5nIHRvIGxvYWQgbG9jYWwgY2FjaGUgZGF0YSBhbmQgaXQgbWF5IGJlIGluY29tcGxldGUgaW4gdGhpcyBzY2VuYXJpbywgd2hpY2ggZ2VuZXJhdGVzIHRoZSBlcnJvci4gV2UgY291bGQgbm90IHJlcHJvZHVjZSB0aGlzIHJlbGlhYmx5LlxuICogVG8gZml4IGl0LCB3ZSBjcmVhdGVkIExvY2FsQ2FjaGVEYXRhLmdldFJlcXVpcmVkTG9jYWxDYWNoZSgpLCBhbmQgY2FsbGVkIGl0IGZvciBtaXNzaW9uIGNyaXRpY2FsIGNhY2hlIGNodW5rcyBpbnN0ZWFkIG9mIExvY2FsQ2FjaGVEYXRhLmdldExvY2FsQ2FjaGUoKVxuICovXG5Mb2NhbENhY2hlRGF0YS5nZXRSZXF1aXJlZExvY2FsQ2FjaGUgPSBmdW5jdGlvbigga2V5LCBmb3JtYXQgKSB7XG5cdHZhciByZXN1bHQgPSBMb2NhbENhY2hlRGF0YS5nZXRMb2NhbENhY2hlKCBrZXksIGZvcm1hdCApO1xuXHRpZiAoIHJlc3VsdCA9PSBudWxsICkge1xuXHRcdC8vVGhlcmUgYXJlIDIgY2FzZXMgd2hlcmUgcmVzdWx0IGNhbiBiZSBudWxsLlxuXHRcdC8vICBGaXJzdCBpcyB0aGUgY2FjaGUgZ29pbmcgZGVhZC5cblx0XHQvLyAgU2Vjb25kIGlzIHRoYXQgYSByZXF1aXJlZCBsb2NhbCBjYWNoZSBpdGVtIGlzIG5vdCB5ZXQgbG9hZGVkIGJlY2F1c2UgbW9zdCBvZiB0aGUgcmVxdWlyZWQgZGF0YSBpc24ndCBzZXQgeWV0LlxuXHRcdC8vICBJbiB0aGUgc2Vjb25kIGNhc2Ugd2UgbmVlZCB0byBmYWlsIGdyYWNlZnVsbHkgdG8gc2hvdyB0aGUgZXJyb3IgYW5kIHN0YWNrIHRyYWNlIG9uIHRoZSBjb25zb2xlLlxuXHRcdHRyeSB7XG5cdFx0XHQvL0lmIHdlIGFyZW4ndCBsb2dnZWQgaW4sIHRoZXJlIGlzbid0IGFueSByZXF1aXJlZCBkYXRhIHRvIGhhdmUsIHNvIGlnbm9yZSBzZW5kaW5nIHRoaXMgZXJyb3IuXG5cdFx0XHQvLyAgVGhpcyBjYW4gYmUgdHJpZ2dlcmVkIGJ5IHNldHRpbmcgYnJvd3NlciB0byBGYXN0IDNHIG5ldHdvcmsgc3BlZWRzLCBsb2dnaW5nIGluLCB0aGVuIGdvaW5nIHRvIE15QWNjb3VudC0+TG9nb3V0IGFzIHNvb24gYXMgcG9zc2libGUgd2hpbGUgQVBJIHJlcXVlc3RzIGFyZSBpbi1mbGlnaHQuXG5cdFx0XHRpZiAoIExvY2FsQ2FjaGVEYXRhLmdldFNlc3Npb25JRCgpICE9ICcnICkge1xuXHRcdFx0XHRHbG9iYWwuc2VuZEVycm9yUmVwb3J0KCAnRVJST1I6IFVuYWJsZSB0byBnZXQgcmVxdWlyZWQgbG9jYWwgY2FjaGUgZGF0YTogJyArIGtleSApOyAvL1NlbmQgZXJyb3IgYXMgc29vbiBhcyBwb3NzaWJsZSwgYmVmb3JlIGFueSBkYXRhIGdldHMgY2xlYXJlZC5cblx0XHRcdH1cblx0XHRcdEdsb2JhbC5Mb2dvdXQoKTtcblx0XHRcdHdpbmRvdy5sb2NhdGlvbi5yZWxvYWQoKTtcblx0XHR9IGNhdGNoICggZSApIHtcblx0XHRcdC8vIEVhcmx5IHBhZ2UgbG9hZHMgd29uJ3QgaGF2ZSBHbG9iYWwgb3IgVEFsZXJ0TWFuYWdlclxuXHRcdFx0Y29uc29sZS5kZWJ1ZyggJ0VSUk9SOiBVbmFibGUgdG8gZ2V0IHJlcXVpcmVkIGxvY2FsIGNhY2hlIGRhdGE6ICcgKyBrZXkgKTtcblx0XHRcdGNvbnNvbGUuZGVidWcoICdFUlJPUjogVW5hYmxlIHRvIHJlcG9ydCBlcnJvciB0byBzZXJ2ZXI6ICcgKyBrZXkgKTtcblx0XHRcdGNvbnNvbGUuZGVidWcoIGUuc3RhY2sgKTtcblx0XHRcdGlmICggY29uZmlybSggJ0xvY2FsIGNhY2hlIGhhcyBleHBpcmVkLiBDbGljayBPSyB0byByZWxvYWQuJyApICkge1xuXHRcdFx0XHR3aW5kb3cubG9jYXRpb24ucmVsb2FkKCk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0cmV0dXJuIHJlc3VsdDtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLmdldEkxOG5EaWMgPSBmdW5jdGlvbigpIHtcblx0cmV0dXJuIExvY2FsQ2FjaGVEYXRhLmdldExvY2FsQ2FjaGUoICdpMThuRGljJywgJ0pTT04nICk7XG59O1xuXG5Mb2NhbENhY2hlRGF0YS5zZXRJMThuRGljID0gZnVuY3Rpb24oIHZhbCApIHtcblx0TG9jYWxDYWNoZURhdGEuc2V0TG9jYWxDYWNoZSggJ2kxOG5EaWMnLCB2YWwsICdKU09OJyApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuZ2V0Vmlld01pbk1hcCA9IGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gTG9jYWxDYWNoZURhdGEuZ2V0TG9jYWxDYWNoZSggJ3ZpZXdNaW5NYXAnLCAnSlNPTicgKTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLnNldFZpZXdNaW5NYXAgPSBmdW5jdGlvbiggdmFsICkge1xuXHRMb2NhbENhY2hlRGF0YS5zZXRMb2NhbENhY2hlKCAndmlld01pbk1hcCcsIHZhbCwgJ0pTT04nICk7XG59O1xuXG5Mb2NhbENhY2hlRGF0YS5nZXRDb3B5UmlnaHRJbmZvID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiBMb2NhbENhY2hlRGF0YS5nZXRMb2NhbENhY2hlKCAnY29weVJpZ2h0SW5mbycgKTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLnNldENvcHlSaWdodEluZm8gPSBmdW5jdGlvbiggdmFsICkge1xuXHRMb2NhbENhY2hlRGF0YS5zZXRMb2NhbENhY2hlKCAnY29weVJpZ2h0SW5mbycsIHZhbCApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuZ2V0QXBwbGljYXRpb25OYW1lID0gZnVuY3Rpb24oKSB7XG5cdC8vcmV0dXJuIExvY2FsQ2FjaGVEYXRhLmdldFJlcXVpcmVkTG9jYWxDYWNoZSggJ2FwcGxpY2F0aW9uTmFtZScgKTtcblx0cmV0dXJuIExvY2FsQ2FjaGVEYXRhLmdldExvZ2luRGF0YSgpLmFwcGxpY2F0aW9uX25hbWU7XG59O1xuXG4vLyBMb2NhbENhY2hlRGF0YS5zZXRBcHBsaWNhdGlvbk5hbWUgPSBmdW5jdGlvbiggdmFsICkge1xuLy8gXHRMb2NhbENhY2hlRGF0YS5zZXRMb2NhbENhY2hlKCAnYXBwbGljYXRpb25OYW1lJywgdmFsICk7XG4vLyB9O1xuXG5Mb2NhbENhY2hlRGF0YS5nZXRDdXJyZW50Q29tcGFueSA9IGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gTG9jYWxDYWNoZURhdGEuZ2V0UmVxdWlyZWRMb2NhbENhY2hlKCAnY3VycmVudF9jb21wYW55JywgJ0pTT04nICk7XG59O1xuXG5Mb2NhbENhY2hlRGF0YS5zZXRDdXJyZW50Q29tcGFueSA9IGZ1bmN0aW9uKCB2YWwgKSB7XG5cdExvY2FsQ2FjaGVEYXRhLnNldExvY2FsQ2FjaGUoICdjdXJyZW50X2NvbXBhbnknLCB2YWwsICdKU09OJyApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuZ2V0TG9naW5Vc2VyID0gZnVuY3Rpb24oKSB7XG5cdC8vQ2FuJ3QgYmUgc2V0IHRvIHJlcXVpcmVkIGFzIHRoZSBkYXRhIGlzIGNoZWtjZWQgZm9yIG51bGwgdG8gdHJpZ2dlciBjYWNoZSBsb2FkLlxuXHQvL1NlZSBsb2dpblZpZXdDb250cm9sbGVyLm9uTG9naW5TdWNjZXNzKClcblx0cmV0dXJuIExvY2FsQ2FjaGVEYXRhLmdldExvY2FsQ2FjaGUoICdsb2dpblVzZXInLCAnSlNPTicgKTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLmdldFBvcnRhbExvZ2luVXNlciA9IGZ1bmN0aW9uKCkge1xuXHQvL0Nhbid0IGJlIHNldCB0byByZXF1aXJlZCBhcyB0aGUgZGF0YSBpcyBjaGVrY2VkIGZvciBudWxsIHRvIHRyaWdnZXIgY2FjaGUgbG9hZC5cblx0Ly9TZWUgbG9naW5WaWV3Q29udHJvbGxlci5vbkxvZ2luU3VjY2VzcygpXG5cdHJldHVybiBMb2NhbENhY2hlRGF0YS5nZXRMb2NhbENhY2hlKCAncG9ydGFsTG9naW5Vc2VyJywgJ0pTT04nICk7XG59O1xuXG5Mb2NhbENhY2hlRGF0YS5zZXRMb2dpblVzZXIgPSBmdW5jdGlvbiggdmFsICkge1xuXHRMb2NhbENhY2hlRGF0YS5zZXRMb2NhbENhY2hlKCAnbG9naW5Vc2VyJywgdmFsLCAnSlNPTicgKTtcbn07XG5Mb2NhbENhY2hlRGF0YS5zZXRQdW5jaExvZ2luVXNlciA9IGZ1bmN0aW9uKCB2YWwgKSB7XG5cdExvY2FsQ2FjaGVEYXRhLnNldExvY2FsQ2FjaGUoICdwdW5jaExvZ2luVXNlcicsIHZhbCwgJ0pTT04nICk7XG59O1xuXG5Mb2NhbENhY2hlRGF0YS5nZXRQdW5jaExvZ2luVXNlciA9IGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gTG9jYWxDYWNoZURhdGEuZ2V0TG9jYWxDYWNoZSggJ3B1bmNoTG9naW5Vc2VyJywgJ0pTT04nICk7XG59O1xuXG5Mb2NhbENhY2hlRGF0YS5zZXRQb3J0YWxMb2dpblVzZXIgPSBmdW5jdGlvbiggdmFsICkge1xuXHRMb2NhbENhY2hlRGF0YS5zZXRMb2NhbENhY2hlKCAncG9ydGFsTG9naW5Vc2VyJywgdmFsLCAnSlNPTicgKTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLnNldFBvcnRhbExvZ2luVXNlciA9IGZ1bmN0aW9uKCB2YWwgKSB7XG5cdExvY2FsQ2FjaGVEYXRhLnNldExvY2FsQ2FjaGUoICdwb3J0YWxMb2dpblVzZXInLCB2YWwsICdKU09OJyApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuZ2V0Q3VycmVudEN1cnJlbmN5U3ltYm9sID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiBMb2NhbENhY2hlRGF0YS5nZXRMb2NhbENhY2hlKCAnY3VycmVudEN1cnJlbmN5U3ltYm9sJyApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuc2V0Q3VycmVudEN1cnJlbmN5U3ltYm9sID0gZnVuY3Rpb24oIHZhbCApIHtcblx0TG9jYWxDYWNoZURhdGEuc2V0TG9jYWxDYWNoZSggJ2N1cnJlbnRDdXJyZW5jeVN5bWJvbCcsIHZhbCApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuZ2V0TG9naW5Vc2VyUHJlZmVyZW5jZSA9IGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gTG9jYWxDYWNoZURhdGEuZ2V0UmVxdWlyZWRMb2NhbENhY2hlKCAnbG9naW5Vc2VyUHJlZmVyZW5jZScsICdKU09OJyApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuc2V0TG9naW5Vc2VyUHJlZmVyZW5jZSA9IGZ1bmN0aW9uKCB2YWwgKSB7XG5cdExvY2FsQ2FjaGVEYXRhLnNldExvY2FsQ2FjaGUoICdsb2dpblVzZXJQcmVmZXJlbmNlJywgdmFsLCAnSlNPTicgKTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLmdldFBlcm1pc3Npb25EYXRhID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiBMb2NhbENhY2hlRGF0YS5nZXRSZXF1aXJlZExvY2FsQ2FjaGUoICdwZXJtaXNzaW9uRGF0YScsICdKU09OJyApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuc2V0UGVybWlzc2lvbkRhdGEgPSBmdW5jdGlvbiggdmFsICkge1xuXHRMb2NhbENhY2hlRGF0YS5zZXRMb2NhbENhY2hlKCAncGVybWlzc2lvbkRhdGEnLCB2YWwsICdKU09OJyApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuZ2V0VW5pcXVlQ291bnRyeUFycmF5ID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiBMb2NhbENhY2hlRGF0YS5nZXRSZXF1aXJlZExvY2FsQ2FjaGUoICd1bmlxdWVDb3VudHJ5QXJyYXknLCAnSlNPTicgKTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLnNldFVuaXF1ZUNvdW50cnlBcnJheSA9IGZ1bmN0aW9uKCB2YWwgKSB7XG5cdExvY2FsQ2FjaGVEYXRhLnNldExvY2FsQ2FjaGUoICd1bmlxdWVDb3VudHJ5QXJyYXknLCB2YWwsICdKU09OJyApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuZ2V0Q3VzdG9tRmllbGREYXRhID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiBMb2NhbENhY2hlRGF0YS5nZXRSZXF1aXJlZExvY2FsQ2FjaGUoICdjdXN0b21fZmllbGRfZGF0YScsICdKU09OJyApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuc2V0Q3VzdG9tRmllbGREYXRhID0gZnVuY3Rpb24oIHZhbCApIHtcblx0TG9jYWxDYWNoZURhdGEuc2V0TG9jYWxDYWNoZSggJ2N1c3RvbV9maWVsZF9kYXRhJywgdmFsLCAnSlNPTicgKTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLmdldFNlc3Npb25JRCA9IGZ1bmN0aW9uKCkge1xuXHR2YXIgcmVzdWx0ID0gTG9jYWxDYWNoZURhdGEuZ2V0TG9jYWxDYWNoZSggR2xvYmFsLmdldFNlc3Npb25JREtleSgpICk7XG5cdGlmICggIXJlc3VsdCApIHtcblx0XHRyZXN1bHQgPSAnJztcblx0fVxuXG5cdHJldHVybiByZXN1bHQ7XG59O1xuXG5Mb2NhbENhY2hlRGF0YS5zZXRTZXNzaW9uSUQgPSBmdW5jdGlvbiggdmFsICkge1xuXHRMb2NhbENhY2hlRGF0YS5zZXRMb2NhbENhY2hlKCBHbG9iYWwuZ2V0U2Vzc2lvbklES2V5KCksIHZhbCApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuZ2V0TG9naW5EYXRhID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiBMb2NhbENhY2hlRGF0YS5nZXRSZXF1aXJlZExvY2FsQ2FjaGUoICdsb2dpbkRhdGEnLCAnSlNPTicgKTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLnNldExvZ2luRGF0YSA9IGZ1bmN0aW9uKCB2YWwgKSB7XG5cdExvY2FsQ2FjaGVEYXRhLnNldExvY2FsQ2FjaGUoICdsb2dpbkRhdGEnLCB2YWwsICdKU09OJyApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuZ2V0Q3VycmVudFNlbGVjdE1lbnVJZCA9IGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gTG9jYWxDYWNoZURhdGEuZ2V0TG9jYWxDYWNoZSggJ2N1cnJlbnRTZWxlY3RNZW51SWQnICk7XG59O1xuXG5Mb2NhbENhY2hlRGF0YS5zZXRDdXJyZW50U2VsZWN0TWVudUlkID0gZnVuY3Rpb24oIHZhbCApIHtcblx0TG9jYWxDYWNoZURhdGEuc2V0TG9jYWxDYWNoZSggJ2N1cnJlbnRTZWxlY3RNZW51SWQnLCB2YWwgKTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLmdldEN1cnJlbnRTZWxlY3RTdWJNZW51SWQgPSBmdW5jdGlvbigpIHtcblx0cmV0dXJuIExvY2FsQ2FjaGVEYXRhLmdldExvY2FsQ2FjaGUoICdjdXJyZW50U2VsZWN0U3ViTWVudUlkJyApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuc2V0Q3VycmVudFNlbGVjdFN1Yk1lbnVJZCA9IGZ1bmN0aW9uKCB2YWwgKSB7XG5cdExvY2FsQ2FjaGVEYXRhLnNldExvY2FsQ2FjaGUoICdjdXJyZW50U2VsZWN0U3ViTWVudUlkJywgdmFsICk7XG59O1xuXG5Mb2NhbENhY2hlRGF0YS5nZXRBdXRvRmlsbERhdGEgPSBmdW5jdGlvbigpIHtcblx0cmV0dXJuIExvY2FsQ2FjaGVEYXRhLmdldExvY2FsQ2FjaGUoICdhdXRvX2ZpbGxfZGF0YScsICdKU09OJyApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuc2V0QXV0b0ZpbGxEYXRhID0gZnVuY3Rpb24oIHZhbCApIHtcblx0TG9jYWxDYWNoZURhdGEuc2V0TG9jYWxDYWNoZSggJ2F1dG9fZmlsbF9kYXRhJywgdmFsLCAnSlNPTicgKTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLnNldEFsbFVSTEFyZ3MgPSBmdW5jdGlvbiggdmFsICkge1xuXHRsZXQgc2FuaXRpemVkX3ZhbCA9IHt9O1xuXHQvLyBPbmx5IGFsbG93IG9iamVjdHMgdG8gYmUgcGFzc2VkIGluLCBub3RlIHRoYXQgbnVsbCBpcyByZWNvZ25pemVkIGFzIGFuIG9iamVjdCBhbmQgd2UgaWdub3JlIGl0LlxuXHRpZiAoIHR5cGVvZiB2YWwgPT09ICdvYmplY3QnICYmIHZhbCAhPT0gbnVsbCApIHtcblx0XHRmb3IgKCB2YXIga2V5IGluIHZhbCApIHtcblx0XHRcdGlmICggdmFsLmhhc093blByb3BlcnR5KCBrZXkgKSAmJiB2YWxba2V5XSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHQvLyBTYW5pdGl6ZSB2YWx1ZXMgdG8gaGVscCBwcmV2ZW50IGFnYWluc3QgWFNTIHdpdGggaHRtbEVuY29kZSBwbHVzIHNvbWUgZXh0cmEgY2hhcmFjdGVyczogJyBcIiA6XG5cdFx0XHRcdHNhbml0aXplZF92YWxba2V5XSA9IEdsb2JhbC5odG1sRW5jb2RlKCB2YWxba2V5XSApLnJlcGxhY2UoIC9cIi9nLCAnJnF1b3Q7JyApXG5cdFx0XHRcdFx0LnJlcGxhY2UoIC8nL2csICcmIzAzOTsnIClcblx0XHRcdFx0XHQucmVwbGFjZSggLzovZywgJyYjNTg7JyApO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXHRMb2NhbENhY2hlRGF0YS5zZXRMb2NhbENhY2hlKCAnYWxsX3VybF9hcmdzJywgc2FuaXRpemVkX3ZhbCwgJ0pTT04nICk7XG59O1xuXG5Mb2NhbENhY2hlRGF0YS5nZXRBbGxVUkxBcmdzID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiBMb2NhbENhY2hlRGF0YS5nZXRMb2NhbENhY2hlKCAnYWxsX3VybF9hcmdzJywgJ0pTT04nICk7XG59O1xuXG5Mb2NhbENhY2hlRGF0YS5jbGVhbk5lY2Vzc2FyeUNhY2hlID0gZnVuY3Rpb24oKSB7XG5cdERlYnVnLlRleHQoICdDbGVhcmluZyBDYWNoZScsICdMb2NhbENhY2hlRGF0YS5qcycsICdMb2NhbENhY2hlRGF0YScsICdjbGVhbk5lY2Vzc2FyeUNhY2hlJywgMTAgKTtcblx0TG9jYWxDYWNoZURhdGEubGFzdF90aW1lc2hlZXRfc2VsZWN0ZWRfdXNlciA9IG51bGw7XG5cdExvY2FsQ2FjaGVEYXRhLmxhc3RfdGltZXNoZWV0X3NlbGVjdGVkX2RhdGUgPSBudWxsO1xuXHQvL0pTIGxvYWQgT3B0aW1pemVcblx0aWYgKCBMb2NhbENhY2hlRGF0YS5sb2FkVmlld1JlcXVpcmVkSlNSZWFkeSApIHtcblx0XHRpZiAoIHR5cGVvZiBBTGF5b3V0Q2FjaGUgIT09ICd1bmRlZmluZWQnICkge1xuXHRcdFx0QUxheW91dENhY2hlLmxheW91dF9kaWMgPSB7fTtcblx0XHR9XG5cdH1cblx0TG9jYWxDYWNoZURhdGEudmlld19sYXlvdXRfY2FjaGUgPSB7fTtcblx0TG9jYWxDYWNoZURhdGEucmVzdWx0X2NhY2hlID0ge307XG5cdC8vQ2xvc2UgYW55IG9wZW4gd2l6YXJkcy5cblx0aWYgKCBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fd2l6YXJkX2NvbnRyb2xsZXJzLmxlbmd0aCA+IDAgKSB7XG4gICAgICAgIGZvciAoIHZhciBpID0gMDsgaSA8IExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl93aXphcmRfY29udHJvbGxlcnMubGVuZ3RoOyBpKysgKSB7XG4gICAgICAgICAgICBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fd2l6YXJkX2NvbnRyb2xsZXJzW2ldLm9uQ2xvc2VDbGljaygpO1xuICAgICAgICB9XG4gICAgfVxuXHRMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fd2l6YXJkX2NvbnRyb2xsZXJzID0gW107XG5cdEdsb2JhbC5jbGVhblZpZXdUYWIoKTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLmdldFNjcm9sbGJhcldpZHRoID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiBMb2NhbENhY2hlRGF0YS5nZXRMb2NhbENhY2hlKCAnc2Nyb2xsX2Jhcl93aWR0aCcgKTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLnNldFNjcm9sbEJhcldpZHRoID0gZnVuY3Rpb24oIHZhbCApIHtcblx0TG9jYWxDYWNoZURhdGEuc2V0TG9jYWxDYWNoZSggJ3Njcm9sbF9iYXJfd2lkdGgnLCB2YWwgKTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLmdldFNjcm9sbGJhckhlaWdodCA9IGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gTG9jYWxDYWNoZURhdGEuZ2V0TG9jYWxDYWNoZSggJ3Njcm9sbF9iYXJfaGVpZ2h0JyApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuc2V0U2Nyb2xsQmFySGVpZ2h0ID0gZnVuY3Rpb24oIHZhbCApIHtcblx0TG9jYWxDYWNoZURhdGEuc2V0TG9jYWxDYWNoZSggJ3Njcm9sbF9iYXJfaGVpZ2h0JywgdmFsICk7XG59O1xuXG5Mb2NhbENhY2hlRGF0YS5nZXRMYXN0UHVuY2hUaW1lID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiBMb2NhbENhY2hlRGF0YS5nZXRMb2NhbENhY2hlKCAnbGFzdF9wdW5jaF90aW1lJyApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuc2V0TGFzdFB1bmNoVGltZSA9IGZ1bmN0aW9uKCB2YWwgKSB7XG5cdExvY2FsQ2FjaGVEYXRhLnNldExvY2FsQ2FjaGUoICdsYXN0X3B1bmNoX3RpbWUnLCB2YWwgKTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLmdldEpvYlF1ZXVlUHVuY2hEYXRhID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiBMb2NhbENhY2hlRGF0YS5nZXRMb2NhbENhY2hlKCAnam9iX3F1ZXVlX3B1bmNoX2RhdGEnLCAnSlNPTicgKTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLnNldEpvYlF1ZXVlUHVuY2hEYXRhID0gZnVuY3Rpb24oIHZhbCApIHtcblx0TG9jYWxDYWNoZURhdGEuc2V0TG9jYWxDYWNoZSggJ2pvYl9xdWV1ZV9wdW5jaF9kYXRhJywgdmFsLCAnSlNPTicgKTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLmdldEZlYXR1cmVGbGFnRGF0YSA9IGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gTG9jYWxDYWNoZURhdGEuZ2V0TG9jYWxDYWNoZSggJ2ZlYXR1cmVfZmxhZ19kYXRhJywgJ0pTT04nICk7XG59O1xuXG5Mb2NhbENhY2hlRGF0YS5zZXRGZWF0dXJlRmxhZ0RhdGEgPSBmdW5jdGlvbiggdmFsICkge1xuXHRMb2NhbENhY2hlRGF0YS5zZXRMb2NhbENhY2hlKCAnZmVhdHVyZV9mbGFnX2RhdGEnLCB2YWwsICdKU09OJyApO1xufTtcblxuLy9DaGVjayB0byBzZWUgaWYgbG9jYWwgc3RvcmFnZSBpcyBhY3R1YWxseSBhdmFpbGFibGUuXG5Mb2NhbENhY2hlRGF0YS5pc1N0b3JhZ2VBdmFpbGFibGUoKTsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///9563\n")},8843:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval("/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"Y\": () => (/* binding */ PermissionManager)\n/* harmony export */ });\nvar PermissionManager = ( function() {\n\n\tvar validate = function( name, value ) {\n\t\tvar permission = PermissionManager.getPermissionData();\n\n\t\t//Error: Uncaught TypeError: Cannot read property 'punch' of null in /interface/html5/global/PermissionManager.js?v=8.0.0-20141230-115759 line 6\n\t\tif ( !permission || !Global.isSet( permission[name] ) || !Global.isSet( permission[name][value] ) ) {\n\t\t\treturn false;\n\t\t} else {\n\t\t\treturn permission[name][value];\n\t\t}\n\t};\n\n\tvar getPermissionLevel = function() {\n\t\tvar permission = PermissionManager.getPermissionData();\n\n\t\tif ( permission && permission['_system'] && permission['_system']['level'] ) {\n\t\t\treturn permission['_system']['level'];\n\t\t}\n\n\t\treturn 0;\n\t};\n\n\tvar subJobApplicationValidate = function( viewId ) {\n\t\tvar permission_section = getPermissionSectionByViewId( viewId );\n\n\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\treturn false;\n\t\t} else if ( PermissionManager.validate( permission_section, 'view' ) ||\n\t\t\tPermissionManager.validate( permission_section, 'edit' ) || PermissionManager.validate( permission_section, 'edit_child' ) ) {\n//\t\t\treturn true; // hide the tab until the API complete.\n\t\t\treturn false;\n\t\t}\n\n\t\treturn false;\n\n\t};\n\n\tvar HelpMenuValidateAdmin = function() {\n\t\tif ( PermissionManager.getPermissionLevel() >= 70 && PermissionManager.validate( 'user', 'edit' ) ) { //70=HR Manager or higher\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t};\n\n\tvar HelpMenuValidateSupervisor = function() {\n\t\tif ( PermissionManager.getPermissionLevel() >= 40 && ( PermissionManager.validate( 'user', 'edit_child' ) || PermissionManager.validate( 'punch', 'edit_child' ) ) ) { //40=Supervisor (Subordinates Only)\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t};\n\n\tvar checkTopLevelPermission = function( viewId ) {\n\t\tvar permission_section = getPermissionSectionByViewId( viewId );\n\n\t\tvar result = false;\n\n\t\tif ( viewId === 'About' ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t//TypeError: Cannot read property 'product_edition_id' of null\n\t\t//BUG#2066 - fail gracefully\n\t\t// Since LocalCacheData.getCurrentCompany() is require data, if the user was logged out or in the process of logging out, it could trigger sendErrorReport()\n\t\t// so first check that 'current_company' exists in the LocalCacheData to avoid calling getCurrentCompany() if it doesn't exist.\n\t\tif ( Global.isSet( LocalCacheData ) == false || LocalCacheData.isLocalCacheExists( 'current_company' ) == false || Global.isSet( LocalCacheData.getCurrentCompany() ) == false ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tswitch ( viewId ) {\n\t\t\tcase 'GridTest':\n\t\t\tcase 'WidgetTest':\n\t\t\tcase 'AwesomeboxTest':\n\t\t\tcase 'UIKitSample':\n\t\t\tcase 'UIKitChildSample':\n\t\t\t\tresult = true;\n\t\t\t\tbreak;\n\t\t\tcase 'JobInvoice':\n\t\t\t\tif ( !( Global.getProductEdition() >= 20 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'add' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'edit' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'edit_own' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'PaymentGateway':\n\t\t\t\tif ( !( Global.getProductEdition() >= 20 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'edit' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'edit_own' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'InvoiceConfig':\n\t\t\t\tif ( !( Global.getProductEdition() >= 20 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'edit' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'edit_own' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'CustomField':\n\t\t\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'view' ) &&\n\t\t\t\t\tPermissionManager.validate( permission_section, 'edit' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'InOut':\n\t\t\t\tif ( PermissionManager.validate( permission_section, 'enabled' ) && PermissionManager.validate( permission_section, 'punch_in_out' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'Employee':\n\t\t\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'view' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_child' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'LegalEntity':\n\t\t\tcase 'PayrollRemittanceAgency':\n\t\t\tcase 'RemittanceSourceAccount':\n\t\t\tcase 'UserTitle':\n\t\t\tcase 'UserGroup':\n\t\t\tcase 'UserDefault':\n\t\t\tcase 'EthnicGroup':\n\t\t\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'edit' ) && PermissionManager.validate( permission_section, 'add' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'RemittanceDestinationAccount': //Uncomment this to enable Employee -> Payment Methods for regular employees. -- Currently Supervisors/Payroll Admins/Admins can see this.\n\t\t\tcase 'Punches':\n\t\t\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'edit' ) || PermissionManager.validate( permission_section, 'edit_child' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'GovernmentDocument':\n\t\t\tcase 'Exception':\n\t\t\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'view' ) || PermissionManager.validate( permission_section, 'view_own' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'Company':\n\t\t\tcase 'LoginUserContact':\n\t\t\tcase 'LoginUserPreference':\n\t\t\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'edit_own' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'Companies':\n\t\t\t\tif ( ( Global.getProductEdition() >= 15 ) &&\n\t\t\t\t\tPermissionManager.validate( permission_section, 'enabled' ) && PermissionManager.validate( permission_section, 'view' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'SavedReport':\n\t\t\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'PermissionControl':\n\t\t\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'edit' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'DocumentGroup':\n\t\t\t\tif ( !( Global.getProductEdition() >= 20 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'edit' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 'PayPeriodSchedule':\n\t\t\tcase 'Branch':\n\t\t\tcase 'Department':\n\t\t\tcase 'HierarchyControl':\n\t\t\tcase 'WageGroup':\n\t\t\tcase 'Station':\n\t\t\tcase 'Currency':\n\t\t\tcase 'PayStubEntryAccount':\n\t\t\tcase 'CompanyTaxDeduction':\n\t\t\tcase 'PolicyGroup':\n\t\t\tcase 'SchedulePolicy':\n\t\t\tcase 'RoundIntervalPolicy':\n\t\t\tcase 'MealPolicy':\n\t\t\tcase 'BreakPolicy':\n\t\t\tcase 'OvertimePolicy':\n\t\t\tcase 'PremiumPolicy':\n\t\t\tcase 'ExceptionPolicyControl':\n\t\t\tcase 'AccrualPolicy':\n\t\t\tcase 'AbsencePolicy':\n\t\t\tcase 'HolidayPolicy':\n\t\t\tcase 'RecurringHoliday':\n\t\t\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'view' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'RequestAuthorization':\n\t\t\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( 'request', 'authorize' ) && ( PermissionManager.validate( permission_section, 'view' ) || PermissionManager.validate( permission_section, 'view_child' ) ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'TimeSheetAuthorization':\n\t\t\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( 'punch', 'authorize' ) && ( PermissionManager.validate( permission_section, 'view' ) || PermissionManager.validate( permission_section, 'view_child' ) ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'ExpenseAuthorization':\n\t\t\t\tif ( !( Global.getProductEdition() >= 25 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( 'user_expense', 'authorize' ) && ( PermissionManager.validate( permission_section, 'view' ) || PermissionManager.validate( permission_section, 'view_child' ) ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'UserExpense':\n\t\t\t\tif ( !( Global.getProductEdition() >= 25 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'view' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'ImportCSV':\n\t\t\t\t//This is the Company -> Import icon, which should only be displayed if 'company','enabled' is also allowed.\n\t\t\t\tif ( PermissionManager.validate( 'company', 'enabled' ) ) {\n\t\t\t\t\tresult = importValidate();\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'ImportCSVSchedule':\n\t\t\t\tresult = importValidateFor( 'schedule' );\n\t\t\t\tbreak;\n\t\t\tcase 'ImportCSVBranch':\n\t\t\t\tresult = importValidateFor( 'branch' );\n\t\t\t\tbreak;\n\t\t\tcase 'ImportCSVDepartment':\n\t\t\t\tresult = importValidateFor( 'department' );\n\t\t\t\tbreak;\n\t\t\tcase 'ImportCSVWage':\n\t\t\t\tresult = importValidateFor( 'wage' );\n\t\t\t\tbreak;\n\t\t\tcase 'ImportCSVEmployeeBankAccount':\n\t\t\t\tresult = importValidateFor( 'user' );\n\t\t\t\tbreak;\n\t\t\tcase 'ImportCSVEmployee':\n\t\t\t\tresult = importValidateFor( 'user' );\n\t\t\t\tbreak;\n\t\t\tcase 'ImportCSVPayStubAmendment':\n\t\t\t\tresult = importValidateFor( 'pay_stub_amendment' );\n\t\t\t\tbreak;\n\t\t\tcase 'ImportCSVJob':\n\t\t\t\tresult = importValidateFor( 'job' );\n\t\t\t\tbreak;\n\t\t\tcase 'ImportCSVJobItem':\n\t\t\t\tresult = importValidateFor( 'job_item' );\n\t\t\t\tbreak;\n\t\t\tcase 'PayrollProcessWizard':\n\t\t\t\tif ( PermissionManager.validate( 'pay_stub', 'add' ) &&\n\t\t\t\t\tPermissionManager.validate( 'pay_stub', 'edit' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'QuickStartWizard':\n\t\t\t\tif ( PermissionManager.validate( 'pay_period_schedule', 'add' ) &&\n\t\t\t\t\tPermissionManager.validate( 'user_preference', 'edit' ) &&\n\t\t\t\t\tPermissionManager.validate( 'policy_group', 'edit' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'AccrualBalance':\n\t\t\tcase 'Accrual':\n\t\t\tcase 'Request':\n\t\t\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'view' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_own' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'ScheduleShift':\n\t\t\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'edit' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'edit_child' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'RecurringScheduleControl':\n\t\t\tcase 'RecurringScheduleTemplateControl':\n\t\t\tcase 'MessageControl':\n\t\t\t\tif ( PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'Notification':\n\t\t\t\tresult = true; // Notification always returns true as notifications should always be enabled.\n\t\t\t\tbreak;\n\t\t\tcase 'UserPreference':\n\t\t\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'edit' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'edit_child' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'Document':\n\t\t\t\tif ( !( Global.getProductEdition() >= 20 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'view' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_own' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_private' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'ChangePassword':\n\t\t\t\tif ( PermissionManager.validate( permission_section, 'edit_own_password' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'edit_own_phone_password' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'ActiveShiftReport':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_active_shift' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'UserSummaryReport':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_user_information' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'AuditTrailReport':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_system_log' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'ScheduleSummaryReport':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_schedule_summary' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'TimesheetSummaryReport':\n\t\t\tcase 'TimesheetDetailReport':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_timesheet_summary' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'PunchSummaryReport':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_punch_summary' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'AccrualBalanceSummaryReport':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_accrual_balance_summary' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'ExceptionSummaryReport':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_exception_summary' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'PayStubTransactionSummaryReport':\n\t\t\tcase 'PayStubSummaryReport':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_pay_stub_summary' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'PayrollExportReport':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_payroll_export' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'GeneralLedgerSummaryReport':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_general_ledger_summary' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'ExpenseSummaryReport':\n\t\t\t\tif ( !( Global.getProductEdition() >= 20 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( 'report', 'view_expense' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'JobSummaryReport':\n\t\t\tcase 'JobInformationReport':\n\t\t\tcase 'JobItemInformationReport':\n\t\t\t\tif ( !( Global.getProductEdition() >= 20 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( 'job_report', 'view_job_summary' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'JobAnalysisReport':\n\t\t\t\tif ( !( Global.getProductEdition() >= 20 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( 'job_report', 'view_job_analysis' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'InvoiceTransactionSummaryReport':\n\t\t\t\tif ( !( Global.getProductEdition() >= 20 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( 'invoice_report', 'view_transaction_summary' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'RemittanceSummaryReport':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_remittance_summary' ) &&\n\t\t\t\t\tcountryPermissionValidate( 'CA' )\n\t\t\t\t) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'T4SummaryReport':\n\t\t\tcase 'T4ASummaryReport':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_t4_summary' ) &&\n\t\t\t\t\tcountryPermissionValidate( 'CA' )\n\t\t\t\t) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'TaxSummaryReport':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_generic_tax_summary' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'Form940Report':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_form940' ) &&\n\t\t\t\t\tcountryPermissionValidate( 'US' )\n\t\t\t\t) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'Form941Report':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_form941' ) &&\n\t\t\t\t\tcountryPermissionValidate( 'US' )\n\t\t\t\t) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'Form1099NecReport':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_form1099nec' ) &&\n\t\t\t\t\tcountryPermissionValidate( 'US' )\n\t\t\t\t) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'FormW2Report':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_formW2' ) &&\n\t\t\t\t\tcountryPermissionValidate( 'US' )\n\t\t\t\t) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'USStateUnemploymentReport':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_us_state_unemployment' ) &&\n\t\t\t\t\tcountryPermissionValidate( 'US' )\n\t\t\t\t) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'AffordableCareReport':\n\t\t\t\tif ( Global.getProductEdition() >= 15 &&\n\t\t\t\t\tPermissionManager.validate( 'report', 'view_affordable_care' ) &&\n\t\t\t\t\tcountryPermissionValidate( 'US' )\n\t\t\t\t) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'UserQualificationReport':\n\t\t\t\tif ( PermissionManager.validate( 'hr_report', 'user_qualification' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'KPIReport':\n\t\t\t\tif ( PermissionManager.validate( 'hr_report', 'user_review' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'UserRecruitmentSummaryReport':\n\t\t\tcase 'UserRecruitmentDetailReport':\n\t\t\t\tif ( !( Global.getProductEdition() >= 25 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( 'recruitment_report', 'user_recruitment' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'Client':\n\t\t\tcase 'ClientContact':\n\t\t\tcase 'InvoiceDistrict':\n\t\t\tcase 'ClientPayment':\n\t\t\tcase 'Invoice':\n\t\t\tcase 'InvoiceTransaction':\n\t\t\tcase 'Product':\n\t\t\tcase 'ClientGroup':\n\t\t\tcase 'ProductGroup':\n\t\t\tcase 'TaxPolicy':\n\t\t\tcase 'ShippingPolicy':\n\t\t\tcase 'AreaPolicy':\n\t\t\t\tif ( !( Global.getProductEdition() >= 20 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'view' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_own' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_child' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'Job':\n\t\t\tcase 'JobItem':\n\t\t\tcase 'JobGroup':\n\t\t\tcase 'JobItemGroup':\n\t\t\t\tif ( !( Global.getProductEdition() >= 20 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'view' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_own' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_child' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'PunchTag':\n\t\t\tcase 'PunchTagGroup':\n\t\t\t\tif ( !( Global.getProductEdition() >= 20 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'view' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_own' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_child' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'GEOFence':\n\t\t\t\tif ( !( Global.getProductEdition() >= 20 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'view' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_own' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'ExpensePolicy':\n\t\t\tcase 'LoginUserExpense':\n\t\t\tcase 'JobVacancy':\n\t\t\tcase 'JobApplicant':\n\t\t\tcase 'JobApplication':\n\n\t\t\t\tif ( !( Global.getProductEdition() >= 25 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'view' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_own' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_child' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'ROE':\n\t\t\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( ( PermissionManager.validate( permission_section, 'view' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_own' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_child' ) ) &&\n\t\t\t\t\tcountryPermissionValidate( 'CA' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'GeneratePayStubs':\n\t\t\t\tif ( PermissionManager.validate( 'pay_period_schedule', 'enabled' )\n\t\t\t\t\t&& ( PermissionManager.validate( 'pay_period_schedule', 'edit' ) || PermissionManager.validate( 'pay_period_schedule', 'edit_own' ) )\n\t\t\t\t\t&& ( PermissionManager.validate( 'pay_stub', 'view' ) || PermissionManager.validate( 'pay_stub', 'view_child' ) ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'PayStubTransaction':\n\t\t\t\tif ( PermissionManager.validate( 'pay_stub', 'enabled' )\n\t\t\t\t\t&& ( PermissionManager.validate( 'pay_stub', 'view' ) || PermissionManager.validate( 'pay_stub', 'view_child' ) ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'view' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_own' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_child' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t}\n\n\t\treturn result;\n\t};\n\n\tvar countryPermissionValidate = function( key ) {\n\n\t\tvar country_array = LocalCacheData.getUniqueCountryArray();\n\n\t\tfor ( var i = 0; i < country_array.length; i++ ) {\n\t\t\tif ( key === country_array[i] ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\n\t};\n\n\tvar importValidate = function() {\n\n\t\tvar result = false;\n\n\t\tif ( importValidateFor( 'branch' ) ||\n\t\t\timportValidateFor( 'payperiod' ) ||\n\t\t\timportValidateFor( 'schedule' ) ||\n\t\t\timportValidateFor( 'user' ) ||\n\t\t\timportValidateFor( 'department' ) ||\n\t\t\timportValidateFor( 'client' ) ||\n\t\t\timportValidateFor( 'job' ) ||\n\t\t\timportValidateFor( 'jobitem' ) ||\n\t\t\timportValidateFor( 'wage' ) ||\n\t\t\timportValidateFor( 'punch' ) ||\n\t\t\timportValidateFor( 'paystubamendment' ) ||\n\t\t\timportValidateFor( 'accrual' ) ) {\n\n\t\t\tresult = true;\n\t\t}\n\n\t\treturn result;\n\t};\n\n\tvar importValidateFor = function( key ) {\n\t\tif ( PermissionManager.validate( key, 'add' ) &&\n\t\t\t( PermissionManager.validate( key, 'edit' ) || PermissionManager.validate( key, 'edit_child' ) ) ) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t};\n\n\tvar getPermissionSectionByViewId = function( viewId ) {\n\n\t\tvar permission_section = '';\n\n\t\tswitch ( viewId ) {\n\t\t\tcase 'AccumulatedTime':\n\t\t\t\tpermission_section = 'user_date_total';\n\t\t\t\tbreak;\n\t\t\tcase 'PaymentGateway':\n\t\t\t\tpermission_section = 'payment_gateway';\n\t\t\t\tbreak;\n\t\t\tcase 'InvoiceConfig':\n\t\t\t\tpermission_section = 'invoice_config';\n\t\t\t\tbreak;\n\t\t\tcase 'AreaPolicy':\n\t\t\t\tpermission_section = 'area_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'ShippingPolicy':\n\t\t\t\tpermission_section = 'shipping_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'GovernmentDocument':\n\t\t\t\tpermission_section = 'government_document';\n\t\t\t\tbreak;\n\t\t\tcase 'TaxPolicy':\n\t\t\t\tpermission_section = 'tax_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'Product':\n\t\t\t\tpermission_section = 'product';\n\t\t\t\tbreak;\n\t\t\tcase 'RemittanceSourceAccount':\n\t\t\t\tpermission_section = 'remittance_source_account';\n\t\t\t\tbreak;\n\t\t\tcase 'RemittanceDestinationAccount':\n\t\t\t\tpermission_section = 'remittance_destination_account';\n\t\t\t\tbreak;\n\t\t\tcase 'ScheduleShift':\n\t\t\tcase 'Schedule':\n\t\t\t\tpermission_section = 'schedule';\n\t\t\t\tbreak;\n\t\t\tcase 'TimeSheet':\n\t\t\tcase 'ManualTimeSheet':\n\t\t\tcase 'UserDateTotalParent':\n\t\t\tcase 'UserDateTotal':\n\t\t\tcase 'InOut':\n\t\t\tcase 'Punches':\n\t\t\tcase 'TimeSheetAuthorization':\n\t\t\tcase 'Exception':\n\t\t\t\tpermission_section = 'punch';\n\t\t\t\tbreak;\n\t\t\tcase 'AccrualBalance':\n\t\t\tcase 'Accrual':\n\t\t\t\tpermission_section = 'accrual';\n\t\t\t\tbreak;\n\t\t\tcase 'Job':\n\t\t\tcase 'JobGroup':\n\t\t\t\tpermission_section = 'job';\n\t\t\t\tbreak;\n\t\t\tcase 'PunchTag':\n\t\t\tcase 'PunchTagGroup':\n\t\t\t\tpermission_section = 'punch_tag';\n\t\t\t\tbreak;\n\t\t\tcase 'PolicyGroup':\n\t\t\t\tpermission_section = 'policy_group';\n\t\t\t\tbreak;\n\t\t\tcase 'PayCode':\n\t\t\t\tpermission_section = 'pay_code';\n\t\t\t\tbreak;\n\t\t\tcase 'PayFormulaPolicy':\n\t\t\t\tpermission_section = 'pay_formula_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'ContributingPayCodePolicy':\n\t\t\t\tpermission_section = 'contributing_pay_code_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'ContributingShiftPolicy':\n\t\t\t\tpermission_section = 'contributing_shift_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'AbsencePolicy':\n\t\t\t\tpermission_section = 'absence_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'MealPolicy':\n\t\t\t\tpermission_section = 'meal_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'ExpensePolicy':\n\t\t\t\tpermission_section = 'expense_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'BreakPolicy':\n\t\t\t\tpermission_section = 'break_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'HolidayPolicy':\n\t\t\tcase 'RecurringHoliday':\n\t\t\t\tpermission_section = 'holiday_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'PremiumPolicy':\n\t\t\t\tpermission_section = 'premium_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'RegularTimePolicy':\n\t\t\t\tpermission_section = 'regular_time_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'OvertimePolicy':\n\t\t\t\tpermission_section = 'over_time_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'RoundIntervalPolicy':\n\t\t\t\tpermission_section = 'round_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'Employee':\n\t\t\tcase 'LoginUserContact':\n\t\t\tcase 'ChangePassword':\n\t\t\t\tpermission_section = 'user';\n\t\t\t\tbreak;\n\t\t\tcase 'UserDefault':\n\t\t\t\tpermission_section = 'user_default';\n\t\t\t\tbreak;\n\t\t\tcase 'UserTitle':\n\t\t\t\tpermission_section = 'user_title';\n\t\t\t\tbreak;\n\t\t\tcase 'UserGroup':\n\t\t\t\tpermission_section = 'user_group';\n\t\t\t\tbreak;\n\t\t\tcase 'EthnicGroup':\n\t\t\t\tpermission_section = 'ethnic_group';\n\t\t\t\tbreak;\n\t\t\tcase 'LegalEntity':\n\t\t\t\tpermission_section = 'legal_entity';\n\t\t\t\tbreak;\n\t\t\tcase 'PayrollRemittanceAgency':\n\t\t\t\tpermission_section = 'payroll_remittance_agency';\n\t\t\t\tbreak;\n\t\t\tcase 'MessageControl':\n\t\t\t\tpermission_section = 'message';\n\t\t\t\tbreak;\n\t\t\tcase 'Notification':\n\t\t\t\tpermission_section = 'notification';\n\t\t\t\tbreak;\n\t\t\tcase 'Wage':\n\t\t\tcase 'WageGroup':\n\t\t\t\tpermission_section = 'wage';\n\t\t\t\tbreak;\n\t\t\tcase 'UserContact':\n\t\t\t\tpermission_section = 'user_contact';\n\t\t\t\tbreak;\n\t\t\tcase 'LoginUserExpense':\n\t\t\tcase 'UserExpense':\n\t\t\t\tpermission_section = 'user_expense';\n\t\t\t\tbreak;\n\t\t\tcase 'UserSkill':\n\t\t\t\tpermission_section = 'user_skill';\n\t\t\t\tbreak;\n\t\t\tcase 'JobApplication':\n\t\t\t\tpermission_section = 'job_application';\n\t\t\t\tbreak;\n\t\t\tcase 'JobApplicant':\n\t\t\tcase 'RecruitmentPortalConfig':\n\t\t\t\tpermission_section = 'job_applicant';\n\t\t\t\tbreak;\n\t\t\tcase 'UserLicense':\n\t\t\t\tpermission_section = 'user_license';\n\t\t\t\tbreak;\n\t\t\tcase 'UserMembership':\n\t\t\t\tpermission_section = 'user_membership';\n\t\t\t\tbreak;\n\t\t\tcase 'UserEducation':\n\t\t\t\tpermission_section = 'user_education';\n\t\t\t\tbreak;\n\t\t\tcase 'UserPreference':\n\t\t\tcase 'LoginUserPreference':\n\t\t\t\tpermission_section = 'user_preference';\n\t\t\t\tbreak;\n\t\t\tcase 'UserLanguage':\n\t\t\t\tpermission_section = 'user_language';\n\t\t\t\tbreak;\n\t\t\tcase 'Company':\n\t\t\tcase 'Companies':\n\t\t\t\tpermission_section = 'company';\n\t\t\t\tbreak;\n\t\t\tcase 'GEOFence':\n\t\t\t\tpermission_section = 'geo_fence';\n\t\t\t\tbreak;\n\t\t\tcase 'Qualification':\n\t\t\tcase 'QualificationGroup':\n\t\t\t\tpermission_section = 'qualification';\n\t\t\t\tbreak;\n\t\t\tcase 'PayPeriodSchedule':\n\t\t\tcase 'PayPeriods':\n\t\t\t\tpermission_section = 'pay_period_schedule';\n\t\t\t\tbreak;\n\t\t\tcase 'PayStubAmendment':\n\t\t\tcase 'RecurringPayStubAmendment':\n\t\t\t\tpermission_section = 'pay_stub_amendment';\n\t\t\t\tbreak;\n\t\t\tcase 'PayStubTransactionSummaryReport':\n\t\t\tcase 'PayStub':\n\t\t\t\tpermission_section = 'pay_stub';\n\t\t\t\tbreak;\n\t\t\tcase 'Branch':\n\t\t\t\tpermission_section = 'branch';\n\t\t\t\tbreak;\n\t\t\tcase 'Department':\n\t\t\t\tpermission_section = 'department';\n\t\t\t\tbreak;\n\t\t\tcase 'HierarchyControl':\n\t\t\t\tpermission_section = 'hierarchy';\n\t\t\t\tbreak;\n\t\t\tcase 'Station':\n\t\t\t\tpermission_section = 'station';\n\t\t\t\tbreak;\n\t\t\tcase 'JobVacancy':\n\t\t\tcase 'PortalJobVacancy':\n\t\t\t\tpermission_section = 'job_vacancy';\n\t\t\t\tbreak;\n\t\t\tcase 'PayStubEntryAccount':\n\t\t\t\tpermission_section = 'pay_stub_account';\n\t\t\t\tbreak;\n\t\t\tcase 'ROE':\n\t\t\t\tpermission_section = 'roe';\n\t\t\t\tbreak;\n\t\t\tcase 'CustomField':\n\t\t\t\tpermission_section = 'custom_field';\n\t\t\t\tbreak;\n\t\t\tcase 'Currency':\n\t\t\t\tpermission_section = 'currency';\n\t\t\t\tbreak;\n\t\t\tcase 'PermissionControl':\n\t\t\t\tpermission_section = 'permission';\n\t\t\t\tbreak;\n\t\t\tcase 'CompanyTaxDeduction':\n\t\t\t\tpermission_section = 'company_tax_deduction';\n\t\t\t\tbreak;\n\t\t\tcase 'UserTaxDeduction':\n\t\t\t\tpermission_section = 'user_tax_deduction';\n\t\t\t\tbreak;\n\t\t\tcase 'Request':\n\t\t\t\tpermission_section = 'request';\n\t\t\t\tbreak;\n\t\t\tcase 'RequestAuthorization':\n\t\t\tcase 'ExpenseAuthorization':\n\t\t\t\tpermission_section = 'authorization';\n\t\t\t\tbreak;\n\t\t\tcase 'Document':\n\t\t\tcase 'DocumentGroup':\n\t\t\t\tpermission_section = 'document';\n\t\t\t\tbreak;\n\t\t\tcase 'SchedulePolicy':\n\t\t\t\tpermission_section = 'schedule_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'AccrualPolicyAccount':\n\t\t\tcase 'AccrualPolicy':\n\t\t\t\tpermission_section = 'accrual_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'Client':\n\t\t\tcase 'ClientContact':\n\t\t\tcase 'InvoiceDistrict':\n\t\t\tcase 'ClientPayment':\n\t\t\t\tpermission_section = 'client';\n\t\t\t\tbreak;\n\t\t\tcase 'InvoiceTransaction':\n\t\t\t\tpermission_section = 'transaction';\n\t\t\t\tbreak;\n\t\t\tcase 'JobItemGroup':\n\t\t\tcase 'JobItem':\n\t\t\t\tpermission_section = 'job_item';\n\t\t\t\tbreak;\n\t\t\tcase 'SavedReport':\n\t\t\t\tpermission_section = 'report';\n\t\t\t\tbreak;\n\t\t\tcase 'RecurringScheduleControl':\n\t\t\t\tpermission_section = 'recurring_schedule';\n\t\t\t\tbreak;\n\t\t\tcase 'RecurringScheduleTemplateControl':\n\t\t\t\tpermission_section = 'recurring_schedule_template';\n\t\t\t\tbreak;\n\t\t\tcase 'KPI':\n\t\t\tcase 'KPIGroup':\n\t\t\t\tpermission_section = 'kpi';\n\t\t\t\tbreak;\n\t\t\tcase 'UserReviewControl':\n\t\t\t\tpermission_section = 'user_review';\n\t\t\t\tbreak;\n\t\t\tcase 'ExceptionPolicyControl':\n\t\t\t\tpermission_section = 'exception_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'ImportCSV':\n\t\t\t\tpermission_section = 'import_csv';\n\t\t\t\tbreak;\n\t\t\tcase 'Invoice':\n\t\t\tcase 'JobInvoice':\n\t\t\t\tpermission_section = 'invoice';\n\t\t\t\tbreak;\n\t\t}\n\n\t\treturn permission_section;\n\t};\n\n\tvar getPermissionData = function() {\n\t\treturn LocalCacheData.getPermissionData();\n\t};\n\n\treturn {\n\t\tcheckTopLevelPermission: checkTopLevelPermission,\n\t\tvalidate: validate,\n\t\tgetPermissionLevel: getPermissionLevel,\n\t\tgetPermissionData: getPermissionData,\n\t\tHelpMenuValidateAdmin: HelpMenuValidateAdmin,\n\t\tHelpMenuValidateSupervisor: HelpMenuValidateSupervisor,\n\t\timportValidate: importValidate,\n\t\tsubJobApplicationValidate: subJobApplicationValidate\n\t};\n\n} )();\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODg0My5qcyIsIm1hcHBpbmdzIjoiOzs7QUFBTzs7QUFFUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQSxrQkFBa0I7QUFDbEI7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBLHdHQUF3RztBQUN4RztBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSx5S0FBeUs7QUFDeks7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQjtBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQSxtQkFBbUIsMEJBQTBCO0FBQzdDO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsRUFBRSIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL2ludGVyZmFjZS9odG1sNS9nbG9iYWwvUGVybWlzc2lvbk1hbmFnZXIuanM/ZWFlNiJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgdmFyIFBlcm1pc3Npb25NYW5hZ2VyID0gKCBmdW5jdGlvbigpIHtcblxuXHR2YXIgdmFsaWRhdGUgPSBmdW5jdGlvbiggbmFtZSwgdmFsdWUgKSB7XG5cdFx0dmFyIHBlcm1pc3Npb24gPSBQZXJtaXNzaW9uTWFuYWdlci5nZXRQZXJtaXNzaW9uRGF0YSgpO1xuXG5cdFx0Ly9FcnJvcjogVW5jYXVnaHQgVHlwZUVycm9yOiBDYW5ub3QgcmVhZCBwcm9wZXJ0eSAncHVuY2gnIG9mIG51bGwgaW4gL2ludGVyZmFjZS9odG1sNS9nbG9iYWwvUGVybWlzc2lvbk1hbmFnZXIuanM/dj04LjAuMC0yMDE0MTIzMC0xMTU3NTkgbGluZSA2XG5cdFx0aWYgKCAhcGVybWlzc2lvbiB8fCAhR2xvYmFsLmlzU2V0KCBwZXJtaXNzaW9uW25hbWVdICkgfHwgIUdsb2JhbC5pc1NldCggcGVybWlzc2lvbltuYW1lXVt2YWx1ZV0gKSApIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0cmV0dXJuIHBlcm1pc3Npb25bbmFtZV1bdmFsdWVdO1xuXHRcdH1cblx0fTtcblxuXHR2YXIgZ2V0UGVybWlzc2lvbkxldmVsID0gZnVuY3Rpb24oKSB7XG5cdFx0dmFyIHBlcm1pc3Npb24gPSBQZXJtaXNzaW9uTWFuYWdlci5nZXRQZXJtaXNzaW9uRGF0YSgpO1xuXG5cdFx0aWYgKCBwZXJtaXNzaW9uICYmIHBlcm1pc3Npb25bJ19zeXN0ZW0nXSAmJiBwZXJtaXNzaW9uWydfc3lzdGVtJ11bJ2xldmVsJ10gKSB7XG5cdFx0XHRyZXR1cm4gcGVybWlzc2lvblsnX3N5c3RlbSddWydsZXZlbCddO1xuXHRcdH1cblxuXHRcdHJldHVybiAwO1xuXHR9O1xuXG5cdHZhciBzdWJKb2JBcHBsaWNhdGlvblZhbGlkYXRlID0gZnVuY3Rpb24oIHZpZXdJZCApIHtcblx0XHR2YXIgcGVybWlzc2lvbl9zZWN0aW9uID0gZ2V0UGVybWlzc2lvblNlY3Rpb25CeVZpZXdJZCggdmlld0lkICk7XG5cblx0XHRpZiAoICFQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZW5hYmxlZCcgKSApIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9IGVsc2UgaWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAndmlldycgKSB8fFxuXHRcdFx0UGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VkaXQnICkgfHwgUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VkaXRfY2hpbGQnICkgKSB7XG4vL1x0XHRcdHJldHVybiB0cnVlOyAvLyBoaWRlIHRoZSB0YWIgdW50aWwgdGhlIEFQSSBjb21wbGV0ZS5cblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHRyZXR1cm4gZmFsc2U7XG5cblx0fTtcblxuXHR2YXIgSGVscE1lbnVWYWxpZGF0ZUFkbWluID0gZnVuY3Rpb24oKSB7XG5cdFx0aWYgKCBQZXJtaXNzaW9uTWFuYWdlci5nZXRQZXJtaXNzaW9uTGV2ZWwoKSA+PSA3MCAmJiBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3VzZXInLCAnZWRpdCcgKSApIHsgLy83MD1IUiBNYW5hZ2VyIG9yIGhpZ2hlclxuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9O1xuXG5cdHZhciBIZWxwTWVudVZhbGlkYXRlU3VwZXJ2aXNvciA9IGZ1bmN0aW9uKCkge1xuXHRcdGlmICggUGVybWlzc2lvbk1hbmFnZXIuZ2V0UGVybWlzc2lvbkxldmVsKCkgPj0gNDAgJiYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3VzZXInLCAnZWRpdF9jaGlsZCcgKSB8fCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3B1bmNoJywgJ2VkaXRfY2hpbGQnICkgKSApIHsgLy80MD1TdXBlcnZpc29yIChTdWJvcmRpbmF0ZXMgT25seSlcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblxuXHRcdHJldHVybiBmYWxzZTtcblx0fTtcblxuXHR2YXIgY2hlY2tUb3BMZXZlbFBlcm1pc3Npb24gPSBmdW5jdGlvbiggdmlld0lkICkge1xuXHRcdHZhciBwZXJtaXNzaW9uX3NlY3Rpb24gPSBnZXRQZXJtaXNzaW9uU2VjdGlvbkJ5Vmlld0lkKCB2aWV3SWQgKTtcblxuXHRcdHZhciByZXN1bHQgPSBmYWxzZTtcblxuXHRcdGlmICggdmlld0lkID09PSAnQWJvdXQnICkge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0Ly9UeXBlRXJyb3I6IENhbm5vdCByZWFkIHByb3BlcnR5ICdwcm9kdWN0X2VkaXRpb25faWQnIG9mIG51bGxcblx0XHQvL0JVRyMyMDY2IC0gZmFpbCBncmFjZWZ1bGx5XG5cdFx0Ly8gU2luY2UgTG9jYWxDYWNoZURhdGEuZ2V0Q3VycmVudENvbXBhbnkoKSBpcyByZXF1aXJlIGRhdGEsIGlmIHRoZSB1c2VyIHdhcyBsb2dnZWQgb3V0IG9yIGluIHRoZSBwcm9jZXNzIG9mIGxvZ2dpbmcgb3V0LCBpdCBjb3VsZCB0cmlnZ2VyIHNlbmRFcnJvclJlcG9ydCgpXG5cdFx0Ly8gICBzbyBmaXJzdCBjaGVjayB0aGF0ICdjdXJyZW50X2NvbXBhbnknIGV4aXN0cyBpbiB0aGUgTG9jYWxDYWNoZURhdGEgdG8gYXZvaWQgY2FsbGluZyBnZXRDdXJyZW50Q29tcGFueSgpIGlmIGl0IGRvZXNuJ3QgZXhpc3QuXG5cdFx0aWYgKCBHbG9iYWwuaXNTZXQoIExvY2FsQ2FjaGVEYXRhICkgPT0gZmFsc2UgfHwgTG9jYWxDYWNoZURhdGEuaXNMb2NhbENhY2hlRXhpc3RzKCAnY3VycmVudF9jb21wYW55JyApID09IGZhbHNlIHx8IEdsb2JhbC5pc1NldCggTG9jYWxDYWNoZURhdGEuZ2V0Q3VycmVudENvbXBhbnkoKSApID09IGZhbHNlICkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdHN3aXRjaCAoIHZpZXdJZCApIHtcblx0XHRcdGNhc2UgJ0dyaWRUZXN0Jzpcblx0XHRcdGNhc2UgJ1dpZGdldFRlc3QnOlxuXHRcdFx0Y2FzZSAnQXdlc29tZWJveFRlc3QnOlxuXHRcdFx0Y2FzZSAnVUlLaXRTYW1wbGUnOlxuXHRcdFx0Y2FzZSAnVUlLaXRDaGlsZFNhbXBsZSc6XG5cdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnSm9iSW52b2ljZSc6XG5cdFx0XHRcdGlmICggISggR2xvYmFsLmdldFByb2R1Y3RFZGl0aW9uKCkgPj0gMjAgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIGlmICggIVBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICdlbmFibGVkJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnYWRkJyApIHx8XG5cdFx0XHRcdFx0UGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VkaXQnICkgfHxcblx0XHRcdFx0XHRQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZWRpdF9vd24nICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1BheW1lbnRHYXRld2F5Jzpcblx0XHRcdFx0aWYgKCAhKCBHbG9iYWwuZ2V0UHJvZHVjdEVkaXRpb24oKSA+PSAyMCApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCAhUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VuYWJsZWQnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH0gZWxzZSBpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICdlZGl0JyApIHx8XG5cdFx0XHRcdFx0UGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VkaXRfb3duJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdJbnZvaWNlQ29uZmlnJzpcblx0XHRcdFx0aWYgKCAhKCBHbG9iYWwuZ2V0UHJvZHVjdEVkaXRpb24oKSA+PSAyMCApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCAhUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VuYWJsZWQnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH0gZWxzZSBpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICdlZGl0JyApIHx8XG5cdFx0XHRcdFx0UGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VkaXRfb3duJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdDdXN0b21GaWVsZCc6XG5cdFx0XHRcdGlmICggIVBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICdlbmFibGVkJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAndmlldycgKSAmJlxuXHRcdFx0XHRcdFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICdlZGl0JyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdJbk91dCc6XG5cdFx0XHRcdGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VuYWJsZWQnICkgJiYgUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ3B1bmNoX2luX291dCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnRW1wbG95ZWUnOlxuXHRcdFx0XHRpZiAoICFQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZW5hYmxlZCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ3ZpZXcnICkgfHxcblx0XHRcdFx0XHRQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAndmlld19jaGlsZCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnTGVnYWxFbnRpdHknOlxuXHRcdFx0Y2FzZSAnUGF5cm9sbFJlbWl0dGFuY2VBZ2VuY3knOlxuXHRcdFx0Y2FzZSAnUmVtaXR0YW5jZVNvdXJjZUFjY291bnQnOlxuXHRcdFx0Y2FzZSAnVXNlclRpdGxlJzpcblx0XHRcdGNhc2UgJ1VzZXJHcm91cCc6XG5cdFx0XHRjYXNlICdVc2VyRGVmYXVsdCc6XG5cdFx0XHRjYXNlICdFdGhuaWNHcm91cCc6XG5cdFx0XHRcdGlmICggIVBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICdlbmFibGVkJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZWRpdCcgKSAmJiBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnYWRkJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdSZW1pdHRhbmNlRGVzdGluYXRpb25BY2NvdW50JzogLy9VbmNvbW1lbnQgdGhpcyB0byBlbmFibGUgRW1wbG95ZWUgLT4gUGF5bWVudCBNZXRob2RzIGZvciByZWd1bGFyIGVtcGxveWVlcy4gLS0gQ3VycmVudGx5IFN1cGVydmlzb3JzL1BheXJvbGwgQWRtaW5zL0FkbWlucyBjYW4gc2VlIHRoaXMuXG5cdFx0XHRjYXNlICdQdW5jaGVzJzpcblx0XHRcdFx0aWYgKCAhUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VuYWJsZWQnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH0gZWxzZSBpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICdlZGl0JyApIHx8IFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICdlZGl0X2NoaWxkJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdHb3Zlcm5tZW50RG9jdW1lbnQnOlxuXHRcdFx0Y2FzZSAnRXhjZXB0aW9uJzpcblx0XHRcdFx0aWYgKCAhUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VuYWJsZWQnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH0gZWxzZSBpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICd2aWV3JyApIHx8IFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICd2aWV3X293bicgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnQ29tcGFueSc6XG5cdFx0XHRjYXNlICdMb2dpblVzZXJDb250YWN0Jzpcblx0XHRcdGNhc2UgJ0xvZ2luVXNlclByZWZlcmVuY2UnOlxuXHRcdFx0XHRpZiAoICFQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZW5hYmxlZCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VkaXRfb3duJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdDb21wYW5pZXMnOlxuXHRcdFx0XHRpZiAoICggR2xvYmFsLmdldFByb2R1Y3RFZGl0aW9uKCkgPj0gMTUgKSAmJlxuXHRcdFx0XHRcdFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICdlbmFibGVkJyApICYmIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICd2aWV3JyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdTYXZlZFJlcG9ydCc6XG5cdFx0XHRcdGlmICggIVBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICdlbmFibGVkJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdQZXJtaXNzaW9uQ29udHJvbCc6XG5cdFx0XHRcdGlmICggIVBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICdlbmFibGVkJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZWRpdCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnRG9jdW1lbnRHcm91cCc6XG5cdFx0XHRcdGlmICggISggR2xvYmFsLmdldFByb2R1Y3RFZGl0aW9uKCkgPj0gMjAgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIGlmICggIVBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICdlbmFibGVkJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZWRpdCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRjYXNlICdQYXlQZXJpb2RTY2hlZHVsZSc6XG5cdFx0XHRjYXNlICdCcmFuY2gnOlxuXHRcdFx0Y2FzZSAnRGVwYXJ0bWVudCc6XG5cdFx0XHRjYXNlICdIaWVyYXJjaHlDb250cm9sJzpcblx0XHRcdGNhc2UgJ1dhZ2VHcm91cCc6XG5cdFx0XHRjYXNlICdTdGF0aW9uJzpcblx0XHRcdGNhc2UgJ0N1cnJlbmN5Jzpcblx0XHRcdGNhc2UgJ1BheVN0dWJFbnRyeUFjY291bnQnOlxuXHRcdFx0Y2FzZSAnQ29tcGFueVRheERlZHVjdGlvbic6XG5cdFx0XHRjYXNlICdQb2xpY3lHcm91cCc6XG5cdFx0XHRjYXNlICdTY2hlZHVsZVBvbGljeSc6XG5cdFx0XHRjYXNlICdSb3VuZEludGVydmFsUG9saWN5Jzpcblx0XHRcdGNhc2UgJ01lYWxQb2xpY3knOlxuXHRcdFx0Y2FzZSAnQnJlYWtQb2xpY3knOlxuXHRcdFx0Y2FzZSAnT3ZlcnRpbWVQb2xpY3knOlxuXHRcdFx0Y2FzZSAnUHJlbWl1bVBvbGljeSc6XG5cdFx0XHRjYXNlICdFeGNlcHRpb25Qb2xpY3lDb250cm9sJzpcblx0XHRcdGNhc2UgJ0FjY3J1YWxQb2xpY3knOlxuXHRcdFx0Y2FzZSAnQWJzZW5jZVBvbGljeSc6XG5cdFx0XHRjYXNlICdIb2xpZGF5UG9saWN5Jzpcblx0XHRcdGNhc2UgJ1JlY3VycmluZ0hvbGlkYXknOlxuXHRcdFx0XHRpZiAoICFQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZW5hYmxlZCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ3ZpZXcnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1JlcXVlc3RBdXRob3JpemF0aW9uJzpcblx0XHRcdFx0aWYgKCAhUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VuYWJsZWQnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH0gZWxzZSBpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAncmVxdWVzdCcsICdhdXRob3JpemUnICkgJiYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAndmlldycgKSB8fCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAndmlld19jaGlsZCcgKSApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdUaW1lU2hlZXRBdXRob3JpemF0aW9uJzpcblx0XHRcdFx0aWYgKCAhUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VuYWJsZWQnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH0gZWxzZSBpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAncHVuY2gnLCAnYXV0aG9yaXplJyApICYmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ3ZpZXcnICkgfHwgUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ3ZpZXdfY2hpbGQnICkgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnRXhwZW5zZUF1dGhvcml6YXRpb24nOlxuXHRcdFx0XHRpZiAoICEoIEdsb2JhbC5nZXRQcm9kdWN0RWRpdGlvbigpID49IDI1ICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH0gZWxzZSBpZiAoICFQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZW5hYmxlZCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoICd1c2VyX2V4cGVuc2UnLCAnYXV0aG9yaXplJyApICYmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ3ZpZXcnICkgfHwgUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ3ZpZXdfY2hpbGQnICkgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnVXNlckV4cGVuc2UnOlxuXHRcdFx0XHRpZiAoICEoIEdsb2JhbC5nZXRQcm9kdWN0RWRpdGlvbigpID49IDI1ICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH0gZWxzZSBpZiAoICFQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZW5hYmxlZCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ3ZpZXcnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0ltcG9ydENTVic6XG5cdFx0XHRcdC8vVGhpcyBpcyB0aGUgQ29tcGFueSAtPiBJbXBvcnQgaWNvbiwgd2hpY2ggc2hvdWxkIG9ubHkgYmUgZGlzcGxheWVkIGlmICdjb21wYW55JywnZW5hYmxlZCcgaXMgYWxzbyBhbGxvd2VkLlxuXHRcdFx0XHRpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAnY29tcGFueScsICdlbmFibGVkJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGltcG9ydFZhbGlkYXRlKCk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdJbXBvcnRDU1ZTY2hlZHVsZSc6XG5cdFx0XHRcdHJlc3VsdCA9IGltcG9ydFZhbGlkYXRlRm9yKCAnc2NoZWR1bGUnICk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnSW1wb3J0Q1NWQnJhbmNoJzpcblx0XHRcdFx0cmVzdWx0ID0gaW1wb3J0VmFsaWRhdGVGb3IoICdicmFuY2gnICk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnSW1wb3J0Q1NWRGVwYXJ0bWVudCc6XG5cdFx0XHRcdHJlc3VsdCA9IGltcG9ydFZhbGlkYXRlRm9yKCAnZGVwYXJ0bWVudCcgKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdJbXBvcnRDU1ZXYWdlJzpcblx0XHRcdFx0cmVzdWx0ID0gaW1wb3J0VmFsaWRhdGVGb3IoICd3YWdlJyApO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0ltcG9ydENTVkVtcGxveWVlQmFua0FjY291bnQnOlxuXHRcdFx0XHRyZXN1bHQgPSBpbXBvcnRWYWxpZGF0ZUZvciggJ3VzZXInICk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnSW1wb3J0Q1NWRW1wbG95ZWUnOlxuXHRcdFx0XHRyZXN1bHQgPSBpbXBvcnRWYWxpZGF0ZUZvciggJ3VzZXInICk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnSW1wb3J0Q1NWUGF5U3R1YkFtZW5kbWVudCc6XG5cdFx0XHRcdHJlc3VsdCA9IGltcG9ydFZhbGlkYXRlRm9yKCAncGF5X3N0dWJfYW1lbmRtZW50JyApO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0ltcG9ydENTVkpvYic6XG5cdFx0XHRcdHJlc3VsdCA9IGltcG9ydFZhbGlkYXRlRm9yKCAnam9iJyApO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0ltcG9ydENTVkpvYkl0ZW0nOlxuXHRcdFx0XHRyZXN1bHQgPSBpbXBvcnRWYWxpZGF0ZUZvciggJ2pvYl9pdGVtJyApO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1BheXJvbGxQcm9jZXNzV2l6YXJkJzpcblx0XHRcdFx0aWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3BheV9zdHViJywgJ2FkZCcgKSAmJlxuXHRcdFx0XHRcdFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAncGF5X3N0dWInLCAnZWRpdCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnUXVpY2tTdGFydFdpemFyZCc6XG5cdFx0XHRcdGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoICdwYXlfcGVyaW9kX3NjaGVkdWxlJywgJ2FkZCcgKSAmJlxuXHRcdFx0XHRcdFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAndXNlcl9wcmVmZXJlbmNlJywgJ2VkaXQnICkgJiZcblx0XHRcdFx0XHRQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3BvbGljeV9ncm91cCcsICdlZGl0JyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdBY2NydWFsQmFsYW5jZSc6XG5cdFx0XHRjYXNlICdBY2NydWFsJzpcblx0XHRcdGNhc2UgJ1JlcXVlc3QnOlxuXHRcdFx0XHRpZiAoICFQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZW5hYmxlZCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ3ZpZXcnICkgfHxcblx0XHRcdFx0XHRQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAndmlld19vd24nICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1NjaGVkdWxlU2hpZnQnOlxuXHRcdFx0XHRpZiAoICFQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZW5hYmxlZCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VkaXQnICkgfHxcblx0XHRcdFx0XHRQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZWRpdF9jaGlsZCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnUmVjdXJyaW5nU2NoZWR1bGVDb250cm9sJzpcblx0XHRcdGNhc2UgJ1JlY3VycmluZ1NjaGVkdWxlVGVtcGxhdGVDb250cm9sJzpcblx0XHRcdGNhc2UgJ01lc3NhZ2VDb250cm9sJzpcblx0XHRcdFx0aWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZW5hYmxlZCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnTm90aWZpY2F0aW9uJzpcblx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTsgLy8gTm90aWZpY2F0aW9uIGFsd2F5cyByZXR1cm5zIHRydWUgYXMgbm90aWZpY2F0aW9ucyBzaG91bGQgYWx3YXlzIGJlIGVuYWJsZWQuXG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnVXNlclByZWZlcmVuY2UnOlxuXHRcdFx0XHRpZiAoICFQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZW5hYmxlZCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VkaXQnICkgfHxcblx0XHRcdFx0XHRQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZWRpdF9jaGlsZCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnRG9jdW1lbnQnOlxuXHRcdFx0XHRpZiAoICEoIEdsb2JhbC5nZXRQcm9kdWN0RWRpdGlvbigpID49IDIwICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH0gZWxzZSBpZiAoICFQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZW5hYmxlZCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ3ZpZXcnICkgfHxcblx0XHRcdFx0XHRQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAndmlld19vd24nICkgfHxcblx0XHRcdFx0XHRQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAndmlld19wcml2YXRlJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdDaGFuZ2VQYXNzd29yZCc6XG5cdFx0XHRcdGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VkaXRfb3duX3Bhc3N3b3JkJyApIHx8XG5cdFx0XHRcdFx0UGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VkaXRfb3duX3Bob25lX3Bhc3N3b3JkJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdBY3RpdmVTaGlmdFJlcG9ydCc6XG5cdFx0XHRcdGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoICdyZXBvcnQnLCAndmlld19hY3RpdmVfc2hpZnQnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1VzZXJTdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdFx0aWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3JlcG9ydCcsICd2aWV3X3VzZXJfaW5mb3JtYXRpb24nICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0F1ZGl0VHJhaWxSZXBvcnQnOlxuXHRcdFx0XHRpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAncmVwb3J0JywgJ3ZpZXdfc3lzdGVtX2xvZycgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnU2NoZWR1bGVTdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdFx0aWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3JlcG9ydCcsICd2aWV3X3NjaGVkdWxlX3N1bW1hcnknICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1RpbWVzaGVldFN1bW1hcnlSZXBvcnQnOlxuXHRcdFx0Y2FzZSAnVGltZXNoZWV0RGV0YWlsUmVwb3J0Jzpcblx0XHRcdFx0aWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3JlcG9ydCcsICd2aWV3X3RpbWVzaGVldF9zdW1tYXJ5JyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdQdW5jaFN1bW1hcnlSZXBvcnQnOlxuXHRcdFx0XHRpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAncmVwb3J0JywgJ3ZpZXdfcHVuY2hfc3VtbWFyeScgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnQWNjcnVhbEJhbGFuY2VTdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdFx0aWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3JlcG9ydCcsICd2aWV3X2FjY3J1YWxfYmFsYW5jZV9zdW1tYXJ5JyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdFeGNlcHRpb25TdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdFx0aWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3JlcG9ydCcsICd2aWV3X2V4Y2VwdGlvbl9zdW1tYXJ5JyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdQYXlTdHViVHJhbnNhY3Rpb25TdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdGNhc2UgJ1BheVN0dWJTdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdFx0aWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3JlcG9ydCcsICd2aWV3X3BheV9zdHViX3N1bW1hcnknICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1BheXJvbGxFeHBvcnRSZXBvcnQnOlxuXHRcdFx0XHRpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAncmVwb3J0JywgJ3ZpZXdfcGF5cm9sbF9leHBvcnQnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0dlbmVyYWxMZWRnZXJTdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdFx0aWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3JlcG9ydCcsICd2aWV3X2dlbmVyYWxfbGVkZ2VyX3N1bW1hcnknICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0V4cGVuc2VTdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdFx0aWYgKCAhKCBHbG9iYWwuZ2V0UHJvZHVjdEVkaXRpb24oKSA+PSAyMCApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3JlcG9ydCcsICd2aWV3X2V4cGVuc2UnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0pvYlN1bW1hcnlSZXBvcnQnOlxuXHRcdFx0Y2FzZSAnSm9iSW5mb3JtYXRpb25SZXBvcnQnOlxuXHRcdFx0Y2FzZSAnSm9iSXRlbUluZm9ybWF0aW9uUmVwb3J0Jzpcblx0XHRcdFx0aWYgKCAhKCBHbG9iYWwuZ2V0UHJvZHVjdEVkaXRpb24oKSA+PSAyMCApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ2pvYl9yZXBvcnQnLCAndmlld19qb2Jfc3VtbWFyeScgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnSm9iQW5hbHlzaXNSZXBvcnQnOlxuXHRcdFx0XHRpZiAoICEoIEdsb2JhbC5nZXRQcm9kdWN0RWRpdGlvbigpID49IDIwICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH0gZWxzZSBpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAnam9iX3JlcG9ydCcsICd2aWV3X2pvYl9hbmFseXNpcycgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnSW52b2ljZVRyYW5zYWN0aW9uU3VtbWFyeVJlcG9ydCc6XG5cdFx0XHRcdGlmICggISggR2xvYmFsLmdldFByb2R1Y3RFZGl0aW9uKCkgPj0gMjAgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoICdpbnZvaWNlX3JlcG9ydCcsICd2aWV3X3RyYW5zYWN0aW9uX3N1bW1hcnknICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1JlbWl0dGFuY2VTdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdFx0aWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3JlcG9ydCcsICd2aWV3X3JlbWl0dGFuY2Vfc3VtbWFyeScgKSAmJlxuXHRcdFx0XHRcdGNvdW50cnlQZXJtaXNzaW9uVmFsaWRhdGUoICdDQScgKVxuXHRcdFx0XHQpIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnVDRTdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdGNhc2UgJ1Q0QVN1bW1hcnlSZXBvcnQnOlxuXHRcdFx0XHRpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAncmVwb3J0JywgJ3ZpZXdfdDRfc3VtbWFyeScgKSAmJlxuXHRcdFx0XHRcdGNvdW50cnlQZXJtaXNzaW9uVmFsaWRhdGUoICdDQScgKVxuXHRcdFx0XHQpIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnVGF4U3VtbWFyeVJlcG9ydCc6XG5cdFx0XHRcdGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoICdyZXBvcnQnLCAndmlld19nZW5lcmljX3RheF9zdW1tYXJ5JyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdGb3JtOTQwUmVwb3J0Jzpcblx0XHRcdFx0aWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3JlcG9ydCcsICd2aWV3X2Zvcm05NDAnICkgJiZcblx0XHRcdFx0XHRjb3VudHJ5UGVybWlzc2lvblZhbGlkYXRlKCAnVVMnIClcblx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0Zvcm05NDFSZXBvcnQnOlxuXHRcdFx0XHRpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAncmVwb3J0JywgJ3ZpZXdfZm9ybTk0MScgKSAmJlxuXHRcdFx0XHRcdGNvdW50cnlQZXJtaXNzaW9uVmFsaWRhdGUoICdVUycgKVxuXHRcdFx0XHQpIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnRm9ybTEwOTlOZWNSZXBvcnQnOlxuXHRcdFx0XHRpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAncmVwb3J0JywgJ3ZpZXdfZm9ybTEwOTluZWMnICkgJiZcblx0XHRcdFx0XHRjb3VudHJ5UGVybWlzc2lvblZhbGlkYXRlKCAnVVMnIClcblx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0Zvcm1XMlJlcG9ydCc6XG5cdFx0XHRcdGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoICdyZXBvcnQnLCAndmlld19mb3JtVzInICkgJiZcblx0XHRcdFx0XHRjb3VudHJ5UGVybWlzc2lvblZhbGlkYXRlKCAnVVMnIClcblx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1VTU3RhdGVVbmVtcGxveW1lbnRSZXBvcnQnOlxuXHRcdFx0XHRpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAncmVwb3J0JywgJ3ZpZXdfdXNfc3RhdGVfdW5lbXBsb3ltZW50JyApICYmXG5cdFx0XHRcdFx0Y291bnRyeVBlcm1pc3Npb25WYWxpZGF0ZSggJ1VTJyApXG5cdFx0XHRcdCkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdBZmZvcmRhYmxlQ2FyZVJlcG9ydCc6XG5cdFx0XHRcdGlmICggR2xvYmFsLmdldFByb2R1Y3RFZGl0aW9uKCkgPj0gMTUgJiZcblx0XHRcdFx0XHRQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3JlcG9ydCcsICd2aWV3X2FmZm9yZGFibGVfY2FyZScgKSAmJlxuXHRcdFx0XHRcdGNvdW50cnlQZXJtaXNzaW9uVmFsaWRhdGUoICdVUycgKVxuXHRcdFx0XHQpIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnVXNlclF1YWxpZmljYXRpb25SZXBvcnQnOlxuXHRcdFx0XHRpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAnaHJfcmVwb3J0JywgJ3VzZXJfcXVhbGlmaWNhdGlvbicgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnS1BJUmVwb3J0Jzpcblx0XHRcdFx0aWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ2hyX3JlcG9ydCcsICd1c2VyX3JldmlldycgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnVXNlclJlY3J1aXRtZW50U3VtbWFyeVJlcG9ydCc6XG5cdFx0XHRjYXNlICdVc2VyUmVjcnVpdG1lbnREZXRhaWxSZXBvcnQnOlxuXHRcdFx0XHRpZiAoICEoIEdsb2JhbC5nZXRQcm9kdWN0RWRpdGlvbigpID49IDI1ICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH0gZWxzZSBpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAncmVjcnVpdG1lbnRfcmVwb3J0JywgJ3VzZXJfcmVjcnVpdG1lbnQnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0NsaWVudCc6XG5cdFx0XHRjYXNlICdDbGllbnRDb250YWN0Jzpcblx0XHRcdGNhc2UgJ0ludm9pY2VEaXN0cmljdCc6XG5cdFx0XHRjYXNlICdDbGllbnRQYXltZW50Jzpcblx0XHRcdGNhc2UgJ0ludm9pY2UnOlxuXHRcdFx0Y2FzZSAnSW52b2ljZVRyYW5zYWN0aW9uJzpcblx0XHRcdGNhc2UgJ1Byb2R1Y3QnOlxuXHRcdFx0Y2FzZSAnQ2xpZW50R3JvdXAnOlxuXHRcdFx0Y2FzZSAnUHJvZHVjdEdyb3VwJzpcblx0XHRcdGNhc2UgJ1RheFBvbGljeSc6XG5cdFx0XHRjYXNlICdTaGlwcGluZ1BvbGljeSc6XG5cdFx0XHRjYXNlICdBcmVhUG9saWN5Jzpcblx0XHRcdFx0aWYgKCAhKCBHbG9iYWwuZ2V0UHJvZHVjdEVkaXRpb24oKSA+PSAyMCApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCAhUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VuYWJsZWQnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH0gZWxzZSBpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICd2aWV3JyApIHx8XG5cdFx0XHRcdFx0UGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ3ZpZXdfb3duJyApIHx8XG5cdFx0XHRcdFx0UGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ3ZpZXdfY2hpbGQnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0pvYic6XG5cdFx0XHRjYXNlICdKb2JJdGVtJzpcblx0XHRcdGNhc2UgJ0pvYkdyb3VwJzpcblx0XHRcdGNhc2UgJ0pvYkl0ZW1Hcm91cCc6XG5cdFx0XHRcdGlmICggISggR2xvYmFsLmdldFByb2R1Y3RFZGl0aW9uKCkgPj0gMjAgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIGlmICggIVBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICdlbmFibGVkJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAndmlldycgKSB8fFxuXHRcdFx0XHRcdFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICd2aWV3X293bicgKSB8fFxuXHRcdFx0XHRcdFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICd2aWV3X2NoaWxkJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdQdW5jaFRhZyc6XG5cdFx0XHRjYXNlICdQdW5jaFRhZ0dyb3VwJzpcblx0XHRcdFx0aWYgKCAhKCBHbG9iYWwuZ2V0UHJvZHVjdEVkaXRpb24oKSA+PSAyMCApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCAhUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VuYWJsZWQnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH0gZWxzZSBpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICd2aWV3JyApIHx8XG5cdFx0XHRcdFx0UGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ3ZpZXdfb3duJyApIHx8XG5cdFx0XHRcdFx0UGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ3ZpZXdfY2hpbGQnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0dFT0ZlbmNlJzpcblx0XHRcdFx0aWYgKCAhKCBHbG9iYWwuZ2V0UHJvZHVjdEVkaXRpb24oKSA+PSAyMCApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCAhUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VuYWJsZWQnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH0gZWxzZSBpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICd2aWV3JyApIHx8XG5cdFx0XHRcdFx0UGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ3ZpZXdfb3duJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdFeHBlbnNlUG9saWN5Jzpcblx0XHRcdGNhc2UgJ0xvZ2luVXNlckV4cGVuc2UnOlxuXHRcdFx0Y2FzZSAnSm9iVmFjYW5jeSc6XG5cdFx0XHRjYXNlICdKb2JBcHBsaWNhbnQnOlxuXHRcdFx0Y2FzZSAnSm9iQXBwbGljYXRpb24nOlxuXG5cdFx0XHRcdGlmICggISggR2xvYmFsLmdldFByb2R1Y3RFZGl0aW9uKCkgPj0gMjUgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIGlmICggIVBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICdlbmFibGVkJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAndmlldycgKSB8fFxuXHRcdFx0XHRcdFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICd2aWV3X293bicgKSB8fFxuXHRcdFx0XHRcdFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICd2aWV3X2NoaWxkJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdST0UnOlxuXHRcdFx0XHRpZiAoICFQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZW5hYmxlZCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIGlmICggKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAndmlldycgKSB8fFxuXHRcdFx0XHRcdFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICd2aWV3X293bicgKSB8fFxuXHRcdFx0XHRcdFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICd2aWV3X2NoaWxkJyApICkgJiZcblx0XHRcdFx0XHRjb3VudHJ5UGVybWlzc2lvblZhbGlkYXRlKCAnQ0EnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0dlbmVyYXRlUGF5U3R1YnMnOlxuXHRcdFx0XHRpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAncGF5X3BlcmlvZF9zY2hlZHVsZScsICdlbmFibGVkJyApXG5cdFx0XHRcdFx0JiYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3BheV9wZXJpb2Rfc2NoZWR1bGUnLCAnZWRpdCcgKSB8fCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3BheV9wZXJpb2Rfc2NoZWR1bGUnLCAnZWRpdF9vd24nICkgKVxuXHRcdFx0XHRcdCYmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoICdwYXlfc3R1YicsICd2aWV3JyApIHx8IFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAncGF5X3N0dWInLCAndmlld19jaGlsZCcgKSApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdQYXlTdHViVHJhbnNhY3Rpb24nOlxuXHRcdFx0XHRpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAncGF5X3N0dWInLCAnZW5hYmxlZCcgKVxuXHRcdFx0XHRcdCYmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoICdwYXlfc3R1YicsICd2aWV3JyApIHx8IFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAncGF5X3N0dWInLCAndmlld19jaGlsZCcgKSApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRpZiAoICFQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZW5hYmxlZCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ3ZpZXcnICkgfHxcblx0XHRcdFx0XHRQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAndmlld19vd24nICkgfHxcblx0XHRcdFx0XHRQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAndmlld19jaGlsZCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fTtcblxuXHR2YXIgY291bnRyeVBlcm1pc3Npb25WYWxpZGF0ZSA9IGZ1bmN0aW9uKCBrZXkgKSB7XG5cblx0XHR2YXIgY291bnRyeV9hcnJheSA9IExvY2FsQ2FjaGVEYXRhLmdldFVuaXF1ZUNvdW50cnlBcnJheSgpO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgY291bnRyeV9hcnJheS5sZW5ndGg7IGkrKyApIHtcblx0XHRcdGlmICgga2V5ID09PSBjb3VudHJ5X2FycmF5W2ldICkge1xuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gZmFsc2U7XG5cblx0fTtcblxuXHR2YXIgaW1wb3J0VmFsaWRhdGUgPSBmdW5jdGlvbigpIHtcblxuXHRcdHZhciByZXN1bHQgPSBmYWxzZTtcblxuXHRcdGlmICggaW1wb3J0VmFsaWRhdGVGb3IoICdicmFuY2gnICkgfHxcblx0XHRcdGltcG9ydFZhbGlkYXRlRm9yKCAncGF5cGVyaW9kJyApIHx8XG5cdFx0XHRpbXBvcnRWYWxpZGF0ZUZvciggJ3NjaGVkdWxlJyApIHx8XG5cdFx0XHRpbXBvcnRWYWxpZGF0ZUZvciggJ3VzZXInICkgfHxcblx0XHRcdGltcG9ydFZhbGlkYXRlRm9yKCAnZGVwYXJ0bWVudCcgKSB8fFxuXHRcdFx0aW1wb3J0VmFsaWRhdGVGb3IoICdjbGllbnQnICkgfHxcblx0XHRcdGltcG9ydFZhbGlkYXRlRm9yKCAnam9iJyApIHx8XG5cdFx0XHRpbXBvcnRWYWxpZGF0ZUZvciggJ2pvYml0ZW0nICkgfHxcblx0XHRcdGltcG9ydFZhbGlkYXRlRm9yKCAnd2FnZScgKSB8fFxuXHRcdFx0aW1wb3J0VmFsaWRhdGVGb3IoICdwdW5jaCcgKSB8fFxuXHRcdFx0aW1wb3J0VmFsaWRhdGVGb3IoICdwYXlzdHViYW1lbmRtZW50JyApIHx8XG5cdFx0XHRpbXBvcnRWYWxpZGF0ZUZvciggJ2FjY3J1YWwnICkgKSB7XG5cblx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fTtcblxuXHR2YXIgaW1wb3J0VmFsaWRhdGVGb3IgPSBmdW5jdGlvbigga2V5ICkge1xuXHRcdGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIGtleSwgJ2FkZCcgKSAmJlxuXHRcdFx0KCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSgga2V5LCAnZWRpdCcgKSB8fCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSgga2V5LCAnZWRpdF9jaGlsZCcgKSApICkge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9O1xuXG5cdHZhciBnZXRQZXJtaXNzaW9uU2VjdGlvbkJ5Vmlld0lkID0gZnVuY3Rpb24oIHZpZXdJZCApIHtcblxuXHRcdHZhciBwZXJtaXNzaW9uX3NlY3Rpb24gPSAnJztcblxuXHRcdHN3aXRjaCAoIHZpZXdJZCApIHtcblx0XHRcdGNhc2UgJ0FjY3VtdWxhdGVkVGltZSc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICd1c2VyX2RhdGVfdG90YWwnO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1BheW1lbnRHYXRld2F5Jzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3BheW1lbnRfZ2F0ZXdheSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnSW52b2ljZUNvbmZpZyc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdpbnZvaWNlX2NvbmZpZyc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnQXJlYVBvbGljeSc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdhcmVhX3BvbGljeSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnU2hpcHBpbmdQb2xpY3knOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAnc2hpcHBpbmdfcG9saWN5Jztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdHb3Zlcm5tZW50RG9jdW1lbnQnOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAnZ292ZXJubWVudF9kb2N1bWVudCc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnVGF4UG9saWN5Jzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3RheF9wb2xpY3knO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1Byb2R1Y3QnOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAncHJvZHVjdCc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnUmVtaXR0YW5jZVNvdXJjZUFjY291bnQnOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAncmVtaXR0YW5jZV9zb3VyY2VfYWNjb3VudCc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnUmVtaXR0YW5jZURlc3RpbmF0aW9uQWNjb3VudCc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdyZW1pdHRhbmNlX2Rlc3RpbmF0aW9uX2FjY291bnQnO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1NjaGVkdWxlU2hpZnQnOlxuXHRcdFx0Y2FzZSAnU2NoZWR1bGUnOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAnc2NoZWR1bGUnO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1RpbWVTaGVldCc6XG5cdFx0XHRjYXNlICdNYW51YWxUaW1lU2hlZXQnOlxuXHRcdFx0Y2FzZSAnVXNlckRhdGVUb3RhbFBhcmVudCc6XG5cdFx0XHRjYXNlICdVc2VyRGF0ZVRvdGFsJzpcblx0XHRcdGNhc2UgJ0luT3V0Jzpcblx0XHRcdGNhc2UgJ1B1bmNoZXMnOlxuXHRcdFx0Y2FzZSAnVGltZVNoZWV0QXV0aG9yaXphdGlvbic6XG5cdFx0XHRjYXNlICdFeGNlcHRpb24nOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAncHVuY2gnO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0FjY3J1YWxCYWxhbmNlJzpcblx0XHRcdGNhc2UgJ0FjY3J1YWwnOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAnYWNjcnVhbCc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnSm9iJzpcblx0XHRcdGNhc2UgJ0pvYkdyb3VwJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ2pvYic7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnUHVuY2hUYWcnOlxuXHRcdFx0Y2FzZSAnUHVuY2hUYWdHcm91cCc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdwdW5jaF90YWcnO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1BvbGljeUdyb3VwJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3BvbGljeV9ncm91cCc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnUGF5Q29kZSc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdwYXlfY29kZSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnUGF5Rm9ybXVsYVBvbGljeSc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdwYXlfZm9ybXVsYV9wb2xpY3knO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0NvbnRyaWJ1dGluZ1BheUNvZGVQb2xpY3knOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAnY29udHJpYnV0aW5nX3BheV9jb2RlX3BvbGljeSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnQ29udHJpYnV0aW5nU2hpZnRQb2xpY3knOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAnY29udHJpYnV0aW5nX3NoaWZ0X3BvbGljeSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnQWJzZW5jZVBvbGljeSc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdhYnNlbmNlX3BvbGljeSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnTWVhbFBvbGljeSc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdtZWFsX3BvbGljeSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnRXhwZW5zZVBvbGljeSc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdleHBlbnNlX3BvbGljeSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnQnJlYWtQb2xpY3knOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAnYnJlYWtfcG9saWN5Jztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdIb2xpZGF5UG9saWN5Jzpcblx0XHRcdGNhc2UgJ1JlY3VycmluZ0hvbGlkYXknOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAnaG9saWRheV9wb2xpY3knO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1ByZW1pdW1Qb2xpY3knOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAncHJlbWl1bV9wb2xpY3knO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1JlZ3VsYXJUaW1lUG9saWN5Jzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3JlZ3VsYXJfdGltZV9wb2xpY3knO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ092ZXJ0aW1lUG9saWN5Jzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ292ZXJfdGltZV9wb2xpY3knO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1JvdW5kSW50ZXJ2YWxQb2xpY3knOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAncm91bmRfcG9saWN5Jztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdFbXBsb3llZSc6XG5cdFx0XHRjYXNlICdMb2dpblVzZXJDb250YWN0Jzpcblx0XHRcdGNhc2UgJ0NoYW5nZVBhc3N3b3JkJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3VzZXInO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1VzZXJEZWZhdWx0Jzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3VzZXJfZGVmYXVsdCc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnVXNlclRpdGxlJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3VzZXJfdGl0bGUnO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1VzZXJHcm91cCc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICd1c2VyX2dyb3VwJztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdFdGhuaWNHcm91cCc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdldGhuaWNfZ3JvdXAnO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0xlZ2FsRW50aXR5Jzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ2xlZ2FsX2VudGl0eSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnUGF5cm9sbFJlbWl0dGFuY2VBZ2VuY3knOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAncGF5cm9sbF9yZW1pdHRhbmNlX2FnZW5jeSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnTWVzc2FnZUNvbnRyb2wnOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAnbWVzc2FnZSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnTm90aWZpY2F0aW9uJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ25vdGlmaWNhdGlvbic7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnV2FnZSc6XG5cdFx0XHRjYXNlICdXYWdlR3JvdXAnOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAnd2FnZSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnVXNlckNvbnRhY3QnOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAndXNlcl9jb250YWN0Jztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdMb2dpblVzZXJFeHBlbnNlJzpcblx0XHRcdGNhc2UgJ1VzZXJFeHBlbnNlJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3VzZXJfZXhwZW5zZSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnVXNlclNraWxsJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3VzZXJfc2tpbGwnO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0pvYkFwcGxpY2F0aW9uJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ2pvYl9hcHBsaWNhdGlvbic7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnSm9iQXBwbGljYW50Jzpcblx0XHRcdGNhc2UgJ1JlY3J1aXRtZW50UG9ydGFsQ29uZmlnJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ2pvYl9hcHBsaWNhbnQnO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1VzZXJMaWNlbnNlJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3VzZXJfbGljZW5zZSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnVXNlck1lbWJlcnNoaXAnOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAndXNlcl9tZW1iZXJzaGlwJztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdVc2VyRWR1Y2F0aW9uJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3VzZXJfZWR1Y2F0aW9uJztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdVc2VyUHJlZmVyZW5jZSc6XG5cdFx0XHRjYXNlICdMb2dpblVzZXJQcmVmZXJlbmNlJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3VzZXJfcHJlZmVyZW5jZSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnVXNlckxhbmd1YWdlJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3VzZXJfbGFuZ3VhZ2UnO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0NvbXBhbnknOlxuXHRcdFx0Y2FzZSAnQ29tcGFuaWVzJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ2NvbXBhbnknO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0dFT0ZlbmNlJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ2dlb19mZW5jZSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnUXVhbGlmaWNhdGlvbic6XG5cdFx0XHRjYXNlICdRdWFsaWZpY2F0aW9uR3JvdXAnOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAncXVhbGlmaWNhdGlvbic7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnUGF5UGVyaW9kU2NoZWR1bGUnOlxuXHRcdFx0Y2FzZSAnUGF5UGVyaW9kcyc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdwYXlfcGVyaW9kX3NjaGVkdWxlJztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdQYXlTdHViQW1lbmRtZW50Jzpcblx0XHRcdGNhc2UgJ1JlY3VycmluZ1BheVN0dWJBbWVuZG1lbnQnOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAncGF5X3N0dWJfYW1lbmRtZW50Jztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdQYXlTdHViVHJhbnNhY3Rpb25TdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdGNhc2UgJ1BheVN0dWInOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAncGF5X3N0dWInO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0JyYW5jaCc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdicmFuY2gnO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0RlcGFydG1lbnQnOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAnZGVwYXJ0bWVudCc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnSGllcmFyY2h5Q29udHJvbCc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdoaWVyYXJjaHknO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1N0YXRpb24nOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAnc3RhdGlvbic7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnSm9iVmFjYW5jeSc6XG5cdFx0XHRjYXNlICdQb3J0YWxKb2JWYWNhbmN5Jzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ2pvYl92YWNhbmN5Jztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdQYXlTdHViRW50cnlBY2NvdW50Jzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3BheV9zdHViX2FjY291bnQnO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1JPRSc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdyb2UnO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0N1c3RvbUZpZWxkJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ2N1c3RvbV9maWVsZCc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnQ3VycmVuY3knOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAnY3VycmVuY3knO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1Blcm1pc3Npb25Db250cm9sJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3Blcm1pc3Npb24nO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0NvbXBhbnlUYXhEZWR1Y3Rpb24nOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAnY29tcGFueV90YXhfZGVkdWN0aW9uJztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdVc2VyVGF4RGVkdWN0aW9uJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3VzZXJfdGF4X2RlZHVjdGlvbic7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnUmVxdWVzdCc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdyZXF1ZXN0Jztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdSZXF1ZXN0QXV0aG9yaXphdGlvbic6XG5cdFx0XHRjYXNlICdFeHBlbnNlQXV0aG9yaXphdGlvbic6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdhdXRob3JpemF0aW9uJztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdEb2N1bWVudCc6XG5cdFx0XHRjYXNlICdEb2N1bWVudEdyb3VwJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ2RvY3VtZW50Jztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdTY2hlZHVsZVBvbGljeSc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdzY2hlZHVsZV9wb2xpY3knO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0FjY3J1YWxQb2xpY3lBY2NvdW50Jzpcblx0XHRcdGNhc2UgJ0FjY3J1YWxQb2xpY3knOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAnYWNjcnVhbF9wb2xpY3knO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0NsaWVudCc6XG5cdFx0XHRjYXNlICdDbGllbnRDb250YWN0Jzpcblx0XHRcdGNhc2UgJ0ludm9pY2VEaXN0cmljdCc6XG5cdFx0XHRjYXNlICdDbGllbnRQYXltZW50Jzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ2NsaWVudCc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnSW52b2ljZVRyYW5zYWN0aW9uJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3RyYW5zYWN0aW9uJztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdKb2JJdGVtR3JvdXAnOlxuXHRcdFx0Y2FzZSAnSm9iSXRlbSc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdqb2JfaXRlbSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnU2F2ZWRSZXBvcnQnOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAncmVwb3J0Jztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdSZWN1cnJpbmdTY2hlZHVsZUNvbnRyb2wnOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAncmVjdXJyaW5nX3NjaGVkdWxlJztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdSZWN1cnJpbmdTY2hlZHVsZVRlbXBsYXRlQ29udHJvbCc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdyZWN1cnJpbmdfc2NoZWR1bGVfdGVtcGxhdGUnO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0tQSSc6XG5cdFx0XHRjYXNlICdLUElHcm91cCc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdrcGknO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1VzZXJSZXZpZXdDb250cm9sJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3VzZXJfcmV2aWV3Jztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdFeGNlcHRpb25Qb2xpY3lDb250cm9sJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ2V4Y2VwdGlvbl9wb2xpY3knO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0ltcG9ydENTVic6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdpbXBvcnRfY3N2Jztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdJbnZvaWNlJzpcblx0XHRcdGNhc2UgJ0pvYkludm9pY2UnOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAnaW52b2ljZSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdH1cblxuXHRcdHJldHVybiBwZXJtaXNzaW9uX3NlY3Rpb247XG5cdH07XG5cblx0dmFyIGdldFBlcm1pc3Npb25EYXRhID0gZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIExvY2FsQ2FjaGVEYXRhLmdldFBlcm1pc3Npb25EYXRhKCk7XG5cdH07XG5cblx0cmV0dXJuIHtcblx0XHRjaGVja1RvcExldmVsUGVybWlzc2lvbjogY2hlY2tUb3BMZXZlbFBlcm1pc3Npb24sXG5cdFx0dmFsaWRhdGU6IHZhbGlkYXRlLFxuXHRcdGdldFBlcm1pc3Npb25MZXZlbDogZ2V0UGVybWlzc2lvbkxldmVsLFxuXHRcdGdldFBlcm1pc3Npb25EYXRhOiBnZXRQZXJtaXNzaW9uRGF0YSxcblx0XHRIZWxwTWVudVZhbGlkYXRlQWRtaW46IEhlbHBNZW51VmFsaWRhdGVBZG1pbixcblx0XHRIZWxwTWVudVZhbGlkYXRlU3VwZXJ2aXNvcjogSGVscE1lbnVWYWxpZGF0ZVN1cGVydmlzb3IsXG5cdFx0aW1wb3J0VmFsaWRhdGU6IGltcG9ydFZhbGlkYXRlLFxuXHRcdHN1YkpvYkFwcGxpY2F0aW9uVmFsaWRhdGU6IHN1YkpvYkFwcGxpY2F0aW9uVmFsaWRhdGVcblx0fTtcblxufSApKCk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///8843\n")},587:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval("/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"k\": () => (/* binding */ ProgressBar)\n/* harmony export */ });\n/* harmony import */ var _services_TimeTrexClientAPI__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7526);\n/* harmony import */ var nanobar__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4893);\n/* harmony import */ var nanobar__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(nanobar__WEBPACK_IMPORTED_MODULE_1__);\n/* provided dependency */ var $ = __webpack_require__(9755);\n\n // need to rely on the default export via CommonJS syntax, hence no named import.\n\nvar ProgressBar = ( function() {\n\n\tvar loading_box = null;\n\t\n\tvar layout_content = null;\n\n\tvar left_offset = 0;\n\n\tvar process_number = false;\n\n\tvar can_close = false;\n\n\tvar timer = null;\n\n\tvar close_time = null;\n\n\tvar circle = null;\n\n\tvar doing_close = false;\n\n\tvar message_id_dic = {};\n\n\tvar updating_message_id = false;\n\n\tvar current_process_id = false;\n\n\tvar _progress_bar_api = false;\n\n\tvar get_progress_timer = null;\n\n\tvar first_start_get_progress_timer = false;\n\n\tvar start_progress_timer = false;\n\n\tvar auto_clear_message_id_dic = {}; //for which api calls don't have return; for example all report view calls\n\n\tvar last_iteration = null;\n\n\tvar temp_message_until_close = '';\n\n\tvar second_timer;\n\n\tvar time_offset;\n\n\tvar nanoBar;\n\n\tvar loading_bar_time;\n\n\tvar no_progress_for_next_call = false;\n\n\tvar showOverlay = function() {\n\t\tGlobal.overlay().addClass( 'overlay' );\n\t\tGlobal.setUINotready();\n\t\tTTPromise.add( 'ProgressBar', 'overlay_visible' );\n\t};\n\n\tvar closeOverlay = function() {\n\t\t//this variable is set in BaseViewController::onContextMenuClick\n\t\tif ( window.clickProcessing == true ) {\n\t\t\twindow.clickProcessing = false;\n\t\t\twindow.clearTimeout( window.clickProcessingHandle );\n\t\t}\n\t\tGlobal.overlay().removeClass( 'overlay' );\n\t\tGlobal.setUIReady();\n\t\tTTPromise.resolve( 'ProgressBar', 'overlay_visible' );\n\t};\n\n\tvar cancelProgressBar = function() {\n\t\tif ( get_progress_timer ) {\n\t\t\tclearInterval( get_progress_timer );\n\t\t\tget_progress_timer = false;\n\t\t}\n\t\tremoveProgressBar( current_process_id );\n\t\tget_progress_timer = false;\n\t\tcurrent_process_id = false;\n\t\tlast_iteration = null;\n\t\tfirst_start_get_progress_timer = false;\n\t};\n\n\tvar showProgressBar = function( message_id, auto_clear, instant ) {\n\n\t\tTTPromise.add( 'ProgressBar', 'MASTER' );\n\t\tif ( no_progress_for_next_call ) {\n\t\t\tno_progress_for_next_call = false;\n\t\t\treturn;\n\t\t}\n\t\tif ( instant ) {\n\t\t\tif ( process_number > 0 && loading_box ) {\n\t\t\t\tloading_box.css( 'display', 'block' );\n\t\t\t}\n\t\t} else {\n\t\t\tif ( !timer ) {\n//\t\t\tclearTimeout( timer );\n\t\t\t\t//Display progress bar after 1 sec\n\t\t\t\ttimer = setTimeout( function() {\n\t\t\t\t\tif ( process_number > 0 && loading_box ) {\n\t\t\t\t\t\tloading_box.css( 'display', 'block' );\n\t\t\t\t\t}\n\n\t\t\t\t}, 1000 );\n\t\t\t}\n\t\t}\n\n\t\tif ( message_id ) {\n\t\t\tmessage_id_dic[message_id] = true;\n\n\t\t\tif ( auto_clear ) {\n\t\t\t\tauto_clear_message_id_dic[message_id] = true;\n\t\t\t}\n\n\t\t}\n\n\t\tif ( message_id && start_progress_timer === false ) {\n\t\t\tstart_progress_timer = setInterval( function() {\n\t\t\t\tgetProgressBarProcess();\n\t\t\t}, 3000 );\n\t\t\tfirst_start_get_progress_timer = true;\n\t\t}\n\n\t\tif ( process_number > 0 ) { //has multi call or the last call is not removed yet\n\t\t\tprocess_number = process_number + 1;\n\t\t\treturn;\n\t\t}\n\n\t\tprocess_number = 1;\n\n\t\tGlobal.addCss( 'global/widgets/loading_bar/LoadingBox.css' );\n\n\t\tclearTimeout( close_time );\n\t\tvar message_label;\n\n\t\tif ( !loading_box ) {\n\t\t\tvar loadingBoxWidget = `\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\tx\n\t\t\t\t\t\n\t\t\t\t\t
100 / 5000 - 15% Complete
\n\t\t\t\t\t
11:11
\n\t\t\t\t
\n\t\t\t`;\n\n\t\t\tvar loadngBox = $( loadingBoxWidget ).attr( 'id', 'progressBar' );\n\n\t\t\tvar close_icon = loadngBox.find( '.close-icon' );\n\n\t\t\tclose_icon.unbind( 'click' ).click( function() {\n\t\t\t\tcancelProgressBar();\n\n\t\t\t} );\n\t\t\t// css only spinner - and yes, it does unfortunately need all those divs. They are for each of the spokes of the circle.\n\t\t\tcircle = $( '
' );\n\t\t\t\t\t\t\tli.append( child_val[child_key] );\n\t\t\t\t\t\t\tul_container.append( li );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( !has_child ) {\n\t\t\t\t\t\tli.append( val[key] );\n\t\t\t\t\t\tul_container.append( li );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t\tvar div = $( '
' );\n\t\tvar p = $( '
' );\n\t\tp.append( $.i18n._( 'Are you sure you wish to save this record without correcting the above warnings?' ) );\n\t\tdiv.append( ul_container );\n\t\tdiv.append( p );\n\t\tshowConfirmAlert( div[0], 'Warning', callBack, 'Save', 'Cancel' );\n\t};\n\n\tvar showAlert = function( content, title, callBack ) {\n\t\tif ( !title ) {\n\t\t\ttitle = $.i18n._( 'Message' );\n\t\t}\n\n\t\tvar result = $( '
' )\n\n\t\tif ( width ) {\n\t\t\tresult.css( 'width', width );\n\t\t}\n\n\t\tview = result;\n\t\t$( 'body' ).append( result );\n\n\t\tif ( form_type === 'dropdown' ) {\n\t\t\tvar form_item_input = Global.loadWidgetByName( FormItemType.COMBO_BOX );\n\t\t\tform_item_input.TComboBox();\n\t\t\tform_item_input.setSourceData( form_data );\n\n\t\t\tresult.find( '#yesBtn' ).bind( 'click', function() {\n\t\t\t\tremove();\n\t\t\t\tcallBackFunction( result.find( 'select' ).val() );\n\t\t\t} );\n\t\t} else if ( form_type === 'password' ) {\n\t\t\tform_item_input = Global.loadWidgetByName( FormItemType.PASSWORD_INPUT );\n\t\t\tform_item_input.TPasswordInput();\n\n\t\t\tresult.find( '#yesBtn' ).bind( 'click', function() {\n\t\t\t\tremove();\n\t\t\t\tcallBackFunction( result.find( '[type=password]' ).val() );\n\t\t\t} );\n\t\t} else if ( form_type === 'text' ) {\n\t\t\tform_item_input = Global.loadWidgetByName( FormItemType.TEXT_INPUT );\n\t\t\tform_item_input.TTextInput();\n\t\t\tform_item_input.setValue( form_data );\n\n\t\t\tif ( width ) {\n\t\t\t\tform_item_input.width( ( width - 20 ) );\n\t\t\t}\n\n\t\t\tshow_cancel_button = false;\n\n\t\t\tresult.find( '#yesBtn' ).bind( 'click', function() {\n\t\t\t\tremove();\n\t\t\t} );\n\t\t} else if ( form_type === 'word_match' ) {\n\t\t\tform_item_input = Global.loadWidgetByName( FormItemType.TEXT_INPUT );\n\t\t\tform_item_input.TTextInput();\n\n\t\t\tresult.find( '#yesBtn' ).bind( 'click', function() {\n\t\t\t\tif ( result.find( '[type=text]' ).val() === form_data ) {\n\t\t\t\t\tremove();\n\t\t\t\t\tcallBackFunction( true );\n\t\t\t\t} else {\n\t\t\t\t\tcallBackFunction( false );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\tresult.find( '#form-holder' ).append( form_item_input );\n\n\t\tresult.find( '#noBtn' ).bind( 'click', function() {\n\t\t\tremove();\n\t\t\tcallBackFunction( false );\n\t\t} );\n\n\t\tresult.find( '#yesBtn' ).text( continue_label );\n\t\tresult.find( '#noBtn' ).text( cancel_label );\n\n\t\tresult.find( '.title' ).text( title );\n\t\tresult.find( '.content' ).html( content );\n\n\t\tif ( show_continue_button == false ) {\n\t\t\tresult.find( '#yesBtn' ).hide();\n\t\t}\n\n\t\tif ( show_cancel_button == false ) {\n\t\t\tresult.find( '#noBtn' ).hide();\n\t\t}\n\n\t\tGlobal.setUIInitComplete();\n\t};\n\n\n\tvar showModalAlert = function( category, step, callBackFunction, img_src ) {\n\t\tlet top_image = '';\n\t\tlet title = '';\n\t\tlet content = '';\n\t\tlet additional_body_style = '';\n\t\tlet button_label = $.i18n._( 'Yes' );\n\t\tlet button_color = '#228b22';\n\n\t\tif ( category === 'push_notification' ) {\n\t\t\ttop_image = '';\n\t\t\ttitle = $.i18n._( 'Turn on Notifications' );\n\n\t\t\tswitch ( step ) {\n\t\t\t\tcase 'ask':\n\t\t\t\t\tbutton_label = $.i18n._( 'Yes, turn on notifications!' );\n\t\t\t\t\tcontent = LocalCacheData.getCurrentCompany().name + ' ' + $.i18n._( 'wants permission to notify you of important messages or alerts related to your employment. You can change your notification settings at anytime.' );\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'wait_for_permission':\n\t\t\t\t\tbutton_label = $.i18n._( 'I don\\'t see it?' );\n\t\t\t\t\tbutton_color = '#AE0000';\n\t\t\t\t\t// Some browsers by default block push notification permission we need to detect them to show user a different prompt.\n\t\t\t\t\tif ( NotificationConsumer.detectBrowserNeedsExtraPermission() === true || Notification.permission === 'denied' ) {\n\t\t\t\t\t\t// User needs to enable push notifications on the browser.\n\t\t\t\t\t\tcontent = $.i18n._( 'A popup should appear on your screen, click \"ALLOW\" to enable notifications. If you don\\'t see it, you may need to enable notifications in your browser settings.' );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcontent = $.i18n._( 'A popup should appear on your screen, click \"ALLOW\" to enable notifications.' );\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'help_text':\n\t\t\t\t\tbutton_label = $.i18n._( 'Ok, done!' );\n\t\t\t\t\tif ( Global.getBrowserVendor() === 'Edge' ) {\n\t\t\t\t\t\tcontent = $.i18n._( '1. Click the icon to the left of the address (URL) bar to view settings. ' +\n\t\t\t\t\t\t\t'2. Click \"Permissions for this Site\" ' +\n\t\t\t\t\t\t\t'3. To the right of \"Notifications\" set the option to \"ALLOW\".' );\n\t\t\t\t\t} else if ( Global.getBrowserVendor() === 'Firefox' ) {\n\t\t\t\t\t\tcontent = $.i18n._( '1. Click the icon to the left of the address (URL) bar to view settings. ' +\n\t\t\t\t\t\t\t'2. Click the \"X\" next Notifications to remove blocked permissions and then refresh the browser. ' );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcontent = $.i18n._( '1. Click the icon to the left of the address (URL) bar to view settings. ' +\n\t\t\t\t\t\t\t'2. Click \"Site settings\" ' +\n\t\t\t\t\t\t\t'3. To the right of \"Notifications\" set the option to \"ALLOW\".' );\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t} else if ( category === 'multifactor_authentication' ) {\n\t\t\ttitle = $.i18n._( 'Multifactor Authentication Instructions' );\n\n\t\t\tswitch ( step ) {\n\t\t\t\tcase 'download_instructions':\n\t\t\t\t\tbutton_label = $.i18n._( 'Ok' );\n\t\t\t\t\tbutton_color = '#426d9d';\n\t\t\t\t\tadditional_body_style = 'style=\"display: block; padding-left: 2rem; padding-right: 2rem; font-size: 1.1rem;\"';\n\n\t\t\t\t\tcontent = ' ';\n\t\t\t\t\tcontent += '1.' + $.i18n._( 'Please download the TimeTrex app from the App Store on your device.' ) + '
';\n\t\t\t\t\tcontent += '2.' + $.i18n._( ' Once installed, on the first step of the \"Setup Wizard\", tap the \"QR Code\" icon at the bottom right to scan the below QR Code.' ) + ' ';\n\t\t\t\t\tcontent += '';\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tGlobal.setUINotready();\n\n\t\tvar result = $( '
`,\n\t\ttab_bar: ``\n\t};\n\n} )( jQuery );//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODI4Ny5qcyIsIm1hcHBpbmdzIjoiO0FBQUE7O0FBRUE7QUFDQSx5QkFBeUI7O0FBRXpCOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLElBQUk7O0FBRUo7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUEsZ0NBQWdDOztBQUVoQyxJQUFJOztBQUVKOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxFQUFFLEdBQUcsTUFBTSIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL2ludGVyZmFjZS9odG1sNS9nbG9iYWwvd2lkZ2V0cy92aWV3X21pbl90YWIvVmlld01pblRhYkJhci5qcz9mODI5Il0sInNvdXJjZXNDb250ZW50IjpbIiggZnVuY3Rpb24oICQgKSB7XG5cblx0JC5mbi5WaWV3TWluVGFiQmFyID0gZnVuY3Rpb24oIG9wdGlvbnMgKSB7XG5cdFx0dmFyIG9wdHMgPSAkLmV4dGVuZCgge30sICQuZm4uVmlld01pblRhYkJhci5kZWZhdWx0cywgb3B0aW9ucyApO1xuXG5cdFx0dmFyICR0aGlzID0gdGhpcztcblxuXHRcdEdsb2JhbC5hZGRDc3MoICdnbG9iYWwvd2lkZ2V0cy92aWV3X21pbl90YWIvVmlld01pblRhYi5jc3MnICk7XG5cblx0XHR2YXIgY3JlYXRlVGFiID0gZnVuY3Rpb24oIHZpZXdfaWQsIHZpZXdfbGFiZWwsIHVybCApIHtcblx0XHRcdHZhciB0YWIgPSAkKCBHbG9iYWwubG9hZFdpZGdldEJ5TmFtZSggV2lkZ2V0TmFtZXNEaWMuVklFV19NSU5fVEFCICkgKTtcblx0XHRcdHZhciB2aWV3X25hbWUgPSB0YWIuZmluZCggJy52aWV3LW5hbWUnICk7XG5cdFx0XHR2aWV3X25hbWUudGV4dCggdmlld19sYWJlbCApO1xuXHRcdFx0dGFiLmF0dHIoICdpZCcsICdtaW5fdGFiXycgKyB2aWV3X2lkICk7XG5cblx0XHRcdHRhYi5hdHRyKCAndmlld191cmwnLCB1cmwgKTtcblxuXHRcdFx0c2V0VGltZW91dCggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHRhYi5hZGRDbGFzcyggJ3Nob3cnICk7XG5cdFx0XHR9LCAxMDAgKTtcblxuXHRcdFx0dmFyIGNsb3NlX2J0biA9IHRhYi5maW5kKCAnLmNsb3NlLWJ0bicgKTtcblxuXHRcdFx0dGFiLnVuYmluZCggJ2NsaWNrJyApLmNsaWNrKCBmdW5jdGlvbigpIHtcblx0XHRcdFx0R2xvYmFsLnNldFVJTm90cmVhZHkoKTtcblx0XHRcdFx0dmFyIHZpZXdfaWQgPSAkKCB0aGlzICkuYXR0ciggJ2lkJyApLnJlcGxhY2UoICdtaW5fdGFiXycsICcnICk7XG5cdFx0XHRcdHZhciB1cmwgPSAkKCB0aGlzICkuYXR0ciggJ3ZpZXdfdXJsJyApO1xuXHRcdFx0XHRHbG9iYWwucmVtb3ZlVmlld1RhYiggdmlld19pZCApO1xuXG5cdFx0XHRcdHN3aXRjaCAoIHZpZXdfaWQgKSB7XG5cdFx0XHRcdFx0Y2FzZSAnUHJvY2Vzc1BheXJvbGxXaXphcmQnOlxuXHRcdFx0XHRcdFx0SW5kZXhWaWV3Q29udHJvbGxlci5vcGVuV2l6YXJkKCB2aWV3X2lkICk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICdQYXlyb2xsUmVtaXR0YW5jZUFnZW5jeUV2ZW50V2l6YXJkQ29udHJvbGxlcic6XG5cdFx0XHRcdFx0XHRJbmRleFZpZXdDb250cm9sbGVyLm9wZW5XaXphcmRDb250cm9sbGVyKCAnUGF5cm9sbFJlbWl0dGFuY2VBZ2VuY3lFdmVudFdpemFyZENvbnRyb2xsZXInICk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRkZWZhdWx0OlxuLy9cdFx0XHRcdFx0XHRJbmRleFZpZXdDb250cm9sbGVyLmdvVG9WaWV3KCB2aWV3X2lkICk7XG5cdFx0XHRcdFx0XHRHbG9iYWwuc2V0VVJMVG9Ccm93c2VyKCB1cmwgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHR9ICk7XG5cblx0XHRcdGNsb3NlX2J0bi51bmJpbmQoICdjbGljaycgKS5jbGljayggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHZhciB2aWV3X2lkID0gJCggdGhpcyApLnBhcmVudCgpLmF0dHIoICdpZCcgKS5yZXBsYWNlKCAnbWluX3RhYl8nLCAnJyApO1xuXHRcdFx0XHRHbG9iYWwucmVtb3ZlVmlld1RhYiggdmlld19pZCApO1xuXHRcdFx0fSApO1xuXG5cdFx0XHQkdGhpcy5hcHBlbmQoIHRhYiApO1xuXHRcdH07XG5cblx0XHR0aGlzLmJ1aWxkVGFicyA9IGZ1bmN0aW9uKCB0YWJfbWFwICkge1xuXG5cdFx0XHQvLyR0aGlzLmVtcHR5KCk7XG5cdFx0XHR2YXIgaSA9IDA7XG5cdFx0XHRmb3IgKCB2YXIga2V5IGluIHRhYl9tYXAgKSB7XG5cdFx0XHRcdGlmICggdGFiX21hcC5oYXNPd25Qcm9wZXJ0eSgga2V5ICkgJiYga2V5LmluZGV4T2YoICdfdXJsJyApID09PSAtMSApIHtcblx0XHRcdFx0XHR2YXIgdmlld19pZCA9IGtleTtcblx0XHRcdFx0XHR2YXIgdmlld19sYWJlbCA9IHRhYl9tYXBba2V5XTtcblx0XHRcdFx0XHR2YXIgdmlld191cmwgPSB0YWJfbWFwW2tleSArICdfdXJsJ107XG5cdFx0XHRcdFx0aWYgKCAkKCAnI21pbl90YWJfJyArIHZpZXdfaWQgKS5sZW5ndGggPT09IDAgKSB7XG5cdFx0XHRcdFx0XHRjcmVhdGVUYWIoIHZpZXdfaWQsIHZpZXdfbGFiZWwsIHZpZXdfdXJsICk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH1cblx0XHRcdFx0aSA9IGkgKyAxO1xuXG5cdFx0XHR9XG5cblx0XHR9O1xuXG5cdFx0dGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblxuXHRcdFx0dmFyIG8gPSAkLm1ldGEgPyAkLmV4dGVuZCgge30sIG9wdHMsICQoIHRoaXMgKS5kYXRhKCkgKSA6IG9wdHM7XG5cblx0XHR9ICk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9O1xuXG5cdCQuZm4uVmlld01pblRhYkJhci5kZWZhdWx0cyA9IHt9O1xuXHQkLmZuLlZpZXdNaW5UYWJCYXIuaHRtbCA9IHtcblx0XHR0YWI6IGBcblx0XHQ8ZGl2IGNsYXNzPVwicC1idXR0b24gcC1jb21wb25lbnQgdmlldy1taW4tdGFiIGFuaW1hdGVkXCI+XG5cdFx0XHQ8c3BhbiBjbGFzcz1cInZpZXctbmFtZVwiPjwvc3Bhbj5cblx0XHRcdDxzcGFuIGNsYXNzPVwidHRpY29uIHR0aWNvbi1jYW5jZWxfYmxhY2tfMjRkcCBjbG9zZS1idG5cIj48L3NwYW4+XG5cdFx0PC9kaXY+YCxcblx0XHR0YWJfYmFyOiBgPGRpdiBjbGFzcz1cInZpZXctbWluLXRhYi1iYXJcIj48L2Rpdj5gXG5cdH07XG5cbn0gKSggalF1ZXJ5ICk7Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8287\n")},9769:(g,t,I)=>{var n={"./awesomebox/AComboBox":[2897,7,"awesomebox-AComboBox"],"./awesomebox/AComboBox.js":[2897,7,"awesomebox-AComboBox"],"./awesomebox/ADropDown":[3234,7,"awesomebox-ADropDown"],"./awesomebox/ADropDown.js":[3234,7,"awesomebox-ADropDown"],"./awesomebox/ALayoutCache":[4243,9,"awesomebox-ALayoutCache"],"./awesomebox/ALayoutCache.js":[4243,9,"awesomebox-ALayoutCache"],"./awesomebox/ASearchInput":[7040,7,"awesomebox-ASearchInput"],"./awesomebox/ASearchInput.js":[7040,7,"awesomebox-ASearchInput"],"./checkbox/TCheckbox":[5529,7,"checkbox-TCheckbox"],"./checkbox/TCheckbox.js":[5529,7,"checkbox-TCheckbox"],"./color-picker/TColorPicker":[3161,9,"color-picker-TColorPicker"],"./color-picker/TColorPicker.js":[3161,9,"color-picker-TColorPicker"],"./column_editor/ColumnEditor":[9613,7,"column_editor-ColumnEditor"],"./column_editor/ColumnEditor.js":[9613,7,"column_editor-ColumnEditor"],"./combobox/TComboBox":[5519,7,"combobox-TComboBox"],"./combobox/TComboBox.js":[5519,7,"combobox-TComboBox"],"./datepicker/TDatePicker":[84,7,"datepicker-TDatePicker"],"./datepicker/TDatePicker.js":[84,7,"datepicker-TDatePicker"],"./datepicker/TRangePicker":[9300,7,"datepicker-TRangePicker"],"./datepicker/TRangePicker.js":[9300,7,"datepicker-TRangePicker"],"./error_tip/ErrorTipBox":[9876,7,"error_tip-ErrorTipBox"],"./error_tip/ErrorTipBox.js":[9876,7,"error_tip-ErrorTipBox"],"./feedback/TFeedback":[8218,7,"feedback-TFeedback"],"./feedback/TFeedback.js":[8218,7,"feedback-TFeedback"],"./filebrowser/CameraBrowser":[8128,7,"filebrowser-CameraBrowser"],"./filebrowser/CameraBrowser.js":[8128,7,"filebrowser-CameraBrowser"],"./filebrowser/TImage":[1469,7,"filebrowser-TImage"],"./filebrowser/TImage.js":[1469,7,"filebrowser-TImage"],"./filebrowser/TImageAdvBrowser":[8243,7,"filebrowser-TImageAdvBrowser"],"./filebrowser/TImageAdvBrowser.js":[8243,7,"filebrowser-TImageAdvBrowser"],"./filebrowser/TImageBrowser":[8326,7,"filebrowser-TImageBrowser"],"./filebrowser/TImageBrowser.js":[8326,7,"filebrowser-TImageBrowser"],"./filebrowser/TImageCutArea":[8453,7,"filebrowser-TImageCutArea"],"./filebrowser/TImageCutArea.js":[8453,7,"filebrowser-TImageCutArea"],"./formula_builder/FormulaBuilder":[9326,7,"formula_builder-FormulaBuilder"],"./formula_builder/FormulaBuilder.js":[9326,7,"formula_builder-FormulaBuilder"],"./inside_editor/InsideEditor":[1745,7,"inside_editor-InsideEditor"],"./inside_editor/InsideEditor.js":[1745,7,"inside_editor-InsideEditor"],"./jqgrid/TGridHeader":[754,7,"jqgrid-TGridHeader"],"./jqgrid/TGridHeader.js":[754,7,"jqgrid-TGridHeader"],"./list/TList":[802,7,"list-TList"],"./list/TList.js":[802,7,"list-TList"],"./live-chat/live-chat":[155,9,"live-chat"],"./live-chat/live-chat.js":[155,9,"live-chat"],"./message_box/NoHierarchyBox":[9110,7,"message_box-NoHierarchyBox"],"./message_box/NoHierarchyBox.js":[9110,7,"message_box-NoHierarchyBox"],"./message_box/NoResultBox":[4938,7,"message_box-NoResultBox"],"./message_box/NoResultBox.js":[4938,7,"message_box-NoResultBox"],"./message_box/SaveAndContinueBox":[350,7,"message_box-SaveAndContinueBox"],"./message_box/SaveAndContinueBox.js":[350,7,"message_box-SaveAndContinueBox"],"./paging/Paging2":[5583,7,"paging-Paging2"],"./paging/Paging2.js":[5583,7,"paging-Paging2"],"./search_panel/FormItemType":[2548,9],"./search_panel/FormItemType.js":[2548,9],"./search_panel/SearchPanel":[4057,7,"search_panel-SearchPanel"],"./search_panel/SearchPanel.js":[4057,7,"search_panel-SearchPanel"],"./separated_box/SeparatedBox":[7316,7,"separated_box-SeparatedBox"],"./separated_box/SeparatedBox.js":[7316,7,"separated_box-SeparatedBox"],"./switch_button/SwitchButton":[6618,9,"switch_button-SwitchButton"],"./switch_button/SwitchButton.js":[6618,9,"switch_button-SwitchButton"],"./tag_input/TTagInput":[4466,7,"tag_input-TTagInput"],"./tag_input/TTagInput.js":[4466,7,"tag_input-TTagInput"],"./text/TText":[7011,7,"text-TText"],"./text/TText.js":[7011,7,"text-TText"],"./text_input/TPasswordInput":[3133,7,"text_input-TPasswordInput"],"./text_input/TPasswordInput.js":[3133,7,"text_input-TPasswordInput"],"./text_input/TTextInput":[9264,7,"text_input-TTextInput"],"./text_input/TTextInput.js":[9264,7,"text_input-TTextInput"],"./textarea/TTextArea":[8917,7,"textarea-TTextArea"],"./textarea/TTextArea.js":[8917,7,"textarea-TTextArea"],"./timepicker/TTimePicker":[9680,7,"timepicker-TTimePicker"],"./timepicker/TTimePicker.js":[9680,7,"timepicker-TTimePicker"],"./toggle_button/TToggleButton":[5110,7,"toggle_button-TToggleButton"],"./toggle_button/TToggleButton.js":[5110,7,"toggle_button-TToggleButton"],"./ttgrid/TTGrid":[2185,7,"ttgrid-TTGrid"],"./ttgrid/TTGrid.js":[2185,7,"ttgrid-TTGrid"],"./view_min_tab/ViewMinTabBar":[8287,7],"./view_min_tab/ViewMinTabBar.js":[8287,7],"./wizard/Wizard":[3207,9,"wizard-Wizard"],"./wizard/Wizard.js":[3207,9,"wizard-Wizard"],"./wizard/WizardStep":[8880,9,"wizard-WizardStep"],"./wizard/WizardStep.js":[8880,9,"wizard-WizardStep"]};function c(g){if(!I.o(n,g))return Promise.resolve().then((()=>{var t=new Error("Cannot find module '"+g+"'");throw t.code="MODULE_NOT_FOUND",t}));var t=n[g],c=t[0];return Promise.all(t.slice(2).map(I.e)).then((()=>I.t(c,16|t[1])))}c.keys=()=>Object.keys(n),c.id=9769,g.exports=c},3751:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "X": () => (/* binding */ Base)\n/* harmony export */ });\n/* provided dependency */ var _ = __webpack_require__(9050);\nclass Base extends Backbone.Model {\n\n\tconstructor( options = {} ) {\n\t\t_.defaults( options, {\n\t\t} );\n\n\t\tsuper( options );\n\t}\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzc1MS5qcyIsIm1hcHBpbmdzIjoiOzs7O0FBQU87O0FBRVAsMkJBQTJCO0FBQzNCLEVBQUUsQ0FBQztBQUNILElBQUk7O0FBRUo7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vaW50ZXJmYWNlL2h0bWw1L21vZGVsL0Jhc2UuanM/NDQzMSJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY2xhc3MgQmFzZSBleHRlbmRzIEJhY2tib25lLk1vZGVsIHtcblxuXHRjb25zdHJ1Y3Rvciggb3B0aW9ucyA9IHt9ICkge1xuXHRcdF8uZGVmYXVsdHMoIG9wdGlvbnMsIHtcblx0XHR9ICk7XG5cblx0XHRzdXBlciggb3B0aW9ucyApO1xuXHR9XG59XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3751\n')},7194:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval("/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"g\": () => (/* binding */ IndexViewController)\n/* harmony export */ });\n/* unused harmony export ApplicationRouter */\n/* harmony import */ var _views_quick_punch_header_HeaderViewController__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5196);\n/* provided dependency */ var _ = __webpack_require__(9050);\n/* provided dependency */ var $ = __webpack_require__(9755);\n\n\nclass ApplicationRouter extends Backbone.Router {\n\tconstructor( options = {} ) {\n\t\t_.defaults( options, {\n\t\t\tcontroller: null,\n\t\t\theaderView: null,\n\t\t\troutes: {\n\t\t\t\t'': 'onViewChange',\n\t\t\t\t'!:viewName': 'onViewChange',\n\t\t\t\t'*notFound': 'notFound'\n\t\t\t}\n\t\t} );\n\n\t\tsuper( options );\n\t}\n\n\tloadView( view_id ) {\n\t\tGlobal.loadViewSource( view_id, view_id + 'View.html', function( result ) {\n\t\t\tvar template = _.template( result );\n\t\t\tGlobal.contentContainer().html( template );\n\n\t\t\tLocalCacheData.current_open_view_id = view_id;\n\n\t\t\tGlobal.trackView( view_id );\n\t\t} );\n\t}\n\n\treloadView( view_id ) {\n\t\t//error: Uncaught ReferenceError: XXXXViewController is not defined ininterface/html5/#!m=TimeSheet line 3\n\t\t// Happens when quickly click on context menu and network is slow.\n\t\tif ( eval( 'typeof '+ view_id + 'ViewController' ) === 'function' ) { //Was ES5: window[view_id + 'ViewController'] &&\n\t\t\tthis.loadView( view_id );\n\t\t}\n\t}\n\n\tnotFound( url ) {\n\t\tvar new_url = Global.getBaseURL();\n\n\t\tGlobal.setURLToBrowser( new_url + '#!m=QuickPunchLogin' );\n\t}\n\n\t/* jshint ignore:start */\n\tonViewChange( viewName ) {\n\t\tvar $this = this;\n\t\tvar args = {};\n\t\tvar view_id;\n\n\t\tif ( Global.needReloadBrowser ) {\n\t\t\tGlobal.needReloadBrowser = false;\n\t\t\twindow.location.reload();\n\t\t\treturn;\n\t\t}\n\n\t\tif ( viewName ) {\n\t\t\targs = Global.buildArgDic( viewName.split( '&' ) );\n\t\t}\n\t\tif ( viewName && viewName.indexOf( 'm=' ) >= 0 && viewName.indexOf( 'QuickPunch' ) >= 0 ) {\n\t\t\tview_id = Global.sanitizeViewId( args.m );\n\t\t} else {\n\t\t\tview_id = 'QuickPunchLogin';\n\t\t\tGlobal.setURLToBrowser( Global.getBaseURL() + '#!m=QuickPunchLogin' );\n\t\t}\n\n\t\tLocalCacheData.fullUrlParameterStr = viewName;\n\n\t\tLocalCacheData.setAllURLArgs( args );\n\t\tvar reg = new RegExp( '^[0-9]*$' );\n\t\tvar timeout_count;\n\t\ttimeout_count = 0;\n\t\t// $('link[title=\"application css\"]').prop('disabled', true);\n\t\tif ( LocalCacheData.loadViewRequiredJSReady ) {\n\t\t\tshowRibbonMenuAndLoadView();\n\t\t} else {\n\t\t\tvar auto_login_timer = setInterval( function() {\n\t\t\t\tif ( timeout_count == 100 ) {\n\t\t\t\t\tclearInterval( auto_login_timer );\n\t\t\t\t}\n\t\t\t\ttimeout_count = timeout_count + 1;\n\t\t\t\tif ( LocalCacheData.loadViewRequiredJSReady ) {\n\t\t\t\t\tshowRibbonMenuAndLoadView();\n\t\t\t\t\tclearInterval( auto_login_timer );\n\t\t\t\t}\n\t\t\t}, 600 );\n\t\t}\n\n\t\tfunction showRibbonMenuAndLoadView() {\n\t\t\t$( 'body' ).removeClass( 'login-bg' );\n\t\t\t// Global.loadStyleSheet( '../theme/default/css/quickPunch.css' + '?v=' + APIGlobal.pre_login_data.application_build ); // #2844 quickpunch css will now be loaded at start.\n\t\t\tif ( !$this.headerView ) {\n\t\t\t\t$this.headerView = new _views_quick_punch_header_HeaderViewController__WEBPACK_IMPORTED_MODULE_0__.HeaderViewController();\n\t\t\t\t$( '#topContainer' ).html( $this.headerView.el );\n\t\t\t}\n\t\t\tloadViewController();\n\t\t}\n\n\t\tfunction loadViewController() {\n\t\t\tGlobal.loadViewSource( view_id, view_id + 'ViewController.js', function() {\n\t\t\t\t/* jshint ignore:start */\n\t\t\t\tvar view_controller = eval( 'new ' + view_id + 'ViewController(); ' );\n\t\t\t\tGlobal.trackView( view_id );\n\t\t\t\t/* jshint ignore:end */\n\n\t\t\t\t// Only show the top and bottom containers until after the view html is loaded, otherwise the download app links flash up at the top of the page, where the login header should be.\n\t\t\t\t// TODO: Improve this with Vue to be smoother and more structured, rather than trial and error.\n\t\t\t\tGlobal.topContainer().css( 'display', 'block' );\n\t\t\t\tGlobal.bottomContainer().css( 'display', 'block' );\n\t\t\t} );\n\t\t}\n\t}\n\n\t/* jshint ignore:end */\n\n\tcleanAnySubViewUI() {\n\t\tvar children = Global.contentContainer().children();\n\n\t\tif ( children.length > 1 ) {\n\t\t\tfor ( var i = 1; i < children.length; i++ ) {\n\t\t\t\t// Object doesn't support property or method 'remove', Not sure why, add try catch to ingore this error since this should no harm\n\t\t\t\ttry {\n\n\t\t\t\t\tif ( $( children[i] ).attr( 'id' ) === LocalCacheData.current_open_primary_controller.ui_id ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tchildren[i].remove();\n\t\t\t\t\t}\n\n\t\t\t\t} catch ( e ) {\n\t\t\t\t\t//Do nothing\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\t}\n\n\tsetContentDivHeight() {\n\t\tGlobal.contentContainer().removeClass( 'content-container' );\n\t\tGlobal.contentContainer().addClass( 'content-container-after-login' );\n\t\tGlobal.topContainer().addClass( 'top-container-after-login' );\n\n\t}\n\n\taddTopMenu() {\n\t\tGlobal.loadScript( 'global/widgets/top_menu/TopMenuController.js' );\n\t\tif ( TopMenuController ) {\n\t\t\tTopMenuController.loadView();\n\t\t}\n\n\t}\n\n\tremoveCurrentView( callBack ) {\n\t\tif ( LocalCacheData.current_open_edit_only_controller ) {\n\t\t\tclean( LocalCacheData.current_open_edit_only_controller );\n\t\t\tLocalCacheData.current_open_edit_only_controller = null;\n\t\t}\n\n\t\tif ( LocalCacheData.current_open_primary_controller ) {\n\t\t\tif ( LocalCacheData.current_open_primary_controller.edit_view ) {\n\t\t\t\tclean( LocalCacheData.current_open_primary_controller );\n\t\t\t}\n\t\t\tGlobal.contentContainer().empty();\n\t\t\tLocalCacheData.current_open_primary_controller.cleanWhenUnloadView( callBack );\n\t\t} else {\n\n\t\t\tif ( Global.isSet( callBack ) ) {\n\t\t\t\tcallBack();\n\t\t\t}\n\t\t}\n\n\t\tfunction clean( viewController ) {\n\t\t\tviewController.clearErrorTips();\n\t\t\t// Cannot read property 'remove' of null in interface/html5/IndexController.js?v=9.0.0-20151016-153057 line 439\n\t\t\tif ( viewController.edit_view ) {\n\t\t\t\tviewController.edit_view.remove();\n\t\t\t}\n\t\t\tviewController.sub_log_view_controller = null;\n\t\t\tviewController.edit_view_ui_dic = {};\n\t\t\tviewController.edit_view_ui_validation_field_dic = {};\n\t\t\tviewController.edit_view_form_item_dic = {};\n\t\t\tviewController.edit_view_error_ui_dic = {};\n\t\t\tLocalCacheData.current_doing_context_action = '';\n\t\t}\n\t}\n}\n\nclass IndexViewController extends Backbone.View {\n\tconstructor( options = {} ) {\n\t\t_.defaults( options, {\n\t\t\tel: 'body', //So we can add event listener for all elements\n\t\t\trouter: null,\n\t\t} );\n\n\t\tsuper( options );\n\t}\n\n\tinitialize( options ) {\n\t\tIndexViewController.instance = this;\n\t\tthis.router = new ApplicationRouter();\n\t\t//Set title in index.php instead.\n\t\t//$( 'title' ).html( '' );\n\t\tthis.router.controller = this;\n\t\t//Error: Backbone.history has already been started in interface/html5/framework/backbone/backbone-min.js?v=9.0.1-20151022-162110 line 28\n\t\tif ( !Backbone.History.started ) {\n\t\t\tBackbone.history.start();\n\t\t}\n\t}\n}\n\nIndexViewController.instance = null;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzE5NC5qcyIsIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQXVGOztBQUVoRjtBQUNQLDJCQUEyQjtBQUMzQixFQUFFLENBQUM7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7O0FBRUo7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esa0JBQWtCLENBQUM7QUFDbkI7O0FBRUE7O0FBRUE7QUFDQSxJQUFJO0FBQ0o7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esd0VBQXdFO0FBQ3hFO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjs7QUFFQTtBQUNBLEdBQUcsQ0FBQztBQUNKLDJIQUEySDtBQUMzSDtBQUNBLDJCQUEyQixnR0FBb0I7QUFDL0MsSUFBSSxDQUFDO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHNFQUFzRTtBQUN0RTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLG9CQUFvQixxQkFBcUI7QUFDekM7QUFDQTs7QUFFQSxVQUFVLENBQUM7QUFDWDtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBLE1BQU07QUFDTjtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRU87QUFDUCwyQkFBMkI7QUFDM0IsRUFBRSxDQUFDO0FBQ0g7QUFDQTtBQUNBLElBQUk7O0FBRUo7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9pbnRlcmZhY2UvaHRtbDUvcXVpY2tfcHVuY2gvSW5kZXhDb250cm9sbGVyLmpzP2Q2ZTAiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSGVhZGVyVmlld0NvbnRyb2xsZXIgfSBmcm9tICdAL3ZpZXdzL3F1aWNrX3B1bmNoL2hlYWRlci9IZWFkZXJWaWV3Q29udHJvbGxlcic7XG5cbmV4cG9ydCBjbGFzcyBBcHBsaWNhdGlvblJvdXRlciBleHRlbmRzIEJhY2tib25lLlJvdXRlciB7XG5cdGNvbnN0cnVjdG9yKCBvcHRpb25zID0ge30gKSB7XG5cdFx0Xy5kZWZhdWx0cyggb3B0aW9ucywge1xuXHRcdFx0Y29udHJvbGxlcjogbnVsbCxcblx0XHRcdGhlYWRlclZpZXc6IG51bGwsXG5cdFx0XHRyb3V0ZXM6IHtcblx0XHRcdFx0Jyc6ICdvblZpZXdDaGFuZ2UnLFxuXHRcdFx0XHQnITp2aWV3TmFtZSc6ICdvblZpZXdDaGFuZ2UnLFxuXHRcdFx0XHQnKm5vdEZvdW5kJzogJ25vdEZvdW5kJ1xuXHRcdFx0fVxuXHRcdH0gKTtcblxuXHRcdHN1cGVyKCBvcHRpb25zICk7XG5cdH1cblxuXHRsb2FkVmlldyggdmlld19pZCApIHtcblx0XHRHbG9iYWwubG9hZFZpZXdTb3VyY2UoIHZpZXdfaWQsIHZpZXdfaWQgKyAnVmlldy5odG1sJywgZnVuY3Rpb24oIHJlc3VsdCApIHtcblx0XHRcdHZhciB0ZW1wbGF0ZSA9IF8udGVtcGxhdGUoIHJlc3VsdCApO1xuXHRcdFx0R2xvYmFsLmNvbnRlbnRDb250YWluZXIoKS5odG1sKCB0ZW1wbGF0ZSApO1xuXG5cdFx0XHRMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fdmlld19pZCA9IHZpZXdfaWQ7XG5cblx0XHRcdEdsb2JhbC50cmFja1ZpZXcoIHZpZXdfaWQgKTtcblx0XHR9ICk7XG5cdH1cblxuXHRyZWxvYWRWaWV3KCB2aWV3X2lkICkge1xuXHRcdC8vZXJyb3I6IFVuY2F1Z2h0IFJlZmVyZW5jZUVycm9yOiBYWFhYVmlld0NvbnRyb2xsZXIgaXMgbm90IGRlZmluZWQgaW5pbnRlcmZhY2UvaHRtbDUvIyFtPVRpbWVTaGVldCBsaW5lIDNcblx0XHQvLyBIYXBwZW5zIHdoZW4gcXVpY2tseSBjbGljayBvbiBjb250ZXh0IG1lbnUgYW5kIG5ldHdvcmsgaXMgc2xvdy5cblx0XHRpZiAoIGV2YWwoICd0eXBlb2YgJysgdmlld19pZCArICdWaWV3Q29udHJvbGxlcicgKSA9PT0gJ2Z1bmN0aW9uJyApIHsgLy9XYXMgRVM1OiB3aW5kb3dbdmlld19pZCArICdWaWV3Q29udHJvbGxlciddICYmXG5cdFx0XHR0aGlzLmxvYWRWaWV3KCB2aWV3X2lkICk7XG5cdFx0fVxuXHR9XG5cblx0bm90Rm91bmQoIHVybCApIHtcblx0XHR2YXIgbmV3X3VybCA9IEdsb2JhbC5nZXRCYXNlVVJMKCk7XG5cblx0XHRHbG9iYWwuc2V0VVJMVG9Ccm93c2VyKCBuZXdfdXJsICsgJyMhbT1RdWlja1B1bmNoTG9naW4nICk7XG5cdH1cblxuXHQvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXG5cdG9uVmlld0NoYW5nZSggdmlld05hbWUgKSB7XG5cdFx0dmFyICR0aGlzID0gdGhpcztcblx0XHR2YXIgYXJncyA9IHt9O1xuXHRcdHZhciB2aWV3X2lkO1xuXG5cdFx0aWYgKCBHbG9iYWwubmVlZFJlbG9hZEJyb3dzZXIgKSB7XG5cdFx0XHRHbG9iYWwubmVlZFJlbG9hZEJyb3dzZXIgPSBmYWxzZTtcblx0XHRcdHdpbmRvdy5sb2NhdGlvbi5yZWxvYWQoKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRpZiAoIHZpZXdOYW1lICkge1xuXHRcdFx0YXJncyA9IEdsb2JhbC5idWlsZEFyZ0RpYyggdmlld05hbWUuc3BsaXQoICcmJyApICk7XG5cdFx0fVxuXHRcdGlmICggdmlld05hbWUgJiYgdmlld05hbWUuaW5kZXhPZiggJ209JyApID49IDAgJiYgdmlld05hbWUuaW5kZXhPZiggJ1F1aWNrUHVuY2gnICkgPj0gMCApIHtcblx0XHRcdHZpZXdfaWQgPSBHbG9iYWwuc2FuaXRpemVWaWV3SWQoIGFyZ3MubSApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR2aWV3X2lkID0gJ1F1aWNrUHVuY2hMb2dpbic7XG5cdFx0XHRHbG9iYWwuc2V0VVJMVG9Ccm93c2VyKCBHbG9iYWwuZ2V0QmFzZVVSTCgpICsgJyMhbT1RdWlja1B1bmNoTG9naW4nICk7XG5cdFx0fVxuXG5cdFx0TG9jYWxDYWNoZURhdGEuZnVsbFVybFBhcmFtZXRlclN0ciA9IHZpZXdOYW1lO1xuXG5cdFx0TG9jYWxDYWNoZURhdGEuc2V0QWxsVVJMQXJncyggYXJncyApO1xuXHRcdHZhciByZWcgPSBuZXcgUmVnRXhwKCAnXlswLTldKiQnICk7XG5cdFx0dmFyIHRpbWVvdXRfY291bnQ7XG5cdFx0dGltZW91dF9jb3VudCA9IDA7XG5cdFx0Ly8gJCgnbGlua1t0aXRsZT1cImFwcGxpY2F0aW9uIGNzc1wiXScpLnByb3AoJ2Rpc2FibGVkJywgdHJ1ZSk7XG5cdFx0aWYgKCBMb2NhbENhY2hlRGF0YS5sb2FkVmlld1JlcXVpcmVkSlNSZWFkeSApIHtcblx0XHRcdHNob3dSaWJib25NZW51QW5kTG9hZFZpZXcoKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dmFyIGF1dG9fbG9naW5fdGltZXIgPSBzZXRJbnRlcnZhbCggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggdGltZW91dF9jb3VudCA9PSAxMDAgKSB7XG5cdFx0XHRcdFx0Y2xlYXJJbnRlcnZhbCggYXV0b19sb2dpbl90aW1lciApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHRpbWVvdXRfY291bnQgPSB0aW1lb3V0X2NvdW50ICsgMTtcblx0XHRcdFx0aWYgKCBMb2NhbENhY2hlRGF0YS5sb2FkVmlld1JlcXVpcmVkSlNSZWFkeSApIHtcblx0XHRcdFx0XHRzaG93UmliYm9uTWVudUFuZExvYWRWaWV3KCk7XG5cdFx0XHRcdFx0Y2xlYXJJbnRlcnZhbCggYXV0b19sb2dpbl90aW1lciApO1xuXHRcdFx0XHR9XG5cdFx0XHR9LCA2MDAgKTtcblx0XHR9XG5cblx0XHRmdW5jdGlvbiBzaG93UmliYm9uTWVudUFuZExvYWRWaWV3KCkge1xuXHRcdFx0JCggJ2JvZHknICkucmVtb3ZlQ2xhc3MoICdsb2dpbi1iZycgKTtcblx0XHRcdC8vIEdsb2JhbC5sb2FkU3R5bGVTaGVldCggJy4uL3RoZW1lL2RlZmF1bHQvY3NzL3F1aWNrUHVuY2guY3NzJyArICc/dj0nICsgQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLmFwcGxpY2F0aW9uX2J1aWxkICk7IC8vICMyODQ0IHF1aWNrcHVuY2ggY3NzIHdpbGwgbm93IGJlIGxvYWRlZCBhdCBzdGFydC5cblx0XHRcdGlmICggISR0aGlzLmhlYWRlclZpZXcgKSB7XG5cdFx0XHRcdCR0aGlzLmhlYWRlclZpZXcgPSBuZXcgSGVhZGVyVmlld0NvbnRyb2xsZXIoKTtcblx0XHRcdFx0JCggJyN0b3BDb250YWluZXInICkuaHRtbCggJHRoaXMuaGVhZGVyVmlldy5lbCApO1xuXHRcdFx0fVxuXHRcdFx0bG9hZFZpZXdDb250cm9sbGVyKCk7XG5cdFx0fVxuXG5cdFx0ZnVuY3Rpb24gbG9hZFZpZXdDb250cm9sbGVyKCkge1xuXHRcdFx0R2xvYmFsLmxvYWRWaWV3U291cmNlKCB2aWV3X2lkLCB2aWV3X2lkICsgJ1ZpZXdDb250cm9sbGVyLmpzJywgZnVuY3Rpb24oKSB7XG5cdFx0XHRcdC8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cblx0XHRcdFx0dmFyIHZpZXdfY29udHJvbGxlciA9IGV2YWwoICduZXcgJyArIHZpZXdfaWQgKyAnVmlld0NvbnRyb2xsZXIoKTsgJyApO1xuXHRcdFx0XHRHbG9iYWwudHJhY2tWaWV3KCB2aWV3X2lkICk7XG5cdFx0XHRcdC8qIGpzaGludCBpZ25vcmU6ZW5kICovXG5cblx0XHRcdFx0Ly8gT25seSBzaG93IHRoZSB0b3AgYW5kIGJvdHRvbSBjb250YWluZXJzIHVudGlsIGFmdGVyIHRoZSB2aWV3IGh0bWwgaXMgbG9hZGVkLCBvdGhlcndpc2UgdGhlIGRvd25sb2FkIGFwcCBsaW5rcyBmbGFzaCB1cCBhdCB0aGUgdG9wIG9mIHRoZSBwYWdlLCB3aGVyZSB0aGUgbG9naW4gaGVhZGVyIHNob3VsZCBiZS5cblx0XHRcdFx0Ly8gVE9ETzogSW1wcm92ZSB0aGlzIHdpdGggVnVlIHRvIGJlIHNtb290aGVyIGFuZCBtb3JlIHN0cnVjdHVyZWQsIHJhdGhlciB0aGFuIHRyaWFsIGFuZCBlcnJvci5cblx0XHRcdFx0R2xvYmFsLnRvcENvbnRhaW5lcigpLmNzcyggJ2Rpc3BsYXknLCAnYmxvY2snICk7XG5cdFx0XHRcdEdsb2JhbC5ib3R0b21Db250YWluZXIoKS5jc3MoICdkaXNwbGF5JywgJ2Jsb2NrJyApO1xuXHRcdFx0fSApO1xuXHRcdH1cblx0fVxuXG5cdC8qIGpzaGludCBpZ25vcmU6ZW5kICovXG5cblx0Y2xlYW5BbnlTdWJWaWV3VUkoKSB7XG5cdFx0dmFyIGNoaWxkcmVuID0gR2xvYmFsLmNvbnRlbnRDb250YWluZXIoKS5jaGlsZHJlbigpO1xuXG5cdFx0aWYgKCBjaGlsZHJlbi5sZW5ndGggPiAxICkge1xuXHRcdFx0Zm9yICggdmFyIGkgPSAxOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRcdC8vIE9iamVjdCBkb2Vzbid0IHN1cHBvcnQgcHJvcGVydHkgb3IgbWV0aG9kICdyZW1vdmUnLCBOb3Qgc3VyZSB3aHksIGFkZCB0cnkgY2F0Y2ggdG8gaW5nb3JlIHRoaXMgZXJyb3Igc2luY2UgdGhpcyBzaG91bGQgbm8gaGFybVxuXHRcdFx0XHR0cnkge1xuXG5cdFx0XHRcdFx0aWYgKCAkKCBjaGlsZHJlbltpXSApLmF0dHIoICdpZCcgKSA9PT0gTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlci51aV9pZCApIHtcblx0XHRcdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRjaGlsZHJlbltpXS5yZW1vdmUoKTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0fSBjYXRjaCAoIGUgKSB7XG5cdFx0XHRcdFx0Ly9EbyBub3RoaW5nXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHNldENvbnRlbnREaXZIZWlnaHQoKSB7XG5cdFx0R2xvYmFsLmNvbnRlbnRDb250YWluZXIoKS5yZW1vdmVDbGFzcyggJ2NvbnRlbnQtY29udGFpbmVyJyApO1xuXHRcdEdsb2JhbC5jb250ZW50Q29udGFpbmVyKCkuYWRkQ2xhc3MoICdjb250ZW50LWNvbnRhaW5lci1hZnRlci1sb2dpbicgKTtcblx0XHRHbG9iYWwudG9wQ29udGFpbmVyKCkuYWRkQ2xhc3MoICd0b3AtY29udGFpbmVyLWFmdGVyLWxvZ2luJyApO1xuXG5cdH1cblxuXHRhZGRUb3BNZW51KCkge1xuXHRcdEdsb2JhbC5sb2FkU2NyaXB0KCAnZ2xvYmFsL3dpZGdldHMvdG9wX21lbnUvVG9wTWVudUNvbnRyb2xsZXIuanMnICk7XG5cdFx0aWYgKCBUb3BNZW51Q29udHJvbGxlciApIHtcblx0XHRcdFRvcE1lbnVDb250cm9sbGVyLmxvYWRWaWV3KCk7XG5cdFx0fVxuXG5cdH1cblxuXHRyZW1vdmVDdXJyZW50VmlldyggY2FsbEJhY2sgKSB7XG5cdFx0aWYgKCBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fZWRpdF9vbmx5X2NvbnRyb2xsZXIgKSB7XG5cdFx0XHRjbGVhbiggTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX2VkaXRfb25seV9jb250cm9sbGVyICk7XG5cdFx0XHRMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fZWRpdF9vbmx5X2NvbnRyb2xsZXIgPSBudWxsO1xuXHRcdH1cblxuXHRcdGlmICggTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlciApIHtcblx0XHRcdGlmICggTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlci5lZGl0X3ZpZXcgKSB7XG5cdFx0XHRcdGNsZWFuKCBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyICk7XG5cdFx0XHR9XG5cdFx0XHRHbG9iYWwuY29udGVudENvbnRhaW5lcigpLmVtcHR5KCk7XG5cdFx0XHRMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyLmNsZWFuV2hlblVubG9hZFZpZXcoIGNhbGxCYWNrICk7XG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0aWYgKCBHbG9iYWwuaXNTZXQoIGNhbGxCYWNrICkgKSB7XG5cdFx0XHRcdGNhbGxCYWNrKCk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0ZnVuY3Rpb24gY2xlYW4oIHZpZXdDb250cm9sbGVyICkge1xuXHRcdFx0dmlld0NvbnRyb2xsZXIuY2xlYXJFcnJvclRpcHMoKTtcblx0XHRcdC8vIENhbm5vdCByZWFkIHByb3BlcnR5ICdyZW1vdmUnIG9mIG51bGwgaW4gaW50ZXJmYWNlL2h0bWw1L0luZGV4Q29udHJvbGxlci5qcz92PTkuMC4wLTIwMTUxMDE2LTE1MzA1NyBsaW5lIDQzOVxuXHRcdFx0aWYgKCB2aWV3Q29udHJvbGxlci5lZGl0X3ZpZXcgKSB7XG5cdFx0XHRcdHZpZXdDb250cm9sbGVyLmVkaXRfdmlldy5yZW1vdmUoKTtcblx0XHRcdH1cblx0XHRcdHZpZXdDb250cm9sbGVyLnN1Yl9sb2dfdmlld19jb250cm9sbGVyID0gbnVsbDtcblx0XHRcdHZpZXdDb250cm9sbGVyLmVkaXRfdmlld191aV9kaWMgPSB7fTtcblx0XHRcdHZpZXdDb250cm9sbGVyLmVkaXRfdmlld191aV92YWxpZGF0aW9uX2ZpZWxkX2RpYyA9IHt9O1xuXHRcdFx0dmlld0NvbnRyb2xsZXIuZWRpdF92aWV3X2Zvcm1faXRlbV9kaWMgPSB7fTtcblx0XHRcdHZpZXdDb250cm9sbGVyLmVkaXRfdmlld19lcnJvcl91aV9kaWMgPSB7fTtcblx0XHRcdExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfZG9pbmdfY29udGV4dF9hY3Rpb24gPSAnJztcblx0XHR9XG5cdH1cbn1cblxuZXhwb3J0IGNsYXNzIEluZGV4Vmlld0NvbnRyb2xsZXIgZXh0ZW5kcyBCYWNrYm9uZS5WaWV3IHtcblx0Y29uc3RydWN0b3IoIG9wdGlvbnMgPSB7fSApIHtcblx0XHRfLmRlZmF1bHRzKCBvcHRpb25zLCB7XG5cdFx0XHRlbDogJ2JvZHknLCAvL1NvIHdlIGNhbiBhZGQgZXZlbnQgbGlzdGVuZXIgZm9yIGFsbCBlbGVtZW50c1xuXHRcdFx0cm91dGVyOiBudWxsLFxuXHRcdH0gKTtcblxuXHRcdHN1cGVyKCBvcHRpb25zICk7XG5cdH1cblxuXHRpbml0aWFsaXplKCBvcHRpb25zICkge1xuXHRcdEluZGV4Vmlld0NvbnRyb2xsZXIuaW5zdGFuY2UgPSB0aGlzO1xuXHRcdHRoaXMucm91dGVyID0gbmV3IEFwcGxpY2F0aW9uUm91dGVyKCk7XG5cdFx0Ly9TZXQgdGl0bGUgaW4gaW5kZXgucGhwIGluc3RlYWQuXG5cdFx0Ly8kKCAndGl0bGUnICkuaHRtbCggJycgKTtcblx0XHR0aGlzLnJvdXRlci5jb250cm9sbGVyID0gdGhpcztcblx0XHQvL0Vycm9yOiBCYWNrYm9uZS5oaXN0b3J5IGhhcyBhbHJlYWR5IGJlZW4gc3RhcnRlZCBpbiBpbnRlcmZhY2UvaHRtbDUvZnJhbWV3b3JrL2JhY2tib25lL2JhY2tib25lLW1pbi5qcz92PTkuMC4xLTIwMTUxMDIyLTE2MjExMCBsaW5lIDI4XG5cdFx0aWYgKCAhQmFja2JvbmUuSGlzdG9yeS5zdGFydGVkICkge1xuXHRcdFx0QmFja2JvbmUuaGlzdG9yeS5zdGFydCgpO1xuXHRcdH1cblx0fVxufVxuXG5JbmRleFZpZXdDb250cm9sbGVyLmluc3RhbmNlID0gbnVsbDsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///7194\n")},3173:(__unused_webpack_module,__unused_webpack___webpack_exports__,__webpack_require__)=>{"use strict";eval("/* harmony import */ var stacktrace_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(401);\n/* harmony import */ var stacktrace_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(stacktrace_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var backbone__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2316);\n/* harmony import */ var backbone__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(backbone__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var jquery_ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6891);\n/* harmony import */ var jquery_ui__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(jquery_ui__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var bootstrap__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(3734);\n/* harmony import */ var bootstrap__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(bootstrap__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var _framework_jquery_i18n_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(6378);\n/* harmony import */ var _framework_jquery_i18n_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_framework_jquery_i18n_js__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var html2canvas__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(1120);\n/* harmony import */ var html2canvas__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(html2canvas__WEBPACK_IMPORTED_MODULE_5__);\n/* harmony import */ var _global_Global__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(9490);\n/* harmony import */ var _global_LocalCacheData__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(9563);\n/* harmony import */ var _global_TTPromise__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(9504);\n/* harmony import */ var _global_ProgressBarManager__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(587);\n/* harmony import */ var _global_PermissionManager__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(8843);\n/* harmony import */ var _global_TAlertManager__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(9239);\n/* harmony import */ var _services_ServiceCaller__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(12);\n/* harmony import */ var _services_TimeTrexClientAPI__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(7526);\n/* harmony import */ var _IndexController__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(7194);\n/* provided dependency */ var $ = __webpack_require__(9755);\n/* Tell js linting to ignore the webpack globals */\n/*global __webpack_public_path__ */\n\n// Modify the webpack config output.publicPath to take into account the extra directory level of quick_punch.\n__webpack_require__.p = '../' + __webpack_require__.p;\n\n// from main app\n\n// import 'expose-loader?exposes=$,jQuery!jquery'; // Now done in webpack config -- Old: Needs be done with expose otherwise other imports error \"jQuery/$ is not defined.\" e.g. plugins like i18n.\n// import _ from 'underscore';\n // does not seem to need expose loader.\n\n// end from main app\n\n// global vendor imports\n\n\n\n\n\n\n\n\n// global imports\n\n\n // Potentially the same issue as ProgressBar (multiple instances, no single state), so lets just make it global to be safe.\n // Must only be imported in one place, otherwise multiple instances could be loaded and clash by leaving open Progressbars. e.g. Seen in TimeSheet\n\n\n\n// imports for this file only\n\n\n // Make sure this is quick_punch/IndexController! Not from main UI.\n\nwindow.$ = window.jQuery = $; // #3028 This is needed because although webpack will handle any references to $/jQuery in our code, its done internally and not on the window. So 3rd party libraries will not find jQuery on the window.\nwindow.html2canvas = (html2canvas__WEBPACK_IMPORTED_MODULE_5___default());\nwindow.StackTrace = stacktrace_js__WEBPACK_IMPORTED_MODULE_0__;\nwindow.Global = _global_Global__WEBPACK_IMPORTED_MODULE_6__/* .Global */ .x;\nwindow.LocalCacheData = _global_LocalCacheData__WEBPACK_IMPORTED_MODULE_7__/* .LocalCacheData */ .B;\nwindow.TTPromise = _global_TTPromise__WEBPACK_IMPORTED_MODULE_8__/* .TTPromise */ .j;\nwindow.ProgressBar = _global_ProgressBarManager__WEBPACK_IMPORTED_MODULE_9__/* .ProgressBar */ .k;\nwindow.PermissionManager = _global_PermissionManager__WEBPACK_IMPORTED_MODULE_10__/* .PermissionManager */ .Y;\nwindow.TAlertManager = _global_TAlertManager__WEBPACK_IMPORTED_MODULE_11__/* .TAlertManager */ .K;\n\nwindow.is_browser_iOS = ( navigator.userAgent.match( /(iPad|iPhone|iPod)/g ) ? true : false );\n\nvar api_authentication = _services_TimeTrexClientAPI__WEBPACK_IMPORTED_MODULE_13__/* .TTAPI.APIAuthentication */ .y.APIAuthentication;\n\nif ( Error ) {\n\tError.stackTraceLimit = 50; //Increase JS exception stack trace limit.\n}\n\nwindow.onerror = function( error_msg, file, line, col, error_obj ) {\n\tif ( !arguments || arguments.length < 1 ) {\n\t\t_global_Global__WEBPACK_IMPORTED_MODULE_6__/* .Global.sendErrorReport */ .x.sendErrorReport( 'No error parameters when window.onerror', _services_ServiceCaller__WEBPACK_IMPORTED_MODULE_12__/* .ServiceCaller.root_url */ .n.root_url, '', '', '' );\n\t} else {\n\t\t_global_Global__WEBPACK_IMPORTED_MODULE_6__/* .Global.sendErrorReport */ .x.sendErrorReport( error_msg, file, line, col, error_obj );\n\t}\n};\n\n_services_ServiceCaller__WEBPACK_IMPORTED_MODULE_12__/* .ServiceCaller.base_url */ .n.base_url = _global_Global__WEBPACK_IMPORTED_MODULE_6__/* .Global.getBaseURL */ .x.getBaseURL( '../../../', false );\n_services_ServiceCaller__WEBPACK_IMPORTED_MODULE_12__/* .ServiceCaller.base_api_url */ .n.base_api_url = 'api/json/quick_punch/api.php';\n_services_ServiceCaller__WEBPACK_IMPORTED_MODULE_12__/* .ServiceCaller.root_url */ .n.root_url = _global_Global__WEBPACK_IMPORTED_MODULE_6__/* .Global.getRootURL */ .x.getRootURL();\n\nvar loginData = {};\n//Set in APIGlobal.php\nif ( !need_load_pre_login_data ) {\n\tloginData = APIGlobal.pre_login_data;\n} else {\n\tneed_load_pre_login_data = false;\n}\nif ( !loginData.hasOwnProperty( 'api_base_url' ) ) {\n\tapi_authentication.getPreLoginData( null, {\n\t\tonResult: function( e ) {\n\n\t\t\tvar result = e.getResult();\n\n\t\t\t_global_LocalCacheData__WEBPACK_IMPORTED_MODULE_7__/* .LocalCacheData.setLoginData */ .B.setLoginData( result );\n\t\t\tAPIGlobal.pre_login_data = result;\n\n\t\t\tloginData = _global_LocalCacheData__WEBPACK_IMPORTED_MODULE_7__/* .LocalCacheData.getLoginData */ .B.getLoginData();\n\t\t\tinitApps();\n\n\t\t}\n\t} );\n} else {\n\t_global_LocalCacheData__WEBPACK_IMPORTED_MODULE_7__/* .LocalCacheData.setLoginData */ .B.setLoginData( loginData ); //set here because the loginData is set from php\n\tinitApps();\n}\ninitAnalytics();\n\nfunction initAnalytics() {\n\t/* jshint ignore:start */\n\tif ( APIGlobal.pre_login_data.analytics_enabled === true && _services_ServiceCaller__WEBPACK_IMPORTED_MODULE_12__/* .ServiceCaller */ .n && _services_ServiceCaller__WEBPACK_IMPORTED_MODULE_12__/* .ServiceCaller.root_url */ .n.root_url && loginData && loginData.base_url ) {\n\t\ttry {\n\t\t\tvar gtag_script = document.createElement('script');\n\t\t\tgtag_script.setAttribute('src','https://www.googletagmanager.com/gtag/js?id='+ APIGlobal.pre_login_data.analytics_tracking_code );\n\t\t\tdocument.head.appendChild(gtag_script);\n\n\t\t\twindow.dataLayer = window.dataLayer || [];\n\t\t\twindow.gtag = function gtag(){window.dataLayer.push(arguments);}\n\t\t\tgtag( 'js', new Date() );\n\t\t\tgtag( 'config', APIGlobal.pre_login_data.analytics_tracking_code, { 'debug_mode': !APIGlobal.pre_login_data.production, 'send_page_view': false, 'custom_map': { 'dimension1': 'application_version', 'dimension2': 'http_host', 'dimension3': 'product_edition_name', 'dimension4': 'registration_key', 'dimension5': 'primary_company_name', 'dimension6': 'user_name', 'dimension7': 'company_name', } } );\n\n\t\t\t//Do not check existance of LocalCacheData with if(LocalCacheData) or JS will execute the unnamed function it uses as a constructor\n\t\t\t//Do not user LocalCacheData.getCurrentCompany for this comparison, or JS will throw a \"cache is expired\" error.\n\t\t\tif ( _global_LocalCacheData__WEBPACK_IMPORTED_MODULE_7__/* .LocalCacheData.getPunchLoginUser */ .B.getPunchLoginUser() && _global_LocalCacheData__WEBPACK_IMPORTED_MODULE_7__/* .LocalCacheData.getLocalCache */ .B.getLocalCache( 'current_company', 'JSON' ) ) {\n\t\t\t\tvar current_company = _global_LocalCacheData__WEBPACK_IMPORTED_MODULE_7__/* .LocalCacheData.getCurrentCompany */ .B.getCurrentCompany();\n\t\t\t\t_global_Global__WEBPACK_IMPORTED_MODULE_6__/* .Global.setAnalyticDimensions */ .x.setAnalyticDimensions( _global_LocalCacheData__WEBPACK_IMPORTED_MODULE_7__/* .LocalCacheData.getPunchLoginUser */ .B.getPunchLoginUser().first_name + ' (' + _global_LocalCacheData__WEBPACK_IMPORTED_MODULE_7__/* .LocalCacheData.getPunchLoginUser */ .B.getPunchLoginUser().id + ')', current_company.name );\n\t\t\t} else {\n\t\t\t\t_global_Global__WEBPACK_IMPORTED_MODULE_6__/* .Global.setAnalyticDimensions */ .x.setAnalyticDimensions();\n\t\t\t}\n\t\t} catch ( e ) {\n\t\t\tthrow e; //Attempt to catch any errors thrown by Google Analytics.\n\t\t}\n\t}\n\t/* jshint ignore:end */\n}\n\nfunction initApps() {\n\tloadViewRequiredJS();\n\n\t//Optimization: Only change locale if its *not* en_US or enable_default_language_translation = TRUE\n\tif ( loginData.locale !== 'en_US' || loginData.enable_default_language_translation == true ) {\n\t\t_global_Global__WEBPACK_IMPORTED_MODULE_6__/* .Global.loadLanguage */ .x.loadLanguage( loginData.locale );\n\t\tDebug.Text( 'Using Locale: ' + loginData.locale, 'quick_punch/main.js', '', 'initApps', 10 );\n\t} else {\n\t\t_global_LocalCacheData__WEBPACK_IMPORTED_MODULE_7__/* .LocalCacheData.setI18nDic */ .B.setI18nDic( {} );\n\t}\n\t$.i18n.load( _global_LocalCacheData__WEBPACK_IMPORTED_MODULE_7__/* .LocalCacheData.getI18nDic */ .B.getI18nDic() );\n\t_global_Global__WEBPACK_IMPORTED_MODULE_6__/* .Global.initStaticStrings */ .x.initStaticStrings();\n\n\t_global_LocalCacheData__WEBPACK_IMPORTED_MODULE_7__/* .LocalCacheData.deployment_on_demand */ .B.deployment_on_demand = loginData.deployment_on_demand;\n\t_global_LocalCacheData__WEBPACK_IMPORTED_MODULE_7__/* .LocalCacheData.productEditionId */ .B.productEditionId = loginData.product_edition;\n\n\tvar controller = new _IndexController__WEBPACK_IMPORTED_MODULE_14__/* .IndexViewController */ .g(); //Even though controller variable is not used, this must be called.\n}\n\nfunction loadViewRequiredJS() {\n\t_global_Global__WEBPACK_IMPORTED_MODULE_6__/* .Global.url_offset */ .x.url_offset = '../'; //Must be defined before any other JS/CSS is loaded, otherwise can cause 404 when changing languages.\n\n\t_global_Global__WEBPACK_IMPORTED_MODULE_6__/* .Global.addCss */ .x.addCss( 'global/widgets/talert/TAlert.css' );\n\t_global_LocalCacheData__WEBPACK_IMPORTED_MODULE_7__/* .LocalCacheData.loadViewRequiredJSReady */ .B.loadViewRequiredJSReady = true;\n}//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzE3My5qcyIsIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFDQTs7QUFFQTtBQUNBLHFCQUF1QixXQUFXLHFCQUF1Qjs7QUFFekQ7QUFDMkM7QUFDM0MsbURBQW1EO0FBQ25EO0FBQ2tCLENBQUM7QUFDQTtBQUNuQjs7QUFFQTtBQUNtQjtBQUNBO0FBQzJCO0FBQ087QUFDSDtBQUNkO0FBQ0U7O0FBRXRDO0FBQ3lDO0FBQ2dCO0FBQ1YsQ0FBQztBQUNVLENBQUM7QUFDSTtBQUNSOztBQUV2RDtBQUN5RDtBQUNKO0FBQ0csQ0FBQzs7QUFFekQsMkJBQTJCLENBQUMsRUFBRTtBQUM5QixxQkFBcUIsb0RBQVc7QUFDaEMsb0JBQW9CLDBDQUFVO0FBQzlCLGdCQUFnQiwyREFBTTtBQUN0Qix3QkFBd0IsMkVBQWM7QUFDdEMsbUJBQW1CLGlFQUFTO0FBQzVCLHFCQUFxQiw0RUFBVztBQUNoQywyQkFBMkIsa0ZBQWlCO0FBQzVDLHVCQUF1QiwwRUFBYTs7QUFFcEM7O0FBRUEseUJBQXlCLDRHQUF1Qjs7QUFFaEQ7QUFDQSw2QkFBNkI7QUFDN0I7O0FBRUE7QUFDQTtBQUNBLEVBQUUsMkZBQXNCLDZDQUE2Qyw4RkFBc0I7QUFDM0YsR0FBRztBQUNILEVBQUUsMkZBQXNCO0FBQ3hCO0FBQ0E7O0FBRUEsOEZBQXNCLEdBQUcsaUZBQWlCO0FBQzFDLHNHQUEwQjtBQUMxQiw4RkFBc0IsR0FBRyxpRkFBaUI7O0FBRTFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsR0FBRyxxR0FBMkI7QUFDOUI7O0FBRUEsZUFBZSxxR0FBMkI7QUFDMUM7O0FBRUE7QUFDQSxHQUFHO0FBQ0gsRUFBRTtBQUNGLENBQUMscUdBQTJCLGVBQWU7QUFDM0M7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw2REFBNkQsNEVBQWEsSUFBSSw4RkFBc0I7QUFDcEc7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQ0FBaUM7QUFDakM7QUFDQSx1RUFBdUUsNkZBQTZGLDJPQUEyTzs7QUFFL1k7QUFDQTtBQUNBLFFBQVEsK0dBQWdDLE1BQU0sdUdBQTRCO0FBQzFFLDBCQUEwQiwrR0FBZ0M7QUFDMUQsSUFBSSx1R0FBNEIsRUFBRSwrR0FBZ0MsdUJBQXVCLCtHQUFnQztBQUN6SCxLQUFLO0FBQ0wsSUFBSSx1R0FBNEI7QUFDaEM7QUFDQSxJQUFJO0FBQ0osWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEVBQUUscUZBQW1CO0FBQ3JCO0FBQ0EsR0FBRztBQUNILEVBQUUsaUdBQXlCLEtBQUs7QUFDaEM7QUFDQSxDQUFDLENBQUMsWUFBWSxpR0FBeUI7QUFDdkMsQ0FBQywrRkFBd0I7O0FBRXpCLENBQUMscUhBQW1DO0FBQ3BDLENBQUMsNkdBQStCOztBQUVoQyxzQkFBc0IsMkVBQW1CLElBQUk7QUFDN0M7O0FBRUE7QUFDQSxDQUFDLGlGQUFpQixVQUFVOztBQUU1QixDQUFDLHlFQUFhO0FBQ2QsQ0FBQywySEFBc0M7QUFDdkMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9pbnRlcmZhY2UvaHRtbDUvcXVpY2tfcHVuY2gvbWFpbi5qcz8zMjQxIl0sInNvdXJjZXNDb250ZW50IjpbIi8qIFRlbGwganMgbGludGluZyB0byBpZ25vcmUgdGhlIHdlYnBhY2sgZ2xvYmFscyAqL1xuLypnbG9iYWwgX193ZWJwYWNrX3B1YmxpY19wYXRoX18gKi9cblxuLy8gTW9kaWZ5IHRoZSB3ZWJwYWNrIGNvbmZpZyBvdXRwdXQucHVibGljUGF0aCB0byB0YWtlIGludG8gYWNjb3VudCB0aGUgZXh0cmEgZGlyZWN0b3J5IGxldmVsIG9mIHF1aWNrX3B1bmNoLlxuX193ZWJwYWNrX3B1YmxpY19wYXRoX18gPSAnLi4vJyArIF9fd2VicGFja19wdWJsaWNfcGF0aF9fO1xuXG4vLyBmcm9tIG1haW4gYXBwXG5pbXBvcnQgKiBhcyBTdGFja1RyYWNlIGZyb20gJ3N0YWNrdHJhY2UtanMnXG4vLyBpbXBvcnQgJ2V4cG9zZS1sb2FkZXI/ZXhwb3Nlcz0kLGpRdWVyeSFqcXVlcnknOyAvLyBOb3cgZG9uZSBpbiB3ZWJwYWNrIGNvbmZpZyAtLSBPbGQ6IE5lZWRzIGJlIGRvbmUgd2l0aCBleHBvc2Ugb3RoZXJ3aXNlIG90aGVyIGltcG9ydHMgZXJyb3IgXCJqUXVlcnkvJCBpcyBub3QgZGVmaW5lZC5cIiBlLmcuIHBsdWdpbnMgbGlrZSBpMThuLlxuLy8gaW1wb3J0IF8gZnJvbSAndW5kZXJzY29yZSc7XG5pbXBvcnQgJ2JhY2tib25lJzsgLy8gZG9lcyBub3Qgc2VlbSB0byBuZWVkIGV4cG9zZSBsb2FkZXIuXG5pbXBvcnQgJ2pxdWVyeS11aSc7XG4vLyBlbmQgZnJvbSBtYWluIGFwcFxuXG4vLyBnbG9iYWwgdmVuZG9yIGltcG9ydHNcbmltcG9ydCAncG9wcGVyLmpzJztcbmltcG9ydCAnYm9vdHN0cmFwJztcbmltcG9ydCAnYm9vdHN0cmFwL2Rpc3QvY3NzL2Jvb3RzdHJhcC5taW4uY3NzJztcbmltcG9ydCAnYm9vdHN0cmFwL2Rpc3QvY3NzL2Jvb3RzdHJhcC1yZWJvb3QubWluLmNzcyc7XG5pbXBvcnQgJ2Jvb3RzdHJhcC9kaXN0L2Nzcy9ib290c3RyYXAtZ3JpZC5taW4uY3NzJ1xuaW1wb3J0ICdAL2ZyYW1ld29yay9qcXVlcnkuaTE4bi5qcyc7XG5pbXBvcnQgaHRtbDJjYW52YXMgZnJvbSAnaHRtbDJjYW52YXMnO1xuXG4vLyBnbG9iYWwgaW1wb3J0c1xuaW1wb3J0IHsgR2xvYmFsIH0gZnJvbSAnQC9nbG9iYWwvR2xvYmFsJztcbmltcG9ydCB7IExvY2FsQ2FjaGVEYXRhIH0gZnJvbSAnQC9nbG9iYWwvTG9jYWxDYWNoZURhdGEnO1xuaW1wb3J0IHsgVFRQcm9taXNlIH0gZnJvbSAnQC9nbG9iYWwvVFRQcm9taXNlJzsgLy8gUG90ZW50aWFsbHkgdGhlIHNhbWUgaXNzdWUgYXMgUHJvZ3Jlc3NCYXIgKG11bHRpcGxlIGluc3RhbmNlcywgbm8gc2luZ2xlIHN0YXRlKSwgc28gbGV0cyBqdXN0IG1ha2UgaXQgZ2xvYmFsIHRvIGJlIHNhZmUuXG5pbXBvcnQgeyBQcm9ncmVzc0JhciB9IGZyb20gJ0AvZ2xvYmFsL1Byb2dyZXNzQmFyTWFuYWdlcic7IC8vIE11c3Qgb25seSBiZSBpbXBvcnRlZCBpbiBvbmUgcGxhY2UsIG90aGVyd2lzZSBtdWx0aXBsZSBpbnN0YW5jZXMgY291bGQgYmUgbG9hZGVkIGFuZCBjbGFzaCBieSBsZWF2aW5nIG9wZW4gUHJvZ3Jlc3NiYXJzLiBlLmcuIFNlZW4gaW4gVGltZVNoZWV0XG5pbXBvcnQgeyBQZXJtaXNzaW9uTWFuYWdlciB9IGZyb20gJ0AvZ2xvYmFsL1Blcm1pc3Npb25NYW5hZ2VyJztcbmltcG9ydCB7IFRBbGVydE1hbmFnZXIgfSBmcm9tICdAL2dsb2JhbC9UQWxlcnRNYW5hZ2VyJztcblxuLy8gaW1wb3J0cyBmb3IgdGhpcyBmaWxlIG9ubHlcbmltcG9ydCB7IFNlcnZpY2VDYWxsZXIgfSBmcm9tICdAL3NlcnZpY2VzL1NlcnZpY2VDYWxsZXInO1xuaW1wb3J0IHsgVFRBUEkgfSBmcm9tICdAL3NlcnZpY2VzL1RpbWVUcmV4Q2xpZW50QVBJJztcbmltcG9ydCB7IEluZGV4Vmlld0NvbnRyb2xsZXIgfSBmcm9tICcuL0luZGV4Q29udHJvbGxlcic7IC8vIE1ha2Ugc3VyZSB0aGlzIGlzIHF1aWNrX3B1bmNoL0luZGV4Q29udHJvbGxlciEgTm90IGZyb20gbWFpbiBVSS5cblxud2luZG93LiQgPSB3aW5kb3cualF1ZXJ5ID0gJDsgLy8gIzMwMjggVGhpcyBpcyBuZWVkZWQgYmVjYXVzZSBhbHRob3VnaCB3ZWJwYWNrIHdpbGwgaGFuZGxlIGFueSByZWZlcmVuY2VzIHRvICQvalF1ZXJ5IGluIG91ciBjb2RlLCBpdHMgZG9uZSBpbnRlcm5hbGx5IGFuZCBub3Qgb24gdGhlIHdpbmRvdy4gU28gM3JkIHBhcnR5IGxpYnJhcmllcyB3aWxsIG5vdCBmaW5kIGpRdWVyeSBvbiB0aGUgd2luZG93Llxud2luZG93Lmh0bWwyY2FudmFzID0gaHRtbDJjYW52YXM7XG53aW5kb3cuU3RhY2tUcmFjZSA9IFN0YWNrVHJhY2U7XG53aW5kb3cuR2xvYmFsID0gR2xvYmFsO1xud2luZG93LkxvY2FsQ2FjaGVEYXRhID0gTG9jYWxDYWNoZURhdGE7XG53aW5kb3cuVFRQcm9taXNlID0gVFRQcm9taXNlO1xud2luZG93LlByb2dyZXNzQmFyID0gUHJvZ3Jlc3NCYXI7XG53aW5kb3cuUGVybWlzc2lvbk1hbmFnZXIgPSBQZXJtaXNzaW9uTWFuYWdlcjtcbndpbmRvdy5UQWxlcnRNYW5hZ2VyID0gVEFsZXJ0TWFuYWdlcjtcblxud2luZG93LmlzX2Jyb3dzZXJfaU9TID0gKCBuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKCAvKGlQYWR8aVBob25lfGlQb2QpL2cgKSA/IHRydWUgOiBmYWxzZSApO1xuXG52YXIgYXBpX2F1dGhlbnRpY2F0aW9uID0gVFRBUEkuQVBJQXV0aGVudGljYXRpb247XG5cbmlmICggRXJyb3IgKSB7XG5cdEVycm9yLnN0YWNrVHJhY2VMaW1pdCA9IDUwOyAvL0luY3JlYXNlIEpTIGV4Y2VwdGlvbiBzdGFjayB0cmFjZSBsaW1pdC5cbn1cblxud2luZG93Lm9uZXJyb3IgPSBmdW5jdGlvbiggZXJyb3JfbXNnLCBmaWxlLCBsaW5lLCBjb2wsIGVycm9yX29iaiApIHtcblx0aWYgKCAhYXJndW1lbnRzIHx8IGFyZ3VtZW50cy5sZW5ndGggPCAxICkge1xuXHRcdEdsb2JhbC5zZW5kRXJyb3JSZXBvcnQoICdObyBlcnJvciBwYXJhbWV0ZXJzIHdoZW4gd2luZG93Lm9uZXJyb3InLCBTZXJ2aWNlQ2FsbGVyLnJvb3RfdXJsLCAnJywgJycsICcnICk7XG5cdH0gZWxzZSB7XG5cdFx0R2xvYmFsLnNlbmRFcnJvclJlcG9ydCggZXJyb3JfbXNnLCBmaWxlLCBsaW5lLCBjb2wsIGVycm9yX29iaiApO1xuXHR9XG59O1xuXG5TZXJ2aWNlQ2FsbGVyLmJhc2VfdXJsID0gR2xvYmFsLmdldEJhc2VVUkwoICcuLi8uLi8uLi8nLCBmYWxzZSApO1xuU2VydmljZUNhbGxlci5iYXNlX2FwaV91cmwgPSAnYXBpL2pzb24vcXVpY2tfcHVuY2gvYXBpLnBocCc7XG5TZXJ2aWNlQ2FsbGVyLnJvb3RfdXJsID0gR2xvYmFsLmdldFJvb3RVUkwoKTtcblxudmFyIGxvZ2luRGF0YSA9IHt9O1xuLy9TZXQgaW4gQVBJR2xvYmFsLnBocFxuaWYgKCAhbmVlZF9sb2FkX3ByZV9sb2dpbl9kYXRhICkge1xuXHRsb2dpbkRhdGEgPSBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGE7XG59IGVsc2Uge1xuXHRuZWVkX2xvYWRfcHJlX2xvZ2luX2RhdGEgPSBmYWxzZTtcbn1cbmlmICggIWxvZ2luRGF0YS5oYXNPd25Qcm9wZXJ0eSggJ2FwaV9iYXNlX3VybCcgKSApIHtcblx0YXBpX2F1dGhlbnRpY2F0aW9uLmdldFByZUxvZ2luRGF0YSggbnVsbCwge1xuXHRcdG9uUmVzdWx0OiBmdW5jdGlvbiggZSApIHtcblxuXHRcdFx0dmFyIHJlc3VsdCA9IGUuZ2V0UmVzdWx0KCk7XG5cblx0XHRcdExvY2FsQ2FjaGVEYXRhLnNldExvZ2luRGF0YSggcmVzdWx0ICk7XG5cdFx0XHRBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEgPSByZXN1bHQ7XG5cblx0XHRcdGxvZ2luRGF0YSA9IExvY2FsQ2FjaGVEYXRhLmdldExvZ2luRGF0YSgpO1xuXHRcdFx0aW5pdEFwcHMoKTtcblxuXHRcdH1cblx0fSApO1xufSBlbHNlIHtcblx0TG9jYWxDYWNoZURhdGEuc2V0TG9naW5EYXRhKCBsb2dpbkRhdGEgKTsgLy9zZXQgaGVyZSBiZWNhdXNlIHRoZSBsb2dpbkRhdGEgaXMgc2V0IGZyb20gcGhwXG5cdGluaXRBcHBzKCk7XG59XG5pbml0QW5hbHl0aWNzKCk7XG5cbmZ1bmN0aW9uIGluaXRBbmFseXRpY3MoKSB7XG5cdC8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cblx0aWYgKCBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEuYW5hbHl0aWNzX2VuYWJsZWQgPT09IHRydWUgJiYgU2VydmljZUNhbGxlciAmJiBTZXJ2aWNlQ2FsbGVyLnJvb3RfdXJsICYmIGxvZ2luRGF0YSAmJiBsb2dpbkRhdGEuYmFzZV91cmwgKSB7XG5cdFx0dHJ5IHtcblx0XHRcdHZhciBndGFnX3NjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpO1xuXHRcdFx0Z3RhZ19zY3JpcHQuc2V0QXR0cmlidXRlKCdzcmMnLCdodHRwczovL3d3dy5nb29nbGV0YWdtYW5hZ2VyLmNvbS9ndGFnL2pzP2lkPScrIEFQSUdsb2JhbC5wcmVfbG9naW5fZGF0YS5hbmFseXRpY3NfdHJhY2tpbmdfY29kZSApO1xuXHRcdFx0ZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChndGFnX3NjcmlwdCk7XG5cblx0XHRcdHdpbmRvdy5kYXRhTGF5ZXIgPSB3aW5kb3cuZGF0YUxheWVyIHx8IFtdO1xuXHRcdFx0d2luZG93Lmd0YWcgPSBmdW5jdGlvbiBndGFnKCl7d2luZG93LmRhdGFMYXllci5wdXNoKGFyZ3VtZW50cyk7fVxuXHRcdFx0Z3RhZyggJ2pzJywgbmV3IERhdGUoKSApO1xuXHRcdFx0Z3RhZyggJ2NvbmZpZycsIEFQSUdsb2JhbC5wcmVfbG9naW5fZGF0YS5hbmFseXRpY3NfdHJhY2tpbmdfY29kZSwgeyAnZGVidWdfbW9kZSc6ICFBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEucHJvZHVjdGlvbiwgJ3NlbmRfcGFnZV92aWV3JzogZmFsc2UsICdjdXN0b21fbWFwJzogeyAnZGltZW5zaW9uMSc6ICdhcHBsaWNhdGlvbl92ZXJzaW9uJywgJ2RpbWVuc2lvbjInOiAnaHR0cF9ob3N0JywgJ2RpbWVuc2lvbjMnOiAncHJvZHVjdF9lZGl0aW9uX25hbWUnLCAnZGltZW5zaW9uNCc6ICdyZWdpc3RyYXRpb25fa2V5JywgJ2RpbWVuc2lvbjUnOiAncHJpbWFyeV9jb21wYW55X25hbWUnLCAnZGltZW5zaW9uNic6ICd1c2VyX25hbWUnLCAnZGltZW5zaW9uNyc6ICdjb21wYW55X25hbWUnLCB9IH0gKTtcblxuXHRcdFx0Ly9EbyBub3QgY2hlY2sgZXhpc3RhbmNlIG9mIExvY2FsQ2FjaGVEYXRhIHdpdGggaWYoTG9jYWxDYWNoZURhdGEpIG9yIEpTIHdpbGwgZXhlY3V0ZSB0aGUgdW5uYW1lZCBmdW5jdGlvbiBpdCB1c2VzIGFzIGEgY29uc3RydWN0b3Jcblx0XHRcdC8vRG8gbm90IHVzZXIgTG9jYWxDYWNoZURhdGEuZ2V0Q3VycmVudENvbXBhbnkgZm9yIHRoaXMgY29tcGFyaXNvbiwgb3IgSlMgd2lsbCB0aHJvdyBhIFwiY2FjaGUgaXMgZXhwaXJlZFwiIGVycm9yLlxuXHRcdFx0aWYgKCBMb2NhbENhY2hlRGF0YS5nZXRQdW5jaExvZ2luVXNlcigpICYmIExvY2FsQ2FjaGVEYXRhLmdldExvY2FsQ2FjaGUoICdjdXJyZW50X2NvbXBhbnknLCAnSlNPTicgKSApIHtcblx0XHRcdFx0dmFyIGN1cnJlbnRfY29tcGFueSA9IExvY2FsQ2FjaGVEYXRhLmdldEN1cnJlbnRDb21wYW55KCk7XG5cdFx0XHRcdEdsb2JhbC5zZXRBbmFseXRpY0RpbWVuc2lvbnMoIExvY2FsQ2FjaGVEYXRhLmdldFB1bmNoTG9naW5Vc2VyKCkuZmlyc3RfbmFtZSArICcgKCcgKyBMb2NhbENhY2hlRGF0YS5nZXRQdW5jaExvZ2luVXNlcigpLmlkICsgJyknLCBjdXJyZW50X2NvbXBhbnkubmFtZSApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0R2xvYmFsLnNldEFuYWx5dGljRGltZW5zaW9ucygpO1xuXHRcdFx0fVxuXHRcdH0gY2F0Y2ggKCBlICkge1xuXHRcdFx0dGhyb3cgZTsgLy9BdHRlbXB0IHRvIGNhdGNoIGFueSBlcnJvcnMgdGhyb3duIGJ5IEdvb2dsZSBBbmFseXRpY3MuXG5cdFx0fVxuXHR9XG5cdC8qIGpzaGludCBpZ25vcmU6ZW5kICovXG59XG5cbmZ1bmN0aW9uIGluaXRBcHBzKCkge1xuXHRsb2FkVmlld1JlcXVpcmVkSlMoKTtcblxuXHQvL09wdGltaXphdGlvbjogT25seSBjaGFuZ2UgbG9jYWxlIGlmIGl0cyAqbm90KiBlbl9VUyBvciBlbmFibGVfZGVmYXVsdF9sYW5ndWFnZV90cmFuc2xhdGlvbiA9IFRSVUVcblx0aWYgKCBsb2dpbkRhdGEubG9jYWxlICE9PSAnZW5fVVMnIHx8IGxvZ2luRGF0YS5lbmFibGVfZGVmYXVsdF9sYW5ndWFnZV90cmFuc2xhdGlvbiA9PSB0cnVlICkge1xuXHRcdEdsb2JhbC5sb2FkTGFuZ3VhZ2UoIGxvZ2luRGF0YS5sb2NhbGUgKTtcblx0XHREZWJ1Zy5UZXh0KCAnVXNpbmcgTG9jYWxlOiAnICsgbG9naW5EYXRhLmxvY2FsZSwgJ3F1aWNrX3B1bmNoL21haW4uanMnLCAnJywgJ2luaXRBcHBzJywgMTAgKTtcblx0fSBlbHNlIHtcblx0XHRMb2NhbENhY2hlRGF0YS5zZXRJMThuRGljKCB7fSApO1xuXHR9XG5cdCQuaTE4bi5sb2FkKCBMb2NhbENhY2hlRGF0YS5nZXRJMThuRGljKCkgKTtcblx0R2xvYmFsLmluaXRTdGF0aWNTdHJpbmdzKCk7XG5cblx0TG9jYWxDYWNoZURhdGEuZGVwbG95bWVudF9vbl9kZW1hbmQgPSBsb2dpbkRhdGEuZGVwbG95bWVudF9vbl9kZW1hbmQ7XG5cdExvY2FsQ2FjaGVEYXRhLnByb2R1Y3RFZGl0aW9uSWQgPSBsb2dpbkRhdGEucHJvZHVjdF9lZGl0aW9uO1xuXG5cdHZhciBjb250cm9sbGVyID0gbmV3IEluZGV4Vmlld0NvbnRyb2xsZXIoKTsgLy9FdmVuIHRob3VnaCBjb250cm9sbGVyIHZhcmlhYmxlIGlzIG5vdCB1c2VkLCB0aGlzIG11c3QgYmUgY2FsbGVkLlxufVxuXG5mdW5jdGlvbiBsb2FkVmlld1JlcXVpcmVkSlMoKSB7XG5cdEdsb2JhbC51cmxfb2Zmc2V0ID0gJy4uLyc7IC8vTXVzdCBiZSBkZWZpbmVkIGJlZm9yZSBhbnkgb3RoZXIgSlMvQ1NTIGlzIGxvYWRlZCwgb3RoZXJ3aXNlIGNhbiBjYXVzZSA0MDQgd2hlbiBjaGFuZ2luZyBsYW5ndWFnZXMuXG5cblx0R2xvYmFsLmFkZENzcyggJ2dsb2JhbC93aWRnZXRzL3RhbGVydC9UQWxlcnQuY3NzJyApO1xuXHRMb2NhbENhY2hlRGF0YS5sb2FkVmlld1JlcXVpcmVkSlNSZWFkeSA9IHRydWU7XG59Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///3173\n")},4578:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "H": () => (/* binding */ HtmlTemplatesGlobal),\n/* harmony export */ "W": () => (/* binding */ TemplateType)\n/* harmony export */ });\nclass HtmlTemplates {\n\n\tconstructor() {\n\t}\n\n\t/**\n\t * Conditionally insert variable or html. Can be used in two ways.\n\t * Either 1) pass html, and if so it will use the html if the field is true.\n\t * Or, 2) if the field is a value (and truthy), and html is undefined/not provided, then return the field value.\n\t * Instead of 2), you can also reference a variable directly, but risk outputting \'undefined\' into the output html.\n\t * @param field Either a data value evaluating as truthy, or a Boolean.\n\t * @param html Optional html field to use if field is Boolean.\n\t * @returns {string|*}\n\t */\n\toutputif( field, html ) { // function to be called outputif, or printif\n\t\tif ( field ) {\n\t\t\treturn html ? html : field;\n\t\t} else {\n\t\t\treturn \'\';\n\t\t}\n\t}\n\n\t/***\n\t * Conditionally output options passed to the view controller constructor. Wrapper for outputif to handle multiple options.\n\t * @param options\n\t * @returns {string}\n\t */\n\toutputOptions( options ) {\n\t\tlet output = [];\n\t\tfor ( var i = 0; i < options.length; i++ ) {\n\t\t\tlet result = this.outputif( options[i].option, options[i].html );\n\t\t\tif ( result ) {\n\t\t\t\toutput.push( result );\n\t\t\t}\n\t\t}\n\t\treturn output.length > 0 ? \'{ \' + output.join( \', \' ) + \' }\' : \'\';\n\t}\n\n\t/**\n\t * PascalCase to snake_case\n\t */\n\tconvertPascalCase2SnakeCase( string ) {\n\t\t// all lowercase separated by _\n\t\treturn string.split( /(?=[A-Z][a-z])/ ).join( \'_\' ).toLowerCase(); // Fix: [A-Z][a-z] is needed to not split on all caps like ROEView. But this wont handle single caps at the end though.\n\t}\n\n\t/**\n\t * PascalCase to kebab-case\n\t */\n\tconvertPascalCase2KebabCase( string ) {\n\t\t// all lowercase separated by -\n\t\treturn string.split( /(?=[A-Z][a-z])/ ).join( \'-\' ).toLowerCase(); // Fix: [A-Z][a-z] is needed to not split on all caps like ROEView. But this wont handle single caps at the end though.\n\t}\n\n\tgetTemplateTypeFromFilename( filename ) {\n\t\tvar type;\n\n\t\tswitch ( true ) { // known as \'overloaded switch\'\n\t\t\t// The following views will use the new templating logic. Order of these statements is important, first rule to match is used.\n\t\t\tcase this.checkViewClassForInlineHtmlbyFilename( filename ) !== false: // If success, it will return a String with the html.\n\t\t\t\t// If a view class contains a static html_template value, then use this as an override instead of any specific type template matched by filename.\n\t\t\t\ttype = TemplateType.INLINE_HTML;\n\t\t\t\tbreak;\n\t\t\tcase filename.indexOf( \'Sub\' ) === 0: // Checks \'Sub\' at start of filename. Must come before ReportView, otherwise it will conflict for SubSavedReportView.html\n\t\t\t\ttype = TemplateType.SUB_VIEW;\n\t\t\t\tbreak;\n\t\t\tcase filename.indexOf( \'EditView.html\' ) !== -1: // Must come before List Views, otherwise it will match for those due to both ending in View.html\n\t\t\t\ttype = TemplateType.EDIT_VIEW;\n\t\t\t\tbreak;\n\t\t\tcase filename.indexOf( \'ReportView.html\' ) !== -1 && filename.includes( \'Saved\' ) === false: // Must come before List Views, and after \'Sub\' otherwise reports will be loaded as list views. However make sure SavedReport is loaded as a list view.\n\t\t\t\ttype = TemplateType.REPORT_VIEW;\n\t\t\t\tbreak;\n\t\t\tcase filename.indexOf( \'View.html\' ) !== -1: // Must come more or less last, otherwise it will conflict with other files containing View.html, like EditView.html and ReportView.html\n\t\t\t\ttype = TemplateType.LIST_VIEW;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\t// If no template types are matched, treat as legacy html.\n\t\t\t\ttype = TemplateType.LEGACY_HTML; // This results in the relevant html file being loaded via the network. The new tab parsing logic may still run!\n\t\t}\n\n\t\treturn type;\n\t}\n\n\t//Certain views do not fall under the rules of \'getTemplateTypeFromFilename()\' and require special handling.\n\t//This can be removed once we switch how views are loaded and can apply these rules directly on the view itself.\n\tgetTemplateOptionsFromViewId( view_id ) {\n\t\tlet options = {\n\t\t\tview_id: view_id,\n\t\t\t// Remember, sub_view_mode is not included here as not yet available here; view controller has not yet been loaded. Sub View Mode will be determined by template_type using the file name data. Will be applied as an option in HtmlTemplates.getGenericListViewHtml\n\t\t};\n\n\t\t//The following tax reports require an additional tab.\n\t\tlet reports_require_form_setup = [\'RemittanceSummaryReport\', \'T4SummaryReport\', \'T4ASummaryReport\', \'Form941Report\', \'Form940Report\', \'Form1099NecReport\', \'FormW2Report\', \'AffordableCareReport\', \'USStateUnemploymentReport\'];\n\t\tif ( reports_require_form_setup.includes( view_id ) ) {\n\t\t\toptions.report_form_setup = true;\n\t\t}\n\n\t\tlet sub_view_require_warning_message = [`UserDateTotal`];\n\t\tif ( sub_view_require_warning_message.includes( view_id ) ) {\n\t\t\toptions.sub_view_warning_message = true;\n\t\t}\n\n\t\t//Issue #3158 - If these controllers are cached then side effects can occur.\n\t\t//Such as permission denied alerts after opening login view on Invoice -> Client view.\n\t\tlet view_do_not_cache_controller = [`LoginUserWizard`, \'LoginUser\', \'FindAvailableWizard\', \'FindAvailable\'];\n\t\tif ( view_do_not_cache_controller.includes( view_id ) ) {\n\t\t\toptions.do_not_cache_controller = true;\n\t\t}\n\n\t\t//Audit log is both a TemplateType.INLINE_HTML and a TemplateType.SUB_VIEW under the current HTML2JS system.\n\t\t//Once we switch to loading ViewControllers before HTML this special case can be removed.\n\t\tif( view_id === \'Log\' ) {\n\t\t\toptions.is_sub_view = true;\n\t\t}\n\n\t\t//Views extending BaseTreeViewController have slightly different requirments such as not show total number div.\n\t\t//Once we switch to loading ViewControllers before the HTML this can be conditional by checking if the controller has tree_mode set to true.\n\t\tlet base_tree_views = [\'JobGroup\', \'JobItemGroup\', \'PunchTagGroup\', \'UserGroup\', \'DocumentGroup\', \'KPIGroup\', \'ClientGroup\', \'ProductGroup\'];\n\t\tif ( base_tree_views.includes( view_id ) ) {\n\t\t\toptions.base_tree_view = true;\n\t\t}\n\n\t\treturn options;\n\t}\n\n\tcheckViewClassForInlineHtmlbyFilename( filename ) {\n\t\t// Lets see if this view class contains a html_template override, which should precede any type definitions.\n\t\tlet check_class = window[ filename.replace(/\\.html$/,\'\') + \'Controller\' ];\n\t\tif( check_class !== undefined && typeof check_class.html_template === \'string\' ) {\n\t\t\treturn check_class.html_template;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t *\n\t * @param {TemplateType} type\n\t * @param {Object} options\n\t * @param {Function} [onResult]\n\t */\n\tgetTemplate( type, options = {}, onResult ) {\n\n\t\tvar html_template;\n\n\t\tswitch ( type ) {\n\t\t\tcase TemplateType.LIST_VIEW:\n\t\t\t\thtml_template = this.getGenericListViewHtml( options );\n\t\t\t\tbreak;\n\t\t\tcase TemplateType.SUB_VIEW:\n\t\t\t\toptions.is_sub_view = true; // Force this to be true, as it\'s a sub_view after all. (This switch data is based off html filename request)\n\t\t\t\thtml_template = this.getGenericListViewHtml( options );\n\t\t\t\tbreak;\n\t\t\tcase TemplateType.EDIT_VIEW:\n\t\t\t\t// code block\n\t\t\t\thtml_template = HtmlTemplatesGlobal.genericEditView( options );\n\t\t\t\tbreak;\n\t\t\tcase TemplateType.REPORT_VIEW:\n\t\t\t\t// code block\n\t\t\t\thtml_template = HtmlTemplatesGlobal.genericReportEditView( options );\n\t\t\t\tbreak;\n\t\t\tcase TemplateType.INLINE_HTML:\n\t\t\t\thtml_template = this.getViewScriptTagHtml( options ) + this.checkViewClassForInlineHtmlbyFilename( options.filename );\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tDebug.Error( \'HTML2JS: Error occured getting template. No matches for \' + options.view_id, \'HtmlTemplates.js\', \'HtmlTemplates.js\', \'getTemplate\', 1 );\n\t\t\t\treturn -1;\n\t\t}\n\n\t\t// If callback onResult exists, call the function, else return html.\n\t\tif ( onResult ) {\n\t\t\tonResult( html_template ); // should we put this outside the switch? Depends how similar the other switch statements are.\n\t\t} else {\n\t\t\treturn html_template;\n\t\t}\n\t}\n\n\t/**\n\t * This also handles subview script tags, if options.is_sub_view is true.\n\t * @param options\n\t * @returns {string}\n\t */\n\tgetGenericListViewHtml( options = {} ) {\n\t\tDebug.Text( \'HTML2JS: Template retrieved for \' + options.view_id, \'HtmlTemplates.js\', \'HtmlTemplates.js\', \'getGenericListViewHtml\', 10 );\n\t\t// Prepend the