/*
* ATTENTION: An "eval-source-map" devtool has been used.
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
/******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({
/***/ 111:
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _fullcalendar_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(112);\n/* harmony import */ var _fullcalendar_interaction__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(117);\n/* harmony import */ var _fullcalendar_daygrid__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(118);\n/* harmony import */ var _fullcalendar_timegrid__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(120);\n/* harmony import */ var _fullcalendar_list__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(122);\n/**\n * @description Fullcalendar Plugin Init\n * @see https://fullcalendar.io/docs\n */\n\n\n\n\n\n\ndocument.addEventListener('DOMContentLoaded', function () {\n var calendarEl = document.getElementById('calendar');\n if (calendarEl != undefined) {\n var calendar = new _fullcalendar_core__WEBPACK_IMPORTED_MODULE_0__.Calendar(calendarEl, {\n plugins: [_fullcalendar_interaction__WEBPACK_IMPORTED_MODULE_1__[\"default\"], _fullcalendar_daygrid__WEBPACK_IMPORTED_MODULE_2__[\"default\"], _fullcalendar_timegrid__WEBPACK_IMPORTED_MODULE_3__[\"default\"], _fullcalendar_list__WEBPACK_IMPORTED_MODULE_4__[\"default\"]],\n headerToolbar: {\n left: 'prev,next today',\n center: 'title',\n right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'\n },\n initialDate: '2023-01-12',\n navLinks: true,\n // can click day/week names to navigate views\n editable: true,\n dayMaxEvents: true,\n // allow \"more\" link when too many events\n events: [{\n title: 'All Day Event',\n start: '2023-01-01'\n }, {\n title: 'Long Event',\n start: '2023-01-07',\n end: '2023-01-10'\n }, {\n groupId: 999,\n title: 'Repeating Event',\n start: '2023-01-09T16:00:00'\n }, {\n groupId: 999,\n title: 'Repeating Event',\n start: '2023-01-16T16:00:00'\n }, {\n title: 'Conference',\n start: '2023-01-11',\n end: '2023-01-13'\n }, {\n title: 'Meeting',\n start: '2023-01-12T10:30:00',\n end: '2023-01-12T12:30:00'\n }, {\n title: 'Lunch',\n start: '2023-01-12T12:00:00'\n }, {\n title: 'Meeting',\n start: '2023-01-12T14:30:00'\n }, {\n title: 'Happy Hour',\n start: '2023-01-12T17:30:00'\n }, {\n title: 'Dinner',\n start: '2023-01-12T20:00:00'\n }, {\n title: 'Birthday Party',\n start: '2023-01-13T07:00:00'\n }, {\n title: 'Click for Google',\n url: 'http://google.com/',\n start: '2023-01-28'\n }]\n });\n calendar.render();\n }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTExLmpzIiwibWFwcGluZ3MiOiI7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBOztBQUU4QztBQUNZO0FBQ1I7QUFDRTtBQUNSO0FBRTVDSyxRQUFRLENBQUNDLGdCQUFnQixDQUFDLGtCQUFrQixFQUFFLFlBQVc7RUFDdkQsSUFBTUMsVUFBVSxHQUFHRixRQUFRLENBQUNHLGNBQWMsQ0FBQyxVQUFVLENBQUM7RUFFdkQsSUFBSUQsVUFBVSxJQUFJRSxTQUFTLEVBQUU7SUFDM0IsSUFBTUMsUUFBUSxHQUFHLElBQUlWLHdEQUFRLENBQUNPLFVBQVUsRUFBRTtNQUN4Q0ksT0FBTyxFQUFFLENBQUVWLGlFQUFpQixFQUFFQyw2REFBYSxFQUFFQyw4REFBYyxFQUFFQywwREFBVSxDQUFFO01BQ3pFUSxhQUFhLEVBQUU7UUFDYkMsSUFBSSxFQUFFLGlCQUFpQjtRQUN2QkMsTUFBTSxFQUFFLE9BQU87UUFDZkMsS0FBSyxFQUFFO01BQ1QsQ0FBQztNQUNEQyxXQUFXLEVBQUUsWUFBWTtNQUN6QkMsUUFBUSxFQUFFLElBQUk7TUFBRTtNQUNoQkMsUUFBUSxFQUFFLElBQUk7TUFDZEMsWUFBWSxFQUFFLElBQUk7TUFBRTtNQUNwQkMsTUFBTSxFQUFFLENBQ047UUFDRUMsS0FBSyxFQUFFLGVBQWU7UUFDdEJDLEtBQUssRUFBRTtNQUNULENBQUMsRUFDRDtRQUNFRCxLQUFLLEVBQUUsWUFBWTtRQUNuQkMsS0FBSyxFQUFFLFlBQVk7UUFDbkJDLEdBQUcsRUFBRTtNQUNQLENBQUMsRUFDRDtRQUNFQyxPQUFPLEVBQUUsR0FBRztRQUNaSCxLQUFLLEVBQUUsaUJBQWlCO1FBQ3hCQyxLQUFLLEVBQUU7TUFDVCxDQUFDLEVBQ0Q7UUFDRUUsT0FBTyxFQUFFLEdBQUc7UUFDWkgsS0FBSyxFQUFFLGlCQUFpQjtRQUN4QkMsS0FBSyxFQUFFO01BQ1QsQ0FBQyxFQUNEO1FBQ0VELEtBQUssRUFBRSxZQUFZO1FBQ25CQyxLQUFLLEVBQUUsWUFBWTtRQUNuQkMsR0FBRyxFQUFFO01BQ1AsQ0FBQyxFQUNEO1FBQ0VGLEtBQUssRUFBRSxTQUFTO1FBQ2hCQyxLQUFLLEVBQUUscUJBQXFCO1FBQzVCQyxHQUFHLEVBQUU7TUFDUCxDQUFDLEVBQ0Q7UUFDRUYsS0FBSyxFQUFFLE9BQU87UUFDZEMsS0FBSyxFQUFFO01BQ1QsQ0FBQyxFQUNEO1FBQ0VELEtBQUssRUFBRSxTQUFTO1FBQ2hCQyxLQUFLLEVBQUU7TUFDVCxDQUFDLEVBQ0Q7UUFDRUQsS0FBSyxFQUFFLFlBQVk7UUFDbkJDLEtBQUssRUFBRTtNQUNULENBQUMsRUFDRDtRQUNFRCxLQUFLLEVBQUUsUUFBUTtRQUNmQyxLQUFLLEVBQUU7TUFDVCxDQUFDLEVBQ0Q7UUFDRUQsS0FBSyxFQUFFLGdCQUFnQjtRQUN2QkMsS0FBSyxFQUFFO01BQ1QsQ0FBQyxFQUNEO1FBQ0VELEtBQUssRUFBRSxrQkFBa0I7UUFDekJJLEdBQUcsRUFBRSxvQkFBb0I7UUFDekJILEtBQUssRUFBRTtNQUNULENBQUM7SUFFTCxDQUFDLENBQUM7SUFFRlosUUFBUSxDQUFDZ0IsTUFBTSxDQUFDLENBQUM7RUFDbkI7QUFDRCxDQUFDLENBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9hcmNoaXRlY3R1aS1odG1sLWZyZWUvLi9zcmMvc2NyaXB0cy1pbml0L2NhbGVuZGFyLmpzP2M2YTAiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAZGVzY3JpcHRpb24gRnVsbGNhbGVuZGFyIFBsdWdpbiBJbml0XG4gKiBAc2VlIGh0dHBzOi8vZnVsbGNhbGVuZGFyLmlvL2RvY3NcbiAqL1xuXG5pbXBvcnQgeyBDYWxlbmRhciB9IGZyb20gJ0BmdWxsY2FsZW5kYXIvY29yZSc7XG5pbXBvcnQgaW50ZXJhY3Rpb25QbHVnaW4gZnJvbSAnQGZ1bGxjYWxlbmRhci9pbnRlcmFjdGlvbic7XG5pbXBvcnQgZGF5R3JpZFBsdWdpbiBmcm9tICdAZnVsbGNhbGVuZGFyL2RheWdyaWQnO1xuaW1wb3J0IHRpbWVHcmlkUGx1Z2luIGZyb20gJ0BmdWxsY2FsZW5kYXIvdGltZWdyaWQnO1xuaW1wb3J0IGxpc3RQbHVnaW4gZnJvbSAnQGZ1bGxjYWxlbmRhci9saXN0JztcblxuZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignRE9NQ29udGVudExvYWRlZCcsIGZ1bmN0aW9uKCkge1xuICBjb25zdCBjYWxlbmRhckVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NhbGVuZGFyJyk7XG5cbiBpZiAoY2FsZW5kYXJFbCAhPSB1bmRlZmluZWQpIHtcbiAgIGNvbnN0IGNhbGVuZGFyID0gbmV3IENhbGVuZGFyKGNhbGVuZGFyRWwsIHtcbiAgICAgcGx1Z2luczogWyBpbnRlcmFjdGlvblBsdWdpbiwgZGF5R3JpZFBsdWdpbiwgdGltZUdyaWRQbHVnaW4sIGxpc3RQbHVnaW4gXSxcbiAgICAgaGVhZGVyVG9vbGJhcjoge1xuICAgICAgIGxlZnQ6ICdwcmV2LG5leHQgdG9kYXknLFxuICAgICAgIGNlbnRlcjogJ3RpdGxlJyxcbiAgICAgICByaWdodDogJ2RheUdyaWRNb250aCx0aW1lR3JpZFdlZWssdGltZUdyaWREYXksbGlzdFdlZWsnXG4gICAgIH0sXG4gICAgIGluaXRpYWxEYXRlOiAnMjAyMy0wMS0xMicsXG4gICAgIG5hdkxpbmtzOiB0cnVlLCAvLyBjYW4gY2xpY2sgZGF5L3dlZWsgbmFtZXMgdG8gbmF2aWdhdGUgdmlld3NcbiAgICAgZWRpdGFibGU6IHRydWUsXG4gICAgIGRheU1heEV2ZW50czogdHJ1ZSwgLy8gYWxsb3cgXCJtb3JlXCIgbGluayB3aGVuIHRvbyBtYW55IGV2ZW50c1xuICAgICBldmVudHM6IFtcbiAgICAgICB7XG4gICAgICAgICB0aXRsZTogJ0FsbCBEYXkgRXZlbnQnLFxuICAgICAgICAgc3RhcnQ6ICcyMDIzLTAxLTAxJyxcbiAgICAgICB9LFxuICAgICAgIHtcbiAgICAgICAgIHRpdGxlOiAnTG9uZyBFdmVudCcsXG4gICAgICAgICBzdGFydDogJzIwMjMtMDEtMDcnLFxuICAgICAgICAgZW5kOiAnMjAyMy0wMS0xMCdcbiAgICAgICB9LFxuICAgICAgIHtcbiAgICAgICAgIGdyb3VwSWQ6IDk5OSxcbiAgICAgICAgIHRpdGxlOiAnUmVwZWF0aW5nIEV2ZW50JyxcbiAgICAgICAgIHN0YXJ0OiAnMjAyMy0wMS0wOVQxNjowMDowMCdcbiAgICAgICB9LFxuICAgICAgIHtcbiAgICAgICAgIGdyb3VwSWQ6IDk5OSxcbiAgICAgICAgIHRpdGxlOiAnUmVwZWF0aW5nIEV2ZW50JyxcbiAgICAgICAgIHN0YXJ0OiAnMjAyMy0wMS0xNlQxNjowMDowMCdcbiAgICAgICB9LFxuICAgICAgIHtcbiAgICAgICAgIHRpdGxlOiAnQ29uZmVyZW5jZScsXG4gICAgICAgICBzdGFydDogJzIwMjMtMDEtMTEnLFxuICAgICAgICAgZW5kOiAnMjAyMy0wMS0xMydcbiAgICAgICB9LFxuICAgICAgIHtcbiAgICAgICAgIHRpdGxlOiAnTWVldGluZycsXG4gICAgICAgICBzdGFydDogJzIwMjMtMDEtMTJUMTA6MzA6MDAnLFxuICAgICAgICAgZW5kOiAnMjAyMy0wMS0xMlQxMjozMDowMCdcbiAgICAgICB9LFxuICAgICAgIHtcbiAgICAgICAgIHRpdGxlOiAnTHVuY2gnLFxuICAgICAgICAgc3RhcnQ6ICcyMDIzLTAxLTEyVDEyOjAwOjAwJ1xuICAgICAgIH0sXG4gICAgICAge1xuICAgICAgICAgdGl0bGU6ICdNZWV0aW5nJyxcbiAgICAgICAgIHN0YXJ0OiAnMjAyMy0wMS0xMlQxNDozMDowMCdcbiAgICAgICB9LFxuICAgICAgIHtcbiAgICAgICAgIHRpdGxlOiAnSGFwcHkgSG91cicsXG4gICAgICAgICBzdGFydDogJzIwMjMtMDEtMTJUMTc6MzA6MDAnXG4gICAgICAgfSxcbiAgICAgICB7XG4gICAgICAgICB0aXRsZTogJ0Rpbm5lcicsXG4gICAgICAgICBzdGFydDogJzIwMjMtMDEtMTJUMjA6MDA6MDAnXG4gICAgICAgfSxcbiAgICAgICB7XG4gICAgICAgICB0aXRsZTogJ0JpcnRoZGF5IFBhcnR5JyxcbiAgICAgICAgIHN0YXJ0OiAnMjAyMy0wMS0xM1QwNzowMDowMCdcbiAgICAgICB9LFxuICAgICAgIHtcbiAgICAgICAgIHRpdGxlOiAnQ2xpY2sgZm9yIEdvb2dsZScsXG4gICAgICAgICB1cmw6ICdodHRwOi8vZ29vZ2xlLmNvbS8nLFxuICAgICAgICAgc3RhcnQ6ICcyMDIzLTAxLTI4J1xuICAgICAgIH1cbiAgICAgXVxuICAgfSk7XG5cbiAgIGNhbGVuZGFyLnJlbmRlcigpO1xuIH1cbn0pOyJdLCJuYW1lcyI6WyJDYWxlbmRhciIsImludGVyYWN0aW9uUGx1Z2luIiwiZGF5R3JpZFBsdWdpbiIsInRpbWVHcmlkUGx1Z2luIiwibGlzdFBsdWdpbiIsImRvY3VtZW50IiwiYWRkRXZlbnRMaXN0ZW5lciIsImNhbGVuZGFyRWwiLCJnZXRFbGVtZW50QnlJZCIsInVuZGVmaW5lZCIsImNhbGVuZGFyIiwicGx1Z2lucyIsImhlYWRlclRvb2xiYXIiLCJsZWZ0IiwiY2VudGVyIiwicmlnaHQiLCJpbml0aWFsRGF0ZSIsIm5hdkxpbmtzIiwiZWRpdGFibGUiLCJkYXlNYXhFdmVudHMiLCJldmVudHMiLCJ0aXRsZSIsInN0YXJ0IiwiZW5kIiwiZ3JvdXBJZCIsInVybCIsInJlbmRlciJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///111\n\n}");
/***/ }),
/***/ 112:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Calendar: () => (/* binding */ Calendar),\n/* harmony export */ JsonRequestError: () => (/* reexport safe */ _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.ae),\n/* harmony export */ createPlugin: () => (/* binding */ createPlugin),\n/* harmony export */ formatDate: () => (/* binding */ formatDate),\n/* harmony export */ formatRange: () => (/* binding */ formatRange),\n/* harmony export */ globalLocales: () => (/* binding */ globalLocales),\n/* harmony export */ globalPlugins: () => (/* binding */ globalPlugins),\n/* harmony export */ sliceEvents: () => (/* binding */ sliceEvents),\n/* harmony export */ version: () => (/* binding */ version)\n/* harmony export */ });\n/* harmony import */ var _internal_common_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(113);\n/* harmony import */ var preact__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(114);\n/* harmony import */ var preact_compat__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(115);\n\n\n\n\n\nconst globalLocales = [];\n\nconst MINIMAL_RAW_EN_LOCALE = {\n code: 'en',\n week: {\n dow: 0,\n doy: 4, // 4 days need to be within the year to be considered the first week\n },\n direction: 'ltr',\n buttonText: {\n prev: 'prev',\n next: 'next',\n prevYear: 'prev year',\n nextYear: 'next year',\n year: 'year',\n today: 'today',\n month: 'month',\n week: 'week',\n day: 'day',\n list: 'list',\n },\n weekText: 'W',\n weekTextLong: 'Week',\n closeHint: 'Close',\n timeHint: 'Time',\n eventHint: 'Event',\n allDayText: 'all-day',\n moreLinkText: 'more',\n noEventsText: 'No events to display',\n};\nconst RAW_EN_LOCALE = Object.assign(Object.assign({}, MINIMAL_RAW_EN_LOCALE), { \n // Includes things we don't want other locales to inherit,\n // things that derive from other translatable strings.\n buttonHints: {\n prev: 'Previous $0',\n next: 'Next $0',\n today(buttonText, unit) {\n return (unit === 'day')\n ? 'Today'\n : `This ${buttonText}`;\n },\n }, viewHint: '$0 view', navLinkHint: 'Go to $0', moreLinkHint(eventCnt) {\n return `Show ${eventCnt} more event${eventCnt === 1 ? '' : 's'}`;\n } });\nfunction organizeRawLocales(explicitRawLocales) {\n let defaultCode = explicitRawLocales.length > 0 ? explicitRawLocales[0].code : 'en';\n let allRawLocales = globalLocales.concat(explicitRawLocales);\n let rawLocaleMap = {\n en: RAW_EN_LOCALE,\n };\n for (let rawLocale of allRawLocales) {\n rawLocaleMap[rawLocale.code] = rawLocale;\n }\n return {\n map: rawLocaleMap,\n defaultCode,\n };\n}\nfunction buildLocale(inputSingular, available) {\n if (typeof inputSingular === 'object' && !Array.isArray(inputSingular)) {\n return parseLocale(inputSingular.code, [inputSingular.code], inputSingular);\n }\n return queryLocale(inputSingular, available);\n}\nfunction queryLocale(codeArg, available) {\n let codes = [].concat(codeArg || []); // will convert to array\n let raw = queryRawLocale(codes, available) || RAW_EN_LOCALE;\n return parseLocale(codeArg, codes, raw);\n}\nfunction queryRawLocale(codes, available) {\n for (let i = 0; i < codes.length; i += 1) {\n let parts = codes[i].toLocaleLowerCase().split('-');\n for (let j = parts.length; j > 0; j -= 1) {\n let simpleId = parts.slice(0, j).join('-');\n if (available[simpleId]) {\n return available[simpleId];\n }\n }\n }\n return null;\n}\nfunction parseLocale(codeArg, codes, raw) {\n let merged = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.m)([MINIMAL_RAW_EN_LOCALE, raw], ['buttonText']);\n delete merged.code; // don't want this part of the options\n let { week } = merged;\n delete merged.week;\n return {\n codeArg,\n codes,\n week,\n simpleNumberFormat: new Intl.NumberFormat(codeArg),\n options: merged,\n };\n}\n\n// TODO: easier way to add new hooks? need to update a million things\nfunction createPlugin(input) {\n return {\n id: (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.g)(),\n name: input.name,\n premiumReleaseDate: input.premiumReleaseDate ? new Date(input.premiumReleaseDate) : undefined,\n deps: input.deps || [],\n reducers: input.reducers || [],\n isLoadingFuncs: input.isLoadingFuncs || [],\n contextInit: [].concat(input.contextInit || []),\n eventRefiners: input.eventRefiners || {},\n eventDefMemberAdders: input.eventDefMemberAdders || [],\n eventSourceRefiners: input.eventSourceRefiners || {},\n isDraggableTransformers: input.isDraggableTransformers || [],\n eventDragMutationMassagers: input.eventDragMutationMassagers || [],\n eventDefMutationAppliers: input.eventDefMutationAppliers || [],\n dateSelectionTransformers: input.dateSelectionTransformers || [],\n datePointTransforms: input.datePointTransforms || [],\n dateSpanTransforms: input.dateSpanTransforms || [],\n views: input.views || {},\n viewPropsTransformers: input.viewPropsTransformers || [],\n isPropsValid: input.isPropsValid || null,\n externalDefTransforms: input.externalDefTransforms || [],\n viewContainerAppends: input.viewContainerAppends || [],\n eventDropTransformers: input.eventDropTransformers || [],\n componentInteractions: input.componentInteractions || [],\n calendarInteractions: input.calendarInteractions || [],\n themeClasses: input.themeClasses || {},\n eventSourceDefs: input.eventSourceDefs || [],\n cmdFormatter: input.cmdFormatter,\n recurringTypes: input.recurringTypes || [],\n namedTimeZonedImpl: input.namedTimeZonedImpl,\n initialView: input.initialView || '',\n elementDraggingImpl: input.elementDraggingImpl,\n optionChangeHandlers: input.optionChangeHandlers || {},\n scrollGridImpl: input.scrollGridImpl || null,\n listenerRefiners: input.listenerRefiners || {},\n optionRefiners: input.optionRefiners || {},\n propSetHandlers: input.propSetHandlers || {},\n };\n}\nfunction buildPluginHooks(pluginDefs, globalDefs) {\n let currentPluginIds = {};\n let hooks = {\n premiumReleaseDate: undefined,\n reducers: [],\n isLoadingFuncs: [],\n contextInit: [],\n eventRefiners: {},\n eventDefMemberAdders: [],\n eventSourceRefiners: {},\n isDraggableTransformers: [],\n eventDragMutationMassagers: [],\n eventDefMutationAppliers: [],\n dateSelectionTransformers: [],\n datePointTransforms: [],\n dateSpanTransforms: [],\n views: {},\n viewPropsTransformers: [],\n isPropsValid: null,\n externalDefTransforms: [],\n viewContainerAppends: [],\n eventDropTransformers: [],\n componentInteractions: [],\n calendarInteractions: [],\n themeClasses: {},\n eventSourceDefs: [],\n cmdFormatter: null,\n recurringTypes: [],\n namedTimeZonedImpl: null,\n initialView: '',\n elementDraggingImpl: null,\n optionChangeHandlers: {},\n scrollGridImpl: null,\n listenerRefiners: {},\n optionRefiners: {},\n propSetHandlers: {},\n };\n function addDefs(defs) {\n for (let def of defs) {\n const pluginName = def.name;\n const currentId = currentPluginIds[pluginName];\n if (currentId === undefined) {\n currentPluginIds[pluginName] = def.id;\n addDefs(def.deps);\n hooks = combineHooks(hooks, def);\n }\n else if (currentId !== def.id) {\n // different ID than the one already added\n console.warn(`Duplicate plugin '${pluginName}'`);\n }\n }\n }\n if (pluginDefs) {\n addDefs(pluginDefs);\n }\n addDefs(globalDefs);\n return hooks;\n}\nfunction buildBuildPluginHooks() {\n let currentOverrideDefs = [];\n let currentGlobalDefs = [];\n let currentHooks;\n return (overrideDefs, globalDefs) => {\n if (!currentHooks || !(0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.i)(overrideDefs, currentOverrideDefs) || !(0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.i)(globalDefs, currentGlobalDefs)) {\n currentHooks = buildPluginHooks(overrideDefs, globalDefs);\n }\n currentOverrideDefs = overrideDefs;\n currentGlobalDefs = globalDefs;\n return currentHooks;\n };\n}\nfunction combineHooks(hooks0, hooks1) {\n return {\n premiumReleaseDate: compareOptionalDates(hooks0.premiumReleaseDate, hooks1.premiumReleaseDate),\n reducers: hooks0.reducers.concat(hooks1.reducers),\n isLoadingFuncs: hooks0.isLoadingFuncs.concat(hooks1.isLoadingFuncs),\n contextInit: hooks0.contextInit.concat(hooks1.contextInit),\n eventRefiners: Object.assign(Object.assign({}, hooks0.eventRefiners), hooks1.eventRefiners),\n eventDefMemberAdders: hooks0.eventDefMemberAdders.concat(hooks1.eventDefMemberAdders),\n eventSourceRefiners: Object.assign(Object.assign({}, hooks0.eventSourceRefiners), hooks1.eventSourceRefiners),\n isDraggableTransformers: hooks0.isDraggableTransformers.concat(hooks1.isDraggableTransformers),\n eventDragMutationMassagers: hooks0.eventDragMutationMassagers.concat(hooks1.eventDragMutationMassagers),\n eventDefMutationAppliers: hooks0.eventDefMutationAppliers.concat(hooks1.eventDefMutationAppliers),\n dateSelectionTransformers: hooks0.dateSelectionTransformers.concat(hooks1.dateSelectionTransformers),\n datePointTransforms: hooks0.datePointTransforms.concat(hooks1.datePointTransforms),\n dateSpanTransforms: hooks0.dateSpanTransforms.concat(hooks1.dateSpanTransforms),\n views: Object.assign(Object.assign({}, hooks0.views), hooks1.views),\n viewPropsTransformers: hooks0.viewPropsTransformers.concat(hooks1.viewPropsTransformers),\n isPropsValid: hooks1.isPropsValid || hooks0.isPropsValid,\n externalDefTransforms: hooks0.externalDefTransforms.concat(hooks1.externalDefTransforms),\n viewContainerAppends: hooks0.viewContainerAppends.concat(hooks1.viewContainerAppends),\n eventDropTransformers: hooks0.eventDropTransformers.concat(hooks1.eventDropTransformers),\n calendarInteractions: hooks0.calendarInteractions.concat(hooks1.calendarInteractions),\n componentInteractions: hooks0.componentInteractions.concat(hooks1.componentInteractions),\n themeClasses: Object.assign(Object.assign({}, hooks0.themeClasses), hooks1.themeClasses),\n eventSourceDefs: hooks0.eventSourceDefs.concat(hooks1.eventSourceDefs),\n cmdFormatter: hooks1.cmdFormatter || hooks0.cmdFormatter,\n recurringTypes: hooks0.recurringTypes.concat(hooks1.recurringTypes),\n namedTimeZonedImpl: hooks1.namedTimeZonedImpl || hooks0.namedTimeZonedImpl,\n initialView: hooks0.initialView || hooks1.initialView,\n elementDraggingImpl: hooks0.elementDraggingImpl || hooks1.elementDraggingImpl,\n optionChangeHandlers: Object.assign(Object.assign({}, hooks0.optionChangeHandlers), hooks1.optionChangeHandlers),\n scrollGridImpl: hooks1.scrollGridImpl || hooks0.scrollGridImpl,\n listenerRefiners: Object.assign(Object.assign({}, hooks0.listenerRefiners), hooks1.listenerRefiners),\n optionRefiners: Object.assign(Object.assign({}, hooks0.optionRefiners), hooks1.optionRefiners),\n propSetHandlers: Object.assign(Object.assign({}, hooks0.propSetHandlers), hooks1.propSetHandlers),\n };\n}\nfunction compareOptionalDates(date0, date1) {\n if (date0 === undefined) {\n return date1;\n }\n if (date1 === undefined) {\n return date0;\n }\n return new Date(Math.max(date0.valueOf(), date1.valueOf()));\n}\n\nclass StandardTheme extends _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.T {\n}\nStandardTheme.prototype.classes = {\n root: 'fc-theme-standard',\n tableCellShaded: 'fc-cell-shaded',\n buttonGroup: 'fc-button-group',\n button: 'fc-button fc-button-primary',\n buttonActive: 'fc-button-active',\n};\nStandardTheme.prototype.baseIconClass = 'fc-icon';\nStandardTheme.prototype.iconClasses = {\n close: 'fc-icon-x',\n prev: 'fc-icon-chevron-left',\n next: 'fc-icon-chevron-right',\n prevYear: 'fc-icon-chevrons-left',\n nextYear: 'fc-icon-chevrons-right',\n};\nStandardTheme.prototype.rtlIconClasses = {\n prev: 'fc-icon-chevron-right',\n next: 'fc-icon-chevron-left',\n prevYear: 'fc-icon-chevrons-right',\n nextYear: 'fc-icon-chevrons-left',\n};\nStandardTheme.prototype.iconOverrideOption = 'buttonIcons'; // TODO: make TS-friendly\nStandardTheme.prototype.iconOverrideCustomButtonOption = 'icon';\nStandardTheme.prototype.iconOverridePrefix = 'fc-icon-';\n\nfunction compileViewDefs(defaultConfigs, overrideConfigs) {\n let hash = {};\n let viewType;\n for (viewType in defaultConfigs) {\n ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs);\n }\n for (viewType in overrideConfigs) {\n ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs);\n }\n return hash;\n}\nfunction ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs) {\n if (hash[viewType]) {\n return hash[viewType];\n }\n let viewDef = buildViewDef(viewType, hash, defaultConfigs, overrideConfigs);\n if (viewDef) {\n hash[viewType] = viewDef;\n }\n return viewDef;\n}\nfunction buildViewDef(viewType, hash, defaultConfigs, overrideConfigs) {\n let defaultConfig = defaultConfigs[viewType];\n let overrideConfig = overrideConfigs[viewType];\n let queryProp = (name) => ((defaultConfig && defaultConfig[name] !== null) ? defaultConfig[name] :\n ((overrideConfig && overrideConfig[name] !== null) ? overrideConfig[name] : null));\n let theComponent = queryProp('component');\n let superType = queryProp('superType');\n let superDef = null;\n if (superType) {\n if (superType === viewType) {\n throw new Error('Can\\'t have a custom view type that references itself');\n }\n superDef = ensureViewDef(superType, hash, defaultConfigs, overrideConfigs);\n }\n if (!theComponent && superDef) {\n theComponent = superDef.component;\n }\n if (!theComponent) {\n return null; // don't throw a warning, might be settings for a single-unit view\n }\n return {\n type: viewType,\n component: theComponent,\n defaults: Object.assign(Object.assign({}, (superDef ? superDef.defaults : {})), (defaultConfig ? defaultConfig.rawOptions : {})),\n overrides: Object.assign(Object.assign({}, (superDef ? superDef.overrides : {})), (overrideConfig ? overrideConfig.rawOptions : {})),\n };\n}\n\nfunction parseViewConfigs(inputs) {\n return (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a)(inputs, parseViewConfig);\n}\nfunction parseViewConfig(input) {\n let rawOptions = typeof input === 'function' ?\n { component: input } :\n input;\n let { component } = rawOptions;\n if (rawOptions.content) {\n // TODO: remove content/classNames/didMount/etc from options?\n component = createViewHookComponent(rawOptions);\n }\n else if (component && !(component.prototype instanceof _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.B)) {\n // WHY?: people were using `component` property for `content`\n // TODO: converge on one setting name\n component = createViewHookComponent(Object.assign(Object.assign({}, rawOptions), { content: component }));\n }\n return {\n superType: rawOptions.type,\n component: component,\n rawOptions, // includes type and component too :(\n };\n}\nfunction createViewHookComponent(options) {\n return (viewProps) => ((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.V.Consumer, null, (context) => ((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.C, { elTag: \"div\", elClasses: (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.b)(context.viewSpec), renderProps: Object.assign(Object.assign({}, viewProps), { nextDayThreshold: context.options.nextDayThreshold }), generatorName: undefined, customGenerator: options.content, classNameGenerator: options.classNames, didMount: options.didMount, willUnmount: options.willUnmount }))));\n}\n\nfunction buildViewSpecs(defaultInputs, optionOverrides, dynamicOptionOverrides, localeDefaults) {\n let defaultConfigs = parseViewConfigs(defaultInputs);\n let overrideConfigs = parseViewConfigs(optionOverrides.views);\n let viewDefs = compileViewDefs(defaultConfigs, overrideConfigs);\n return (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a)(viewDefs, (viewDef) => buildViewSpec(viewDef, overrideConfigs, optionOverrides, dynamicOptionOverrides, localeDefaults));\n}\nfunction buildViewSpec(viewDef, overrideConfigs, optionOverrides, dynamicOptionOverrides, localeDefaults) {\n let durationInput = viewDef.overrides.duration ||\n viewDef.defaults.duration ||\n dynamicOptionOverrides.duration ||\n optionOverrides.duration;\n let duration = null;\n let durationUnit = '';\n let singleUnit = '';\n let singleUnitOverrides = {};\n if (durationInput) {\n duration = createDurationCached(durationInput);\n if (duration) { // valid?\n let denom = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.c)(duration);\n durationUnit = denom.unit;\n if (denom.value === 1) {\n singleUnit = durationUnit;\n singleUnitOverrides = overrideConfigs[durationUnit] ? overrideConfigs[durationUnit].rawOptions : {};\n }\n }\n }\n let queryButtonText = (optionsSubset) => {\n let buttonTextMap = optionsSubset.buttonText || {};\n let buttonTextKey = viewDef.defaults.buttonTextKey;\n if (buttonTextKey != null && buttonTextMap[buttonTextKey] != null) {\n return buttonTextMap[buttonTextKey];\n }\n if (buttonTextMap[viewDef.type] != null) {\n return buttonTextMap[viewDef.type];\n }\n if (buttonTextMap[singleUnit] != null) {\n return buttonTextMap[singleUnit];\n }\n return null;\n };\n let queryButtonTitle = (optionsSubset) => {\n let buttonHints = optionsSubset.buttonHints || {};\n let buttonKey = viewDef.defaults.buttonTextKey; // use same key as text\n if (buttonKey != null && buttonHints[buttonKey] != null) {\n return buttonHints[buttonKey];\n }\n if (buttonHints[viewDef.type] != null) {\n return buttonHints[viewDef.type];\n }\n if (buttonHints[singleUnit] != null) {\n return buttonHints[singleUnit];\n }\n return null;\n };\n return {\n type: viewDef.type,\n component: viewDef.component,\n duration,\n durationUnit,\n singleUnit,\n optionDefaults: viewDef.defaults,\n optionOverrides: Object.assign(Object.assign({}, singleUnitOverrides), viewDef.overrides),\n buttonTextOverride: queryButtonText(dynamicOptionOverrides) ||\n queryButtonText(optionOverrides) || // constructor-specified buttonText lookup hash takes precedence\n viewDef.overrides.buttonText,\n buttonTextDefault: queryButtonText(localeDefaults) ||\n viewDef.defaults.buttonText ||\n queryButtonText(_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.e) ||\n viewDef.type,\n // not DRY\n buttonTitleOverride: queryButtonTitle(dynamicOptionOverrides) ||\n queryButtonTitle(optionOverrides) ||\n viewDef.overrides.buttonHint,\n buttonTitleDefault: queryButtonTitle(localeDefaults) ||\n viewDef.defaults.buttonHint ||\n queryButtonTitle(_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.e),\n // will eventually fall back to buttonText\n };\n}\n// hack to get memoization working\nlet durationInputMap = {};\nfunction createDurationCached(durationInput) {\n let json = JSON.stringify(durationInput);\n let res = durationInputMap[json];\n if (res === undefined) {\n res = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.d)(durationInput);\n durationInputMap[json] = res;\n }\n return res;\n}\n\nfunction reduceViewType(viewType, action) {\n switch (action.type) {\n case 'CHANGE_VIEW_TYPE':\n viewType = action.viewType;\n }\n return viewType;\n}\n\nfunction reduceCurrentDate(currentDate, action) {\n switch (action.type) {\n case 'CHANGE_DATE':\n return action.dateMarker;\n default:\n return currentDate;\n }\n}\n// should be initialized once and stay constant\n// this will change too\nfunction getInitialDate(options, dateEnv, nowManager) {\n let initialDateInput = options.initialDate;\n // compute the initial ambig-timezone date\n if (initialDateInput != null) {\n return dateEnv.createMarker(initialDateInput);\n }\n return nowManager.getDateMarker();\n}\n\nfunction reduceDynamicOptionOverrides(dynamicOptionOverrides, action) {\n switch (action.type) {\n case 'SET_OPTION':\n return Object.assign(Object.assign({}, dynamicOptionOverrides), { [action.optionName]: action.rawOptionValue });\n default:\n return dynamicOptionOverrides;\n }\n}\n\nfunction reduceDateProfile(currentDateProfile, action, currentDate, dateProfileGenerator) {\n let dp;\n switch (action.type) {\n case 'CHANGE_VIEW_TYPE':\n return dateProfileGenerator.build(action.dateMarker || currentDate);\n case 'CHANGE_DATE':\n return dateProfileGenerator.build(action.dateMarker);\n case 'PREV':\n dp = dateProfileGenerator.buildPrev(currentDateProfile, currentDate);\n if (dp.isValid) {\n return dp;\n }\n break;\n case 'NEXT':\n dp = dateProfileGenerator.buildNext(currentDateProfile, currentDate);\n if (dp.isValid) {\n return dp;\n }\n break;\n }\n return currentDateProfile;\n}\n\nfunction initEventSources(calendarOptions, dateProfile, context) {\n let activeRange = dateProfile ? dateProfile.activeRange : null;\n return addSources({}, parseInitialSources(calendarOptions, context), activeRange, context);\n}\nfunction reduceEventSources(eventSources, action, dateProfile, context) {\n let activeRange = dateProfile ? dateProfile.activeRange : null; // need this check?\n switch (action.type) {\n case 'ADD_EVENT_SOURCES': // already parsed\n return addSources(eventSources, action.sources, activeRange, context);\n case 'REMOVE_EVENT_SOURCE':\n return removeSource(eventSources, action.sourceId);\n case 'PREV': // TODO: how do we track all actions that affect dateProfile :(\n case 'NEXT':\n case 'CHANGE_DATE':\n case 'CHANGE_VIEW_TYPE':\n if (dateProfile) {\n return fetchDirtySources(eventSources, activeRange, context);\n }\n return eventSources;\n case 'FETCH_EVENT_SOURCES':\n return fetchSourcesByIds(eventSources, action.sourceIds ? // why no type?\n (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.f)(action.sourceIds) :\n excludeStaticSources(eventSources, context), activeRange, action.isRefetch || false, context);\n case 'RECEIVE_EVENTS':\n case 'RECEIVE_EVENT_ERROR':\n return receiveResponse(eventSources, action.sourceId, action.fetchId, action.fetchRange);\n case 'REMOVE_ALL_EVENT_SOURCES':\n return {};\n default:\n return eventSources;\n }\n}\nfunction reduceEventSourcesNewTimeZone(eventSources, dateProfile, context) {\n let activeRange = dateProfile ? dateProfile.activeRange : null; // need this check?\n return fetchSourcesByIds(eventSources, excludeStaticSources(eventSources, context), activeRange, true, context);\n}\nfunction computeEventSourcesLoading(eventSources) {\n for (let sourceId in eventSources) {\n if (eventSources[sourceId].isFetching) {\n return true;\n }\n }\n return false;\n}\nfunction addSources(eventSourceHash, sources, fetchRange, context) {\n let hash = {};\n for (let source of sources) {\n hash[source.sourceId] = source;\n }\n if (fetchRange) {\n hash = fetchDirtySources(hash, fetchRange, context);\n }\n return Object.assign(Object.assign({}, eventSourceHash), hash);\n}\nfunction removeSource(eventSourceHash, sourceId) {\n return (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.h)(eventSourceHash, (eventSource) => eventSource.sourceId !== sourceId);\n}\nfunction fetchDirtySources(sourceHash, fetchRange, context) {\n return fetchSourcesByIds(sourceHash, (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.h)(sourceHash, (eventSource) => isSourceDirty(eventSource, fetchRange, context)), fetchRange, false, context);\n}\nfunction isSourceDirty(eventSource, fetchRange, context) {\n if (!doesSourceNeedRange(eventSource, context)) {\n return !eventSource.latestFetchId;\n }\n return !context.options.lazyFetching ||\n !eventSource.fetchRange ||\n eventSource.isFetching || // always cancel outdated in-progress fetches\n fetchRange.start < eventSource.fetchRange.start ||\n fetchRange.end > eventSource.fetchRange.end;\n}\nfunction fetchSourcesByIds(prevSources, sourceIdHash, fetchRange, isRefetch, context) {\n let nextSources = {};\n for (let sourceId in prevSources) {\n let source = prevSources[sourceId];\n if (sourceIdHash[sourceId]) {\n nextSources[sourceId] = fetchSource(source, fetchRange, isRefetch, context);\n }\n else {\n nextSources[sourceId] = source;\n }\n }\n return nextSources;\n}\nfunction fetchSource(eventSource, fetchRange, isRefetch, context) {\n let { options, calendarApi } = context;\n let sourceDef = context.pluginHooks.eventSourceDefs[eventSource.sourceDefId];\n let fetchId = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.g)();\n sourceDef.fetch({\n eventSource,\n range: fetchRange,\n isRefetch,\n context,\n }, (res) => {\n let { rawEvents } = res;\n if (options.eventSourceSuccess) {\n rawEvents = options.eventSourceSuccess.call(calendarApi, rawEvents, res.response) || rawEvents;\n }\n if (eventSource.success) {\n rawEvents = eventSource.success.call(calendarApi, rawEvents, res.response) || rawEvents;\n }\n context.dispatch({\n type: 'RECEIVE_EVENTS',\n sourceId: eventSource.sourceId,\n fetchId,\n fetchRange,\n rawEvents,\n });\n }, (error) => {\n let errorHandled = false;\n if (options.eventSourceFailure) {\n options.eventSourceFailure.call(calendarApi, error);\n errorHandled = true;\n }\n if (eventSource.failure) {\n eventSource.failure(error);\n errorHandled = true;\n }\n if (!errorHandled) {\n console.warn(error.message, error);\n }\n context.dispatch({\n type: 'RECEIVE_EVENT_ERROR',\n sourceId: eventSource.sourceId,\n fetchId,\n fetchRange,\n error,\n });\n });\n return Object.assign(Object.assign({}, eventSource), { isFetching: true, latestFetchId: fetchId });\n}\nfunction receiveResponse(sourceHash, sourceId, fetchId, fetchRange) {\n let eventSource = sourceHash[sourceId];\n if (eventSource && // not already removed\n fetchId === eventSource.latestFetchId) {\n return Object.assign(Object.assign({}, sourceHash), { [sourceId]: Object.assign(Object.assign({}, eventSource), { isFetching: false, fetchRange }) });\n }\n return sourceHash;\n}\nfunction excludeStaticSources(eventSources, context) {\n return (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.h)(eventSources, (eventSource) => doesSourceNeedRange(eventSource, context));\n}\nfunction parseInitialSources(rawOptions, context) {\n let refiners = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.j)(context);\n let rawSources = [].concat(rawOptions.eventSources || []);\n let sources = []; // parsed\n if (rawOptions.initialEvents) {\n rawSources.unshift(rawOptions.initialEvents);\n }\n if (rawOptions.events) {\n rawSources.unshift(rawOptions.events);\n }\n for (let rawSource of rawSources) {\n let source = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.p)(rawSource, context, refiners);\n if (source) {\n sources.push(source);\n }\n }\n return sources;\n}\nfunction doesSourceNeedRange(eventSource, context) {\n let defs = context.pluginHooks.eventSourceDefs;\n return !defs[eventSource.sourceDefId].ignoreRange;\n}\n\nfunction reduceDateSelection(currentSelection, action) {\n switch (action.type) {\n case 'UNSELECT_DATES':\n return null;\n case 'SELECT_DATES':\n return action.selection;\n default:\n return currentSelection;\n }\n}\n\nfunction reduceSelectedEvent(currentInstanceId, action) {\n switch (action.type) {\n case 'UNSELECT_EVENT':\n return '';\n case 'SELECT_EVENT':\n return action.eventInstanceId;\n default:\n return currentInstanceId;\n }\n}\n\nfunction reduceEventDrag(currentDrag, action) {\n let newDrag;\n switch (action.type) {\n case 'UNSET_EVENT_DRAG':\n return null;\n case 'SET_EVENT_DRAG':\n newDrag = action.state;\n return {\n affectedEvents: newDrag.affectedEvents,\n mutatedEvents: newDrag.mutatedEvents,\n isEvent: newDrag.isEvent,\n };\n default:\n return currentDrag;\n }\n}\n\nfunction reduceEventResize(currentResize, action) {\n let newResize;\n switch (action.type) {\n case 'UNSET_EVENT_RESIZE':\n return null;\n case 'SET_EVENT_RESIZE':\n newResize = action.state;\n return {\n affectedEvents: newResize.affectedEvents,\n mutatedEvents: newResize.mutatedEvents,\n isEvent: newResize.isEvent,\n };\n default:\n return currentResize;\n }\n}\n\nfunction parseToolbars(calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) {\n let header = calendarOptions.headerToolbar ? parseToolbar(calendarOptions.headerToolbar, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) : null;\n let footer = calendarOptions.footerToolbar ? parseToolbar(calendarOptions.footerToolbar, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) : null;\n return { header, footer };\n}\nfunction parseToolbar(sectionStrHash, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) {\n let sectionWidgets = {};\n let viewsWithButtons = [];\n let hasTitle = false;\n for (let sectionName in sectionStrHash) {\n let sectionStr = sectionStrHash[sectionName];\n let sectionRes = parseSection(sectionStr, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi);\n sectionWidgets[sectionName] = sectionRes.widgets;\n viewsWithButtons.push(...sectionRes.viewsWithButtons);\n hasTitle = hasTitle || sectionRes.hasTitle;\n }\n return { sectionWidgets, viewsWithButtons, hasTitle };\n}\n/*\nBAD: querying icons and text here. should be done at render time\n*/\nfunction parseSection(sectionStr, calendarOptions, // defaults+overrides, then refined\ncalendarOptionOverrides, // overrides only!, unrefined :(\ntheme, viewSpecs, calendarApi) {\n let isRtl = calendarOptions.direction === 'rtl';\n let calendarCustomButtons = calendarOptions.customButtons || {};\n let calendarButtonTextOverrides = calendarOptionOverrides.buttonText || {};\n let calendarButtonText = calendarOptions.buttonText || {};\n let calendarButtonHintOverrides = calendarOptionOverrides.buttonHints || {};\n let calendarButtonHints = calendarOptions.buttonHints || {};\n let sectionSubstrs = sectionStr ? sectionStr.split(' ') : [];\n let viewsWithButtons = [];\n let hasTitle = false;\n let widgets = sectionSubstrs.map((buttonGroupStr) => (buttonGroupStr.split(',').map((buttonName) => {\n if (buttonName === 'title') {\n hasTitle = true;\n return { buttonName };\n }\n let customButtonProps;\n let viewSpec;\n let buttonClick;\n let buttonIcon; // only one of these will be set\n let buttonText; // \"\n let buttonHint;\n // ^ for the title=\"\" attribute, for accessibility\n if ((customButtonProps = calendarCustomButtons[buttonName])) {\n buttonClick = (ev) => {\n if (customButtonProps.click) {\n customButtonProps.click.call(ev.target, ev, ev.target); // TODO: use Calendar this context?\n }\n };\n (buttonIcon = theme.getCustomButtonIconClass(customButtonProps)) ||\n (buttonIcon = theme.getIconClass(buttonName, isRtl)) ||\n (buttonText = customButtonProps.text);\n buttonHint = customButtonProps.hint || customButtonProps.text;\n }\n else if ((viewSpec = viewSpecs[buttonName])) {\n viewsWithButtons.push(buttonName);\n buttonClick = () => {\n calendarApi.changeView(buttonName);\n };\n (buttonText = viewSpec.buttonTextOverride) ||\n (buttonIcon = theme.getIconClass(buttonName, isRtl)) ||\n (buttonText = viewSpec.buttonTextDefault);\n let textFallback = viewSpec.buttonTextOverride ||\n viewSpec.buttonTextDefault;\n buttonHint = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.k)(viewSpec.buttonTitleOverride ||\n viewSpec.buttonTitleDefault ||\n calendarOptions.viewHint, [textFallback, buttonName], // view-name = buttonName\n textFallback);\n }\n else if (calendarApi[buttonName]) { // a calendarApi method\n buttonClick = () => {\n calendarApi[buttonName]();\n };\n (buttonText = calendarButtonTextOverrides[buttonName]) ||\n (buttonIcon = theme.getIconClass(buttonName, isRtl)) ||\n (buttonText = calendarButtonText[buttonName]); // everything else is considered default\n if (buttonName === 'prevYear' || buttonName === 'nextYear') {\n let prevOrNext = buttonName === 'prevYear' ? 'prev' : 'next';\n buttonHint = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.k)(calendarButtonHintOverrides[prevOrNext] ||\n calendarButtonHints[prevOrNext], [\n calendarButtonText.year || 'year',\n 'year',\n ], calendarButtonText[buttonName]);\n }\n else {\n buttonHint = (navUnit) => (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.k)(calendarButtonHintOverrides[buttonName] ||\n calendarButtonHints[buttonName], [\n calendarButtonText[navUnit] || navUnit,\n navUnit,\n ], calendarButtonText[buttonName]);\n }\n }\n return { buttonName, buttonClick, buttonIcon, buttonText, buttonHint };\n })));\n return { widgets, viewsWithButtons, hasTitle };\n}\n\n// always represents the current view. otherwise, it'd need to change value every time date changes\nclass ViewImpl {\n constructor(type, getCurrentData, dateEnv) {\n this.type = type;\n this.getCurrentData = getCurrentData;\n this.dateEnv = dateEnv;\n }\n get calendar() {\n return this.getCurrentData().calendarApi;\n }\n get title() {\n return this.getCurrentData().viewTitle;\n }\n get activeStart() {\n return this.dateEnv.toDate(this.getCurrentData().dateProfile.activeRange.start);\n }\n get activeEnd() {\n return this.dateEnv.toDate(this.getCurrentData().dateProfile.activeRange.end);\n }\n get currentStart() {\n return this.dateEnv.toDate(this.getCurrentData().dateProfile.currentRange.start);\n }\n get currentEnd() {\n return this.dateEnv.toDate(this.getCurrentData().dateProfile.currentRange.end);\n }\n getOption(name) {\n return this.getCurrentData().options[name]; // are the view-specific options\n }\n}\n\nlet eventSourceDef$2 = {\n ignoreRange: true,\n parseMeta(refined) {\n if (Array.isArray(refined.events)) {\n return refined.events;\n }\n return null;\n },\n fetch(arg, successCallback) {\n successCallback({\n rawEvents: arg.eventSource.meta,\n });\n },\n};\nconst arrayEventSourcePlugin = createPlugin({\n name: 'array-event-source',\n eventSourceDefs: [eventSourceDef$2],\n});\n\nlet eventSourceDef$1 = {\n parseMeta(refined) {\n if (typeof refined.events === 'function') {\n return refined.events;\n }\n return null;\n },\n fetch(arg, successCallback, errorCallback) {\n const { dateEnv } = arg.context;\n const func = arg.eventSource.meta;\n (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.u)(func.bind(null, (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.l)(arg.range, dateEnv)), (rawEvents) => successCallback({ rawEvents }), errorCallback);\n },\n};\nconst funcEventSourcePlugin = createPlugin({\n name: 'func-event-source',\n eventSourceDefs: [eventSourceDef$1],\n});\n\nconst JSON_FEED_EVENT_SOURCE_REFINERS = {\n method: String,\n extraParams: _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.n,\n startParam: String,\n endParam: String,\n timeZoneParam: String,\n};\n\nlet eventSourceDef = {\n parseMeta(refined) {\n if (refined.url && (refined.format === 'json' || !refined.format)) {\n return {\n url: refined.url,\n format: 'json',\n method: (refined.method || 'GET').toUpperCase(),\n extraParams: refined.extraParams,\n startParam: refined.startParam,\n endParam: refined.endParam,\n timeZoneParam: refined.timeZoneParam,\n };\n }\n return null;\n },\n fetch(arg, successCallback, errorCallback) {\n const { meta } = arg.eventSource;\n const requestParams = buildRequestParams(meta, arg.range, arg.context);\n (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.r)(meta.method, meta.url, requestParams).then(([rawEvents, response]) => {\n successCallback({ rawEvents, response });\n }, errorCallback);\n },\n};\nconst jsonFeedEventSourcePlugin = createPlugin({\n name: 'json-event-source',\n eventSourceRefiners: JSON_FEED_EVENT_SOURCE_REFINERS,\n eventSourceDefs: [eventSourceDef],\n});\nfunction buildRequestParams(meta, range, context) {\n let { dateEnv, options } = context;\n let startParam;\n let endParam;\n let timeZoneParam;\n let customRequestParams;\n let params = {};\n startParam = meta.startParam;\n if (startParam == null) {\n startParam = options.startParam;\n }\n endParam = meta.endParam;\n if (endParam == null) {\n endParam = options.endParam;\n }\n timeZoneParam = meta.timeZoneParam;\n if (timeZoneParam == null) {\n timeZoneParam = options.timeZoneParam;\n }\n // retrieve any outbound GET/POST data from the options\n if (typeof meta.extraParams === 'function') {\n // supplied as a function that returns a key/value object\n customRequestParams = meta.extraParams();\n }\n else {\n // probably supplied as a straight key/value object\n customRequestParams = meta.extraParams || {};\n }\n Object.assign(params, customRequestParams);\n params[startParam] = dateEnv.formatIso(range.start);\n params[endParam] = dateEnv.formatIso(range.end);\n if (dateEnv.timeZone !== 'local') {\n params[timeZoneParam] = dateEnv.timeZone;\n }\n return params;\n}\n\nconst SIMPLE_RECURRING_REFINERS = {\n daysOfWeek: _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.n,\n startTime: _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.d,\n endTime: _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.d,\n duration: _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.d,\n startRecur: _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.n,\n endRecur: _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.n,\n};\n\nlet recurring = {\n parse(refined, dateEnv) {\n if (refined.daysOfWeek || refined.startTime || refined.endTime || refined.startRecur || refined.endRecur) {\n let recurringData = {\n daysOfWeek: refined.daysOfWeek || null,\n startTime: refined.startTime || null,\n endTime: refined.endTime || null,\n startRecur: refined.startRecur ? dateEnv.createMarker(refined.startRecur) : null,\n endRecur: refined.endRecur ? dateEnv.createMarker(refined.endRecur) : null,\n dateEnv,\n };\n let duration;\n if (refined.duration) {\n duration = refined.duration;\n }\n if (!duration && refined.startTime && refined.endTime) {\n duration = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.s)(refined.endTime, refined.startTime);\n }\n return {\n allDayGuess: Boolean(!refined.startTime && !refined.endTime),\n duration,\n typeData: recurringData, // doesn't need endTime anymore but oh well\n };\n }\n return null;\n },\n expand(typeData, framingRange, dateEnv) {\n let clippedFramingRange = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.o)(framingRange, { start: typeData.startRecur, end: typeData.endRecur });\n if (clippedFramingRange) {\n return expandRanges(typeData.daysOfWeek, typeData.startTime, typeData.dateEnv, dateEnv, clippedFramingRange);\n }\n return [];\n },\n};\nconst simpleRecurringEventsPlugin = createPlugin({\n name: 'simple-recurring-event',\n recurringTypes: [recurring],\n eventRefiners: SIMPLE_RECURRING_REFINERS,\n});\nfunction expandRanges(daysOfWeek, startTime, eventDateEnv, calendarDateEnv, framingRange) {\n let dowHash = daysOfWeek ? (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.f)(daysOfWeek) : null;\n let dayMarker = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.q)(framingRange.start);\n let endMarker = framingRange.end;\n let instanceStarts = [];\n // https://github.com/fullcalendar/fullcalendar/issues/7934\n if (startTime) {\n if (startTime.milliseconds < 0) {\n // possible for next-day to have negative business hours that go into current day\n endMarker = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.t)(endMarker, 1);\n }\n else if (startTime.milliseconds >= 1000 * 60 * 60 * 24) {\n // possible for prev-day to have >24hr business hours that go into current day\n dayMarker = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.t)(dayMarker, -1);\n }\n }\n while (dayMarker < endMarker) {\n let instanceStart;\n // if everyday, or this particular day-of-week\n if (!dowHash || dowHash[dayMarker.getUTCDay()]) {\n if (startTime) {\n instanceStart = calendarDateEnv.add(dayMarker, startTime);\n }\n else {\n instanceStart = dayMarker;\n }\n instanceStarts.push(calendarDateEnv.createMarker(eventDateEnv.toDate(instanceStart)));\n }\n dayMarker = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.t)(dayMarker, 1);\n }\n return instanceStarts;\n}\n\nconst changeHandlerPlugin = createPlugin({\n name: 'change-handler',\n optionChangeHandlers: {\n events(events, context) {\n handleEventSources([events], context);\n },\n eventSources: handleEventSources,\n },\n});\n/*\nBUG: if `event` was supplied, all previously-given `eventSources` will be wiped out\n*/\nfunction handleEventSources(inputs, context) {\n let unfoundSources = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.v)(context.getCurrentData().eventSources);\n if (unfoundSources.length === 1 &&\n inputs.length === 1 &&\n Array.isArray(unfoundSources[0]._raw) &&\n Array.isArray(inputs[0])) {\n context.dispatch({\n type: 'RESET_RAW_EVENTS',\n sourceId: unfoundSources[0].sourceId,\n rawEvents: inputs[0],\n });\n return;\n }\n let newInputs = [];\n for (let input of inputs) {\n let inputFound = false;\n for (let i = 0; i < unfoundSources.length; i += 1) {\n if (unfoundSources[i]._raw === input) {\n unfoundSources.splice(i, 1); // delete\n inputFound = true;\n break;\n }\n }\n if (!inputFound) {\n newInputs.push(input);\n }\n }\n for (let unfoundSource of unfoundSources) {\n context.dispatch({\n type: 'REMOVE_EVENT_SOURCE',\n sourceId: unfoundSource.sourceId,\n });\n }\n for (let newInput of newInputs) {\n context.calendarApi.addEventSource(newInput);\n }\n}\n\nfunction handleDateProfile(dateProfile, context) {\n context.emitter.trigger('datesSet', Object.assign(Object.assign({}, (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.l)(dateProfile.activeRange, context.dateEnv)), { view: context.viewApi }));\n}\n\nfunction handleEventStore(eventStore, context) {\n let { emitter } = context;\n if (emitter.hasHandlers('eventsSet')) {\n emitter.trigger('eventsSet', (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.w)(eventStore, context));\n }\n}\n\n/*\nthis array is exposed on the root namespace so that UMD plugins can add to it.\nsee the rollup-bundles script.\n*/\nconst globalPlugins = [\n arrayEventSourcePlugin,\n funcEventSourcePlugin,\n jsonFeedEventSourcePlugin,\n simpleRecurringEventsPlugin,\n changeHandlerPlugin,\n createPlugin({\n name: 'misc',\n isLoadingFuncs: [\n (state) => computeEventSourcesLoading(state.eventSources),\n ],\n propSetHandlers: {\n dateProfile: handleDateProfile,\n eventStore: handleEventStore,\n },\n }),\n];\n\nclass TaskRunner {\n constructor(runTaskOption, drainedOption) {\n this.runTaskOption = runTaskOption;\n this.drainedOption = drainedOption;\n this.queue = [];\n this.delayedRunner = new _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.D(this.drain.bind(this));\n }\n request(task, delay) {\n this.queue.push(task);\n this.delayedRunner.request(delay);\n }\n pause(scope) {\n this.delayedRunner.pause(scope);\n }\n resume(scope, force) {\n this.delayedRunner.resume(scope, force);\n }\n drain() {\n let { queue } = this;\n while (queue.length) {\n let completedTasks = [];\n let task;\n while ((task = queue.shift())) {\n this.runTask(task);\n completedTasks.push(task);\n }\n this.drained(completedTasks);\n } // keep going, in case new tasks were added in the drained handler\n }\n runTask(task) {\n if (this.runTaskOption) {\n this.runTaskOption(task);\n }\n }\n drained(completedTasks) {\n if (this.drainedOption) {\n this.drainedOption(completedTasks);\n }\n }\n}\n\n// Computes what the title at the top of the calendarApi should be for this view\nfunction buildTitle(dateProfile, viewOptions, dateEnv) {\n let range;\n // for views that span a large unit of time, show the proper interval, ignoring stray days before and after\n if (/^(year|month)$/.test(dateProfile.currentRangeUnit)) {\n range = dateProfile.currentRange;\n }\n else { // for day units or smaller, use the actual day range\n range = dateProfile.activeRange;\n }\n return dateEnv.formatRange(range.start, range.end, (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.x)(viewOptions.titleFormat || buildTitleFormat(dateProfile)), {\n isEndExclusive: dateProfile.isRangeAllDay,\n defaultSeparator: viewOptions.titleRangeSeparator,\n });\n}\n// Generates the format string that should be used to generate the title for the current date range.\n// Attempts to compute the most appropriate format if not explicitly specified with `titleFormat`.\nfunction buildTitleFormat(dateProfile) {\n let { currentRangeUnit } = dateProfile;\n if (currentRangeUnit === 'year') {\n return { year: 'numeric' };\n }\n if (currentRangeUnit === 'month') {\n return { year: 'numeric', month: 'long' }; // like \"September 2014\"\n }\n let days = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.y)(dateProfile.currentRange.start, dateProfile.currentRange.end);\n if (days !== null && days > 1) {\n // multi-day range. shorter, like \"Sep 9 - 10 2014\"\n return { year: 'numeric', month: 'short', day: 'numeric' };\n }\n // one day. longer, like \"September 9 2014\"\n return { year: 'numeric', month: 'long', day: 'numeric' };\n}\n\n/*\nTODO: test switching timezones when NO timezone plugin\n*/\nclass CalendarNowManager {\n constructor() {\n this.resetListeners = new Set();\n }\n handleInput(dateEnv, // will change if timezone setup changed\n nowInput) {\n const oldDateEnv = this.dateEnv;\n if (dateEnv !== oldDateEnv) {\n if (typeof nowInput === 'function') {\n this.nowFn = nowInput;\n }\n else if (!oldDateEnv) { // first time?\n this.nowAnchorDate = dateEnv.toDate(nowInput\n ? dateEnv.createMarker(nowInput)\n : dateEnv.createNowMarker());\n this.nowAnchorQueried = Date.now();\n }\n this.dateEnv = dateEnv;\n // not first time? fire reset handlers\n if (oldDateEnv) {\n for (const resetListener of this.resetListeners.values()) {\n resetListener();\n }\n }\n }\n }\n getDateMarker() {\n return this.nowAnchorDate\n ? this.dateEnv.timestampToMarker(this.nowAnchorDate.valueOf() +\n (Date.now() - this.nowAnchorQueried))\n : this.dateEnv.createMarker(this.nowFn());\n }\n addResetListener(handler) {\n this.resetListeners.add(handler);\n }\n removeResetListener(handler) {\n this.resetListeners.delete(handler);\n }\n}\n\n// in future refactor, do the redux-style function(state=initial) for initial-state\n// also, whatever is happening in constructor, have it happen in action queue too\nclass CalendarDataManager {\n constructor(props) {\n this.computeCurrentViewData = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(this._computeCurrentViewData);\n this.organizeRawLocales = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(organizeRawLocales);\n this.buildLocale = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildLocale);\n this.buildPluginHooks = buildBuildPluginHooks();\n this.buildDateEnv = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildDateEnv$1);\n this.buildTheme = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildTheme);\n this.parseToolbars = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(parseToolbars);\n this.buildViewSpecs = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildViewSpecs);\n this.buildDateProfileGenerator = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.A)(buildDateProfileGenerator);\n this.buildViewApi = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildViewApi);\n this.buildViewUiProps = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.A)(buildViewUiProps);\n this.buildEventUiBySource = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildEventUiBySource, _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.E);\n this.buildEventUiBases = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildEventUiBases);\n this.parseContextBusinessHours = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.A)(parseContextBusinessHours);\n this.buildTitle = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildTitle);\n this.nowManager = new CalendarNowManager();\n this.emitter = new _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.F();\n this.actionRunner = new TaskRunner(this._handleAction.bind(this), this.updateData.bind(this));\n this.currentCalendarOptionsInput = {};\n this.currentCalendarOptionsRefined = {};\n this.currentViewOptionsInput = {};\n this.currentViewOptionsRefined = {};\n this.currentCalendarOptionsRefiners = {};\n this.optionsForRefining = [];\n this.optionsForHandling = [];\n this.getCurrentData = () => this.data;\n this.dispatch = (action) => {\n this.actionRunner.request(action); // protects against recursive calls to _handleAction\n };\n this.props = props;\n this.actionRunner.pause();\n this.nowManager = new CalendarNowManager();\n let dynamicOptionOverrides = {};\n let optionsData = this.computeOptionsData(props.optionOverrides, dynamicOptionOverrides, props.calendarApi);\n let currentViewType = optionsData.calendarOptions.initialView || optionsData.pluginHooks.initialView;\n let currentViewData = this.computeCurrentViewData(currentViewType, optionsData, props.optionOverrides, dynamicOptionOverrides);\n // wire things up\n // TODO: not DRY\n props.calendarApi.currentDataManager = this;\n this.emitter.setThisContext(props.calendarApi);\n this.emitter.setOptions(currentViewData.options);\n let calendarContext = {\n nowManager: this.nowManager,\n dateEnv: optionsData.dateEnv,\n options: optionsData.calendarOptions,\n pluginHooks: optionsData.pluginHooks,\n calendarApi: props.calendarApi,\n dispatch: this.dispatch,\n emitter: this.emitter,\n getCurrentData: this.getCurrentData,\n };\n let currentDate = getInitialDate(optionsData.calendarOptions, optionsData.dateEnv, this.nowManager);\n let dateProfile = currentViewData.dateProfileGenerator.build(currentDate);\n if (!(0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.G)(dateProfile.activeRange, currentDate)) {\n currentDate = dateProfile.currentRange.start;\n }\n // needs to be after setThisContext\n for (let callback of optionsData.pluginHooks.contextInit) {\n callback(calendarContext);\n }\n // NOT DRY\n let eventSources = initEventSources(optionsData.calendarOptions, dateProfile, calendarContext);\n let initialState = {\n dynamicOptionOverrides,\n currentViewType,\n currentDate,\n dateProfile,\n businessHours: this.parseContextBusinessHours(calendarContext),\n eventSources,\n eventUiBases: {},\n eventStore: (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.H)(),\n renderableEventStore: (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.H)(),\n dateSelection: null,\n eventSelection: '',\n eventDrag: null,\n eventResize: null,\n selectionConfig: this.buildViewUiProps(calendarContext).selectionConfig,\n };\n let contextAndState = Object.assign(Object.assign({}, calendarContext), initialState);\n for (let reducer of optionsData.pluginHooks.reducers) {\n Object.assign(initialState, reducer(null, null, contextAndState));\n }\n if (computeIsLoading(initialState, calendarContext)) {\n this.emitter.trigger('loading', true); // NOT DRY\n }\n this.state = initialState;\n this.updateData();\n this.actionRunner.resume();\n }\n resetOptions(optionOverrides, changedOptionNames) {\n let { props } = this;\n if (changedOptionNames === undefined) {\n props.optionOverrides = optionOverrides;\n }\n else {\n props.optionOverrides = Object.assign(Object.assign({}, (props.optionOverrides || {})), optionOverrides);\n this.optionsForRefining.push(...changedOptionNames);\n }\n if (changedOptionNames === undefined || changedOptionNames.length) {\n this.actionRunner.request({\n type: 'NOTHING',\n });\n }\n }\n _handleAction(action) {\n let { props, state, emitter } = this;\n let dynamicOptionOverrides = reduceDynamicOptionOverrides(state.dynamicOptionOverrides, action);\n let optionsData = this.computeOptionsData(props.optionOverrides, dynamicOptionOverrides, props.calendarApi);\n let currentViewType = reduceViewType(state.currentViewType, action);\n let currentViewData = this.computeCurrentViewData(currentViewType, optionsData, props.optionOverrides, dynamicOptionOverrides);\n // wire things up\n // TODO: not DRY\n props.calendarApi.currentDataManager = this;\n emitter.setThisContext(props.calendarApi);\n emitter.setOptions(currentViewData.options);\n let calendarContext = {\n nowManager: this.nowManager,\n dateEnv: optionsData.dateEnv,\n options: optionsData.calendarOptions,\n pluginHooks: optionsData.pluginHooks,\n calendarApi: props.calendarApi,\n dispatch: this.dispatch,\n emitter,\n getCurrentData: this.getCurrentData,\n };\n let { currentDate, dateProfile } = state;\n if (this.data && this.data.dateProfileGenerator !== currentViewData.dateProfileGenerator) { // hack\n dateProfile = currentViewData.dateProfileGenerator.build(currentDate);\n }\n currentDate = reduceCurrentDate(currentDate, action);\n dateProfile = reduceDateProfile(dateProfile, action, currentDate, currentViewData.dateProfileGenerator);\n if (action.type === 'PREV' || // TODO: move this logic into DateProfileGenerator\n action.type === 'NEXT' || // \"\n !(0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.G)(dateProfile.currentRange, currentDate)) {\n currentDate = dateProfile.currentRange.start;\n }\n let eventSources = reduceEventSources(state.eventSources, action, dateProfile, calendarContext);\n let eventStore = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.I)(state.eventStore, action, eventSources, dateProfile, calendarContext);\n let isEventsLoading = computeEventSourcesLoading(eventSources); // BAD. also called in this func in computeIsLoading\n let renderableEventStore = (isEventsLoading && !currentViewData.options.progressiveEventRendering) ?\n (state.renderableEventStore || eventStore) : // try from previous state\n eventStore;\n let { eventUiSingleBase, selectionConfig } = this.buildViewUiProps(calendarContext); // will memoize obj\n let eventUiBySource = this.buildEventUiBySource(eventSources);\n let eventUiBases = this.buildEventUiBases(renderableEventStore.defs, eventUiSingleBase, eventUiBySource);\n let newState = {\n dynamicOptionOverrides,\n currentViewType,\n currentDate,\n dateProfile,\n eventSources,\n eventStore,\n renderableEventStore,\n selectionConfig,\n eventUiBases,\n businessHours: this.parseContextBusinessHours(calendarContext),\n dateSelection: reduceDateSelection(state.dateSelection, action),\n eventSelection: reduceSelectedEvent(state.eventSelection, action),\n eventDrag: reduceEventDrag(state.eventDrag, action),\n eventResize: reduceEventResize(state.eventResize, action),\n };\n let contextAndState = Object.assign(Object.assign({}, calendarContext), newState);\n for (let reducer of optionsData.pluginHooks.reducers) {\n Object.assign(newState, reducer(state, action, contextAndState)); // give the OLD state, for old value\n }\n let wasLoading = computeIsLoading(state, calendarContext);\n let isLoading = computeIsLoading(newState, calendarContext);\n // TODO: use propSetHandlers in plugin system\n if (!wasLoading && isLoading) {\n emitter.trigger('loading', true);\n }\n else if (wasLoading && !isLoading) {\n emitter.trigger('loading', false);\n }\n this.state = newState;\n if (props.onAction) {\n props.onAction(action);\n }\n }\n updateData() {\n let { props, state } = this;\n let oldData = this.data;\n let optionsData = this.computeOptionsData(props.optionOverrides, state.dynamicOptionOverrides, props.calendarApi);\n let currentViewData = this.computeCurrentViewData(state.currentViewType, optionsData, props.optionOverrides, state.dynamicOptionOverrides);\n let data = this.data = Object.assign(Object.assign(Object.assign({ nowManager: this.nowManager, viewTitle: this.buildTitle(state.dateProfile, currentViewData.options, optionsData.dateEnv), calendarApi: props.calendarApi, dispatch: this.dispatch, emitter: this.emitter, getCurrentData: this.getCurrentData }, optionsData), currentViewData), state);\n let changeHandlers = optionsData.pluginHooks.optionChangeHandlers;\n let oldCalendarOptions = oldData && oldData.calendarOptions;\n let newCalendarOptions = optionsData.calendarOptions;\n if (oldCalendarOptions && oldCalendarOptions !== newCalendarOptions) {\n if (oldCalendarOptions.timeZone !== newCalendarOptions.timeZone) {\n // hack\n state.eventSources = data.eventSources = reduceEventSourcesNewTimeZone(data.eventSources, state.dateProfile, data);\n state.eventStore = data.eventStore = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.J)(data.eventStore, oldData.dateEnv, data.dateEnv);\n state.renderableEventStore = data.renderableEventStore = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.J)(data.renderableEventStore, oldData.dateEnv, data.dateEnv);\n }\n for (let optionName in changeHandlers) {\n if (this.optionsForHandling.indexOf(optionName) !== -1 ||\n oldCalendarOptions[optionName] !== newCalendarOptions[optionName]) {\n changeHandlers[optionName](newCalendarOptions[optionName], data);\n }\n }\n }\n this.optionsForHandling = [];\n if (props.onData) {\n props.onData(data);\n }\n }\n computeOptionsData(optionOverrides, dynamicOptionOverrides, calendarApi) {\n // TODO: blacklist options that are handled by optionChangeHandlers\n if (!this.optionsForRefining.length &&\n optionOverrides === this.stableOptionOverrides &&\n dynamicOptionOverrides === this.stableDynamicOptionOverrides) {\n return this.stableCalendarOptionsData;\n }\n let { refinedOptions, pluginHooks, localeDefaults, availableLocaleData, extra, } = this.processRawCalendarOptions(optionOverrides, dynamicOptionOverrides);\n warnUnknownOptions(extra);\n let dateEnv = this.buildDateEnv(refinedOptions.timeZone, refinedOptions.locale, refinedOptions.weekNumberCalculation, refinedOptions.firstDay, refinedOptions.weekText, pluginHooks, availableLocaleData, refinedOptions.defaultRangeSeparator);\n let viewSpecs = this.buildViewSpecs(pluginHooks.views, this.stableOptionOverrides, this.stableDynamicOptionOverrides, localeDefaults);\n let theme = this.buildTheme(refinedOptions, pluginHooks);\n let toolbarConfig = this.parseToolbars(refinedOptions, this.stableOptionOverrides, theme, viewSpecs, calendarApi);\n return this.stableCalendarOptionsData = {\n calendarOptions: refinedOptions,\n pluginHooks,\n dateEnv,\n viewSpecs,\n theme,\n toolbarConfig,\n localeDefaults,\n availableRawLocales: availableLocaleData.map,\n };\n }\n // always called from behind a memoizer\n processRawCalendarOptions(optionOverrides, dynamicOptionOverrides) {\n let { locales, locale } = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.K)([\n _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.e,\n optionOverrides,\n dynamicOptionOverrides,\n ]);\n let availableLocaleData = this.organizeRawLocales(locales);\n let availableRawLocales = availableLocaleData.map;\n let localeDefaults = this.buildLocale(locale || availableLocaleData.defaultCode, availableRawLocales).options;\n let pluginHooks = this.buildPluginHooks(optionOverrides.plugins || [], globalPlugins);\n let refiners = this.currentCalendarOptionsRefiners = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.L), _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.M), _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.N), pluginHooks.listenerRefiners), pluginHooks.optionRefiners);\n let extra = {};\n let raw = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.K)([\n _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.e,\n localeDefaults,\n optionOverrides,\n dynamicOptionOverrides,\n ]);\n let refined = {};\n let currentRaw = this.currentCalendarOptionsInput;\n let currentRefined = this.currentCalendarOptionsRefined;\n let anyChanges = false;\n for (let optionName in raw) {\n if (this.optionsForRefining.indexOf(optionName) === -1 && (raw[optionName] === currentRaw[optionName] || (_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.O[optionName] &&\n (optionName in currentRaw) &&\n _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.O[optionName](currentRaw[optionName], raw[optionName])))) {\n refined[optionName] = currentRefined[optionName];\n }\n else if (refiners[optionName]) {\n refined[optionName] = refiners[optionName](raw[optionName]);\n anyChanges = true;\n }\n else {\n extra[optionName] = currentRaw[optionName];\n }\n }\n if (anyChanges) {\n this.currentCalendarOptionsInput = raw;\n this.currentCalendarOptionsRefined = refined;\n this.stableOptionOverrides = optionOverrides;\n this.stableDynamicOptionOverrides = dynamicOptionOverrides;\n }\n this.optionsForHandling.push(...this.optionsForRefining);\n this.optionsForRefining = [];\n return {\n rawOptions: this.currentCalendarOptionsInput,\n refinedOptions: this.currentCalendarOptionsRefined,\n pluginHooks,\n availableLocaleData,\n localeDefaults,\n extra,\n };\n }\n _computeCurrentViewData(viewType, optionsData, optionOverrides, dynamicOptionOverrides) {\n let viewSpec = optionsData.viewSpecs[viewType];\n if (!viewSpec) {\n throw new Error(`viewType \"${viewType}\" is not available. Please make sure you've loaded all neccessary plugins`);\n }\n let { refinedOptions, extra } = this.processRawViewOptions(viewSpec, optionsData.pluginHooks, optionsData.localeDefaults, optionOverrides, dynamicOptionOverrides);\n warnUnknownOptions(extra);\n this.nowManager.handleInput(optionsData.dateEnv, refinedOptions.now);\n let dateProfileGenerator = this.buildDateProfileGenerator({\n dateProfileGeneratorClass: viewSpec.optionDefaults.dateProfileGeneratorClass,\n nowManager: this.nowManager,\n duration: viewSpec.duration,\n durationUnit: viewSpec.durationUnit,\n usesMinMaxTime: viewSpec.optionDefaults.usesMinMaxTime,\n dateEnv: optionsData.dateEnv,\n calendarApi: this.props.calendarApi,\n slotMinTime: refinedOptions.slotMinTime,\n slotMaxTime: refinedOptions.slotMaxTime,\n showNonCurrentDates: refinedOptions.showNonCurrentDates,\n dayCount: refinedOptions.dayCount,\n dateAlignment: refinedOptions.dateAlignment,\n dateIncrement: refinedOptions.dateIncrement,\n hiddenDays: refinedOptions.hiddenDays,\n weekends: refinedOptions.weekends,\n validRangeInput: refinedOptions.validRange,\n visibleRangeInput: refinedOptions.visibleRange,\n fixedWeekCount: refinedOptions.fixedWeekCount,\n });\n let viewApi = this.buildViewApi(viewType, this.getCurrentData, optionsData.dateEnv);\n return { viewSpec, options: refinedOptions, dateProfileGenerator, viewApi };\n }\n processRawViewOptions(viewSpec, pluginHooks, localeDefaults, optionOverrides, dynamicOptionOverrides) {\n let raw = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.K)([\n _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.e,\n viewSpec.optionDefaults,\n localeDefaults,\n optionOverrides,\n viewSpec.optionOverrides,\n dynamicOptionOverrides,\n ]);\n let refiners = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.L), _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.M), _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.N), _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.P), pluginHooks.listenerRefiners), pluginHooks.optionRefiners);\n let refined = {};\n let currentRaw = this.currentViewOptionsInput;\n let currentRefined = this.currentViewOptionsRefined;\n let anyChanges = false;\n let extra = {};\n for (let optionName in raw) {\n if (raw[optionName] === currentRaw[optionName] ||\n (_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.O[optionName] &&\n _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.O[optionName](raw[optionName], currentRaw[optionName]))) {\n refined[optionName] = currentRefined[optionName];\n }\n else {\n if (raw[optionName] === this.currentCalendarOptionsInput[optionName] ||\n (_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.O[optionName] &&\n _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.O[optionName](raw[optionName], this.currentCalendarOptionsInput[optionName]))) {\n if (optionName in this.currentCalendarOptionsRefined) { // might be an \"extra\" prop\n refined[optionName] = this.currentCalendarOptionsRefined[optionName];\n }\n }\n else if (refiners[optionName]) {\n refined[optionName] = refiners[optionName](raw[optionName]);\n }\n else {\n extra[optionName] = raw[optionName];\n }\n anyChanges = true;\n }\n }\n if (anyChanges) {\n this.currentViewOptionsInput = raw;\n this.currentViewOptionsRefined = refined;\n }\n return {\n rawOptions: this.currentViewOptionsInput,\n refinedOptions: this.currentViewOptionsRefined,\n extra,\n };\n }\n}\nfunction buildDateEnv$1(timeZone, explicitLocale, weekNumberCalculation, firstDay, weekText, pluginHooks, availableLocaleData, defaultSeparator) {\n let locale = buildLocale(explicitLocale || availableLocaleData.defaultCode, availableLocaleData.map);\n return new _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.Q({\n calendarSystem: 'gregory',\n timeZone,\n namedTimeZoneImpl: pluginHooks.namedTimeZonedImpl,\n locale,\n weekNumberCalculation,\n firstDay,\n weekText,\n cmdFormatter: pluginHooks.cmdFormatter,\n defaultSeparator,\n });\n}\nfunction buildTheme(options, pluginHooks) {\n let ThemeClass = pluginHooks.themeClasses[options.themeSystem] || StandardTheme;\n return new ThemeClass(options);\n}\nfunction buildDateProfileGenerator(props) {\n let DateProfileGeneratorClass = props.dateProfileGeneratorClass || _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.R;\n return new DateProfileGeneratorClass(props);\n}\nfunction buildViewApi(type, getCurrentData, dateEnv) {\n return new ViewImpl(type, getCurrentData, dateEnv);\n}\nfunction buildEventUiBySource(eventSources) {\n return (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a)(eventSources, (eventSource) => eventSource.ui);\n}\nfunction buildEventUiBases(eventDefs, eventUiSingleBase, eventUiBySource) {\n let eventUiBases = { '': eventUiSingleBase };\n for (let defId in eventDefs) {\n let def = eventDefs[defId];\n if (def.sourceId && eventUiBySource[def.sourceId]) {\n eventUiBases[defId] = eventUiBySource[def.sourceId];\n }\n }\n return eventUiBases;\n}\nfunction buildViewUiProps(calendarContext) {\n let { options } = calendarContext;\n return {\n eventUiSingleBase: (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.S)({\n display: options.eventDisplay,\n editable: options.editable,\n startEditable: options.eventStartEditable,\n durationEditable: options.eventDurationEditable,\n constraint: options.eventConstraint,\n overlap: typeof options.eventOverlap === 'boolean' ? options.eventOverlap : undefined,\n allow: options.eventAllow,\n backgroundColor: options.eventBackgroundColor,\n borderColor: options.eventBorderColor,\n textColor: options.eventTextColor,\n color: options.eventColor,\n // classNames: options.eventClassNames // render hook will handle this\n }, calendarContext),\n selectionConfig: (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.S)({\n constraint: options.selectConstraint,\n overlap: typeof options.selectOverlap === 'boolean' ? options.selectOverlap : undefined,\n allow: options.selectAllow,\n }, calendarContext),\n };\n}\nfunction computeIsLoading(state, context) {\n for (let isLoadingFunc of context.pluginHooks.isLoadingFuncs) {\n if (isLoadingFunc(state)) {\n return true;\n }\n }\n return false;\n}\nfunction parseContextBusinessHours(calendarContext) {\n return (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.U)(calendarContext.options.businessHours, calendarContext);\n}\nfunction warnUnknownOptions(options, viewName) {\n for (let optionName in options) {\n console.warn(`Unknown option '${optionName}'` +\n (viewName ? ` for view '${viewName}'` : ''));\n }\n}\n\nclass ToolbarSection extends _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.B {\n render() {\n let children = this.props.widgetGroups.map((widgetGroup) => this.renderWidgetGroup(widgetGroup));\n return (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)('div', { className: 'fc-toolbar-chunk' }, ...children);\n }\n renderWidgetGroup(widgetGroup) {\n let { props } = this;\n let { theme } = this.context;\n let children = [];\n let isOnlyButtons = true;\n for (let widget of widgetGroup) {\n let { buttonName, buttonClick, buttonText, buttonIcon, buttonHint } = widget;\n if (buttonName === 'title') {\n isOnlyButtons = false;\n children.push((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"h2\", { className: \"fc-toolbar-title\", id: props.titleId }, props.title));\n }\n else {\n let isPressed = buttonName === props.activeButton;\n let isDisabled = (!props.isTodayEnabled && buttonName === 'today') ||\n (!props.isPrevEnabled && buttonName === 'prev') ||\n (!props.isNextEnabled && buttonName === 'next');\n let buttonClasses = [`fc-${buttonName}-button`, theme.getClass('button')];\n if (isPressed) {\n buttonClasses.push(theme.getClass('buttonActive'));\n }\n children.push((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"button\", { type: \"button\", title: typeof buttonHint === 'function' ? buttonHint(props.navUnit) : buttonHint, disabled: isDisabled, \"aria-pressed\": isPressed, className: buttonClasses.join(' '), onClick: buttonClick }, buttonText || (buttonIcon ? (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"span\", { className: buttonIcon, role: \"img\" }) : '')));\n }\n }\n if (children.length > 1) {\n let groupClassName = (isOnlyButtons && theme.getClass('buttonGroup')) || '';\n return (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)('div', { className: groupClassName }, ...children);\n }\n return children[0];\n }\n}\n\nclass Toolbar extends _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.B {\n render() {\n let { model, extraClassName } = this.props;\n let forceLtr = false;\n let startContent;\n let endContent;\n let sectionWidgets = model.sectionWidgets;\n let centerContent = sectionWidgets.center;\n if (sectionWidgets.left) {\n forceLtr = true;\n startContent = sectionWidgets.left;\n }\n else {\n startContent = sectionWidgets.start;\n }\n if (sectionWidgets.right) {\n forceLtr = true;\n endContent = sectionWidgets.right;\n }\n else {\n endContent = sectionWidgets.end;\n }\n let classNames = [\n extraClassName || '',\n 'fc-toolbar',\n forceLtr ? 'fc-toolbar-ltr' : '',\n ];\n return ((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { className: classNames.join(' ') },\n this.renderSection('start', startContent || []),\n this.renderSection('center', centerContent || []),\n this.renderSection('end', endContent || [])));\n }\n renderSection(key, widgetGroups) {\n let { props } = this;\n return ((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(ToolbarSection, { key: key, widgetGroups: widgetGroups, title: props.title, navUnit: props.navUnit, activeButton: props.activeButton, isTodayEnabled: props.isTodayEnabled, isPrevEnabled: props.isPrevEnabled, isNextEnabled: props.isNextEnabled, titleId: props.titleId }));\n }\n}\n\nclass ViewHarness extends _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.B {\n constructor() {\n super(...arguments);\n this.state = {\n availableWidth: null,\n };\n this.handleEl = (el) => {\n this.el = el;\n (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.W)(this.props.elRef, el);\n this.updateAvailableWidth();\n };\n this.handleResize = () => {\n this.updateAvailableWidth();\n };\n }\n render() {\n let { props, state } = this;\n let { aspectRatio } = props;\n let classNames = [\n 'fc-view-harness',\n (aspectRatio || props.liquid || props.height)\n ? 'fc-view-harness-active' // harness controls the height\n : 'fc-view-harness-passive', // let the view do the height\n ];\n let height = '';\n let paddingBottom = '';\n if (aspectRatio) {\n if (state.availableWidth !== null) {\n height = state.availableWidth / aspectRatio;\n }\n else {\n // while waiting to know availableWidth, we can't set height to *zero*\n // because will cause lots of unnecessary scrollbars within scrollgrid.\n // BETTER: don't start rendering ANYTHING yet until we know container width\n // NOTE: why not always use paddingBottom? Causes height oscillation (issue 5606)\n paddingBottom = `${(1 / aspectRatio) * 100}%`;\n }\n }\n else {\n height = props.height || '';\n }\n return ((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { \"aria-labelledby\": props.labeledById, ref: this.handleEl, className: classNames.join(' '), style: { height, paddingBottom } }, props.children));\n }\n componentDidMount() {\n this.context.addResizeHandler(this.handleResize);\n }\n componentWillUnmount() {\n this.context.removeResizeHandler(this.handleResize);\n }\n updateAvailableWidth() {\n if (this.el && // needed. but why?\n this.props.aspectRatio // aspectRatio is the only height setting that needs availableWidth\n ) {\n this.setState({ availableWidth: this.el.offsetWidth });\n }\n }\n}\n\n/*\nDetects when the user clicks on an event within a DateComponent\n*/\nclass EventClicking extends _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.X {\n constructor(settings) {\n super(settings);\n this.handleSegClick = (ev, segEl) => {\n let { component } = this;\n let { context } = component;\n let seg = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.Y)(segEl);\n if (seg && // might be the
surrounding the more link\n component.isValidSegDownEl(ev.target)) {\n // our way to simulate a link click for elements that can't be
tags\n // grab before trigger fired in case trigger trashes DOM thru rerendering\n let hasUrlContainer = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.Z)(ev.target, '.fc-event-forced-url');\n let url = hasUrlContainer ? hasUrlContainer.querySelector('a[href]').href : '';\n context.emitter.trigger('eventClick', {\n el: segEl,\n event: new _internal_common_js__WEBPACK_IMPORTED_MODULE_0__._(component.context, seg.eventRange.def, seg.eventRange.instance),\n jsEvent: ev,\n view: context.viewApi,\n });\n if (url && !ev.defaultPrevented) {\n window.location.href = url;\n }\n }\n };\n this.destroy = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.$)(settings.el, 'click', '.fc-event', // on both fg and bg events\n this.handleSegClick);\n }\n}\n\n/*\nTriggers events and adds/removes core classNames when the user's pointer\nenters/leaves event-elements of a component.\n*/\nclass EventHovering extends _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.X {\n constructor(settings) {\n super(settings);\n // for simulating an eventMouseLeave when the event el is destroyed while mouse is over it\n this.handleEventElRemove = (el) => {\n if (el === this.currentSegEl) {\n this.handleSegLeave(null, this.currentSegEl);\n }\n };\n this.handleSegEnter = (ev, segEl) => {\n if ((0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.Y)(segEl)) { // TODO: better way to make sure not hovering over more+ link or its wrapper\n this.currentSegEl = segEl;\n this.triggerEvent('eventMouseEnter', ev, segEl);\n }\n };\n this.handleSegLeave = (ev, segEl) => {\n if (this.currentSegEl) {\n this.currentSegEl = null;\n this.triggerEvent('eventMouseLeave', ev, segEl);\n }\n };\n this.removeHoverListeners = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a0)(settings.el, '.fc-event', // on both fg and bg events\n this.handleSegEnter, this.handleSegLeave);\n }\n destroy() {\n this.removeHoverListeners();\n }\n triggerEvent(publicEvName, ev, segEl) {\n let { component } = this;\n let { context } = component;\n let seg = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.Y)(segEl);\n if (!ev || component.isValidSegDownEl(ev.target)) {\n context.emitter.trigger(publicEvName, {\n el: segEl,\n event: new _internal_common_js__WEBPACK_IMPORTED_MODULE_0__._(context, seg.eventRange.def, seg.eventRange.instance),\n jsEvent: ev,\n view: context.viewApi,\n });\n }\n }\n}\n\nclass CalendarContent extends _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a1 {\n constructor() {\n super(...arguments);\n this.buildViewContext = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a2);\n this.buildViewPropTransformers = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildViewPropTransformers);\n this.buildToolbarProps = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildToolbarProps);\n this.headerRef = (0,preact__WEBPACK_IMPORTED_MODULE_1__.createRef)();\n this.footerRef = (0,preact__WEBPACK_IMPORTED_MODULE_1__.createRef)();\n this.interactionsStore = {};\n // eslint-disable-next-line\n this.state = {\n viewLabelId: (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a3)(),\n };\n // Component Registration\n // -----------------------------------------------------------------------------------------------------------------\n this.registerInteractiveComponent = (component, settingsInput) => {\n let settings = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a4)(component, settingsInput);\n let DEFAULT_INTERACTIONS = [\n EventClicking,\n EventHovering,\n ];\n let interactionClasses = DEFAULT_INTERACTIONS.concat(this.props.pluginHooks.componentInteractions);\n let interactions = interactionClasses.map((TheInteractionClass) => new TheInteractionClass(settings));\n this.interactionsStore[component.uid] = interactions;\n _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a5[component.uid] = settings;\n };\n this.unregisterInteractiveComponent = (component) => {\n let listeners = this.interactionsStore[component.uid];\n if (listeners) {\n for (let listener of listeners) {\n listener.destroy();\n }\n delete this.interactionsStore[component.uid];\n }\n delete _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a5[component.uid];\n };\n // Resizing\n // -----------------------------------------------------------------------------------------------------------------\n this.resizeRunner = new _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.D(() => {\n this.props.emitter.trigger('_resize', true); // should window resizes be considered \"forced\" ?\n this.props.emitter.trigger('windowResize', { view: this.props.viewApi });\n });\n this.handleWindowResize = (ev) => {\n let { options } = this.props;\n if (options.handleWindowResize &&\n ev.target === window // avoid jqui events\n ) {\n this.resizeRunner.request(options.windowResizeDelay);\n }\n };\n }\n /*\n renders INSIDE of an outer div\n */\n render() {\n let { props } = this;\n let { toolbarConfig, options } = props;\n let viewVGrow = false;\n let viewHeight = '';\n let viewAspectRatio;\n if (props.isHeightAuto || props.forPrint) {\n viewHeight = '';\n }\n else if (options.height != null) {\n viewVGrow = true;\n }\n else if (options.contentHeight != null) {\n viewHeight = options.contentHeight;\n }\n else {\n viewAspectRatio = Math.max(options.aspectRatio, 0.5); // prevent from getting too tall\n }\n let viewContext = this.buildViewContext(props.viewSpec, props.viewApi, props.options, props.dateProfileGenerator, props.dateEnv, props.nowManager, props.theme, props.pluginHooks, props.dispatch, props.getCurrentData, props.emitter, props.calendarApi, this.registerInteractiveComponent, this.unregisterInteractiveComponent);\n let viewLabelId = (toolbarConfig.header && toolbarConfig.header.hasTitle)\n ? this.state.viewLabelId\n : undefined;\n return ((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.V.Provider, { value: viewContext },\n (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a6, { unit: \"day\" }, (nowDate) => {\n let toolbarProps = this.buildToolbarProps(props.viewSpec, props.dateProfile, props.dateProfileGenerator, props.currentDate, nowDate, props.viewTitle);\n return ((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(preact__WEBPACK_IMPORTED_MODULE_1__.Fragment, null,\n toolbarConfig.header && ((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(Toolbar, Object.assign({ ref: this.headerRef, extraClassName: \"fc-header-toolbar\", model: toolbarConfig.header, titleId: viewLabelId }, toolbarProps))),\n (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(ViewHarness, { liquid: viewVGrow, height: viewHeight, aspectRatio: viewAspectRatio, labeledById: viewLabelId },\n this.renderView(props),\n this.buildAppendContent()),\n toolbarConfig.footer && ((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(Toolbar, Object.assign({ ref: this.footerRef, extraClassName: \"fc-footer-toolbar\", model: toolbarConfig.footer, titleId: \"\" }, toolbarProps)))));\n })));\n }\n componentDidMount() {\n let { props } = this;\n this.calendarInteractions = props.pluginHooks.calendarInteractions\n .map((CalendarInteractionClass) => new CalendarInteractionClass(props));\n window.addEventListener('resize', this.handleWindowResize);\n let { propSetHandlers } = props.pluginHooks;\n for (let propName in propSetHandlers) {\n propSetHandlers[propName](props[propName], props);\n }\n }\n componentDidUpdate(prevProps) {\n let { props } = this;\n let { propSetHandlers } = props.pluginHooks;\n for (let propName in propSetHandlers) {\n if (props[propName] !== prevProps[propName]) {\n propSetHandlers[propName](props[propName], props);\n }\n }\n }\n componentWillUnmount() {\n window.removeEventListener('resize', this.handleWindowResize);\n this.resizeRunner.clear();\n for (let interaction of this.calendarInteractions) {\n interaction.destroy();\n }\n this.props.emitter.trigger('_unmount');\n }\n buildAppendContent() {\n let { props } = this;\n let children = props.pluginHooks.viewContainerAppends.map((buildAppendContent) => buildAppendContent(props));\n return (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(preact__WEBPACK_IMPORTED_MODULE_1__.Fragment, {}, ...children);\n }\n renderView(props) {\n let { pluginHooks } = props;\n let { viewSpec } = props;\n let viewProps = {\n dateProfile: props.dateProfile,\n businessHours: props.businessHours,\n eventStore: props.renderableEventStore,\n eventUiBases: props.eventUiBases,\n dateSelection: props.dateSelection,\n eventSelection: props.eventSelection,\n eventDrag: props.eventDrag,\n eventResize: props.eventResize,\n isHeightAuto: props.isHeightAuto,\n forPrint: props.forPrint,\n };\n let transformers = this.buildViewPropTransformers(pluginHooks.viewPropsTransformers);\n for (let transformer of transformers) {\n Object.assign(viewProps, transformer.transform(viewProps, props));\n }\n let ViewComponent = viewSpec.component;\n return ((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(ViewComponent, Object.assign({}, viewProps)));\n }\n}\nfunction buildToolbarProps(viewSpec, dateProfile, dateProfileGenerator, currentDate, now, title) {\n // don't force any date-profiles to valid date profiles (the `false`) so that we can tell if it's invalid\n let todayInfo = dateProfileGenerator.build(now, undefined, false); // TODO: need `undefined` or else INFINITE LOOP for some reason\n let prevInfo = dateProfileGenerator.buildPrev(dateProfile, currentDate, false);\n let nextInfo = dateProfileGenerator.buildNext(dateProfile, currentDate, false);\n return {\n title,\n activeButton: viewSpec.type,\n navUnit: viewSpec.singleUnit,\n isTodayEnabled: todayInfo.isValid && !(0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.G)(dateProfile.currentRange, now),\n isPrevEnabled: prevInfo.isValid,\n isNextEnabled: nextInfo.isValid,\n };\n}\n// Plugin\n// -----------------------------------------------------------------------------------------------------------------\nfunction buildViewPropTransformers(theClasses) {\n return theClasses.map((TheClass) => new TheClass());\n}\n\nclass Calendar extends _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a7 {\n constructor(el, optionOverrides = {}) {\n super();\n this.isRendering = false;\n this.isRendered = false;\n this.currentClassNames = [];\n this.customContentRenderId = 0;\n this.handleAction = (action) => {\n // actions we know we want to render immediately\n switch (action.type) {\n case 'SET_EVENT_DRAG':\n case 'SET_EVENT_RESIZE':\n this.renderRunner.tryDrain();\n }\n };\n this.handleData = (data) => {\n this.currentData = data;\n this.renderRunner.request(data.calendarOptions.rerenderDelay);\n };\n this.handleRenderRequest = () => {\n if (this.isRendering) {\n this.isRendered = true;\n let { currentData } = this;\n (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a8)(() => {\n (0,preact__WEBPACK_IMPORTED_MODULE_1__.render)((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a9, { options: currentData.calendarOptions, theme: currentData.theme, emitter: currentData.emitter }, (classNames, height, isHeightAuto, forPrint) => {\n this.setClassNames(classNames);\n this.setHeight(height);\n return ((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.aa.Provider, { value: this.customContentRenderId },\n (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(CalendarContent, Object.assign({ isHeightAuto: isHeightAuto, forPrint: forPrint }, currentData))));\n }), this.el);\n });\n }\n else if (this.isRendered) {\n this.isRendered = false;\n (0,preact__WEBPACK_IMPORTED_MODULE_1__.render)(null, this.el);\n this.setClassNames([]);\n this.setHeight('');\n }\n };\n (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.ab)(el);\n this.el = el;\n this.renderRunner = new _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.D(this.handleRenderRequest);\n new CalendarDataManager({\n optionOverrides,\n calendarApi: this,\n onAction: this.handleAction,\n onData: this.handleData,\n });\n }\n render() {\n let wasRendering = this.isRendering;\n if (!wasRendering) {\n this.isRendering = true;\n }\n else {\n this.customContentRenderId += 1;\n }\n this.renderRunner.request();\n if (wasRendering) {\n this.updateSize();\n }\n }\n destroy() {\n if (this.isRendering) {\n this.isRendering = false;\n this.renderRunner.request();\n }\n }\n updateSize() {\n (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a8)(() => {\n super.updateSize();\n });\n }\n batchRendering(func) {\n this.renderRunner.pause('batchRendering');\n func();\n this.renderRunner.resume('batchRendering');\n }\n pauseRendering() {\n this.renderRunner.pause('pauseRendering');\n }\n resumeRendering() {\n this.renderRunner.resume('pauseRendering', true);\n }\n resetOptions(optionOverrides, changedOptionNames) {\n this.currentDataManager.resetOptions(optionOverrides, changedOptionNames);\n }\n setClassNames(classNames) {\n if (!(0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.i)(classNames, this.currentClassNames)) {\n let { classList } = this.el;\n for (let className of this.currentClassNames) {\n classList.remove(className);\n }\n for (let className of classNames) {\n classList.add(className);\n }\n this.currentClassNames = classNames;\n }\n }\n setHeight(height) {\n (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.ac)(this.el, 'height', height);\n }\n}\n\nfunction formatDate(dateInput, options = {}) {\n let dateEnv = buildDateEnv(options);\n let formatter = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.x)(options);\n let dateMeta = dateEnv.createMarkerMeta(dateInput);\n if (!dateMeta) { // TODO: warning?\n return '';\n }\n return dateEnv.format(dateMeta.marker, formatter, {\n forcedTzo: dateMeta.forcedTzo,\n });\n}\nfunction formatRange(startInput, endInput, options) {\n let dateEnv = buildDateEnv(typeof options === 'object' && options ? options : {}); // pass in if non-null object\n let formatter = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.x)(options);\n let startMeta = dateEnv.createMarkerMeta(startInput);\n let endMeta = dateEnv.createMarkerMeta(endInput);\n if (!startMeta || !endMeta) { // TODO: warning?\n return '';\n }\n return dateEnv.formatRange(startMeta.marker, endMeta.marker, formatter, {\n forcedStartTzo: startMeta.forcedTzo,\n forcedEndTzo: endMeta.forcedTzo,\n isEndExclusive: options.isEndExclusive,\n defaultSeparator: _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.e.defaultRangeSeparator,\n });\n}\n// TODO: more DRY and optimized\nfunction buildDateEnv(settings) {\n let locale = buildLocale(settings.locale || 'en', organizeRawLocales([]).map); // TODO: don't hardcode 'en' everywhere\n return new _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.Q(Object.assign(Object.assign({ timeZone: _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.e.timeZone, calendarSystem: 'gregory' }, settings), { locale }));\n}\n\n// HELPERS\n/*\nif nextDayThreshold is specified, slicing is done in an all-day fashion.\nyou can get nextDayThreshold from context.nextDayThreshold\n*/\nfunction sliceEvents(props, allDay) {\n return (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.ad)(props.eventStore, props.eventUiBases, props.dateProfile.activeRange, allDay ? props.nextDayThreshold : null).fg;\n}\n\nconst version = '6.1.19';\n\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTEyLmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7OztBQUFvL0M7QUFDdDdDO0FBQ007QUFDN0M7O0FBRXZCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9EQUFvRDtBQUNwRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCLFdBQVc7QUFDckMsU0FBUztBQUNULEtBQUs7QUFDTCx1QkFBdUIsVUFBVSxZQUFZLDBCQUEwQjtBQUN2RSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMENBQTBDO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLGtCQUFrQjtBQUN0QztBQUNBLG1DQUFtQyxPQUFPO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixzREFBVTtBQUMzQix3QkFBd0I7QUFDeEIsVUFBVSxPQUFPO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLHNEQUFJO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdEQUFnRDtBQUNoRDtBQUNBLDREQUE0RDtBQUM1RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0M7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4Q0FBOEM7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOERBQThEO0FBQzlEO0FBQ0Esc0RBQXNEO0FBQ3RELGtEQUFrRDtBQUNsRCxvREFBb0Q7QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0EsK0JBQStCO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QjtBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0M7QUFDaEM7QUFDQSw0QkFBNEI7QUFDNUIsMEJBQTBCO0FBQzFCLDJCQUEyQjtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrREFBa0QsV0FBVztBQUM3RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOEJBQThCLHNEQUFhLHdDQUF3QyxzREFBYTtBQUNoRztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFEQUFxRDtBQUNyRDtBQUNBLDJEQUEyRDtBQUMzRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkM7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvREFBb0Q7QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNERBQTREO0FBQzVEO0FBQ0Esd0RBQXdEO0FBQ3hELHNEQUFzRDtBQUN0RCx1REFBdUQ7QUFDdkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSw0QkFBNEIsa0RBQUs7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0REFBNEQ7QUFDNUQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnREFBZ0Qsb0NBQW9DLGtEQUFrRDtBQUN0SSxpREFBaUQscUNBQXFDLG9EQUFvRDtBQUMxSTtBQUNBOztBQUVBO0FBQ0EsV0FBVyxzREFBTztBQUNsQjtBQUNBO0FBQ0E7QUFDQSxVQUFVLG1CQUFtQjtBQUM3QjtBQUNBLFVBQVUsWUFBWTtBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJEQUEyRCxrREFBYTtBQUN4RTtBQUNBO0FBQ0EsMEVBQTBFLGlCQUFpQixvQkFBb0I7QUFDL0c7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQixxREFBYSxDQUFDLGtEQUFlLCtCQUErQixxREFBYSxDQUFDLGtEQUFnQixJQUFJLHlCQUF5QixzREFBbUIsK0RBQStELGdCQUFnQixvREFBb0QscUtBQXFLO0FBQzdjOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxzREFBTztBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0I7QUFDeEIsd0JBQXdCLHNEQUEyQjtBQUNuRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0RBQXdEO0FBQ3hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVEQUF1RDtBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLGtEQUFvQjtBQUNoRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixrREFBb0I7QUFDakQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxzREFBYztBQUM1QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaURBQWlELDZCQUE2Qiw0Q0FBNEM7QUFDMUg7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHdCQUF3QjtBQUN4QjtBQUNBO0FBQ0Esb0VBQW9FO0FBQ3BFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixzREFBVztBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0VBQW9FO0FBQ3BFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlDQUF5QztBQUN6QztBQUNBO0FBQ0EsV0FBVyxzREFBVTtBQUNyQjtBQUNBO0FBQ0EseUNBQXlDLHNEQUFVO0FBQ25EO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVSx1QkFBdUI7QUFDakM7QUFDQSxrQkFBa0Isc0RBQUk7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxjQUFjLFlBQVk7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsS0FBSztBQUNMLHlDQUF5QyxrQkFBa0IsMENBQTBDO0FBQ3JHO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkMsaUJBQWlCLDBDQUEwQyxrQkFBa0IsK0JBQStCLEdBQUc7QUFDNUo7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLHNEQUFVO0FBQ3JCO0FBQ0E7QUFDQSxtQkFBbUIsc0RBQXdCO0FBQzNDO0FBQ0Esc0JBQXNCO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCLHNEQUFnQjtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCO0FBQ3hCLHdCQUF3QjtBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEVBQTRFO0FBQzVFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUIsc0RBQWtCO0FBQzNDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNENBQTRDO0FBQzVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrREFBK0Q7QUFDL0Q7QUFDQTtBQUNBLDZCQUE2QixzREFBa0I7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMENBQTBDLHNEQUFrQjtBQUM1RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakIsS0FBSztBQUNMLGFBQWE7QUFDYjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0RBQW9EO0FBQ3BEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsZ0JBQWdCLFVBQVU7QUFDMUI7QUFDQSxRQUFRLHNEQUFXLGlCQUFpQixzREFBeUIsd0RBQXdELFdBQVc7QUFDaEksS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0EsaUJBQWlCLGtEQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxnQkFBZ0IsT0FBTztBQUN2QjtBQUNBLFFBQVEsc0RBQVc7QUFDbkIsOEJBQThCLHFCQUFxQjtBQUNuRCxTQUFTO0FBQ1QsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQSxVQUFVLG1CQUFtQjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGdCQUFnQixrREFBUTtBQUN4QixlQUFlLGtEQUFjO0FBQzdCLGFBQWEsa0RBQWM7QUFDM0IsY0FBYyxrREFBYztBQUM1QixnQkFBZ0Isa0RBQVE7QUFDeEIsY0FBYyxrREFBUTtBQUN0Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQixzREFBaUI7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLGtDQUFrQyxzREFBZSxpQkFBaUIsb0RBQW9EO0FBQ3RIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQSwrQkFBK0Isc0RBQVc7QUFDMUMsb0JBQW9CLHNEQUFVO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QixzREFBTztBQUMvQjtBQUNBO0FBQ0E7QUFDQSx3QkFBd0Isc0RBQU87QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQixzREFBTztBQUMzQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLEtBQUs7QUFDTCxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUIsc0RBQWlCO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QiwyQkFBMkI7QUFDbkQ7QUFDQSw2Q0FBNkM7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxzRUFBc0UsRUFBRSxzREFBeUIsK0NBQStDLHVCQUF1QjtBQUN2Szs7QUFFQTtBQUNBLFVBQVUsVUFBVTtBQUNwQjtBQUNBLHFDQUFxQyxzREFBYztBQUNuRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQyxrREFBYTtBQUM5QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLFFBQVE7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7QUFDQTtBQUNBLHVEQUF1RCxzREFBZTtBQUN0RTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVSxtQkFBbUI7QUFDN0I7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQixrQ0FBa0M7QUFDbkQ7QUFDQSxlQUFlLHNEQUFhO0FBQzVCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGFBQWE7QUFDYjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0NBQW9DO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDQUFzQyxzREFBTztBQUM3QyxrQ0FBa0Msc0RBQU87QUFDekMsMkJBQTJCLHNEQUFPO0FBQ2xDO0FBQ0EsNEJBQTRCLHNEQUFPO0FBQ25DLDBCQUEwQixzREFBTztBQUNqQyw2QkFBNkIsc0RBQU87QUFDcEMsOEJBQThCLHNEQUFPO0FBQ3JDLHlDQUF5QyxzREFBYTtBQUN0RCw0QkFBNEIsc0RBQU87QUFDbkMsZ0NBQWdDLHNEQUFhO0FBQzdDLG9DQUFvQyxzREFBTyx1QkFBdUIsa0RBQVk7QUFDOUUsaUNBQWlDLHNEQUFPO0FBQ3hDLHlDQUF5QyxzREFBYTtBQUN0RCwwQkFBMEIsc0RBQU87QUFDakM7QUFDQSwyQkFBMkIsa0RBQU87QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQ0FBK0M7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLHNEQUFtQjtBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0QkFBNEI7QUFDNUIsd0JBQXdCLHNEQUFxQjtBQUM3QyxrQ0FBa0Msc0RBQXFCO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDREQUE0RDtBQUM1RDtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1EQUFtRDtBQUNuRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLFFBQVE7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrRUFBa0UsOEJBQThCO0FBQ2hHO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0EsY0FBYyx3QkFBd0I7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLDJCQUEyQjtBQUN6QyxvR0FBb0c7QUFDcEc7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxzREFBbUI7QUFDaEM7QUFDQTtBQUNBO0FBQ0EseUJBQXlCLHNEQUFnQjtBQUN6Qyx3RUFBd0U7QUFDeEU7QUFDQTtBQUNBO0FBQ0EsY0FBYyxxQ0FBcUMsMENBQTBDO0FBQzdGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDREQUE0RDtBQUM1RDtBQUNBLDhFQUE4RTtBQUM5RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsZUFBZTtBQUM3QjtBQUNBO0FBQ0E7QUFDQSwyRUFBMkUsK09BQStPO0FBQzFUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscURBQXFELHNEQUFxQjtBQUMxRSx5RUFBeUUsc0RBQXFCO0FBQzlGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLDJFQUEyRTtBQUN6RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLGtCQUFrQixFQUFFLHNEQUFlO0FBQ2pELFlBQVksa0RBQW9CO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUlBQXFJLEVBQUUsa0RBQW9CLEdBQUcsa0RBQTBCLEdBQUcsa0RBQXdCO0FBQ25OO0FBQ0Esa0JBQWtCLHNEQUFlO0FBQ2pDLFlBQVksa0RBQW9CO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNIQUFzSCxrREFBMEI7QUFDaEo7QUFDQSxnQkFBZ0Isa0RBQTBCO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlDQUF5QyxTQUFTO0FBQ2xEO0FBQ0EsY0FBYyx3QkFBd0I7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxrQkFBa0Isc0RBQWU7QUFDakMsWUFBWSxrREFBb0I7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkdBQTZHLEVBQUUsa0RBQW9CLEdBQUcsa0RBQTBCLEdBQUcsa0RBQXdCLEdBQUcsa0RBQW9CO0FBQ2xOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLGtEQUEwQjtBQUMzQyxvQkFBb0Isa0RBQTBCO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCLGtEQUEwQjtBQUMvQyx3QkFBd0Isa0RBQTBCO0FBQ2xELDRFQUE0RTtBQUM1RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsa0RBQU87QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVFQUF1RSxrREFBb0I7QUFDM0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxzREFBTztBQUNsQjtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVUsVUFBVTtBQUNwQjtBQUNBLDJCQUEyQixzREFBYTtBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QseUJBQXlCLHNEQUFhO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxzREFBa0I7QUFDN0I7QUFDQTtBQUNBO0FBQ0Esd0NBQXdDLFdBQVc7QUFDbkQsc0NBQXNDLFNBQVM7QUFDL0M7QUFDQTs7QUFFQSw2QkFBNkIsa0RBQWE7QUFDMUM7QUFDQTtBQUNBLGVBQWUscURBQWEsVUFBVSwrQkFBK0I7QUFDckU7QUFDQTtBQUNBLGNBQWMsUUFBUTtBQUN0QixjQUFjLFFBQVE7QUFDdEI7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLDhEQUE4RDtBQUNoRjtBQUNBO0FBQ0EsOEJBQThCLHFEQUFhLFNBQVMsa0RBQWtEO0FBQ3RHO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJDQUEyQyxXQUFXO0FBQ3REO0FBQ0E7QUFDQTtBQUNBLDhCQUE4QixxREFBYSxhQUFhLDZNQUE2TSw4QkFBOEIscURBQWEsV0FBVyxvQ0FBb0M7QUFDL1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIscURBQWEsVUFBVSwyQkFBMkI7QUFDckU7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsc0JBQXNCLGtEQUFhO0FBQ25DO0FBQ0EsY0FBYyx3QkFBd0I7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLHFEQUFhLFVBQVUsaUNBQWlDO0FBQ3hFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLFFBQVE7QUFDdEIsZ0JBQWdCLHFEQUFhLG1CQUFtQiwwUEFBMFA7QUFDMVM7QUFDQTs7QUFFQSwwQkFBMEIsa0RBQWE7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLHNEQUFNO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxlQUFlO0FBQzdCLGNBQWMsY0FBYztBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DLHdCQUF3QjtBQUMzRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLHFEQUFhLFVBQVUsb0dBQW9HLHlCQUF5QjtBQUNwSztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLHFDQUFxQztBQUNqRTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLGtEQUFXO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQixZQUFZO0FBQzlCLGtCQUFrQixVQUFVO0FBQzVCLHNCQUFzQixzREFBUTtBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDQUFzQyxzREFBYztBQUNwRDtBQUNBO0FBQ0E7QUFDQSwrQkFBK0Isa0RBQVM7QUFDeEM7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLHNEQUFnQjtBQUN2QztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0QkFBNEIsa0RBQVc7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLHNEQUFRLFdBQVc7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQ0FBb0MsdURBQXVCO0FBQzNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsWUFBWTtBQUMxQixjQUFjLFVBQVU7QUFDeEIsa0JBQWtCLHNEQUFRO0FBQzFCO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQixrREFBUztBQUNwQztBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTs7QUFFQSw4QkFBOEIsbURBQWE7QUFDM0M7QUFDQTtBQUNBLGdDQUFnQyxzREFBTyxDQUFDLG1EQUFnQjtBQUN4RCx5Q0FBeUMsc0RBQU87QUFDaEQsaUNBQWlDLHNEQUFPO0FBQ3hDLHlCQUF5QixpREFBUztBQUNsQyx5QkFBeUIsaURBQVM7QUFDbEM7QUFDQTtBQUNBO0FBQ0EseUJBQXlCLHVEQUFjO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCLHVEQUF3QjtBQUNuRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksbURBQXdCO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixtREFBd0I7QUFDM0M7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLGtEQUFhO0FBQzdDLHlEQUF5RDtBQUN6RCx5REFBeUQsMEJBQTBCO0FBQ25GLFNBQVM7QUFDVDtBQUNBLGtCQUFrQixVQUFVO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLFFBQVE7QUFDdEIsY0FBYyx5QkFBeUI7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrRUFBa0U7QUFDbEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixxREFBYSxDQUFDLGtEQUFlLGFBQWEsb0JBQW9CO0FBQzlFLFlBQVkscURBQWEsQ0FBQyxtREFBUSxJQUFJLGFBQWE7QUFDbkQ7QUFDQSx3QkFBd0IscURBQWEsQ0FBQyw0Q0FBUTtBQUM5Qyw2Q0FBNkMscURBQWEsMEJBQTBCLDZHQUE2RztBQUNqTSxvQkFBb0IscURBQWEsZ0JBQWdCLCtGQUErRjtBQUNoSjtBQUNBO0FBQ0EsNkNBQTZDLHFEQUFhLDBCQUEwQixvR0FBb0c7QUFDeEwsYUFBYTtBQUNiO0FBQ0E7QUFDQSxjQUFjLFFBQVE7QUFDdEI7QUFDQTtBQUNBO0FBQ0EsY0FBYyxrQkFBa0I7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsUUFBUTtBQUN0QixjQUFjLGtCQUFrQjtBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLFFBQVE7QUFDdEI7QUFDQSxlQUFlLHFEQUFhLENBQUMsNENBQVEsSUFBSTtBQUN6QztBQUNBO0FBQ0EsY0FBYyxjQUFjO0FBQzVCLGNBQWMsV0FBVztBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLHFEQUFhLGdDQUFnQztBQUM3RDtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVFQUF1RTtBQUN2RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4Q0FBOEMsc0RBQW1CO0FBQ2pFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSx1QkFBdUIsbURBQVk7QUFDbkMsd0NBQXdDO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0IsY0FBYztBQUNwQyxnQkFBZ0IsdURBQVM7QUFDekIsb0JBQW9CLDhDQUFNLENBQUMscURBQWEsQ0FBQyxtREFBWSxJQUFJLDhGQUE4RjtBQUN2SjtBQUNBO0FBQ0EsZ0NBQWdDLHFEQUFhLENBQUMsbURBQVEsYUFBYSxtQ0FBbUM7QUFDdEcsNEJBQTRCLHFEQUFhLGtDQUFrQyxnREFBZ0Q7QUFDM0gscUJBQXFCO0FBQ3JCLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsOENBQU07QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLHVEQUFpQjtBQUN6QjtBQUNBLGdDQUFnQyxrREFBYTtBQUM3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsdURBQVM7QUFDakI7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLHNEQUFhO0FBQzFCLGtCQUFrQixZQUFZO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSx1REFBYztBQUN0QjtBQUNBOztBQUVBLDJDQUEyQztBQUMzQztBQUNBLG9CQUFvQixzREFBZTtBQUNuQztBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0Esb0ZBQW9GLEdBQUc7QUFDdkYsb0JBQW9CLHNEQUFlO0FBQ25DO0FBQ0E7QUFDQSxrQ0FBa0M7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCLGtEQUFvQjtBQUM5QyxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsbUZBQW1GO0FBQ25GLGVBQWUsa0RBQU8sK0JBQStCLFVBQVUsa0RBQW9CLHNDQUFzQyxlQUFlLFFBQVE7QUFDaEo7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyx1REFBZTtBQUMxQjs7QUFFQTs7QUFFK0ciLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9hcmNoaXRlY3R1aS1odG1sLWZyZWUvLi9ub2RlX21vZHVsZXMvQGZ1bGxjYWxlbmRhci9jb3JlL2luZGV4LmpzPzk0ZDUiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgbSBhcyBtZXJnZVByb3BzLCBnIGFzIGd1aWQsIGkgYXMgaXNBcnJheXNFcXVhbCwgVCBhcyBUaGVtZSwgYSBhcyBtYXBIYXNoLCBCIGFzIEJhc2VDb21wb25lbnQsIFYgYXMgVmlld0NvbnRleHRUeXBlLCBDIGFzIENvbnRlbnRDb250YWluZXIsIGIgYXMgYnVpbGRWaWV3Q2xhc3NOYW1lcywgYyBhcyBncmVhdGVzdER1cmF0aW9uRGVub21pbmF0b3IsIGQgYXMgY3JlYXRlRHVyYXRpb24sIGUgYXMgQkFTRV9PUFRJT05fREVGQVVMVFMsIGYgYXMgYXJyYXlUb0hhc2gsIGggYXMgZmlsdGVySGFzaCwgaiBhcyBidWlsZEV2ZW50U291cmNlUmVmaW5lcnMsIHAgYXMgcGFyc2VFdmVudFNvdXJjZSwgayBhcyBmb3JtYXRXaXRoT3JkaW5hbHMsIHUgYXMgdW5wcm9taXNpZnksIGwgYXMgYnVpbGRSYW5nZUFwaVdpdGhUaW1lWm9uZSwgbiBhcyBpZGVudGl0eSwgciBhcyByZXF1ZXN0SnNvbiwgcyBhcyBzdWJ0cmFjdER1cmF0aW9ucywgbyBhcyBpbnRlcnNlY3RSYW5nZXMsIHEgYXMgc3RhcnRPZkRheSwgdCBhcyBhZGREYXlzLCB2IGFzIGhhc2hWYWx1ZXNUb0FycmF5LCB3IGFzIGJ1aWxkRXZlbnRBcGlzLCBEIGFzIERlbGF5ZWRSdW5uZXIsIHggYXMgY3JlYXRlRm9ybWF0dGVyLCB5IGFzIGRpZmZXaG9sZURheXMsIHogYXMgbWVtb2l6ZSwgQSBhcyBtZW1vaXplT2JqQXJnLCBFIGFzIGlzUHJvcHNFcXVhbCwgRiBhcyBFbWl0dGVyLCBHIGFzIHJhbmdlQ29udGFpbnNNYXJrZXIsIEggYXMgY3JlYXRlRW1wdHlFdmVudFN0b3JlLCBJIGFzIHJlZHVjZUV2ZW50U3RvcmUsIEogYXMgcmV6b25lRXZlbnRTdG9yZURhdGVzLCBLIGFzIG1lcmdlUmF3T3B0aW9ucywgTCBhcyBCQVNFX09QVElPTl9SRUZJTkVSUywgTSBhcyBDQUxFTkRBUl9MSVNURU5FUl9SRUZJTkVSUywgTiBhcyBDQUxFTkRBUl9PUFRJT05fUkVGSU5FUlMsIE8gYXMgQ09NUExFWF9PUFRJT05fQ09NUEFSQVRPUlMsIFAgYXMgVklFV19PUFRJT05fUkVGSU5FUlMsIFEgYXMgRGF0ZUVudiwgUiBhcyBEYXRlUHJvZmlsZUdlbmVyYXRvciwgUyBhcyBjcmVhdGVFdmVudFVpLCBVIGFzIHBhcnNlQnVzaW5lc3NIb3VycywgVyBhcyBzZXRSZWYsIFggYXMgSW50ZXJhY3Rpb24sIFkgYXMgZ2V0RWxTZWcsIFogYXMgZWxlbWVudENsb3Nlc3QsIF8gYXMgRXZlbnRJbXBsLCAkIGFzIGxpc3RlbkJ5U2VsZWN0b3IsIGEwIGFzIGxpc3RlblRvSG92ZXJCeVNlbGVjdG9yLCBhMSBhcyBQdXJlQ29tcG9uZW50LCBhMiBhcyBidWlsZFZpZXdDb250ZXh0LCBhMyBhcyBnZXRVbmlxdWVEb21JZCwgYTQgYXMgcGFyc2VJbnRlcmFjdGlvblNldHRpbmdzLCBhNSBhcyBpbnRlcmFjdGlvblNldHRpbmdzU3RvcmUsIGE2IGFzIE5vd1RpbWVyLCBhNyBhcyBDYWxlbmRhckltcGwsIGE4IGFzIGZsdXNoU3luYywgYTkgYXMgQ2FsZW5kYXJSb290LCBhYSBhcyBSZW5kZXJJZCwgYWIgYXMgZW5zdXJlRWxIYXNTdHlsZXMsIGFjIGFzIGFwcGx5U3R5bGVQcm9wLCBhZCBhcyBzbGljZUV2ZW50U3RvcmUgfSBmcm9tICcuL2ludGVybmFsLWNvbW1vbi5qcyc7XG5leHBvcnQgeyBhZSBhcyBKc29uUmVxdWVzdEVycm9yIH0gZnJvbSAnLi9pbnRlcm5hbC1jb21tb24uanMnO1xuaW1wb3J0IHsgY3JlYXRlRWxlbWVudCwgY3JlYXRlUmVmLCBGcmFnbWVudCwgcmVuZGVyIH0gZnJvbSAncHJlYWN0JztcbmltcG9ydCAncHJlYWN0L2NvbXBhdCc7XG5cbmNvbnN0IGdsb2JhbExvY2FsZXMgPSBbXTtcblxuY29uc3QgTUlOSU1BTF9SQVdfRU5fTE9DQUxFID0ge1xuICAgIGNvZGU6ICdlbicsXG4gICAgd2Vlazoge1xuICAgICAgICBkb3c6IDAsXG4gICAgICAgIGRveTogNCwgLy8gNCBkYXlzIG5lZWQgdG8gYmUgd2l0aGluIHRoZSB5ZWFyIHRvIGJlIGNvbnNpZGVyZWQgdGhlIGZpcnN0IHdlZWtcbiAgICB9LFxuICAgIGRpcmVjdGlvbjogJ2x0cicsXG4gICAgYnV0dG9uVGV4dDoge1xuICAgICAgICBwcmV2OiAncHJldicsXG4gICAgICAgIG5leHQ6ICduZXh0JyxcbiAgICAgICAgcHJldlllYXI6ICdwcmV2IHllYXInLFxuICAgICAgICBuZXh0WWVhcjogJ25leHQgeWVhcicsXG4gICAgICAgIHllYXI6ICd5ZWFyJyxcbiAgICAgICAgdG9kYXk6ICd0b2RheScsXG4gICAgICAgIG1vbnRoOiAnbW9udGgnLFxuICAgICAgICB3ZWVrOiAnd2VlaycsXG4gICAgICAgIGRheTogJ2RheScsXG4gICAgICAgIGxpc3Q6ICdsaXN0JyxcbiAgICB9LFxuICAgIHdlZWtUZXh0OiAnVycsXG4gICAgd2Vla1RleHRMb25nOiAnV2VlaycsXG4gICAgY2xvc2VIaW50OiAnQ2xvc2UnLFxuICAgIHRpbWVIaW50OiAnVGltZScsXG4gICAgZXZlbnRIaW50OiAnRXZlbnQnLFxuICAgIGFsbERheVRleHQ6ICdhbGwtZGF5JyxcbiAgICBtb3JlTGlua1RleHQ6ICdtb3JlJyxcbiAgICBub0V2ZW50c1RleHQ6ICdObyBldmVudHMgdG8gZGlzcGxheScsXG59O1xuY29uc3QgUkFXX0VOX0xPQ0FMRSA9IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgTUlOSU1BTF9SQVdfRU5fTE9DQUxFKSwgeyBcbiAgICAvLyBJbmNsdWRlcyB0aGluZ3Mgd2UgZG9uJ3Qgd2FudCBvdGhlciBsb2NhbGVzIHRvIGluaGVyaXQsXG4gICAgLy8gdGhpbmdzIHRoYXQgZGVyaXZlIGZyb20gb3RoZXIgdHJhbnNsYXRhYmxlIHN0cmluZ3MuXG4gICAgYnV0dG9uSGludHM6IHtcbiAgICAgICAgcHJldjogJ1ByZXZpb3VzICQwJyxcbiAgICAgICAgbmV4dDogJ05leHQgJDAnLFxuICAgICAgICB0b2RheShidXR0b25UZXh0LCB1bml0KSB7XG4gICAgICAgICAgICByZXR1cm4gKHVuaXQgPT09ICdkYXknKVxuICAgICAgICAgICAgICAgID8gJ1RvZGF5J1xuICAgICAgICAgICAgICAgIDogYFRoaXMgJHtidXR0b25UZXh0fWA7XG4gICAgICAgIH0sXG4gICAgfSwgdmlld0hpbnQ6ICckMCB2aWV3JywgbmF2TGlua0hpbnQ6ICdHbyB0byAkMCcsIG1vcmVMaW5rSGludChldmVudENudCkge1xuICAgICAgICByZXR1cm4gYFNob3cgJHtldmVudENudH0gbW9yZSBldmVudCR7ZXZlbnRDbnQgPT09IDEgPyAnJyA6ICdzJ31gO1xuICAgIH0gfSk7XG5mdW5jdGlvbiBvcmdhbml6ZVJhd0xvY2FsZXMoZXhwbGljaXRSYXdMb2NhbGVzKSB7XG4gICAgbGV0IGRlZmF1bHRDb2RlID0gZXhwbGljaXRSYXdMb2NhbGVzLmxlbmd0aCA+IDAgPyBleHBsaWNpdFJhd0xvY2FsZXNbMF0uY29kZSA6ICdlbic7XG4gICAgbGV0IGFsbFJhd0xvY2FsZXMgPSBnbG9iYWxMb2NhbGVzLmNvbmNhdChleHBsaWNpdFJhd0xvY2FsZXMpO1xuICAgIGxldCByYXdMb2NhbGVNYXAgPSB7XG4gICAgICAgIGVuOiBSQVdfRU5fTE9DQUxFLFxuICAgIH07XG4gICAgZm9yIChsZXQgcmF3TG9jYWxlIG9mIGFsbFJhd0xvY2FsZXMpIHtcbiAgICAgICAgcmF3TG9jYWxlTWFwW3Jhd0xvY2FsZS5jb2RlXSA9IHJhd0xvY2FsZTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbWFwOiByYXdMb2NhbGVNYXAsXG4gICAgICAgIGRlZmF1bHRDb2RlLFxuICAgIH07XG59XG5mdW5jdGlvbiBidWlsZExvY2FsZShpbnB1dFNpbmd1bGFyLCBhdmFpbGFibGUpIHtcbiAgICBpZiAodHlwZW9mIGlucHV0U2luZ3VsYXIgPT09ICdvYmplY3QnICYmICFBcnJheS5pc0FycmF5KGlucHV0U2luZ3VsYXIpKSB7XG4gICAgICAgIHJldHVybiBwYXJzZUxvY2FsZShpbnB1dFNpbmd1bGFyLmNvZGUsIFtpbnB1dFNpbmd1bGFyLmNvZGVdLCBpbnB1dFNpbmd1bGFyKTtcbiAgICB9XG4gICAgcmV0dXJuIHF1ZXJ5TG9jYWxlKGlucHV0U2luZ3VsYXIsIGF2YWlsYWJsZSk7XG59XG5mdW5jdGlvbiBxdWVyeUxvY2FsZShjb2RlQXJnLCBhdmFpbGFibGUpIHtcbiAgICBsZXQgY29kZXMgPSBbXS5jb25jYXQoY29kZUFyZyB8fCBbXSk7IC8vIHdpbGwgY29udmVydCB0byBhcnJheVxuICAgIGxldCByYXcgPSBxdWVyeVJhd0xvY2FsZShjb2RlcywgYXZhaWxhYmxlKSB8fCBSQVdfRU5fTE9DQUxFO1xuICAgIHJldHVybiBwYXJzZUxvY2FsZShjb2RlQXJnLCBjb2RlcywgcmF3KTtcbn1cbmZ1bmN0aW9uIHF1ZXJ5UmF3TG9jYWxlKGNvZGVzLCBhdmFpbGFibGUpIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvZGVzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgIGxldCBwYXJ0cyA9IGNvZGVzW2ldLnRvTG9jYWxlTG93ZXJDYXNlKCkuc3BsaXQoJy0nKTtcbiAgICAgICAgZm9yIChsZXQgaiA9IHBhcnRzLmxlbmd0aDsgaiA+IDA7IGogLT0gMSkge1xuICAgICAgICAgICAgbGV0IHNpbXBsZUlkID0gcGFydHMuc2xpY2UoMCwgaikuam9pbignLScpO1xuICAgICAgICAgICAgaWYgKGF2YWlsYWJsZVtzaW1wbGVJZF0pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXZhaWxhYmxlW3NpbXBsZUlkXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn1cbmZ1bmN0aW9uIHBhcnNlTG9jYWxlKGNvZGVBcmcsIGNvZGVzLCByYXcpIHtcbiAgICBsZXQgbWVyZ2VkID0gbWVyZ2VQcm9wcyhbTUlOSU1BTF9SQVdfRU5fTE9DQUxFLCByYXddLCBbJ2J1dHRvblRleHQnXSk7XG4gICAgZGVsZXRlIG1lcmdlZC5jb2RlOyAvLyBkb24ndCB3YW50IHRoaXMgcGFydCBvZiB0aGUgb3B0aW9uc1xuICAgIGxldCB7IHdlZWsgfSA9IG1lcmdlZDtcbiAgICBkZWxldGUgbWVyZ2VkLndlZWs7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgY29kZUFyZyxcbiAgICAgICAgY29kZXMsXG4gICAgICAgIHdlZWssXG4gICAgICAgIHNpbXBsZU51bWJlckZvcm1hdDogbmV3IEludGwuTnVtYmVyRm9ybWF0KGNvZGVBcmcpLFxuICAgICAgICBvcHRpb25zOiBtZXJnZWQsXG4gICAgfTtcbn1cblxuLy8gVE9ETzogZWFzaWVyIHdheSB0byBhZGQgbmV3IGhvb2tzPyBuZWVkIHRvIHVwZGF0ZSBhIG1pbGxpb24gdGhpbmdzXG5mdW5jdGlvbiBjcmVhdGVQbHVnaW4oaW5wdXQpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBpZDogZ3VpZCgpLFxuICAgICAgICBuYW1lOiBpbnB1dC5uYW1lLFxuICAgICAgICBwcmVtaXVtUmVsZWFzZURhdGU6IGlucHV0LnByZW1pdW1SZWxlYXNlRGF0ZSA/IG5ldyBEYXRlKGlucHV0LnByZW1pdW1SZWxlYXNlRGF0ZSkgOiB1bmRlZmluZWQsXG4gICAgICAgIGRlcHM6IGlucHV0LmRlcHMgfHwgW10sXG4gICAgICAgIHJlZHVjZXJzOiBpbnB1dC5yZWR1Y2VycyB8fCBbXSxcbiAgICAgICAgaXNMb2FkaW5nRnVuY3M6IGlucHV0LmlzTG9hZGluZ0Z1bmNzIHx8IFtdLFxuICAgICAgICBjb250ZXh0SW5pdDogW10uY29uY2F0KGlucHV0LmNvbnRleHRJbml0IHx8IFtdKSxcbiAgICAgICAgZXZlbnRSZWZpbmVyczogaW5wdXQuZXZlbnRSZWZpbmVycyB8fCB7fSxcbiAgICAgICAgZXZlbnREZWZNZW1iZXJBZGRlcnM6IGlucHV0LmV2ZW50RGVmTWVtYmVyQWRkZXJzIHx8IFtdLFxuICAgICAgICBldmVudFNvdXJjZVJlZmluZXJzOiBpbnB1dC5ldmVudFNvdXJjZVJlZmluZXJzIHx8IHt9LFxuICAgICAgICBpc0RyYWdnYWJsZVRyYW5zZm9ybWVyczogaW5wdXQuaXNEcmFnZ2FibGVUcmFuc2Zvcm1lcnMgfHwgW10sXG4gICAgICAgIGV2ZW50RHJhZ011dGF0aW9uTWFzc2FnZXJzOiBpbnB1dC5ldmVudERyYWdNdXRhdGlvbk1hc3NhZ2VycyB8fCBbXSxcbiAgICAgICAgZXZlbnREZWZNdXRhdGlvbkFwcGxpZXJzOiBpbnB1dC5ldmVudERlZk11dGF0aW9uQXBwbGllcnMgfHwgW10sXG4gICAgICAgIGRhdGVTZWxlY3Rpb25UcmFuc2Zvcm1lcnM6IGlucHV0LmRhdGVTZWxlY3Rpb25UcmFuc2Zvcm1lcnMgfHwgW10sXG4gICAgICAgIGRhdGVQb2ludFRyYW5zZm9ybXM6IGlucHV0LmRhdGVQb2ludFRyYW5zZm9ybXMgfHwgW10sXG4gICAgICAgIGRhdGVTcGFuVHJhbnNmb3JtczogaW5wdXQuZGF0ZVNwYW5UcmFuc2Zvcm1zIHx8IFtdLFxuICAgICAgICB2aWV3czogaW5wdXQudmlld3MgfHwge30sXG4gICAgICAgIHZpZXdQcm9wc1RyYW5zZm9ybWVyczogaW5wdXQudmlld1Byb3BzVHJhbnNmb3JtZXJzIHx8IFtdLFxuICAgICAgICBpc1Byb3BzVmFsaWQ6IGlucHV0LmlzUHJvcHNWYWxpZCB8fCBudWxsLFxuICAgICAgICBleHRlcm5hbERlZlRyYW5zZm9ybXM6IGlucHV0LmV4dGVybmFsRGVmVHJhbnNmb3JtcyB8fCBbXSxcbiAgICAgICAgdmlld0NvbnRhaW5lckFwcGVuZHM6IGlucHV0LnZpZXdDb250YWluZXJBcHBlbmRzIHx8IFtdLFxuICAgICAgICBldmVudERyb3BUcmFuc2Zvcm1lcnM6IGlucHV0LmV2ZW50RHJvcFRyYW5zZm9ybWVycyB8fCBbXSxcbiAgICAgICAgY29tcG9uZW50SW50ZXJhY3Rpb25zOiBpbnB1dC5jb21wb25lbnRJbnRlcmFjdGlvbnMgfHwgW10sXG4gICAgICAgIGNhbGVuZGFySW50ZXJhY3Rpb25zOiBpbnB1dC5jYWxlbmRhckludGVyYWN0aW9ucyB8fCBbXSxcbiAgICAgICAgdGhlbWVDbGFzc2VzOiBpbnB1dC50aGVtZUNsYXNzZXMgfHwge30sXG4gICAgICAgIGV2ZW50U291cmNlRGVmczogaW5wdXQuZXZlbnRTb3VyY2VEZWZzIHx8IFtdLFxuICAgICAgICBjbWRGb3JtYXR0ZXI6IGlucHV0LmNtZEZvcm1hdHRlcixcbiAgICAgICAgcmVjdXJyaW5nVHlwZXM6IGlucHV0LnJlY3VycmluZ1R5cGVzIHx8IFtdLFxuICAgICAgICBuYW1lZFRpbWVab25lZEltcGw6IGlucHV0Lm5hbWVkVGltZVpvbmVkSW1wbCxcbiAgICAgICAgaW5pdGlhbFZpZXc6IGlucHV0LmluaXRpYWxWaWV3IHx8ICcnLFxuICAgICAgICBlbGVtZW50RHJhZ2dpbmdJbXBsOiBpbnB1dC5lbGVtZW50RHJhZ2dpbmdJbXBsLFxuICAgICAgICBvcHRpb25DaGFuZ2VIYW5kbGVyczogaW5wdXQub3B0aW9uQ2hhbmdlSGFuZGxlcnMgfHwge30sXG4gICAgICAgIHNjcm9sbEdyaWRJbXBsOiBpbnB1dC5zY3JvbGxHcmlkSW1wbCB8fCBudWxsLFxuICAgICAgICBsaXN0ZW5lclJlZmluZXJzOiBpbnB1dC5saXN0ZW5lclJlZmluZXJzIHx8IHt9LFxuICAgICAgICBvcHRpb25SZWZpbmVyczogaW5wdXQub3B0aW9uUmVmaW5lcnMgfHwge30sXG4gICAgICAgIHByb3BTZXRIYW5kbGVyczogaW5wdXQucHJvcFNldEhhbmRsZXJzIHx8IHt9LFxuICAgIH07XG59XG5mdW5jdGlvbiBidWlsZFBsdWdpbkhvb2tzKHBsdWdpbkRlZnMsIGdsb2JhbERlZnMpIHtcbiAgICBsZXQgY3VycmVudFBsdWdpbklkcyA9IHt9O1xuICAgIGxldCBob29rcyA9IHtcbiAgICAgICAgcHJlbWl1bVJlbGVhc2VEYXRlOiB1bmRlZmluZWQsXG4gICAgICAgIHJlZHVjZXJzOiBbXSxcbiAgICAgICAgaXNMb2FkaW5nRnVuY3M6IFtdLFxuICAgICAgICBjb250ZXh0SW5pdDogW10sXG4gICAgICAgIGV2ZW50UmVmaW5lcnM6IHt9LFxuICAgICAgICBldmVudERlZk1lbWJlckFkZGVyczogW10sXG4gICAgICAgIGV2ZW50U291cmNlUmVmaW5lcnM6IHt9LFxuICAgICAgICBpc0RyYWdnYWJsZVRyYW5zZm9ybWVyczogW10sXG4gICAgICAgIGV2ZW50RHJhZ011dGF0aW9uTWFzc2FnZXJzOiBbXSxcbiAgICAgICAgZXZlbnREZWZNdXRhdGlvbkFwcGxpZXJzOiBbXSxcbiAgICAgICAgZGF0ZVNlbGVjdGlvblRyYW5zZm9ybWVyczogW10sXG4gICAgICAgIGRhdGVQb2ludFRyYW5zZm9ybXM6IFtdLFxuICAgICAgICBkYXRlU3BhblRyYW5zZm9ybXM6IFtdLFxuICAgICAgICB2aWV3czoge30sXG4gICAgICAgIHZpZXdQcm9wc1RyYW5zZm9ybWVyczogW10sXG4gICAgICAgIGlzUHJvcHNWYWxpZDogbnVsbCxcbiAgICAgICAgZXh0ZXJuYWxEZWZUcmFuc2Zvcm1zOiBbXSxcbiAgICAgICAgdmlld0NvbnRhaW5lckFwcGVuZHM6IFtdLFxuICAgICAgICBldmVudERyb3BUcmFuc2Zvcm1lcnM6IFtdLFxuICAgICAgICBjb21wb25lbnRJbnRlcmFjdGlvbnM6IFtdLFxuICAgICAgICBjYWxlbmRhckludGVyYWN0aW9uczogW10sXG4gICAgICAgIHRoZW1lQ2xhc3Nlczoge30sXG4gICAgICAgIGV2ZW50U291cmNlRGVmczogW10sXG4gICAgICAgIGNtZEZvcm1hdHRlcjogbnVsbCxcbiAgICAgICAgcmVjdXJyaW5nVHlwZXM6IFtdLFxuICAgICAgICBuYW1lZFRpbWVab25lZEltcGw6IG51bGwsXG4gICAgICAgIGluaXRpYWxWaWV3OiAnJyxcbiAgICAgICAgZWxlbWVudERyYWdnaW5nSW1wbDogbnVsbCxcbiAgICAgICAgb3B0aW9uQ2hhbmdlSGFuZGxlcnM6IHt9LFxuICAgICAgICBzY3JvbGxHcmlkSW1wbDogbnVsbCxcbiAgICAgICAgbGlzdGVuZXJSZWZpbmVyczoge30sXG4gICAgICAgIG9wdGlvblJlZmluZXJzOiB7fSxcbiAgICAgICAgcHJvcFNldEhhbmRsZXJzOiB7fSxcbiAgICB9O1xuICAgIGZ1bmN0aW9uIGFkZERlZnMoZGVmcykge1xuICAgICAgICBmb3IgKGxldCBkZWYgb2YgZGVmcykge1xuICAgICAgICAgICAgY29uc3QgcGx1Z2luTmFtZSA9IGRlZi5uYW1lO1xuICAgICAgICAgICAgY29uc3QgY3VycmVudElkID0gY3VycmVudFBsdWdpbklkc1twbHVnaW5OYW1lXTtcbiAgICAgICAgICAgIGlmIChjdXJyZW50SWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGN1cnJlbnRQbHVnaW5JZHNbcGx1Z2luTmFtZV0gPSBkZWYuaWQ7XG4gICAgICAgICAgICAgICAgYWRkRGVmcyhkZWYuZGVwcyk7XG4gICAgICAgICAgICAgICAgaG9va3MgPSBjb21iaW5lSG9va3MoaG9va3MsIGRlZik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChjdXJyZW50SWQgIT09IGRlZi5pZCkge1xuICAgICAgICAgICAgICAgIC8vIGRpZmZlcmVudCBJRCB0aGFuIHRoZSBvbmUgYWxyZWFkeSBhZGRlZFxuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihgRHVwbGljYXRlIHBsdWdpbiAnJHtwbHVnaW5OYW1lfSdgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAocGx1Z2luRGVmcykge1xuICAgICAgICBhZGREZWZzKHBsdWdpbkRlZnMpO1xuICAgIH1cbiAgICBhZGREZWZzKGdsb2JhbERlZnMpO1xuICAgIHJldHVybiBob29rcztcbn1cbmZ1bmN0aW9uIGJ1aWxkQnVpbGRQbHVnaW5Ib29rcygpIHtcbiAgICBsZXQgY3VycmVudE92ZXJyaWRlRGVmcyA9IFtdO1xuICAgIGxldCBjdXJyZW50R2xvYmFsRGVmcyA9IFtdO1xuICAgIGxldCBjdXJyZW50SG9va3M7XG4gICAgcmV0dXJuIChvdmVycmlkZURlZnMsIGdsb2JhbERlZnMpID0+IHtcbiAgICAgICAgaWYgKCFjdXJyZW50SG9va3MgfHwgIWlzQXJyYXlzRXF1YWwob3ZlcnJpZGVEZWZzLCBjdXJyZW50T3ZlcnJpZGVEZWZzKSB8fCAhaXNBcnJheXNFcXVhbChnbG9iYWxEZWZzLCBjdXJyZW50R2xvYmFsRGVmcykpIHtcbiAgICAgICAgICAgIGN1cnJlbnRIb29rcyA9IGJ1aWxkUGx1Z2luSG9va3Mob3ZlcnJpZGVEZWZzLCBnbG9iYWxEZWZzKTtcbiAgICAgICAgfVxuICAgICAgICBjdXJyZW50T3ZlcnJpZGVEZWZzID0gb3ZlcnJpZGVEZWZzO1xuICAgICAgICBjdXJyZW50R2xvYmFsRGVmcyA9IGdsb2JhbERlZnM7XG4gICAgICAgIHJldHVybiBjdXJyZW50SG9va3M7XG4gICAgfTtcbn1cbmZ1bmN0aW9uIGNvbWJpbmVIb29rcyhob29rczAsIGhvb2tzMSkge1xuICAgIHJldHVybiB7XG4gICAgICAgIHByZW1pdW1SZWxlYXNlRGF0ZTogY29tcGFyZU9wdGlvbmFsRGF0ZXMoaG9va3MwLnByZW1pdW1SZWxlYXNlRGF0ZSwgaG9va3MxLnByZW1pdW1SZWxlYXNlRGF0ZSksXG4gICAgICAgIHJlZHVjZXJzOiBob29rczAucmVkdWNlcnMuY29uY2F0KGhvb2tzMS5yZWR1Y2VycyksXG4gICAgICAgIGlzTG9hZGluZ0Z1bmNzOiBob29rczAuaXNMb2FkaW5nRnVuY3MuY29uY2F0KGhvb2tzMS5pc0xvYWRpbmdGdW5jcyksXG4gICAgICAgIGNvbnRleHRJbml0OiBob29rczAuY29udGV4dEluaXQuY29uY2F0KGhvb2tzMS5jb250ZXh0SW5pdCksXG4gICAgICAgIGV2ZW50UmVmaW5lcnM6IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgaG9va3MwLmV2ZW50UmVmaW5lcnMpLCBob29rczEuZXZlbnRSZWZpbmVycyksXG4gICAgICAgIGV2ZW50RGVmTWVtYmVyQWRkZXJzOiBob29rczAuZXZlbnREZWZNZW1iZXJBZGRlcnMuY29uY2F0KGhvb2tzMS5ldmVudERlZk1lbWJlckFkZGVycyksXG4gICAgICAgIGV2ZW50U291cmNlUmVmaW5lcnM6IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgaG9va3MwLmV2ZW50U291cmNlUmVmaW5lcnMpLCBob29rczEuZXZlbnRTb3VyY2VSZWZpbmVycyksXG4gICAgICAgIGlzRHJhZ2dhYmxlVHJhbnNmb3JtZXJzOiBob29rczAuaXNEcmFnZ2FibGVUcmFuc2Zvcm1lcnMuY29uY2F0KGhvb2tzMS5pc0RyYWdnYWJsZVRyYW5zZm9ybWVycyksXG4gICAgICAgIGV2ZW50RHJhZ011dGF0aW9uTWFzc2FnZXJzOiBob29rczAuZXZlbnREcmFnTXV0YXRpb25NYXNzYWdlcnMuY29uY2F0KGhvb2tzMS5ldmVudERyYWdNdXRhdGlvbk1hc3NhZ2VycyksXG4gICAgICAgIGV2ZW50RGVmTXV0YXRpb25BcHBsaWVyczogaG9va3MwLmV2ZW50RGVmTXV0YXRpb25BcHBsaWVycy5jb25jYXQoaG9va3MxLmV2ZW50RGVmTXV0YXRpb25BcHBsaWVycyksXG4gICAgICAgIGRhdGVTZWxlY3Rpb25UcmFuc2Zvcm1lcnM6IGhvb2tzMC5kYXRlU2VsZWN0aW9uVHJhbnNmb3JtZXJzLmNvbmNhdChob29rczEuZGF0ZVNlbGVjdGlvblRyYW5zZm9ybWVycyksXG4gICAgICAgIGRhdGVQb2ludFRyYW5zZm9ybXM6IGhvb2tzMC5kYXRlUG9pbnRUcmFuc2Zvcm1zLmNvbmNhdChob29rczEuZGF0ZVBvaW50VHJhbnNmb3JtcyksXG4gICAgICAgIGRhdGVTcGFuVHJhbnNmb3JtczogaG9va3MwLmRhdGVTcGFuVHJhbnNmb3Jtcy5jb25jYXQoaG9va3MxLmRhdGVTcGFuVHJhbnNmb3JtcyksXG4gICAgICAgIHZpZXdzOiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIGhvb2tzMC52aWV3cyksIGhvb2tzMS52aWV3cyksXG4gICAgICAgIHZpZXdQcm9wc1RyYW5zZm9ybWVyczogaG9va3MwLnZpZXdQcm9wc1RyYW5zZm9ybWVycy5jb25jYXQoaG9va3MxLnZpZXdQcm9wc1RyYW5zZm9ybWVycyksXG4gICAgICAgIGlzUHJvcHNWYWxpZDogaG9va3MxLmlzUHJvcHNWYWxpZCB8fCBob29rczAuaXNQcm9wc1ZhbGlkLFxuICAgICAgICBleHRlcm5hbERlZlRyYW5zZm9ybXM6IGhvb2tzMC5leHRlcm5hbERlZlRyYW5zZm9ybXMuY29uY2F0KGhvb2tzMS5leHRlcm5hbERlZlRyYW5zZm9ybXMpLFxuICAgICAgICB2aWV3Q29udGFpbmVyQXBwZW5kczogaG9va3MwLnZpZXdDb250YWluZXJBcHBlbmRzLmNvbmNhdChob29rczEudmlld0NvbnRhaW5lckFwcGVuZHMpLFxuICAgICAgICBldmVudERyb3BUcmFuc2Zvcm1lcnM6IGhvb2tzMC5ldmVudERyb3BUcmFuc2Zvcm1lcnMuY29uY2F0KGhvb2tzMS5ldmVudERyb3BUcmFuc2Zvcm1lcnMpLFxuICAgICAgICBjYWxlbmRhckludGVyYWN0aW9uczogaG9va3MwLmNhbGVuZGFySW50ZXJhY3Rpb25zLmNvbmNhdChob29rczEuY2FsZW5kYXJJbnRlcmFjdGlvbnMpLFxuICAgICAgICBjb21wb25lbnRJbnRlcmFjdGlvbnM6IGhvb2tzMC5jb21wb25lbnRJbnRlcmFjdGlvbnMuY29uY2F0KGhvb2tzMS5jb21wb25lbnRJbnRlcmFjdGlvbnMpLFxuICAgICAgICB0aGVtZUNsYXNzZXM6IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgaG9va3MwLnRoZW1lQ2xhc3NlcyksIGhvb2tzMS50aGVtZUNsYXNzZXMpLFxuICAgICAgICBldmVudFNvdXJjZURlZnM6IGhvb2tzMC5ldmVudFNvdXJjZURlZnMuY29uY2F0KGhvb2tzMS5ldmVudFNvdXJjZURlZnMpLFxuICAgICAgICBjbWRGb3JtYXR0ZXI6IGhvb2tzMS5jbWRGb3JtYXR0ZXIgfHwgaG9va3MwLmNtZEZvcm1hdHRlcixcbiAgICAgICAgcmVjdXJyaW5nVHlwZXM6IGhvb2tzMC5yZWN1cnJpbmdUeXBlcy5jb25jYXQoaG9va3MxLnJlY3VycmluZ1R5cGVzKSxcbiAgICAgICAgbmFtZWRUaW1lWm9uZWRJbXBsOiBob29rczEubmFtZWRUaW1lWm9uZWRJbXBsIHx8IGhvb2tzMC5uYW1lZFRpbWVab25lZEltcGwsXG4gICAgICAgIGluaXRpYWxWaWV3OiBob29rczAuaW5pdGlhbFZpZXcgfHwgaG9va3MxLmluaXRpYWxWaWV3LFxuICAgICAgICBlbGVtZW50RHJhZ2dpbmdJbXBsOiBob29rczAuZWxlbWVudERyYWdnaW5nSW1wbCB8fCBob29rczEuZWxlbWVudERyYWdnaW5nSW1wbCxcbiAgICAgICAgb3B0aW9uQ2hhbmdlSGFuZGxlcnM6IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgaG9va3MwLm9wdGlvbkNoYW5nZUhhbmRsZXJzKSwgaG9va3MxLm9wdGlvbkNoYW5nZUhhbmRsZXJzKSxcbiAgICAgICAgc2Nyb2xsR3JpZEltcGw6IGhvb2tzMS5zY3JvbGxHcmlkSW1wbCB8fCBob29rczAuc2Nyb2xsR3JpZEltcGwsXG4gICAgICAgIGxpc3RlbmVyUmVmaW5lcnM6IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgaG9va3MwLmxpc3RlbmVyUmVmaW5lcnMpLCBob29rczEubGlzdGVuZXJSZWZpbmVycyksXG4gICAgICAgIG9wdGlvblJlZmluZXJzOiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIGhvb2tzMC5vcHRpb25SZWZpbmVycyksIGhvb2tzMS5vcHRpb25SZWZpbmVycyksXG4gICAgICAgIHByb3BTZXRIYW5kbGVyczogT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBob29rczAucHJvcFNldEhhbmRsZXJzKSwgaG9va3MxLnByb3BTZXRIYW5kbGVycyksXG4gICAgfTtcbn1cbmZ1bmN0aW9uIGNvbXBhcmVPcHRpb25hbERhdGVzKGRhdGUwLCBkYXRlMSkge1xuICAgIGlmIChkYXRlMCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBkYXRlMTtcbiAgICB9XG4gICAgaWYgKGRhdGUxID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIGRhdGUwO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IERhdGUoTWF0aC5tYXgoZGF0ZTAudmFsdWVPZigpLCBkYXRlMS52YWx1ZU9mKCkpKTtcbn1cblxuY2xhc3MgU3RhbmRhcmRUaGVtZSBleHRlbmRzIFRoZW1lIHtcbn1cblN0YW5kYXJkVGhlbWUucHJvdG90eXBlLmNsYXNzZXMgPSB7XG4gICAgcm9vdDogJ2ZjLXRoZW1lLXN0YW5kYXJkJyxcbiAgICB0YWJsZUNlbGxTaGFkZWQ6ICdmYy1jZWxsLXNoYWRlZCcsXG4gICAgYnV0dG9uR3JvdXA6ICdmYy1idXR0b24tZ3JvdXAnLFxuICAgIGJ1dHRvbjogJ2ZjLWJ1dHRvbiBmYy1idXR0b24tcHJpbWFyeScsXG4gICAgYnV0dG9uQWN0aXZlOiAnZmMtYnV0dG9uLWFjdGl2ZScsXG59O1xuU3RhbmRhcmRUaGVtZS5wcm90b3R5cGUuYmFzZUljb25DbGFzcyA9ICdmYy1pY29uJztcblN0YW5kYXJkVGhlbWUucHJvdG90eXBlLmljb25DbGFzc2VzID0ge1xuICAgIGNsb3NlOiAnZmMtaWNvbi14JyxcbiAgICBwcmV2OiAnZmMtaWNvbi1jaGV2cm9uLWxlZnQnLFxuICAgIG5leHQ6ICdmYy1pY29uLWNoZXZyb24tcmlnaHQnLFxuICAgIHByZXZZZWFyOiAnZmMtaWNvbi1jaGV2cm9ucy1sZWZ0JyxcbiAgICBuZXh0WWVhcjogJ2ZjLWljb24tY2hldnJvbnMtcmlnaHQnLFxufTtcblN0YW5kYXJkVGhlbWUucHJvdG90eXBlLnJ0bEljb25DbGFzc2VzID0ge1xuICAgIHByZXY6ICdmYy1pY29uLWNoZXZyb24tcmlnaHQnLFxuICAgIG5leHQ6ICdmYy1pY29uLWNoZXZyb24tbGVmdCcsXG4gICAgcHJldlllYXI6ICdmYy1pY29uLWNoZXZyb25zLXJpZ2h0JyxcbiAgICBuZXh0WWVhcjogJ2ZjLWljb24tY2hldnJvbnMtbGVmdCcsXG59O1xuU3RhbmRhcmRUaGVtZS5wcm90b3R5cGUuaWNvbk92ZXJyaWRlT3B0aW9uID0gJ2J1dHRvbkljb25zJzsgLy8gVE9ETzogbWFrZSBUUy1mcmllbmRseVxuU3RhbmRhcmRUaGVtZS5wcm90b3R5cGUuaWNvbk92ZXJyaWRlQ3VzdG9tQnV0dG9uT3B0aW9uID0gJ2ljb24nO1xuU3RhbmRhcmRUaGVtZS5wcm90b3R5cGUuaWNvbk92ZXJyaWRlUHJlZml4ID0gJ2ZjLWljb24tJztcblxuZnVuY3Rpb24gY29tcGlsZVZpZXdEZWZzKGRlZmF1bHRDb25maWdzLCBvdmVycmlkZUNvbmZpZ3MpIHtcbiAgICBsZXQgaGFzaCA9IHt9O1xuICAgIGxldCB2aWV3VHlwZTtcbiAgICBmb3IgKHZpZXdUeXBlIGluIGRlZmF1bHRDb25maWdzKSB7XG4gICAgICAgIGVuc3VyZVZpZXdEZWYodmlld1R5cGUsIGhhc2gsIGRlZmF1bHRDb25maWdzLCBvdmVycmlkZUNvbmZpZ3MpO1xuICAgIH1cbiAgICBmb3IgKHZpZXdUeXBlIGluIG92ZXJyaWRlQ29uZmlncykge1xuICAgICAgICBlbnN1cmVWaWV3RGVmKHZpZXdUeXBlLCBoYXNoLCBkZWZhdWx0Q29uZmlncywgb3ZlcnJpZGVDb25maWdzKTtcbiAgICB9XG4gICAgcmV0dXJuIGhhc2g7XG59XG5mdW5jdGlvbiBlbnN1cmVWaWV3RGVmKHZpZXdUeXBlLCBoYXNoLCBkZWZhdWx0Q29uZmlncywgb3ZlcnJpZGVDb25maWdzKSB7XG4gICAgaWYgKGhhc2hbdmlld1R5cGVdKSB7XG4gICAgICAgIHJldHVybiBoYXNoW3ZpZXdUeXBlXTtcbiAgICB9XG4gICAgbGV0IHZpZXdEZWYgPSBidWlsZFZpZXdEZWYodmlld1R5cGUsIGhhc2gsIGRlZmF1bHRDb25maWdzLCBvdmVycmlkZUNvbmZpZ3MpO1xuICAgIGlmICh2aWV3RGVmKSB7XG4gICAgICAgIGhhc2hbdmlld1R5cGVdID0gdmlld0RlZjtcbiAgICB9XG4gICAgcmV0dXJuIHZpZXdEZWY7XG59XG5mdW5jdGlvbiBidWlsZFZpZXdEZWYodmlld1R5cGUsIGhhc2gsIGRlZmF1bHRDb25maWdzLCBvdmVycmlkZUNvbmZpZ3MpIHtcbiAgICBsZXQgZGVmYXVsdENvbmZpZyA9IGRlZmF1bHRDb25maWdzW3ZpZXdUeXBlXTtcbiAgICBsZXQgb3ZlcnJpZGVDb25maWcgPSBvdmVycmlkZUNvbmZpZ3Nbdmlld1R5cGVdO1xuICAgIGxldCBxdWVyeVByb3AgPSAobmFtZSkgPT4gKChkZWZhdWx0Q29uZmlnICYmIGRlZmF1bHRDb25maWdbbmFtZV0gIT09IG51bGwpID8gZGVmYXVsdENvbmZpZ1tuYW1lXSA6XG4gICAgICAgICgob3ZlcnJpZGVDb25maWcgJiYgb3ZlcnJpZGVDb25maWdbbmFtZV0gIT09IG51bGwpID8gb3ZlcnJpZGVDb25maWdbbmFtZV0gOiBudWxsKSk7XG4gICAgbGV0IHRoZUNvbXBvbmVudCA9IHF1ZXJ5UHJvcCgnY29tcG9uZW50Jyk7XG4gICAgbGV0IHN1cGVyVHlwZSA9IHF1ZXJ5UHJvcCgnc3VwZXJUeXBlJyk7XG4gICAgbGV0IHN1cGVyRGVmID0gbnVsbDtcbiAgICBpZiAoc3VwZXJUeXBlKSB7XG4gICAgICAgIGlmIChzdXBlclR5cGUgPT09IHZpZXdUeXBlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NhblxcJ3QgaGF2ZSBhIGN1c3RvbSB2aWV3IHR5cGUgdGhhdCByZWZlcmVuY2VzIGl0c2VsZicpO1xuICAgICAgICB9XG4gICAgICAgIHN1cGVyRGVmID0gZW5zdXJlVmlld0RlZihzdXBlclR5cGUsIGhhc2gsIGRlZmF1bHRDb25maWdzLCBvdmVycmlkZUNvbmZpZ3MpO1xuICAgIH1cbiAgICBpZiAoIXRoZUNvbXBvbmVudCAmJiBzdXBlckRlZikge1xuICAgICAgICB0aGVDb21wb25lbnQgPSBzdXBlckRlZi5jb21wb25lbnQ7XG4gICAgfVxuICAgIGlmICghdGhlQ29tcG9uZW50KSB7XG4gICAgICAgIHJldHVybiBudWxsOyAvLyBkb24ndCB0aHJvdyBhIHdhcm5pbmcsIG1pZ2h0IGJlIHNldHRpbmdzIGZvciBhIHNpbmdsZS11bml0IHZpZXdcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogdmlld1R5cGUsXG4gICAgICAgIGNvbXBvbmVudDogdGhlQ29tcG9uZW50LFxuICAgICAgICBkZWZhdWx0czogT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCAoc3VwZXJEZWYgPyBzdXBlckRlZi5kZWZhdWx0cyA6IHt9KSksIChkZWZhdWx0Q29uZmlnID8gZGVmYXVsdENvbmZpZy5yYXdPcHRpb25zIDoge30pKSxcbiAgICAgICAgb3ZlcnJpZGVzOiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIChzdXBlckRlZiA/IHN1cGVyRGVmLm92ZXJyaWRlcyA6IHt9KSksIChvdmVycmlkZUNvbmZpZyA/IG92ZXJyaWRlQ29uZmlnLnJhd09wdGlvbnMgOiB7fSkpLFxuICAgIH07XG59XG5cbmZ1bmN0aW9uIHBhcnNlVmlld0NvbmZpZ3MoaW5wdXRzKSB7XG4gICAgcmV0dXJuIG1hcEhhc2goaW5wdXRzLCBwYXJzZVZpZXdDb25maWcpO1xufVxuZnVuY3Rpb24gcGFyc2VWaWV3Q29uZmlnKGlucHV0KSB7XG4gICAgbGV0IHJhd09wdGlvbnMgPSB0eXBlb2YgaW5wdXQgPT09ICdmdW5jdGlvbicgP1xuICAgICAgICB7IGNvbXBvbmVudDogaW5wdXQgfSA6XG4gICAgICAgIGlucHV0O1xuICAgIGxldCB7IGNvbXBvbmVudCB9ID0gcmF3T3B0aW9ucztcbiAgICBpZiAocmF3T3B0aW9ucy5jb250ZW50KSB7XG4gICAgICAgIC8vIFRPRE86IHJlbW92ZSBjb250ZW50L2NsYXNzTmFtZXMvZGlkTW91bnQvZXRjIGZyb20gb3B0aW9ucz9cbiAgICAgICAgY29tcG9uZW50ID0gY3JlYXRlVmlld0hvb2tDb21wb25lbnQocmF3T3B0aW9ucyk7XG4gICAgfVxuICAgIGVsc2UgaWYgKGNvbXBvbmVudCAmJiAhKGNvbXBvbmVudC5wcm90b3R5cGUgaW5zdGFuY2VvZiBCYXNlQ29tcG9uZW50KSkge1xuICAgICAgICAvLyBXSFk/OiBwZW9wbGUgd2VyZSB1c2luZyBgY29tcG9uZW50YCBwcm9wZXJ0eSBmb3IgYGNvbnRlbnRgXG4gICAgICAgIC8vIFRPRE86IGNvbnZlcmdlIG9uIG9uZSBzZXR0aW5nIG5hbWVcbiAgICAgICAgY29tcG9uZW50ID0gY3JlYXRlVmlld0hvb2tDb21wb25lbnQoT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCByYXdPcHRpb25zKSwgeyBjb250ZW50OiBjb21wb25lbnQgfSkpO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBzdXBlclR5cGU6IHJhd09wdGlvbnMudHlwZSxcbiAgICAgICAgY29tcG9uZW50OiBjb21wb25lbnQsXG4gICAgICAgIHJhd09wdGlvbnMsIC8vIGluY2x1ZGVzIHR5cGUgYW5kIGNvbXBvbmVudCB0b28gOihcbiAgICB9O1xufVxuZnVuY3Rpb24gY3JlYXRlVmlld0hvb2tDb21wb25lbnQob3B0aW9ucykge1xuICAgIHJldHVybiAodmlld1Byb3BzKSA9PiAoY3JlYXRlRWxlbWVudChWaWV3Q29udGV4dFR5cGUuQ29uc3VtZXIsIG51bGwsIChjb250ZXh0KSA9PiAoY3JlYXRlRWxlbWVudChDb250ZW50Q29udGFpbmVyLCB7IGVsVGFnOiBcImRpdlwiLCBlbENsYXNzZXM6IGJ1aWxkVmlld0NsYXNzTmFtZXMoY29udGV4dC52aWV3U3BlYyksIHJlbmRlclByb3BzOiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIHZpZXdQcm9wcyksIHsgbmV4dERheVRocmVzaG9sZDogY29udGV4dC5vcHRpb25zLm5leHREYXlUaHJlc2hvbGQgfSksIGdlbmVyYXRvck5hbWU6IHVuZGVmaW5lZCwgY3VzdG9tR2VuZXJhdG9yOiBvcHRpb25zLmNvbnRlbnQsIGNsYXNzTmFtZUdlbmVyYXRvcjogb3B0aW9ucy5jbGFzc05hbWVzLCBkaWRNb3VudDogb3B0aW9ucy5kaWRNb3VudCwgd2lsbFVubW91bnQ6IG9wdGlvbnMud2lsbFVubW91bnQgfSkpKSk7XG59XG5cbmZ1bmN0aW9uIGJ1aWxkVmlld1NwZWNzKGRlZmF1bHRJbnB1dHMsIG9wdGlvbk92ZXJyaWRlcywgZHluYW1pY09wdGlvbk92ZXJyaWRlcywgbG9jYWxlRGVmYXVsdHMpIHtcbiAgICBsZXQgZGVmYXVsdENvbmZpZ3MgPSBwYXJzZVZpZXdDb25maWdzKGRlZmF1bHRJbnB1dHMpO1xuICAgIGxldCBvdmVycmlkZUNvbmZpZ3MgPSBwYXJzZVZpZXdDb25maWdzKG9wdGlvbk92ZXJyaWRlcy52aWV3cyk7XG4gICAgbGV0IHZpZXdEZWZzID0gY29tcGlsZVZpZXdEZWZzKGRlZmF1bHRDb25maWdzLCBvdmVycmlkZUNvbmZpZ3MpO1xuICAgIHJldHVybiBtYXBIYXNoKHZpZXdEZWZzLCAodmlld0RlZikgPT4gYnVpbGRWaWV3U3BlYyh2aWV3RGVmLCBvdmVycmlkZUNvbmZpZ3MsIG9wdGlvbk92ZXJyaWRlcywgZHluYW1pY09wdGlvbk92ZXJyaWRlcywgbG9jYWxlRGVmYXVsdHMpKTtcbn1cbmZ1bmN0aW9uIGJ1aWxkVmlld1NwZWModmlld0RlZiwgb3ZlcnJpZGVDb25maWdzLCBvcHRpb25PdmVycmlkZXMsIGR5bmFtaWNPcHRpb25PdmVycmlkZXMsIGxvY2FsZURlZmF1bHRzKSB7XG4gICAgbGV0IGR1cmF0aW9uSW5wdXQgPSB2aWV3RGVmLm92ZXJyaWRlcy5kdXJhdGlvbiB8fFxuICAgICAgICB2aWV3RGVmLmRlZmF1bHRzLmR1cmF0aW9uIHx8XG4gICAgICAgIGR5bmFtaWNPcHRpb25PdmVycmlkZXMuZHVyYXRpb24gfHxcbiAgICAgICAgb3B0aW9uT3ZlcnJpZGVzLmR1cmF0aW9uO1xuICAgIGxldCBkdXJhdGlvbiA9IG51bGw7XG4gICAgbGV0IGR1cmF0aW9uVW5pdCA9ICcnO1xuICAgIGxldCBzaW5nbGVVbml0ID0gJyc7XG4gICAgbGV0IHNpbmdsZVVuaXRPdmVycmlkZXMgPSB7fTtcbiAgICBpZiAoZHVyYXRpb25JbnB1dCkge1xuICAgICAgICBkdXJhdGlvbiA9IGNyZWF0ZUR1cmF0aW9uQ2FjaGVkKGR1cmF0aW9uSW5wdXQpO1xuICAgICAgICBpZiAoZHVyYXRpb24pIHsgLy8gdmFsaWQ/XG4gICAgICAgICAgICBsZXQgZGVub20gPSBncmVhdGVzdER1cmF0aW9uRGVub21pbmF0b3IoZHVyYXRpb24pO1xuICAgICAgICAgICAgZHVyYXRpb25Vbml0ID0gZGVub20udW5pdDtcbiAgICAgICAgICAgIGlmIChkZW5vbS52YWx1ZSA9PT0gMSkge1xuICAgICAgICAgICAgICAgIHNpbmdsZVVuaXQgPSBkdXJhdGlvblVuaXQ7XG4gICAgICAgICAgICAgICAgc2luZ2xlVW5pdE92ZXJyaWRlcyA9IG92ZXJyaWRlQ29uZmlnc1tkdXJhdGlvblVuaXRdID8gb3ZlcnJpZGVDb25maWdzW2R1cmF0aW9uVW5pdF0ucmF3T3B0aW9ucyA6IHt9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIGxldCBxdWVyeUJ1dHRvblRleHQgPSAob3B0aW9uc1N1YnNldCkgPT4ge1xuICAgICAgICBsZXQgYnV0dG9uVGV4dE1hcCA9IG9wdGlvbnNTdWJzZXQuYnV0dG9uVGV4dCB8fCB7fTtcbiAgICAgICAgbGV0IGJ1dHRvblRleHRLZXkgPSB2aWV3RGVmLmRlZmF1bHRzLmJ1dHRvblRleHRLZXk7XG4gICAgICAgIGlmIChidXR0b25UZXh0S2V5ICE9IG51bGwgJiYgYnV0dG9uVGV4dE1hcFtidXR0b25UZXh0S2V5XSAhPSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gYnV0dG9uVGV4dE1hcFtidXR0b25UZXh0S2V5XTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYnV0dG9uVGV4dE1hcFt2aWV3RGVmLnR5cGVdICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBidXR0b25UZXh0TWFwW3ZpZXdEZWYudHlwZV07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGJ1dHRvblRleHRNYXBbc2luZ2xlVW5pdF0gIT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIGJ1dHRvblRleHRNYXBbc2luZ2xlVW5pdF07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcbiAgICBsZXQgcXVlcnlCdXR0b25UaXRsZSA9IChvcHRpb25zU3Vic2V0KSA9PiB7XG4gICAgICAgIGxldCBidXR0b25IaW50cyA9IG9wdGlvbnNTdWJzZXQuYnV0dG9uSGludHMgfHwge307XG4gICAgICAgIGxldCBidXR0b25LZXkgPSB2aWV3RGVmLmRlZmF1bHRzLmJ1dHRvblRleHRLZXk7IC8vIHVzZSBzYW1lIGtleSBhcyB0ZXh0XG4gICAgICAgIGlmIChidXR0b25LZXkgIT0gbnVsbCAmJiBidXR0b25IaW50c1tidXR0b25LZXldICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBidXR0b25IaW50c1tidXR0b25LZXldO1xuICAgICAgICB9XG4gICAgICAgIGlmIChidXR0b25IaW50c1t2aWV3RGVmLnR5cGVdICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBidXR0b25IaW50c1t2aWV3RGVmLnR5cGVdO1xuICAgICAgICB9XG4gICAgICAgIGlmIChidXR0b25IaW50c1tzaW5nbGVVbml0XSAhPSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gYnV0dG9uSGludHNbc2luZ2xlVW5pdF07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcbiAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiB2aWV3RGVmLnR5cGUsXG4gICAgICAgIGNvbXBvbmVudDogdmlld0RlZi5jb21wb25lbnQsXG4gICAgICAgIGR1cmF0aW9uLFxuICAgICAgICBkdXJhdGlvblVuaXQsXG4gICAgICAgIHNpbmdsZVVuaXQsXG4gICAgICAgIG9wdGlvbkRlZmF1bHRzOiB2aWV3RGVmLmRlZmF1bHRzLFxuICAgICAgICBvcHRpb25PdmVycmlkZXM6IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgc2luZ2xlVW5pdE92ZXJyaWRlcyksIHZpZXdEZWYub3ZlcnJpZGVzKSxcbiAgICAgICAgYnV0dG9uVGV4dE92ZXJyaWRlOiBxdWVyeUJ1dHRvblRleHQoZHluYW1pY09wdGlvbk92ZXJyaWRlcykgfHxcbiAgICAgICAgICAgIHF1ZXJ5QnV0dG9uVGV4dChvcHRpb25PdmVycmlkZXMpIHx8IC8vIGNvbnN0cnVjdG9yLXNwZWNpZmllZCBidXR0b25UZXh0IGxvb2t1cCBoYXNoIHRha2VzIHByZWNlZGVuY2VcbiAgICAgICAgICAgIHZpZXdEZWYub3ZlcnJpZGVzLmJ1dHRvblRleHQsXG4gICAgICAgIGJ1dHRvblRleHREZWZhdWx0OiBxdWVyeUJ1dHRvblRleHQobG9jYWxlRGVmYXVsdHMpIHx8XG4gICAgICAgICAgICB2aWV3RGVmLmRlZmF1bHRzLmJ1dHRvblRleHQgfHxcbiAgICAgICAgICAgIHF1ZXJ5QnV0dG9uVGV4dChCQVNFX09QVElPTl9ERUZBVUxUUykgfHxcbiAgICAgICAgICAgIHZpZXdEZWYudHlwZSxcbiAgICAgICAgLy8gbm90IERSWVxuICAgICAgICBidXR0b25UaXRsZU92ZXJyaWRlOiBxdWVyeUJ1dHRvblRpdGxlKGR5bmFtaWNPcHRpb25PdmVycmlkZXMpIHx8XG4gICAgICAgICAgICBxdWVyeUJ1dHRvblRpdGxlKG9wdGlvbk92ZXJyaWRlcykgfHxcbiAgICAgICAgICAgIHZpZXdEZWYub3ZlcnJpZGVzLmJ1dHRvbkhpbnQsXG4gICAgICAgIGJ1dHRvblRpdGxlRGVmYXVsdDogcXVlcnlCdXR0b25UaXRsZShsb2NhbGVEZWZhdWx0cykgfHxcbiAgICAgICAgICAgIHZpZXdEZWYuZGVmYXVsdHMuYnV0dG9uSGludCB8fFxuICAgICAgICAgICAgcXVlcnlCdXR0b25UaXRsZShCQVNFX09QVElPTl9ERUZBVUxUUyksXG4gICAgICAgIC8vIHdpbGwgZXZlbnR1YWxseSBmYWxsIGJhY2sgdG8gYnV0dG9uVGV4dFxuICAgIH07XG59XG4vLyBoYWNrIHRvIGdldCBtZW1vaXphdGlvbiB3b3JraW5nXG5sZXQgZHVyYXRpb25JbnB1dE1hcCA9IHt9O1xuZnVuY3Rpb24gY3JlYXRlRHVyYXRpb25DYWNoZWQoZHVyYXRpb25JbnB1dCkge1xuICAgIGxldCBqc29uID0gSlNPTi5zdHJpbmdpZnkoZHVyYXRpb25JbnB1dCk7XG4gICAgbGV0IHJlcyA9IGR1cmF0aW9uSW5wdXRNYXBbanNvbl07XG4gICAgaWYgKHJlcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJlcyA9IGNyZWF0ZUR1cmF0aW9uKGR1cmF0aW9uSW5wdXQpO1xuICAgICAgICBkdXJhdGlvbklucHV0TWFwW2pzb25dID0gcmVzO1xuICAgIH1cbiAgICByZXR1cm4gcmVzO1xufVxuXG5mdW5jdGlvbiByZWR1Y2VWaWV3VHlwZSh2aWV3VHlwZSwgYWN0aW9uKSB7XG4gICAgc3dpdGNoIChhY3Rpb24udHlwZSkge1xuICAgICAgICBjYXNlICdDSEFOR0VfVklFV19UWVBFJzpcbiAgICAgICAgICAgIHZpZXdUeXBlID0gYWN0aW9uLnZpZXdUeXBlO1xuICAgIH1cbiAgICByZXR1cm4gdmlld1R5cGU7XG59XG5cbmZ1bmN0aW9uIHJlZHVjZUN1cnJlbnREYXRlKGN1cnJlbnREYXRlLCBhY3Rpb24pIHtcbiAgICBzd2l0Y2ggKGFjdGlvbi50eXBlKSB7XG4gICAgICAgIGNhc2UgJ0NIQU5HRV9EQVRFJzpcbiAgICAgICAgICAgIHJldHVybiBhY3Rpb24uZGF0ZU1hcmtlcjtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJldHVybiBjdXJyZW50RGF0ZTtcbiAgICB9XG59XG4vLyBzaG91bGQgYmUgaW5pdGlhbGl6ZWQgb25jZSBhbmQgc3RheSBjb25zdGFudFxuLy8gdGhpcyB3aWxsIGNoYW5nZSB0b29cbmZ1bmN0aW9uIGdldEluaXRpYWxEYXRlKG9wdGlvbnMsIGRhdGVFbnYsIG5vd01hbmFnZXIpIHtcbiAgICBsZXQgaW5pdGlhbERhdGVJbnB1dCA9IG9wdGlvbnMuaW5pdGlhbERhdGU7XG4gICAgLy8gY29tcHV0ZSB0aGUgaW5pdGlhbCBhbWJpZy10aW1lem9uZSBkYXRlXG4gICAgaWYgKGluaXRpYWxEYXRlSW5wdXQgIT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gZGF0ZUVudi5jcmVhdGVNYXJrZXIoaW5pdGlhbERhdGVJbnB1dCk7XG4gICAgfVxuICAgIHJldHVybiBub3dNYW5hZ2VyLmdldERhdGVNYXJrZXIoKTtcbn1cblxuZnVuY3Rpb24gcmVkdWNlRHluYW1pY09wdGlvbk92ZXJyaWRlcyhkeW5hbWljT3B0aW9uT3ZlcnJpZGVzLCBhY3Rpb24pIHtcbiAgICBzd2l0Y2ggKGFjdGlvbi50eXBlKSB7XG4gICAgICAgIGNhc2UgJ1NFVF9PUFRJT04nOlxuICAgICAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgZHluYW1pY09wdGlvbk92ZXJyaWRlcyksIHsgW2FjdGlvbi5vcHRpb25OYW1lXTogYWN0aW9uLnJhd09wdGlvblZhbHVlIH0pO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmV0dXJuIGR5bmFtaWNPcHRpb25PdmVycmlkZXM7XG4gICAgfVxufVxuXG5mdW5jdGlvbiByZWR1Y2VEYXRlUHJvZmlsZShjdXJyZW50RGF0ZVByb2ZpbGUsIGFjdGlvbiwgY3VycmVudERhdGUsIGRhdGVQcm9maWxlR2VuZXJhdG9yKSB7XG4gICAgbGV0IGRwO1xuICAgIHN3aXRjaCAoYWN0aW9uLnR5cGUpIHtcbiAgICAgICAgY2FzZSAnQ0hBTkdFX1ZJRVdfVFlQRSc6XG4gICAgICAgICAgICByZXR1cm4gZGF0ZVByb2ZpbGVHZW5lcmF0b3IuYnVpbGQoYWN0aW9uLmRhdGVNYXJrZXIgfHwgY3VycmVudERhdGUpO1xuICAgICAgICBjYXNlICdDSEFOR0VfREFURSc6XG4gICAgICAgICAgICByZXR1cm4gZGF0ZVByb2ZpbGVHZW5lcmF0b3IuYnVpbGQoYWN0aW9uLmRhdGVNYXJrZXIpO1xuICAgICAgICBjYXNlICdQUkVWJzpcbiAgICAgICAgICAgIGRwID0gZGF0ZVByb2ZpbGVHZW5lcmF0b3IuYnVpbGRQcmV2KGN1cnJlbnREYXRlUHJvZmlsZSwgY3VycmVudERhdGUpO1xuICAgICAgICAgICAgaWYgKGRwLmlzVmFsaWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZHA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnTkVYVCc6XG4gICAgICAgICAgICBkcCA9IGRhdGVQcm9maWxlR2VuZXJhdG9yLmJ1aWxkTmV4dChjdXJyZW50RGF0ZVByb2ZpbGUsIGN1cnJlbnREYXRlKTtcbiAgICAgICAgICAgIGlmIChkcC5pc1ZhbGlkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHJldHVybiBjdXJyZW50RGF0ZVByb2ZpbGU7XG59XG5cbmZ1bmN0aW9uIGluaXRFdmVudFNvdXJjZXMoY2FsZW5kYXJPcHRpb25zLCBkYXRlUHJvZmlsZSwgY29udGV4dCkge1xuICAgIGxldCBhY3RpdmVSYW5nZSA9IGRhdGVQcm9maWxlID8gZGF0ZVByb2ZpbGUuYWN0aXZlUmFuZ2UgOiBudWxsO1xuICAgIHJldHVybiBhZGRTb3VyY2VzKHt9LCBwYXJzZUluaXRpYWxTb3VyY2VzKGNhbGVuZGFyT3B0aW9ucywgY29udGV4dCksIGFjdGl2ZVJhbmdlLCBjb250ZXh0KTtcbn1cbmZ1bmN0aW9uIHJlZHVjZUV2ZW50U291cmNlcyhldmVudFNvdXJjZXMsIGFjdGlvbiwgZGF0ZVByb2ZpbGUsIGNvbnRleHQpIHtcbiAgICBsZXQgYWN0aXZlUmFuZ2UgPSBkYXRlUHJvZmlsZSA/IGRhdGVQcm9maWxlLmFjdGl2ZVJhbmdlIDogbnVsbDsgLy8gbmVlZCB0aGlzIGNoZWNrP1xuICAgIHN3aXRjaCAoYWN0aW9uLnR5cGUpIHtcbiAgICAgICAgY2FzZSAnQUREX0VWRU5UX1NPVVJDRVMnOiAvLyBhbHJlYWR5IHBhcnNlZFxuICAgICAgICAgICAgcmV0dXJuIGFkZFNvdXJjZXMoZXZlbnRTb3VyY2VzLCBhY3Rpb24uc291cmNlcywgYWN0aXZlUmFuZ2UsIGNvbnRleHQpO1xuICAgICAgICBjYXNlICdSRU1PVkVfRVZFTlRfU09VUkNFJzpcbiAgICAgICAgICAgIHJldHVybiByZW1vdmVTb3VyY2UoZXZlbnRTb3VyY2VzLCBhY3Rpb24uc291cmNlSWQpO1xuICAgICAgICBjYXNlICdQUkVWJzogLy8gVE9ETzogaG93IGRvIHdlIHRyYWNrIGFsbCBhY3Rpb25zIHRoYXQgYWZmZWN0IGRhdGVQcm9maWxlIDooXG4gICAgICAgIGNhc2UgJ05FWFQnOlxuICAgICAgICBjYXNlICdDSEFOR0VfREFURSc6XG4gICAgICAgIGNhc2UgJ0NIQU5HRV9WSUVXX1RZUEUnOlxuICAgICAgICAgICAgaWYgKGRhdGVQcm9maWxlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZldGNoRGlydHlTb3VyY2VzKGV2ZW50U291cmNlcywgYWN0aXZlUmFuZ2UsIGNvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGV2ZW50U291cmNlcztcbiAgICAgICAgY2FzZSAnRkVUQ0hfRVZFTlRfU09VUkNFUyc6XG4gICAgICAgICAgICByZXR1cm4gZmV0Y2hTb3VyY2VzQnlJZHMoZXZlbnRTb3VyY2VzLCBhY3Rpb24uc291cmNlSWRzID8gLy8gd2h5IG5vIHR5cGU/XG4gICAgICAgICAgICAgICAgYXJyYXlUb0hhc2goYWN0aW9uLnNvdXJjZUlkcykgOlxuICAgICAgICAgICAgICAgIGV4Y2x1ZGVTdGF0aWNTb3VyY2VzKGV2ZW50U291cmNlcywgY29udGV4dCksIGFjdGl2ZVJhbmdlLCBhY3Rpb24uaXNSZWZldGNoIHx8IGZhbHNlLCBjb250ZXh0KTtcbiAgICAgICAgY2FzZSAnUkVDRUlWRV9FVkVOVFMnOlxuICAgICAgICBjYXNlICdSRUNFSVZFX0VWRU5UX0VSUk9SJzpcbiAgICAgICAgICAgIHJldHVybiByZWNlaXZlUmVzcG9uc2UoZXZlbnRTb3VyY2VzLCBhY3Rpb24uc291cmNlSWQsIGFjdGlvbi5mZXRjaElkLCBhY3Rpb24uZmV0Y2hSYW5nZSk7XG4gICAgICAgIGNhc2UgJ1JFTU9WRV9BTExfRVZFTlRfU09VUkNFUyc6XG4gICAgICAgICAgICByZXR1cm4ge307XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gZXZlbnRTb3VyY2VzO1xuICAgIH1cbn1cbmZ1bmN0aW9uIHJlZHVjZUV2ZW50U291cmNlc05ld1RpbWVab25lKGV2ZW50U291cmNlcywgZGF0ZVByb2ZpbGUsIGNvbnRleHQpIHtcbiAgICBsZXQgYWN0aXZlUmFuZ2UgPSBkYXRlUHJvZmlsZSA/IGRhdGVQcm9maWxlLmFjdGl2ZVJhbmdlIDogbnVsbDsgLy8gbmVlZCB0aGlzIGNoZWNrP1xuICAgIHJldHVybiBmZXRjaFNvdXJjZXNCeUlkcyhldmVudFNvdXJjZXMsIGV4Y2x1ZGVTdGF0aWNTb3VyY2VzKGV2ZW50U291cmNlcywgY29udGV4dCksIGFjdGl2ZVJhbmdlLCB0cnVlLCBjb250ZXh0KTtcbn1cbmZ1bmN0aW9uIGNvbXB1dGVFdmVudFNvdXJjZXNMb2FkaW5nKGV2ZW50U291cmNlcykge1xuICAgIGZvciAobGV0IHNvdXJjZUlkIGluIGV2ZW50U291cmNlcykge1xuICAgICAgICBpZiAoZXZlbnRTb3VyY2VzW3NvdXJjZUlkXS5pc0ZldGNoaW5nKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5mdW5jdGlvbiBhZGRTb3VyY2VzKGV2ZW50U291cmNlSGFzaCwgc291cmNlcywgZmV0Y2hSYW5nZSwgY29udGV4dCkge1xuICAgIGxldCBoYXNoID0ge307XG4gICAgZm9yIChsZXQgc291cmNlIG9mIHNvdXJjZXMpIHtcbiAgICAgICAgaGFzaFtzb3VyY2Uuc291cmNlSWRdID0gc291cmNlO1xuICAgIH1cbiAgICBpZiAoZmV0Y2hSYW5nZSkge1xuICAgICAgICBoYXNoID0gZmV0Y2hEaXJ0eVNvdXJjZXMoaGFzaCwgZmV0Y2hSYW5nZSwgY29udGV4dCk7XG4gICAgfVxuICAgIHJldHVybiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIGV2ZW50U291cmNlSGFzaCksIGhhc2gpO1xufVxuZnVuY3Rpb24gcmVtb3ZlU291cmNlKGV2ZW50U291cmNlSGFzaCwgc291cmNlSWQpIHtcbiAgICByZXR1cm4gZmlsdGVySGFzaChldmVudFNvdXJjZUhhc2gsIChldmVudFNvdXJjZSkgPT4gZXZlbnRTb3VyY2Uuc291cmNlSWQgIT09IHNvdXJjZUlkKTtcbn1cbmZ1bmN0aW9uIGZldGNoRGlydHlTb3VyY2VzKHNvdXJjZUhhc2gsIGZldGNoUmFuZ2UsIGNvbnRleHQpIHtcbiAgICByZXR1cm4gZmV0Y2hTb3VyY2VzQnlJZHMoc291cmNlSGFzaCwgZmlsdGVySGFzaChzb3VyY2VIYXNoLCAoZXZlbnRTb3VyY2UpID0+IGlzU291cmNlRGlydHkoZXZlbnRTb3VyY2UsIGZldGNoUmFuZ2UsIGNvbnRleHQpKSwgZmV0Y2hSYW5nZSwgZmFsc2UsIGNvbnRleHQpO1xufVxuZnVuY3Rpb24gaXNTb3VyY2VEaXJ0eShldmVudFNvdXJjZSwgZmV0Y2hSYW5nZSwgY29udGV4dCkge1xuICAgIGlmICghZG9lc1NvdXJjZU5lZWRSYW5nZShldmVudFNvdXJjZSwgY29udGV4dCkpIHtcbiAgICAgICAgcmV0dXJuICFldmVudFNvdXJjZS5sYXRlc3RGZXRjaElkO1xuICAgIH1cbiAgICByZXR1cm4gIWNvbnRleHQub3B0aW9ucy5sYXp5RmV0Y2hpbmcgfHxcbiAgICAgICAgIWV2ZW50U291cmNlLmZldGNoUmFuZ2UgfHxcbiAgICAgICAgZXZlbnRTb3VyY2UuaXNGZXRjaGluZyB8fCAvLyBhbHdheXMgY2FuY2VsIG91dGRhdGVkIGluLXByb2dyZXNzIGZldGNoZXNcbiAgICAgICAgZmV0Y2hSYW5nZS5zdGFydCA8IGV2ZW50U291cmNlLmZldGNoUmFuZ2Uuc3RhcnQgfHxcbiAgICAgICAgZmV0Y2hSYW5nZS5lbmQgPiBldmVudFNvdXJjZS5mZXRjaFJhbmdlLmVuZDtcbn1cbmZ1bmN0aW9uIGZldGNoU291cmNlc0J5SWRzKHByZXZTb3VyY2VzLCBzb3VyY2VJZEhhc2gsIGZldGNoUmFuZ2UsIGlzUmVmZXRjaCwgY29udGV4dCkge1xuICAgIGxldCBuZXh0U291cmNlcyA9IHt9O1xuICAgIGZvciAobGV0IHNvdXJjZUlkIGluIHByZXZTb3VyY2VzKSB7XG4gICAgICAgIGxldCBzb3VyY2UgPSBwcmV2U291cmNlc1tzb3VyY2VJZF07XG4gICAgICAgIGlmIChzb3VyY2VJZEhhc2hbc291cmNlSWRdKSB7XG4gICAgICAgICAgICBuZXh0U291cmNlc1tzb3VyY2VJZF0gPSBmZXRjaFNvdXJjZShzb3VyY2UsIGZldGNoUmFuZ2UsIGlzUmVmZXRjaCwgY29udGV4dCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBuZXh0U291cmNlc1tzb3VyY2VJZF0gPSBzb3VyY2U7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG5leHRTb3VyY2VzO1xufVxuZnVuY3Rpb24gZmV0Y2hTb3VyY2UoZXZlbnRTb3VyY2UsIGZldGNoUmFuZ2UsIGlzUmVmZXRjaCwgY29udGV4dCkge1xuICAgIGxldCB7IG9wdGlvbnMsIGNhbGVuZGFyQXBpIH0gPSBjb250ZXh0O1xuICAgIGxldCBzb3VyY2VEZWYgPSBjb250ZXh0LnBsdWdpbkhvb2tzLmV2ZW50U291cmNlRGVmc1tldmVudFNvdXJjZS5zb3VyY2VEZWZJZF07XG4gICAgbGV0IGZldGNoSWQgPSBndWlkKCk7XG4gICAgc291cmNlRGVmLmZldGNoKHtcbiAgICAgICAgZXZlbnRTb3VyY2UsXG4gICAgICAgIHJhbmdlOiBmZXRjaFJhbmdlLFxuICAgICAgICBpc1JlZmV0Y2gsXG4gICAgICAgIGNvbnRleHQsXG4gICAgfSwgKHJlcykgPT4ge1xuICAgICAgICBsZXQgeyByYXdFdmVudHMgfSA9IHJlcztcbiAgICAgICAgaWYgKG9wdGlvbnMuZXZlbnRTb3VyY2VTdWNjZXNzKSB7XG4gICAgICAgICAgICByYXdFdmVudHMgPSBvcHRpb25zLmV2ZW50U291cmNlU3VjY2Vzcy5jYWxsKGNhbGVuZGFyQXBpLCByYXdFdmVudHMsIHJlcy5yZXNwb25zZSkgfHwgcmF3RXZlbnRzO1xuICAgICAgICB9XG4gICAgICAgIGlmIChldmVudFNvdXJjZS5zdWNjZXNzKSB7XG4gICAgICAgICAgICByYXdFdmVudHMgPSBldmVudFNvdXJjZS5zdWNjZXNzLmNhbGwoY2FsZW5kYXJBcGksIHJhd0V2ZW50cywgcmVzLnJlc3BvbnNlKSB8fCByYXdFdmVudHM7XG4gICAgICAgIH1cbiAgICAgICAgY29udGV4dC5kaXNwYXRjaCh7XG4gICAgICAgICAgICB0eXBlOiAnUkVDRUlWRV9FVkVOVFMnLFxuICAgICAgICAgICAgc291cmNlSWQ6IGV2ZW50U291cmNlLnNvdXJjZUlkLFxuICAgICAgICAgICAgZmV0Y2hJZCxcbiAgICAgICAgICAgIGZldGNoUmFuZ2UsXG4gICAgICAgICAgICByYXdFdmVudHMsXG4gICAgICAgIH0pO1xuICAgIH0sIChlcnJvcikgPT4ge1xuICAgICAgICBsZXQgZXJyb3JIYW5kbGVkID0gZmFsc2U7XG4gICAgICAgIGlmIChvcHRpb25zLmV2ZW50U291cmNlRmFpbHVyZSkge1xuICAgICAgICAgICAgb3B0aW9ucy5ldmVudFNvdXJjZUZhaWx1cmUuY2FsbChjYWxlbmRhckFwaSwgZXJyb3IpO1xuICAgICAgICAgICAgZXJyb3JIYW5kbGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZXZlbnRTb3VyY2UuZmFpbHVyZSkge1xuICAgICAgICAgICAgZXZlbnRTb3VyY2UuZmFpbHVyZShlcnJvcik7XG4gICAgICAgICAgICBlcnJvckhhbmRsZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmICghZXJyb3JIYW5kbGVkKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oZXJyb3IubWVzc2FnZSwgZXJyb3IpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRleHQuZGlzcGF0Y2goe1xuICAgICAgICAgICAgdHlwZTogJ1JFQ0VJVkVfRVZFTlRfRVJST1InLFxuICAgICAgICAgICAgc291cmNlSWQ6IGV2ZW50U291cmNlLnNvdXJjZUlkLFxuICAgICAgICAgICAgZmV0Y2hJZCxcbiAgICAgICAgICAgIGZldGNoUmFuZ2UsXG4gICAgICAgICAgICBlcnJvcixcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgZXZlbnRTb3VyY2UpLCB7IGlzRmV0Y2hpbmc6IHRydWUsIGxhdGVzdEZldGNoSWQ6IGZldGNoSWQgfSk7XG59XG5mdW5jdGlvbiByZWNlaXZlUmVzcG9uc2Uoc291cmNlSGFzaCwgc291cmNlSWQsIGZldGNoSWQsIGZldGNoUmFuZ2UpIHtcbiAgICBsZXQgZXZlbnRTb3VyY2UgPSBzb3VyY2VIYXNoW3NvdXJjZUlkXTtcbiAgICBpZiAoZXZlbnRTb3VyY2UgJiYgLy8gbm90IGFscmVhZHkgcmVtb3ZlZFxuICAgICAgICBmZXRjaElkID09PSBldmVudFNvdXJjZS5sYXRlc3RGZXRjaElkKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIHNvdXJjZUhhc2gpLCB7IFtzb3VyY2VJZF06IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgZXZlbnRTb3VyY2UpLCB7IGlzRmV0Y2hpbmc6IGZhbHNlLCBmZXRjaFJhbmdlIH0pIH0pO1xuICAgIH1cbiAgICByZXR1cm4gc291cmNlSGFzaDtcbn1cbmZ1bmN0aW9uIGV4Y2x1ZGVTdGF0aWNTb3VyY2VzKGV2ZW50U291cmNlcywgY29udGV4dCkge1xuICAgIHJldHVybiBmaWx0ZXJIYXNoKGV2ZW50U291cmNlcywgKGV2ZW50U291cmNlKSA9PiBkb2VzU291cmNlTmVlZFJhbmdlKGV2ZW50U291cmNlLCBjb250ZXh0KSk7XG59XG5mdW5jdGlvbiBwYXJzZUluaXRpYWxTb3VyY2VzKHJhd09wdGlvbnMsIGNvbnRleHQpIHtcbiAgICBsZXQgcmVmaW5lcnMgPSBidWlsZEV2ZW50U291cmNlUmVmaW5lcnMoY29udGV4dCk7XG4gICAgbGV0IHJhd1NvdXJjZXMgPSBbXS5jb25jYXQocmF3T3B0aW9ucy5ldmVudFNvdXJjZXMgfHwgW10pO1xuICAgIGxldCBzb3VyY2VzID0gW107IC8vIHBhcnNlZFxuICAgIGlmIChyYXdPcHRpb25zLmluaXRpYWxFdmVudHMpIHtcbiAgICAgICAgcmF3U291cmNlcy51bnNoaWZ0KHJhd09wdGlvbnMuaW5pdGlhbEV2ZW50cyk7XG4gICAgfVxuICAgIGlmIChyYXdPcHRpb25zLmV2ZW50cykge1xuICAgICAgICByYXdTb3VyY2VzLnVuc2hpZnQocmF3T3B0aW9ucy5ldmVudHMpO1xuICAgIH1cbiAgICBmb3IgKGxldCByYXdTb3VyY2Ugb2YgcmF3U291cmNlcykge1xuICAgICAgICBsZXQgc291cmNlID0gcGFyc2VFdmVudFNvdXJjZShyYXdTb3VyY2UsIGNvbnRleHQsIHJlZmluZXJzKTtcbiAgICAgICAgaWYgKHNvdXJjZSkge1xuICAgICAgICAgICAgc291cmNlcy5wdXNoKHNvdXJjZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHNvdXJjZXM7XG59XG5mdW5jdGlvbiBkb2VzU291cmNlTmVlZFJhbmdlKGV2ZW50U291cmNlLCBjb250ZXh0KSB7XG4gICAgbGV0IGRlZnMgPSBjb250ZXh0LnBsdWdpbkhvb2tzLmV2ZW50U291cmNlRGVmcztcbiAgICByZXR1cm4gIWRlZnNbZXZlbnRTb3VyY2Uuc291cmNlRGVmSWRdLmlnbm9yZVJhbmdlO1xufVxuXG5mdW5jdGlvbiByZWR1Y2VEYXRlU2VsZWN0aW9uKGN1cnJlbnRTZWxlY3Rpb24sIGFjdGlvbikge1xuICAgIHN3aXRjaCAoYWN0aW9uLnR5cGUpIHtcbiAgICAgICAgY2FzZSAnVU5TRUxFQ1RfREFURVMnOlxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIGNhc2UgJ1NFTEVDVF9EQVRFUyc6XG4gICAgICAgICAgICByZXR1cm4gYWN0aW9uLnNlbGVjdGlvbjtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJldHVybiBjdXJyZW50U2VsZWN0aW9uO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gcmVkdWNlU2VsZWN0ZWRFdmVudChjdXJyZW50SW5zdGFuY2VJZCwgYWN0aW9uKSB7XG4gICAgc3dpdGNoIChhY3Rpb24udHlwZSkge1xuICAgICAgICBjYXNlICdVTlNFTEVDVF9FVkVOVCc6XG4gICAgICAgICAgICByZXR1cm4gJyc7XG4gICAgICAgIGNhc2UgJ1NFTEVDVF9FVkVOVCc6XG4gICAgICAgICAgICByZXR1cm4gYWN0aW9uLmV2ZW50SW5zdGFuY2VJZDtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJldHVybiBjdXJyZW50SW5zdGFuY2VJZDtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHJlZHVjZUV2ZW50RHJhZyhjdXJyZW50RHJhZywgYWN0aW9uKSB7XG4gICAgbGV0IG5ld0RyYWc7XG4gICAgc3dpdGNoIChhY3Rpb24udHlwZSkge1xuICAgICAgICBjYXNlICdVTlNFVF9FVkVOVF9EUkFHJzpcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICBjYXNlICdTRVRfRVZFTlRfRFJBRyc6XG4gICAgICAgICAgICBuZXdEcmFnID0gYWN0aW9uLnN0YXRlO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBhZmZlY3RlZEV2ZW50czogbmV3RHJhZy5hZmZlY3RlZEV2ZW50cyxcbiAgICAgICAgICAgICAgICBtdXRhdGVkRXZlbnRzOiBuZXdEcmFnLm11dGF0ZWRFdmVudHMsXG4gICAgICAgICAgICAgICAgaXNFdmVudDogbmV3RHJhZy5pc0V2ZW50LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJldHVybiBjdXJyZW50RHJhZztcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHJlZHVjZUV2ZW50UmVzaXplKGN1cnJlbnRSZXNpemUsIGFjdGlvbikge1xuICAgIGxldCBuZXdSZXNpemU7XG4gICAgc3dpdGNoIChhY3Rpb24udHlwZSkge1xuICAgICAgICBjYXNlICdVTlNFVF9FVkVOVF9SRVNJWkUnOlxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIGNhc2UgJ1NFVF9FVkVOVF9SRVNJWkUnOlxuICAgICAgICAgICAgbmV3UmVzaXplID0gYWN0aW9uLnN0YXRlO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBhZmZlY3RlZEV2ZW50czogbmV3UmVzaXplLmFmZmVjdGVkRXZlbnRzLFxuICAgICAgICAgICAgICAgIG11dGF0ZWRFdmVudHM6IG5ld1Jlc2l6ZS5tdXRhdGVkRXZlbnRzLFxuICAgICAgICAgICAgICAgIGlzRXZlbnQ6IG5ld1Jlc2l6ZS5pc0V2ZW50LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJldHVybiBjdXJyZW50UmVzaXplO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gcGFyc2VUb29sYmFycyhjYWxlbmRhck9wdGlvbnMsIGNhbGVuZGFyT3B0aW9uT3ZlcnJpZGVzLCB0aGVtZSwgdmlld1NwZWNzLCBjYWxlbmRhckFwaSkge1xuICAgIGxldCBoZWFkZXIgPSBjYWxlbmRhck9wdGlvbnMuaGVhZGVyVG9vbGJhciA/IHBhcnNlVG9vbGJhcihjYWxlbmRhck9wdGlvbnMuaGVhZGVyVG9vbGJhciwgY2FsZW5kYXJPcHRpb25zLCBjYWxlbmRhck9wdGlvbk92ZXJyaWRlcywgdGhlbWUsIHZpZXdTcGVjcywgY2FsZW5kYXJBcGkpIDogbnVsbDtcbiAgICBsZXQgZm9vdGVyID0gY2FsZW5kYXJPcHRpb25zLmZvb3RlclRvb2xiYXIgPyBwYXJzZVRvb2xiYXIoY2FsZW5kYXJPcHRpb25zLmZvb3RlclRvb2xiYXIsIGNhbGVuZGFyT3B0aW9ucywgY2FsZW5kYXJPcHRpb25PdmVycmlkZXMsIHRoZW1lLCB2aWV3U3BlY3MsIGNhbGVuZGFyQXBpKSA6IG51bGw7XG4gICAgcmV0dXJuIHsgaGVhZGVyLCBmb290ZXIgfTtcbn1cbmZ1bmN0aW9uIHBhcnNlVG9vbGJhcihzZWN0aW9uU3RySGFzaCwgY2FsZW5kYXJPcHRpb25zLCBjYWxlbmRhck9wdGlvbk92ZXJyaWRlcywgdGhlbWUsIHZpZXdTcGVjcywgY2FsZW5kYXJBcGkpIHtcbiAgICBsZXQgc2VjdGlvbldpZGdldHMgPSB7fTtcbiAgICBsZXQgdmlld3NXaXRoQnV0dG9ucyA9IFtdO1xuICAgIGxldCBoYXNUaXRsZSA9IGZhbHNlO1xuICAgIGZvciAobGV0IHNlY3Rpb25OYW1lIGluIHNlY3Rpb25TdHJIYXNoKSB7XG4gICAgICAgIGxldCBzZWN0aW9uU3RyID0gc2VjdGlvblN0ckhhc2hbc2VjdGlvbk5hbWVdO1xuICAgICAgICBsZXQgc2VjdGlvblJlcyA9IHBhcnNlU2VjdGlvbihzZWN0aW9uU3RyLCBjYWxlbmRhck9wdGlvbnMsIGNhbGVuZGFyT3B0aW9uT3ZlcnJpZGVzLCB0aGVtZSwgdmlld1NwZWNzLCBjYWxlbmRhckFwaSk7XG4gICAgICAgIHNlY3Rpb25XaWRnZXRzW3NlY3Rpb25OYW1lXSA9IHNlY3Rpb25SZXMud2lkZ2V0cztcbiAgICAgICAgdmlld3NXaXRoQnV0dG9ucy5wdXNoKC4uLnNlY3Rpb25SZXMudmlld3NXaXRoQnV0dG9ucyk7XG4gICAgICAgIGhhc1RpdGxlID0gaGFzVGl0bGUgfHwgc2VjdGlvblJlcy5oYXNUaXRsZTtcbiAgICB9XG4gICAgcmV0dXJuIHsgc2VjdGlvbldpZGdldHMsIHZpZXdzV2l0aEJ1dHRvbnMsIGhhc1RpdGxlIH07XG59XG4vKlxuQkFEOiBxdWVyeWluZyBpY29ucyBhbmQgdGV4dCBoZXJlLiBzaG91bGQgYmUgZG9uZSBhdCByZW5kZXIgdGltZVxuKi9cbmZ1bmN0aW9uIHBhcnNlU2VjdGlvbihzZWN0aW9uU3RyLCBjYWxlbmRhck9wdGlvbnMsIC8vIGRlZmF1bHRzK292ZXJyaWRlcywgdGhlbiByZWZpbmVkXG5jYWxlbmRhck9wdGlvbk92ZXJyaWRlcywgLy8gb3ZlcnJpZGVzIG9ubHkhLCB1bnJlZmluZWQgOihcbnRoZW1lLCB2aWV3U3BlY3MsIGNhbGVuZGFyQXBpKSB7XG4gICAgbGV0IGlzUnRsID0gY2FsZW5kYXJPcHRpb25zLmRpcmVjdGlvbiA9PT0gJ3J0bCc7XG4gICAgbGV0IGNhbGVuZGFyQ3VzdG9tQnV0dG9ucyA9IGNhbGVuZGFyT3B0aW9ucy5jdXN0b21CdXR0b25zIHx8IHt9O1xuICAgIGxldCBjYWxlbmRhckJ1dHRvblRleHRPdmVycmlkZXMgPSBjYWxlbmRhck9wdGlvbk92ZXJyaWRlcy5idXR0b25UZXh0IHx8IHt9O1xuICAgIGxldCBjYWxlbmRhckJ1dHRvblRleHQgPSBjYWxlbmRhck9wdGlvbnMuYnV0dG9uVGV4dCB8fCB7fTtcbiAgICBsZXQgY2FsZW5kYXJCdXR0b25IaW50T3ZlcnJpZGVzID0gY2FsZW5kYXJPcHRpb25PdmVycmlkZXMuYnV0dG9uSGludHMgfHwge307XG4gICAgbGV0IGNhbGVuZGFyQnV0dG9uSGludHMgPSBjYWxlbmRhck9wdGlvbnMuYnV0dG9uSGludHMgfHwge307XG4gICAgbGV0IHNlY3Rpb25TdWJzdHJzID0gc2VjdGlvblN0ciA/IHNlY3Rpb25TdHIuc3BsaXQoJyAnKSA6IFtdO1xuICAgIGxldCB2aWV3c1dpdGhCdXR0b25zID0gW107XG4gICAgbGV0IGhhc1RpdGxlID0gZmFsc2U7XG4gICAgbGV0IHdpZGdldHMgPSBzZWN0aW9uU3Vic3Rycy5tYXAoKGJ1dHRvbkdyb3VwU3RyKSA9PiAoYnV0dG9uR3JvdXBTdHIuc3BsaXQoJywnKS5tYXAoKGJ1dHRvbk5hbWUpID0+IHtcbiAgICAgICAgaWYgKGJ1dHRvbk5hbWUgPT09ICd0aXRsZScpIHtcbiAgICAgICAgICAgIGhhc1RpdGxlID0gdHJ1ZTtcbiAgICAgICAgICAgIHJldHVybiB7IGJ1dHRvbk5hbWUgfTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgY3VzdG9tQnV0dG9uUHJvcHM7XG4gICAgICAgIGxldCB2aWV3U3BlYztcbiAgICAgICAgbGV0IGJ1dHRvbkNsaWNrO1xuICAgICAgICBsZXQgYnV0dG9uSWNvbjsgLy8gb25seSBvbmUgb2YgdGhlc2Ugd2lsbCBiZSBzZXRcbiAgICAgICAgbGV0IGJ1dHRvblRleHQ7IC8vIFwiXG4gICAgICAgIGxldCBidXR0b25IaW50O1xuICAgICAgICAvLyBeIGZvciB0aGUgdGl0bGU9XCJcIiBhdHRyaWJ1dGUsIGZvciBhY2Nlc3NpYmlsaXR5XG4gICAgICAgIGlmICgoY3VzdG9tQnV0dG9uUHJvcHMgPSBjYWxlbmRhckN1c3RvbUJ1dHRvbnNbYnV0dG9uTmFtZV0pKSB7XG4gICAgICAgICAgICBidXR0b25DbGljayA9IChldikgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChjdXN0b21CdXR0b25Qcm9wcy5jbGljaykge1xuICAgICAgICAgICAgICAgICAgICBjdXN0b21CdXR0b25Qcm9wcy5jbGljay5jYWxsKGV2LnRhcmdldCwgZXYsIGV2LnRhcmdldCk7IC8vIFRPRE86IHVzZSBDYWxlbmRhciB0aGlzIGNvbnRleHQ/XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIChidXR0b25JY29uID0gdGhlbWUuZ2V0Q3VzdG9tQnV0dG9uSWNvbkNsYXNzKGN1c3RvbUJ1dHRvblByb3BzKSkgfHxcbiAgICAgICAgICAgICAgICAoYnV0dG9uSWNvbiA9IHRoZW1lLmdldEljb25DbGFzcyhidXR0b25OYW1lLCBpc1J0bCkpIHx8XG4gICAgICAgICAgICAgICAgKGJ1dHRvblRleHQgPSBjdXN0b21CdXR0b25Qcm9wcy50ZXh0KTtcbiAgICAgICAgICAgIGJ1dHRvbkhpbnQgPSBjdXN0b21CdXR0b25Qcm9wcy5oaW50IHx8IGN1c3RvbUJ1dHRvblByb3BzLnRleHQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoKHZpZXdTcGVjID0gdmlld1NwZWNzW2J1dHRvbk5hbWVdKSkge1xuICAgICAgICAgICAgdmlld3NXaXRoQnV0dG9ucy5wdXNoKGJ1dHRvbk5hbWUpO1xuICAgICAgICAgICAgYnV0dG9uQ2xpY2sgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY2FsZW5kYXJBcGkuY2hhbmdlVmlldyhidXR0b25OYW1lKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICAoYnV0dG9uVGV4dCA9IHZpZXdTcGVjLmJ1dHRvblRleHRPdmVycmlkZSkgfHxcbiAgICAgICAgICAgICAgICAoYnV0dG9uSWNvbiA9IHRoZW1lLmdldEljb25DbGFzcyhidXR0b25OYW1lLCBpc1J0bCkpIHx8XG4gICAgICAgICAgICAgICAgKGJ1dHRvblRleHQgPSB2aWV3U3BlYy5idXR0b25UZXh0RGVmYXVsdCk7XG4gICAgICAgICAgICBsZXQgdGV4dEZhbGxiYWNrID0gdmlld1NwZWMuYnV0dG9uVGV4dE92ZXJyaWRlIHx8XG4gICAgICAgICAgICAgICAgdmlld1NwZWMuYnV0dG9uVGV4dERlZmF1bHQ7XG4gICAgICAgICAgICBidXR0b25IaW50ID0gZm9ybWF0V2l0aE9yZGluYWxzKHZpZXdTcGVjLmJ1dHRvblRpdGxlT3ZlcnJpZGUgfHxcbiAgICAgICAgICAgICAgICB2aWV3U3BlYy5idXR0b25UaXRsZURlZmF1bHQgfHxcbiAgICAgICAgICAgICAgICBjYWxlbmRhck9wdGlvbnMudmlld0hpbnQsIFt0ZXh0RmFsbGJhY2ssIGJ1dHRvbk5hbWVdLCAvLyB2aWV3LW5hbWUgPSBidXR0b25OYW1lXG4gICAgICAgICAgICB0ZXh0RmFsbGJhY2spO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGNhbGVuZGFyQXBpW2J1dHRvbk5hbWVdKSB7IC8vIGEgY2FsZW5kYXJBcGkgbWV0aG9kXG4gICAgICAgICAgICBidXR0b25DbGljayA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjYWxlbmRhckFwaVtidXR0b25OYW1lXSgpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIChidXR0b25UZXh0ID0gY2FsZW5kYXJCdXR0b25UZXh0T3ZlcnJpZGVzW2J1dHRvbk5hbWVdKSB8fFxuICAgICAgICAgICAgICAgIChidXR0b25JY29uID0gdGhlbWUuZ2V0SWNvbkNsYXNzKGJ1dHRvbk5hbWUsIGlzUnRsKSkgfHxcbiAgICAgICAgICAgICAgICAoYnV0dG9uVGV4dCA9IGNhbGVuZGFyQnV0dG9uVGV4dFtidXR0b25OYW1lXSk7IC8vIGV2ZXJ5dGhpbmcgZWxzZSBpcyBjb25zaWRlcmVkIGRlZmF1bHRcbiAgICAgICAgICAgIGlmIChidXR0b25OYW1lID09PSAncHJldlllYXInIHx8IGJ1dHRvbk5hbWUgPT09ICduZXh0WWVhcicpIHtcbiAgICAgICAgICAgICAgICBsZXQgcHJldk9yTmV4dCA9IGJ1dHRvbk5hbWUgPT09ICdwcmV2WWVhcicgPyAncHJldicgOiAnbmV4dCc7XG4gICAgICAgICAgICAgICAgYnV0dG9uSGludCA9IGZvcm1hdFdpdGhPcmRpbmFscyhjYWxlbmRhckJ1dHRvbkhpbnRPdmVycmlkZXNbcHJldk9yTmV4dF0gfHxcbiAgICAgICAgICAgICAgICAgICAgY2FsZW5kYXJCdXR0b25IaW50c1twcmV2T3JOZXh0XSwgW1xuICAgICAgICAgICAgICAgICAgICBjYWxlbmRhckJ1dHRvblRleHQueWVhciB8fCAneWVhcicsXG4gICAgICAgICAgICAgICAgICAgICd5ZWFyJyxcbiAgICAgICAgICAgICAgICBdLCBjYWxlbmRhckJ1dHRvblRleHRbYnV0dG9uTmFtZV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYnV0dG9uSGludCA9IChuYXZVbml0KSA9PiBmb3JtYXRXaXRoT3JkaW5hbHMoY2FsZW5kYXJCdXR0b25IaW50T3ZlcnJpZGVzW2J1dHRvbk5hbWVdIHx8XG4gICAgICAgICAgICAgICAgICAgIGNhbGVuZGFyQnV0dG9uSGludHNbYnV0dG9uTmFtZV0sIFtcbiAgICAgICAgICAgICAgICAgICAgY2FsZW5kYXJCdXR0b25UZXh0W25hdlVuaXRdIHx8IG5hdlVuaXQsXG4gICAgICAgICAgICAgICAgICAgIG5hdlVuaXQsXG4gICAgICAgICAgICAgICAgXSwgY2FsZW5kYXJCdXR0b25UZXh0W2J1dHRvbk5hbWVdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geyBidXR0b25OYW1lLCBidXR0b25DbGljaywgYnV0dG9uSWNvbiwgYnV0dG9uVGV4dCwgYnV0dG9uSGludCB9O1xuICAgIH0pKSk7XG4gICAgcmV0dXJuIHsgd2lkZ2V0cywgdmlld3NXaXRoQnV0dG9ucywgaGFzVGl0bGUgfTtcbn1cblxuLy8gYWx3YXlzIHJlcHJlc2VudHMgdGhlIGN1cnJlbnQgdmlldy4gb3RoZXJ3aXNlLCBpdCdkIG5lZWQgdG8gY2hhbmdlIHZhbHVlIGV2ZXJ5IHRpbWUgZGF0ZSBjaGFuZ2VzXG5jbGFzcyBWaWV3SW1wbCB7XG4gICAgY29uc3RydWN0b3IodHlwZSwgZ2V0Q3VycmVudERhdGEsIGRhdGVFbnYpIHtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5nZXRDdXJyZW50RGF0YSA9IGdldEN1cnJlbnREYXRhO1xuICAgICAgICB0aGlzLmRhdGVFbnYgPSBkYXRlRW52O1xuICAgIH1cbiAgICBnZXQgY2FsZW5kYXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldEN1cnJlbnREYXRhKCkuY2FsZW5kYXJBcGk7XG4gICAgfVxuICAgIGdldCB0aXRsZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0Q3VycmVudERhdGEoKS52aWV3VGl0bGU7XG4gICAgfVxuICAgIGdldCBhY3RpdmVTdGFydCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGF0ZUVudi50b0RhdGUodGhpcy5nZXRDdXJyZW50RGF0YSgpLmRhdGVQcm9maWxlLmFjdGl2ZVJhbmdlLnN0YXJ0KTtcbiAgICB9XG4gICAgZ2V0IGFjdGl2ZUVuZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGF0ZUVudi50b0RhdGUodGhpcy5nZXRDdXJyZW50RGF0YSgpLmRhdGVQcm9maWxlLmFjdGl2ZVJhbmdlLmVuZCk7XG4gICAgfVxuICAgIGdldCBjdXJyZW50U3RhcnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmRhdGVFbnYudG9EYXRlKHRoaXMuZ2V0Q3VycmVudERhdGEoKS5kYXRlUHJvZmlsZS5jdXJyZW50UmFuZ2Uuc3RhcnQpO1xuICAgIH1cbiAgICBnZXQgY3VycmVudEVuZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGF0ZUVudi50b0RhdGUodGhpcy5nZXRDdXJyZW50RGF0YSgpLmRhdGVQcm9maWxlLmN1cnJlbnRSYW5nZS5lbmQpO1xuICAgIH1cbiAgICBnZXRPcHRpb24obmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRDdXJyZW50RGF0YSgpLm9wdGlvbnNbbmFtZV07IC8vIGFyZSB0aGUgdmlldy1zcGVjaWZpYyBvcHRpb25zXG4gICAgfVxufVxuXG5sZXQgZXZlbnRTb3VyY2VEZWYkMiA9IHtcbiAgICBpZ25vcmVSYW5nZTogdHJ1ZSxcbiAgICBwYXJzZU1ldGEocmVmaW5lZCkge1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShyZWZpbmVkLmV2ZW50cykpIHtcbiAgICAgICAgICAgIHJldHVybiByZWZpbmVkLmV2ZW50cztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9LFxuICAgIGZldGNoKGFyZywgc3VjY2Vzc0NhbGxiYWNrKSB7XG4gICAgICAgIHN1Y2Nlc3NDYWxsYmFjayh7XG4gICAgICAgICAgICByYXdFdmVudHM6IGFyZy5ldmVudFNvdXJjZS5tZXRhLFxuICAgICAgICB9KTtcbiAgICB9LFxufTtcbmNvbnN0IGFycmF5RXZlbnRTb3VyY2VQbHVnaW4gPSBjcmVhdGVQbHVnaW4oe1xuICAgIG5hbWU6ICdhcnJheS1ldmVudC1zb3VyY2UnLFxuICAgIGV2ZW50U291cmNlRGVmczogW2V2ZW50U291cmNlRGVmJDJdLFxufSk7XG5cbmxldCBldmVudFNvdXJjZURlZiQxID0ge1xuICAgIHBhcnNlTWV0YShyZWZpbmVkKSB7XG4gICAgICAgIGlmICh0eXBlb2YgcmVmaW5lZC5ldmVudHMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiByZWZpbmVkLmV2ZW50cztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9LFxuICAgIGZldGNoKGFyZywgc3VjY2Vzc0NhbGxiYWNrLCBlcnJvckNhbGxiYWNrKSB7XG4gICAgICAgIGNvbnN0IHsgZGF0ZUVudiB9ID0gYXJnLmNvbnRleHQ7XG4gICAgICAgIGNvbnN0IGZ1bmMgPSBhcmcuZXZlbnRTb3VyY2UubWV0YTtcbiAgICAgICAgdW5wcm9taXNpZnkoZnVuYy5iaW5kKG51bGwsIGJ1aWxkUmFuZ2VBcGlXaXRoVGltZVpvbmUoYXJnLnJhbmdlLCBkYXRlRW52KSksIChyYXdFdmVudHMpID0+IHN1Y2Nlc3NDYWxsYmFjayh7IHJhd0V2ZW50cyB9KSwgZXJyb3JDYWxsYmFjayk7XG4gICAgfSxcbn07XG5jb25zdCBmdW5jRXZlbnRTb3VyY2VQbHVnaW4gPSBjcmVhdGVQbHVnaW4oe1xuICAgIG5hbWU6ICdmdW5jLWV2ZW50LXNvdXJjZScsXG4gICAgZXZlbnRTb3VyY2VEZWZzOiBbZXZlbnRTb3VyY2VEZWYkMV0sXG59KTtcblxuY29uc3QgSlNPTl9GRUVEX0VWRU5UX1NPVVJDRV9SRUZJTkVSUyA9IHtcbiAgICBtZXRob2Q6IFN0cmluZyxcbiAgICBleHRyYVBhcmFtczogaWRlbnRpdHksXG4gICAgc3RhcnRQYXJhbTogU3RyaW5nLFxuICAgIGVuZFBhcmFtOiBTdHJpbmcsXG4gICAgdGltZVpvbmVQYXJhbTogU3RyaW5nLFxufTtcblxubGV0IGV2ZW50U291cmNlRGVmID0ge1xuICAgIHBhcnNlTWV0YShyZWZpbmVkKSB7XG4gICAgICAgIGlmIChyZWZpbmVkLnVybCAmJiAocmVmaW5lZC5mb3JtYXQgPT09ICdqc29uJyB8fCAhcmVmaW5lZC5mb3JtYXQpKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHVybDogcmVmaW5lZC51cmwsXG4gICAgICAgICAgICAgICAgZm9ybWF0OiAnanNvbicsXG4gICAgICAgICAgICAgICAgbWV0aG9kOiAocmVmaW5lZC5tZXRob2QgfHwgJ0dFVCcpLnRvVXBwZXJDYXNlKCksXG4gICAgICAgICAgICAgICAgZXh0cmFQYXJhbXM6IHJlZmluZWQuZXh0cmFQYXJhbXMsXG4gICAgICAgICAgICAgICAgc3RhcnRQYXJhbTogcmVmaW5lZC5zdGFydFBhcmFtLFxuICAgICAgICAgICAgICAgIGVuZFBhcmFtOiByZWZpbmVkLmVuZFBhcmFtLFxuICAgICAgICAgICAgICAgIHRpbWVab25lUGFyYW06IHJlZmluZWQudGltZVpvbmVQYXJhbSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfSxcbiAgICBmZXRjaChhcmcsIHN1Y2Nlc3NDYWxsYmFjaywgZXJyb3JDYWxsYmFjaykge1xuICAgICAgICBjb25zdCB7IG1ldGEgfSA9IGFyZy5ldmVudFNvdXJjZTtcbiAgICAgICAgY29uc3QgcmVxdWVzdFBhcmFtcyA9IGJ1aWxkUmVxdWVzdFBhcmFtcyhtZXRhLCBhcmcucmFuZ2UsIGFyZy5jb250ZXh0KTtcbiAgICAgICAgcmVxdWVzdEpzb24obWV0YS5tZXRob2QsIG1ldGEudXJsLCByZXF1ZXN0UGFyYW1zKS50aGVuKChbcmF3RXZlbnRzLCByZXNwb25zZV0pID0+IHtcbiAgICAgICAgICAgIHN1Y2Nlc3NDYWxsYmFjayh7IHJhd0V2ZW50cywgcmVzcG9uc2UgfSk7XG4gICAgICAgIH0sIGVycm9yQ2FsbGJhY2spO1xuICAgIH0sXG59O1xuY29uc3QganNvbkZlZWRFdmVudFNvdXJjZVBsdWdpbiA9IGNyZWF0ZVBsdWdpbih7XG4gICAgbmFtZTogJ2pzb24tZXZlbnQtc291cmNlJyxcbiAgICBldmVudFNvdXJjZVJlZmluZXJzOiBKU09OX0ZFRURfRVZFTlRfU09VUkNFX1JFRklORVJTLFxuICAgIGV2ZW50U291cmNlRGVmczogW2V2ZW50U291cmNlRGVmXSxcbn0pO1xuZnVuY3Rpb24gYnVpbGRSZXF1ZXN0UGFyYW1zKG1ldGEsIHJhbmdlLCBjb250ZXh0KSB7XG4gICAgbGV0IHsgZGF0ZUVudiwgb3B0aW9ucyB9ID0gY29udGV4dDtcbiAgICBsZXQgc3RhcnRQYXJhbTtcbiAgICBsZXQgZW5kUGFyYW07XG4gICAgbGV0IHRpbWVab25lUGFyYW07XG4gICAgbGV0IGN1c3RvbVJlcXVlc3RQYXJhbXM7XG4gICAgbGV0IHBhcmFtcyA9IHt9O1xuICAgIHN0YXJ0UGFyYW0gPSBtZXRhLnN0YXJ0UGFyYW07XG4gICAgaWYgKHN0YXJ0UGFyYW0gPT0gbnVsbCkge1xuICAgICAgICBzdGFydFBhcmFtID0gb3B0aW9ucy5zdGFydFBhcmFtO1xuICAgIH1cbiAgICBlbmRQYXJhbSA9IG1ldGEuZW5kUGFyYW07XG4gICAgaWYgKGVuZFBhcmFtID09IG51bGwpIHtcbiAgICAgICAgZW5kUGFyYW0gPSBvcHRpb25zLmVuZFBhcmFtO1xuICAgIH1cbiAgICB0aW1lWm9uZVBhcmFtID0gbWV0YS50aW1lWm9uZVBhcmFtO1xuICAgIGlmICh0aW1lWm9uZVBhcmFtID09IG51bGwpIHtcbiAgICAgICAgdGltZVpvbmVQYXJhbSA9IG9wdGlvbnMudGltZVpvbmVQYXJhbTtcbiAgICB9XG4gICAgLy8gcmV0cmlldmUgYW55IG91dGJvdW5kIEdFVC9QT1NUIGRhdGEgZnJvbSB0aGUgb3B0aW9uc1xuICAgIGlmICh0eXBlb2YgbWV0YS5leHRyYVBhcmFtcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAvLyBzdXBwbGllZCBhcyBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBhIGtleS92YWx1ZSBvYmplY3RcbiAgICAgICAgY3VzdG9tUmVxdWVzdFBhcmFtcyA9IG1ldGEuZXh0cmFQYXJhbXMoKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIC8vIHByb2JhYmx5IHN1cHBsaWVkIGFzIGEgc3RyYWlnaHQga2V5L3ZhbHVlIG9iamVjdFxuICAgICAgICBjdXN0b21SZXF1ZXN0UGFyYW1zID0gbWV0YS5leHRyYVBhcmFtcyB8fCB7fTtcbiAgICB9XG4gICAgT2JqZWN0LmFzc2lnbihwYXJhbXMsIGN1c3RvbVJlcXVlc3RQYXJhbXMpO1xuICAgIHBhcmFtc1tzdGFydFBhcmFtXSA9IGRhdGVFbnYuZm9ybWF0SXNvKHJhbmdlLnN0YXJ0KTtcbiAgICBwYXJhbXNbZW5kUGFyYW1dID0gZGF0ZUVudi5mb3JtYXRJc28ocmFuZ2UuZW5kKTtcbiAgICBpZiAoZGF0ZUVudi50aW1lWm9uZSAhPT0gJ2xvY2FsJykge1xuICAgICAgICBwYXJhbXNbdGltZVpvbmVQYXJhbV0gPSBkYXRlRW52LnRpbWVab25lO1xuICAgIH1cbiAgICByZXR1cm4gcGFyYW1zO1xufVxuXG5jb25zdCBTSU1QTEVfUkVDVVJSSU5HX1JFRklORVJTID0ge1xuICAgIGRheXNPZldlZWs6IGlkZW50aXR5LFxuICAgIHN0YXJ0VGltZTogY3JlYXRlRHVyYXRpb24sXG4gICAgZW5kVGltZTogY3JlYXRlRHVyYXRpb24sXG4gICAgZHVyYXRpb246IGNyZWF0ZUR1cmF0aW9uLFxuICAgIHN0YXJ0UmVjdXI6IGlkZW50aXR5LFxuICAgIGVuZFJlY3VyOiBpZGVudGl0eSxcbn07XG5cbmxldCByZWN1cnJpbmcgPSB7XG4gICAgcGFyc2UocmVmaW5lZCwgZGF0ZUVudikge1xuICAgICAgICBpZiAocmVmaW5lZC5kYXlzT2ZXZWVrIHx8IHJlZmluZWQuc3RhcnRUaW1lIHx8IHJlZmluZWQuZW5kVGltZSB8fCByZWZpbmVkLnN0YXJ0UmVjdXIgfHwgcmVmaW5lZC5lbmRSZWN1cikge1xuICAgICAgICAgICAgbGV0IHJlY3VycmluZ0RhdGEgPSB7XG4gICAgICAgICAgICAgICAgZGF5c09mV2VlazogcmVmaW5lZC5kYXlzT2ZXZWVrIHx8IG51bGwsXG4gICAgICAgICAgICAgICAgc3RhcnRUaW1lOiByZWZpbmVkLnN0YXJ0VGltZSB8fCBudWxsLFxuICAgICAgICAgICAgICAgIGVuZFRpbWU6IHJlZmluZWQuZW5kVGltZSB8fCBudWxsLFxuICAgICAgICAgICAgICAgIHN0YXJ0UmVjdXI6IHJlZmluZWQuc3RhcnRSZWN1ciA/IGRhdGVFbnYuY3JlYXRlTWFya2VyKHJlZmluZWQuc3RhcnRSZWN1cikgOiBudWxsLFxuICAgICAgICAgICAgICAgIGVuZFJlY3VyOiByZWZpbmVkLmVuZFJlY3VyID8gZGF0ZUVudi5jcmVhdGVNYXJrZXIocmVmaW5lZC5lbmRSZWN1cikgOiBudWxsLFxuICAgICAgICAgICAgICAgIGRhdGVFbnYsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgbGV0IGR1cmF0aW9uO1xuICAgICAgICAgICAgaWYgKHJlZmluZWQuZHVyYXRpb24pIHtcbiAgICAgICAgICAgICAgICBkdXJhdGlvbiA9IHJlZmluZWQuZHVyYXRpb247XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIWR1cmF0aW9uICYmIHJlZmluZWQuc3RhcnRUaW1lICYmIHJlZmluZWQuZW5kVGltZSkge1xuICAgICAgICAgICAgICAgIGR1cmF0aW9uID0gc3VidHJhY3REdXJhdGlvbnMocmVmaW5lZC5lbmRUaW1lLCByZWZpbmVkLnN0YXJ0VGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGFsbERheUd1ZXNzOiBCb29sZWFuKCFyZWZpbmVkLnN0YXJ0VGltZSAmJiAhcmVmaW5lZC5lbmRUaW1lKSxcbiAgICAgICAgICAgICAgICBkdXJhdGlvbixcbiAgICAgICAgICAgICAgICB0eXBlRGF0YTogcmVjdXJyaW5nRGF0YSwgLy8gZG9lc24ndCBuZWVkIGVuZFRpbWUgYW55bW9yZSBidXQgb2ggd2VsbFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9LFxuICAgIGV4cGFuZCh0eXBlRGF0YSwgZnJhbWluZ1JhbmdlLCBkYXRlRW52KSB7XG4gICAgICAgIGxldCBjbGlwcGVkRnJhbWluZ1JhbmdlID0gaW50ZXJzZWN0UmFuZ2VzKGZyYW1pbmdSYW5nZSwgeyBzdGFydDogdHlwZURhdGEuc3RhcnRSZWN1ciwgZW5kOiB0eXBlRGF0YS5lbmRSZWN1ciB9KTtcbiAgICAgICAgaWYgKGNsaXBwZWRGcmFtaW5nUmFuZ2UpIHtcbiAgICAgICAgICAgIHJldHVybiBleHBhbmRSYW5nZXModHlwZURhdGEuZGF5c09mV2VlaywgdHlwZURhdGEuc3RhcnRUaW1lLCB0eXBlRGF0YS5kYXRlRW52LCBkYXRlRW52LCBjbGlwcGVkRnJhbWluZ1JhbmdlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gW107XG4gICAgfSxcbn07XG5jb25zdCBzaW1wbGVSZWN1cnJpbmdFdmVudHNQbHVnaW4gPSBjcmVhdGVQbHVnaW4oe1xuICAgIG5hbWU6ICdzaW1wbGUtcmVjdXJyaW5nLWV2ZW50JyxcbiAgICByZWN1cnJpbmdUeXBlczogW3JlY3VycmluZ10sXG4gICAgZXZlbnRSZWZpbmVyczogU0lNUExFX1JFQ1VSUklOR19SRUZJTkVSUyxcbn0pO1xuZnVuY3Rpb24gZXhwYW5kUmFuZ2VzKGRheXNPZldlZWssIHN0YXJ0VGltZSwgZXZlbnREYXRlRW52LCBjYWxlbmRhckRhdGVFbnYsIGZyYW1pbmdSYW5nZSkge1xuICAgIGxldCBkb3dIYXNoID0gZGF5c09mV2VlayA/IGFycmF5VG9IYXNoKGRheXNPZldlZWspIDogbnVsbDtcbiAgICBsZXQgZGF5TWFya2VyID0gc3RhcnRPZkRheShmcmFtaW5nUmFuZ2Uuc3RhcnQpO1xuICAgIGxldCBlbmRNYXJrZXIgPSBmcmFtaW5nUmFuZ2UuZW5kO1xuICAgIGxldCBpbnN0YW5jZVN0YXJ0cyA9IFtdO1xuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mdWxsY2FsZW5kYXIvZnVsbGNhbGVuZGFyL2lzc3Vlcy83OTM0XG4gICAgaWYgKHN0YXJ0VGltZSkge1xuICAgICAgICBpZiAoc3RhcnRUaW1lLm1pbGxpc2Vjb25kcyA8IDApIHtcbiAgICAgICAgICAgIC8vIHBvc3NpYmxlIGZvciBuZXh0LWRheSB0byBoYXZlIG5lZ2F0aXZlIGJ1c2luZXNzIGhvdXJzIHRoYXQgZ28gaW50byBjdXJyZW50IGRheVxuICAgICAgICAgICAgZW5kTWFya2VyID0gYWRkRGF5cyhlbmRNYXJrZXIsIDEpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHN0YXJ0VGltZS5taWxsaXNlY29uZHMgPj0gMTAwMCAqIDYwICogNjAgKiAyNCkge1xuICAgICAgICAgICAgLy8gcG9zc2libGUgZm9yIHByZXYtZGF5IHRvIGhhdmUgPjI0aHIgYnVzaW5lc3MgaG91cnMgdGhhdCBnbyBpbnRvIGN1cnJlbnQgZGF5XG4gICAgICAgICAgICBkYXlNYXJrZXIgPSBhZGREYXlzKGRheU1hcmtlciwgLTEpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHdoaWxlIChkYXlNYXJrZXIgPCBlbmRNYXJrZXIpIHtcbiAgICAgICAgbGV0IGluc3RhbmNlU3RhcnQ7XG4gICAgICAgIC8vIGlmIGV2ZXJ5ZGF5LCBvciB0aGlzIHBhcnRpY3VsYXIgZGF5LW9mLXdlZWtcbiAgICAgICAgaWYgKCFkb3dIYXNoIHx8IGRvd0hhc2hbZGF5TWFya2VyLmdldFVUQ0RheSgpXSkge1xuICAgICAgICAgICAgaWYgKHN0YXJ0VGltZSkge1xuICAgICAgICAgICAgICAgIGluc3RhbmNlU3RhcnQgPSBjYWxlbmRhckRhdGVFbnYuYWRkKGRheU1hcmtlciwgc3RhcnRUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGluc3RhbmNlU3RhcnQgPSBkYXlNYXJrZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpbnN0YW5jZVN0YXJ0cy5wdXNoKGNhbGVuZGFyRGF0ZUVudi5jcmVhdGVNYXJrZXIoZXZlbnREYXRlRW52LnRvRGF0ZShpbnN0YW5jZVN0YXJ0KSkpO1xuICAgICAgICB9XG4gICAgICAgIGRheU1hcmtlciA9IGFkZERheXMoZGF5TWFya2VyLCAxKTtcbiAgICB9XG4gICAgcmV0dXJuIGluc3RhbmNlU3RhcnRzO1xufVxuXG5jb25zdCBjaGFuZ2VIYW5kbGVyUGx1Z2luID0gY3JlYXRlUGx1Z2luKHtcbiAgICBuYW1lOiAnY2hhbmdlLWhhbmRsZXInLFxuICAgIG9wdGlvbkNoYW5nZUhhbmRsZXJzOiB7XG4gICAgICAgIGV2ZW50cyhldmVudHMsIGNvbnRleHQpIHtcbiAgICAgICAgICAgIGhhbmRsZUV2ZW50U291cmNlcyhbZXZlbnRzXSwgY29udGV4dCk7XG4gICAgICAgIH0sXG4gICAgICAgIGV2ZW50U291cmNlczogaGFuZGxlRXZlbnRTb3VyY2VzLFxuICAgIH0sXG59KTtcbi8qXG5CVUc6IGlmIGBldmVudGAgd2FzIHN1cHBsaWVkLCBhbGwgcHJldmlvdXNseS1naXZlbiBgZXZlbnRTb3VyY2VzYCB3aWxsIGJlIHdpcGVkIG91dFxuKi9cbmZ1bmN0aW9uIGhhbmRsZUV2ZW50U291cmNlcyhpbnB1dHMsIGNvbnRleHQpIHtcbiAgICBsZXQgdW5mb3VuZFNvdXJjZXMgPSBoYXNoVmFsdWVzVG9BcnJheShjb250ZXh0LmdldEN1cnJlbnREYXRhKCkuZXZlbnRTb3VyY2VzKTtcbiAgICBpZiAodW5mb3VuZFNvdXJjZXMubGVuZ3RoID09PSAxICYmXG4gICAgICAgIGlucHV0cy5sZW5ndGggPT09IDEgJiZcbiAgICAgICAgQXJyYXkuaXNBcnJheSh1bmZvdW5kU291cmNlc1swXS5fcmF3KSAmJlxuICAgICAgICBBcnJheS5pc0FycmF5KGlucHV0c1swXSkpIHtcbiAgICAgICAgY29udGV4dC5kaXNwYXRjaCh7XG4gICAgICAgICAgICB0eXBlOiAnUkVTRVRfUkFXX0VWRU5UUycsXG4gICAgICAgICAgICBzb3VyY2VJZDogdW5mb3VuZFNvdXJjZXNbMF0uc291cmNlSWQsXG4gICAgICAgICAgICByYXdFdmVudHM6IGlucHV0c1swXSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGV0IG5ld0lucHV0cyA9IFtdO1xuICAgIGZvciAobGV0IGlucHV0IG9mIGlucHV0cykge1xuICAgICAgICBsZXQgaW5wdXRGb3VuZCA9IGZhbHNlO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHVuZm91bmRTb3VyY2VzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICBpZiAodW5mb3VuZFNvdXJjZXNbaV0uX3JhdyA9PT0gaW5wdXQpIHtcbiAgICAgICAgICAgICAgICB1bmZvdW5kU291cmNlcy5zcGxpY2UoaSwgMSk7IC8vIGRlbGV0ZVxuICAgICAgICAgICAgICAgIGlucHV0Rm91bmQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICghaW5wdXRGb3VuZCkge1xuICAgICAgICAgICAgbmV3SW5wdXRzLnB1c2goaW5wdXQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGZvciAobGV0IHVuZm91bmRTb3VyY2Ugb2YgdW5mb3VuZFNvdXJjZXMpIHtcbiAgICAgICAgY29udGV4dC5kaXNwYXRjaCh7XG4gICAgICAgICAgICB0eXBlOiAnUkVNT1ZFX0VWRU5UX1NPVVJDRScsXG4gICAgICAgICAgICBzb3VyY2VJZDogdW5mb3VuZFNvdXJjZS5zb3VyY2VJZCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGZvciAobGV0IG5ld0lucHV0IG9mIG5ld0lucHV0cykge1xuICAgICAgICBjb250ZXh0LmNhbGVuZGFyQXBpLmFkZEV2ZW50U291cmNlKG5ld0lucHV0KTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGhhbmRsZURhdGVQcm9maWxlKGRhdGVQcm9maWxlLCBjb250ZXh0KSB7XG4gICAgY29udGV4dC5lbWl0dGVyLnRyaWdnZXIoJ2RhdGVzU2V0JywgT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBidWlsZFJhbmdlQXBpV2l0aFRpbWVab25lKGRhdGVQcm9maWxlLmFjdGl2ZVJhbmdlLCBjb250ZXh0LmRhdGVFbnYpKSwgeyB2aWV3OiBjb250ZXh0LnZpZXdBcGkgfSkpO1xufVxuXG5mdW5jdGlvbiBoYW5kbGVFdmVudFN0b3JlKGV2ZW50U3RvcmUsIGNvbnRleHQpIHtcbiAgICBsZXQgeyBlbWl0dGVyIH0gPSBjb250ZXh0O1xuICAgIGlmIChlbWl0dGVyLmhhc0hhbmRsZXJzKCdldmVudHNTZXQnKSkge1xuICAgICAgICBlbWl0dGVyLnRyaWdnZXIoJ2V2ZW50c1NldCcsIGJ1aWxkRXZlbnRBcGlzKGV2ZW50U3RvcmUsIGNvbnRleHQpKTtcbiAgICB9XG59XG5cbi8qXG50aGlzIGFycmF5IGlzIGV4cG9zZWQgb24gdGhlIHJvb3QgbmFtZXNwYWNlIHNvIHRoYXQgVU1EIHBsdWdpbnMgY2FuIGFkZCB0byBpdC5cbnNlZSB0aGUgcm9sbHVwLWJ1bmRsZXMgc2NyaXB0LlxuKi9cbmNvbnN0IGdsb2JhbFBsdWdpbnMgPSBbXG4gICAgYXJyYXlFdmVudFNvdXJjZVBsdWdpbixcbiAgICBmdW5jRXZlbnRTb3VyY2VQbHVnaW4sXG4gICAganNvbkZlZWRFdmVudFNvdXJjZVBsdWdpbixcbiAgICBzaW1wbGVSZWN1cnJpbmdFdmVudHNQbHVnaW4sXG4gICAgY2hhbmdlSGFuZGxlclBsdWdpbixcbiAgICBjcmVhdGVQbHVnaW4oe1xuICAgICAgICBuYW1lOiAnbWlzYycsXG4gICAgICAgIGlzTG9hZGluZ0Z1bmNzOiBbXG4gICAgICAgICAgICAoc3RhdGUpID0+IGNvbXB1dGVFdmVudFNvdXJjZXNMb2FkaW5nKHN0YXRlLmV2ZW50U291cmNlcyksXG4gICAgICAgIF0sXG4gICAgICAgIHByb3BTZXRIYW5kbGVyczoge1xuICAgICAgICAgICAgZGF0ZVByb2ZpbGU6IGhhbmRsZURhdGVQcm9maWxlLFxuICAgICAgICAgICAgZXZlbnRTdG9yZTogaGFuZGxlRXZlbnRTdG9yZSxcbiAgICAgICAgfSxcbiAgICB9KSxcbl07XG5cbmNsYXNzIFRhc2tSdW5uZXIge1xuICAgIGNvbnN0cnVjdG9yKHJ1blRhc2tPcHRpb24sIGRyYWluZWRPcHRpb24pIHtcbiAgICAgICAgdGhpcy5ydW5UYXNrT3B0aW9uID0gcnVuVGFza09wdGlvbjtcbiAgICAgICAgdGhpcy5kcmFpbmVkT3B0aW9uID0gZHJhaW5lZE9wdGlvbjtcbiAgICAgICAgdGhpcy5xdWV1ZSA9IFtdO1xuICAgICAgICB0aGlzLmRlbGF5ZWRSdW5uZXIgPSBuZXcgRGVsYXllZFJ1bm5lcih0aGlzLmRyYWluLmJpbmQodGhpcykpO1xuICAgIH1cbiAgICByZXF1ZXN0KHRhc2ssIGRlbGF5KSB7XG4gICAgICAgIHRoaXMucXVldWUucHVzaCh0YXNrKTtcbiAgICAgICAgdGhpcy5kZWxheWVkUnVubmVyLnJlcXVlc3QoZGVsYXkpO1xuICAgIH1cbiAgICBwYXVzZShzY29wZSkge1xuICAgICAgICB0aGlzLmRlbGF5ZWRSdW5uZXIucGF1c2Uoc2NvcGUpO1xuICAgIH1cbiAgICByZXN1bWUoc2NvcGUsIGZvcmNlKSB7XG4gICAgICAgIHRoaXMuZGVsYXllZFJ1bm5lci5yZXN1bWUoc2NvcGUsIGZvcmNlKTtcbiAgICB9XG4gICAgZHJhaW4oKSB7XG4gICAgICAgIGxldCB7IHF1ZXVlIH0gPSB0aGlzO1xuICAgICAgICB3aGlsZSAocXVldWUubGVuZ3RoKSB7XG4gICAgICAgICAgICBsZXQgY29tcGxldGVkVGFza3MgPSBbXTtcbiAgICAgICAgICAgIGxldCB0YXNrO1xuICAgICAgICAgICAgd2hpbGUgKCh0YXNrID0gcXVldWUuc2hpZnQoKSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJ1blRhc2sodGFzayk7XG4gICAgICAgICAgICAgICAgY29tcGxldGVkVGFza3MucHVzaCh0YXNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZHJhaW5lZChjb21wbGV0ZWRUYXNrcyk7XG4gICAgICAgIH0gLy8ga2VlcCBnb2luZywgaW4gY2FzZSBuZXcgdGFza3Mgd2VyZSBhZGRlZCBpbiB0aGUgZHJhaW5lZCBoYW5kbGVyXG4gICAgfVxuICAgIHJ1blRhc2sodGFzaykge1xuICAgICAgICBpZiAodGhpcy5ydW5UYXNrT3B0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLnJ1blRhc2tPcHRpb24odGFzayk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZHJhaW5lZChjb21wbGV0ZWRUYXNrcykge1xuICAgICAgICBpZiAodGhpcy5kcmFpbmVkT3B0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLmRyYWluZWRPcHRpb24oY29tcGxldGVkVGFza3MpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG4vLyBDb21wdXRlcyB3aGF0IHRoZSB0aXRsZSBhdCB0aGUgdG9wIG9mIHRoZSBjYWxlbmRhckFwaSBzaG91bGQgYmUgZm9yIHRoaXMgdmlld1xuZnVuY3Rpb24gYnVpbGRUaXRsZShkYXRlUHJvZmlsZSwgdmlld09wdGlvbnMsIGRhdGVFbnYpIHtcbiAgICBsZXQgcmFuZ2U7XG4gICAgLy8gZm9yIHZpZXdzIHRoYXQgc3BhbiBhIGxhcmdlIHVuaXQgb2YgdGltZSwgc2hvdyB0aGUgcHJvcGVyIGludGVydmFsLCBpZ25vcmluZyBzdHJheSBkYXlzIGJlZm9yZSBhbmQgYWZ0ZXJcbiAgICBpZiAoL14oeWVhcnxtb250aCkkLy50ZXN0KGRhdGVQcm9maWxlLmN1cnJlbnRSYW5nZVVuaXQpKSB7XG4gICAgICAgIHJhbmdlID0gZGF0ZVByb2ZpbGUuY3VycmVudFJhbmdlO1xuICAgIH1cbiAgICBlbHNlIHsgLy8gZm9yIGRheSB1bml0cyBvciBzbWFsbGVyLCB1c2UgdGhlIGFjdHVhbCBkYXkgcmFuZ2VcbiAgICAgICAgcmFuZ2UgPSBkYXRlUHJvZmlsZS5hY3RpdmVSYW5nZTtcbiAgICB9XG4gICAgcmV0dXJuIGRhdGVFbnYuZm9ybWF0UmFuZ2UocmFuZ2Uuc3RhcnQsIHJhbmdlLmVuZCwgY3JlYXRlRm9ybWF0dGVyKHZpZXdPcHRpb25zLnRpdGxlRm9ybWF0IHx8IGJ1aWxkVGl0bGVGb3JtYXQoZGF0ZVByb2ZpbGUpKSwge1xuICAgICAgICBpc0VuZEV4Y2x1c2l2ZTogZGF0ZVByb2ZpbGUuaXNSYW5nZUFsbERheSxcbiAgICAgICAgZGVmYXVsdFNlcGFyYXRvcjogdmlld09wdGlvbnMudGl0bGVSYW5nZVNlcGFyYXRvcixcbiAgICB9KTtcbn1cbi8vIEdlbmVyYXRlcyB0aGUgZm9ybWF0IHN0cmluZyB0aGF0IHNob3VsZCBiZSB1c2VkIHRvIGdlbmVyYXRlIHRoZSB0aXRsZSBmb3IgdGhlIGN1cnJlbnQgZGF0ZSByYW5nZS5cbi8vIEF0dGVtcHRzIHRvIGNvbXB1dGUgdGhlIG1vc3QgYXBwcm9wcmlhdGUgZm9ybWF0IGlmIG5vdCBleHBsaWNpdGx5IHNwZWNpZmllZCB3aXRoIGB0aXRsZUZvcm1hdGAuXG5mdW5jdGlvbiBidWlsZFRpdGxlRm9ybWF0KGRhdGVQcm9maWxlKSB7XG4gICAgbGV0IHsgY3VycmVudFJhbmdlVW5pdCB9ID0gZGF0ZVByb2ZpbGU7XG4gICAgaWYgKGN1cnJlbnRSYW5nZVVuaXQgPT09ICd5ZWFyJykge1xuICAgICAgICByZXR1cm4geyB5ZWFyOiAnbnVtZXJpYycgfTtcbiAgICB9XG4gICAgaWYgKGN1cnJlbnRSYW5nZVVuaXQgPT09ICdtb250aCcpIHtcbiAgICAgICAgcmV0dXJuIHsgeWVhcjogJ251bWVyaWMnLCBtb250aDogJ2xvbmcnIH07IC8vIGxpa2UgXCJTZXB0ZW1iZXIgMjAxNFwiXG4gICAgfVxuICAgIGxldCBkYXlzID0gZGlmZldob2xlRGF5cyhkYXRlUHJvZmlsZS5jdXJyZW50UmFuZ2Uuc3RhcnQsIGRhdGVQcm9maWxlLmN1cnJlbnRSYW5nZS5lbmQpO1xuICAgIGlmIChkYXlzICE9PSBudWxsICYmIGRheXMgPiAxKSB7XG4gICAgICAgIC8vIG11bHRpLWRheSByYW5nZS4gc2hvcnRlciwgbGlrZSBcIlNlcCA5IC0gMTAgMjAxNFwiXG4gICAgICAgIHJldHVybiB7IHllYXI6ICdudW1lcmljJywgbW9udGg6ICdzaG9ydCcsIGRheTogJ251bWVyaWMnIH07XG4gICAgfVxuICAgIC8vIG9uZSBkYXkuIGxvbmdlciwgbGlrZSBcIlNlcHRlbWJlciA5IDIwMTRcIlxuICAgIHJldHVybiB7IHllYXI6ICdudW1lcmljJywgbW9udGg6ICdsb25nJywgZGF5OiAnbnVtZXJpYycgfTtcbn1cblxuLypcblRPRE86IHRlc3Qgc3dpdGNoaW5nIHRpbWV6b25lcyB3aGVuIE5PIHRpbWV6b25lIHBsdWdpblxuKi9cbmNsYXNzIENhbGVuZGFyTm93TWFuYWdlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMucmVzZXRMaXN0ZW5lcnMgPSBuZXcgU2V0KCk7XG4gICAgfVxuICAgIGhhbmRsZUlucHV0KGRhdGVFbnYsIC8vIHdpbGwgY2hhbmdlIGlmIHRpbWV6b25lIHNldHVwIGNoYW5nZWRcbiAgICBub3dJbnB1dCkge1xuICAgICAgICBjb25zdCBvbGREYXRlRW52ID0gdGhpcy5kYXRlRW52O1xuICAgICAgICBpZiAoZGF0ZUVudiAhPT0gb2xkRGF0ZUVudikge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBub3dJbnB1dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgIHRoaXMubm93Rm4gPSBub3dJbnB1dDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKCFvbGREYXRlRW52KSB7IC8vIGZpcnN0IHRpbWU/XG4gICAgICAgICAgICAgICAgdGhpcy5ub3dBbmNob3JEYXRlID0gZGF0ZUVudi50b0RhdGUobm93SW5wdXRcbiAgICAgICAgICAgICAgICAgICAgPyBkYXRlRW52LmNyZWF0ZU1hcmtlcihub3dJbnB1dClcbiAgICAgICAgICAgICAgICAgICAgOiBkYXRlRW52LmNyZWF0ZU5vd01hcmtlcigpKTtcbiAgICAgICAgICAgICAgICB0aGlzLm5vd0FuY2hvclF1ZXJpZWQgPSBEYXRlLm5vdygpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5kYXRlRW52ID0gZGF0ZUVudjtcbiAgICAgICAgICAgIC8vIG5vdCBmaXJzdCB0aW1lPyBmaXJlIHJlc2V0IGhhbmRsZXJzXG4gICAgICAgICAgICBpZiAob2xkRGF0ZUVudikge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgcmVzZXRMaXN0ZW5lciBvZiB0aGlzLnJlc2V0TGlzdGVuZXJzLnZhbHVlcygpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc2V0TGlzdGVuZXIoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0RGF0ZU1hcmtlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubm93QW5jaG9yRGF0ZVxuICAgICAgICAgICAgPyB0aGlzLmRhdGVFbnYudGltZXN0YW1wVG9NYXJrZXIodGhpcy5ub3dBbmNob3JEYXRlLnZhbHVlT2YoKSArXG4gICAgICAgICAgICAgICAgKERhdGUubm93KCkgLSB0aGlzLm5vd0FuY2hvclF1ZXJpZWQpKVxuICAgICAgICAgICAgOiB0aGlzLmRhdGVFbnYuY3JlYXRlTWFya2VyKHRoaXMubm93Rm4oKSk7XG4gICAgfVxuICAgIGFkZFJlc2V0TGlzdGVuZXIoaGFuZGxlcikge1xuICAgICAgICB0aGlzLnJlc2V0TGlzdGVuZXJzLmFkZChoYW5kbGVyKTtcbiAgICB9XG4gICAgcmVtb3ZlUmVzZXRMaXN0ZW5lcihoYW5kbGVyKSB7XG4gICAgICAgIHRoaXMucmVzZXRMaXN0ZW5lcnMuZGVsZXRlKGhhbmRsZXIpO1xuICAgIH1cbn1cblxuLy8gaW4gZnV0dXJlIHJlZmFjdG9yLCBkbyB0aGUgcmVkdXgtc3R5bGUgZnVuY3Rpb24oc3RhdGU9aW5pdGlhbCkgZm9yIGluaXRpYWwtc3RhdGVcbi8vIGFsc28sIHdoYXRldmVyIGlzIGhhcHBlbmluZyBpbiBjb25zdHJ1Y3RvciwgaGF2ZSBpdCBoYXBwZW4gaW4gYWN0aW9uIHF1ZXVlIHRvb1xuY2xhc3MgQ2FsZW5kYXJEYXRhTWFuYWdlciB7XG4gICAgY29uc3RydWN0b3IocHJvcHMpIHtcbiAgICAgICAgdGhpcy5jb21wdXRlQ3VycmVudFZpZXdEYXRhID0gbWVtb2l6ZSh0aGlzLl9jb21wdXRlQ3VycmVudFZpZXdEYXRhKTtcbiAgICAgICAgdGhpcy5vcmdhbml6ZVJhd0xvY2FsZXMgPSBtZW1vaXplKG9yZ2FuaXplUmF3TG9jYWxlcyk7XG4gICAgICAgIHRoaXMuYnVpbGRMb2NhbGUgPSBtZW1vaXplKGJ1aWxkTG9jYWxlKTtcbiAgICAgICAgdGhpcy5idWlsZFBsdWdpbkhvb2tzID0gYnVpbGRCdWlsZFBsdWdpbkhvb2tzKCk7XG4gICAgICAgIHRoaXMuYnVpbGREYXRlRW52ID0gbWVtb2l6ZShidWlsZERhdGVFbnYkMSk7XG4gICAgICAgIHRoaXMuYnVpbGRUaGVtZSA9IG1lbW9pemUoYnVpbGRUaGVtZSk7XG4gICAgICAgIHRoaXMucGFyc2VUb29sYmFycyA9IG1lbW9pemUocGFyc2VUb29sYmFycyk7XG4gICAgICAgIHRoaXMuYnVpbGRWaWV3U3BlY3MgPSBtZW1vaXplKGJ1aWxkVmlld1NwZWNzKTtcbiAgICAgICAgdGhpcy5idWlsZERhdGVQcm9maWxlR2VuZXJhdG9yID0gbWVtb2l6ZU9iakFyZyhidWlsZERhdGVQcm9maWxlR2VuZXJhdG9yKTtcbiAgICAgICAgdGhpcy5idWlsZFZpZXdBcGkgPSBtZW1vaXplKGJ1aWxkVmlld0FwaSk7XG4gICAgICAgIHRoaXMuYnVpbGRWaWV3VWlQcm9wcyA9IG1lbW9pemVPYmpBcmcoYnVpbGRWaWV3VWlQcm9wcyk7XG4gICAgICAgIHRoaXMuYnVpbGRFdmVudFVpQnlTb3VyY2UgPSBtZW1vaXplKGJ1aWxkRXZlbnRVaUJ5U291cmNlLCBpc1Byb3BzRXF1YWwpO1xuICAgICAgICB0aGlzLmJ1aWxkRXZlbnRVaUJhc2VzID0gbWVtb2l6ZShidWlsZEV2ZW50VWlCYXNlcyk7XG4gICAgICAgIHRoaXMucGFyc2VDb250ZXh0QnVzaW5lc3NIb3VycyA9IG1lbW9pemVPYmpBcmcocGFyc2VDb250ZXh0QnVzaW5lc3NIb3Vycyk7XG4gICAgICAgIHRoaXMuYnVpbGRUaXRsZSA9IG1lbW9pemUoYnVpbGRUaXRsZSk7XG4gICAgICAgIHRoaXMubm93TWFuYWdlciA9IG5ldyBDYWxlbmRhck5vd01hbmFnZXIoKTtcbiAgICAgICAgdGhpcy5lbWl0dGVyID0gbmV3IEVtaXR0ZXIoKTtcbiAgICAgICAgdGhpcy5hY3Rpb25SdW5uZXIgPSBuZXcgVGFza1J1bm5lcih0aGlzLl9oYW5kbGVBY3Rpb24uYmluZCh0aGlzKSwgdGhpcy51cGRhdGVEYXRhLmJpbmQodGhpcykpO1xuICAgICAgICB0aGlzLmN1cnJlbnRDYWxlbmRhck9wdGlvbnNJbnB1dCA9IHt9O1xuICAgICAgICB0aGlzLmN1cnJlbnRDYWxlbmRhck9wdGlvbnNSZWZpbmVkID0ge307XG4gICAgICAgIHRoaXMuY3VycmVudFZpZXdPcHRpb25zSW5wdXQgPSB7fTtcbiAgICAgICAgdGhpcy5jdXJyZW50Vmlld09wdGlvbnNSZWZpbmVkID0ge307XG4gICAgICAgIHRoaXMuY3VycmVudENhbGVuZGFyT3B0aW9uc1JlZmluZXJzID0ge307XG4gICAgICAgIHRoaXMub3B0aW9uc0ZvclJlZmluaW5nID0gW107XG4gICAgICAgIHRoaXMub3B0aW9uc0ZvckhhbmRsaW5nID0gW107XG4gICAgICAgIHRoaXMuZ2V0Q3VycmVudERhdGEgPSAoKSA9PiB0aGlzLmRhdGE7XG4gICAgICAgIHRoaXMuZGlzcGF0Y2ggPSAoYWN0aW9uKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmFjdGlvblJ1bm5lci5yZXF1ZXN0KGFjdGlvbik7IC8vIHByb3RlY3RzIGFnYWluc3QgcmVjdXJzaXZlIGNhbGxzIHRvIF9oYW5kbGVBY3Rpb25cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5wcm9wcyA9IHByb3BzO1xuICAgICAgICB0aGlzLmFjdGlvblJ1bm5lci5wYXVzZSgpO1xuICAgICAgICB0aGlzLm5vd01hbmFnZXIgPSBuZXcgQ2FsZW5kYXJOb3dNYW5hZ2VyKCk7XG4gICAgICAgIGxldCBkeW5hbWljT3B0aW9uT3ZlcnJpZGVzID0ge307XG4gICAgICAgIGxldCBvcHRpb25zRGF0YSA9IHRoaXMuY29tcHV0ZU9wdGlvbnNEYXRhKHByb3BzLm9wdGlvbk92ZXJyaWRlcywgZHluYW1pY09wdGlvbk92ZXJyaWRlcywgcHJvcHMuY2FsZW5kYXJBcGkpO1xuICAgICAgICBsZXQgY3VycmVudFZpZXdUeXBlID0gb3B0aW9uc0RhdGEuY2FsZW5kYXJPcHRpb25zLmluaXRpYWxWaWV3IHx8IG9wdGlvbnNEYXRhLnBsdWdpbkhvb2tzLmluaXRpYWxWaWV3O1xuICAgICAgICBsZXQgY3VycmVudFZpZXdEYXRhID0gdGhpcy5jb21wdXRlQ3VycmVudFZpZXdEYXRhKGN1cnJlbnRWaWV3VHlwZSwgb3B0aW9uc0RhdGEsIHByb3BzLm9wdGlvbk92ZXJyaWRlcywgZHluYW1pY09wdGlvbk92ZXJyaWRlcyk7XG4gICAgICAgIC8vIHdpcmUgdGhpbmdzIHVwXG4gICAgICAgIC8vIFRPRE86IG5vdCBEUllcbiAgICAgICAgcHJvcHMuY2FsZW5kYXJBcGkuY3VycmVudERhdGFNYW5hZ2VyID0gdGhpcztcbiAgICAgICAgdGhpcy5lbWl0dGVyLnNldFRoaXNDb250ZXh0KHByb3BzLmNhbGVuZGFyQXBpKTtcbiAgICAgICAgdGhpcy5lbWl0dGVyLnNldE9wdGlvbnMoY3VycmVudFZpZXdEYXRhLm9wdGlvbnMpO1xuICAgICAgICBsZXQgY2FsZW5kYXJDb250ZXh0ID0ge1xuICAgICAgICAgICAgbm93TWFuYWdlcjogdGhpcy5ub3dNYW5hZ2VyLFxuICAgICAgICAgICAgZGF0ZUVudjogb3B0aW9uc0RhdGEuZGF0ZUVudixcbiAgICAgICAgICAgIG9wdGlvbnM6IG9wdGlvbnNEYXRhLmNhbGVuZGFyT3B0aW9ucyxcbiAgICAgICAgICAgIHBsdWdpbkhvb2tzOiBvcHRpb25zRGF0YS5wbHVnaW5Ib29rcyxcbiAgICAgICAgICAgIGNhbGVuZGFyQXBpOiBwcm9wcy5jYWxlbmRhckFwaSxcbiAgICAgICAgICAgIGRpc3BhdGNoOiB0aGlzLmRpc3BhdGNoLFxuICAgICAgICAgICAgZW1pdHRlcjogdGhpcy5lbWl0dGVyLFxuICAgICAgICAgICAgZ2V0Q3VycmVudERhdGE6IHRoaXMuZ2V0Q3VycmVudERhdGEsXG4gICAgICAgIH07XG4gICAgICAgIGxldCBjdXJyZW50RGF0ZSA9IGdldEluaXRpYWxEYXRlKG9wdGlvbnNEYXRhLmNhbGVuZGFyT3B0aW9ucywgb3B0aW9uc0RhdGEuZGF0ZUVudiwgdGhpcy5ub3dNYW5hZ2VyKTtcbiAgICAgICAgbGV0IGRhdGVQcm9maWxlID0gY3VycmVudFZpZXdEYXRhLmRhdGVQcm9maWxlR2VuZXJhdG9yLmJ1aWxkKGN1cnJlbnREYXRlKTtcbiAgICAgICAgaWYgKCFyYW5nZUNvbnRhaW5zTWFya2VyKGRhdGVQcm9maWxlLmFjdGl2ZVJhbmdlLCBjdXJyZW50RGF0ZSkpIHtcbiAgICAgICAgICAgIGN1cnJlbnREYXRlID0gZGF0ZVByb2ZpbGUuY3VycmVudFJhbmdlLnN0YXJ0O1xuICAgICAgICB9XG4gICAgICAgIC8vIG5lZWRzIHRvIGJlIGFmdGVyIHNldFRoaXNDb250ZXh0XG4gICAgICAgIGZvciAobGV0IGNhbGxiYWNrIG9mIG9wdGlvbnNEYXRhLnBsdWdpbkhvb2tzLmNvbnRleHRJbml0KSB7XG4gICAgICAgICAgICBjYWxsYmFjayhjYWxlbmRhckNvbnRleHQpO1xuICAgICAgICB9XG4gICAgICAgIC8vIE5PVCBEUllcbiAgICAgICAgbGV0IGV2ZW50U291cmNlcyA9IGluaXRFdmVudFNvdXJjZXMob3B0aW9uc0RhdGEuY2FsZW5kYXJPcHRpb25zLCBkYXRlUHJvZmlsZSwgY2FsZW5kYXJDb250ZXh0KTtcbiAgICAgICAgbGV0IGluaXRpYWxTdGF0ZSA9IHtcbiAgICAgICAgICAgIGR5bmFtaWNPcHRpb25PdmVycmlkZXMsXG4gICAgICAgICAgICBjdXJyZW50Vmlld1R5cGUsXG4gICAgICAgICAgICBjdXJyZW50RGF0ZSxcbiAgICAgICAgICAgIGRhdGVQcm9maWxlLFxuICAgICAgICAgICAgYnVzaW5lc3NIb3VyczogdGhpcy5wYXJzZUNvbnRleHRCdXNpbmVzc0hvdXJzKGNhbGVuZGFyQ29udGV4dCksXG4gICAgICAgICAgICBldmVudFNvdXJjZXMsXG4gICAgICAgICAgICBldmVudFVpQmFzZXM6IHt9LFxuICAgICAgICAgICAgZXZlbnRTdG9yZTogY3JlYXRlRW1wdHlFdmVudFN0b3JlKCksXG4gICAgICAgICAgICByZW5kZXJhYmxlRXZlbnRTdG9yZTogY3JlYXRlRW1wdHlFdmVudFN0b3JlKCksXG4gICAgICAgICAgICBkYXRlU2VsZWN0aW9uOiBudWxsLFxuICAgICAgICAgICAgZXZlbnRTZWxlY3Rpb246ICcnLFxuICAgICAgICAgICAgZXZlbnREcmFnOiBudWxsLFxuICAgICAgICAgICAgZXZlbnRSZXNpemU6IG51bGwsXG4gICAgICAgICAgICBzZWxlY3Rpb25Db25maWc6IHRoaXMuYnVpbGRWaWV3VWlQcm9wcyhjYWxlbmRhckNvbnRleHQpLnNlbGVjdGlvbkNvbmZpZyxcbiAgICAgICAgfTtcbiAgICAgICAgbGV0IGNvbnRleHRBbmRTdGF0ZSA9IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgY2FsZW5kYXJDb250ZXh0KSwgaW5pdGlhbFN0YXRlKTtcbiAgICAgICAgZm9yIChsZXQgcmVkdWNlciBvZiBvcHRpb25zRGF0YS5wbHVnaW5Ib29rcy5yZWR1Y2Vycykge1xuICAgICAgICAgICAgT2JqZWN0LmFzc2lnbihpbml0aWFsU3RhdGUsIHJlZHVjZXIobnVsbCwgbnVsbCwgY29udGV4dEFuZFN0YXRlKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvbXB1dGVJc0xvYWRpbmcoaW5pdGlhbFN0YXRlLCBjYWxlbmRhckNvbnRleHQpKSB7XG4gICAgICAgICAgICB0aGlzLmVtaXR0ZXIudHJpZ2dlcignbG9hZGluZycsIHRydWUpOyAvLyBOT1QgRFJZXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zdGF0ZSA9IGluaXRpYWxTdGF0ZTtcbiAgICAgICAgdGhpcy51cGRhdGVEYXRhKCk7XG4gICAgICAgIHRoaXMuYWN0aW9uUnVubmVyLnJlc3VtZSgpO1xuICAgIH1cbiAgICByZXNldE9wdGlvbnMob3B0aW9uT3ZlcnJpZGVzLCBjaGFuZ2VkT3B0aW9uTmFtZXMpIHtcbiAgICAgICAgbGV0IHsgcHJvcHMgfSA9IHRoaXM7XG4gICAgICAgIGlmIChjaGFuZ2VkT3B0aW9uTmFtZXMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcHJvcHMub3B0aW9uT3ZlcnJpZGVzID0gb3B0aW9uT3ZlcnJpZGVzO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcHJvcHMub3B0aW9uT3ZlcnJpZGVzID0gT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCAocHJvcHMub3B0aW9uT3ZlcnJpZGVzIHx8IHt9KSksIG9wdGlvbk92ZXJyaWRlcyk7XG4gICAgICAgICAgICB0aGlzLm9wdGlvbnNGb3JSZWZpbmluZy5wdXNoKC4uLmNoYW5nZWRPcHRpb25OYW1lcyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNoYW5nZWRPcHRpb25OYW1lcyA9PT0gdW5kZWZpbmVkIHx8IGNoYW5nZWRPcHRpb25OYW1lcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRoaXMuYWN0aW9uUnVubmVyLnJlcXVlc3Qoe1xuICAgICAgICAgICAgICAgIHR5cGU6ICdOT1RISU5HJyxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIF9oYW5kbGVBY3Rpb24oYWN0aW9uKSB7XG4gICAgICAgIGxldCB7IHByb3BzLCBzdGF0ZSwgZW1pdHRlciB9ID0gdGhpcztcbiAgICAgICAgbGV0IGR5bmFtaWNPcHRpb25PdmVycmlkZXMgPSByZWR1Y2VEeW5hbWljT3B0aW9uT3ZlcnJpZGVzKHN0YXRlLmR5bmFtaWNPcHRpb25PdmVycmlkZXMsIGFjdGlvbik7XG4gICAgICAgIGxldCBvcHRpb25zRGF0YSA9IHRoaXMuY29tcHV0ZU9wdGlvbnNEYXRhKHByb3BzLm9wdGlvbk92ZXJyaWRlcywgZHluYW1pY09wdGlvbk92ZXJyaWRlcywgcHJvcHMuY2FsZW5kYXJBcGkpO1xuICAgICAgICBsZXQgY3VycmVudFZpZXdUeXBlID0gcmVkdWNlVmlld1R5cGUoc3RhdGUuY3VycmVudFZpZXdUeXBlLCBhY3Rpb24pO1xuICAgICAgICBsZXQgY3VycmVudFZpZXdEYXRhID0gdGhpcy5jb21wdXRlQ3VycmVudFZpZXdEYXRhKGN1cnJlbnRWaWV3VHlwZSwgb3B0aW9uc0RhdGEsIHByb3BzLm9wdGlvbk92ZXJyaWRlcywgZHluYW1pY09wdGlvbk92ZXJyaWRlcyk7XG4gICAgICAgIC8vIHdpcmUgdGhpbmdzIHVwXG4gICAgICAgIC8vIFRPRE86IG5vdCBEUllcbiAgICAgICAgcHJvcHMuY2FsZW5kYXJBcGkuY3VycmVudERhdGFNYW5hZ2VyID0gdGhpcztcbiAgICAgICAgZW1pdHRlci5zZXRUaGlzQ29udGV4dChwcm9wcy5jYWxlbmRhckFwaSk7XG4gICAgICAgIGVtaXR0ZXIuc2V0T3B0aW9ucyhjdXJyZW50Vmlld0RhdGEub3B0aW9ucyk7XG4gICAgICAgIGxldCBjYWxlbmRhckNvbnRleHQgPSB7XG4gICAgICAgICAgICBub3dNYW5hZ2VyOiB0aGlzLm5vd01hbmFnZXIsXG4gICAgICAgICAgICBkYXRlRW52OiBvcHRpb25zRGF0YS5kYXRlRW52LFxuICAgICAgICAgICAgb3B0aW9uczogb3B0aW9uc0RhdGEuY2FsZW5kYXJPcHRpb25zLFxuICAgICAgICAgICAgcGx1Z2luSG9va3M6IG9wdGlvbnNEYXRhLnBsdWdpbkhvb2tzLFxuICAgICAgICAgICAgY2FsZW5kYXJBcGk6IHByb3BzLmNhbGVuZGFyQXBpLFxuICAgICAgICAgICAgZGlzcGF0Y2g6IHRoaXMuZGlzcGF0Y2gsXG4gICAgICAgICAgICBlbWl0dGVyLFxuICAgICAgICAgICAgZ2V0Q3VycmVudERhdGE6IHRoaXMuZ2V0Q3VycmVudERhdGEsXG4gICAgICAgIH07XG4gICAgICAgIGxldCB7IGN1cnJlbnREYXRlLCBkYXRlUHJvZmlsZSB9ID0gc3RhdGU7XG4gICAgICAgIGlmICh0aGlzLmRhdGEgJiYgdGhpcy5kYXRhLmRhdGVQcm9maWxlR2VuZXJhdG9yICE9PSBjdXJyZW50Vmlld0RhdGEuZGF0ZVByb2ZpbGVHZW5lcmF0b3IpIHsgLy8gaGFja1xuICAgICAgICAgICAgZGF0ZVByb2ZpbGUgPSBjdXJyZW50Vmlld0RhdGEuZGF0ZVByb2ZpbGVHZW5lcmF0b3IuYnVpbGQoY3VycmVudERhdGUpO1xuICAgICAgICB9XG4gICAgICAgIGN1cnJlbnREYXRlID0gcmVkdWNlQ3VycmVudERhdGUoY3VycmVudERhdGUsIGFjdGlvbik7XG4gICAgICAgIGRhdGVQcm9maWxlID0gcmVkdWNlRGF0ZVByb2ZpbGUoZGF0ZVByb2ZpbGUsIGFjdGlvbiwgY3VycmVudERhdGUsIGN1cnJlbnRWaWV3RGF0YS5kYXRlUHJvZmlsZUdlbmVyYXRvcik7XG4gICAgICAgIGlmIChhY3Rpb24udHlwZSA9PT0gJ1BSRVYnIHx8IC8vIFRPRE86IG1vdmUgdGhpcyBsb2dpYyBpbnRvIERhdGVQcm9maWxlR2VuZXJhdG9yXG4gICAgICAgICAgICBhY3Rpb24udHlwZSA9PT0gJ05FWFQnIHx8IC8vIFwiXG4gICAgICAgICAgICAhcmFuZ2VDb250YWluc01hcmtlcihkYXRlUHJvZmlsZS5jdXJyZW50UmFuZ2UsIGN1cnJlbnREYXRlKSkge1xuICAgICAgICAgICAgY3VycmVudERhdGUgPSBkYXRlUHJvZmlsZS5jdXJyZW50UmFuZ2Uuc3RhcnQ7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGV2ZW50U291cmNlcyA9IHJlZHVjZUV2ZW50U291cmNlcyhzdGF0ZS5ldmVudFNvdXJjZXMsIGFjdGlvbiwgZGF0ZVByb2ZpbGUsIGNhbGVuZGFyQ29udGV4dCk7XG4gICAgICAgIGxldCBldmVudFN0b3JlID0gcmVkdWNlRXZlbnRTdG9yZShzdGF0ZS5ldmVudFN0b3JlLCBhY3Rpb24sIGV2ZW50U291cmNlcywgZGF0ZVByb2ZpbGUsIGNhbGVuZGFyQ29udGV4dCk7XG4gICAgICAgIGxldCBpc0V2ZW50c0xvYWRpbmcgPSBjb21wdXRlRXZlbnRTb3VyY2VzTG9hZGluZyhldmVudFNvdXJjZXMpOyAvLyBCQUQuIGFsc28gY2FsbGVkIGluIHRoaXMgZnVuYyBpbiBjb21wdXRlSXNMb2FkaW5nXG4gICAgICAgIGxldCByZW5kZXJhYmxlRXZlbnRTdG9yZSA9IChpc0V2ZW50c0xvYWRpbmcgJiYgIWN1cnJlbnRWaWV3RGF0YS5vcHRpb25zLnByb2dyZXNzaXZlRXZlbnRSZW5kZXJpbmcpID9cbiAgICAgICAgICAgIChzdGF0ZS5yZW5kZXJhYmxlRXZlbnRTdG9yZSB8fCBldmVudFN0b3JlKSA6IC8vIHRyeSBmcm9tIHByZXZpb3VzIHN0YXRlXG4gICAgICAgICAgICBldmVudFN0b3JlO1xuICAgICAgICBsZXQgeyBldmVudFVpU2luZ2xlQmFzZSwgc2VsZWN0aW9uQ29uZmlnIH0gPSB0aGlzLmJ1aWxkVmlld1VpUHJvcHMoY2FsZW5kYXJDb250ZXh0KTsgLy8gd2lsbCBtZW1vaXplIG9ialxuICAgICAgICBsZXQgZXZlbnRVaUJ5U291cmNlID0gdGhpcy5idWlsZEV2ZW50VWlCeVNvdXJjZShldmVudFNvdXJjZXMpO1xuICAgICAgICBsZXQgZXZlbnRVaUJhc2VzID0gdGhpcy5idWlsZEV2ZW50VWlCYXNlcyhyZW5kZXJhYmxlRXZlbnRTdG9yZS5kZWZzLCBldmVudFVpU2luZ2xlQmFzZSwgZXZlbnRVaUJ5U291cmNlKTtcbiAgICAgICAgbGV0IG5ld1N0YXRlID0ge1xuICAgICAgICAgICAgZHluYW1pY09wdGlvbk92ZXJyaWRlcyxcbiAgICAgICAgICAgIGN1cnJlbnRWaWV3VHlwZSxcbiAgICAgICAgICAgIGN1cnJlbnREYXRlLFxuICAgICAgICAgICAgZGF0ZVByb2ZpbGUsXG4gICAgICAgICAgICBldmVudFNvdXJjZXMsXG4gICAgICAgICAgICBldmVudFN0b3JlLFxuICAgICAgICAgICAgcmVuZGVyYWJsZUV2ZW50U3RvcmUsXG4gICAgICAgICAgICBzZWxlY3Rpb25Db25maWcsXG4gICAgICAgICAgICBldmVudFVpQmFzZXMsXG4gICAgICAgICAgICBidXNpbmVzc0hvdXJzOiB0aGlzLnBhcnNlQ29udGV4dEJ1c2luZXNzSG91cnMoY2FsZW5kYXJDb250ZXh0KSxcbiAgICAgICAgICAgIGRhdGVTZWxlY3Rpb246IHJlZHVjZURhdGVTZWxlY3Rpb24oc3RhdGUuZGF0ZVNlbGVjdGlvbiwgYWN0aW9uKSxcbiAgICAgICAgICAgIGV2ZW50U2VsZWN0aW9uOiByZWR1Y2VTZWxlY3RlZEV2ZW50KHN0YXRlLmV2ZW50U2VsZWN0aW9uLCBhY3Rpb24pLFxuICAgICAgICAgICAgZXZlbnREcmFnOiByZWR1Y2VFdmVudERyYWcoc3RhdGUuZXZlbnREcmFnLCBhY3Rpb24pLFxuICAgICAgICAgICAgZXZlbnRSZXNpemU6IHJlZHVjZUV2ZW50UmVzaXplKHN0YXRlLmV2ZW50UmVzaXplLCBhY3Rpb24pLFxuICAgICAgICB9O1xuICAgICAgICBsZXQgY29udGV4dEFuZFN0YXRlID0gT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBjYWxlbmRhckNvbnRleHQpLCBuZXdTdGF0ZSk7XG4gICAgICAgIGZvciAobGV0IHJlZHVjZXIgb2Ygb3B0aW9uc0RhdGEucGx1Z2luSG9va3MucmVkdWNlcnMpIHtcbiAgICAgICAgICAgIE9iamVjdC5hc3NpZ24obmV3U3RhdGUsIHJlZHVjZXIoc3RhdGUsIGFjdGlvbiwgY29udGV4dEFuZFN0YXRlKSk7IC8vIGdpdmUgdGhlIE9MRCBzdGF0ZSwgZm9yIG9sZCB2YWx1ZVxuICAgICAgICB9XG4gICAgICAgIGxldCB3YXNMb2FkaW5nID0gY29tcHV0ZUlzTG9hZGluZyhzdGF0ZSwgY2FsZW5kYXJDb250ZXh0KTtcbiAgICAgICAgbGV0IGlzTG9hZGluZyA9IGNvbXB1dGVJc0xvYWRpbmcobmV3U3RhdGUsIGNhbGVuZGFyQ29udGV4dCk7XG4gICAgICAgIC8vIFRPRE86IHVzZSBwcm9wU2V0SGFuZGxlcnMgaW4gcGx1Z2luIHN5c3RlbVxuICAgICAgICBpZiAoIXdhc0xvYWRpbmcgJiYgaXNMb2FkaW5nKSB7XG4gICAgICAgICAgICBlbWl0dGVyLnRyaWdnZXIoJ2xvYWRpbmcnLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh3YXNMb2FkaW5nICYmICFpc0xvYWRpbmcpIHtcbiAgICAgICAgICAgIGVtaXR0ZXIudHJpZ2dlcignbG9hZGluZycsIGZhbHNlKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnN0YXRlID0gbmV3U3RhdGU7XG4gICAgICAgIGlmIChwcm9wcy5vbkFjdGlvbikge1xuICAgICAgICAgICAgcHJvcHMub25BY3Rpb24oYWN0aW9uKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICB1cGRhdGVEYXRhKCkge1xuICAgICAgICBsZXQgeyBwcm9wcywgc3RhdGUgfSA9IHRoaXM7XG4gICAgICAgIGxldCBvbGREYXRhID0gdGhpcy5kYXRhO1xuICAgICAgICBsZXQgb3B0aW9uc0RhdGEgPSB0aGlzLmNvbXB1dGVPcHRpb25zRGF0YShwcm9wcy5vcHRpb25PdmVycmlkZXMsIHN0YXRlLmR5bmFtaWNPcHRpb25PdmVycmlkZXMsIHByb3BzLmNhbGVuZGFyQXBpKTtcbiAgICAgICAgbGV0IGN1cnJlbnRWaWV3RGF0YSA9IHRoaXMuY29tcHV0ZUN1cnJlbnRWaWV3RGF0YShzdGF0ZS5jdXJyZW50Vmlld1R5cGUsIG9wdGlvbnNEYXRhLCBwcm9wcy5vcHRpb25PdmVycmlkZXMsIHN0YXRlLmR5bmFtaWNPcHRpb25PdmVycmlkZXMpO1xuICAgICAgICBsZXQgZGF0YSA9IHRoaXMuZGF0YSA9IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHsgbm93TWFuYWdlcjogdGhpcy5ub3dNYW5hZ2VyLCB2aWV3VGl0bGU6IHRoaXMuYnVpbGRUaXRsZShzdGF0ZS5kYXRlUHJvZmlsZSwgY3VycmVudFZpZXdEYXRhLm9wdGlvbnMsIG9wdGlvbnNEYXRhLmRhdGVFbnYpLCBjYWxlbmRhckFwaTogcHJvcHMuY2FsZW5kYXJBcGksIGRpc3BhdGNoOiB0aGlzLmRpc3BhdGNoLCBlbWl0dGVyOiB0aGlzLmVtaXR0ZXIsIGdldEN1cnJlbnREYXRhOiB0aGlzLmdldEN1cnJlbnREYXRhIH0sIG9wdGlvbnNEYXRhKSwgY3VycmVudFZpZXdEYXRhKSwgc3RhdGUpO1xuICAgICAgICBsZXQgY2hhbmdlSGFuZGxlcnMgPSBvcHRpb25zRGF0YS5wbHVnaW5Ib29rcy5vcHRpb25DaGFuZ2VIYW5kbGVycztcbiAgICAgICAgbGV0IG9sZENhbGVuZGFyT3B0aW9ucyA9IG9sZERhdGEgJiYgb2xkRGF0YS5jYWxlbmRhck9wdGlvbnM7XG4gICAgICAgIGxldCBuZXdDYWxlbmRhck9wdGlvbnMgPSBvcHRpb25zRGF0YS5jYWxlbmRhck9wdGlvbnM7XG4gICAgICAgIGlmIChvbGRDYWxlbmRhck9wdGlvbnMgJiYgb2xkQ2FsZW5kYXJPcHRpb25zICE9PSBuZXdDYWxlbmRhck9wdGlvbnMpIHtcbiAgICAgICAgICAgIGlmIChvbGRDYWxlbmRhck9wdGlvbnMudGltZVpvbmUgIT09IG5ld0NhbGVuZGFyT3B0aW9ucy50aW1lWm9uZSkge1xuICAgICAgICAgICAgICAgIC8vIGhhY2tcbiAgICAgICAgICAgICAgICBzdGF0ZS5ldmVudFNvdXJjZXMgPSBkYXRhLmV2ZW50U291cmNlcyA9IHJlZHVjZUV2ZW50U291cmNlc05ld1RpbWVab25lKGRhdGEuZXZlbnRTb3VyY2VzLCBzdGF0ZS5kYXRlUHJvZmlsZSwgZGF0YSk7XG4gICAgICAgICAgICAgICAgc3RhdGUuZXZlbnRTdG9yZSA9IGRhdGEuZXZlbnRTdG9yZSA9IHJlem9uZUV2ZW50U3RvcmVEYXRlcyhkYXRhLmV2ZW50U3RvcmUsIG9sZERhdGEuZGF0ZUVudiwgZGF0YS5kYXRlRW52KTtcbiAgICAgICAgICAgICAgICBzdGF0ZS5yZW5kZXJhYmxlRXZlbnRTdG9yZSA9IGRhdGEucmVuZGVyYWJsZUV2ZW50U3RvcmUgPSByZXpvbmVFdmVudFN0b3JlRGF0ZXMoZGF0YS5yZW5kZXJhYmxlRXZlbnRTdG9yZSwgb2xkRGF0YS5kYXRlRW52LCBkYXRhLmRhdGVFbnYpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yIChsZXQgb3B0aW9uTmFtZSBpbiBjaGFuZ2VIYW5kbGVycykge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnNGb3JIYW5kbGluZy5pbmRleE9mKG9wdGlvbk5hbWUpICE9PSAtMSB8fFxuICAgICAgICAgICAgICAgICAgICBvbGRDYWxlbmRhck9wdGlvbnNbb3B0aW9uTmFtZV0gIT09IG5ld0NhbGVuZGFyT3B0aW9uc1tvcHRpb25OYW1lXSkge1xuICAgICAgICAgICAgICAgICAgICBjaGFuZ2VIYW5kbGVyc1tvcHRpb25OYW1lXShuZXdDYWxlbmRhck9wdGlvbnNbb3B0aW9uTmFtZV0sIGRhdGEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLm9wdGlvbnNGb3JIYW5kbGluZyA9IFtdO1xuICAgICAgICBpZiAocHJvcHMub25EYXRhKSB7XG4gICAgICAgICAgICBwcm9wcy5vbkRhdGEoZGF0YSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY29tcHV0ZU9wdGlvbnNEYXRhKG9wdGlvbk92ZXJyaWRlcywgZHluYW1pY09wdGlvbk92ZXJyaWRlcywgY2FsZW5kYXJBcGkpIHtcbiAgICAgICAgLy8gVE9ETzogYmxhY2tsaXN0IG9wdGlvbnMgdGhhdCBhcmUgaGFuZGxlZCBieSBvcHRpb25DaGFuZ2VIYW5kbGVyc1xuICAgICAgICBpZiAoIXRoaXMub3B0aW9uc0ZvclJlZmluaW5nLmxlbmd0aCAmJlxuICAgICAgICAgICAgb3B0aW9uT3ZlcnJpZGVzID09PSB0aGlzLnN0YWJsZU9wdGlvbk92ZXJyaWRlcyAmJlxuICAgICAgICAgICAgZHluYW1pY09wdGlvbk92ZXJyaWRlcyA9PT0gdGhpcy5zdGFibGVEeW5hbWljT3B0aW9uT3ZlcnJpZGVzKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zdGFibGVDYWxlbmRhck9wdGlvbnNEYXRhO1xuICAgICAgICB9XG4gICAgICAgIGxldCB7IHJlZmluZWRPcHRpb25zLCBwbHVnaW5Ib29rcywgbG9jYWxlRGVmYXVsdHMsIGF2YWlsYWJsZUxvY2FsZURhdGEsIGV4dHJhLCB9ID0gdGhpcy5wcm9jZXNzUmF3Q2FsZW5kYXJPcHRpb25zKG9wdGlvbk92ZXJyaWRlcywgZHluYW1pY09wdGlvbk92ZXJyaWRlcyk7XG4gICAgICAgIHdhcm5Vbmtub3duT3B0aW9ucyhleHRyYSk7XG4gICAgICAgIGxldCBkYXRlRW52ID0gdGhpcy5idWlsZERhdGVFbnYocmVmaW5lZE9wdGlvbnMudGltZVpvbmUsIHJlZmluZWRPcHRpb25zLmxvY2FsZSwgcmVmaW5lZE9wdGlvbnMud2Vla051bWJlckNhbGN1bGF0aW9uLCByZWZpbmVkT3B0aW9ucy5maXJzdERheSwgcmVmaW5lZE9wdGlvbnMud2Vla1RleHQsIHBsdWdpbkhvb2tzLCBhdmFpbGFibGVMb2NhbGVEYXRhLCByZWZpbmVkT3B0aW9ucy5kZWZhdWx0UmFuZ2VTZXBhcmF0b3IpO1xuICAgICAgICBsZXQgdmlld1NwZWNzID0gdGhpcy5idWlsZFZpZXdTcGVjcyhwbHVnaW5Ib29rcy52aWV3cywgdGhpcy5zdGFibGVPcHRpb25PdmVycmlkZXMsIHRoaXMuc3RhYmxlRHluYW1pY09wdGlvbk92ZXJyaWRlcywgbG9jYWxlRGVmYXVsdHMpO1xuICAgICAgICBsZXQgdGhlbWUgPSB0aGlzLmJ1aWxkVGhlbWUocmVmaW5lZE9wdGlvbnMsIHBsdWdpbkhvb2tzKTtcbiAgICAgICAgbGV0IHRvb2xiYXJDb25maWcgPSB0aGlzLnBhcnNlVG9vbGJhcnMocmVmaW5lZE9wdGlvbnMsIHRoaXMuc3RhYmxlT3B0aW9uT3ZlcnJpZGVzLCB0aGVtZSwgdmlld1NwZWNzLCBjYWxlbmRhckFwaSk7XG4gICAgICAgIHJldHVybiB0aGlzLnN0YWJsZUNhbGVuZGFyT3B0aW9uc0RhdGEgPSB7XG4gICAgICAgICAgICBjYWxlbmRhck9wdGlvbnM6IHJlZmluZWRPcHRpb25zLFxuICAgICAgICAgICAgcGx1Z2luSG9va3MsXG4gICAgICAgICAgICBkYXRlRW52LFxuICAgICAgICAgICAgdmlld1NwZWNzLFxuICAgICAgICAgICAgdGhlbWUsXG4gICAgICAgICAgICB0b29sYmFyQ29uZmlnLFxuICAgICAgICAgICAgbG9jYWxlRGVmYXVsdHMsXG4gICAgICAgICAgICBhdmFpbGFibGVSYXdMb2NhbGVzOiBhdmFpbGFibGVMb2NhbGVEYXRhLm1hcCxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLy8gYWx3YXlzIGNhbGxlZCBmcm9tIGJlaGluZCBhIG1lbW9pemVyXG4gICAgcHJvY2Vzc1Jhd0NhbGVuZGFyT3B0aW9ucyhvcHRpb25PdmVycmlkZXMsIGR5bmFtaWNPcHRpb25PdmVycmlkZXMpIHtcbiAgICAgICAgbGV0IHsgbG9jYWxlcywgbG9jYWxlIH0gPSBtZXJnZVJhd09wdGlvbnMoW1xuICAgICAgICAgICAgQkFTRV9PUFRJT05fREVGQVVMVFMsXG4gICAgICAgICAgICBvcHRpb25PdmVycmlkZXMsXG4gICAgICAgICAgICBkeW5hbWljT3B0aW9uT3ZlcnJpZGVzLFxuICAgICAgICBdKTtcbiAgICAgICAgbGV0IGF2YWlsYWJsZUxvY2FsZURhdGEgPSB0aGlzLm9yZ2FuaXplUmF3TG9jYWxlcyhsb2NhbGVzKTtcbiAgICAgICAgbGV0IGF2YWlsYWJsZVJhd0xvY2FsZXMgPSBhdmFpbGFibGVMb2NhbGVEYXRhLm1hcDtcbiAgICAgICAgbGV0IGxvY2FsZURlZmF1bHRzID0gdGhpcy5idWlsZExvY2FsZShsb2NhbGUgfHwgYXZhaWxhYmxlTG9jYWxlRGF0YS5kZWZhdWx0Q29kZSwgYXZhaWxhYmxlUmF3TG9jYWxlcykub3B0aW9ucztcbiAgICAgICAgbGV0IHBsdWdpbkhvb2tzID0gdGhpcy5idWlsZFBsdWdpbkhvb2tzKG9wdGlvbk92ZXJyaWRlcy5wbHVnaW5zIHx8IFtdLCBnbG9iYWxQbHVnaW5zKTtcbiAgICAgICAgbGV0IHJlZmluZXJzID0gdGhpcy5jdXJyZW50Q2FsZW5kYXJPcHRpb25zUmVmaW5lcnMgPSBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIEJBU0VfT1BUSU9OX1JFRklORVJTKSwgQ0FMRU5EQVJfTElTVEVORVJfUkVGSU5FUlMpLCBDQUxFTkRBUl9PUFRJT05fUkVGSU5FUlMpLCBwbHVnaW5Ib29rcy5saXN0ZW5lclJlZmluZXJzKSwgcGx1Z2luSG9va3Mub3B0aW9uUmVmaW5lcnMpO1xuICAgICAgICBsZXQgZXh0cmEgPSB7fTtcbiAgICAgICAgbGV0IHJhdyA9IG1lcmdlUmF3T3B0aW9ucyhbXG4gICAgICAgICAgICBCQVNFX09QVElPTl9ERUZBVUxUUyxcbiAgICAgICAgICAgIGxvY2FsZURlZmF1bHRzLFxuICAgICAgICAgICAgb3B0aW9uT3ZlcnJpZGVzLFxuICAgICAgICAgICAgZHluYW1pY09wdGlvbk92ZXJyaWRlcyxcbiAgICAgICAgXSk7XG4gICAgICAgIGxldCByZWZpbmVkID0ge307XG4gICAgICAgIGxldCBjdXJyZW50UmF3ID0gdGhpcy5jdXJyZW50Q2FsZW5kYXJPcHRpb25zSW5wdXQ7XG4gICAgICAgIGxldCBjdXJyZW50UmVmaW5lZCA9IHRoaXMuY3VycmVudENhbGVuZGFyT3B0aW9uc1JlZmluZWQ7XG4gICAgICAgIGxldCBhbnlDaGFuZ2VzID0gZmFsc2U7XG4gICAgICAgIGZvciAobGV0IG9wdGlvbk5hbWUgaW4gcmF3KSB7XG4gICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zRm9yUmVmaW5pbmcuaW5kZXhPZihvcHRpb25OYW1lKSA9PT0gLTEgJiYgKHJhd1tvcHRpb25OYW1lXSA9PT0gY3VycmVudFJhd1tvcHRpb25OYW1lXSB8fCAoQ09NUExFWF9PUFRJT05fQ09NUEFSQVRPUlNbb3B0aW9uTmFtZV0gJiZcbiAgICAgICAgICAgICAgICAob3B0aW9uTmFtZSBpbiBjdXJyZW50UmF3KSAmJlxuICAgICAgICAgICAgICAgIENPTVBMRVhfT1BUSU9OX0NPTVBBUkFUT1JTW29wdGlvbk5hbWVdKGN1cnJlbnRSYXdbb3B0aW9uTmFtZV0sIHJhd1tvcHRpb25OYW1lXSkpKSkge1xuICAgICAgICAgICAgICAgIHJlZmluZWRbb3B0aW9uTmFtZV0gPSBjdXJyZW50UmVmaW5lZFtvcHRpb25OYW1lXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHJlZmluZXJzW29wdGlvbk5hbWVdKSB7XG4gICAgICAgICAgICAgICAgcmVmaW5lZFtvcHRpb25OYW1lXSA9IHJlZmluZXJzW29wdGlvbk5hbWVdKHJhd1tvcHRpb25OYW1lXSk7XG4gICAgICAgICAgICAgICAgYW55Q2hhbmdlcyA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBleHRyYVtvcHRpb25OYW1lXSA9IGN1cnJlbnRSYXdbb3B0aW9uTmFtZV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGFueUNoYW5nZXMpIHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudENhbGVuZGFyT3B0aW9uc0lucHV0ID0gcmF3O1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50Q2FsZW5kYXJPcHRpb25zUmVmaW5lZCA9IHJlZmluZWQ7XG4gICAgICAgICAgICB0aGlzLnN0YWJsZU9wdGlvbk92ZXJyaWRlcyA9IG9wdGlvbk92ZXJyaWRlcztcbiAgICAgICAgICAgIHRoaXMuc3RhYmxlRHluYW1pY09wdGlvbk92ZXJyaWRlcyA9IGR5bmFtaWNPcHRpb25PdmVycmlkZXM7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vcHRpb25zRm9ySGFuZGxpbmcucHVzaCguLi50aGlzLm9wdGlvbnNGb3JSZWZpbmluZyk7XG4gICAgICAgIHRoaXMub3B0aW9uc0ZvclJlZmluaW5nID0gW107XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByYXdPcHRpb25zOiB0aGlzLmN1cnJlbnRDYWxlbmRhck9wdGlvbnNJbnB1dCxcbiAgICAgICAgICAgIHJlZmluZWRPcHRpb25zOiB0aGlzLmN1cnJlbnRDYWxlbmRhck9wdGlvbnNSZWZpbmVkLFxuICAgICAgICAgICAgcGx1Z2luSG9va3MsXG4gICAgICAgICAgICBhdmFpbGFibGVMb2NhbGVEYXRhLFxuICAgICAgICAgICAgbG9jYWxlRGVmYXVsdHMsXG4gICAgICAgICAgICBleHRyYSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgX2NvbXB1dGVDdXJyZW50Vmlld0RhdGEodmlld1R5cGUsIG9wdGlvbnNEYXRhLCBvcHRpb25PdmVycmlkZXMsIGR5bmFtaWNPcHRpb25PdmVycmlkZXMpIHtcbiAgICAgICAgbGV0IHZpZXdTcGVjID0gb3B0aW9uc0RhdGEudmlld1NwZWNzW3ZpZXdUeXBlXTtcbiAgICAgICAgaWYgKCF2aWV3U3BlYykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB2aWV3VHlwZSBcIiR7dmlld1R5cGV9XCIgaXMgbm90IGF2YWlsYWJsZS4gUGxlYXNlIG1ha2Ugc3VyZSB5b3UndmUgbG9hZGVkIGFsbCBuZWNjZXNzYXJ5IHBsdWdpbnNgKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgeyByZWZpbmVkT3B0aW9ucywgZXh0cmEgfSA9IHRoaXMucHJvY2Vzc1Jhd1ZpZXdPcHRpb25zKHZpZXdTcGVjLCBvcHRpb25zRGF0YS5wbHVnaW5Ib29rcywgb3B0aW9uc0RhdGEubG9jYWxlRGVmYXVsdHMsIG9wdGlvbk92ZXJyaWRlcywgZHluYW1pY09wdGlvbk92ZXJyaWRlcyk7XG4gICAgICAgIHdhcm5Vbmtub3duT3B0aW9ucyhleHRyYSk7XG4gICAgICAgIHRoaXMubm93TWFuYWdlci5oYW5kbGVJbnB1dChvcHRpb25zRGF0YS5kYXRlRW52LCByZWZpbmVkT3B0aW9ucy5ub3cpO1xuICAgICAgICBsZXQgZGF0ZVByb2ZpbGVHZW5lcmF0b3IgPSB0aGlzLmJ1aWxkRGF0ZVByb2ZpbGVHZW5lcmF0b3Ioe1xuICAgICAgICAgICAgZGF0ZVByb2ZpbGVHZW5lcmF0b3JDbGFzczogdmlld1NwZWMub3B0aW9uRGVmYXVsdHMuZGF0ZVByb2ZpbGVHZW5lcmF0b3JDbGFzcyxcbiAgICAgICAgICAgIG5vd01hbmFnZXI6IHRoaXMubm93TWFuYWdlcixcbiAgICAgICAgICAgIGR1cmF0aW9uOiB2aWV3U3BlYy5kdXJhdGlvbixcbiAgICAgICAgICAgIGR1cmF0aW9uVW5pdDogdmlld1NwZWMuZHVyYXRpb25Vbml0LFxuICAgICAgICAgICAgdXNlc01pbk1heFRpbWU6IHZpZXdTcGVjLm9wdGlvbkRlZmF1bHRzLnVzZXNNaW5NYXhUaW1lLFxuICAgICAgICAgICAgZGF0ZUVudjogb3B0aW9uc0RhdGEuZGF0ZUVudixcbiAgICAgICAgICAgIGNhbGVuZGFyQXBpOiB0aGlzLnByb3BzLmNhbGVuZGFyQXBpLFxuICAgICAgICAgICAgc2xvdE1pblRpbWU6IHJlZmluZWRPcHRpb25zLnNsb3RNaW5UaW1lLFxuICAgICAgICAgICAgc2xvdE1heFRpbWU6IHJlZmluZWRPcHRpb25zLnNsb3RNYXhUaW1lLFxuICAgICAgICAgICAgc2hvd05vbkN1cnJlbnREYXRlczogcmVmaW5lZE9wdGlvbnMuc2hvd05vbkN1cnJlbnREYXRlcyxcbiAgICAgICAgICAgIGRheUNvdW50OiByZWZpbmVkT3B0aW9ucy5kYXlDb3VudCxcbiAgICAgICAgICAgIGRhdGVBbGlnbm1lbnQ6IHJlZmluZWRPcHRpb25zLmRhdGVBbGlnbm1lbnQsXG4gICAgICAgICAgICBkYXRlSW5jcmVtZW50OiByZWZpbmVkT3B0aW9ucy5kYXRlSW5jcmVtZW50LFxuICAgICAgICAgICAgaGlkZGVuRGF5czogcmVmaW5lZE9wdGlvbnMuaGlkZGVuRGF5cyxcbiAgICAgICAgICAgIHdlZWtlbmRzOiByZWZpbmVkT3B0aW9ucy53ZWVrZW5kcyxcbiAgICAgICAgICAgIHZhbGlkUmFuZ2VJbnB1dDogcmVmaW5lZE9wdGlvbnMudmFsaWRSYW5nZSxcbiAgICAgICAgICAgIHZpc2libGVSYW5nZUlucHV0OiByZWZpbmVkT3B0aW9ucy52aXNpYmxlUmFuZ2UsXG4gICAgICAgICAgICBmaXhlZFdlZWtDb3VudDogcmVmaW5lZE9wdGlvbnMuZml4ZWRXZWVrQ291bnQsXG4gICAgICAgIH0pO1xuICAgICAgICBsZXQgdmlld0FwaSA9IHRoaXMuYnVpbGRWaWV3QXBpKHZpZXdUeXBlLCB0aGlzLmdldEN1cnJlbnREYXRhLCBvcHRpb25zRGF0YS5kYXRlRW52KTtcbiAgICAgICAgcmV0dXJuIHsgdmlld1NwZWMsIG9wdGlvbnM6IHJlZmluZWRPcHRpb25zLCBkYXRlUHJvZmlsZUdlbmVyYXRvciwgdmlld0FwaSB9O1xuICAgIH1cbiAgICBwcm9jZXNzUmF3Vmlld09wdGlvbnModmlld1NwZWMsIHBsdWdpbkhvb2tzLCBsb2NhbGVEZWZhdWx0cywgb3B0aW9uT3ZlcnJpZGVzLCBkeW5hbWljT3B0aW9uT3ZlcnJpZGVzKSB7XG4gICAgICAgIGxldCByYXcgPSBtZXJnZVJhd09wdGlvbnMoW1xuICAgICAgICAgICAgQkFTRV9PUFRJT05fREVGQVVMVFMsXG4gICAgICAgICAgICB2aWV3U3BlYy5vcHRpb25EZWZhdWx0cyxcbiAgICAgICAgICAgIGxvY2FsZURlZmF1bHRzLFxuICAgICAgICAgICAgb3B0aW9uT3ZlcnJpZGVzLFxuICAgICAgICAgICAgdmlld1NwZWMub3B0aW9uT3ZlcnJpZGVzLFxuICAgICAgICAgICAgZHluYW1pY09wdGlvbk92ZXJyaWRlcyxcbiAgICAgICAgXSk7XG4gICAgICAgIGxldCByZWZpbmVycyA9IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBCQVNFX09QVElPTl9SRUZJTkVSUyksIENBTEVOREFSX0xJU1RFTkVSX1JFRklORVJTKSwgQ0FMRU5EQVJfT1BUSU9OX1JFRklORVJTKSwgVklFV19PUFRJT05fUkVGSU5FUlMpLCBwbHVnaW5Ib29rcy5saXN0ZW5lclJlZmluZXJzKSwgcGx1Z2luSG9va3Mub3B0aW9uUmVmaW5lcnMpO1xuICAgICAgICBsZXQgcmVmaW5lZCA9IHt9O1xuICAgICAgICBsZXQgY3VycmVudFJhdyA9IHRoaXMuY3VycmVudFZpZXdPcHRpb25zSW5wdXQ7XG4gICAgICAgIGxldCBjdXJyZW50UmVmaW5lZCA9IHRoaXMuY3VycmVudFZpZXdPcHRpb25zUmVmaW5lZDtcbiAgICAgICAgbGV0IGFueUNoYW5nZXMgPSBmYWxzZTtcbiAgICAgICAgbGV0IGV4dHJhID0ge307XG4gICAgICAgIGZvciAobGV0IG9wdGlvbk5hbWUgaW4gcmF3KSB7XG4gICAgICAgICAgICBpZiAocmF3W29wdGlvbk5hbWVdID09PSBjdXJyZW50UmF3W29wdGlvbk5hbWVdIHx8XG4gICAgICAgICAgICAgICAgKENPTVBMRVhfT1BUSU9OX0NPTVBBUkFUT1JTW29wdGlvbk5hbWVdICYmXG4gICAgICAgICAgICAgICAgICAgIENPTVBMRVhfT1BUSU9OX0NPTVBBUkFUT1JTW29wdGlvbk5hbWVdKHJhd1tvcHRpb25OYW1lXSwgY3VycmVudFJhd1tvcHRpb25OYW1lXSkpKSB7XG4gICAgICAgICAgICAgICAgcmVmaW5lZFtvcHRpb25OYW1lXSA9IGN1cnJlbnRSZWZpbmVkW29wdGlvbk5hbWVdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKHJhd1tvcHRpb25OYW1lXSA9PT0gdGhpcy5jdXJyZW50Q2FsZW5kYXJPcHRpb25zSW5wdXRbb3B0aW9uTmFtZV0gfHxcbiAgICAgICAgICAgICAgICAgICAgKENPTVBMRVhfT1BUSU9OX0NPTVBBUkFUT1JTW29wdGlvbk5hbWVdICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBDT01QTEVYX09QVElPTl9DT01QQVJBVE9SU1tvcHRpb25OYW1lXShyYXdbb3B0aW9uTmFtZV0sIHRoaXMuY3VycmVudENhbGVuZGFyT3B0aW9uc0lucHV0W29wdGlvbk5hbWVdKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbk5hbWUgaW4gdGhpcy5jdXJyZW50Q2FsZW5kYXJPcHRpb25zUmVmaW5lZCkgeyAvLyBtaWdodCBiZSBhbiBcImV4dHJhXCIgcHJvcFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVmaW5lZFtvcHRpb25OYW1lXSA9IHRoaXMuY3VycmVudENhbGVuZGFyT3B0aW9uc1JlZmluZWRbb3B0aW9uTmFtZV07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAocmVmaW5lcnNbb3B0aW9uTmFtZV0pIHtcbiAgICAgICAgICAgICAgICAgICAgcmVmaW5lZFtvcHRpb25OYW1lXSA9IHJlZmluZXJzW29wdGlvbk5hbWVdKHJhd1tvcHRpb25OYW1lXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBleHRyYVtvcHRpb25OYW1lXSA9IHJhd1tvcHRpb25OYW1lXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYW55Q2hhbmdlcyA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGFueUNoYW5nZXMpIHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudFZpZXdPcHRpb25zSW5wdXQgPSByYXc7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRWaWV3T3B0aW9uc1JlZmluZWQgPSByZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByYXdPcHRpb25zOiB0aGlzLmN1cnJlbnRWaWV3T3B0aW9uc0lucHV0LFxuICAgICAgICAgICAgcmVmaW5lZE9wdGlvbnM6IHRoaXMuY3VycmVudFZpZXdPcHRpb25zUmVmaW5lZCxcbiAgICAgICAgICAgIGV4dHJhLFxuICAgICAgICB9O1xuICAgIH1cbn1cbmZ1bmN0aW9uIGJ1aWxkRGF0ZUVudiQxKHRpbWVab25lLCBleHBsaWNpdExvY2FsZSwgd2Vla051bWJlckNhbGN1bGF0aW9uLCBmaXJzdERheSwgd2Vla1RleHQsIHBsdWdpbkhvb2tzLCBhdmFpbGFibGVMb2NhbGVEYXRhLCBkZWZhdWx0U2VwYXJhdG9yKSB7XG4gICAgbGV0IGxvY2FsZSA9IGJ1aWxkTG9jYWxlKGV4cGxpY2l0TG9jYWxlIHx8IGF2YWlsYWJsZUxvY2FsZURhdGEuZGVmYXVsdENvZGUsIGF2YWlsYWJsZUxvY2FsZURhdGEubWFwKTtcbiAgICByZXR1cm4gbmV3IERhdGVFbnYoe1xuICAgICAgICBjYWxlbmRhclN5c3RlbTogJ2dyZWdvcnknLFxuICAgICAgICB0aW1lWm9uZSxcbiAgICAgICAgbmFtZWRUaW1lWm9uZUltcGw6IHBsdWdpbkhvb2tzLm5hbWVkVGltZVpvbmVkSW1wbCxcbiAgICAgICAgbG9jYWxlLFxuICAgICAgICB3ZWVrTnVtYmVyQ2FsY3VsYXRpb24sXG4gICAgICAgIGZpcnN0RGF5LFxuICAgICAgICB3ZWVrVGV4dCxcbiAgICAgICAgY21kRm9ybWF0dGVyOiBwbHVnaW5Ib29rcy5jbWRGb3JtYXR0ZXIsXG4gICAgICAgIGRlZmF1bHRTZXBhcmF0b3IsXG4gICAgfSk7XG59XG5mdW5jdGlvbiBidWlsZFRoZW1lKG9wdGlvbnMsIHBsdWdpbkhvb2tzKSB7XG4gICAgbGV0IFRoZW1lQ2xhc3MgPSBwbHVnaW5Ib29rcy50aGVtZUNsYXNzZXNbb3B0aW9ucy50aGVtZVN5c3RlbV0gfHwgU3RhbmRhcmRUaGVtZTtcbiAgICByZXR1cm4gbmV3IFRoZW1lQ2xhc3Mob3B0aW9ucyk7XG59XG5mdW5jdGlvbiBidWlsZERhdGVQcm9maWxlR2VuZXJhdG9yKHByb3BzKSB7XG4gICAgbGV0IERhdGVQcm9maWxlR2VuZXJhdG9yQ2xhc3MgPSBwcm9wcy5kYXRlUHJvZmlsZUdlbmVyYXRvckNsYXNzIHx8IERhdGVQcm9maWxlR2VuZXJhdG9yO1xuICAgIHJldHVybiBuZXcgRGF0ZVByb2ZpbGVHZW5lcmF0b3JDbGFzcyhwcm9wcyk7XG59XG5mdW5jdGlvbiBidWlsZFZpZXdBcGkodHlwZSwgZ2V0Q3VycmVudERhdGEsIGRhdGVFbnYpIHtcbiAgICByZXR1cm4gbmV3IFZpZXdJbXBsKHR5cGUsIGdldEN1cnJlbnREYXRhLCBkYXRlRW52KTtcbn1cbmZ1bmN0aW9uIGJ1aWxkRXZlbnRVaUJ5U291cmNlKGV2ZW50U291cmNlcykge1xuICAgIHJldHVybiBtYXBIYXNoKGV2ZW50U291cmNlcywgKGV2ZW50U291cmNlKSA9PiBldmVudFNvdXJjZS51aSk7XG59XG5mdW5jdGlvbiBidWlsZEV2ZW50VWlCYXNlcyhldmVudERlZnMsIGV2ZW50VWlTaW5nbGVCYXNlLCBldmVudFVpQnlTb3VyY2UpIHtcbiAgICBsZXQgZXZlbnRVaUJhc2VzID0geyAnJzogZXZlbnRVaVNpbmdsZUJhc2UgfTtcbiAgICBmb3IgKGxldCBkZWZJZCBpbiBldmVudERlZnMpIHtcbiAgICAgICAgbGV0IGRlZiA9IGV2ZW50RGVmc1tkZWZJZF07XG4gICAgICAgIGlmIChkZWYuc291cmNlSWQgJiYgZXZlbnRVaUJ5U291cmNlW2RlZi5zb3VyY2VJZF0pIHtcbiAgICAgICAgICAgIGV2ZW50VWlCYXNlc1tkZWZJZF0gPSBldmVudFVpQnlTb3VyY2VbZGVmLnNvdXJjZUlkXTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZXZlbnRVaUJhc2VzO1xufVxuZnVuY3Rpb24gYnVpbGRWaWV3VWlQcm9wcyhjYWxlbmRhckNvbnRleHQpIHtcbiAgICBsZXQgeyBvcHRpb25zIH0gPSBjYWxlbmRhckNvbnRleHQ7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgZXZlbnRVaVNpbmdsZUJhc2U6IGNyZWF0ZUV2ZW50VWkoe1xuICAgICAgICAgICAgZGlzcGxheTogb3B0aW9ucy5ldmVudERpc3BsYXksXG4gICAgICAgICAgICBlZGl0YWJsZTogb3B0aW9ucy5lZGl0YWJsZSxcbiAgICAgICAgICAgIHN0YXJ0RWRpdGFibGU6IG9wdGlvbnMuZXZlbnRTdGFydEVkaXRhYmxlLFxuICAgICAgICAgICAgZHVyYXRpb25FZGl0YWJsZTogb3B0aW9ucy5ldmVudER1cmF0aW9uRWRpdGFibGUsXG4gICAgICAgICAgICBjb25zdHJhaW50OiBvcHRpb25zLmV2ZW50Q29uc3RyYWludCxcbiAgICAgICAgICAgIG92ZXJsYXA6IHR5cGVvZiBvcHRpb25zLmV2ZW50T3ZlcmxhcCA9PT0gJ2Jvb2xlYW4nID8gb3B0aW9ucy5ldmVudE92ZXJsYXAgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBhbGxvdzogb3B0aW9ucy5ldmVudEFsbG93LFxuICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiBvcHRpb25zLmV2ZW50QmFja2dyb3VuZENvbG9yLFxuICAgICAgICAgICAgYm9yZGVyQ29sb3I6IG9wdGlvbnMuZXZlbnRCb3JkZXJDb2xvcixcbiAgICAgICAgICAgIHRleHRDb2xvcjogb3B0aW9ucy5ldmVudFRleHRDb2xvcixcbiAgICAgICAgICAgIGNvbG9yOiBvcHRpb25zLmV2ZW50Q29sb3IsXG4gICAgICAgICAgICAvLyBjbGFzc05hbWVzOiBvcHRpb25zLmV2ZW50Q2xhc3NOYW1lcyAvLyByZW5kZXIgaG9vayB3aWxsIGhhbmRsZSB0aGlzXG4gICAgICAgIH0sIGNhbGVuZGFyQ29udGV4dCksXG4gICAgICAgIHNlbGVjdGlvbkNvbmZpZzogY3JlYXRlRXZlbnRVaSh7XG4gICAgICAgICAgICBjb25zdHJhaW50OiBvcHRpb25zLnNlbGVjdENvbnN0cmFpbnQsXG4gICAgICAgICAgICBvdmVybGFwOiB0eXBlb2Ygb3B0aW9ucy5zZWxlY3RPdmVybGFwID09PSAnYm9vbGVhbicgPyBvcHRpb25zLnNlbGVjdE92ZXJsYXAgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBhbGxvdzogb3B0aW9ucy5zZWxlY3RBbGxvdyxcbiAgICAgICAgfSwgY2FsZW5kYXJDb250ZXh0KSxcbiAgICB9O1xufVxuZnVuY3Rpb24gY29tcHV0ZUlzTG9hZGluZyhzdGF0ZSwgY29udGV4dCkge1xuICAgIGZvciAobGV0IGlzTG9hZGluZ0Z1bmMgb2YgY29udGV4dC5wbHVnaW5Ib29rcy5pc0xvYWRpbmdGdW5jcykge1xuICAgICAgICBpZiAoaXNMb2FkaW5nRnVuYyhzdGF0ZSkpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cbmZ1bmN0aW9uIHBhcnNlQ29udGV4dEJ1c2luZXNzSG91cnMoY2FsZW5kYXJDb250ZXh0KSB7XG4gICAgcmV0dXJuIHBhcnNlQnVzaW5lc3NIb3VycyhjYWxlbmRhckNvbnRleHQub3B0aW9ucy5idXNpbmVzc0hvdXJzLCBjYWxlbmRhckNvbnRleHQpO1xufVxuZnVuY3Rpb24gd2FyblVua25vd25PcHRpb25zKG9wdGlvbnMsIHZpZXdOYW1lKSB7XG4gICAgZm9yIChsZXQgb3B0aW9uTmFtZSBpbiBvcHRpb25zKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihgVW5rbm93biBvcHRpb24gJyR7b3B0aW9uTmFtZX0nYCArXG4gICAgICAgICAgICAodmlld05hbWUgPyBgIGZvciB2aWV3ICcke3ZpZXdOYW1lfSdgIDogJycpKTtcbiAgICB9XG59XG5cbmNsYXNzIFRvb2xiYXJTZWN0aW9uIGV4dGVuZHMgQmFzZUNvbXBvbmVudCB7XG4gICAgcmVuZGVyKCkge1xuICAgICAgICBsZXQgY2hpbGRyZW4gPSB0aGlzLnByb3BzLndpZGdldEdyb3Vwcy5tYXAoKHdpZGdldEdyb3VwKSA9PiB0aGlzLnJlbmRlcldpZGdldEdyb3VwKHdpZGdldEdyb3VwKSk7XG4gICAgICAgIHJldHVybiBjcmVhdGVFbGVtZW50KCdkaXYnLCB7IGNsYXNzTmFtZTogJ2ZjLXRvb2xiYXItY2h1bmsnIH0sIC4uLmNoaWxkcmVuKTtcbiAgICB9XG4gICAgcmVuZGVyV2lkZ2V0R3JvdXAod2lkZ2V0R3JvdXApIHtcbiAgICAgICAgbGV0IHsgcHJvcHMgfSA9IHRoaXM7XG4gICAgICAgIGxldCB7IHRoZW1lIH0gPSB0aGlzLmNvbnRleHQ7XG4gICAgICAgIGxldCBjaGlsZHJlbiA9IFtdO1xuICAgICAgICBsZXQgaXNPbmx5QnV0dG9ucyA9IHRydWU7XG4gICAgICAgIGZvciAobGV0IHdpZGdldCBvZiB3aWRnZXRHcm91cCkge1xuICAgICAgICAgICAgbGV0IHsgYnV0dG9uTmFtZSwgYnV0dG9uQ2xpY2ssIGJ1dHRvblRleHQsIGJ1dHRvbkljb24sIGJ1dHRvbkhpbnQgfSA9IHdpZGdldDtcbiAgICAgICAgICAgIGlmIChidXR0b25OYW1lID09PSAndGl0bGUnKSB7XG4gICAgICAgICAgICAgICAgaXNPbmx5QnV0dG9ucyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGNoaWxkcmVuLnB1c2goY3JlYXRlRWxlbWVudChcImgyXCIsIHsgY2xhc3NOYW1lOiBcImZjLXRvb2xiYXItdGl0bGVcIiwgaWQ6IHByb3BzLnRpdGxlSWQgfSwgcHJvcHMudGl0bGUpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGxldCBpc1ByZXNzZWQgPSBidXR0b25OYW1lID09PSBwcm9wcy5hY3RpdmVCdXR0b247XG4gICAgICAgICAgICAgICAgbGV0IGlzRGlzYWJsZWQgPSAoIXByb3BzLmlzVG9kYXlFbmFibGVkICYmIGJ1dHRvbk5hbWUgPT09ICd0b2RheScpIHx8XG4gICAgICAgICAgICAgICAgICAgICghcHJvcHMuaXNQcmV2RW5hYmxlZCAmJiBidXR0b25OYW1lID09PSAncHJldicpIHx8XG4gICAgICAgICAgICAgICAgICAgICghcHJvcHMuaXNOZXh0RW5hYmxlZCAmJiBidXR0b25OYW1lID09PSAnbmV4dCcpO1xuICAgICAgICAgICAgICAgIGxldCBidXR0b25DbGFzc2VzID0gW2BmYy0ke2J1dHRvbk5hbWV9LWJ1dHRvbmAsIHRoZW1lLmdldENsYXNzKCdidXR0b24nKV07XG4gICAgICAgICAgICAgICAgaWYgKGlzUHJlc3NlZCkge1xuICAgICAgICAgICAgICAgICAgICBidXR0b25DbGFzc2VzLnB1c2godGhlbWUuZ2V0Q2xhc3MoJ2J1dHRvbkFjdGl2ZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2hpbGRyZW4ucHVzaChjcmVhdGVFbGVtZW50KFwiYnV0dG9uXCIsIHsgdHlwZTogXCJidXR0b25cIiwgdGl0bGU6IHR5cGVvZiBidXR0b25IaW50ID09PSAnZnVuY3Rpb24nID8gYnV0dG9uSGludChwcm9wcy5uYXZVbml0KSA6IGJ1dHRvbkhpbnQsIGRpc2FibGVkOiBpc0Rpc2FibGVkLCBcImFyaWEtcHJlc3NlZFwiOiBpc1ByZXNzZWQsIGNsYXNzTmFtZTogYnV0dG9uQ2xhc3Nlcy5qb2luKCcgJyksIG9uQ2xpY2s6IGJ1dHRvbkNsaWNrIH0sIGJ1dHRvblRleHQgfHwgKGJ1dHRvbkljb24gPyBjcmVhdGVFbGVtZW50KFwic3BhblwiLCB7IGNsYXNzTmFtZTogYnV0dG9uSWNvbiwgcm9sZTogXCJpbWdcIiB9KSA6ICcnKSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChjaGlsZHJlbi5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICBsZXQgZ3JvdXBDbGFzc05hbWUgPSAoaXNPbmx5QnV0dG9ucyAmJiB0aGVtZS5nZXRDbGFzcygnYnV0dG9uR3JvdXAnKSkgfHwgJyc7XG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlRWxlbWVudCgnZGl2JywgeyBjbGFzc05hbWU6IGdyb3VwQ2xhc3NOYW1lIH0sIC4uLmNoaWxkcmVuKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2hpbGRyZW5bMF07XG4gICAgfVxufVxuXG5jbGFzcyBUb29sYmFyIGV4dGVuZHMgQmFzZUNvbXBvbmVudCB7XG4gICAgcmVuZGVyKCkge1xuICAgICAgICBsZXQgeyBtb2RlbCwgZXh0cmFDbGFzc05hbWUgfSA9IHRoaXMucHJvcHM7XG4gICAgICAgIGxldCBmb3JjZUx0ciA9IGZhbHNlO1xuICAgICAgICBsZXQgc3RhcnRDb250ZW50O1xuICAgICAgICBsZXQgZW5kQ29udGVudDtcbiAgICAgICAgbGV0IHNlY3Rpb25XaWRnZXRzID0gbW9kZWwuc2VjdGlvbldpZGdldHM7XG4gICAgICAgIGxldCBjZW50ZXJDb250ZW50ID0gc2VjdGlvbldpZGdldHMuY2VudGVyO1xuICAgICAgICBpZiAoc2VjdGlvbldpZGdldHMubGVmdCkge1xuICAgICAgICAgICAgZm9yY2VMdHIgPSB0cnVlO1xuICAgICAgICAgICAgc3RhcnRDb250ZW50ID0gc2VjdGlvbldpZGdldHMubGVmdDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHN0YXJ0Q29udGVudCA9IHNlY3Rpb25XaWRnZXRzLnN0YXJ0O1xuICAgICAgICB9XG4gICAgICAgIGlmIChzZWN0aW9uV2lkZ2V0cy5yaWdodCkge1xuICAgICAgICAgICAgZm9yY2VMdHIgPSB0cnVlO1xuICAgICAgICAgICAgZW5kQ29udGVudCA9IHNlY3Rpb25XaWRnZXRzLnJpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZW5kQ29udGVudCA9IHNlY3Rpb25XaWRnZXRzLmVuZDtcbiAgICAgICAgfVxuICAgICAgICBsZXQgY2xhc3NOYW1lcyA9IFtcbiAgICAgICAgICAgIGV4dHJhQ2xhc3NOYW1lIHx8ICcnLFxuICAgICAgICAgICAgJ2ZjLXRvb2xiYXInLFxuICAgICAgICAgICAgZm9yY2VMdHIgPyAnZmMtdG9vbGJhci1sdHInIDogJycsXG4gICAgICAgIF07XG4gICAgICAgIHJldHVybiAoY3JlYXRlRWxlbWVudChcImRpdlwiLCB7IGNsYXNzTmFtZTogY2xhc3NOYW1lcy5qb2luKCcgJykgfSxcbiAgICAgICAgICAgIHRoaXMucmVuZGVyU2VjdGlvbignc3RhcnQnLCBzdGFydENvbnRlbnQgfHwgW10pLFxuICAgICAgICAgICAgdGhpcy5yZW5kZXJTZWN0aW9uKCdjZW50ZXInLCBjZW50ZXJDb250ZW50IHx8IFtdKSxcbiAgICAgICAgICAgIHRoaXMucmVuZGVyU2VjdGlvbignZW5kJywgZW5kQ29udGVudCB8fCBbXSkpKTtcbiAgICB9XG4gICAgcmVuZGVyU2VjdGlvbihrZXksIHdpZGdldEdyb3Vwcykge1xuICAgICAgICBsZXQgeyBwcm9wcyB9ID0gdGhpcztcbiAgICAgICAgcmV0dXJuIChjcmVhdGVFbGVtZW50KFRvb2xiYXJTZWN0aW9uLCB7IGtleToga2V5LCB3aWRnZXRHcm91cHM6IHdpZGdldEdyb3VwcywgdGl0bGU6IHByb3BzLnRpdGxlLCBuYXZVbml0OiBwcm9wcy5uYXZVbml0LCBhY3RpdmVCdXR0b246IHByb3BzLmFjdGl2ZUJ1dHRvbiwgaXNUb2RheUVuYWJsZWQ6IHByb3BzLmlzVG9kYXlFbmFibGVkLCBpc1ByZXZFbmFibGVkOiBwcm9wcy5pc1ByZXZFbmFibGVkLCBpc05leHRFbmFibGVkOiBwcm9wcy5pc05leHRFbmFibGVkLCB0aXRsZUlkOiBwcm9wcy50aXRsZUlkIH0pKTtcbiAgICB9XG59XG5cbmNsYXNzIFZpZXdIYXJuZXNzIGV4dGVuZHMgQmFzZUNvbXBvbmVudCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICAgICAgICBhdmFpbGFibGVXaWR0aDogbnVsbCxcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5oYW5kbGVFbCA9IChlbCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5lbCA9IGVsO1xuICAgICAgICAgICAgc2V0UmVmKHRoaXMucHJvcHMuZWxSZWYsIGVsKTtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlQXZhaWxhYmxlV2lkdGgoKTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5oYW5kbGVSZXNpemUgPSAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZUF2YWlsYWJsZVdpZHRoKCk7XG4gICAgICAgIH07XG4gICAgfVxuICAgIHJlbmRlcigpIHtcbiAgICAgICAgbGV0IHsgcHJvcHMsIHN0YXRlIH0gPSB0aGlzO1xuICAgICAgICBsZXQgeyBhc3BlY3RSYXRpbyB9ID0gcHJvcHM7XG4gICAgICAgIGxldCBjbGFzc05hbWVzID0gW1xuICAgICAgICAgICAgJ2ZjLXZpZXctaGFybmVzcycsXG4gICAgICAgICAgICAoYXNwZWN0UmF0aW8gfHwgcHJvcHMubGlxdWlkIHx8IHByb3BzLmhlaWdodClcbiAgICAgICAgICAgICAgICA/ICdmYy12aWV3LWhhcm5lc3MtYWN0aXZlJyAvLyBoYXJuZXNzIGNvbnRyb2xzIHRoZSBoZWlnaHRcbiAgICAgICAgICAgICAgICA6ICdmYy12aWV3LWhhcm5lc3MtcGFzc2l2ZScsIC8vIGxldCB0aGUgdmlldyBkbyB0aGUgaGVpZ2h0XG4gICAgICAgIF07XG4gICAgICAgIGxldCBoZWlnaHQgPSAnJztcbiAgICAgICAgbGV0IHBhZGRpbmdCb3R0b20gPSAnJztcbiAgICAgICAgaWYgKGFzcGVjdFJhdGlvKSB7XG4gICAgICAgICAgICBpZiAoc3RhdGUuYXZhaWxhYmxlV2lkdGggIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBoZWlnaHQgPSBzdGF0ZS5hdmFpbGFibGVXaWR0aCAvIGFzcGVjdFJhdGlvO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gd2hpbGUgd2FpdGluZyB0byBrbm93IGF2YWlsYWJsZVdpZHRoLCB3ZSBjYW4ndCBzZXQgaGVpZ2h0IHRvICp6ZXJvKlxuICAgICAgICAgICAgICAgIC8vIGJlY2F1c2Ugd2lsbCBjYXVzZSBsb3RzIG9mIHVubmVjZXNzYXJ5IHNjcm9sbGJhcnMgd2l0aGluIHNjcm9sbGdyaWQuXG4gICAgICAgICAgICAgICAgLy8gQkVUVEVSOiBkb24ndCBzdGFydCByZW5kZXJpbmcgQU5ZVEhJTkcgeWV0IHVudGlsIHdlIGtub3cgY29udGFpbmVyIHdpZHRoXG4gICAgICAgICAgICAgICAgLy8gTk9URTogd2h5IG5vdCBhbHdheXMgdXNlIHBhZGRpbmdCb3R0b20/IENhdXNlcyBoZWlnaHQgb3NjaWxsYXRpb24gKGlzc3VlIDU2MDYpXG4gICAgICAgICAgICAgICAgcGFkZGluZ0JvdHRvbSA9IGAkeygxIC8gYXNwZWN0UmF0aW8pICogMTAwfSVgO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaGVpZ2h0ID0gcHJvcHMuaGVpZ2h0IHx8ICcnO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAoY3JlYXRlRWxlbWVudChcImRpdlwiLCB7IFwiYXJpYS1sYWJlbGxlZGJ5XCI6IHByb3BzLmxhYmVsZWRCeUlkLCByZWY6IHRoaXMuaGFuZGxlRWwsIGNsYXNzTmFtZTogY2xhc3NOYW1lcy5qb2luKCcgJyksIHN0eWxlOiB7IGhlaWdodCwgcGFkZGluZ0JvdHRvbSB9IH0sIHByb3BzLmNoaWxkcmVuKSk7XG4gICAgfVxuICAgIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgICAgICB0aGlzLmNvbnRleHQuYWRkUmVzaXplSGFuZGxlcih0aGlzLmhhbmRsZVJlc2l6ZSk7XG4gICAgfVxuICAgIGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xuICAgICAgICB0aGlzLmNvbnRleHQucmVtb3ZlUmVzaXplSGFuZGxlcih0aGlzLmhhbmRsZVJlc2l6ZSk7XG4gICAgfVxuICAgIHVwZGF0ZUF2YWlsYWJsZVdpZHRoKCkge1xuICAgICAgICBpZiAodGhpcy5lbCAmJiAvLyBuZWVkZWQuIGJ1dCB3aHk/XG4gICAgICAgICAgICB0aGlzLnByb3BzLmFzcGVjdFJhdGlvIC8vIGFzcGVjdFJhdGlvIGlzIHRoZSBvbmx5IGhlaWdodCBzZXR0aW5nIHRoYXQgbmVlZHMgYXZhaWxhYmxlV2lkdGhcbiAgICAgICAgKSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgYXZhaWxhYmxlV2lkdGg6IHRoaXMuZWwub2Zmc2V0V2lkdGggfSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8qXG5EZXRlY3RzIHdoZW4gdGhlIHVzZXIgY2xpY2tzIG9uIGFuIGV2ZW50IHdpdGhpbiBhIERhdGVDb21wb25lbnRcbiovXG5jbGFzcyBFdmVudENsaWNraW5nIGV4dGVuZHMgSW50ZXJhY3Rpb24ge1xuICAgIGNvbnN0cnVjdG9yKHNldHRpbmdzKSB7XG4gICAgICAgIHN1cGVyKHNldHRpbmdzKTtcbiAgICAgICAgdGhpcy5oYW5kbGVTZWdDbGljayA9IChldiwgc2VnRWwpID0+IHtcbiAgICAgICAgICAgIGxldCB7IGNvbXBvbmVudCB9ID0gdGhpcztcbiAgICAgICAgICAgIGxldCB7IGNvbnRleHQgfSA9IGNvbXBvbmVudDtcbiAgICAgICAgICAgIGxldCBzZWcgPSBnZXRFbFNlZyhzZWdFbCk7XG4gICAgICAgICAgICBpZiAoc2VnICYmIC8vIG1pZ2h0IGJlIHRoZSA8ZGl2PiBzdXJyb3VuZGluZyB0aGUgbW9yZSBsaW5rXG4gICAgICAgICAgICAgICAgY29tcG9uZW50LmlzVmFsaWRTZWdEb3duRWwoZXYudGFyZ2V0KSkge1xuICAgICAgICAgICAgICAgIC8vIG91ciB3YXkgdG8gc2ltdWxhdGUgYSBsaW5rIGNsaWNrIGZvciBlbGVtZW50cyB0aGF0IGNhbid0IGJlIDxhPiB0YWdzXG4gICAgICAgICAgICAgICAgLy8gZ3JhYiBiZWZvcmUgdHJpZ2dlciBmaXJlZCBpbiBjYXNlIHRyaWdnZXIgdHJhc2hlcyBET00gdGhydSByZXJlbmRlcmluZ1xuICAgICAgICAgICAgICAgIGxldCBoYXNVcmxDb250YWluZXIgPSBlbGVtZW50Q2xvc2VzdChldi50YXJnZXQsICcuZmMtZXZlbnQtZm9yY2VkLXVybCcpO1xuICAgICAgICAgICAgICAgIGxldCB1cmwgPSBoYXNVcmxDb250YWluZXIgPyBoYXNVcmxDb250YWluZXIucXVlcnlTZWxlY3RvcignYVtocmVmXScpLmhyZWYgOiAnJztcbiAgICAgICAgICAgICAgICBjb250ZXh0LmVtaXR0ZXIudHJpZ2dlcignZXZlbnRDbGljaycsIHtcbiAgICAgICAgICAgICAgICAgICAgZWw6IHNlZ0VsLFxuICAgICAgICAgICAgICAgICAgICBldmVudDogbmV3IEV2ZW50SW1wbChjb21wb25lbnQuY29udGV4dCwgc2VnLmV2ZW50UmFuZ2UuZGVmLCBzZWcuZXZlbnRSYW5nZS5pbnN0YW5jZSksXG4gICAgICAgICAgICAgICAgICAgIGpzRXZlbnQ6IGV2LFxuICAgICAgICAgICAgICAgICAgICB2aWV3OiBjb250ZXh0LnZpZXdBcGksXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgaWYgKHVybCAmJiAhZXYuZGVmYXVsdFByZXZlbnRlZCkge1xuICAgICAgICAgICAgICAgICAgICB3aW5kb3cubG9jYXRpb24uaHJlZiA9IHVybDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuZGVzdHJveSA9IGxpc3RlbkJ5U2VsZWN0b3Ioc2V0dGluZ3MuZWwsICdjbGljaycsICcuZmMtZXZlbnQnLCAvLyBvbiBib3RoIGZnIGFuZCBiZyBldmVudHNcbiAgICAgICAgdGhpcy5oYW5kbGVTZWdDbGljayk7XG4gICAgfVxufVxuXG4vKlxuVHJpZ2dlcnMgZXZlbnRzIGFuZCBhZGRzL3JlbW92ZXMgY29yZSBjbGFzc05hbWVzIHdoZW4gdGhlIHVzZXIncyBwb2ludGVyXG5lbnRlcnMvbGVhdmVzIGV2ZW50LWVsZW1lbnRzIG9mIGEgY29tcG9uZW50LlxuKi9cbmNsYXNzIEV2ZW50SG92ZXJpbmcgZXh0ZW5kcyBJbnRlcmFjdGlvbiB7XG4gICAgY29uc3RydWN0b3Ioc2V0dGluZ3MpIHtcbiAgICAgICAgc3VwZXIoc2V0dGluZ3MpO1xuICAgICAgICAvLyBmb3Igc2ltdWxhdGluZyBhbiBldmVudE1vdXNlTGVhdmUgd2hlbiB0aGUgZXZlbnQgZWwgaXMgZGVzdHJveWVkIHdoaWxlIG1vdXNlIGlzIG92ZXIgaXRcbiAgICAgICAgdGhpcy5oYW5kbGVFdmVudEVsUmVtb3ZlID0gKGVsKSA9PiB7XG4gICAgICAgICAgICBpZiAoZWwgPT09IHRoaXMuY3VycmVudFNlZ0VsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVTZWdMZWF2ZShudWxsLCB0aGlzLmN1cnJlbnRTZWdFbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuaGFuZGxlU2VnRW50ZXIgPSAoZXYsIHNlZ0VsKSA9PiB7XG4gICAgICAgICAgICBpZiAoZ2V0RWxTZWcoc2VnRWwpKSB7IC8vIFRPRE86IGJldHRlciB3YXkgdG8gbWFrZSBzdXJlIG5vdCBob3ZlcmluZyBvdmVyIG1vcmUrIGxpbmsgb3IgaXRzIHdyYXBwZXJcbiAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRTZWdFbCA9IHNlZ0VsO1xuICAgICAgICAgICAgICAgIHRoaXMudHJpZ2dlckV2ZW50KCdldmVudE1vdXNlRW50ZXInLCBldiwgc2VnRWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB0aGlzLmhhbmRsZVNlZ0xlYXZlID0gKGV2LCBzZWdFbCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuY3VycmVudFNlZ0VsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50U2VnRWwgPSBudWxsO1xuICAgICAgICAgICAgICAgIHRoaXMudHJpZ2dlckV2ZW50KCdldmVudE1vdXNlTGVhdmUnLCBldiwgc2VnRWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB0aGlzLnJlbW92ZUhvdmVyTGlzdGVuZXJzID0gbGlzdGVuVG9Ib3ZlckJ5U2VsZWN0b3Ioc2V0dGluZ3MuZWwsICcuZmMtZXZlbnQnLCAvLyBvbiBib3RoIGZnIGFuZCBiZyBldmVudHNcbiAgICAgICAgdGhpcy5oYW5kbGVTZWdFbnRlciwgdGhpcy5oYW5kbGVTZWdMZWF2ZSk7XG4gICAgfVxuICAgIGRlc3Ryb3koKSB7XG4gICAgICAgIHRoaXMucmVtb3ZlSG92ZXJMaXN0ZW5lcnMoKTtcbiAgICB9XG4gICAgdHJpZ2dlckV2ZW50KHB1YmxpY0V2TmFtZSwgZXYsIHNlZ0VsKSB7XG4gICAgICAgIGxldCB7IGNvbXBvbmVudCB9ID0gdGhpcztcbiAgICAgICAgbGV0IHsgY29udGV4dCB9ID0gY29tcG9uZW50O1xuICAgICAgICBsZXQgc2VnID0gZ2V0RWxTZWcoc2VnRWwpO1xuICAgICAgICBpZiAoIWV2IHx8IGNvbXBvbmVudC5pc1ZhbGlkU2VnRG93bkVsKGV2LnRhcmdldCkpIHtcbiAgICAgICAgICAgIGNvbnRleHQuZW1pdHRlci50cmlnZ2VyKHB1YmxpY0V2TmFtZSwge1xuICAgICAgICAgICAgICAgIGVsOiBzZWdFbCxcbiAgICAgICAgICAgICAgICBldmVudDogbmV3IEV2ZW50SW1wbChjb250ZXh0LCBzZWcuZXZlbnRSYW5nZS5kZWYsIHNlZy5ldmVudFJhbmdlLmluc3RhbmNlKSxcbiAgICAgICAgICAgICAgICBqc0V2ZW50OiBldixcbiAgICAgICAgICAgICAgICB2aWV3OiBjb250ZXh0LnZpZXdBcGksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuY2xhc3MgQ2FsZW5kYXJDb250ZW50IGV4dGVuZHMgUHVyZUNvbXBvbmVudCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuYnVpbGRWaWV3Q29udGV4dCA9IG1lbW9pemUoYnVpbGRWaWV3Q29udGV4dCk7XG4gICAgICAgIHRoaXMuYnVpbGRWaWV3UHJvcFRyYW5zZm9ybWVycyA9IG1lbW9pemUoYnVpbGRWaWV3UHJvcFRyYW5zZm9ybWVycyk7XG4gICAgICAgIHRoaXMuYnVpbGRUb29sYmFyUHJvcHMgPSBtZW1vaXplKGJ1aWxkVG9vbGJhclByb3BzKTtcbiAgICAgICAgdGhpcy5oZWFkZXJSZWYgPSBjcmVhdGVSZWYoKTtcbiAgICAgICAgdGhpcy5mb290ZXJSZWYgPSBjcmVhdGVSZWYoKTtcbiAgICAgICAgdGhpcy5pbnRlcmFjdGlvbnNTdG9yZSA9IHt9O1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgICAgICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgICAgICAgIHZpZXdMYWJlbElkOiBnZXRVbmlxdWVEb21JZCgpLFxuICAgICAgICB9O1xuICAgICAgICAvLyBDb21wb25lbnQgUmVnaXN0cmF0aW9uXG4gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIHRoaXMucmVnaXN0ZXJJbnRlcmFjdGl2ZUNvbXBvbmVudCA9IChjb21wb25lbnQsIHNldHRpbmdzSW5wdXQpID0+IHtcbiAgICAgICAgICAgIGxldCBzZXR0aW5ncyA9IHBhcnNlSW50ZXJhY3Rpb25TZXR0aW5ncyhjb21wb25lbnQsIHNldHRpbmdzSW5wdXQpO1xuICAgICAgICAgICAgbGV0IERFRkFVTFRfSU5URVJBQ1RJT05TID0gW1xuICAgICAgICAgICAgICAgIEV2ZW50Q2xpY2tpbmcsXG4gICAgICAgICAgICAgICAgRXZlbnRIb3ZlcmluZyxcbiAgICAgICAgICAgIF07XG4gICAgICAgICAgICBsZXQgaW50ZXJhY3Rpb25DbGFzc2VzID0gREVGQVVMVF9JTlRFUkFDVElPTlMuY29uY2F0KHRoaXMucHJvcHMucGx1Z2luSG9va3MuY29tcG9uZW50SW50ZXJhY3Rpb25zKTtcbiAgICAgICAgICAgIGxldCBpbnRlcmFjdGlvbnMgPSBpbnRlcmFjdGlvbkNsYXNzZXMubWFwKChUaGVJbnRlcmFjdGlvbkNsYXNzKSA9PiBuZXcgVGhlSW50ZXJhY3Rpb25DbGFzcyhzZXR0aW5ncykpO1xuICAgICAgICAgICAgdGhpcy5pbnRlcmFjdGlvbnNTdG9yZVtjb21wb25lbnQudWlkXSA9IGludGVyYWN0aW9ucztcbiAgICAgICAgICAgIGludGVyYWN0aW9uU2V0dGluZ3NTdG9yZVtjb21wb25lbnQudWlkXSA9IHNldHRpbmdzO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLnVucmVnaXN0ZXJJbnRlcmFjdGl2ZUNvbXBvbmVudCA9IChjb21wb25lbnQpID0+IHtcbiAgICAgICAgICAgIGxldCBsaXN0ZW5lcnMgPSB0aGlzLmludGVyYWN0aW9uc1N0b3JlW2NvbXBvbmVudC51aWRdO1xuICAgICAgICAgICAgaWYgKGxpc3RlbmVycykge1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGxpc3RlbmVyIG9mIGxpc3RlbmVycykge1xuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lci5kZXN0cm95KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmludGVyYWN0aW9uc1N0b3JlW2NvbXBvbmVudC51aWRdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVsZXRlIGludGVyYWN0aW9uU2V0dGluZ3NTdG9yZVtjb21wb25lbnQudWlkXTtcbiAgICAgICAgfTtcbiAgICAgICAgLy8gUmVzaXppbmdcbiAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgdGhpcy5yZXNpemVSdW5uZXIgPSBuZXcgRGVsYXllZFJ1bm5lcigoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnByb3BzLmVtaXR0ZXIudHJpZ2dlcignX3Jlc2l6ZScsIHRydWUpOyAvLyBzaG91bGQgd2luZG93IHJlc2l6ZXMgYmUgY29uc2lkZXJlZCBcImZvcmNlZFwiID9cbiAgICAgICAgICAgIHRoaXMucHJvcHMuZW1pdHRlci50cmlnZ2VyKCd3aW5kb3dSZXNpemUnLCB7IHZpZXc6IHRoaXMucHJvcHMudmlld0FwaSB9KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuaGFuZGxlV2luZG93UmVzaXplID0gKGV2KSA9PiB7XG4gICAgICAgICAgICBsZXQgeyBvcHRpb25zIH0gPSB0aGlzLnByb3BzO1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMuaGFuZGxlV2luZG93UmVzaXplICYmXG4gICAgICAgICAgICAgICAgZXYudGFyZ2V0ID09PSB3aW5kb3cgLy8gYXZvaWQganF1aSBldmVudHNcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIHRoaXMucmVzaXplUnVubmVyLnJlcXVlc3Qob3B0aW9ucy53aW5kb3dSZXNpemVEZWxheSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfVxuICAgIC8qXG4gICAgcmVuZGVycyBJTlNJREUgb2YgYW4gb3V0ZXIgZGl2XG4gICAgKi9cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGxldCB7IHByb3BzIH0gPSB0aGlzO1xuICAgICAgICBsZXQgeyB0b29sYmFyQ29uZmlnLCBvcHRpb25zIH0gPSBwcm9wcztcbiAgICAgICAgbGV0IHZpZXdWR3JvdyA9IGZhbHNlO1xuICAgICAgICBsZXQgdmlld0hlaWdodCA9ICcnO1xuICAgICAgICBsZXQgdmlld0FzcGVjdFJhdGlvO1xuICAgICAgICBpZiAocHJvcHMuaXNIZWlnaHRBdXRvIHx8IHByb3BzLmZvclByaW50KSB7XG4gICAgICAgICAgICB2aWV3SGVpZ2h0ID0gJyc7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAob3B0aW9ucy5oZWlnaHQgIT0gbnVsbCkge1xuICAgICAgICAgICAgdmlld1ZHcm93ID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChvcHRpb25zLmNvbnRlbnRIZWlnaHQgIT0gbnVsbCkge1xuICAgICAgICAgICAgdmlld0hlaWdodCA9IG9wdGlvbnMuY29udGVudEhlaWdodDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZpZXdBc3BlY3RSYXRpbyA9IE1hdGgubWF4KG9wdGlvbnMuYXNwZWN0UmF0aW8sIDAuNSk7IC8vIHByZXZlbnQgZnJvbSBnZXR0aW5nIHRvbyB0YWxsXG4gICAgICAgIH1cbiAgICAgICAgbGV0IHZpZXdDb250ZXh0ID0gdGhpcy5idWlsZFZpZXdDb250ZXh0KHByb3BzLnZpZXdTcGVjLCBwcm9wcy52aWV3QXBpLCBwcm9wcy5vcHRpb25zLCBwcm9wcy5kYXRlUHJvZmlsZUdlbmVyYXRvciwgcHJvcHMuZGF0ZUVudiwgcHJvcHMubm93TWFuYWdlciwgcHJvcHMudGhlbWUsIHByb3BzLnBsdWdpbkhvb2tzLCBwcm9wcy5kaXNwYXRjaCwgcHJvcHMuZ2V0Q3VycmVudERhdGEsIHByb3BzLmVtaXR0ZXIsIHByb3BzLmNhbGVuZGFyQXBpLCB0aGlzLnJlZ2lzdGVySW50ZXJhY3RpdmVDb21wb25lbnQsIHRoaXMudW5yZWdpc3RlckludGVyYWN0aXZlQ29tcG9uZW50KTtcbiAgICAgICAgbGV0IHZpZXdMYWJlbElkID0gKHRvb2xiYXJDb25maWcuaGVhZGVyICYmIHRvb2xiYXJDb25maWcuaGVhZGVyLmhhc1RpdGxlKVxuICAgICAgICAgICAgPyB0aGlzLnN0YXRlLnZpZXdMYWJlbElkXG4gICAgICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIChjcmVhdGVFbGVtZW50KFZpZXdDb250ZXh0VHlwZS5Qcm92aWRlciwgeyB2YWx1ZTogdmlld0NvbnRleHQgfSxcbiAgICAgICAgICAgIGNyZWF0ZUVsZW1lbnQoTm93VGltZXIsIHsgdW5pdDogXCJkYXlcIiB9LCAobm93RGF0ZSkgPT4ge1xuICAgICAgICAgICAgICAgIGxldCB0b29sYmFyUHJvcHMgPSB0aGlzLmJ1aWxkVG9vbGJhclByb3BzKHByb3BzLnZpZXdTcGVjLCBwcm9wcy5kYXRlUHJvZmlsZSwgcHJvcHMuZGF0ZVByb2ZpbGVHZW5lcmF0b3IsIHByb3BzLmN1cnJlbnREYXRlLCBub3dEYXRlLCBwcm9wcy52aWV3VGl0bGUpO1xuICAgICAgICAgICAgICAgIHJldHVybiAoY3JlYXRlRWxlbWVudChGcmFnbWVudCwgbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgdG9vbGJhckNvbmZpZy5oZWFkZXIgJiYgKGNyZWF0ZUVsZW1lbnQoVG9vbGJhciwgT2JqZWN0LmFzc2lnbih7IHJlZjogdGhpcy5oZWFkZXJSZWYsIGV4dHJhQ2xhc3NOYW1lOiBcImZjLWhlYWRlci10b29sYmFyXCIsIG1vZGVsOiB0b29sYmFyQ29uZmlnLmhlYWRlciwgdGl0bGVJZDogdmlld0xhYmVsSWQgfSwgdG9vbGJhclByb3BzKSkpLFxuICAgICAgICAgICAgICAgICAgICBjcmVhdGVFbGVtZW50KFZpZXdIYXJuZXNzLCB7IGxpcXVpZDogdmlld1ZHcm93LCBoZWlnaHQ6IHZpZXdIZWlnaHQsIGFzcGVjdFJhdGlvOiB2aWV3QXNwZWN0UmF0aW8sIGxhYmVsZWRCeUlkOiB2aWV3TGFiZWxJZCB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJWaWV3KHByb3BzKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYnVpbGRBcHBlbmRDb250ZW50KCkpLFxuICAgICAgICAgICAgICAgICAgICB0b29sYmFyQ29uZmlnLmZvb3RlciAmJiAoY3JlYXRlRWxlbWVudChUb29sYmFyLCBPYmplY3QuYXNzaWduKHsgcmVmOiB0aGlzLmZvb3RlclJlZiwgZXh0cmFDbGFzc05hbWU6IFwiZmMtZm9vdGVyLXRvb2xiYXJcIiwgbW9kZWw6IHRvb2xiYXJDb25maWcuZm9vdGVyLCB0aXRsZUlkOiBcIlwiIH0sIHRvb2xiYXJQcm9wcykpKSkpO1xuICAgICAgICAgICAgfSkpKTtcbiAgICB9XG4gICAgY29tcG9uZW50RGlkTW91bnQoKSB7XG4gICAgICAgIGxldCB7IHByb3BzIH0gPSB0aGlzO1xuICAgICAgICB0aGlzLmNhbGVuZGFySW50ZXJhY3Rpb25zID0gcHJvcHMucGx1Z2luSG9va3MuY2FsZW5kYXJJbnRlcmFjdGlvbnNcbiAgICAgICAgICAgIC5tYXAoKENhbGVuZGFySW50ZXJhY3Rpb25DbGFzcykgPT4gbmV3IENhbGVuZGFySW50ZXJhY3Rpb25DbGFzcyhwcm9wcykpO1xuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgdGhpcy5oYW5kbGVXaW5kb3dSZXNpemUpO1xuICAgICAgICBsZXQgeyBwcm9wU2V0SGFuZGxlcnMgfSA9IHByb3BzLnBsdWdpbkhvb2tzO1xuICAgICAgICBmb3IgKGxldCBwcm9wTmFtZSBpbiBwcm9wU2V0SGFuZGxlcnMpIHtcbiAgICAgICAgICAgIHByb3BTZXRIYW5kbGVyc1twcm9wTmFtZV0ocHJvcHNbcHJvcE5hbWVdLCBwcm9wcyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY29tcG9uZW50RGlkVXBkYXRlKHByZXZQcm9wcykge1xuICAgICAgICBsZXQgeyBwcm9wcyB9ID0gdGhpcztcbiAgICAgICAgbGV0IHsgcHJvcFNldEhhbmRsZXJzIH0gPSBwcm9wcy5wbHVnaW5Ib29rcztcbiAgICAgICAgZm9yIChsZXQgcHJvcE5hbWUgaW4gcHJvcFNldEhhbmRsZXJzKSB7XG4gICAgICAgICAgICBpZiAocHJvcHNbcHJvcE5hbWVdICE9PSBwcmV2UHJvcHNbcHJvcE5hbWVdKSB7XG4gICAgICAgICAgICAgICAgcHJvcFNldEhhbmRsZXJzW3Byb3BOYW1lXShwcm9wc1twcm9wTmFtZV0sIHByb3BzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcbiAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIHRoaXMuaGFuZGxlV2luZG93UmVzaXplKTtcbiAgICAgICAgdGhpcy5yZXNpemVSdW5uZXIuY2xlYXIoKTtcbiAgICAgICAgZm9yIChsZXQgaW50ZXJhY3Rpb24gb2YgdGhpcy5jYWxlbmRhckludGVyYWN0aW9ucykge1xuICAgICAgICAgICAgaW50ZXJhY3Rpb24uZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucHJvcHMuZW1pdHRlci50cmlnZ2VyKCdfdW5tb3VudCcpO1xuICAgIH1cbiAgICBidWlsZEFwcGVuZENvbnRlbnQoKSB7XG4gICAgICAgIGxldCB7IHByb3BzIH0gPSB0aGlzO1xuICAgICAgICBsZXQgY2hpbGRyZW4gPSBwcm9wcy5wbHVnaW5Ib29rcy52aWV3Q29udGFpbmVyQXBwZW5kcy5tYXAoKGJ1aWxkQXBwZW5kQ29udGVudCkgPT4gYnVpbGRBcHBlbmRDb250ZW50KHByb3BzKSk7XG4gICAgICAgIHJldHVybiBjcmVhdGVFbGVtZW50KEZyYWdtZW50LCB7fSwgLi4uY2hpbGRyZW4pO1xuICAgIH1cbiAgICByZW5kZXJWaWV3KHByb3BzKSB7XG4gICAgICAgIGxldCB7IHBsdWdpbkhvb2tzIH0gPSBwcm9wcztcbiAgICAgICAgbGV0IHsgdmlld1NwZWMgfSA9IHByb3BzO1xuICAgICAgICBsZXQgdmlld1Byb3BzID0ge1xuICAgICAgICAgICAgZGF0ZVByb2ZpbGU6IHByb3BzLmRhdGVQcm9maWxlLFxuICAgICAgICAgICAgYnVzaW5lc3NIb3VyczogcHJvcHMuYnVzaW5lc3NIb3VycyxcbiAgICAgICAgICAgIGV2ZW50U3RvcmU6IHByb3BzLnJlbmRlcmFibGVFdmVudFN0b3JlLFxuICAgICAgICAgICAgZXZlbnRVaUJhc2VzOiBwcm9wcy5ldmVudFVpQmFzZXMsXG4gICAgICAgICAgICBkYXRlU2VsZWN0aW9uOiBwcm9wcy5kYXRlU2VsZWN0aW9uLFxuICAgICAgICAgICAgZXZlbnRTZWxlY3Rpb246IHByb3BzLmV2ZW50U2VsZWN0aW9uLFxuICAgICAgICAgICAgZXZlbnREcmFnOiBwcm9wcy5ldmVudERyYWcsXG4gICAgICAgICAgICBldmVudFJlc2l6ZTogcHJvcHMuZXZlbnRSZXNpemUsXG4gICAgICAgICAgICBpc0hlaWdodEF1dG86IHByb3BzLmlzSGVpZ2h0QXV0byxcbiAgICAgICAgICAgIGZvclByaW50OiBwcm9wcy5mb3JQcmludCxcbiAgICAgICAgfTtcbiAgICAgICAgbGV0IHRyYW5zZm9ybWVycyA9IHRoaXMuYnVpbGRWaWV3UHJvcFRyYW5zZm9ybWVycyhwbHVnaW5Ib29rcy52aWV3UHJvcHNUcmFuc2Zvcm1lcnMpO1xuICAgICAgICBmb3IgKGxldCB0cmFuc2Zvcm1lciBvZiB0cmFuc2Zvcm1lcnMpIHtcbiAgICAgICAgICAgIE9iamVjdC5hc3NpZ24odmlld1Byb3BzLCB0cmFuc2Zvcm1lci50cmFuc2Zvcm0odmlld1Byb3BzLCBwcm9wcykpO1xuICAgICAgICB9XG4gICAgICAgIGxldCBWaWV3Q29tcG9uZW50ID0gdmlld1NwZWMuY29tcG9uZW50O1xuICAgICAgICByZXR1cm4gKGNyZWF0ZUVsZW1lbnQoVmlld0NvbXBvbmVudCwgT2JqZWN0LmFzc2lnbih7fSwgdmlld1Byb3BzKSkpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGJ1aWxkVG9vbGJhclByb3BzKHZpZXdTcGVjLCBkYXRlUHJvZmlsZSwgZGF0ZVByb2ZpbGVHZW5lcmF0b3IsIGN1cnJlbnREYXRlLCBub3csIHRpdGxlKSB7XG4gICAgLy8gZG9uJ3QgZm9yY2UgYW55IGRhdGUtcHJvZmlsZXMgdG8gdmFsaWQgZGF0ZSBwcm9maWxlcyAodGhlIGBmYWxzZWApIHNvIHRoYXQgd2UgY2FuIHRlbGwgaWYgaXQncyBpbnZhbGlkXG4gICAgbGV0IHRvZGF5SW5mbyA9IGRhdGVQcm9maWxlR2VuZXJhdG9yLmJ1aWxkKG5vdywgdW5kZWZpbmVkLCBmYWxzZSk7IC8vIFRPRE86IG5lZWQgYHVuZGVmaW5lZGAgb3IgZWxzZSBJTkZJTklURSBMT09QIGZvciBzb21lIHJlYXNvblxuICAgIGxldCBwcmV2SW5mbyA9IGRhdGVQcm9maWxlR2VuZXJhdG9yLmJ1aWxkUHJldihkYXRlUHJvZmlsZSwgY3VycmVudERhdGUsIGZhbHNlKTtcbiAgICBsZXQgbmV4dEluZm8gPSBkYXRlUHJvZmlsZUdlbmVyYXRvci5idWlsZE5leHQoZGF0ZVByb2ZpbGUsIGN1cnJlbnREYXRlLCBmYWxzZSk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgdGl0bGUsXG4gICAgICAgIGFjdGl2ZUJ1dHRvbjogdmlld1NwZWMudHlwZSxcbiAgICAgICAgbmF2VW5pdDogdmlld1NwZWMuc2luZ2xlVW5pdCxcbiAgICAgICAgaXNUb2RheUVuYWJsZWQ6IHRvZGF5SW5mby5pc1ZhbGlkICYmICFyYW5nZUNvbnRhaW5zTWFya2VyKGRhdGVQcm9maWxlLmN1cnJlbnRSYW5nZSwgbm93KSxcbiAgICAgICAgaXNQcmV2RW5hYmxlZDogcHJldkluZm8uaXNWYWxpZCxcbiAgICAgICAgaXNOZXh0RW5hYmxlZDogbmV4dEluZm8uaXNWYWxpZCxcbiAgICB9O1xufVxuLy8gUGx1Z2luXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuZnVuY3Rpb24gYnVpbGRWaWV3UHJvcFRyYW5zZm9ybWVycyh0aGVDbGFzc2VzKSB7XG4gICAgcmV0dXJuIHRoZUNsYXNzZXMubWFwKChUaGVDbGFzcykgPT4gbmV3IFRoZUNsYXNzKCkpO1xufVxuXG5jbGFzcyBDYWxlbmRhciBleHRlbmRzIENhbGVuZGFySW1wbCB7XG4gICAgY29uc3RydWN0b3IoZWwsIG9wdGlvbk92ZXJyaWRlcyA9IHt9KSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMuaXNSZW5kZXJpbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5pc1JlbmRlcmVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuY3VycmVudENsYXNzTmFtZXMgPSBbXTtcbiAgICAgICAgdGhpcy5jdXN0b21Db250ZW50UmVuZGVySWQgPSAwO1xuICAgICAgICB0aGlzLmhhbmRsZUFjdGlvbiA9IChhY3Rpb24pID0+IHtcbiAgICAgICAgICAgIC8vIGFjdGlvbnMgd2Uga25vdyB3ZSB3YW50IHRvIHJlbmRlciBpbW1lZGlhdGVseVxuICAgICAgICAgICAgc3dpdGNoIChhY3Rpb24udHlwZSkge1xuICAgICAgICAgICAgICAgIGNhc2UgJ1NFVF9FVkVOVF9EUkFHJzpcbiAgICAgICAgICAgICAgICBjYXNlICdTRVRfRVZFTlRfUkVTSVpFJzpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJSdW5uZXIudHJ5RHJhaW4oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5oYW5kbGVEYXRhID0gKGRhdGEpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudERhdGEgPSBkYXRhO1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJSdW5uZXIucmVxdWVzdChkYXRhLmNhbGVuZGFyT3B0aW9ucy5yZXJlbmRlckRlbGF5KTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5oYW5kbGVSZW5kZXJSZXF1ZXN0ID0gKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuaXNSZW5kZXJpbmcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmlzUmVuZGVyZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGxldCB7IGN1cnJlbnREYXRhIH0gPSB0aGlzO1xuICAgICAgICAgICAgICAgIGZsdXNoU3luYygoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlbmRlcihjcmVhdGVFbGVtZW50KENhbGVuZGFyUm9vdCwgeyBvcHRpb25zOiBjdXJyZW50RGF0YS5jYWxlbmRhck9wdGlvbnMsIHRoZW1lOiBjdXJyZW50RGF0YS50aGVtZSwgZW1pdHRlcjogY3VycmVudERhdGEuZW1pdHRlciB9LCAoY2xhc3NOYW1lcywgaGVpZ2h0LCBpc0hlaWdodEF1dG8sIGZvclByaW50KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldENsYXNzTmFtZXMoY2xhc3NOYW1lcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldEhlaWdodChoZWlnaHQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChjcmVhdGVFbGVtZW50KFJlbmRlcklkLlByb3ZpZGVyLCB7IHZhbHVlOiB0aGlzLmN1c3RvbUNvbnRlbnRSZW5kZXJJZCB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZUVsZW1lbnQoQ2FsZW5kYXJDb250ZW50LCBPYmplY3QuYXNzaWduKHsgaXNIZWlnaHRBdXRvOiBpc0hlaWdodEF1dG8sIGZvclByaW50OiBmb3JQcmludCB9LCBjdXJyZW50RGF0YSkpKSk7XG4gICAgICAgICAgICAgICAgICAgIH0pLCB0aGlzLmVsKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuaXNSZW5kZXJlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuaXNSZW5kZXJlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHJlbmRlcihudWxsLCB0aGlzLmVsKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNldENsYXNzTmFtZXMoW10pO1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0SGVpZ2h0KCcnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgZW5zdXJlRWxIYXNTdHlsZXMoZWwpO1xuICAgICAgICB0aGlzLmVsID0gZWw7XG4gICAgICAgIHRoaXMucmVuZGVyUnVubmVyID0gbmV3IERlbGF5ZWRSdW5uZXIodGhpcy5oYW5kbGVSZW5kZXJSZXF1ZXN0KTtcbiAgICAgICAgbmV3IENhbGVuZGFyRGF0YU1hbmFnZXIoe1xuICAgICAgICAgICAgb3B0aW9uT3ZlcnJpZGVzLFxuICAgICAgICAgICAgY2FsZW5kYXJBcGk6IHRoaXMsXG4gICAgICAgICAgICBvbkFjdGlvbjogdGhpcy5oYW5kbGVBY3Rpb24sXG4gICAgICAgICAgICBvbkRhdGE6IHRoaXMuaGFuZGxlRGF0YSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJlbmRlcigpIHtcbiAgICAgICAgbGV0IHdhc1JlbmRlcmluZyA9IHRoaXMuaXNSZW5kZXJpbmc7XG4gICAgICAgIGlmICghd2FzUmVuZGVyaW5nKSB7XG4gICAgICAgICAgICB0aGlzLmlzUmVuZGVyaW5nID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY3VzdG9tQ29udGVudFJlbmRlcklkICs9IDE7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZW5kZXJSdW5uZXIucmVxdWVzdCgpO1xuICAgICAgICBpZiAod2FzUmVuZGVyaW5nKSB7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZVNpemUoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBkZXN0cm95KCkge1xuICAgICAgICBpZiAodGhpcy5pc1JlbmRlcmluZykge1xuICAgICAgICAgICAgdGhpcy5pc1JlbmRlcmluZyA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJSdW5uZXIucmVxdWVzdCgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHVwZGF0ZVNpemUoKSB7XG4gICAgICAgIGZsdXNoU3luYygoKSA9PiB7XG4gICAgICAgICAgICBzdXBlci51cGRhdGVTaXplKCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBiYXRjaFJlbmRlcmluZyhmdW5jKSB7XG4gICAgICAgIHRoaXMucmVuZGVyUnVubmVyLnBhdXNlKCdiYXRjaFJlbmRlcmluZycpO1xuICAgICAgICBmdW5jKCk7XG4gICAgICAgIHRoaXMucmVuZGVyUnVubmVyLnJlc3VtZSgnYmF0Y2hSZW5kZXJpbmcnKTtcbiAgICB9XG4gICAgcGF1c2VSZW5kZXJpbmcoKSB7XG4gICAgICAgIHRoaXMucmVuZGVyUnVubmVyLnBhdXNlKCdwYXVzZVJlbmRlcmluZycpO1xuICAgIH1cbiAgICByZXN1bWVSZW5kZXJpbmcoKSB7XG4gICAgICAgIHRoaXMucmVuZGVyUnVubmVyLnJlc3VtZSgncGF1c2VSZW5kZXJpbmcnLCB0cnVlKTtcbiAgICB9XG4gICAgcmVzZXRPcHRpb25zKG9wdGlvbk92ZXJyaWRlcywgY2hhbmdlZE9wdGlvbk5hbWVzKSB7XG4gICAgICAgIHRoaXMuY3VycmVudERhdGFNYW5hZ2VyLnJlc2V0T3B0aW9ucyhvcHRpb25PdmVycmlkZXMsIGNoYW5nZWRPcHRpb25OYW1lcyk7XG4gICAgfVxuICAgIHNldENsYXNzTmFtZXMoY2xhc3NOYW1lcykge1xuICAgICAgICBpZiAoIWlzQXJyYXlzRXF1YWwoY2xhc3NOYW1lcywgdGhpcy5jdXJyZW50Q2xhc3NOYW1lcykpIHtcbiAgICAgICAgICAgIGxldCB7IGNsYXNzTGlzdCB9ID0gdGhpcy5lbDtcbiAgICAgICAgICAgIGZvciAobGV0IGNsYXNzTmFtZSBvZiB0aGlzLmN1cnJlbnRDbGFzc05hbWVzKSB7XG4gICAgICAgICAgICAgICAgY2xhc3NMaXN0LnJlbW92ZShjbGFzc05hbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yIChsZXQgY2xhc3NOYW1lIG9mIGNsYXNzTmFtZXMpIHtcbiAgICAgICAgICAgICAgICBjbGFzc0xpc3QuYWRkKGNsYXNzTmFtZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRDbGFzc05hbWVzID0gY2xhc3NOYW1lcztcbiAgICAgICAgfVxuICAgIH1cbiAgICBzZXRIZWlnaHQoaGVpZ2h0KSB7XG4gICAgICAgIGFwcGx5U3R5bGVQcm9wKHRoaXMuZWwsICdoZWlnaHQnLCBoZWlnaHQpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZm9ybWF0RGF0ZShkYXRlSW5wdXQsIG9wdGlvbnMgPSB7fSkge1xuICAgIGxldCBkYXRlRW52ID0gYnVpbGREYXRlRW52KG9wdGlvbnMpO1xuICAgIGxldCBmb3JtYXR0ZXIgPSBjcmVhdGVGb3JtYXR0ZXIob3B0aW9ucyk7XG4gICAgbGV0IGRhdGVNZXRhID0gZGF0ZUVudi5jcmVhdGVNYXJrZXJNZXRhKGRhdGVJbnB1dCk7XG4gICAgaWYgKCFkYXRlTWV0YSkgeyAvLyBUT0RPOiB3YXJuaW5nP1xuICAgICAgICByZXR1cm4gJyc7XG4gICAgfVxuICAgIHJldHVybiBkYXRlRW52LmZvcm1hdChkYXRlTWV0YS5tYXJrZXIsIGZvcm1hdHRlciwge1xuICAgICAgICBmb3JjZWRUem86IGRhdGVNZXRhLmZvcmNlZFR6byxcbiAgICB9KTtcbn1cbmZ1bmN0aW9uIGZvcm1hdFJhbmdlKHN0YXJ0SW5wdXQsIGVuZElucHV0LCBvcHRpb25zKSB7XG4gICAgbGV0IGRhdGVFbnYgPSBidWlsZERhdGVFbnYodHlwZW9mIG9wdGlvbnMgPT09ICdvYmplY3QnICYmIG9wdGlvbnMgPyBvcHRpb25zIDoge30pOyAvLyBwYXNzIGluIGlmIG5vbi1udWxsIG9iamVjdFxuICAgIGxldCBmb3JtYXR0ZXIgPSBjcmVhdGVGb3JtYXR0ZXIob3B0aW9ucyk7XG4gICAgbGV0IHN0YXJ0TWV0YSA9IGRhdGVFbnYuY3JlYXRlTWFya2VyTWV0YShzdGFydElucHV0KTtcbiAgICBsZXQgZW5kTWV0YSA9IGRhdGVFbnYuY3JlYXRlTWFya2VyTWV0YShlbmRJbnB1dCk7XG4gICAgaWYgKCFzdGFydE1ldGEgfHwgIWVuZE1ldGEpIHsgLy8gVE9ETzogd2FybmluZz9cbiAgICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgICByZXR1cm4gZGF0ZUVudi5mb3JtYXRSYW5nZShzdGFydE1ldGEubWFya2VyLCBlbmRNZXRhLm1hcmtlciwgZm9ybWF0dGVyLCB7XG4gICAgICAgIGZvcmNlZFN0YXJ0VHpvOiBzdGFydE1ldGEuZm9yY2VkVHpvLFxuICAgICAgICBmb3JjZWRFbmRUem86IGVuZE1ldGEuZm9yY2VkVHpvLFxuICAgICAgICBpc0VuZEV4Y2x1c2l2ZTogb3B0aW9ucy5pc0VuZEV4Y2x1c2l2ZSxcbiAgICAgICAgZGVmYXVsdFNlcGFyYXRvcjogQkFTRV9PUFRJT05fREVGQVVMVFMuZGVmYXVsdFJhbmdlU2VwYXJhdG9yLFxuICAgIH0pO1xufVxuLy8gVE9ETzogbW9yZSBEUlkgYW5kIG9wdGltaXplZFxuZnVuY3Rpb24gYnVpbGREYXRlRW52KHNldHRpbmdzKSB7XG4gICAgbGV0IGxvY2FsZSA9IGJ1aWxkTG9jYWxlKHNldHRpbmdzLmxvY2FsZSB8fCAnZW4nLCBvcmdhbml6ZVJhd0xvY2FsZXMoW10pLm1hcCk7IC8vIFRPRE86IGRvbid0IGhhcmRjb2RlICdlbicgZXZlcnl3aGVyZVxuICAgIHJldHVybiBuZXcgRGF0ZUVudihPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oeyB0aW1lWm9uZTogQkFTRV9PUFRJT05fREVGQVVMVFMudGltZVpvbmUsIGNhbGVuZGFyU3lzdGVtOiAnZ3JlZ29yeScgfSwgc2V0dGluZ3MpLCB7IGxvY2FsZSB9KSk7XG59XG5cbi8vIEhFTFBFUlNcbi8qXG5pZiBuZXh0RGF5VGhyZXNob2xkIGlzIHNwZWNpZmllZCwgc2xpY2luZyBpcyBkb25lIGluIGFuIGFsbC1kYXkgZmFzaGlvbi5cbnlvdSBjYW4gZ2V0IG5leHREYXlUaHJlc2hvbGQgZnJvbSBjb250ZXh0Lm5leHREYXlUaHJlc2hvbGRcbiovXG5mdW5jdGlvbiBzbGljZUV2ZW50cyhwcm9wcywgYWxsRGF5KSB7XG4gICAgcmV0dXJuIHNsaWNlRXZlbnRTdG9yZShwcm9wcy5ldmVudFN0b3JlLCBwcm9wcy5ldmVudFVpQmFzZXMsIHByb3BzLmRhdGVQcm9maWxlLmFjdGl2ZVJhbmdlLCBhbGxEYXkgPyBwcm9wcy5uZXh0RGF5VGhyZXNob2xkIDogbnVsbCkuZmc7XG59XG5cbmNvbnN0IHZlcnNpb24gPSAnNi4xLjE5JztcblxuZXhwb3J0IHsgQ2FsZW5kYXIsIGNyZWF0ZVBsdWdpbiwgZm9ybWF0RGF0ZSwgZm9ybWF0UmFuZ2UsIGdsb2JhbExvY2FsZXMsIGdsb2JhbFBsdWdpbnMsIHNsaWNlRXZlbnRzLCB2ZXJzaW9uIH07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///112\n\n}");
/***/ }),
/***/ 113:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ $: () => (/* binding */ listenBySelector),\n/* harmony export */ A: () => (/* binding */ memoizeObjArg),\n/* harmony export */ B: () => (/* binding */ BaseComponent),\n/* harmony export */ C: () => (/* binding */ ContentContainer),\n/* harmony export */ D: () => (/* binding */ DelayedRunner),\n/* harmony export */ E: () => (/* binding */ isPropsEqual),\n/* harmony export */ F: () => (/* binding */ Emitter),\n/* harmony export */ G: () => (/* binding */ rangeContainsMarker),\n/* harmony export */ H: () => (/* binding */ createEmptyEventStore),\n/* harmony export */ I: () => (/* binding */ reduceEventStore),\n/* harmony export */ J: () => (/* binding */ rezoneEventStoreDates),\n/* harmony export */ K: () => (/* binding */ mergeRawOptions),\n/* harmony export */ L: () => (/* binding */ BASE_OPTION_REFINERS),\n/* harmony export */ M: () => (/* binding */ CALENDAR_LISTENER_REFINERS),\n/* harmony export */ N: () => (/* binding */ CALENDAR_OPTION_REFINERS),\n/* harmony export */ O: () => (/* binding */ COMPLEX_OPTION_COMPARATORS),\n/* harmony export */ P: () => (/* binding */ VIEW_OPTION_REFINERS),\n/* harmony export */ Q: () => (/* binding */ DateEnv),\n/* harmony export */ R: () => (/* binding */ DateProfileGenerator),\n/* harmony export */ S: () => (/* binding */ createEventUi),\n/* harmony export */ T: () => (/* binding */ Theme),\n/* harmony export */ U: () => (/* binding */ parseBusinessHours),\n/* harmony export */ V: () => (/* binding */ ViewContextType),\n/* harmony export */ W: () => (/* binding */ setRef),\n/* harmony export */ X: () => (/* binding */ Interaction),\n/* harmony export */ Y: () => (/* binding */ getElSeg),\n/* harmony export */ Z: () => (/* binding */ elementClosest),\n/* harmony export */ _: () => (/* binding */ EventImpl),\n/* harmony export */ a: () => (/* binding */ mapHash),\n/* harmony export */ a$: () => (/* binding */ preventDefault),\n/* harmony export */ a0: () => (/* binding */ listenToHoverBySelector),\n/* harmony export */ a1: () => (/* binding */ PureComponent),\n/* harmony export */ a2: () => (/* binding */ buildViewContext),\n/* harmony export */ a3: () => (/* binding */ getUniqueDomId),\n/* harmony export */ a4: () => (/* binding */ parseInteractionSettings),\n/* harmony export */ a5: () => (/* binding */ interactionSettingsStore),\n/* harmony export */ a6: () => (/* binding */ NowTimer),\n/* harmony export */ a7: () => (/* binding */ CalendarImpl),\n/* harmony export */ a8: () => (/* binding */ flushSync),\n/* harmony export */ a9: () => (/* binding */ CalendarRoot),\n/* harmony export */ aA: () => (/* binding */ memoizeArraylike),\n/* harmony export */ aB: () => (/* binding */ memoizeHashlike),\n/* harmony export */ aC: () => (/* binding */ intersectRects),\n/* harmony export */ aD: () => (/* binding */ pointInsideRect),\n/* harmony export */ aE: () => (/* binding */ constrainPoint),\n/* harmony export */ aF: () => (/* binding */ getRectCenter),\n/* harmony export */ aG: () => (/* binding */ diffPoints),\n/* harmony export */ aH: () => (/* binding */ translateRect),\n/* harmony export */ aI: () => (/* binding */ compareObjs),\n/* harmony export */ aJ: () => (/* binding */ collectFromHash),\n/* harmony export */ aK: () => (/* binding */ findElements),\n/* harmony export */ aL: () => (/* binding */ findDirectChildren),\n/* harmony export */ aM: () => (/* binding */ removeElement),\n/* harmony export */ aN: () => (/* binding */ applyStyle),\n/* harmony export */ aO: () => (/* binding */ elementMatches),\n/* harmony export */ aP: () => (/* binding */ getEventTargetViaRoot),\n/* harmony export */ aQ: () => (/* binding */ parseClassNames),\n/* harmony export */ aR: () => (/* binding */ getCanVGrowWithinCell),\n/* harmony export */ aS: () => (/* binding */ mergeEventStores),\n/* harmony export */ aT: () => (/* binding */ getRelevantEvents),\n/* harmony export */ aU: () => (/* binding */ eventTupleToStore),\n/* harmony export */ aV: () => (/* binding */ combineEventUis),\n/* harmony export */ aW: () => (/* binding */ Splitter),\n/* harmony export */ aX: () => (/* binding */ getDayClassNames),\n/* harmony export */ aY: () => (/* binding */ getDateMeta),\n/* harmony export */ aZ: () => (/* binding */ getSlotClassNames),\n/* harmony export */ a_: () => (/* binding */ buildNavLinkAttrs),\n/* harmony export */ aa: () => (/* binding */ RenderId),\n/* harmony export */ ab: () => (/* binding */ ensureElHasStyles),\n/* harmony export */ ac: () => (/* binding */ applyStyleProp),\n/* harmony export */ ad: () => (/* binding */ sliceEventStore),\n/* harmony export */ ae: () => (/* binding */ JsonRequestError),\n/* harmony export */ af: () => (/* binding */ createContext),\n/* harmony export */ ag: () => (/* binding */ refineProps),\n/* harmony export */ ah: () => (/* binding */ createEventInstance),\n/* harmony export */ ai: () => (/* binding */ parseEventDef),\n/* harmony export */ aj: () => (/* binding */ refineEventDef),\n/* harmony export */ ak: () => (/* binding */ padStart),\n/* harmony export */ al: () => (/* binding */ isInt),\n/* harmony export */ am: () => (/* binding */ parseFieldSpecs),\n/* harmony export */ an: () => (/* binding */ compareByFieldSpecs),\n/* harmony export */ ao: () => (/* binding */ flexibleCompare),\n/* harmony export */ ap: () => (/* binding */ preventSelection),\n/* harmony export */ aq: () => (/* binding */ allowSelection),\n/* harmony export */ ar: () => (/* binding */ preventContextMenu),\n/* harmony export */ as: () => (/* binding */ allowContextMenu),\n/* harmony export */ at: () => (/* binding */ compareNumbers),\n/* harmony export */ au: () => (/* binding */ enableCursor),\n/* harmony export */ av: () => (/* binding */ disableCursor),\n/* harmony export */ aw: () => (/* binding */ computeVisibleDayRange),\n/* harmony export */ ax: () => (/* binding */ isMultiDayRange),\n/* harmony export */ ay: () => (/* binding */ diffDates),\n/* harmony export */ az: () => (/* binding */ removeExact),\n/* harmony export */ b: () => (/* binding */ buildViewClassNames),\n/* harmony export */ b$: () => (/* binding */ renderMicroColGroup),\n/* harmony export */ b0: () => (/* binding */ whenTransitionDone),\n/* harmony export */ b1: () => (/* binding */ computeInnerRect),\n/* harmony export */ b2: () => (/* binding */ computeEdges),\n/* harmony export */ b3: () => (/* binding */ getClippingParents),\n/* harmony export */ b4: () => (/* binding */ computeRect),\n/* harmony export */ b5: () => (/* binding */ rangesEqual),\n/* harmony export */ b6: () => (/* binding */ rangesIntersect),\n/* harmony export */ b7: () => (/* binding */ rangeContainsRange),\n/* harmony export */ b8: () => (/* binding */ PositionCache),\n/* harmony export */ b9: () => (/* binding */ ScrollController),\n/* harmony export */ bA: () => (/* binding */ getEntrySpanEnd),\n/* harmony export */ bB: () => (/* binding */ binarySearch),\n/* harmony export */ bC: () => (/* binding */ groupIntersectingEntries),\n/* harmony export */ bD: () => (/* binding */ intersectSpans),\n/* harmony export */ bE: () => (/* binding */ interactionSettingsToStore),\n/* harmony export */ bF: () => (/* binding */ ElementDragging),\n/* harmony export */ bG: () => (/* binding */ config),\n/* harmony export */ bH: () => (/* binding */ parseDragMeta),\n/* harmony export */ bI: () => (/* binding */ DayHeader),\n/* harmony export */ bJ: () => (/* binding */ computeFallbackHeaderFormat),\n/* harmony export */ bK: () => (/* binding */ TableDateCell),\n/* harmony export */ bL: () => (/* binding */ TableDowCell),\n/* harmony export */ bM: () => (/* binding */ DaySeriesModel),\n/* harmony export */ bN: () => (/* binding */ hasBgRendering),\n/* harmony export */ bO: () => (/* binding */ buildSegTimeText),\n/* harmony export */ bP: () => (/* binding */ sortEventSegs),\n/* harmony export */ bQ: () => (/* binding */ getSegMeta),\n/* harmony export */ bR: () => (/* binding */ buildEventRangeKey),\n/* harmony export */ bS: () => (/* binding */ getSegAnchorAttrs),\n/* harmony export */ bT: () => (/* binding */ DayTableModel),\n/* harmony export */ bU: () => (/* binding */ Slicer),\n/* harmony export */ bV: () => (/* binding */ applyMutationToEventStore),\n/* harmony export */ bW: () => (/* binding */ isPropsValid),\n/* harmony export */ bX: () => (/* binding */ isInteractionValid),\n/* harmony export */ bY: () => (/* binding */ isDateSelectionValid),\n/* harmony export */ bZ: () => (/* binding */ SimpleScrollGrid),\n/* harmony export */ b_: () => (/* binding */ hasShrinkWidth),\n/* harmony export */ ba: () => (/* binding */ ElementScrollController),\n/* harmony export */ bb: () => (/* binding */ WindowScrollController),\n/* harmony export */ bc: () => (/* binding */ DateComponent),\n/* harmony export */ bd: () => (/* binding */ isDateSpansEqual),\n/* harmony export */ be: () => (/* binding */ addMs),\n/* harmony export */ bf: () => (/* binding */ addWeeks),\n/* harmony export */ bg: () => (/* binding */ diffWeeks),\n/* harmony export */ bh: () => (/* binding */ diffWholeWeeks),\n/* harmony export */ bi: () => (/* binding */ diffDayAndTime),\n/* harmony export */ bj: () => (/* binding */ diffDays),\n/* harmony export */ bk: () => (/* binding */ isValidDate),\n/* harmony export */ bl: () => (/* binding */ asCleanDays),\n/* harmony export */ bm: () => (/* binding */ multiplyDuration),\n/* harmony export */ bn: () => (/* binding */ addDurations),\n/* harmony export */ bo: () => (/* binding */ asRoughMinutes),\n/* harmony export */ bp: () => (/* binding */ asRoughSeconds),\n/* harmony export */ bq: () => (/* binding */ asRoughMs),\n/* harmony export */ br: () => (/* binding */ wholeDivideDurations),\n/* harmony export */ bs: () => (/* binding */ formatIsoTimeString),\n/* harmony export */ bt: () => (/* binding */ formatDayString),\n/* harmony export */ bu: () => (/* binding */ buildIsoString),\n/* harmony export */ bv: () => (/* binding */ formatIsoMonthStr),\n/* harmony export */ bw: () => (/* binding */ NamedTimeZoneImpl),\n/* harmony export */ bx: () => (/* binding */ parse),\n/* harmony export */ by: () => (/* binding */ SegHierarchy),\n/* harmony export */ bz: () => (/* binding */ buildEntryKey),\n/* harmony export */ c: () => (/* binding */ greatestDurationDenominator),\n/* harmony export */ c0: () => (/* binding */ getScrollGridClassNames),\n/* harmony export */ c1: () => (/* binding */ getSectionClassNames),\n/* harmony export */ c2: () => (/* binding */ getSectionHasLiquidHeight),\n/* harmony export */ c3: () => (/* binding */ getAllowYScrolling),\n/* harmony export */ c4: () => (/* binding */ renderChunkContent),\n/* harmony export */ c5: () => (/* binding */ computeShrinkWidth),\n/* harmony export */ c6: () => (/* binding */ sanitizeShrinkWidth),\n/* harmony export */ c7: () => (/* binding */ isColPropsEqual),\n/* harmony export */ c8: () => (/* binding */ renderScrollShim),\n/* harmony export */ c9: () => (/* binding */ getStickyFooterScrollbar),\n/* harmony export */ ca: () => (/* binding */ getStickyHeaderDates),\n/* harmony export */ cb: () => (/* binding */ Scroller),\n/* harmony export */ cc: () => (/* binding */ getScrollbarWidths),\n/* harmony export */ cd: () => (/* binding */ RefMap),\n/* harmony export */ ce: () => (/* binding */ getIsRtlScrollbarOnLeft),\n/* harmony export */ cf: () => (/* binding */ ScrollResponder),\n/* harmony export */ cg: () => (/* binding */ StandardEvent),\n/* harmony export */ ch: () => (/* binding */ NowIndicatorContainer),\n/* harmony export */ ci: () => (/* binding */ DayCellContainer),\n/* harmony export */ cj: () => (/* binding */ hasCustomDayCellContent),\n/* harmony export */ ck: () => (/* binding */ EventContainer),\n/* harmony export */ cl: () => (/* binding */ renderFill),\n/* harmony export */ cm: () => (/* binding */ BgEvent),\n/* harmony export */ cn: () => (/* binding */ WeekNumberContainer),\n/* harmony export */ co: () => (/* binding */ MoreLinkContainer),\n/* harmony export */ cp: () => (/* binding */ computeEarliestSegStart),\n/* harmony export */ cq: () => (/* binding */ ViewContainer),\n/* harmony export */ cr: () => (/* binding */ triggerDateSelect),\n/* harmony export */ cs: () => (/* binding */ getDefaultEventEnd),\n/* harmony export */ ct: () => (/* binding */ injectStyles),\n/* harmony export */ cu: () => (/* binding */ buildElAttrs),\n/* harmony export */ cv: () => (/* binding */ CustomRenderingStore),\n/* harmony export */ d: () => (/* binding */ createDuration),\n/* harmony export */ e: () => (/* binding */ BASE_OPTION_DEFAULTS),\n/* harmony export */ f: () => (/* binding */ arrayToHash),\n/* harmony export */ g: () => (/* binding */ guid),\n/* harmony export */ h: () => (/* binding */ filterHash),\n/* harmony export */ i: () => (/* binding */ isArraysEqual),\n/* harmony export */ j: () => (/* binding */ buildEventSourceRefiners),\n/* harmony export */ k: () => (/* binding */ formatWithOrdinals),\n/* harmony export */ l: () => (/* binding */ buildRangeApiWithTimeZone),\n/* harmony export */ m: () => (/* binding */ mergeProps),\n/* harmony export */ n: () => (/* binding */ identity),\n/* harmony export */ o: () => (/* binding */ intersectRanges),\n/* harmony export */ p: () => (/* binding */ parseEventSource),\n/* harmony export */ q: () => (/* binding */ startOfDay),\n/* harmony export */ r: () => (/* binding */ requestJson),\n/* harmony export */ s: () => (/* binding */ subtractDurations),\n/* harmony export */ t: () => (/* binding */ addDays),\n/* harmony export */ u: () => (/* binding */ unpromisify),\n/* harmony export */ v: () => (/* binding */ hashValuesToArray),\n/* harmony export */ w: () => (/* binding */ buildEventApis),\n/* harmony export */ x: () => (/* binding */ createFormatter),\n/* harmony export */ y: () => (/* binding */ diffWholeDays),\n/* harmony export */ z: () => (/* binding */ memoize)\n/* harmony export */ });\n/* harmony import */ var preact__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(114);\n/* harmony import */ var preact_compat__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(115);\n\n\n\n\nconst styleTexts = [];\nconst styleEls = new Map();\nfunction injectStyles(styleText) {\n styleTexts.push(styleText);\n styleEls.forEach((styleEl) => {\n appendStylesTo(styleEl, styleText);\n });\n}\nfunction ensureElHasStyles(el) {\n if (el.isConnected && // sometimes true if SSR system simulates DOM\n el.getRootNode // sometimes undefined if SSR system simulates DOM\n ) {\n registerStylesRoot(el.getRootNode());\n }\n}\nfunction registerStylesRoot(rootNode) {\n let styleEl = styleEls.get(rootNode);\n if (!styleEl || !styleEl.isConnected) {\n styleEl = rootNode.querySelector('style[data-fullcalendar]');\n if (!styleEl) {\n styleEl = document.createElement('style');\n styleEl.setAttribute('data-fullcalendar', '');\n const nonce = getNonceValue();\n if (nonce) {\n styleEl.nonce = nonce;\n }\n const parentEl = rootNode === document ? document.head : rootNode;\n const insertBefore = rootNode === document\n ? parentEl.querySelector('script,link[rel=stylesheet],link[as=style],style')\n : parentEl.firstChild;\n parentEl.insertBefore(styleEl, insertBefore);\n }\n styleEls.set(rootNode, styleEl);\n hydrateStylesRoot(styleEl);\n }\n}\nfunction hydrateStylesRoot(styleEl) {\n for (const styleText of styleTexts) {\n appendStylesTo(styleEl, styleText);\n }\n}\nfunction appendStylesTo(styleEl, styleText) {\n const { sheet } = styleEl;\n const ruleCnt = sheet.cssRules.length;\n styleText.split('}').forEach((styleStr, i) => {\n styleStr = styleStr.trim();\n if (styleStr) {\n sheet.insertRule(styleStr + '}', ruleCnt + i);\n }\n });\n}\n// nonce\n// -------------------------------------------------------------------------------------------------\nlet queriedNonceValue;\nfunction getNonceValue() {\n if (queriedNonceValue === undefined) {\n queriedNonceValue = queryNonceValue();\n }\n return queriedNonceValue;\n}\n/*\nTODO: discourage meta tag and instead put nonce attribute on placeholder