diff --git a/.babelrc b/.babelrc deleted file mode 100644 index 75b86286..00000000 --- a/.babelrc +++ /dev/null @@ -1,9 +0,0 @@ -{ - "presets": [ - "es2015-loose", - "stage-1" - ], - "plugins": [ - "transform-flow-comments" - ] -} diff --git a/.browserslistrc b/.browserslistrc new file mode 100644 index 00000000..9dee6464 --- /dev/null +++ b/.browserslistrc @@ -0,0 +1,3 @@ +> 1% +last 2 versions +not ie <= 8 diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 00000000..1c6179f3 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,17 @@ +module.exports = { + root: true, + env: { + node: true + }, + 'extends': [ + 'plugin:vue/essential', + 'eslint:recommended' + ], + rules: { + 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', + 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' + }, + parserOptions: { + parser: 'babel-eslint' + } +} diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..c2925fb8 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: jbaysolutions diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..45af7344 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,35 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Software version (please complete the following information):** + - Browser [e.g. chrome, safari] + - Vue Version [e.g. 2.5.7] + - vue-grid-layout Version: [e.g. 2.3.3] + +**Describe the bug** +A clear and concise description of what the bug is. + +Please use the [CodeSandbox Template](https://codesandbox.io/s/5wy3rz5z1x?module=%2Fsrc%2FShowcaseLayout.js) to demonstrate your bug. It is much easier for us to help you if you do. + + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..2672375c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,22 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +## If you have a feature request, please try to implement it before requesting it.
This is free software and the author is busy with other projects. + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml new file mode 100644 index 00000000..a6d9d440 --- /dev/null +++ b/.github/workflows/build-test.yml @@ -0,0 +1,32 @@ +name: Build and Test + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [10.x, 12.x, 14.x, 15.x] + # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + + steps: + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + - name: Install dependency + run: yarn + - name: Lint check + run: yarn lint + - name: Build + run: yarn build + - name: Unit test + run: yarn test:unit diff --git a/.github/workflows/vuepress-deploy.yml b/.github/workflows/vuepress-deploy.yml new file mode 100644 index 00000000..a936b2b7 --- /dev/null +++ b/.github/workflows/vuepress-deploy.yml @@ -0,0 +1,24 @@ +name: Deploy vuepress website +on: + push: + branches: + - master +jobs: + build-and-deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@master + + - uses: actions/setup-node@v2 + with: + node-version: '16' + + - name: vuepress-deploy + uses: jenkey2011/vuepress-deploy@master + env: + ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }} + TARGET_REPO: jbaysolutions/vue-grid-layout + TARGET_BRANCH: gh-pages + BUILD_SCRIPT: cd website && yarn && yarn build + BUILD_DIR: public diff --git a/.gitignore b/.gitignore index fb39cb11..83dfe282 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,26 @@ .DS_Store node_modules -build -npm-debug.log -.idea \ No newline at end of file +#/dist +dist/demo.html + +# local env files +.env.local +.env.*.local + +# Log files +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw* + +yarn-error.log + +website/docs/dist diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 3b9aa2ba..00000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,67 +0,0 @@ -# Changelog - -## 2.1.11 (Jan 5, 2018) - -* Fixed issue with multiple grids on same vm (#134) (thanks [Suen](https://github.com/sunzongzheng)) -* Fixed issue with layout update on reassignment (#130) (thanks [daizengyu](https://github.com/daizengyu123)) - -## 2.1.10 (Dec 15, 2017) - -* Fixed possible bug related with #119 -* Changed css translate to translate3d (#96) -* Added is-mirrored config, allowing the grid items to be rendered from right to left (horizontal flip) (thanks [kweij](https://github.com/kweij)) -* Added grid updated event for easier integration with vuex (thanks [SergeyKhval](https://github.com/SergeyKhval)) - -## 2.1.9 (Aug 17, 2017) - -* Fixed local module reference to interact.js - -## 2.1.8 (Aug 17, 2017) - -* Fixed #61 and #37 -* Fixed #82 -* Fixed #87 - -## 2.1.7 (Aug 17, 2017) - -* Fixed #59 -* Fixed #83 -* Implemented support for dragAllowFrom and dragIgnoreFrom props on GridItem (thanks [ThePlastic](https://github.com/ThePlastic)) - -## 2.1.6 (Apr 6, 2017) - -* Fixed #43, configurable drag elements ignore on grid item contents (thanks [neithere](https://github.com/neithere)) -* Fix for getLayoutItem, sometimes returns null elements (thanks [pbabey](https://github.com/pbabey)) - -## 2.1.5 (Mar 24, 2017) - -* Really fixed #22 #32, multiple grid instances were not working properly in 2.1.4 -* resizedEvent now also returns item width and height in pixels (implements #34) - - -## 2.1.4 (Mar 20, 2017) - -* Implemented #32, support for multiple grid instances on the same page - -## 2.1.3 (Mar 9, 2017) - -* Fixed #27, props mutation warnings - - -## 2.1.2 (Fev 16, 2017) - -* Implemented #12, buttons on GridItems would trigger drag on mobile -* Implemented #24, listeners removal beforeDestroy (thanks [pbabey](https://github.com/pbabey)) - - -## 2.1.1 (Fev 9, 2017) - -* Implemented #13, dynamic row height update support -* Implemented #23, dynamic enable/disable dragging and resizing support -* Implemented #21, moved and resized events - - -## 2.1.0 (Fev 6, 2017) - -* RTL support (thanks [easteregg](https://github.com/easteregg)) -* Move and resize events (thanks [ThePlastic](https://github.com/ThePlastic)) \ No newline at end of file diff --git a/README-zh_CN.md b/README-zh_CN.md new file mode 100644 index 00000000..e940b464 --- /dev/null +++ b/README-zh_CN.md @@ -0,0 +1,592 @@ +

vue-grid-layout

+ +

+ +

+ +vue-grid-layout是一个类似于[Gridster](http://dsmorse.github.io/gridster.js/)的栅格布局系统, 适用于Vue.js。 **灵感源自于 [React-Grid-Layout](https://github.com/STRML/react-grid-layout)** + +### **当前版本:** 2.4.0 (支持 Vue 2.2+) + +### **Vue 2.1.10 及以下请使用 [2.1.3](https://github.com/jbaysolutions/vue-grid-layout/tree/2.1.3)** +### **Vue 1 请使用 [1.0.3](https://github.com/jbaysolutions/vue-grid-layout/tree/1.0.3)** + +
+ +[**[在线演示](https://jbaysolutions.github.io/vue-grid-layout/examples/01-basic.html) | [更新日志](/CHANGELOG.md)**] + +[English](./README.md) | 简体中文 + + + +#### 成功案例 + +- [DocsFold](https://www.docsfold.com/?utm_source=github&utm_medium=web&utm_campaign=vue-grid-layout) +- [Draxed](https://www.draxed.com/?utm_source=github&utm_medium=web&utm_campaign=vue-grid-layout) +- [Data Providers](https://www.dataproviders.io/?utm_source=github&utm_medium=web&utm_campaign=vue-grid-layout) +- [Cataholic](https://cataholic.glitch.me/) + +*您还知悉其他项目? 请创建一个PR,谢谢!* + +## 特性 + +* 可拖拽 +* 可调整大小 +* 静态部件(不可拖拽、调整大小) +* 拖拽和调整大小时进行边界检查 +* 增减部件时避免重建栅格 +* 可序列化和还原的布局 +* 自动化 RTL 支持 +* 响应式 + + +## 入门指南 + +### 安装 + +#### npm + + # 使用 npm + npm install vue-grid-layout --save + + # 使用 yarn + yarn add vue-grid-layout + + +引入 + +```javascript + import VueGridLayout from 'vue-grid-layout'; +``` + +加入到 Vue 组件 + + ```javascript + export default { + components: { + GridLayout: VueGridLayout.GridLayout, + GridItem: VueGridLayout.GridItem + }, + // ... data, methods, mounted (), etc. + } + +``` + +#### 浏览器 + +在页面中使用已打包好的 [文件](https://github.com/jbaysolutions/vue-grid-layout/releases)。 此时组件已为可用状态。 + +```html + +``` + +### 使用 + +```javascript + var testLayout = [ + {"x":0,"y":0,"w":2,"h":2,"i":"0"}, + {"x":2,"y":0,"w":2,"h":4,"i":"1"}, + {"x":4,"y":0,"w":2,"h":5,"i":"2"}, + {"x":6,"y":0,"w":2,"h":3,"i":"3"}, + {"x":8,"y":0,"w":2,"h":3,"i":"4"}, + {"x":10,"y":0,"w":2,"h":3,"i":"5"}, + {"x":0,"y":5,"w":2,"h":5,"i":"6"}, + {"x":2,"y":5,"w":2,"h":5,"i":"7"}, + {"x":4,"y":5,"w":2,"h":5,"i":"8"}, + {"x":6,"y":3,"w":2,"h":4,"i":"9"}, + {"x":8,"y":4,"w":2,"h":4,"i":"10"}, + {"x":10,"y":4,"w":2,"h":4,"i":"11"}, + {"x":0,"y":10,"w":2,"h":5,"i":"12"}, + {"x":2,"y":10,"w":2,"h":5,"i":"13"}, + {"x":4,"y":8,"w":2,"h":4,"i":"14"}, + {"x":6,"y":8,"w":2,"h":4,"i":"15"}, + {"x":8,"y":10,"w":2,"h":5,"i":"16"}, + {"x":10,"y":4,"w":2,"h":2,"i":"17"}, + {"x":0,"y":9,"w":2,"h":3,"i":"18"}, + {"x":2,"y":6,"w":2,"h":2,"i":"19"} + ]; + + new Vue({ + el: '#app', + data: { + layout: testLayout, + }, + }); +``` + + +```html + + + + + {{item.i}} + + +``` + + +### 文档 + +#### 属性 + +##### GridLayout + +* **layout** + + * type: `Array` + * required: `true` + + 数据源。值必须为 `Array`,其数据项为 `Object`。 每条数据项必须有 `i`, `x`, `y`, `w` 和 `h` 属性。 请参考下面的 `GridItem`。 + +* **responsiveLayouts** + + * type: `Object` + * required: `false` + * default: `{}` + + 如果 `responsive` 设置为 `true`,该配置将作为栅格中每个断点的初始布局。键值是断点名称,每项的值都是类似 `layout` 属性定义的数据结构,值必须为 `Array`,其数据项为 `Object`。例如: `{lg: [layout items], md: [layout items]}`。需要注意的是,在创建栅格布局后设置该属性无效。 + +* **colNum** + + * type: `Number` + * required: `false` + * default: `12` + + 定义栅格系统的列数,其值需为自然数。 + +* **rowHeight** + + * type: `Number` + * required: `false` + * default: `150` + + 每行的高度,单位像素。 + +* **maxRows** + + * type: `Number` + * required: `false` + * default: `Infinity` + + 定义最大行数。 + +* **margin** + + * type: `Array` + * required: `false` + * default: `[10, 10]` + + 定义栅格中的元素边距。 + + 值必须是包含两个 `Number`的数组,数组中第一个元素表示水平边距,第二个表示垂直边距,单位为像素。 + +* **isDraggable** + + * type: `Boolean` + * required: `false` + * default: `true` + + 标识栅格中的元素是否可拖拽。 + +* **isResizable** + + * type: `Boolean` + * required: `false` + * default: `true` + + 标识栅格中的元素是否可调整大小。 + +* **isMirrored** + + * type: `Boolean` + * required: `false` + * default: `false` + + 标识栅格中的元素是否可镜像反转。 + +* **autoSize** + + * type: `Boolean` + * required: `false` + * default: `true` + + 标识容器是否自动调整大小。 + +* **verticalCompact** + + * type: `Boolean` + * required: `false` + * default: `true` + + 标识布局是否垂直压缩。 + +* **useCssTransforms** + + * type: `Boolean` + * required: `false` + * default: `true` + + 标识是否使用CSS属性 `transition-property: transform;`。 + +* **responsive** + + * type: `Boolean` + * required: `false` + * default: `false` + + 标识布局是否为响应式。 + +* **breakpoints** + + * type: `Object` + * required: `false` + * default: { lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 } + + 为响应式布局设置断点,其中参数代表不同设备的宽度:lg(large),md(medium),sm(small),xs(extra small)。 + +* **cols** + + * type: `Object` + * required: `false` + * default: { lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 } + + 设置每个断点对应的列数。 + +* **useStyleCursor** + + * type: `Boolean` + * required: `false` + * default: `true` + + 标识是否使用动态鼠标指针样式。当拖动出现卡顿时,将此值设为 `false`也许可以缓解布局问题。 + + * **preventCollision** + + * type: `Boolean` + * default: `false` + + 值设置为ture时,栅格只能拖动至空白处。 + +##### GridItem + +* **i** + + * type: `String` + * required: `true` + + 栅格中元素的ID。 + +* **x** + + * type: `Number` + * required: `true` + + 标识栅格元素位于第几列,需为自然数。 + +* **y** + + * type: `Number` + * required: `true` + + 标识栅格元素位于第几行,需为自然数。 + +* **w** + + * type: `Number` + * required: `true` + + 标识栅格元素的初始宽度,值为`colWidth`的倍数。 + +* **h** + + * type: `Number` + * required: `true` + + 标识栅格元素的初始高度,值为`rowHeight`的倍数。 + +* **minW** + + * type: `Number` + * required: `false` + * default: `1` + + 栅格元素的最小宽度,值为`colWidth`的倍数。 + + 如果`w`小于`minW`,则`minW`的值会被`w`覆盖。 + +* **minH** + + * type: `Number` + * required: `false` + * default: `1` + + 栅格元素的最小高度,值为`rowHeight`的倍数。 + + 如果`h`小于`minH`,则`minH`的值会被`h`覆盖。 + +* **maxW** + + * type: `Number` + * required: `false` + * default: `Infinity` + + 栅格元素的最大宽度,值为`colWidth`的倍数。 + + 如果`w`大于`maxW`,则`maxW`的值会被`w`覆盖。 + +* **maxH** + + * type: `Number` + * required: `false` + * default: `Infinity` + + 栅格元素的最大高度,值为`rowHeight`的倍数。 + + 如果`h`大于`maxH`,则`maxH`的值会被`h`覆盖。 + +* **isDraggable** + + * type: `Boolean` + * required: `false` + * default: `null` + + 标识栅格元素是否可拖拽。如果值为`null`则取决于父容器。 + +* **isResizable** + + * type: `Boolean` + * required: `false` + * default: `null` + + 标识栅格元素是否可调整大小。如果值为`null`则取决于父容器。 + +* **static** + + * type: `Boolean` + * required: `false` + * default: `false` + + 标识栅格元素是否为静态的(无法拖拽、调整大小或被其他元素移动)。 + +* **dragIgnoreFrom** + + * type: `String` + * required: `false` + * default: `'a, button'` + + 标识栅格元素中哪些子元素无法触发拖拽事件,值为`css-like`选择器。 + + 请参考 [interact.js docs](http://interactjs.io/docs/#ignorable-selectors)中的`ignoreFrom`。 + +* **dragAllowFrom** + + * type: `String` + * required: `false` + * default: `null` + + 标识栅格元素中哪些子元素可以触发拖拽事件,值为`css-like`选择器。 + + 如果值为`null`则表示所有子元素(`dragIgnoreFrom`的除外)。 + + 请参考 [interact.js docs](http://interactjs.io/docs/#ignorable-selectors)中的`allowFrom`。 + +* **resizeIgnoreFrom** + + * type: `String` + * required: `false` + * default: `'a, button'` + + 标识栅格元素中哪些子元素无法触发调整大小的事件,值为`css-like`选择器。 + + 请参考 [interact.js docs](http://interactjs.io/docs/#ignorable-selectors)中的`ignoreFrom`。 + + + +#### 事件 + +每一个栅格元素`grid-item`上都可以添加监听器,用于监听移动和调整大小事件,这样父级Vue对象就可以收到通知。 + + [示例](https://jbaysolutions.github.io/vue-grid-layout/examples/02-events.html) + +````html + + + + + {{item.i}} + + +```` + +* **layoutCreatedEvent** + + 对应Vue生命周期的`created` + +```javascript + layoutCreatedEvent: function(newLayout){ + console.log("Created layout: ", newLayout) + } +``` + +* **layoutBeforeMountEvent** + + 对应Vue生命周期的`beforeMount` + +```javascript + layoutBeforeMountEvent: function(newLayout){ + console.log("beforeMount layout: ", newLayout) + } +``` + +* **layoutMountedEvent** + + 对应Vue生命周期的`mounted` + +```javascript + layoutMountedEvent: function(newLayout){ + console.log("Mounted layout: ", newLayout) + } +``` + +* **layoutReadyEvent** + + 当完成mount中的所有操作时生成的事件 + +```javascript + layoutReadyEvent: function(newLayout){ + console.log("Ready layout: ", newLayout) + } +``` + +* **layoutUpdatedEvent** + + 更新事件(布局更新或栅格元素的位置重新计算) + +```javascript + layoutUpdatedEvent: function(newLayout){ + console.log("Updated layout: ", newLayout) + } +``` + +* **moveEvent** + + 移动时的事件 + +```javascript + moveEvent: function(i, newX, newY){ + console.log("MOVE i=" + i + ", X=" + newX + ", Y=" + newY); + }, +``` + +* **resizeEvent** + + 调整大小时的事件 + +```javascript + resizeEvent: function(i, newH, newW, newHPx, newWPx){ + console.log("RESIZE i=" + i + ", H=" + newH + ", W=" + newW + ", H(px)=" + newHPx + ", W(px)=" + newWPx); + }, +``` + +* **movedEvent** + + 移动后的事件 + +```javascript + movedEvent: function(i, newX, newY){ + console.log("MOVED i=" + i + ", X=" + newX + ", Y=" + newY); + }, +``` + +* **resizedEvent** + + 调整大小后的事件 + +```javascript + /** + * + * @param i the item id/index + * @param newH new height in grid rows + * @param newW new width in grid columns + * @param newHPx new height in pixels + * @param newWPx new width in pixels + * + */ + resizedEvent: function(i, newH, newW, newHPx, newWPx){ + console.log("RESIZED i=" + i + ", H=" + newH + ", W=" + newW + ", H(px)=" + newHPx + ", W(px)=" + newWPx); + }, +``` + + +## 如何贡献 + +请提交issue或PR。 + + +## 待办事项 + +- [x] 基础栅格布局 +- [x] 响应式 +- [x] 可拖拽的栅格元素 +- [x] 可调整大小的栅格元素 +- [x] 静态元素 +- [x] 每个元素的Min/max w/h diff --git a/README.md b/README.md index a0ed850a..540b2231 100644 --- a/README.md +++ b/README.md @@ -1,484 +1,60 @@ -# vue-grid-layout - -vue-grid-layout is a grid layout system, like [Gridster](http://dsmorse.github.io/gridster.js/), for Vue.js. **Heavily inspired in [React-Grid-Layout](https://github.com/STRML/react-grid-layout)** - -### **Current version:** 2.1.11 (Supports Vue 2.2+) - -### **For Vue 2.1.10 and below use version [2.1.3](https://github.com/jbaysolutions/vue-grid-layout/tree/2.1.3)** -### **For Vue 1 use version [1.0.3](https://github.com/jbaysolutions/vue-grid-layout/tree/1.0.3)** - -
- -[**[Demo](https://jbaysolutions.github.io/vue-grid-layout/examples/01-basic.html) | [Changelog](/CHANGELOG.md)**] - - - -#### Projects using vue-grid-layout - -- [Draxed](https://www.draxed.com/?utm_source=github&utm_medium=web&utm_campaign=vue-grid-layout) - -*Know of others? Create a PR to let me know!* +

Vue Grid Layout

+ +

vue-grid-layout

+ +

+ + + + + + + + +

+

+Documentation Website +

+ +## What is Vue Grid Layout? + +vue-grid-layout is a grid layout system, like [Gridster](http://dsmorse.github.io/gridster.js/), for Vue.js. **Heavily inspired by [React-Grid-Layout](https://github.com/STRML/react-grid-layout)** ## Features * Draggable widgets * Resizable widgets +* Static widgets * Bounds checking for dragging and resizing * Widgets may be added or removed without rebuilding grid * Layout can be serialized and restored -* Automatic RTL support - - -## Getting Started - -### Installation - -Install the vue-grid-layout [package](https://www.npmjs.org/package/vue-grid-layout) package using [npm](https://www.npmjs.com/): - - npm install vue-grid-layout - - -### Usage - - npm install vue-grid-layout - -or include the script in your html (download from [releases](https://github.com/jbaysolutions/vue-grid-layout/releases)): - -```html - -```` - -```javascript - - var testLayout = [ - {"x":0,"y":0,"w":2,"h":2,"i":"0"}, - {"x":2,"y":0,"w":2,"h":4,"i":"1"}, - {"x":4,"y":0,"w":2,"h":5,"i":"2"}, - {"x":6,"y":0,"w":2,"h":3,"i":"3"}, - {"x":8,"y":0,"w":2,"h":3,"i":"4"}, - {"x":10,"y":0,"w":2,"h":3,"i":"5"}, - {"x":0,"y":5,"w":2,"h":5,"i":"6"}, - {"x":2,"y":5,"w":2,"h":5,"i":"7"}, - {"x":4,"y":5,"w":2,"h":5,"i":"8"}, - {"x":6,"y":4,"w":2,"h":4,"i":"9"}, - {"x":8,"y":4,"w":2,"h":4,"i":"10"}, - {"x":10,"y":4,"w":2,"h":4,"i":"11"}, - {"x":0,"y":10,"w":2,"h":5,"i":"12"}, - {"x":2,"y":10,"w":2,"h":5,"i":"13"}, - {"x":4,"y":8,"w":2,"h":4,"i":"14"}, - {"x":6,"y":8,"w":2,"h":4,"i":"15"}, - {"x":8,"y":10,"w":2,"h":5,"i":"16"}, - {"x":10,"y":4,"w":2,"h":2,"i":"17"}, - {"x":0,"y":9,"w":2,"h":3,"i":"18"}, - {"x":2,"y":6,"w":2,"h":2,"i":"19"} - ]; - - var GridLayout = VueGridLayout.GridLayout; - var GridItem = VueGridLayout.GridItem; - - new Vue({ - el: '#app', - components: { - GridLayout, - GridItem, - }, - data: { - layout: testLayout, - }, - }); -```` - - -````html - - - - - {{item.i}} - - -```` - - -### Documentation - -#### Properties - -##### GridLayout - -* **layout** - - * type: `Array` - * required: `true` - - This is the initial layout of the grid. - - The value must be an `Array` of `Object` items. Each item must have `i`, `x`, `y`, `w` and `h` proprties. Please refer to `GridItem` documentation below for more informations. - -* **colNum** - - * type: `Number` - * required: `false` - * default: `12` - - Says how many columns the grid has. - - The value should be a _natural number_. - -* **rowHeight** - - * type: `Number` - * required: `false` - * default: `150` - - Says what is a height of a single row in pixels. - -* **maxRows** - - * type: `Number` - * required: `false` - * default: `Infinity` - - Says what is a maximal number of rows in the grid. - -* **margin** - - * type: `Array` - * required: `false` - * default: `[10, 10]` - - Says what are the margins of elements inside the grid. - - The value must be a two-element `Array` of `Number`. Each value is expressed in pixels. The first element is a margin horizontally, the second element is a vertical margin. - -* **isDraggable** - - * type: `Boolean` - * required: `false` - * default: `true` - - Says if the grids items are draggable. - -* **isResizable** - - * type: `Boolean` - * required: `false` - * default: `true` - - Says if the grids items are resizable. - -* **isMirrored** - - * type: `Boolean` - * required: `false` - * default: `false` - - Says if the RTL/LTR should be reversed. - -* **autoSize** - - * type: `Boolean` - * required: `false` - * default: `true` - - Says if the container height should swells and contracts to fit contents. - -* **verticalCompact** - - * type: `Boolean` - * required: `false` - * default: `true` - - Says if the layout should be compact vertically. - -* **useCssTransforms** - - * type: `Boolean` - * required: `false` - * default: `true` - - Says if the CSS `transition-property: transform;` should be used. - - - -##### GridItem - -* **i** - - * type: `String` - * required: `true` - - This is the unique identifier of the item. +* Automatic RTL support (resizing not working with RTL on 2.2.0) +* Responsive -* **x** - - * type: `Number` - * required: `true` +## **Current version:** 2.4.0 (Supports Vue 2.2+) - Says what is a initial horizontal position of the item (in which column it should be placed). +#### **For legacy browsers**, like IE11, use version [2.3.12-legacy](https://github.com/jbaysolutions/vue-grid-layout/tree/legacy) +#### **For Vue 2.1.10 and below use version [2.1.3](https://github.com/jbaysolutions/vue-grid-layout/tree/2.1.3)** +#### **For Vue 1 use version [1.0.3](https://github.com/jbaysolutions/vue-grid-layout/tree/1.0.3)** - The value must be a _whole number_. +## Documentation -* **y** - - * type: `Number` - * required: `true` +Check out the Documentation Website - Says what is a initial vertical position of the item (in which row it should be placed). - - The value must be a _whole number_. - -* **w** - - * type: `Number` - * required: `true` - - Says what is a initial width of the item. - - The value is a number that is multiplied by `colWidth`. - -* **h** - - * type: `Number` - * required: `true` - - Says what is a initial height of the item. - - The value is a number that is multiplied by `rowHeight`. - -* **minW** - - * type: `Number` - * required: `false` - * default: `1` - - Says what is a minimal width of the item. If `w` will be smaller then `minW` then `w` will be set to `minW`. - - The value is a number that is multiplied by `colWidth`. - -* **minH** - - * type: `Number` - * required: `false` - * default: `1` - - Says what is a minimal hieght of the item. If `h` will be smaller then `minH` then `h` will be set to `minH`. - - The value is a number that is multiplied by `rowHeight`. - -* **maxW** - - * type: `Number` - * required: `false` - * default: `Infinity` - - Says what is a maximal width of the item. If `w` will be bigger then `maxW` then `w` will be set to `maxW`. - - The value is a number that is multiplied by `colWidth`. - -* **maxH** - - * type: `Number` - * required: `false` - * default: `Infinity` - - Says what is a maximal height of the item. If `h` will be bigger then `maxH` then `h` will be set to `maxH`. - - The value is a number that is multiplied by `rowHeight` - -* **isDraggable** - - * type: `Boolean` - * required: `false` - * default: `null` - - Says if item is draggable. - - If default value is `null` then it's inherited from parent. - -* **isResizable** - - * type: `Boolean` - * required: `false` - * default: `null` - - Says if item is resizable. - - If default value is `null` then it's inherited from parent. - -* **dragIgnoreFrom** - - * type: `String` - * required: `false` - * default: `'a, button'` - - Says which elements of the item shouldn't trigger drag event of the item. - - The value is `css-like` selector string. - - For more info please refer to `ignoreFrom` in [interact.js docs](http://interactjs.io/docs/#ignorable-selectors). - -* **dragAllowFrom** - - * type: `String` - * required: `false` - * default: `null` - - Says which elements of the item should trigger drag event of the item. - - The value is `css-like` selector string. - - If `null` then one can drag by any (excluding `dragIgnoreFrom`) element of the item. - - For more info please refer to `allowFrom` in [interact.js docs](http://interactjs.io/docs/#ignorable-selectors). - -* **resizeIgnoreFrom** - - * type: `String` - * required: `false` - * default: `'a, button'` - - Says which elements of the item shouldn't trigger resize event of the item. - - The value is `css-like` selector string. - - For more info please refer to `ignoreFrom` in [interact.js docs](http://interactjs.io/docs/#ignorable-selectors). - - - -#### Events - -Move and resize event listeners can be added to each grid-item, so that the parent Vue can be notified when a grid element is being moved or resized. -Moved and resized event listeners can be added, if the only notification needed is when an item is finished moving or resizing. - -Working example [here](https://jbaysolutions.github.io/vue-grid-layout/examples/02-events.html) - -````html - - - - - {{item.i}} - - -```` - -* **layoutUpdatedEvent** - - Layout updated event - - Every time the layout has finished updating and positions of all grid-items are recalculated - -```javascript - layoutUpdatedEvent: function(newLayout){ - console.log("Updated layout: ", newLayout) - } -``` - -* **moveEvent** - - Move event - - Every time an item is being moved and changes position - -```javascript - moveEvent: function(i, newX, newY){ - console.log("MOVE i=" + i + ", X=" + newX + ", Y=" + newY); - }, -``` - -* **resizeEvent** - - Resize event - - Every time an item is being resized and changes size - -```javascript - resizeEvent: function(i, newH, newW){ - console.log("RESIZE i=" + i + ", H=" + newH + ", W=" + newW); - }, -``` - -* **movedEvent** - - Moved event - - Every time an item is finished being moved and changes position - -```javascript - movedEvent: function(i, newX, newY){ - console.log("MOVED i=" + i + ", X=" + newX + ", Y=" + newY); - }, -``` + -* **resizedEvent** +#### Projects using vue-grid-layout - Resized event +- [DocsFold](https://www.docsfold.com/?utm_source=github&utm_medium=web&utm_campaign=vue-grid-layout) +- [Draxed](https://www.draxed.com/?utm_source=github&utm_medium=web&utm_campaign=vue-grid-layout) +- [Data Providers](https://www.dataproviders.io/?utm_source=github&utm_medium=web&utm_campaign=vue-grid-layout) +- [Cataholic](https://cataholic.glitch.me/) - Every time an item is finished being resized and changes size - -```javascript - /** - * - * @param i the item id/index - * @param newH new height in grid rows - * @param newW new width in grid columns - * @param newHPx new height in pixels - * @param newWPx new width in pixels - * - */ - resizedEvent: function(i, newH, newW, newHPx, newWPx){ - console.log("RESIZED i=" + i + ", H=" + newH + ", W=" + newW + ", H(px)=" + newHPx + ", W(px)=" + newWPx); - }, -``` +*Know of others? Create a PR to let me know!* ## Contribute @@ -486,11 +62,4 @@ Working example [here](https://jbaysolutions.github.io/vue-grid-layout/examples/ If you have a feature request, please add it as an issue or make a pull request. -## TODO List - -- [x] Basic grid layout -- [ ] Responsive -- [x] Draggable grid items -- [x] Resizable grid items -- [ ] Static elements -- [x] Min/max w/h per item +Developed by JBay Solutions diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 00000000..4fc4adba --- /dev/null +++ b/babel.config.js @@ -0,0 +1,9 @@ +module.exports = { + presets: [ + '@vue/app', + '@babel/preset-env' + ], + "plugins": [ + "transform-flow-comments" + ] +} diff --git a/dist/vue-grid-layout.common.js b/dist/vue-grid-layout.common.js new file mode 100644 index 00000000..39ae33d2 --- /dev/null +++ b/dist/vue-grid-layout.common.js @@ -0,0 +1,14135 @@ +/*! vue-grid-layout - 2.4.0 | (c) 2015, 2022 Gustavo Santos (JBay Solutions) (http://www.jbaysolutions.com) | https://github.com/jbaysolutions/vue-grid-layout */ +module.exports = +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); +/******/ } +/******/ }; +/******/ +/******/ // define __esModule on exports +/******/ __webpack_require__.r = function(exports) { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ +/******/ // create a fake namespace object +/******/ // mode & 1: value is a module id, require it +/******/ // mode & 2: merge all properties of value into the ns +/******/ // mode & 4: return value when already ns object +/******/ // mode & 8|1: behave like require +/******/ __webpack_require__.t = function(value, mode) { +/******/ if(mode & 1) value = __webpack_require__(value); +/******/ if(mode & 8) return value; +/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; +/******/ var ns = Object.create(null); +/******/ __webpack_require__.r(ns); +/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); +/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); +/******/ return ns; +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = "fb15"); +/******/ }) +/************************************************************************/ +/******/ ({ + +/***/ "01f9": +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var LIBRARY = __webpack_require__("2d00"); +var $export = __webpack_require__("5ca1"); +var redefine = __webpack_require__("2aba"); +var hide = __webpack_require__("32e9"); +var Iterators = __webpack_require__("84f2"); +var $iterCreate = __webpack_require__("41a0"); +var setToStringTag = __webpack_require__("7f20"); +var getPrototypeOf = __webpack_require__("38fd"); +var ITERATOR = __webpack_require__("2b4c")('iterator'); +var BUGGY = !([].keys && 'next' in [].keys()); // Safari has buggy iterators w/o `next` +var FF_ITERATOR = '@@iterator'; +var KEYS = 'keys'; +var VALUES = 'values'; + +var returnThis = function () { return this; }; + +module.exports = function (Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED) { + $iterCreate(Constructor, NAME, next); + var getMethod = function (kind) { + if (!BUGGY && kind in proto) return proto[kind]; + switch (kind) { + case KEYS: return function keys() { return new Constructor(this, kind); }; + case VALUES: return function values() { return new Constructor(this, kind); }; + } return function entries() { return new Constructor(this, kind); }; + }; + var TAG = NAME + ' Iterator'; + var DEF_VALUES = DEFAULT == VALUES; + var VALUES_BUG = false; + var proto = Base.prototype; + var $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT]; + var $default = $native || getMethod(DEFAULT); + var $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined; + var $anyNative = NAME == 'Array' ? proto.entries || $native : $native; + var methods, key, IteratorPrototype; + // Fix native + if ($anyNative) { + IteratorPrototype = getPrototypeOf($anyNative.call(new Base())); + if (IteratorPrototype !== Object.prototype && IteratorPrototype.next) { + // Set @@toStringTag to native iterators + setToStringTag(IteratorPrototype, TAG, true); + // fix for some old engines + if (!LIBRARY && typeof IteratorPrototype[ITERATOR] != 'function') hide(IteratorPrototype, ITERATOR, returnThis); + } + } + // fix Array#{values, @@iterator}.name in V8 / FF + if (DEF_VALUES && $native && $native.name !== VALUES) { + VALUES_BUG = true; + $default = function values() { return $native.call(this); }; + } + // Define iterator + if ((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])) { + hide(proto, ITERATOR, $default); + } + // Plug for library + Iterators[NAME] = $default; + Iterators[TAG] = returnThis; + if (DEFAULT) { + methods = { + values: DEF_VALUES ? $default : getMethod(VALUES), + keys: IS_SET ? $default : getMethod(KEYS), + entries: $entries + }; + if (FORCED) for (key in methods) { + if (!(key in proto)) redefine(proto, key, methods[key]); + } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods); + } + return methods; +}; + + +/***/ }), + +/***/ "02f4": +/***/ (function(module, exports, __webpack_require__) { + +var toInteger = __webpack_require__("4588"); +var defined = __webpack_require__("be13"); +// true -> String#at +// false -> String#codePointAt +module.exports = function (TO_STRING) { + return function (that, pos) { + var s = String(defined(that)); + var i = toInteger(pos); + var l = s.length; + var a, b; + if (i < 0 || i >= l) return TO_STRING ? '' : undefined; + a = s.charCodeAt(i); + return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff + ? TO_STRING ? s.charAt(i) : a + : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000; + }; +}; + + +/***/ }), + +/***/ "0390": +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var at = __webpack_require__("02f4")(true); + + // `AdvanceStringIndex` abstract operation +// https://tc39.github.io/ecma262/#sec-advancestringindex +module.exports = function (S, index, unicode) { + return index + (unicode ? at(S, index).length : 1); +}; + + +/***/ }), + +/***/ "0bfb": +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// 21.2.5.3 get RegExp.prototype.flags +var anObject = __webpack_require__("cb7c"); +module.exports = function () { + var that = anObject(this); + var result = ''; + if (that.global) result += 'g'; + if (that.ignoreCase) result += 'i'; + if (that.multiline) result += 'm'; + if (that.unicode) result += 'u'; + if (that.sticky) result += 'y'; + return result; +}; + + +/***/ }), + +/***/ "0d58": +/***/ (function(module, exports, __webpack_require__) { + +// 19.1.2.14 / 15.2.3.14 Object.keys(O) +var $keys = __webpack_require__("ce10"); +var enumBugKeys = __webpack_require__("e11e"); + +module.exports = Object.keys || function keys(O) { + return $keys(O, enumBugKeys); +}; + + +/***/ }), + +/***/ "1156": +/***/ (function(module, exports, __webpack_require__) { + +// style-loader: Adds some css to the DOM by adding a \r\n\r\n","import mod from \"-!../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./GridLayout.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./GridLayout.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./GridLayout.vue?vue&type=template&id=361da5e4&\"\nimport script from \"./GridLayout.vue?vue&type=script&lang=js&\"\nexport * from \"./GridLayout.vue?vue&type=script&lang=js&\"\nimport style0 from \"./GridLayout.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","// 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O)\nvar has = require('./_has');\nvar toObject = require('./_to-object');\nvar IE_PROTO = require('./_shared-key')('IE_PROTO');\nvar ObjectProto = Object.prototype;\n\nmodule.exports = Object.getPrototypeOf || function (O) {\n O = toObject(O);\n if (has(O, IE_PROTO)) return O[IE_PROTO];\n if (typeof O.constructor == 'function' && O instanceof O.constructor) {\n return O.constructor.prototype;\n } return O instanceof Object ? ObjectProto : null;\n};\n","'use strict';\nvar create = require('./_object-create');\nvar descriptor = require('./_property-desc');\nvar setToStringTag = require('./_set-to-string-tag');\nvar IteratorPrototype = {};\n\n// 25.1.2.1.1 %IteratorPrototype%[@@iterator]()\nrequire('./_hide')(IteratorPrototype, require('./_wks')('iterator'), function () { return this; });\n\nmodule.exports = function (Constructor, NAME, next) {\n Constructor.prototype = create(IteratorPrototype, { next: descriptor(1, next) });\n setToStringTag(Constructor, NAME + ' Iterator');\n};\n","// 19.1.2.14 Object.keys(O)\nvar toObject = require('./_to-object');\nvar $keys = require('./_object-keys');\n\nrequire('./_object-sap')('keys', function () {\n return function keys(it) {\n return $keys(toObject(it));\n };\n});\n","// 7.1.4 ToInteger\nvar ceil = Math.ceil;\nvar floor = Math.floor;\nmodule.exports = function (it) {\n return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);\n};\n","module.exports = function (bitmap, value) {\n return {\n enumerable: !(bitmap & 1),\n configurable: !(bitmap & 2),\n writable: !(bitmap & 4),\n value: value\n };\n};\n","'use strict';\n\nvar anObject = require('./_an-object');\nvar toLength = require('./_to-length');\nvar advanceStringIndex = require('./_advance-string-index');\nvar regExpExec = require('./_regexp-exec-abstract');\n\n// @@match logic\nrequire('./_fix-re-wks')('match', 1, function (defined, MATCH, $match, maybeCallNative) {\n return [\n // `String.prototype.match` method\n // https://tc39.github.io/ecma262/#sec-string.prototype.match\n function match(regexp) {\n var O = defined(this);\n var fn = regexp == undefined ? undefined : regexp[MATCH];\n return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[MATCH](String(O));\n },\n // `RegExp.prototype[@@match]` method\n // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@match\n function (regexp) {\n var res = maybeCallNative($match, regexp, this);\n if (res.done) return res.value;\n var rx = anObject(regexp);\n var S = String(this);\n if (!rx.global) return regExpExec(rx, S);\n var fullUnicode = rx.unicode;\n rx.lastIndex = 0;\n var A = [];\n var n = 0;\n var result;\n while ((result = regExpExec(rx, S)) !== null) {\n var matchStr = String(result[0]);\n A[n] = matchStr;\n if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength(rx.lastIndex), fullUnicode);\n n++;\n }\n return n === 0 ? null : A;\n }\n ];\n});\n","/**\n * Translates the list format produced by css-loader into something\n * easier to manipulate.\n */\nexport default function listToStyles (parentId, list) {\n var styles = []\n var newStyles = {}\n for (var i = 0; i < list.length; i++) {\n var item = list[i]\n var id = item[0]\n var css = item[1]\n var media = item[2]\n var sourceMap = item[3]\n var part = {\n id: parentId + ':' + i,\n css: css,\n media: media,\n sourceMap: sourceMap\n }\n if (!newStyles[id]) {\n styles.push(newStyles[id] = { id: id, parts: [part] })\n } else {\n newStyles[id].parts.push(part)\n }\n }\n return styles\n}\n","/*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n Modified by Evan You @yyx990803\n*/\n\nimport listToStyles from './listToStyles'\n\nvar hasDocument = typeof document !== 'undefined'\n\nif (typeof DEBUG !== 'undefined' && DEBUG) {\n if (!hasDocument) {\n throw new Error(\n 'vue-style-loader cannot be used in a non-browser environment. ' +\n \"Use { target: 'node' } in your Webpack config to indicate a server-rendering environment.\"\n ) }\n}\n\n/*\ntype StyleObject = {\n id: number;\n parts: Array\n}\n\ntype StyleObjectPart = {\n css: string;\n media: string;\n sourceMap: ?string\n}\n*/\n\nvar stylesInDom = {/*\n [id: number]: {\n id: number,\n refs: number,\n parts: Array<(obj?: StyleObjectPart) => void>\n }\n*/}\n\nvar head = hasDocument && (document.head || document.getElementsByTagName('head')[0])\nvar singletonElement = null\nvar singletonCounter = 0\nvar isProduction = false\nvar noop = function () {}\nvar options = null\nvar ssrIdKey = 'data-vue-ssr-id'\n\n// Force single-tag solution on IE6-9, which has a hard limit on the # of \r\n\r\n","import mod from \"-!../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./GridItem.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./GridItem.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./GridItem.vue?vue&type=template&id=e7489122&\"\nimport script from \"./GridItem.vue?vue&type=script&lang=js&\"\nexport * from \"./GridItem.vue?vue&type=script&lang=js&\"\nimport style0 from \"./GridItem.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","// 7.2.1 RequireObjectCoercible(argument)\nmodule.exports = function (it) {\n if (it == undefined) throw TypeError(\"Can't call method on \" + it);\n return it;\n};\n","\"use strict\";\n\nvar utils = require(\"./utils\");\n\nmodule.exports = function batchProcessorMaker(options) {\n options = options || {};\n var reporter = options.reporter;\n var asyncProcess = utils.getOption(options, \"async\", true);\n var autoProcess = utils.getOption(options, \"auto\", true);\n\n if(autoProcess && !asyncProcess) {\n reporter && reporter.warn(\"Invalid options combination. auto=true and async=false is invalid. Setting async=true.\");\n asyncProcess = true;\n }\n\n var batch = Batch();\n var asyncFrameHandler;\n var isProcessing = false;\n\n function addFunction(level, fn) {\n if(!isProcessing && autoProcess && asyncProcess && batch.size() === 0) {\n // Since this is async, it is guaranteed to be executed after that the fn is added to the batch.\n // This needs to be done before, since we're checking the size of the batch to be 0.\n processBatchAsync();\n }\n\n batch.add(level, fn);\n }\n\n function processBatch() {\n // Save the current batch, and create a new batch so that incoming functions are not added into the currently processing batch.\n // Continue processing until the top-level batch is empty (functions may be added to the new batch while processing, and so on).\n isProcessing = true;\n while (batch.size()) {\n var processingBatch = batch;\n batch = Batch();\n processingBatch.process();\n }\n isProcessing = false;\n }\n\n function forceProcessBatch(localAsyncProcess) {\n if (isProcessing) {\n return;\n }\n\n if(localAsyncProcess === undefined) {\n localAsyncProcess = asyncProcess;\n }\n\n if(asyncFrameHandler) {\n cancelFrame(asyncFrameHandler);\n asyncFrameHandler = null;\n }\n\n if(localAsyncProcess) {\n processBatchAsync();\n } else {\n processBatch();\n }\n }\n\n function processBatchAsync() {\n asyncFrameHandler = requestFrame(processBatch);\n }\n\n function clearBatch() {\n batch = {};\n batchSize = 0;\n topLevel = 0;\n bottomLevel = 0;\n }\n\n function cancelFrame(listener) {\n // var cancel = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame || window.clearTimeout;\n var cancel = clearTimeout;\n return cancel(listener);\n }\n\n function requestFrame(callback) {\n // var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || function(fn) { return window.setTimeout(fn, 20); };\n var raf = function(fn) { return setTimeout(fn, 0); };\n return raf(callback);\n }\n\n return {\n add: addFunction,\n force: forceProcessBatch\n };\n};\n\nfunction Batch() {\n var batch = {};\n var size = 0;\n var topLevel = 0;\n var bottomLevel = 0;\n\n function add(level, fn) {\n if(!fn) {\n fn = level;\n level = 0;\n }\n\n if(level > topLevel) {\n topLevel = level;\n } else if(level < bottomLevel) {\n bottomLevel = level;\n }\n\n if(!batch[level]) {\n batch[level] = [];\n }\n\n batch[level].push(fn);\n size++;\n }\n\n function process() {\n for(var level = bottomLevel; level <= topLevel; level++) {\n var fns = batch[level];\n\n for(var i = 0; i < fns.length; i++) {\n var fn = fns[i];\n fn();\n }\n }\n }\n\n function getSize() {\n return size;\n }\n\n return {\n add: add,\n process: process,\n size: getSize\n };\n}\n","// false -> Array#indexOf\n// true -> Array#includes\nvar toIObject = require('./_to-iobject');\nvar toLength = require('./_to-length');\nvar toAbsoluteIndex = require('./_to-absolute-index');\nmodule.exports = function (IS_INCLUDES) {\n return function ($this, el, fromIndex) {\n var O = toIObject($this);\n var length = toLength(O.length);\n var index = toAbsoluteIndex(fromIndex, length);\n var value;\n // Array#includes uses SameValueZero equality algorithm\n // eslint-disable-next-line no-self-compare\n if (IS_INCLUDES && el != el) while (length > index) {\n value = O[index++];\n // eslint-disable-next-line no-self-compare\n if (value != value) return true;\n // Array#indexOf ignores holes, Array#includes - not\n } else for (;length > index; index++) if (IS_INCLUDES || index in O) {\n if (O[index] === el) return IS_INCLUDES || index || 0;\n } return !IS_INCLUDES && -1;\n };\n};\n","'use strict';\nvar global = require('./_global');\nvar has = require('./_has');\nvar cof = require('./_cof');\nvar inheritIfRequired = require('./_inherit-if-required');\nvar toPrimitive = require('./_to-primitive');\nvar fails = require('./_fails');\nvar gOPN = require('./_object-gopn').f;\nvar gOPD = require('./_object-gopd').f;\nvar dP = require('./_object-dp').f;\nvar $trim = require('./_string-trim').trim;\nvar NUMBER = 'Number';\nvar $Number = global[NUMBER];\nvar Base = $Number;\nvar proto = $Number.prototype;\n// Opera ~12 has broken Object#toString\nvar BROKEN_COF = cof(require('./_object-create')(proto)) == NUMBER;\nvar TRIM = 'trim' in String.prototype;\n\n// 7.1.3 ToNumber(argument)\nvar toNumber = function (argument) {\n var it = toPrimitive(argument, false);\n if (typeof it == 'string' && it.length > 2) {\n it = TRIM ? it.trim() : $trim(it, 3);\n var first = it.charCodeAt(0);\n var third, radix, maxCode;\n if (first === 43 || first === 45) {\n third = it.charCodeAt(2);\n if (third === 88 || third === 120) return NaN; // Number('+0x1') should be NaN, old V8 fix\n } else if (first === 48) {\n switch (it.charCodeAt(1)) {\n case 66: case 98: radix = 2; maxCode = 49; break; // fast equal /^0b[01]+$/i\n case 79: case 111: radix = 8; maxCode = 55; break; // fast equal /^0o[0-7]+$/i\n default: return +it;\n }\n for (var digits = it.slice(2), i = 0, l = digits.length, code; i < l; i++) {\n code = digits.charCodeAt(i);\n // parseInt parses a string to a first unavailable symbol\n // but ToNumber should return NaN if a string contains unavailable symbols\n if (code < 48 || code > maxCode) return NaN;\n } return parseInt(digits, radix);\n }\n } return +it;\n};\n\nif (!$Number(' 0o1') || !$Number('0b1') || $Number('+0x1')) {\n $Number = function Number(value) {\n var it = arguments.length < 1 ? 0 : value;\n var that = this;\n return that instanceof $Number\n // check on 1..constructor(foo) case\n && (BROKEN_COF ? fails(function () { proto.valueOf.call(that); }) : cof(that) != NUMBER)\n ? inheritIfRequired(new Base(toNumber(it)), that, $Number) : toNumber(it);\n };\n for (var keys = require('./_descriptors') ? gOPN(Base) : (\n // ES3:\n 'MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,' +\n // ES6 (in case, if modules with ES6 Number statics required before):\n 'EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,' +\n 'MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger'\n ).split(','), j = 0, key; keys.length > j; j++) {\n if (has(Base, key = keys[j]) && !has($Number, key)) {\n dP($Number, key, gOPD(Base, key));\n }\n }\n $Number.prototype = proto;\n proto.constructor = $Number;\n require('./_redefine')(global, NUMBER, $Number);\n}\n","module.exports = !require('./_descriptors') && !require('./_fails')(function () {\n return Object.defineProperty(require('./_dom-create')('div'), 'a', { get: function () { return 7; } }).a != 7;\n});\n","var g;\n\n// This works in non-strict mode\ng = (function() {\n\treturn this;\n})();\n\ntry {\n\t// This works if eval is allowed (see CSP)\n\tg = g || new Function(\"return this\")();\n} catch (e) {\n\t// This works if the window reference is available\n\tif (typeof window === \"object\") g = window;\n}\n\n// g can still be undefined, but nothing to do about it...\n// We return undefined, instead of nothing here, so it's\n// easier to handle this case. if(!global) { ...}\n\nmodule.exports = g;\n","/**\n * Resize detection strategy that injects divs to elements in order to detect resize events on scroll events.\n * Heavily inspired by: https://github.com/marcj/css-element-queries/blob/master/src/ResizeSensor.js\n */\n\n\"use strict\";\n\nvar forEach = require(\"../collection-utils\").forEach;\n\nmodule.exports = function(options) {\n options = options || {};\n var reporter = options.reporter;\n var batchProcessor = options.batchProcessor;\n var getState = options.stateHandler.getState;\n var hasState = options.stateHandler.hasState;\n var idHandler = options.idHandler;\n\n if (!batchProcessor) {\n throw new Error(\"Missing required dependency: batchProcessor\");\n }\n\n if (!reporter) {\n throw new Error(\"Missing required dependency: reporter.\");\n }\n\n //TODO: Could this perhaps be done at installation time?\n var scrollbarSizes = getScrollbarSizes();\n\n var styleId = \"erd_scroll_detection_scrollbar_style\";\n var detectionContainerClass = \"erd_scroll_detection_container\";\n\n function initDocument(targetDocument) {\n // Inject the scrollbar styling that prevents them from appearing sometimes in Chrome.\n // The injected container needs to have a class, so that it may be styled with CSS (pseudo elements).\n injectScrollStyle(targetDocument, styleId, detectionContainerClass);\n }\n\n initDocument(window.document);\n\n function buildCssTextString(rules) {\n var seperator = options.important ? \" !important; \" : \"; \";\n\n return (rules.join(seperator) + seperator).trim();\n }\n\n function getScrollbarSizes() {\n var width = 500;\n var height = 500;\n\n var child = document.createElement(\"div\");\n child.style.cssText = buildCssTextString([\"position: absolute\", \"width: \" + width*2 + \"px\", \"height: \" + height*2 + \"px\", \"visibility: hidden\", \"margin: 0\", \"padding: 0\"]);\n\n var container = document.createElement(\"div\");\n container.style.cssText = buildCssTextString([\"position: absolute\", \"width: \" + width + \"px\", \"height: \" + height + \"px\", \"overflow: scroll\", \"visibility: none\", \"top: \" + -width*3 + \"px\", \"left: \" + -height*3 + \"px\", \"visibility: hidden\", \"margin: 0\", \"padding: 0\"]);\n\n container.appendChild(child);\n\n document.body.insertBefore(container, document.body.firstChild);\n\n var widthSize = width - container.clientWidth;\n var heightSize = height - container.clientHeight;\n\n document.body.removeChild(container);\n\n return {\n width: widthSize,\n height: heightSize\n };\n }\n\n function injectScrollStyle(targetDocument, styleId, containerClass) {\n function injectStyle(style, method) {\n method = method || function (element) {\n targetDocument.head.appendChild(element);\n };\n\n var styleElement = targetDocument.createElement(\"style\");\n styleElement.innerHTML = style;\n styleElement.id = styleId;\n method(styleElement);\n return styleElement;\n }\n\n if (!targetDocument.getElementById(styleId)) {\n var containerAnimationClass = containerClass + \"_animation\";\n var containerAnimationActiveClass = containerClass + \"_animation_active\";\n var style = \"/* Created by the element-resize-detector library. */\\n\";\n style += \".\" + containerClass + \" > div::-webkit-scrollbar { \" + buildCssTextString([\"display: none\"]) + \" }\\n\\n\";\n style += \".\" + containerAnimationActiveClass + \" { \" + buildCssTextString([\"-webkit-animation-duration: 0.1s\", \"animation-duration: 0.1s\", \"-webkit-animation-name: \" + containerAnimationClass, \"animation-name: \" + containerAnimationClass]) + \" }\\n\";\n style += \"@-webkit-keyframes \" + containerAnimationClass + \" { 0% { opacity: 1; } 50% { opacity: 0; } 100% { opacity: 1; } }\\n\";\n style += \"@keyframes \" + containerAnimationClass + \" { 0% { opacity: 1; } 50% { opacity: 0; } 100% { opacity: 1; } }\";\n injectStyle(style);\n }\n }\n\n function addAnimationClass(element) {\n element.className += \" \" + detectionContainerClass + \"_animation_active\";\n }\n\n function addEvent(el, name, cb) {\n if (el.addEventListener) {\n el.addEventListener(name, cb);\n } else if(el.attachEvent) {\n el.attachEvent(\"on\" + name, cb);\n } else {\n return reporter.error(\"[scroll] Don't know how to add event listeners.\");\n }\n }\n\n function removeEvent(el, name, cb) {\n if (el.removeEventListener) {\n el.removeEventListener(name, cb);\n } else if(el.detachEvent) {\n el.detachEvent(\"on\" + name, cb);\n } else {\n return reporter.error(\"[scroll] Don't know how to remove event listeners.\");\n }\n }\n\n function getExpandElement(element) {\n return getState(element).container.childNodes[0].childNodes[0].childNodes[0];\n }\n\n function getShrinkElement(element) {\n return getState(element).container.childNodes[0].childNodes[0].childNodes[1];\n }\n\n /**\n * Adds a resize event listener to the element.\n * @public\n * @param {element} element The element that should have the listener added.\n * @param {function} listener The listener callback to be called for each resize event of the element. The element will be given as a parameter to the listener callback.\n */\n function addListener(element, listener) {\n var listeners = getState(element).listeners;\n\n if (!listeners.push) {\n throw new Error(\"Cannot add listener to an element that is not detectable.\");\n }\n\n getState(element).listeners.push(listener);\n }\n\n /**\n * Makes an element detectable and ready to be listened for resize events. Will call the callback when the element is ready to be listened for resize changes.\n * @private\n * @param {object} options Optional options object.\n * @param {element} element The element to make detectable\n * @param {function} callback The callback to be called when the element is ready to be listened for resize changes. Will be called with the element as first parameter.\n */\n function makeDetectable(options, element, callback) {\n if (!callback) {\n callback = element;\n element = options;\n options = null;\n }\n\n options = options || {};\n\n function debug() {\n if (options.debug) {\n var args = Array.prototype.slice.call(arguments);\n args.unshift(idHandler.get(element), \"Scroll: \");\n if (reporter.log.apply) {\n reporter.log.apply(null, args);\n } else {\n for (var i = 0; i < args.length; i++) {\n reporter.log(args[i]);\n }\n }\n }\n }\n\n function isDetached(element) {\n function isInDocument(element) {\n var isInShadowRoot = element.getRootNode && element.getRootNode().contains(element);\n return element === element.ownerDocument.body || element.ownerDocument.body.contains(element) || isInShadowRoot;\n }\n\n if (!isInDocument(element)) {\n return true;\n }\n\n // FireFox returns null style in hidden iframes. See https://github.com/wnr/element-resize-detector/issues/68 and https://bugzilla.mozilla.org/show_bug.cgi?id=795520\n if (window.getComputedStyle(element) === null) {\n return true;\n }\n\n return false;\n }\n\n function isUnrendered(element) {\n // Check the absolute positioned container since the top level container is display: inline.\n var container = getState(element).container.childNodes[0];\n var style = window.getComputedStyle(container);\n return !style.width || style.width.indexOf(\"px\") === -1; //Can only compute pixel value when rendered.\n }\n\n function getStyle() {\n // Some browsers only force layouts when actually reading the style properties of the style object, so make sure that they are all read here,\n // so that the user of the function can be sure that it will perform the layout here, instead of later (important for batching).\n var elementStyle = window.getComputedStyle(element);\n var style = {};\n style.position = elementStyle.position;\n style.width = element.offsetWidth;\n style.height = element.offsetHeight;\n style.top = elementStyle.top;\n style.right = elementStyle.right;\n style.bottom = elementStyle.bottom;\n style.left = elementStyle.left;\n style.widthCSS = elementStyle.width;\n style.heightCSS = elementStyle.height;\n return style;\n }\n\n function storeStartSize() {\n var style = getStyle();\n getState(element).startSize = {\n width: style.width,\n height: style.height\n };\n debug(\"Element start size\", getState(element).startSize);\n }\n\n function initListeners() {\n getState(element).listeners = [];\n }\n\n function storeStyle() {\n debug(\"storeStyle invoked.\");\n if (!getState(element)) {\n debug(\"Aborting because element has been uninstalled\");\n return;\n }\n\n var style = getStyle();\n getState(element).style = style;\n }\n\n function storeCurrentSize(element, width, height) {\n getState(element).lastWidth = width;\n getState(element).lastHeight = height;\n }\n\n function getExpandChildElement(element) {\n return getExpandElement(element).childNodes[0];\n }\n\n function getWidthOffset() {\n return 2 * scrollbarSizes.width + 1;\n }\n\n function getHeightOffset() {\n return 2 * scrollbarSizes.height + 1;\n }\n\n function getExpandWidth(width) {\n return width + 10 + getWidthOffset();\n }\n\n function getExpandHeight(height) {\n return height + 10 + getHeightOffset();\n }\n\n function getShrinkWidth(width) {\n return width * 2 + getWidthOffset();\n }\n\n function getShrinkHeight(height) {\n return height * 2 + getHeightOffset();\n }\n\n function positionScrollbars(element, width, height) {\n var expand = getExpandElement(element);\n var shrink = getShrinkElement(element);\n var expandWidth = getExpandWidth(width);\n var expandHeight = getExpandHeight(height);\n var shrinkWidth = getShrinkWidth(width);\n var shrinkHeight = getShrinkHeight(height);\n expand.scrollLeft = expandWidth;\n expand.scrollTop = expandHeight;\n shrink.scrollLeft = shrinkWidth;\n shrink.scrollTop = shrinkHeight;\n }\n\n function injectContainerElement() {\n var container = getState(element).container;\n\n if (!container) {\n container = document.createElement(\"div\");\n container.className = detectionContainerClass;\n container.style.cssText = buildCssTextString([\"visibility: hidden\", \"display: inline\", \"width: 0px\", \"height: 0px\", \"z-index: -1\", \"overflow: hidden\", \"margin: 0\", \"padding: 0\"]);\n getState(element).container = container;\n addAnimationClass(container);\n element.appendChild(container);\n\n var onAnimationStart = function () {\n getState(element).onRendered && getState(element).onRendered();\n };\n\n addEvent(container, \"animationstart\", onAnimationStart);\n\n // Store the event handler here so that they may be removed when uninstall is called.\n // See uninstall function for an explanation why it is needed.\n getState(element).onAnimationStart = onAnimationStart;\n }\n\n return container;\n }\n\n function injectScrollElements() {\n function alterPositionStyles() {\n var style = getState(element).style;\n\n if(style.position === \"static\") {\n element.style.setProperty(\"position\", \"relative\",options.important ? \"important\" : \"\");\n\n var removeRelativeStyles = function(reporter, element, style, property) {\n function getNumericalValue(value) {\n return value.replace(/[^-\\d\\.]/g, \"\");\n }\n\n var value = style[property];\n\n if(value !== \"auto\" && getNumericalValue(value) !== \"0\") {\n reporter.warn(\"An element that is positioned static has style.\" + property + \"=\" + value + \" which is ignored due to the static positioning. The element will need to be positioned relative, so the style.\" + property + \" will be set to 0. Element: \", element);\n element.style[property] = 0;\n }\n };\n\n //Check so that there are no accidental styles that will make the element styled differently now that is is relative.\n //If there are any, set them to 0 (this should be okay with the user since the style properties did nothing before [since the element was positioned static] anyway).\n removeRelativeStyles(reporter, element, style, \"top\");\n removeRelativeStyles(reporter, element, style, \"right\");\n removeRelativeStyles(reporter, element, style, \"bottom\");\n removeRelativeStyles(reporter, element, style, \"left\");\n }\n }\n\n function getLeftTopBottomRightCssText(left, top, bottom, right) {\n left = (!left ? \"0\" : (left + \"px\"));\n top = (!top ? \"0\" : (top + \"px\"));\n bottom = (!bottom ? \"0\" : (bottom + \"px\"));\n right = (!right ? \"0\" : (right + \"px\"));\n\n return [\"left: \" + left, \"top: \" + top, \"right: \" + right, \"bottom: \" + bottom];\n }\n\n debug(\"Injecting elements\");\n\n if (!getState(element)) {\n debug(\"Aborting because element has been uninstalled\");\n return;\n }\n\n alterPositionStyles();\n\n var rootContainer = getState(element).container;\n\n if (!rootContainer) {\n rootContainer = injectContainerElement();\n }\n\n // Due to this WebKit bug https://bugs.webkit.org/show_bug.cgi?id=80808 (currently fixed in Blink, but still present in WebKit browsers such as Safari),\n // we need to inject two containers, one that is width/height 100% and another that is left/top -1px so that the final container always is 1x1 pixels bigger than\n // the targeted element.\n // When the bug is resolved, \"containerContainer\" may be removed.\n\n // The outer container can occasionally be less wide than the targeted when inside inline elements element in WebKit (see https://bugs.webkit.org/show_bug.cgi?id=152980).\n // This should be no problem since the inner container either way makes sure the injected scroll elements are at least 1x1 px.\n\n var scrollbarWidth = scrollbarSizes.width;\n var scrollbarHeight = scrollbarSizes.height;\n var containerContainerStyle = buildCssTextString([\"position: absolute\", \"flex: none\", \"overflow: hidden\", \"z-index: -1\", \"visibility: hidden\", \"width: 100%\", \"height: 100%\", \"left: 0px\", \"top: 0px\"]);\n var containerStyle = buildCssTextString([\"position: absolute\", \"flex: none\", \"overflow: hidden\", \"z-index: -1\", \"visibility: hidden\"].concat(getLeftTopBottomRightCssText(-(1 + scrollbarWidth), -(1 + scrollbarHeight), -scrollbarHeight, -scrollbarWidth)));\n var expandStyle = buildCssTextString([\"position: absolute\", \"flex: none\", \"overflow: scroll\", \"z-index: -1\", \"visibility: hidden\", \"width: 100%\", \"height: 100%\"]);\n var shrinkStyle = buildCssTextString([\"position: absolute\", \"flex: none\", \"overflow: scroll\", \"z-index: -1\", \"visibility: hidden\", \"width: 100%\", \"height: 100%\"]);\n var expandChildStyle = buildCssTextString([\"position: absolute\", \"left: 0\", \"top: 0\"]);\n var shrinkChildStyle = buildCssTextString([\"position: absolute\", \"width: 200%\", \"height: 200%\"]);\n\n var containerContainer = document.createElement(\"div\");\n var container = document.createElement(\"div\");\n var expand = document.createElement(\"div\");\n var expandChild = document.createElement(\"div\");\n var shrink = document.createElement(\"div\");\n var shrinkChild = document.createElement(\"div\");\n\n // Some browsers choke on the resize system being rtl, so force it to ltr. https://github.com/wnr/element-resize-detector/issues/56\n // However, dir should not be set on the top level container as it alters the dimensions of the target element in some browsers.\n containerContainer.dir = \"ltr\";\n\n containerContainer.style.cssText = containerContainerStyle;\n containerContainer.className = detectionContainerClass;\n container.className = detectionContainerClass;\n container.style.cssText = containerStyle;\n expand.style.cssText = expandStyle;\n expandChild.style.cssText = expandChildStyle;\n shrink.style.cssText = shrinkStyle;\n shrinkChild.style.cssText = shrinkChildStyle;\n\n expand.appendChild(expandChild);\n shrink.appendChild(shrinkChild);\n container.appendChild(expand);\n container.appendChild(shrink);\n containerContainer.appendChild(container);\n rootContainer.appendChild(containerContainer);\n\n function onExpandScroll() {\n var state = getState(element);\n if (state && state.onExpand) {\n state.onExpand();\n } else {\n debug(\"Aborting expand scroll handler: element has been uninstalled\");\n }\n }\n\n function onShrinkScroll() {\n var state = getState(element);\n if (state && state.onShrink) {\n state.onShrink();\n } else {\n debug(\"Aborting shrink scroll handler: element has been uninstalled\");\n }\n }\n\n addEvent(expand, \"scroll\", onExpandScroll);\n addEvent(shrink, \"scroll\", onShrinkScroll);\n\n // Store the event handlers here so that they may be removed when uninstall is called.\n // See uninstall function for an explanation why it is needed.\n getState(element).onExpandScroll = onExpandScroll;\n getState(element).onShrinkScroll = onShrinkScroll;\n }\n\n function registerListenersAndPositionElements() {\n function updateChildSizes(element, width, height) {\n var expandChild = getExpandChildElement(element);\n var expandWidth = getExpandWidth(width);\n var expandHeight = getExpandHeight(height);\n expandChild.style.setProperty(\"width\", expandWidth + \"px\", options.important ? \"important\" : \"\");\n expandChild.style.setProperty(\"height\", expandHeight + \"px\", options.important ? \"important\" : \"\");\n }\n\n function updateDetectorElements(done) {\n var width = element.offsetWidth;\n var height = element.offsetHeight;\n\n // Check whether the size has actually changed since last time the algorithm ran. If not, some steps may be skipped.\n var sizeChanged = width !== getState(element).lastWidth || height !== getState(element).lastHeight;\n\n debug(\"Storing current size\", width, height);\n\n // Store the size of the element sync here, so that multiple scroll events may be ignored in the event listeners.\n // Otherwise the if-check in handleScroll is useless.\n storeCurrentSize(element, width, height);\n\n // Since we delay the processing of the batch, there is a risk that uninstall has been called before the batch gets to execute.\n // Since there is no way to cancel the fn executions, we need to add an uninstall guard to all fns of the batch.\n\n batchProcessor.add(0, function performUpdateChildSizes() {\n if (!sizeChanged) {\n return;\n }\n\n if (!getState(element)) {\n debug(\"Aborting because element has been uninstalled\");\n return;\n }\n\n if (!areElementsInjected()) {\n debug(\"Aborting because element container has not been initialized\");\n return;\n }\n\n if (options.debug) {\n var w = element.offsetWidth;\n var h = element.offsetHeight;\n\n if (w !== width || h !== height) {\n reporter.warn(idHandler.get(element), \"Scroll: Size changed before updating detector elements.\");\n }\n }\n\n updateChildSizes(element, width, height);\n });\n\n batchProcessor.add(1, function updateScrollbars() {\n // This function needs to be invoked event though the size is unchanged. The element could have been resized very quickly and then\n // been restored to the original size, which will have changed the scrollbar positions.\n\n if (!getState(element)) {\n debug(\"Aborting because element has been uninstalled\");\n return;\n }\n\n if (!areElementsInjected()) {\n debug(\"Aborting because element container has not been initialized\");\n return;\n }\n\n positionScrollbars(element, width, height);\n });\n\n if (sizeChanged && done) {\n batchProcessor.add(2, function () {\n if (!getState(element)) {\n debug(\"Aborting because element has been uninstalled\");\n return;\n }\n\n if (!areElementsInjected()) {\n debug(\"Aborting because element container has not been initialized\");\n return;\n }\n\n done();\n });\n }\n }\n\n function areElementsInjected() {\n return !!getState(element).container;\n }\n\n function notifyListenersIfNeeded() {\n function isFirstNotify() {\n return getState(element).lastNotifiedWidth === undefined;\n }\n\n debug(\"notifyListenersIfNeeded invoked\");\n\n var state = getState(element);\n\n // Don't notify if the current size is the start size, and this is the first notification.\n if (isFirstNotify() && state.lastWidth === state.startSize.width && state.lastHeight === state.startSize.height) {\n return debug(\"Not notifying: Size is the same as the start size, and there has been no notification yet.\");\n }\n\n // Don't notify if the size already has been notified.\n if (state.lastWidth === state.lastNotifiedWidth && state.lastHeight === state.lastNotifiedHeight) {\n return debug(\"Not notifying: Size already notified\");\n }\n\n\n debug(\"Current size not notified, notifying...\");\n state.lastNotifiedWidth = state.lastWidth;\n state.lastNotifiedHeight = state.lastHeight;\n forEach(getState(element).listeners, function (listener) {\n listener(element);\n });\n }\n\n function handleRender() {\n debug(\"startanimation triggered.\");\n\n if (isUnrendered(element)) {\n debug(\"Ignoring since element is still unrendered...\");\n return;\n }\n\n debug(\"Element rendered.\");\n var expand = getExpandElement(element);\n var shrink = getShrinkElement(element);\n if (expand.scrollLeft === 0 || expand.scrollTop === 0 || shrink.scrollLeft === 0 || shrink.scrollTop === 0) {\n debug(\"Scrollbars out of sync. Updating detector elements...\");\n updateDetectorElements(notifyListenersIfNeeded);\n }\n }\n\n function handleScroll() {\n debug(\"Scroll detected.\");\n\n if (isUnrendered(element)) {\n // Element is still unrendered. Skip this scroll event.\n debug(\"Scroll event fired while unrendered. Ignoring...\");\n return;\n }\n\n updateDetectorElements(notifyListenersIfNeeded);\n }\n\n debug(\"registerListenersAndPositionElements invoked.\");\n\n if (!getState(element)) {\n debug(\"Aborting because element has been uninstalled\");\n return;\n }\n\n getState(element).onRendered = handleRender;\n getState(element).onExpand = handleScroll;\n getState(element).onShrink = handleScroll;\n\n var style = getState(element).style;\n updateChildSizes(element, style.width, style.height);\n }\n\n function finalizeDomMutation() {\n debug(\"finalizeDomMutation invoked.\");\n\n if (!getState(element)) {\n debug(\"Aborting because element has been uninstalled\");\n return;\n }\n\n var style = getState(element).style;\n storeCurrentSize(element, style.width, style.height);\n positionScrollbars(element, style.width, style.height);\n }\n\n function ready() {\n callback(element);\n }\n\n function install() {\n debug(\"Installing...\");\n initListeners();\n storeStartSize();\n\n batchProcessor.add(0, storeStyle);\n batchProcessor.add(1, injectScrollElements);\n batchProcessor.add(2, registerListenersAndPositionElements);\n batchProcessor.add(3, finalizeDomMutation);\n batchProcessor.add(4, ready);\n }\n\n debug(\"Making detectable...\");\n\n if (isDetached(element)) {\n debug(\"Element is detached\");\n\n injectContainerElement();\n\n debug(\"Waiting until element is attached...\");\n\n getState(element).onRendered = function () {\n debug(\"Element is now attached\");\n install();\n };\n } else {\n install();\n }\n }\n\n function uninstall(element) {\n var state = getState(element);\n\n if (!state) {\n // Uninstall has been called on a non-erd element.\n return;\n }\n\n // Uninstall may have been called in the following scenarios:\n // (1) Right between the sync code and async batch (here state.busy = true, but nothing have been registered or injected).\n // (2) In the ready callback of the last level of the batch by another element (here, state.busy = true, but all the stuff has been injected).\n // (3) After the installation process (here, state.busy = false and all the stuff has been injected).\n // So to be on the safe side, let's check for each thing before removing.\n\n // We need to remove the event listeners, because otherwise the event might fire on an uninstall element which results in an error when trying to get the state of the element.\n state.onExpandScroll && removeEvent(getExpandElement(element), \"scroll\", state.onExpandScroll);\n state.onShrinkScroll && removeEvent(getShrinkElement(element), \"scroll\", state.onShrinkScroll);\n state.onAnimationStart && removeEvent(state.container, \"animationstart\", state.onAnimationStart);\n\n state.container && element.removeChild(state.container);\n }\n\n return {\n makeDetectable: makeDetectable,\n addListener: addListener,\n uninstall: uninstall,\n initDocument: initDocument\n };\n};\n","var id = 0;\nvar px = Math.random();\nmodule.exports = function (key) {\n return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));\n};\n","'use strict';\nvar addToUnscopables = require('./_add-to-unscopables');\nvar step = require('./_iter-step');\nvar Iterators = require('./_iterators');\nvar toIObject = require('./_to-iobject');\n\n// 22.1.3.4 Array.prototype.entries()\n// 22.1.3.13 Array.prototype.keys()\n// 22.1.3.29 Array.prototype.values()\n// 22.1.3.30 Array.prototype[@@iterator]()\nmodule.exports = require('./_iter-define')(Array, 'Array', function (iterated, kind) {\n this._t = toIObject(iterated); // target\n this._i = 0; // next index\n this._k = kind; // kind\n// 22.1.5.2.1 %ArrayIteratorPrototype%.next()\n}, function () {\n var O = this._t;\n var kind = this._k;\n var index = this._i++;\n if (!O || index >= O.length) {\n this._t = undefined;\n return step(1);\n }\n if (kind == 'keys') return step(0, index);\n if (kind == 'values') return step(0, O[index]);\n return step(0, [index, O[index]]);\n}, 'values');\n\n// argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7)\nIterators.Arguments = Iterators.Array;\n\naddToUnscopables('keys');\naddToUnscopables('values');\naddToUnscopables('entries');\n","var isObject = require('./_is-object');\nmodule.exports = function (it) {\n if (!isObject(it)) throw TypeError(it + ' is not an object!');\n return it;\n};\n","var has = require('./_has');\nvar toIObject = require('./_to-iobject');\nvar arrayIndexOf = require('./_array-includes')(false);\nvar IE_PROTO = require('./_shared-key')('IE_PROTO');\n\nmodule.exports = function (object, names) {\n var O = toIObject(object);\n var i = 0;\n var result = [];\n var key;\n for (key in O) if (key != IE_PROTO) has(O, key) && result.push(key);\n // Don't enum bug & hidden keys\n while (names.length > i) if (has(O, key = names[i++])) {\n ~arrayIndexOf(result, key) || result.push(key);\n }\n return result;\n};\n","module.exports = function (it) {\n return typeof it === 'object' ? it !== null : typeof it === 'function';\n};\n","module.exports = function (done, value) {\n return { value: value, done: !!done };\n};\n","\"use strict\";\n\nvar prop = \"_erd\";\n\nfunction initState(element) {\n element[prop] = {};\n return getState(element);\n}\n\nfunction getState(element) {\n return element[prop];\n}\n\nfunction cleanState(element) {\n delete element[prop];\n}\n\nmodule.exports = {\n initState: initState,\n getState: getState,\n cleanState: cleanState\n};\n","module.exports = function (it) {\n if (typeof it != 'function') throw TypeError(it + ' is not a function!');\n return it;\n};\n","// IE 8- don't enum bug keys\nmodule.exports = (\n 'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf'\n).split(',');\n","export * from \"-!../../node_modules/vue-style-loader/index.js??ref--6-oneOf-1-0!../../node_modules/css-loader/index.js??ref--6-oneOf-1-1!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-3!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./GridLayout.vue?vue&type=style&index=0&lang=css&\"","\"use strict\";\n\nvar forEach = require(\"./collection-utils\").forEach;\nvar elementUtilsMaker = require(\"./element-utils\");\nvar listenerHandlerMaker = require(\"./listener-handler\");\nvar idGeneratorMaker = require(\"./id-generator\");\nvar idHandlerMaker = require(\"./id-handler\");\nvar reporterMaker = require(\"./reporter\");\nvar browserDetector = require(\"./browser-detector\");\nvar batchProcessorMaker = require(\"batch-processor\");\nvar stateHandler = require(\"./state-handler\");\n\n//Detection strategies.\nvar objectStrategyMaker = require(\"./detection-strategy/object.js\");\nvar scrollStrategyMaker = require(\"./detection-strategy/scroll.js\");\n\nfunction isCollection(obj) {\n return Array.isArray(obj) || obj.length !== undefined;\n}\n\nfunction toArray(collection) {\n if (!Array.isArray(collection)) {\n var array = [];\n forEach(collection, function (obj) {\n array.push(obj);\n });\n return array;\n } else {\n return collection;\n }\n}\n\nfunction isElement(obj) {\n return obj && obj.nodeType === 1;\n}\n\n/**\n * @typedef idHandler\n * @type {object}\n * @property {function} get Gets the resize detector id of the element.\n * @property {function} set Generate and sets the resize detector id of the element.\n */\n\n/**\n * @typedef Options\n * @type {object}\n * @property {boolean} callOnAdd Determines if listeners should be called when they are getting added.\n Default is true. If true, the listener is guaranteed to be called when it has been added.\n If false, the listener will not be guarenteed to be called when it has been added (does not prevent it from being called).\n * @property {idHandler} idHandler A custom id handler that is responsible for generating, setting and retrieving id's for elements.\n If not provided, a default id handler will be used.\n * @property {reporter} reporter A custom reporter that handles reporting logs, warnings and errors.\n If not provided, a default id handler will be used.\n If set to false, then nothing will be reported.\n * @property {boolean} debug If set to true, the the system will report debug messages as default for the listenTo method.\n */\n\n/**\n * Creates an element resize detector instance.\n * @public\n * @param {Options?} options Optional global options object that will decide how this instance will work.\n */\nmodule.exports = function(options) {\n options = options || {};\n\n //idHandler is currently not an option to the listenTo function, so it should not be added to globalOptions.\n var idHandler;\n\n if (options.idHandler) {\n // To maintain compatability with idHandler.get(element, readonly), make sure to wrap the given idHandler\n // so that readonly flag always is true when it's used here. This may be removed next major version bump.\n idHandler = {\n get: function (element) { return options.idHandler.get(element, true); },\n set: options.idHandler.set\n };\n } else {\n var idGenerator = idGeneratorMaker();\n var defaultIdHandler = idHandlerMaker({\n idGenerator: idGenerator,\n stateHandler: stateHandler\n });\n idHandler = defaultIdHandler;\n }\n\n //reporter is currently not an option to the listenTo function, so it should not be added to globalOptions.\n var reporter = options.reporter;\n\n if(!reporter) {\n //If options.reporter is false, then the reporter should be quiet.\n var quiet = reporter === false;\n reporter = reporterMaker(quiet);\n }\n\n //batchProcessor is currently not an option to the listenTo function, so it should not be added to globalOptions.\n var batchProcessor = getOption(options, \"batchProcessor\", batchProcessorMaker({ reporter: reporter }));\n\n //Options to be used as default for the listenTo function.\n var globalOptions = {};\n globalOptions.callOnAdd = !!getOption(options, \"callOnAdd\", true);\n globalOptions.debug = !!getOption(options, \"debug\", false);\n\n var eventListenerHandler = listenerHandlerMaker(idHandler);\n var elementUtils = elementUtilsMaker({\n stateHandler: stateHandler\n });\n\n //The detection strategy to be used.\n var detectionStrategy;\n var desiredStrategy = getOption(options, \"strategy\", \"object\");\n var importantCssRules = getOption(options, \"important\", false);\n var strategyOptions = {\n reporter: reporter,\n batchProcessor: batchProcessor,\n stateHandler: stateHandler,\n idHandler: idHandler,\n important: importantCssRules\n };\n\n if(desiredStrategy === \"scroll\") {\n if (browserDetector.isLegacyOpera()) {\n reporter.warn(\"Scroll strategy is not supported on legacy Opera. Changing to object strategy.\");\n desiredStrategy = \"object\";\n } else if (browserDetector.isIE(9)) {\n reporter.warn(\"Scroll strategy is not supported on IE9. Changing to object strategy.\");\n desiredStrategy = \"object\";\n }\n }\n\n if(desiredStrategy === \"scroll\") {\n detectionStrategy = scrollStrategyMaker(strategyOptions);\n } else if(desiredStrategy === \"object\") {\n detectionStrategy = objectStrategyMaker(strategyOptions);\n } else {\n throw new Error(\"Invalid strategy name: \" + desiredStrategy);\n }\n\n //Calls can be made to listenTo with elements that are still being installed.\n //Also, same elements can occur in the elements list in the listenTo function.\n //With this map, the ready callbacks can be synchronized between the calls\n //so that the ready callback can always be called when an element is ready - even if\n //it wasn't installed from the function itself.\n var onReadyCallbacks = {};\n\n /**\n * Makes the given elements resize-detectable and starts listening to resize events on the elements. Calls the event callback for each event for each element.\n * @public\n * @param {Options?} options Optional options object. These options will override the global options. Some options may not be overriden, such as idHandler.\n * @param {element[]|element} elements The given array of elements to detect resize events of. Single element is also valid.\n * @param {function} listener The callback to be executed for each resize event for each element.\n */\n function listenTo(options, elements, listener) {\n function onResizeCallback(element) {\n var listeners = eventListenerHandler.get(element);\n forEach(listeners, function callListenerProxy(listener) {\n listener(element);\n });\n }\n\n function addListener(callOnAdd, element, listener) {\n eventListenerHandler.add(element, listener);\n\n if(callOnAdd) {\n listener(element);\n }\n }\n\n //Options object may be omitted.\n if(!listener) {\n listener = elements;\n elements = options;\n options = {};\n }\n\n if(!elements) {\n throw new Error(\"At least one element required.\");\n }\n\n if(!listener) {\n throw new Error(\"Listener required.\");\n }\n\n if (isElement(elements)) {\n // A single element has been passed in.\n elements = [elements];\n } else if (isCollection(elements)) {\n // Convert collection to array for plugins.\n // TODO: May want to check so that all the elements in the collection are valid elements.\n elements = toArray(elements);\n } else {\n return reporter.error(\"Invalid arguments. Must be a DOM element or a collection of DOM elements.\");\n }\n\n var elementsReady = 0;\n\n var callOnAdd = getOption(options, \"callOnAdd\", globalOptions.callOnAdd);\n var onReadyCallback = getOption(options, \"onReady\", function noop() {});\n var debug = getOption(options, \"debug\", globalOptions.debug);\n\n forEach(elements, function attachListenerToElement(element) {\n if (!stateHandler.getState(element)) {\n stateHandler.initState(element);\n idHandler.set(element);\n }\n\n var id = idHandler.get(element);\n\n debug && reporter.log(\"Attaching listener to element\", id, element);\n\n if(!elementUtils.isDetectable(element)) {\n debug && reporter.log(id, \"Not detectable.\");\n if(elementUtils.isBusy(element)) {\n debug && reporter.log(id, \"System busy making it detectable\");\n\n //The element is being prepared to be detectable. Do not make it detectable.\n //Just add the listener, because the element will soon be detectable.\n addListener(callOnAdd, element, listener);\n onReadyCallbacks[id] = onReadyCallbacks[id] || [];\n onReadyCallbacks[id].push(function onReady() {\n elementsReady++;\n\n if(elementsReady === elements.length) {\n onReadyCallback();\n }\n });\n return;\n }\n\n debug && reporter.log(id, \"Making detectable...\");\n //The element is not prepared to be detectable, so do prepare it and add a listener to it.\n elementUtils.markBusy(element, true);\n return detectionStrategy.makeDetectable({ debug: debug, important: importantCssRules }, element, function onElementDetectable(element) {\n debug && reporter.log(id, \"onElementDetectable\");\n\n if (stateHandler.getState(element)) {\n elementUtils.markAsDetectable(element);\n elementUtils.markBusy(element, false);\n detectionStrategy.addListener(element, onResizeCallback);\n addListener(callOnAdd, element, listener);\n\n // Since the element size might have changed since the call to \"listenTo\", we need to check for this change,\n // so that a resize event may be emitted.\n // Having the startSize object is optional (since it does not make sense in some cases such as unrendered elements), so check for its existance before.\n // Also, check the state existance before since the element may have been uninstalled in the installation process.\n var state = stateHandler.getState(element);\n if (state && state.startSize) {\n var width = element.offsetWidth;\n var height = element.offsetHeight;\n if (state.startSize.width !== width || state.startSize.height !== height) {\n onResizeCallback(element);\n }\n }\n\n if(onReadyCallbacks[id]) {\n forEach(onReadyCallbacks[id], function(callback) {\n callback();\n });\n }\n } else {\n // The element has been unisntalled before being detectable.\n debug && reporter.log(id, \"Element uninstalled before being detectable.\");\n }\n\n delete onReadyCallbacks[id];\n\n elementsReady++;\n if(elementsReady === elements.length) {\n onReadyCallback();\n }\n });\n }\n\n debug && reporter.log(id, \"Already detecable, adding listener.\");\n\n //The element has been prepared to be detectable and is ready to be listened to.\n addListener(callOnAdd, element, listener);\n elementsReady++;\n });\n\n if(elementsReady === elements.length) {\n onReadyCallback();\n }\n }\n\n function uninstall(elements) {\n if(!elements) {\n return reporter.error(\"At least one element is required.\");\n }\n\n if (isElement(elements)) {\n // A single element has been passed in.\n elements = [elements];\n } else if (isCollection(elements)) {\n // Convert collection to array for plugins.\n // TODO: May want to check so that all the elements in the collection are valid elements.\n elements = toArray(elements);\n } else {\n return reporter.error(\"Invalid arguments. Must be a DOM element or a collection of DOM elements.\");\n }\n\n forEach(elements, function (element) {\n eventListenerHandler.removeAllListeners(element);\n detectionStrategy.uninstall(element);\n stateHandler.cleanState(element);\n });\n }\n\n function initDocument(targetDocument) {\n detectionStrategy.initDocument && detectionStrategy.initDocument(targetDocument);\n }\n\n return {\n listenTo: listenTo,\n removeListener: eventListenerHandler.removeListener,\n removeAllListeners: eventListenerHandler.removeAllListeners,\n uninstall: uninstall,\n initDocument: initDocument\n };\n};\n\nfunction getOption(options, name, defaultValue) {\n var value = options[name];\n\n if((value === undefined || value === null) && defaultValue !== undefined) {\n return defaultValue;\n }\n\n return value;\n}\n","'use strict';\nvar $defineProperty = require('./_object-dp');\nvar createDesc = require('./_property-desc');\n\nmodule.exports = function (object, index, value) {\n if (index in object) $defineProperty.f(object, index, createDesc(0, value));\n else object[index] = value;\n};\n","// document.currentScript polyfill by Adam Miller\n\n// MIT license\n\n(function(document){\n var currentScript = \"currentScript\",\n scripts = document.getElementsByTagName('script'); // Live NodeList collection\n\n // If browser needs currentScript polyfill, add get currentScript() to the document object\n if (!(currentScript in document)) {\n Object.defineProperty(document, currentScript, {\n get: function(){\n\n // IE 6-10 supports script readyState\n // IE 10+ support stack trace\n try { throw new Error(); }\n catch (err) {\n\n // Find the second match for the \"at\" string to get file src url from stack.\n // Specifically works with the format of stack traces in IE.\n var i, res = ((/.*at [^\\(]*\\((.*):.+:.+\\)$/ig).exec(err.stack) || [false])[1];\n\n // For all scripts on the page, if src matches or if ready state is interactive, return the script tag\n for(i in scripts){\n if(scripts[i].src == res || scripts[i].readyState == \"interactive\"){\n return scripts[i];\n }\n }\n\n // If no match, return null\n return null;\n }\n }\n });\n }\n})(document);\n","// 19.1.3.1 Object.assign(target, source)\nvar $export = require('./_export');\n\n$export($export.S + $export.F, 'Object', { assign: require('./_object-assign') });\n","module.exports = require('./_shared')('native-function-to-string', Function.toString);\n","var document = require('./_global').document;\nmodule.exports = document && document.documentElement;\n","// This file is imported into lib/wc client bundles.\n\nif (typeof window !== 'undefined') {\n if (process.env.NEED_CURRENTSCRIPT_POLYFILL) {\n require('current-script-polyfill')\n }\n\n var i\n if ((i = window.document.currentScript) && (i = i.src.match(/(.+\\/)[^/]+\\.js(\\?.*)?$/))) {\n __webpack_public_path__ = i[1] // eslint-disable-line\n }\n}\n\n// Indicate to webpack that this file can be concatenated\nexport default null\n","import './setPublicPath'\nimport mod from '~entry'\nexport default mod\nexport * from '~entry'\n","// 20.1.2.2 Number.isFinite(number)\nvar $export = require('./_export');\nvar _isFinite = require('./_global').isFinite;\n\n$export($export.S, 'Number', {\n isFinite: function isFinite(it) {\n return typeof it == 'number' && _isFinite(it);\n }\n});\n","module.exports = '\\x09\\x0A\\x0B\\x0C\\x0D\\x20\\xA0\\u1680\\u180E\\u2000\\u2001\\u2002\\u2003' +\n '\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\u2028\\u2029\\uFEFF';\n"],"sourceRoot":""} \ No newline at end of file diff --git a/dist/vue-grid-layout.js b/dist/vue-grid-layout.js deleted file mode 100644 index 8398b1dc..00000000 --- a/dist/vue-grid-layout.js +++ /dev/null @@ -1,339 +0,0 @@ -(function webpackUniversalModuleDefinition(root, factory) { - if(typeof exports === 'object' && typeof module === 'object') - module.exports = factory(); - else if(typeof define === 'function' && define.amd) - define([], factory); - else if(typeof exports === 'object') - exports["VueGridLayout"] = factory(); - else - root["VueGridLayout"] = factory(); -})(this, function() { -return /******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { -/******/ configurable: false, -/******/ enumerable: true, -/******/ get: getter -/******/ }); -/******/ } -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 9); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -eval("/* WEBPACK VAR INJECTION */(function(process) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.bottom = bottom;\nexports.cloneLayout = cloneLayout;\nexports.cloneLayoutItem = cloneLayoutItem;\nexports.collides = collides;\nexports.compact = compact;\nexports.compactItem = compactItem;\nexports.correctBounds = correctBounds;\nexports.getLayoutItem = getLayoutItem;\nexports.getFirstCollision = getFirstCollision;\nexports.getAllCollisions = getAllCollisions;\nexports.getStatics = getStatics;\nexports.moveElement = moveElement;\nexports.moveElementAwayFromCollision = moveElementAwayFromCollision;\nexports.perc = perc;\nexports.setTransform = setTransform;\nexports.setTransformRtl = setTransformRtl;\nexports.setTopLeft = setTopLeft;\nexports.setTopRight = setTopRight;\nexports.sortLayoutItemsByRowCol = sortLayoutItemsByRowCol;\nexports.validateLayout = validateLayout;\nexports.autoBindHandlers = autoBindHandlers;\nexports.createMarkup = createMarkup;\nexports.addPx = addPx;\nexports.hyphenate = hyphenate;\nexports.findItemInArray = findItemInArray;\nexports.findAndRemove = findAndRemove;\n// @flow\n/*:: export type LayoutItemRequired = {w: number, h: number, x: number, y: number, i: string};*/\n/*:: export type LayoutItem = LayoutItemRequired &\r\n {minW?: number, minH?: number, maxW?: number, maxH?: number,\r\n moved?: boolean, static?: boolean,\r\n isDraggable?: ?boolean, isResizable?: ?boolean};*/\n/*:: export type Layout = Array;*/\n/*:: export type Position = {left: number, top: number, width: number, height: number};*/\n/*:: export type DragCallbackData = {\r\n node: HTMLElement,\r\n x: number, y: number,\r\n deltaX: number, deltaY: number,\r\n lastX: number, lastY: number\r\n};*/\n/*:: export type DragEvent = {e: Event} & DragCallbackData;*/\n/*:: export type Size = {width: number, height: number};*/\n/*:: export type ResizeEvent = {e: Event, node: HTMLElement, size: Size};*/\n\n\nvar isProduction = process.env.NODE_ENV === 'production';\n/**\r\n * Return the bottom coordinate of the layout.\r\n *\r\n * @param {Array} layout Layout array.\r\n * @return {Number} Bottom coordinate.\r\n */\nfunction bottom(layout /*: Layout*/) /*: number*/ {\n var max = 0,\n bottomY = void 0;\n for (var _i = 0, len = layout.length; _i < len; _i++) {\n bottomY = layout[_i].y + layout[_i].h;\n if (bottomY > max) max = bottomY;\n }\n return max;\n}\n\nfunction cloneLayout(layout /*: Layout*/) /*: Layout*/ {\n var newLayout = Array(layout.length);\n for (var _i2 = 0, len = layout.length; _i2 < len; _i2++) {\n newLayout[_i2] = cloneLayoutItem(layout[_i2]);\n }\n return newLayout;\n}\n\n// Fast path to cloning, since this is monomorphic\nfunction cloneLayoutItem(layoutItem /*: LayoutItem*/) /*: LayoutItem*/ {\n /*return {\r\n w: layoutItem.w, h: layoutItem.h, x: layoutItem.x, y: layoutItem.y, i: layoutItem.i,\r\n minW: layoutItem.minW, maxW: layoutItem.maxW, minH: layoutItem.minH, maxH: layoutItem.maxH,\r\n moved: Boolean(layoutItem.moved), static: Boolean(layoutItem.static),\r\n // These can be null\r\n isDraggable: layoutItem.isDraggable, isResizable: layoutItem.isResizable\r\n };*/\n return JSON.parse(JSON.stringify(layoutItem));\n}\n\n/**\r\n * Given two layoutitems, check if they collide.\r\n *\r\n * @return {Boolean} True if colliding.\r\n */\nfunction collides(l1 /*: LayoutItem*/, l2 /*: LayoutItem*/) /*: boolean*/ {\n if (l1 === l2) return false; // same element\n if (l1.x + l1.w <= l2.x) return false; // l1 is left of l2\n if (l1.x >= l2.x + l2.w) return false; // l1 is right of l2\n if (l1.y + l1.h <= l2.y) return false; // l1 is above l2\n if (l1.y >= l2.y + l2.h) return false; // l1 is below l2\n return true; // boxes overlap\n}\n\n/**\r\n * Given a layout, compact it. This involves going down each y coordinate and removing gaps\r\n * between items.\r\n *\r\n * @param {Array} layout Layout.\r\n * @param {Boolean} verticalCompact Whether or not to compact the layout\r\n * vertically.\r\n * @return {Array} Compacted Layout.\r\n */\nfunction compact(layout /*: Layout*/, verticalCompact /*: Boolean*/) /*: Layout*/ {\n // Statics go in the compareWith array right away so items flow around them.\n var compareWith = getStatics(layout);\n // We go through the items by row and column.\n var sorted = sortLayoutItemsByRowCol(layout);\n // Holding for new items.\n var out = Array(layout.length);\n\n for (var _i3 = 0, len = sorted.length; _i3 < len; _i3++) {\n var l = sorted[_i3];\n\n // Don't move static elements\n if (!l.static) {\n l = compactItem(compareWith, l, verticalCompact);\n\n // Add to comparison array. We only collide with items before this one.\n // Statics are already in this array.\n compareWith.push(l);\n }\n\n // Add to output array to make sure they still come out in the right order.\n out[layout.indexOf(l)] = l;\n\n // Clear moved flag, if it exists.\n l.moved = false;\n }\n\n return out;\n}\n\n/**\r\n * Compact an item in the layout.\r\n */\nfunction compactItem(compareWith /*: Layout*/, l /*: LayoutItem*/, verticalCompact /*: boolean*/) /*: LayoutItem*/ {\n if (verticalCompact) {\n // Move the element up as far as it can go without colliding.\n while (l.y > 0 && !getFirstCollision(compareWith, l)) {\n l.y--;\n }\n }\n\n // Move it down, and keep moving it down if it's colliding.\n var collides = void 0;\n while (collides = getFirstCollision(compareWith, l)) {\n l.y = collides.y + collides.h;\n }\n return l;\n}\n\n/**\r\n * Given a layout, make sure all elements fit within its bounds.\r\n *\r\n * @param {Array} layout Layout array.\r\n * @param {Number} bounds Number of columns.\r\n */\nfunction correctBounds(layout /*: Layout*/, bounds /*: {cols: number}*/) /*: Layout*/ {\n var collidesWith = getStatics(layout);\n for (var _i4 = 0, len = layout.length; _i4 < len; _i4++) {\n var l = layout[_i4];\n // Overflows right\n if (l.x + l.w > bounds.cols) l.x = bounds.cols - l.w;\n // Overflows left\n if (l.x < 0) {\n l.x = 0;\n l.w = bounds.cols;\n }\n if (!l.static) collidesWith.push(l);else {\n // If this is static and collides with other statics, we must move it down.\n // We have to do something nicer than just letting them overlap.\n while (getFirstCollision(collidesWith, l)) {\n l.y++;\n }\n }\n }\n return layout;\n}\n\n/**\r\n * Get a layout item by ID. Used so we can override later on if necessary.\r\n *\r\n * @param {Array} layout Layout array.\r\n * @param {String} id ID\r\n * @return {LayoutItem} Item at ID.\r\n */\nfunction getLayoutItem(layout /*: Layout*/, id /*: string*/) /*: ?LayoutItem*/ {\n for (var _i5 = 0, len = layout.length; _i5 < len; _i5++) {\n if (layout[_i5].i === id) return layout[_i5];\n }\n}\n\n/**\r\n * Returns the first item this layout collides with.\r\n * It doesn't appear to matter which order we approach this from, although\r\n * perhaps that is the wrong thing to do.\r\n *\r\n * @param {Object} layoutItem Layout item.\r\n * @return {Object|undefined} A colliding layout item, or undefined.\r\n */\nfunction getFirstCollision(layout /*: Layout*/, layoutItem /*: LayoutItem*/) /*: ?LayoutItem*/ {\n for (var _i6 = 0, len = layout.length; _i6 < len; _i6++) {\n if (collides(layout[_i6], layoutItem)) return layout[_i6];\n }\n}\n\nfunction getAllCollisions(layout /*: Layout*/, layoutItem /*: LayoutItem*/) /*: Array*/ {\n return layout.filter(function (l) {\n return collides(l, layoutItem);\n });\n}\n\n/**\r\n * Get all static elements.\r\n * @param {Array} layout Array of layout objects.\r\n * @return {Array} Array of static layout items..\r\n */\nfunction getStatics(layout /*: Layout*/) /*: Array*/ {\n //return [];\n return layout.filter(function (l) {\n return l.static;\n });\n}\n\n/**\r\n * Move an element. Responsible for doing cascading movements of other elements.\r\n *\r\n * @param {Array} layout Full layout to modify.\r\n * @param {LayoutItem} l element to move.\r\n * @param {Number} [x] X position in grid units.\r\n * @param {Number} [y] Y position in grid units.\r\n * @param {Boolean} [isUserAction] If true, designates that the item we're moving is\r\n * being dragged/resized by th euser.\r\n */\nfunction moveElement(layout /*: Layout*/, l /*: LayoutItem*/, x /*: Number*/, y /*: Number*/, isUserAction /*: Boolean*/) /*: Layout*/ {\n if (l.static) return layout;\n\n // Short-circuit if nothing to do.\n //if (l.y === y && l.x === x) return layout;\n\n var movingUp = y && l.y > y;\n // This is quite a bit faster than extending the object\n if (typeof x === 'number') l.x = x;\n if (typeof y === 'number') l.y = y;\n l.moved = true;\n\n // If this collides with anything, move it.\n // When doing this comparison, we have to sort the items we compare with\n // to ensure, in the case of multiple collisions, that we're getting the\n // nearest collision.\n var sorted = sortLayoutItemsByRowCol(layout);\n if (movingUp) sorted = sorted.reverse();\n var collisions = getAllCollisions(sorted, l);\n\n // Move each item that collides away from this element.\n for (var _i7 = 0, len = collisions.length; _i7 < len; _i7++) {\n var collision = collisions[_i7];\n // console.log('resolving collision between', l.i, 'at', l.y, 'and', collision.i, 'at', collision.y);\n\n // Short circuit so we can't infinite loop\n if (collision.moved) continue;\n\n // This makes it feel a bit more precise by waiting to swap for just a bit when moving up.\n if (l.y > collision.y && l.y - collision.y > collision.h / 4) continue;\n\n // Don't move static items - we have to move *this* element away\n if (collision.static) {\n layout = moveElementAwayFromCollision(layout, collision, l, isUserAction);\n } else {\n layout = moveElementAwayFromCollision(layout, l, collision, isUserAction);\n }\n }\n\n return layout;\n}\n\n/**\r\n * This is where the magic needs to happen - given a collision, move an element away from the collision.\r\n * We attempt to move it up if there's room, otherwise it goes below.\r\n *\r\n * @param {Array} layout Full layout to modify.\r\n * @param {LayoutItem} collidesWith Layout item we're colliding with.\r\n * @param {LayoutItem} itemToMove Layout item we're moving.\r\n * @param {Boolean} [isUserAction] If true, designates that the item we're moving is being dragged/resized\r\n * by the user.\r\n */\nfunction moveElementAwayFromCollision(layout /*: Layout*/, collidesWith /*: LayoutItem*/, itemToMove /*: LayoutItem*/, isUserAction /*: ?boolean*/) /*: Layout*/ {\n\n // If there is enough space above the collision to put this element, move it there.\n // We only do this on the main collision as this can get funky in cascades and cause\n // unwanted swapping behavior.\n if (isUserAction) {\n // Make a mock item so we don't modify the item here, only modify in moveElement.\n var fakeItem /*: LayoutItem*/ = {\n x: itemToMove.x,\n y: itemToMove.y,\n w: itemToMove.w,\n h: itemToMove.h,\n i: '-1'\n };\n fakeItem.y = Math.max(collidesWith.y - itemToMove.h, 0);\n if (!getFirstCollision(layout, fakeItem)) {\n return moveElement(layout, itemToMove, undefined, fakeItem.y);\n }\n }\n\n // Previously this was optimized to move below the collision directly, but this can cause problems\n // with cascading moves, as an item may actually leapflog a collision and cause a reversal in order.\n return moveElement(layout, itemToMove, undefined, itemToMove.y + 1);\n}\n\n/**\r\n * Helper to convert a number to a percentage string.\r\n *\r\n * @param {Number} num Any number\r\n * @return {String} That number as a percentage.\r\n */\nfunction perc(num /*: number*/) /*: string*/ {\n return num * 100 + '%';\n}\n\nfunction setTransform(top, left, width, height) /*: Object*/ {\n // Replace unitless items with px\n var translate = \"translate3d(\" + left + \"px,\" + top + \"px, 0)\";\n return {\n transform: translate,\n WebkitTransform: translate,\n MozTransform: translate,\n msTransform: translate,\n OTransform: translate,\n width: width + \"px\",\n height: height + \"px\",\n position: 'absolute'\n };\n}\n/**\r\n * Just like the setTransform method, but instead it will return a negative value of right.\r\n *\r\n * @param top\r\n * @param right\r\n * @param width\r\n * @param height\r\n * @returns {{transform: string, WebkitTransform: string, MozTransform: string, msTransform: string, OTransform: string, width: string, height: string, position: string}}\r\n */\nfunction setTransformRtl(top, right, width, height) /*: Object*/ {\n // Replace unitless items with px\n var translate = \"translate3d(\" + right * -1 + \"px,\" + top + \"px, 0)\";\n return {\n transform: translate,\n WebkitTransform: translate,\n MozTransform: translate,\n msTransform: translate,\n OTransform: translate,\n width: width + \"px\",\n height: height + \"px\",\n position: 'absolute'\n };\n}\n\nfunction setTopLeft(top, left, width, height) /*: Object*/ {\n return {\n top: top + \"px\",\n left: left + \"px\",\n width: width + \"px\",\n height: height + \"px\",\n position: 'absolute'\n };\n}\n/**\r\n * Just like the setTopLeft method, but instead, it will return a right property instead of left.\r\n *\r\n * @param top\r\n * @param right\r\n * @param width\r\n * @param height\r\n * @returns {{top: string, right: string, width: string, height: string, position: string}}\r\n */\nfunction setTopRight(top, right, width, height) /*: Object*/ {\n return {\n top: top + \"px\",\n right: right + \"px\",\n width: width + \"px\",\n height: height + \"px\",\n position: 'absolute'\n };\n}\n\n/**\r\n * Get layout items sorted from top left to right and down.\r\n *\r\n * @return {Array} Array of layout objects.\r\n * @return {Array} Layout, sorted static items first.\r\n */\nfunction sortLayoutItemsByRowCol(layout /*: Layout*/) /*: Layout*/ {\n return [].concat(layout).sort(function (a, b) {\n if (a.y > b.y || a.y === b.y && a.x > b.x) {\n return 1;\n }\n return -1;\n });\n}\n\n/**\r\n * Generate a layout using the initialLayout and children as a template.\r\n * Missing entries will be added, extraneous ones will be truncated.\r\n *\r\n * @param {Array} initialLayout Layout passed in through props.\r\n * @param {String} breakpoint Current responsive breakpoint.\r\n * @param {Boolean} verticalCompact Whether or not to compact the layout vertically.\r\n * @return {Array} Working layout.\r\n */\n/*\r\nexport function synchronizeLayoutWithChildren(initialLayout: Layout, children: Array|React.Element,\r\n cols: number, verticalCompact: boolean): Layout {\r\n // ensure 'children' is always an array\r\n if (!Array.isArray(children)) {\r\n children = [children];\r\n }\r\n initialLayout = initialLayout || [];\r\n\r\n // Generate one layout item per child.\r\n let layout: Layout = [];\r\n for (let i = 0, len = children.length; i < len; i++) {\r\n let newItem;\r\n const child = children[i];\r\n\r\n // Don't overwrite if it already exists.\r\n const exists = getLayoutItem(initialLayout, child.key || \"1\" /!* FIXME satisfies Flow *!/);\r\n if (exists) {\r\n newItem = exists;\r\n } else {\r\n const g = child.props._grid;\r\n\r\n // Hey, this item has a _grid property, use it.\r\n if (g) {\r\n if (!isProduction) {\r\n validateLayout([g], 'ReactGridLayout.children');\r\n }\r\n // Validated; add it to the layout. Bottom 'y' possible is the bottom of the layout.\r\n // This allows you to do nice stuff like specify {y: Infinity}\r\n if (verticalCompact) {\r\n newItem = cloneLayoutItem({...g, y: Math.min(bottom(layout), g.y), i: child.key});\r\n } else {\r\n newItem = cloneLayoutItem({...g, y: g.y, i: child.key});\r\n }\r\n }\r\n // Nothing provided: ensure this is added to the bottom\r\n else {\r\n newItem = cloneLayoutItem({w: 1, h: 1, x: 0, y: bottom(layout), i: child.key || \"1\"});\r\n }\r\n }\r\n layout[i] = newItem;\r\n }\r\n\r\n // Correct the layout.\r\n layout = correctBounds(layout, {cols: cols});\r\n layout = compact(layout, verticalCompact);\r\n\r\n return layout;\r\n}\r\n*/\n\n/**\r\n * Validate a layout. Throws errors.\r\n *\r\n * @param {Array} layout Array of layout items.\r\n * @param {String} [contextName] Context name for errors.\r\n * @throw {Error} Validation error.\r\n */\nfunction validateLayout(layout /*: Layout*/, contextName /*: string*/) /*: void*/ {\n contextName = contextName || \"Layout\";\n var subProps = ['x', 'y', 'w', 'h'];\n if (!Array.isArray(layout)) throw new Error(contextName + \" must be an array!\");\n for (var _i8 = 0, len = layout.length; _i8 < len; _i8++) {\n var item = layout[_i8];\n for (var j = 0; j < subProps.length; j++) {\n if (typeof item[subProps[j]] !== 'number') {\n throw new Error('VueGridLayout: ' + contextName + '[' + _i8 + '].' + subProps[j] + ' must be a number!');\n }\n }\n if (item.i && typeof item.i !== 'string') {\n throw new Error('VueGridLayout: ' + contextName + '[' + _i8 + '].i must be a string!');\n }\n if (item.static !== undefined && typeof item.static !== 'boolean') {\n throw new Error('VueGridLayout: ' + contextName + '[' + _i8 + '].static must be a boolean!');\n }\n }\n}\n\n// Flow can't really figure this out, so we just use Object\nfunction autoBindHandlers(el /*: Object*/, fns /*: Array*/) /*: void*/ {\n fns.forEach(function (key) {\n return el[key] = el[key].bind(el);\n });\n}\n\n/**\r\n * Convert a JS object to CSS string. Similar to React's output of CSS.\r\n * @param obj\r\n * @returns {string}\r\n */\nfunction createMarkup(obj) {\n var keys = Object.keys(obj);\n if (!keys.length) return '';\n var i,\n len = keys.length;\n var result = '';\n\n for (i = 0; i < len; i++) {\n var key = keys[i];\n var val = obj[key];\n result += hyphenate(key) + ':' + addPx(key, val) + ';';\n }\n\n return result;\n}\n\n/* The following list is defined in React's core */\nvar IS_UNITLESS = exports.IS_UNITLESS = {\n animationIterationCount: true,\n boxFlex: true,\n boxFlexGroup: true,\n boxOrdinalGroup: true,\n columnCount: true,\n flex: true,\n flexGrow: true,\n flexPositive: true,\n flexShrink: true,\n flexNegative: true,\n flexOrder: true,\n gridRow: true,\n gridColumn: true,\n fontWeight: true,\n lineClamp: true,\n lineHeight: true,\n opacity: true,\n order: true,\n orphans: true,\n tabSize: true,\n widows: true,\n zIndex: true,\n zoom: true,\n\n // SVG-related properties\n fillOpacity: true,\n stopOpacity: true,\n strokeDashoffset: true,\n strokeOpacity: true,\n strokeWidth: true\n};\n\n/**\r\n * Will add px to the end of style values which are Numbers.\r\n * @param name\r\n * @param value\r\n * @returns {*}\r\n */\nfunction addPx(name, value) {\n if (typeof value === 'number' && !IS_UNITLESS[name]) {\n return value + 'px';\n } else {\n return value;\n }\n}\n\n/**\r\n * Hyphenate a camelCase string.\r\n *\r\n * @param {String} str\r\n * @return {String}\r\n */\n\nvar hyphenateRE = exports.hyphenateRE = /([a-z\\d])([A-Z])/g;\n\nfunction hyphenate(str) {\n return str.replace(hyphenateRE, '$1-$2').toLowerCase();\n}\n\nfunction findItemInArray(array, property, value) {\n for (var i = 0; i < array.length; i++) {\n if (array[i][property] == value) return true;\n }return false;\n}\n\nfunction findAndRemove(array, property, value) {\n array.forEach(function (result, index) {\n if (result[property] === value) {\n //Remove from array\n array.splice(index, 1);\n }\n });\n}\n/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(5)))\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvdXRpbHMuanM/MmZmOCJdLCJuYW1lcyI6WyJib3R0b20iLCJjbG9uZUxheW91dCIsImNsb25lTGF5b3V0SXRlbSIsImNvbGxpZGVzIiwiY29tcGFjdCIsImNvbXBhY3RJdGVtIiwiY29ycmVjdEJvdW5kcyIsImdldExheW91dEl0ZW0iLCJnZXRGaXJzdENvbGxpc2lvbiIsImdldEFsbENvbGxpc2lvbnMiLCJnZXRTdGF0aWNzIiwibW92ZUVsZW1lbnQiLCJtb3ZlRWxlbWVudEF3YXlGcm9tQ29sbGlzaW9uIiwicGVyYyIsInNldFRyYW5zZm9ybSIsInNldFRyYW5zZm9ybVJ0bCIsInNldFRvcExlZnQiLCJzZXRUb3BSaWdodCIsInNvcnRMYXlvdXRJdGVtc0J5Um93Q29sIiwidmFsaWRhdGVMYXlvdXQiLCJhdXRvQmluZEhhbmRsZXJzIiwiY3JlYXRlTWFya3VwIiwiYWRkUHgiLCJoeXBoZW5hdGUiLCJmaW5kSXRlbUluQXJyYXkiLCJmaW5kQW5kUmVtb3ZlIiwiaXNQcm9kdWN0aW9uIiwicHJvY2VzcyIsImVudiIsIk5PREVfRU5WIiwibGF5b3V0IiwibWF4IiwiYm90dG9tWSIsImkiLCJsZW4iLCJsZW5ndGgiLCJ5IiwiaCIsIm5ld0xheW91dCIsIkFycmF5IiwibGF5b3V0SXRlbSIsIkpTT04iLCJwYXJzZSIsInN0cmluZ2lmeSIsImwxIiwibDIiLCJ4IiwidyIsInZlcnRpY2FsQ29tcGFjdCIsImNvbXBhcmVXaXRoIiwic29ydGVkIiwib3V0IiwibCIsInN0YXRpYyIsInB1c2giLCJpbmRleE9mIiwibW92ZWQiLCJib3VuZHMiLCJjb2xsaWRlc1dpdGgiLCJjb2xzIiwiaWQiLCJmaWx0ZXIiLCJpc1VzZXJBY3Rpb24iLCJtb3ZpbmdVcCIsInJldmVyc2UiLCJjb2xsaXNpb25zIiwiY29sbGlzaW9uIiwiaXRlbVRvTW92ZSIsImZha2VJdGVtIiwiTWF0aCIsInVuZGVmaW5lZCIsIm51bSIsInRvcCIsImxlZnQiLCJ3aWR0aCIsImhlaWdodCIsInRyYW5zbGF0ZSIsInRyYW5zZm9ybSIsIldlYmtpdFRyYW5zZm9ybSIsIk1velRyYW5zZm9ybSIsIm1zVHJhbnNmb3JtIiwiT1RyYW5zZm9ybSIsInBvc2l0aW9uIiwicmlnaHQiLCJjb25jYXQiLCJzb3J0IiwiYSIsImIiLCJjb250ZXh0TmFtZSIsInN1YlByb3BzIiwiaXNBcnJheSIsIkVycm9yIiwiaXRlbSIsImoiLCJlbCIsImZucyIsImZvckVhY2giLCJrZXkiLCJiaW5kIiwib2JqIiwia2V5cyIsIk9iamVjdCIsInJlc3VsdCIsInZhbCIsIklTX1VOSVRMRVNTIiwiYW5pbWF0aW9uSXRlcmF0aW9uQ291bnQiLCJib3hGbGV4IiwiYm94RmxleEdyb3VwIiwiYm94T3JkaW5hbEdyb3VwIiwiY29sdW1uQ291bnQiLCJmbGV4IiwiZmxleEdyb3ciLCJmbGV4UG9zaXRpdmUiLCJmbGV4U2hyaW5rIiwiZmxleE5lZ2F0aXZlIiwiZmxleE9yZGVyIiwiZ3JpZFJvdyIsImdyaWRDb2x1bW4iLCJmb250V2VpZ2h0IiwibGluZUNsYW1wIiwibGluZUhlaWdodCIsIm9wYWNpdHkiLCJvcmRlciIsIm9ycGhhbnMiLCJ0YWJTaXplIiwid2lkb3dzIiwiekluZGV4Iiwiem9vbSIsImZpbGxPcGFjaXR5Iiwic3RvcE9wYWNpdHkiLCJzdHJva2VEYXNob2Zmc2V0Iiwic3Ryb2tlT3BhY2l0eSIsInN0cm9rZVdpZHRoIiwibmFtZSIsInZhbHVlIiwiaHlwaGVuYXRlUkUiLCJzdHIiLCJyZXBsYWNlIiwidG9Mb3dlckNhc2UiLCJhcnJheSIsInByb3BlcnR5IiwiaW5kZXgiLCJzcGxpY2UiXSwibWFwcGluZ3MiOiI7Ozs7O1FBeUJnQkEsTSxHQUFBQSxNO1FBU0FDLFcsR0FBQUEsVztRQVNBQyxlLEdBQUFBLGU7UUFnQkFDLFEsR0FBQUEsUTtRQWtCQUMsTyxHQUFBQSxPO1FBaUNBQyxXLEdBQUFBLFc7UUFzQkFDLGEsR0FBQUEsYTtRQThCQUMsYSxHQUFBQSxhO1FBY0FDLGlCLEdBQUFBLGlCO1FBTUFDLGdCLEdBQUFBLGdCO1FBU0FDLFUsR0FBQUEsVTtRQWVBQyxXLEdBQUFBLFc7UUFvREFDLDRCLEdBQUFBLDRCO1FBZ0NBQyxJLEdBQUFBLEk7UUFJQUMsWSxHQUFBQSxZO1FBdUJBQyxlLEdBQUFBLGU7UUFlQUMsVSxHQUFBQSxVO1FBa0JBQyxXLEdBQUFBLFc7UUFpQkFDLHVCLEdBQUFBLHVCO1FBNEVBQyxjLEdBQUFBLGM7UUFxQkFDLGdCLEdBQUFBLGdCO1FBV0FDLFksR0FBQUEsWTtRQXlEQUMsSyxHQUFBQSxLO1FBa0JBQyxTLEdBQUFBLFM7UUFLQUMsZSxHQUFBQSxlO1FBUUFDLGEsR0FBQUEsYTtBQW5qQmhCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBa0JBLElBQU1DLGVBQWVDLFFBQVFDLEdBQVIsQ0FBWUMsUUFBWixLQUF5QixZQUE5QztBQUNBOzs7Ozs7QUFNTyxTQUFTN0IsTUFBVCxDQUFnQjhCLE1BQWhCLDRCQUF3QztBQUM3QyxNQUFJQyxNQUFNLENBQVY7QUFBQSxNQUFhQyxnQkFBYjtBQUNBLE9BQUssSUFBSUMsS0FBSSxDQUFSLEVBQVdDLE1BQU1KLE9BQU9LLE1BQTdCLEVBQXFDRixLQUFJQyxHQUF6QyxFQUE4Q0QsSUFBOUMsRUFBbUQ7QUFDakRELGNBQVVGLE9BQU9HLEVBQVAsRUFBV0csQ0FBWCxHQUFlTixPQUFPRyxFQUFQLEVBQVVJLENBQW5DO0FBQ0EsUUFBSUwsVUFBVUQsR0FBZCxFQUFtQkEsTUFBTUMsT0FBTjtBQUNwQjtBQUNELFNBQU9ELEdBQVA7QUFDRDs7QUFFTSxTQUFTOUIsV0FBVCxDQUFxQjZCLE1BQXJCLDRCQUE2QztBQUNsRCxNQUFNUSxZQUFZQyxNQUFNVCxPQUFPSyxNQUFiLENBQWxCO0FBQ0EsT0FBSyxJQUFJRixNQUFJLENBQVIsRUFBV0MsTUFBTUosT0FBT0ssTUFBN0IsRUFBcUNGLE1BQUlDLEdBQXpDLEVBQThDRCxLQUE5QyxFQUFtRDtBQUNqREssY0FBVUwsR0FBVixJQUFlL0IsZ0JBQWdCNEIsT0FBT0csR0FBUCxDQUFoQixDQUFmO0FBQ0Q7QUFDRCxTQUFPSyxTQUFQO0FBQ0Q7O0FBRUQ7QUFDTyxTQUFTcEMsZUFBVCxDQUF5QnNDLFVBQXpCLG9DQUE2RDtBQUNsRTs7Ozs7OztBQU9FLFNBQU9DLEtBQUtDLEtBQUwsQ0FBV0QsS0FBS0UsU0FBTCxDQUFlSCxVQUFmLENBQVgsQ0FBUDtBQUNIOztBQUVEOzs7OztBQUtPLFNBQVNyQyxRQUFULENBQWtCeUMsRUFBbEIsbUJBQWtDQyxFQUFsQyxpQ0FBMkQ7QUFDaEUsTUFBSUQsT0FBT0MsRUFBWCxFQUFlLE9BQU8sS0FBUCxDQURpRCxDQUNuQztBQUM3QixNQUFJRCxHQUFHRSxDQUFILEdBQU9GLEdBQUdHLENBQVYsSUFBZUYsR0FBR0MsQ0FBdEIsRUFBeUIsT0FBTyxLQUFQLENBRnVDLENBRXpCO0FBQ3ZDLE1BQUlGLEdBQUdFLENBQUgsSUFBUUQsR0FBR0MsQ0FBSCxHQUFPRCxHQUFHRSxDQUF0QixFQUF5QixPQUFPLEtBQVAsQ0FIdUMsQ0FHekI7QUFDdkMsTUFBSUgsR0FBR1IsQ0FBSCxHQUFPUSxHQUFHUCxDQUFWLElBQWVRLEdBQUdULENBQXRCLEVBQXlCLE9BQU8sS0FBUCxDQUp1QyxDQUl6QjtBQUN2QyxNQUFJUSxHQUFHUixDQUFILElBQVFTLEdBQUdULENBQUgsR0FBT1MsR0FBR1IsQ0FBdEIsRUFBeUIsT0FBTyxLQUFQLENBTHVDLENBS3pCO0FBQ3ZDLFNBQU8sSUFBUCxDQU5nRSxDQU1uRDtBQUNkOztBQUVEOzs7Ozs7Ozs7QUFTTyxTQUFTakMsT0FBVCxDQUFpQjBCLE1BQWpCLGVBQWlDa0IsZUFBakMsNkJBQW1FO0FBQ3RFO0FBQ0YsTUFBTUMsY0FBY3ZDLFdBQVdvQixNQUFYLENBQXBCO0FBQ0E7QUFDQSxNQUFNb0IsU0FBU2hDLHdCQUF3QlksTUFBeEIsQ0FBZjtBQUNBO0FBQ0EsTUFBTXFCLE1BQU1aLE1BQU1ULE9BQU9LLE1BQWIsQ0FBWjs7QUFFQSxPQUFLLElBQUlGLE1BQUksQ0FBUixFQUFXQyxNQUFNZ0IsT0FBT2YsTUFBN0IsRUFBcUNGLE1BQUlDLEdBQXpDLEVBQThDRCxLQUE5QyxFQUFtRDtBQUNqRCxRQUFJbUIsSUFBSUYsT0FBT2pCLEdBQVAsQ0FBUjs7QUFFQTtBQUNBLFFBQUksQ0FBQ21CLEVBQUVDLE1BQVAsRUFBZTtBQUNiRCxVQUFJL0MsWUFBWTRDLFdBQVosRUFBeUJHLENBQXpCLEVBQTRCSixlQUE1QixDQUFKOztBQUVBO0FBQ0E7QUFDQUMsa0JBQVlLLElBQVosQ0FBaUJGLENBQWpCO0FBQ0Q7O0FBRUQ7QUFDQUQsUUFBSXJCLE9BQU95QixPQUFQLENBQWVILENBQWYsQ0FBSixJQUF5QkEsQ0FBekI7O0FBRUE7QUFDQUEsTUFBRUksS0FBRixHQUFVLEtBQVY7QUFDRDs7QUFFRCxTQUFPTCxHQUFQO0FBQ0Q7O0FBRUQ7OztBQUdPLFNBQVM5QyxXQUFULENBQXFCNEMsV0FBckIsZUFBMENHLENBQTFDLG1CQUF5REosZUFBekQsaUNBQStGO0FBQ3BHLE1BQUlBLGVBQUosRUFBcUI7QUFDbkI7QUFDQSxXQUFPSSxFQUFFaEIsQ0FBRixHQUFNLENBQU4sSUFBVyxDQUFDNUIsa0JBQWtCeUMsV0FBbEIsRUFBK0JHLENBQS9CLENBQW5CLEVBQXNEO0FBQ3BEQSxRQUFFaEIsQ0FBRjtBQUNEO0FBQ0Y7O0FBRUQ7QUFDQSxNQUFJakMsaUJBQUo7QUFDQSxTQUFPQSxXQUFXSyxrQkFBa0J5QyxXQUFsQixFQUErQkcsQ0FBL0IsQ0FBbEIsRUFBc0Q7QUFDcERBLE1BQUVoQixDQUFGLEdBQU1qQyxTQUFTaUMsQ0FBVCxHQUFhakMsU0FBU2tDLENBQTVCO0FBQ0Q7QUFDRCxTQUFPZSxDQUFQO0FBQ0Q7O0FBRUQ7Ozs7OztBQU1PLFNBQVM5QyxhQUFULENBQXVCd0IsTUFBdkIsZUFBdUMyQixNQUF2QyxvQ0FBdUU7QUFDNUUsTUFBTUMsZUFBZWhELFdBQVdvQixNQUFYLENBQXJCO0FBQ0EsT0FBSyxJQUFJRyxNQUFJLENBQVIsRUFBV0MsTUFBTUosT0FBT0ssTUFBN0IsRUFBcUNGLE1BQUlDLEdBQXpDLEVBQThDRCxLQUE5QyxFQUFtRDtBQUNqRCxRQUFNbUIsSUFBSXRCLE9BQU9HLEdBQVAsQ0FBVjtBQUNBO0FBQ0EsUUFBSW1CLEVBQUVOLENBQUYsR0FBTU0sRUFBRUwsQ0FBUixHQUFZVSxPQUFPRSxJQUF2QixFQUE2QlAsRUFBRU4sQ0FBRixHQUFNVyxPQUFPRSxJQUFQLEdBQWNQLEVBQUVMLENBQXRCO0FBQzdCO0FBQ0EsUUFBSUssRUFBRU4sQ0FBRixHQUFNLENBQVYsRUFBYTtBQUNYTSxRQUFFTixDQUFGLEdBQU0sQ0FBTjtBQUNBTSxRQUFFTCxDQUFGLEdBQU1VLE9BQU9FLElBQWI7QUFDRDtBQUNELFFBQUksQ0FBQ1AsRUFBRUMsTUFBUCxFQUFlSyxhQUFhSixJQUFiLENBQWtCRixDQUFsQixFQUFmLEtBQ0s7QUFDSDtBQUNBO0FBQ0EsYUFBTTVDLGtCQUFrQmtELFlBQWxCLEVBQWdDTixDQUFoQyxDQUFOLEVBQTBDO0FBQ3hDQSxVQUFFaEIsQ0FBRjtBQUNEO0FBQ0Y7QUFDRjtBQUNELFNBQU9OLE1BQVA7QUFDRDs7QUFFRDs7Ozs7OztBQU9PLFNBQVN2QixhQUFULENBQXVCdUIsTUFBdkIsZUFBdUM4QixFQUF2QyxpQ0FBZ0U7QUFDckUsT0FBSyxJQUFJM0IsTUFBSSxDQUFSLEVBQVdDLE1BQU1KLE9BQU9LLE1BQTdCLEVBQXFDRixNQUFJQyxHQUF6QyxFQUE4Q0QsS0FBOUMsRUFBbUQ7QUFDakQsUUFBSUgsT0FBT0csR0FBUCxFQUFVQSxDQUFWLEtBQWdCMkIsRUFBcEIsRUFBd0IsT0FBTzlCLE9BQU9HLEdBQVAsQ0FBUDtBQUN6QjtBQUNGOztBQUVEOzs7Ozs7OztBQVFPLFNBQVN6QixpQkFBVCxDQUEyQnNCLE1BQTNCLGVBQTJDVSxVQUEzQyxxQ0FBZ0Y7QUFDckYsT0FBSyxJQUFJUCxNQUFJLENBQVIsRUFBV0MsTUFBTUosT0FBT0ssTUFBN0IsRUFBcUNGLE1BQUlDLEdBQXpDLEVBQThDRCxLQUE5QyxFQUFtRDtBQUNqRCxRQUFJOUIsU0FBUzJCLE9BQU9HLEdBQVAsQ0FBVCxFQUFvQk8sVUFBcEIsQ0FBSixFQUFxQyxPQUFPVixPQUFPRyxHQUFQLENBQVA7QUFDdEM7QUFDRjs7QUFFTSxTQUFTeEIsZ0JBQVQsQ0FBMEJxQixNQUExQixlQUEwQ1UsVUFBMUMsMkNBQXFGO0FBQzFGLFNBQU9WLE9BQU8rQixNQUFQLENBQWMsVUFBQ1QsQ0FBRDtBQUFBLFdBQU9qRCxTQUFTaUQsQ0FBVCxFQUFZWixVQUFaLENBQVA7QUFBQSxHQUFkLENBQVA7QUFDRDs7QUFFRDs7Ozs7QUFLTyxTQUFTOUIsVUFBVCxDQUFvQm9CLE1BQXBCLHVDQUF1RDtBQUMxRDtBQUNBLFNBQU9BLE9BQU8rQixNQUFQLENBQWMsVUFBQ1QsQ0FBRDtBQUFBLFdBQU9BLEVBQUVDLE1BQVQ7QUFBQSxHQUFkLENBQVA7QUFDSDs7QUFFRDs7Ozs7Ozs7OztBQVVPLFNBQVMxQyxXQUFULENBQXFCbUIsTUFBckIsZUFBcUNzQixDQUFyQyxtQkFBb0ROLENBQXBELGVBQStEVixDQUEvRCxlQUEwRTBCLFlBQTFFLDZCQUF5RztBQUM5RyxNQUFJVixFQUFFQyxNQUFOLEVBQWMsT0FBT3ZCLE1BQVA7O0FBRWQ7QUFDQTs7QUFFQSxNQUFNaUMsV0FBVzNCLEtBQUtnQixFQUFFaEIsQ0FBRixHQUFNQSxDQUE1QjtBQUNBO0FBQ0EsTUFBSSxPQUFPVSxDQUFQLEtBQWEsUUFBakIsRUFBMkJNLEVBQUVOLENBQUYsR0FBTUEsQ0FBTjtBQUMzQixNQUFJLE9BQU9WLENBQVAsS0FBYSxRQUFqQixFQUEyQmdCLEVBQUVoQixDQUFGLEdBQU1BLENBQU47QUFDM0JnQixJQUFFSSxLQUFGLEdBQVUsSUFBVjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUlOLFNBQVNoQyx3QkFBd0JZLE1BQXhCLENBQWI7QUFDQSxNQUFJaUMsUUFBSixFQUFjYixTQUFTQSxPQUFPYyxPQUFQLEVBQVQ7QUFDZCxNQUFNQyxhQUFheEQsaUJBQWlCeUMsTUFBakIsRUFBeUJFLENBQXpCLENBQW5COztBQUVBO0FBQ0EsT0FBSyxJQUFJbkIsTUFBSSxDQUFSLEVBQVdDLE1BQU0rQixXQUFXOUIsTUFBakMsRUFBeUNGLE1BQUlDLEdBQTdDLEVBQWtERCxLQUFsRCxFQUF1RDtBQUNyRCxRQUFNaUMsWUFBWUQsV0FBV2hDLEdBQVgsQ0FBbEI7QUFDQTs7QUFFQTtBQUNBLFFBQUlpQyxVQUFVVixLQUFkLEVBQXFCOztBQUVyQjtBQUNBLFFBQUlKLEVBQUVoQixDQUFGLEdBQU04QixVQUFVOUIsQ0FBaEIsSUFBcUJnQixFQUFFaEIsQ0FBRixHQUFNOEIsVUFBVTlCLENBQWhCLEdBQW9COEIsVUFBVTdCLENBQVYsR0FBYyxDQUEzRCxFQUE4RDs7QUFFOUQ7QUFDQSxRQUFJNkIsVUFBVWIsTUFBZCxFQUFzQjtBQUNwQnZCLGVBQVNsQiw2QkFBNkJrQixNQUE3QixFQUFxQ29DLFNBQXJDLEVBQWdEZCxDQUFoRCxFQUFtRFUsWUFBbkQsQ0FBVDtBQUNELEtBRkQsTUFFTztBQUNMaEMsZUFBU2xCLDZCQUE2QmtCLE1BQTdCLEVBQXFDc0IsQ0FBckMsRUFBd0NjLFNBQXhDLEVBQW1ESixZQUFuRCxDQUFUO0FBQ0Q7QUFDRjs7QUFFRCxTQUFPaEMsTUFBUDtBQUNEOztBQUVEOzs7Ozs7Ozs7O0FBVU8sU0FBU2xCLDRCQUFULENBQXNDa0IsTUFBdEMsZUFBc0Q0QixZQUF0RCxtQkFDc0NTLFVBRHRDLG1CQUM4REwsWUFEOUQsOEJBQzhGOztBQUVuRztBQUNBO0FBQ0E7QUFDQSxNQUFJQSxZQUFKLEVBQWtCO0FBQ2hCO0FBQ0EsUUFBTU0sNEJBQXVCO0FBQzNCdEIsU0FBR3FCLFdBQVdyQixDQURhO0FBRTNCVixTQUFHK0IsV0FBVy9CLENBRmE7QUFHM0JXLFNBQUdvQixXQUFXcEIsQ0FIYTtBQUkzQlYsU0FBRzhCLFdBQVc5QixDQUphO0FBSzNCSixTQUFHO0FBTHdCLEtBQTdCO0FBT0FtQyxhQUFTaEMsQ0FBVCxHQUFhaUMsS0FBS3RDLEdBQUwsQ0FBUzJCLGFBQWF0QixDQUFiLEdBQWlCK0IsV0FBVzlCLENBQXJDLEVBQXdDLENBQXhDLENBQWI7QUFDQSxRQUFJLENBQUM3QixrQkFBa0JzQixNQUFsQixFQUEwQnNDLFFBQTFCLENBQUwsRUFBMEM7QUFDeEMsYUFBT3pELFlBQVltQixNQUFaLEVBQW9CcUMsVUFBcEIsRUFBZ0NHLFNBQWhDLEVBQTJDRixTQUFTaEMsQ0FBcEQsQ0FBUDtBQUNEO0FBQ0Y7O0FBRUQ7QUFDQTtBQUNBLFNBQU96QixZQUFZbUIsTUFBWixFQUFvQnFDLFVBQXBCLEVBQWdDRyxTQUFoQyxFQUEyQ0gsV0FBVy9CLENBQVgsR0FBZSxDQUExRCxDQUFQO0FBQ0Q7O0FBRUQ7Ozs7OztBQU1PLFNBQVN2QixJQUFULENBQWMwRCxHQUFkLDRCQUFtQztBQUN4QyxTQUFPQSxNQUFNLEdBQU4sR0FBWSxHQUFuQjtBQUNEOztBQUVNLFNBQVN6RCxZQUFULENBQXNCMEQsR0FBdEIsRUFBMkJDLElBQTNCLEVBQWlDQyxLQUFqQyxFQUF3Q0MsTUFBeEMsZUFBd0Q7QUFDN0Q7QUFDQSxNQUFNQyxZQUFZLGlCQUFpQkgsSUFBakIsR0FBd0IsS0FBeEIsR0FBZ0NELEdBQWhDLEdBQXNDLFFBQXhEO0FBQ0EsU0FBTztBQUNMSyxlQUFXRCxTQUROO0FBRUxFLHFCQUFpQkYsU0FGWjtBQUdMRyxrQkFBY0gsU0FIVDtBQUlMSSxpQkFBYUosU0FKUjtBQUtMSyxnQkFBWUwsU0FMUDtBQU1MRixXQUFPQSxRQUFRLElBTlY7QUFPTEMsWUFBUUEsU0FBUyxJQVBaO0FBUUxPLGNBQVU7QUFSTCxHQUFQO0FBVUQ7QUFDRDs7Ozs7Ozs7O0FBU08sU0FBU25FLGVBQVQsQ0FBeUJ5RCxHQUF6QixFQUE4QlcsS0FBOUIsRUFBcUNULEtBQXJDLEVBQTRDQyxNQUE1QyxlQUE0RDtBQUMvRDtBQUNBLE1BQU1DLFlBQVksaUJBQWlCTyxRQUFRLENBQUMsQ0FBMUIsR0FBOEIsS0FBOUIsR0FBc0NYLEdBQXRDLEdBQTRDLFFBQTlEO0FBQ0EsU0FBTztBQUNISyxlQUFXRCxTQURSO0FBRUhFLHFCQUFpQkYsU0FGZDtBQUdIRyxrQkFBY0gsU0FIWDtBQUlISSxpQkFBYUosU0FKVjtBQUtISyxnQkFBWUwsU0FMVDtBQU1IRixXQUFPQSxRQUFRLElBTlo7QUFPSEMsWUFBUUEsU0FBUyxJQVBkO0FBUUhPLGNBQVU7QUFSUCxHQUFQO0FBVUg7O0FBRU0sU0FBU2xFLFVBQVQsQ0FBb0J3RCxHQUFwQixFQUF5QkMsSUFBekIsRUFBK0JDLEtBQS9CLEVBQXNDQyxNQUF0QyxlQUFzRDtBQUN6RCxTQUFPO0FBQ0hILFNBQUtBLE1BQU0sSUFEUjtBQUVIQyxVQUFNQSxPQUFPLElBRlY7QUFHSEMsV0FBT0EsUUFBUSxJQUhaO0FBSUhDLFlBQVFBLFNBQVMsSUFKZDtBQUtITyxjQUFVO0FBTFAsR0FBUDtBQU9IO0FBQ0Q7Ozs7Ozs7OztBQVNPLFNBQVNqRSxXQUFULENBQXFCdUQsR0FBckIsRUFBMEJXLEtBQTFCLEVBQWlDVCxLQUFqQyxFQUF3Q0MsTUFBeEMsZUFBd0Q7QUFDM0QsU0FBTztBQUNISCxTQUFLQSxNQUFNLElBRFI7QUFFSFcsV0FBT0EsUUFBTyxJQUZYO0FBR0hULFdBQU9BLFFBQVEsSUFIWjtBQUlIQyxZQUFRQSxTQUFTLElBSmQ7QUFLSE8sY0FBVTtBQUxQLEdBQVA7QUFPSDs7QUFHRDs7Ozs7O0FBTU8sU0FBU2hFLHVCQUFULENBQWlDWSxNQUFqQyw0QkFBeUQ7QUFDOUQsU0FBTyxHQUFHc0QsTUFBSCxDQUFVdEQsTUFBVixFQUFrQnVELElBQWxCLENBQXVCLFVBQVNDLENBQVQsRUFBWUMsQ0FBWixFQUFlO0FBQzNDLFFBQUlELEVBQUVsRCxDQUFGLEdBQU1tRCxFQUFFbkQsQ0FBUixJQUFja0QsRUFBRWxELENBQUYsS0FBUW1ELEVBQUVuRCxDQUFWLElBQWVrRCxFQUFFeEMsQ0FBRixHQUFNeUMsRUFBRXpDLENBQXpDLEVBQTZDO0FBQzNDLGFBQU8sQ0FBUDtBQUNEO0FBQ0QsV0FBTyxDQUFDLENBQVI7QUFDRCxHQUxNLENBQVA7QUFNRDs7QUFFRDs7Ozs7Ozs7O0FBU0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQW1EQTs7Ozs7OztBQU9PLFNBQVMzQixjQUFULENBQXdCVyxNQUF4QixlQUF3QzBELFdBQXhDLDBCQUFtRTtBQUN4RUEsZ0JBQWNBLGVBQWUsUUFBN0I7QUFDQSxNQUFNQyxXQUFXLENBQUMsR0FBRCxFQUFNLEdBQU4sRUFBVyxHQUFYLEVBQWdCLEdBQWhCLENBQWpCO0FBQ0EsTUFBSSxDQUFDbEQsTUFBTW1ELE9BQU4sQ0FBYzVELE1BQWQsQ0FBTCxFQUE0QixNQUFNLElBQUk2RCxLQUFKLENBQVVILGNBQWMsb0JBQXhCLENBQU47QUFDNUIsT0FBSyxJQUFJdkQsTUFBSSxDQUFSLEVBQVdDLE1BQU1KLE9BQU9LLE1BQTdCLEVBQXFDRixNQUFJQyxHQUF6QyxFQUE4Q0QsS0FBOUMsRUFBbUQ7QUFDakQsUUFBTTJELE9BQU85RCxPQUFPRyxHQUFQLENBQWI7QUFDQSxTQUFLLElBQUk0RCxJQUFJLENBQWIsRUFBZ0JBLElBQUlKLFNBQVN0RCxNQUE3QixFQUFxQzBELEdBQXJDLEVBQTBDO0FBQ3hDLFVBQUksT0FBT0QsS0FBS0gsU0FBU0ksQ0FBVCxDQUFMLENBQVAsS0FBNkIsUUFBakMsRUFBMkM7QUFDekMsY0FBTSxJQUFJRixLQUFKLENBQVUsb0JBQW9CSCxXQUFwQixHQUFrQyxHQUFsQyxHQUF3Q3ZELEdBQXhDLEdBQTRDLElBQTVDLEdBQW1Ed0QsU0FBU0ksQ0FBVCxDQUFuRCxHQUFpRSxvQkFBM0UsQ0FBTjtBQUNEO0FBQ0Y7QUFDRCxRQUFJRCxLQUFLM0QsQ0FBTCxJQUFVLE9BQU8yRCxLQUFLM0QsQ0FBWixLQUFrQixRQUFoQyxFQUEwQztBQUN4QyxZQUFNLElBQUkwRCxLQUFKLENBQVUsb0JBQW9CSCxXQUFwQixHQUFrQyxHQUFsQyxHQUF3Q3ZELEdBQXhDLEdBQTRDLHVCQUF0RCxDQUFOO0FBQ0Q7QUFDRCxRQUFJMkQsS0FBS3ZDLE1BQUwsS0FBZ0JpQixTQUFoQixJQUE2QixPQUFPc0IsS0FBS3ZDLE1BQVosS0FBdUIsU0FBeEQsRUFBbUU7QUFDakUsWUFBTSxJQUFJc0MsS0FBSixDQUFVLG9CQUFvQkgsV0FBcEIsR0FBa0MsR0FBbEMsR0FBd0N2RCxHQUF4QyxHQUE0Qyw2QkFBdEQsQ0FBTjtBQUNEO0FBQ0Y7QUFDRjs7QUFFRDtBQUNPLFNBQVNiLGdCQUFULENBQTBCMEUsRUFBMUIsZUFBc0NDLEdBQXRDLGlDQUFnRTtBQUNyRUEsTUFBSUMsT0FBSixDQUFZLFVBQUNDLEdBQUQ7QUFBQSxXQUFTSCxHQUFHRyxHQUFILElBQVVILEdBQUdHLEdBQUgsRUFBUUMsSUFBUixDQUFhSixFQUFiLENBQW5CO0FBQUEsR0FBWjtBQUNEOztBQUlEOzs7OztBQUtPLFNBQVN6RSxZQUFULENBQXNCOEUsR0FBdEIsRUFBMkI7QUFDOUIsTUFBSUMsT0FBT0MsT0FBT0QsSUFBUCxDQUFZRCxHQUFaLENBQVg7QUFDQSxNQUFJLENBQUNDLEtBQUtqRSxNQUFWLEVBQWtCLE9BQU8sRUFBUDtBQUNsQixNQUFJRixDQUFKO0FBQUEsTUFBT0MsTUFBTWtFLEtBQUtqRSxNQUFsQjtBQUNBLE1BQUltRSxTQUFTLEVBQWI7O0FBRUEsT0FBS3JFLElBQUksQ0FBVCxFQUFZQSxJQUFJQyxHQUFoQixFQUFxQkQsR0FBckIsRUFBMEI7QUFDdEIsUUFBSWdFLE1BQU1HLEtBQUtuRSxDQUFMLENBQVY7QUFDQSxRQUFJc0UsTUFBTUosSUFBSUYsR0FBSixDQUFWO0FBQ0FLLGNBQVUvRSxVQUFVMEUsR0FBVixJQUFpQixHQUFqQixHQUF1QjNFLE1BQU0yRSxHQUFOLEVBQVdNLEdBQVgsQ0FBdkIsR0FBeUMsR0FBbkQ7QUFDSDs7QUFFRCxTQUFPRCxNQUFQO0FBQ0g7O0FBR0Q7QUFDTyxJQUFJRSxvQ0FBYztBQUNyQkMsMkJBQXlCLElBREo7QUFFckJDLFdBQVMsSUFGWTtBQUdyQkMsZ0JBQWMsSUFITztBQUlyQkMsbUJBQWlCLElBSkk7QUFLckJDLGVBQWEsSUFMUTtBQU1yQkMsUUFBTSxJQU5lO0FBT3JCQyxZQUFVLElBUFc7QUFRckJDLGdCQUFjLElBUk87QUFTckJDLGNBQVksSUFUUztBQVVyQkMsZ0JBQWMsSUFWTztBQVdyQkMsYUFBVyxJQVhVO0FBWXJCQyxXQUFTLElBWlk7QUFhckJDLGNBQVksSUFiUztBQWNyQkMsY0FBWSxJQWRTO0FBZXJCQyxhQUFXLElBZlU7QUFnQnJCQyxjQUFZLElBaEJTO0FBaUJyQkMsV0FBUyxJQWpCWTtBQWtCckJDLFNBQU8sSUFsQmM7QUFtQnJCQyxXQUFTLElBbkJZO0FBb0JyQkMsV0FBUyxJQXBCWTtBQXFCckJDLFVBQVEsSUFyQmE7QUFzQnJCQyxVQUFRLElBdEJhO0FBdUJyQkMsUUFBTSxJQXZCZTs7QUF5QnJCO0FBQ0FDLGVBQWEsSUExQlE7QUEyQnJCQyxlQUFhLElBM0JRO0FBNEJyQkMsb0JBQWtCLElBNUJHO0FBNkJyQkMsaUJBQWUsSUE3Qk07QUE4QnJCQyxlQUFhO0FBOUJRLENBQWxCOztBQWtDUDs7Ozs7O0FBTU8sU0FBUzlHLEtBQVQsQ0FBZStHLElBQWYsRUFBcUJDLEtBQXJCLEVBQTRCO0FBQy9CLE1BQUcsT0FBT0EsS0FBUCxLQUFpQixRQUFqQixJQUE2QixDQUFDOUIsWUFBYTZCLElBQWIsQ0FBakMsRUFBc0Q7QUFDbEQsV0FBT0MsUUFBUSxJQUFmO0FBQ0gsR0FGRCxNQUVPO0FBQ0gsV0FBT0EsS0FBUDtBQUNIO0FBQ0o7O0FBR0Q7Ozs7Ozs7QUFPTyxJQUFJQyxvQ0FBYyxtQkFBbEI7O0FBRUEsU0FBU2hILFNBQVQsQ0FBbUJpSCxHQUFuQixFQUF3QjtBQUMzQixTQUFPQSxJQUFJQyxPQUFKLENBQVlGLFdBQVosRUFBeUIsT0FBekIsRUFBa0NHLFdBQWxDLEVBQVA7QUFDSDs7QUFHTSxTQUFTbEgsZUFBVCxDQUF5Qm1ILEtBQXpCLEVBQWdDQyxRQUFoQyxFQUEwQ04sS0FBMUMsRUFBaUQ7QUFDcEQsT0FBSyxJQUFJckcsSUFBRSxDQUFYLEVBQWNBLElBQUkwRyxNQUFNeEcsTUFBeEIsRUFBZ0NGLEdBQWhDO0FBQ0ksUUFBSTBHLE1BQU0xRyxDQUFOLEVBQVMyRyxRQUFULEtBQXNCTixLQUExQixFQUNJLE9BQU8sSUFBUDtBQUZSLEdBSUEsT0FBTyxLQUFQO0FBQ0g7O0FBRU0sU0FBUzdHLGFBQVQsQ0FBdUJrSCxLQUF2QixFQUE4QkMsUUFBOUIsRUFBd0NOLEtBQXhDLEVBQStDO0FBQ2xESyxRQUFNM0MsT0FBTixDQUFjLFVBQVVNLE1BQVYsRUFBa0J1QyxLQUFsQixFQUF5QjtBQUNuQyxRQUFJdkMsT0FBT3NDLFFBQVAsTUFBcUJOLEtBQXpCLEVBQWdDO0FBQzVCO0FBQ0FLLFlBQU1HLE1BQU4sQ0FBYUQsS0FBYixFQUFvQixDQUFwQjtBQUNIO0FBQ0osR0FMRDtBQU1ILEMiLCJmaWxlIjoiMC5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEBmbG93XHJcbmV4cG9ydCB0eXBlIExheW91dEl0ZW1SZXF1aXJlZCA9IHt3OiBudW1iZXIsIGg6IG51bWJlciwgeDogbnVtYmVyLCB5OiBudW1iZXIsIGk6IHN0cmluZ307XHJcbmV4cG9ydCB0eXBlIExheW91dEl0ZW0gPSBMYXlvdXRJdGVtUmVxdWlyZWQgJlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAge21pblc/OiBudW1iZXIsIG1pbkg/OiBudW1iZXIsIG1heFc/OiBudW1iZXIsIG1heEg/OiBudW1iZXIsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgbW92ZWQ/OiBib29sZWFuLCBzdGF0aWM/OiBib29sZWFuLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlzRHJhZ2dhYmxlPzogP2Jvb2xlYW4sIGlzUmVzaXphYmxlPzogP2Jvb2xlYW59O1xyXG5leHBvcnQgdHlwZSBMYXlvdXQgPSBBcnJheTxMYXlvdXRJdGVtPjtcclxuZXhwb3J0IHR5cGUgUG9zaXRpb24gPSB7bGVmdDogbnVtYmVyLCB0b3A6IG51bWJlciwgd2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXJ9O1xyXG5leHBvcnQgdHlwZSBEcmFnQ2FsbGJhY2tEYXRhID0ge1xyXG4gIG5vZGU6IEhUTUxFbGVtZW50LFxyXG4gIHg6IG51bWJlciwgeTogbnVtYmVyLFxyXG4gIGRlbHRhWDogbnVtYmVyLCBkZWx0YVk6IG51bWJlcixcclxuICBsYXN0WDogbnVtYmVyLCBsYXN0WTogbnVtYmVyXHJcbn07XHJcbmV4cG9ydCB0eXBlIERyYWdFdmVudCA9IHtlOiBFdmVudH0gJiBEcmFnQ2FsbGJhY2tEYXRhO1xyXG5leHBvcnQgdHlwZSBTaXplID0ge3dpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyfTtcclxuZXhwb3J0IHR5cGUgUmVzaXplRXZlbnQgPSB7ZTogRXZlbnQsIG5vZGU6IEhUTUxFbGVtZW50LCBzaXplOiBTaXplfTtcclxuXHJcbmNvbnN0IGlzUHJvZHVjdGlvbiA9IHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAncHJvZHVjdGlvbic7XHJcbi8qKlxyXG4gKiBSZXR1cm4gdGhlIGJvdHRvbSBjb29yZGluYXRlIG9mIHRoZSBsYXlvdXQuXHJcbiAqXHJcbiAqIEBwYXJhbSAge0FycmF5fSBsYXlvdXQgTGF5b3V0IGFycmF5LlxyXG4gKiBAcmV0dXJuIHtOdW1iZXJ9ICAgICAgIEJvdHRvbSBjb29yZGluYXRlLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGJvdHRvbShsYXlvdXQ6IExheW91dCk6IG51bWJlciB7XHJcbiAgbGV0IG1heCA9IDAsIGJvdHRvbVk7XHJcbiAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGxheW91dC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgYm90dG9tWSA9IGxheW91dFtpXS4geSArIGxheW91dFtpXS5oO1xyXG4gICAgaWYgKGJvdHRvbVkgPiBtYXgpIG1heCA9IGJvdHRvbVk7XHJcbiAgfVxyXG4gIHJldHVybiBtYXg7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBjbG9uZUxheW91dChsYXlvdXQ6IExheW91dCk6IExheW91dCB7XHJcbiAgY29uc3QgbmV3TGF5b3V0ID0gQXJyYXkobGF5b3V0Lmxlbmd0aCk7XHJcbiAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGxheW91dC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgbmV3TGF5b3V0W2ldID0gY2xvbmVMYXlvdXRJdGVtKGxheW91dFtpXSk7XHJcbiAgfVxyXG4gIHJldHVybiBuZXdMYXlvdXQ7XHJcbn1cclxuXHJcbi8vIEZhc3QgcGF0aCB0byBjbG9uaW5nLCBzaW5jZSB0aGlzIGlzIG1vbm9tb3JwaGljXHJcbmV4cG9ydCBmdW5jdGlvbiBjbG9uZUxheW91dEl0ZW0obGF5b3V0SXRlbTogTGF5b3V0SXRlbSk6IExheW91dEl0ZW0ge1xyXG4gIC8qcmV0dXJuIHtcclxuICAgIHc6IGxheW91dEl0ZW0udywgaDogbGF5b3V0SXRlbS5oLCB4OiBsYXlvdXRJdGVtLngsIHk6IGxheW91dEl0ZW0ueSwgaTogbGF5b3V0SXRlbS5pLFxyXG4gICAgbWluVzogbGF5b3V0SXRlbS5taW5XLCBtYXhXOiBsYXlvdXRJdGVtLm1heFcsIG1pbkg6IGxheW91dEl0ZW0ubWluSCwgbWF4SDogbGF5b3V0SXRlbS5tYXhILFxyXG4gICAgbW92ZWQ6IEJvb2xlYW4obGF5b3V0SXRlbS5tb3ZlZCksIHN0YXRpYzogQm9vbGVhbihsYXlvdXRJdGVtLnN0YXRpYyksXHJcbiAgICAvLyBUaGVzZSBjYW4gYmUgbnVsbFxyXG4gICAgaXNEcmFnZ2FibGU6IGxheW91dEl0ZW0uaXNEcmFnZ2FibGUsIGlzUmVzaXphYmxlOiBsYXlvdXRJdGVtLmlzUmVzaXphYmxlXHJcbiAgfTsqL1xyXG4gICAgcmV0dXJuIEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkobGF5b3V0SXRlbSkpO1xyXG59XHJcblxyXG4vKipcclxuICogR2l2ZW4gdHdvIGxheW91dGl0ZW1zLCBjaGVjayBpZiB0aGV5IGNvbGxpZGUuXHJcbiAqXHJcbiAqIEByZXR1cm4ge0Jvb2xlYW59ICAgVHJ1ZSBpZiBjb2xsaWRpbmcuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gY29sbGlkZXMobDE6IExheW91dEl0ZW0sIGwyOiBMYXlvdXRJdGVtKTogYm9vbGVhbiB7XHJcbiAgaWYgKGwxID09PSBsMikgcmV0dXJuIGZhbHNlOyAvLyBzYW1lIGVsZW1lbnRcclxuICBpZiAobDEueCArIGwxLncgPD0gbDIueCkgcmV0dXJuIGZhbHNlOyAvLyBsMSBpcyBsZWZ0IG9mIGwyXHJcbiAgaWYgKGwxLnggPj0gbDIueCArIGwyLncpIHJldHVybiBmYWxzZTsgLy8gbDEgaXMgcmlnaHQgb2YgbDJcclxuICBpZiAobDEueSArIGwxLmggPD0gbDIueSkgcmV0dXJuIGZhbHNlOyAvLyBsMSBpcyBhYm92ZSBsMlxyXG4gIGlmIChsMS55ID49IGwyLnkgKyBsMi5oKSByZXR1cm4gZmFsc2U7IC8vIGwxIGlzIGJlbG93IGwyXHJcbiAgcmV0dXJuIHRydWU7IC8vIGJveGVzIG92ZXJsYXBcclxufVxyXG5cclxuLyoqXHJcbiAqIEdpdmVuIGEgbGF5b3V0LCBjb21wYWN0IGl0LiBUaGlzIGludm9sdmVzIGdvaW5nIGRvd24gZWFjaCB5IGNvb3JkaW5hdGUgYW5kIHJlbW92aW5nIGdhcHNcclxuICogYmV0d2VlbiBpdGVtcy5cclxuICpcclxuICogQHBhcmFtICB7QXJyYXl9IGxheW91dCBMYXlvdXQuXHJcbiAqIEBwYXJhbSAge0Jvb2xlYW59IHZlcnRpY2FsQ29tcGFjdCBXaGV0aGVyIG9yIG5vdCB0byBjb21wYWN0IHRoZSBsYXlvdXRcclxuICogICB2ZXJ0aWNhbGx5LlxyXG4gKiBAcmV0dXJuIHtBcnJheX0gICAgICAgQ29tcGFjdGVkIExheW91dC5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBjb21wYWN0KGxheW91dDogTGF5b3V0LCB2ZXJ0aWNhbENvbXBhY3Q6IEJvb2xlYW4pOiBMYXlvdXQge1xyXG4gICAgLy8gU3RhdGljcyBnbyBpbiB0aGUgY29tcGFyZVdpdGggYXJyYXkgcmlnaHQgYXdheSBzbyBpdGVtcyBmbG93IGFyb3VuZCB0aGVtLlxyXG4gIGNvbnN0IGNvbXBhcmVXaXRoID0gZ2V0U3RhdGljcyhsYXlvdXQpO1xyXG4gIC8vIFdlIGdvIHRocm91Z2ggdGhlIGl0ZW1zIGJ5IHJvdyBhbmQgY29sdW1uLlxyXG4gIGNvbnN0IHNvcnRlZCA9IHNvcnRMYXlvdXRJdGVtc0J5Um93Q29sKGxheW91dCk7XHJcbiAgLy8gSG9sZGluZyBmb3IgbmV3IGl0ZW1zLlxyXG4gIGNvbnN0IG91dCA9IEFycmF5KGxheW91dC5sZW5ndGgpO1xyXG5cclxuICBmb3IgKGxldCBpID0gMCwgbGVuID0gc29ydGVkLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICBsZXQgbCA9IHNvcnRlZFtpXTtcclxuXHJcbiAgICAvLyBEb24ndCBtb3ZlIHN0YXRpYyBlbGVtZW50c1xyXG4gICAgaWYgKCFsLnN0YXRpYykge1xyXG4gICAgICBsID0gY29tcGFjdEl0ZW0oY29tcGFyZVdpdGgsIGwsIHZlcnRpY2FsQ29tcGFjdCk7XHJcblxyXG4gICAgICAvLyBBZGQgdG8gY29tcGFyaXNvbiBhcnJheS4gV2Ugb25seSBjb2xsaWRlIHdpdGggaXRlbXMgYmVmb3JlIHRoaXMgb25lLlxyXG4gICAgICAvLyBTdGF0aWNzIGFyZSBhbHJlYWR5IGluIHRoaXMgYXJyYXkuXHJcbiAgICAgIGNvbXBhcmVXaXRoLnB1c2gobCk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQWRkIHRvIG91dHB1dCBhcnJheSB0byBtYWtlIHN1cmUgdGhleSBzdGlsbCBjb21lIG91dCBpbiB0aGUgcmlnaHQgb3JkZXIuXHJcbiAgICBvdXRbbGF5b3V0LmluZGV4T2YobCldID0gbDtcclxuXHJcbiAgICAvLyBDbGVhciBtb3ZlZCBmbGFnLCBpZiBpdCBleGlzdHMuXHJcbiAgICBsLm1vdmVkID0gZmFsc2U7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gb3V0O1xyXG59XHJcblxyXG4vKipcclxuICogQ29tcGFjdCBhbiBpdGVtIGluIHRoZSBsYXlvdXQuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gY29tcGFjdEl0ZW0oY29tcGFyZVdpdGg6IExheW91dCwgbDogTGF5b3V0SXRlbSwgdmVydGljYWxDb21wYWN0OiBib29sZWFuKTogTGF5b3V0SXRlbSB7XHJcbiAgaWYgKHZlcnRpY2FsQ29tcGFjdCkge1xyXG4gICAgLy8gTW92ZSB0aGUgZWxlbWVudCB1cCBhcyBmYXIgYXMgaXQgY2FuIGdvIHdpdGhvdXQgY29sbGlkaW5nLlxyXG4gICAgd2hpbGUgKGwueSA+IDAgJiYgIWdldEZpcnN0Q29sbGlzaW9uKGNvbXBhcmVXaXRoLCBsKSkge1xyXG4gICAgICBsLnktLTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIE1vdmUgaXQgZG93biwgYW5kIGtlZXAgbW92aW5nIGl0IGRvd24gaWYgaXQncyBjb2xsaWRpbmcuXHJcbiAgbGV0IGNvbGxpZGVzO1xyXG4gIHdoaWxlKChjb2xsaWRlcyA9IGdldEZpcnN0Q29sbGlzaW9uKGNvbXBhcmVXaXRoLCBsKSkpIHtcclxuICAgIGwueSA9IGNvbGxpZGVzLnkgKyBjb2xsaWRlcy5oO1xyXG4gIH1cclxuICByZXR1cm4gbDtcclxufVxyXG5cclxuLyoqXHJcbiAqIEdpdmVuIGEgbGF5b3V0LCBtYWtlIHN1cmUgYWxsIGVsZW1lbnRzIGZpdCB3aXRoaW4gaXRzIGJvdW5kcy5cclxuICpcclxuICogQHBhcmFtICB7QXJyYXl9IGxheW91dCBMYXlvdXQgYXJyYXkuXHJcbiAqIEBwYXJhbSAge051bWJlcn0gYm91bmRzIE51bWJlciBvZiBjb2x1bW5zLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGNvcnJlY3RCb3VuZHMobGF5b3V0OiBMYXlvdXQsIGJvdW5kczoge2NvbHM6IG51bWJlcn0pOiBMYXlvdXQge1xyXG4gIGNvbnN0IGNvbGxpZGVzV2l0aCA9IGdldFN0YXRpY3MobGF5b3V0KTtcclxuICBmb3IgKGxldCBpID0gMCwgbGVuID0gbGF5b3V0Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICBjb25zdCBsID0gbGF5b3V0W2ldO1xyXG4gICAgLy8gT3ZlcmZsb3dzIHJpZ2h0XHJcbiAgICBpZiAobC54ICsgbC53ID4gYm91bmRzLmNvbHMpIGwueCA9IGJvdW5kcy5jb2xzIC0gbC53O1xyXG4gICAgLy8gT3ZlcmZsb3dzIGxlZnRcclxuICAgIGlmIChsLnggPCAwKSB7XHJcbiAgICAgIGwueCA9IDA7XHJcbiAgICAgIGwudyA9IGJvdW5kcy5jb2xzO1xyXG4gICAgfVxyXG4gICAgaWYgKCFsLnN0YXRpYykgY29sbGlkZXNXaXRoLnB1c2gobCk7XHJcbiAgICBlbHNlIHtcclxuICAgICAgLy8gSWYgdGhpcyBpcyBzdGF0aWMgYW5kIGNvbGxpZGVzIHdpdGggb3RoZXIgc3RhdGljcywgd2UgbXVzdCBtb3ZlIGl0IGRvd24uXHJcbiAgICAgIC8vIFdlIGhhdmUgdG8gZG8gc29tZXRoaW5nIG5pY2VyIHRoYW4ganVzdCBsZXR0aW5nIHRoZW0gb3ZlcmxhcC5cclxuICAgICAgd2hpbGUoZ2V0Rmlyc3RDb2xsaXNpb24oY29sbGlkZXNXaXRoLCBsKSkge1xyXG4gICAgICAgIGwueSsrO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG4gIHJldHVybiBsYXlvdXQ7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZXQgYSBsYXlvdXQgaXRlbSBieSBJRC4gVXNlZCBzbyB3ZSBjYW4gb3ZlcnJpZGUgbGF0ZXIgb24gaWYgbmVjZXNzYXJ5LlxyXG4gKlxyXG4gKiBAcGFyYW0gIHtBcnJheX0gIGxheW91dCBMYXlvdXQgYXJyYXkuXHJcbiAqIEBwYXJhbSAge1N0cmluZ30gaWQgICAgIElEXHJcbiAqIEByZXR1cm4ge0xheW91dEl0ZW19ICAgIEl0ZW0gYXQgSUQuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZ2V0TGF5b3V0SXRlbShsYXlvdXQ6IExheW91dCwgaWQ6IHN0cmluZyk6ID9MYXlvdXRJdGVtIHtcclxuICBmb3IgKGxldCBpID0gMCwgbGVuID0gbGF5b3V0Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICBpZiAobGF5b3V0W2ldLmkgPT09IGlkKSByZXR1cm4gbGF5b3V0W2ldO1xyXG4gIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgdGhlIGZpcnN0IGl0ZW0gdGhpcyBsYXlvdXQgY29sbGlkZXMgd2l0aC5cclxuICogSXQgZG9lc24ndCBhcHBlYXIgdG8gbWF0dGVyIHdoaWNoIG9yZGVyIHdlIGFwcHJvYWNoIHRoaXMgZnJvbSwgYWx0aG91Z2hcclxuICogcGVyaGFwcyB0aGF0IGlzIHRoZSB3cm9uZyB0aGluZyB0byBkby5cclxuICpcclxuICogQHBhcmFtICB7T2JqZWN0fSBsYXlvdXRJdGVtIExheW91dCBpdGVtLlxyXG4gKiBAcmV0dXJuIHtPYmplY3R8dW5kZWZpbmVkfSAgQSBjb2xsaWRpbmcgbGF5b3V0IGl0ZW0sIG9yIHVuZGVmaW5lZC5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRGaXJzdENvbGxpc2lvbihsYXlvdXQ6IExheW91dCwgbGF5b3V0SXRlbTogTGF5b3V0SXRlbSk6ID9MYXlvdXRJdGVtIHtcclxuICBmb3IgKGxldCBpID0gMCwgbGVuID0gbGF5b3V0Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICBpZiAoY29sbGlkZXMobGF5b3V0W2ldLCBsYXlvdXRJdGVtKSkgcmV0dXJuIGxheW91dFtpXTtcclxuICB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRBbGxDb2xsaXNpb25zKGxheW91dDogTGF5b3V0LCBsYXlvdXRJdGVtOiBMYXlvdXRJdGVtKTogQXJyYXk8TGF5b3V0SXRlbT4ge1xyXG4gIHJldHVybiBsYXlvdXQuZmlsdGVyKChsKSA9PiBjb2xsaWRlcyhsLCBsYXlvdXRJdGVtKSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZXQgYWxsIHN0YXRpYyBlbGVtZW50cy5cclxuICogQHBhcmFtICB7QXJyYXl9IGxheW91dCBBcnJheSBvZiBsYXlvdXQgb2JqZWN0cy5cclxuICogQHJldHVybiB7QXJyYXl9ICAgICAgICBBcnJheSBvZiBzdGF0aWMgbGF5b3V0IGl0ZW1zLi5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRTdGF0aWNzKGxheW91dDogTGF5b3V0KTogQXJyYXk8TGF5b3V0SXRlbT4ge1xyXG4gICAgLy9yZXR1cm4gW107XHJcbiAgICByZXR1cm4gbGF5b3V0LmZpbHRlcigobCkgPT4gbC5zdGF0aWMpO1xyXG59XHJcblxyXG4vKipcclxuICogTW92ZSBhbiBlbGVtZW50LiBSZXNwb25zaWJsZSBmb3IgZG9pbmcgY2FzY2FkaW5nIG1vdmVtZW50cyBvZiBvdGhlciBlbGVtZW50cy5cclxuICpcclxuICogQHBhcmFtICB7QXJyYXl9ICAgICAgbGF5b3V0IEZ1bGwgbGF5b3V0IHRvIG1vZGlmeS5cclxuICogQHBhcmFtICB7TGF5b3V0SXRlbX0gbCAgICAgIGVsZW1lbnQgdG8gbW92ZS5cclxuICogQHBhcmFtICB7TnVtYmVyfSAgICAgW3hdICAgIFggcG9zaXRpb24gaW4gZ3JpZCB1bml0cy5cclxuICogQHBhcmFtICB7TnVtYmVyfSAgICAgW3ldICAgIFkgcG9zaXRpb24gaW4gZ3JpZCB1bml0cy5cclxuICogQHBhcmFtICB7Qm9vbGVhbn0gICAgW2lzVXNlckFjdGlvbl0gSWYgdHJ1ZSwgZGVzaWduYXRlcyB0aGF0IHRoZSBpdGVtIHdlJ3JlIG1vdmluZyBpc1xyXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZWluZyBkcmFnZ2VkL3Jlc2l6ZWQgYnkgdGggZXVzZXIuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gbW92ZUVsZW1lbnQobGF5b3V0OiBMYXlvdXQsIGw6IExheW91dEl0ZW0sIHg6IE51bWJlciwgeTogTnVtYmVyLCBpc1VzZXJBY3Rpb246IEJvb2xlYW4pOiBMYXlvdXQge1xyXG4gIGlmIChsLnN0YXRpYykgcmV0dXJuIGxheW91dDtcclxuXHJcbiAgLy8gU2hvcnQtY2lyY3VpdCBpZiBub3RoaW5nIHRvIGRvLlxyXG4gIC8vaWYgKGwueSA9PT0geSAmJiBsLnggPT09IHgpIHJldHVybiBsYXlvdXQ7XHJcblxyXG4gIGNvbnN0IG1vdmluZ1VwID0geSAmJiBsLnkgPiB5O1xyXG4gIC8vIFRoaXMgaXMgcXVpdGUgYSBiaXQgZmFzdGVyIHRoYW4gZXh0ZW5kaW5nIHRoZSBvYmplY3RcclxuICBpZiAodHlwZW9mIHggPT09ICdudW1iZXInKSBsLnggPSB4O1xyXG4gIGlmICh0eXBlb2YgeSA9PT0gJ251bWJlcicpIGwueSA9IHk7XHJcbiAgbC5tb3ZlZCA9IHRydWU7XHJcblxyXG4gIC8vIElmIHRoaXMgY29sbGlkZXMgd2l0aCBhbnl0aGluZywgbW92ZSBpdC5cclxuICAvLyBXaGVuIGRvaW5nIHRoaXMgY29tcGFyaXNvbiwgd2UgaGF2ZSB0byBzb3J0IHRoZSBpdGVtcyB3ZSBjb21wYXJlIHdpdGhcclxuICAvLyB0byBlbnN1cmUsIGluIHRoZSBjYXNlIG9mIG11bHRpcGxlIGNvbGxpc2lvbnMsIHRoYXQgd2UncmUgZ2V0dGluZyB0aGVcclxuICAvLyBuZWFyZXN0IGNvbGxpc2lvbi5cclxuICBsZXQgc29ydGVkID0gc29ydExheW91dEl0ZW1zQnlSb3dDb2wobGF5b3V0KTtcclxuICBpZiAobW92aW5nVXApIHNvcnRlZCA9IHNvcnRlZC5yZXZlcnNlKCk7XHJcbiAgY29uc3QgY29sbGlzaW9ucyA9IGdldEFsbENvbGxpc2lvbnMoc29ydGVkLCBsKTtcclxuXHJcbiAgLy8gTW92ZSBlYWNoIGl0ZW0gdGhhdCBjb2xsaWRlcyBhd2F5IGZyb20gdGhpcyBlbGVtZW50LlxyXG4gIGZvciAobGV0IGkgPSAwLCBsZW4gPSBjb2xsaXNpb25zLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICBjb25zdCBjb2xsaXNpb24gPSBjb2xsaXNpb25zW2ldO1xyXG4gICAgLy8gY29uc29sZS5sb2coJ3Jlc29sdmluZyBjb2xsaXNpb24gYmV0d2VlbicsIGwuaSwgJ2F0JywgbC55LCAnYW5kJywgY29sbGlzaW9uLmksICdhdCcsIGNvbGxpc2lvbi55KTtcclxuXHJcbiAgICAvLyBTaG9ydCBjaXJjdWl0IHNvIHdlIGNhbid0IGluZmluaXRlIGxvb3BcclxuICAgIGlmIChjb2xsaXNpb24ubW92ZWQpIGNvbnRpbnVlO1xyXG5cclxuICAgIC8vIFRoaXMgbWFrZXMgaXQgZmVlbCBhIGJpdCBtb3JlIHByZWNpc2UgYnkgd2FpdGluZyB0byBzd2FwIGZvciBqdXN0IGEgYml0IHdoZW4gbW92aW5nIHVwLlxyXG4gICAgaWYgKGwueSA+IGNvbGxpc2lvbi55ICYmIGwueSAtIGNvbGxpc2lvbi55ID4gY29sbGlzaW9uLmggLyA0KSBjb250aW51ZTtcclxuXHJcbiAgICAvLyBEb24ndCBtb3ZlIHN0YXRpYyBpdGVtcyAtIHdlIGhhdmUgdG8gbW92ZSAqdGhpcyogZWxlbWVudCBhd2F5XHJcbiAgICBpZiAoY29sbGlzaW9uLnN0YXRpYykge1xyXG4gICAgICBsYXlvdXQgPSBtb3ZlRWxlbWVudEF3YXlGcm9tQ29sbGlzaW9uKGxheW91dCwgY29sbGlzaW9uLCBsLCBpc1VzZXJBY3Rpb24pO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgbGF5b3V0ID0gbW92ZUVsZW1lbnRBd2F5RnJvbUNvbGxpc2lvbihsYXlvdXQsIGwsIGNvbGxpc2lvbiwgaXNVc2VyQWN0aW9uKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHJldHVybiBsYXlvdXQ7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBUaGlzIGlzIHdoZXJlIHRoZSBtYWdpYyBuZWVkcyB0byBoYXBwZW4gLSBnaXZlbiBhIGNvbGxpc2lvbiwgbW92ZSBhbiBlbGVtZW50IGF3YXkgZnJvbSB0aGUgY29sbGlzaW9uLlxyXG4gKiBXZSBhdHRlbXB0IHRvIG1vdmUgaXQgdXAgaWYgdGhlcmUncyByb29tLCBvdGhlcndpc2UgaXQgZ29lcyBiZWxvdy5cclxuICpcclxuICogQHBhcmFtICB7QXJyYXl9IGxheW91dCAgICAgICAgICAgIEZ1bGwgbGF5b3V0IHRvIG1vZGlmeS5cclxuICogQHBhcmFtICB7TGF5b3V0SXRlbX0gY29sbGlkZXNXaXRoIExheW91dCBpdGVtIHdlJ3JlIGNvbGxpZGluZyB3aXRoLlxyXG4gKiBAcGFyYW0gIHtMYXlvdXRJdGVtfSBpdGVtVG9Nb3ZlICAgTGF5b3V0IGl0ZW0gd2UncmUgbW92aW5nLlxyXG4gKiBAcGFyYW0gIHtCb29sZWFufSBbaXNVc2VyQWN0aW9uXSAgSWYgdHJ1ZSwgZGVzaWduYXRlcyB0aGF0IHRoZSBpdGVtIHdlJ3JlIG1vdmluZyBpcyBiZWluZyBkcmFnZ2VkL3Jlc2l6ZWRcclxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5IHRoZSB1c2VyLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIG1vdmVFbGVtZW50QXdheUZyb21Db2xsaXNpb24obGF5b3V0OiBMYXlvdXQsIGNvbGxpZGVzV2l0aDogTGF5b3V0SXRlbSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbVRvTW92ZTogTGF5b3V0SXRlbSwgaXNVc2VyQWN0aW9uOiA/Ym9vbGVhbik6IExheW91dCB7XHJcblxyXG4gIC8vIElmIHRoZXJlIGlzIGVub3VnaCBzcGFjZSBhYm92ZSB0aGUgY29sbGlzaW9uIHRvIHB1dCB0aGlzIGVsZW1lbnQsIG1vdmUgaXQgdGhlcmUuXHJcbiAgLy8gV2Ugb25seSBkbyB0aGlzIG9uIHRoZSBtYWluIGNvbGxpc2lvbiBhcyB0aGlzIGNhbiBnZXQgZnVua3kgaW4gY2FzY2FkZXMgYW5kIGNhdXNlXHJcbiAgLy8gdW53YW50ZWQgc3dhcHBpbmcgYmVoYXZpb3IuXHJcbiAgaWYgKGlzVXNlckFjdGlvbikge1xyXG4gICAgLy8gTWFrZSBhIG1vY2sgaXRlbSBzbyB3ZSBkb24ndCBtb2RpZnkgdGhlIGl0ZW0gaGVyZSwgb25seSBtb2RpZnkgaW4gbW92ZUVsZW1lbnQuXHJcbiAgICBjb25zdCBmYWtlSXRlbTogTGF5b3V0SXRlbSA9IHtcclxuICAgICAgeDogaXRlbVRvTW92ZS54LFxyXG4gICAgICB5OiBpdGVtVG9Nb3ZlLnksXHJcbiAgICAgIHc6IGl0ZW1Ub01vdmUudyxcclxuICAgICAgaDogaXRlbVRvTW92ZS5oLFxyXG4gICAgICBpOiAnLTEnXHJcbiAgICB9O1xyXG4gICAgZmFrZUl0ZW0ueSA9IE1hdGgubWF4KGNvbGxpZGVzV2l0aC55IC0gaXRlbVRvTW92ZS5oLCAwKTtcclxuICAgIGlmICghZ2V0Rmlyc3RDb2xsaXNpb24obGF5b3V0LCBmYWtlSXRlbSkpIHtcclxuICAgICAgcmV0dXJuIG1vdmVFbGVtZW50KGxheW91dCwgaXRlbVRvTW92ZSwgdW5kZWZpbmVkLCBmYWtlSXRlbS55KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIFByZXZpb3VzbHkgdGhpcyB3YXMgb3B0aW1pemVkIHRvIG1vdmUgYmVsb3cgdGhlIGNvbGxpc2lvbiBkaXJlY3RseSwgYnV0IHRoaXMgY2FuIGNhdXNlIHByb2JsZW1zXHJcbiAgLy8gd2l0aCBjYXNjYWRpbmcgbW92ZXMsIGFzIGFuIGl0ZW0gbWF5IGFjdHVhbGx5IGxlYXBmbG9nIGEgY29sbGlzaW9uIGFuZCBjYXVzZSBhIHJldmVyc2FsIGluIG9yZGVyLlxyXG4gIHJldHVybiBtb3ZlRWxlbWVudChsYXlvdXQsIGl0ZW1Ub01vdmUsIHVuZGVmaW5lZCwgaXRlbVRvTW92ZS55ICsgMSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBIZWxwZXIgdG8gY29udmVydCBhIG51bWJlciB0byBhIHBlcmNlbnRhZ2Ugc3RyaW5nLlxyXG4gKlxyXG4gKiBAcGFyYW0gIHtOdW1iZXJ9IG51bSBBbnkgbnVtYmVyXHJcbiAqIEByZXR1cm4ge1N0cmluZ30gICAgIFRoYXQgbnVtYmVyIGFzIGEgcGVyY2VudGFnZS5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBwZXJjKG51bTogbnVtYmVyKTogc3RyaW5nIHtcclxuICByZXR1cm4gbnVtICogMTAwICsgJyUnO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gc2V0VHJhbnNmb3JtKHRvcCwgbGVmdCwgd2lkdGgsIGhlaWdodCk6IE9iamVjdCB7XHJcbiAgLy8gUmVwbGFjZSB1bml0bGVzcyBpdGVtcyB3aXRoIHB4XHJcbiAgY29uc3QgdHJhbnNsYXRlID0gXCJ0cmFuc2xhdGUzZChcIiArIGxlZnQgKyBcInB4LFwiICsgdG9wICsgXCJweCwgMClcIjtcclxuICByZXR1cm4ge1xyXG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGUsXHJcbiAgICBXZWJraXRUcmFuc2Zvcm06IHRyYW5zbGF0ZSxcclxuICAgIE1velRyYW5zZm9ybTogdHJhbnNsYXRlLFxyXG4gICAgbXNUcmFuc2Zvcm06IHRyYW5zbGF0ZSxcclxuICAgIE9UcmFuc2Zvcm06IHRyYW5zbGF0ZSxcclxuICAgIHdpZHRoOiB3aWR0aCArIFwicHhcIixcclxuICAgIGhlaWdodDogaGVpZ2h0ICsgXCJweFwiLFxyXG4gICAgcG9zaXRpb246ICdhYnNvbHV0ZSdcclxuICB9O1xyXG59XHJcbi8qKlxyXG4gKiBKdXN0IGxpa2UgdGhlIHNldFRyYW5zZm9ybSBtZXRob2QsIGJ1dCBpbnN0ZWFkIGl0IHdpbGwgcmV0dXJuIGEgbmVnYXRpdmUgdmFsdWUgb2YgcmlnaHQuXHJcbiAqXHJcbiAqIEBwYXJhbSB0b3BcclxuICogQHBhcmFtIHJpZ2h0XHJcbiAqIEBwYXJhbSB3aWR0aFxyXG4gKiBAcGFyYW0gaGVpZ2h0XHJcbiAqIEByZXR1cm5zIHt7dHJhbnNmb3JtOiBzdHJpbmcsIFdlYmtpdFRyYW5zZm9ybTogc3RyaW5nLCBNb3pUcmFuc2Zvcm06IHN0cmluZywgbXNUcmFuc2Zvcm06IHN0cmluZywgT1RyYW5zZm9ybTogc3RyaW5nLCB3aWR0aDogc3RyaW5nLCBoZWlnaHQ6IHN0cmluZywgcG9zaXRpb246IHN0cmluZ319XHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gc2V0VHJhbnNmb3JtUnRsKHRvcCwgcmlnaHQsIHdpZHRoLCBoZWlnaHQpOiBPYmplY3Qge1xyXG4gICAgLy8gUmVwbGFjZSB1bml0bGVzcyBpdGVtcyB3aXRoIHB4XHJcbiAgICBjb25zdCB0cmFuc2xhdGUgPSBcInRyYW5zbGF0ZTNkKFwiICsgcmlnaHQgKiAtMSArIFwicHgsXCIgKyB0b3AgKyBcInB4LCAwKVwiO1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZSxcclxuICAgICAgICBXZWJraXRUcmFuc2Zvcm06IHRyYW5zbGF0ZSxcclxuICAgICAgICBNb3pUcmFuc2Zvcm06IHRyYW5zbGF0ZSxcclxuICAgICAgICBtc1RyYW5zZm9ybTogdHJhbnNsYXRlLFxyXG4gICAgICAgIE9UcmFuc2Zvcm06IHRyYW5zbGF0ZSxcclxuICAgICAgICB3aWR0aDogd2lkdGggKyBcInB4XCIsXHJcbiAgICAgICAgaGVpZ2h0OiBoZWlnaHQgKyBcInB4XCIsXHJcbiAgICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZSdcclxuICAgIH07XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBzZXRUb3BMZWZ0KHRvcCwgbGVmdCwgd2lkdGgsIGhlaWdodCk6IE9iamVjdCB7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIHRvcDogdG9wICsgXCJweFwiLFxyXG4gICAgICAgIGxlZnQ6IGxlZnQgKyBcInB4XCIsXHJcbiAgICAgICAgd2lkdGg6IHdpZHRoICsgXCJweFwiLFxyXG4gICAgICAgIGhlaWdodDogaGVpZ2h0ICsgXCJweFwiLFxyXG4gICAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnXHJcbiAgICB9O1xyXG59XHJcbi8qKlxyXG4gKiBKdXN0IGxpa2UgdGhlIHNldFRvcExlZnQgbWV0aG9kLCBidXQgaW5zdGVhZCwgaXQgd2lsbCByZXR1cm4gYSByaWdodCBwcm9wZXJ0eSBpbnN0ZWFkIG9mIGxlZnQuXHJcbiAqXHJcbiAqIEBwYXJhbSB0b3BcclxuICogQHBhcmFtIHJpZ2h0XHJcbiAqIEBwYXJhbSB3aWR0aFxyXG4gKiBAcGFyYW0gaGVpZ2h0XHJcbiAqIEByZXR1cm5zIHt7dG9wOiBzdHJpbmcsIHJpZ2h0OiBzdHJpbmcsIHdpZHRoOiBzdHJpbmcsIGhlaWdodDogc3RyaW5nLCBwb3NpdGlvbjogc3RyaW5nfX1cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBzZXRUb3BSaWdodCh0b3AsIHJpZ2h0LCB3aWR0aCwgaGVpZ2h0KTogT2JqZWN0IHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgdG9wOiB0b3AgKyBcInB4XCIsXHJcbiAgICAgICAgcmlnaHQ6IHJpZ2h0KyBcInB4XCIsXHJcbiAgICAgICAgd2lkdGg6IHdpZHRoICsgXCJweFwiLFxyXG4gICAgICAgIGhlaWdodDogaGVpZ2h0ICsgXCJweFwiLFxyXG4gICAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnXHJcbiAgICB9O1xyXG59XHJcblxyXG5cclxuLyoqXHJcbiAqIEdldCBsYXlvdXQgaXRlbXMgc29ydGVkIGZyb20gdG9wIGxlZnQgdG8gcmlnaHQgYW5kIGRvd24uXHJcbiAqXHJcbiAqIEByZXR1cm4ge0FycmF5fSBBcnJheSBvZiBsYXlvdXQgb2JqZWN0cy5cclxuICogQHJldHVybiB7QXJyYXl9ICAgICAgICBMYXlvdXQsIHNvcnRlZCBzdGF0aWMgaXRlbXMgZmlyc3QuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gc29ydExheW91dEl0ZW1zQnlSb3dDb2wobGF5b3V0OiBMYXlvdXQpOiBMYXlvdXQge1xyXG4gIHJldHVybiBbXS5jb25jYXQobGF5b3V0KS5zb3J0KGZ1bmN0aW9uKGEsIGIpIHtcclxuICAgIGlmIChhLnkgPiBiLnkgfHwgKGEueSA9PT0gYi55ICYmIGEueCA+IGIueCkpIHtcclxuICAgICAgcmV0dXJuIDE7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gLTE7XHJcbiAgfSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZW5lcmF0ZSBhIGxheW91dCB1c2luZyB0aGUgaW5pdGlhbExheW91dCBhbmQgY2hpbGRyZW4gYXMgYSB0ZW1wbGF0ZS5cclxuICogTWlzc2luZyBlbnRyaWVzIHdpbGwgYmUgYWRkZWQsIGV4dHJhbmVvdXMgb25lcyB3aWxsIGJlIHRydW5jYXRlZC5cclxuICpcclxuICogQHBhcmFtICB7QXJyYXl9ICBpbml0aWFsTGF5b3V0IExheW91dCBwYXNzZWQgaW4gdGhyb3VnaCBwcm9wcy5cclxuICogQHBhcmFtICB7U3RyaW5nfSBicmVha3BvaW50ICAgIEN1cnJlbnQgcmVzcG9uc2l2ZSBicmVha3BvaW50LlxyXG4gKiBAcGFyYW0gIHtCb29sZWFufSB2ZXJ0aWNhbENvbXBhY3QgV2hldGhlciBvciBub3QgdG8gY29tcGFjdCB0aGUgbGF5b3V0IHZlcnRpY2FsbHkuXHJcbiAqIEByZXR1cm4ge0FycmF5fSAgICAgICAgICAgICAgICBXb3JraW5nIGxheW91dC5cclxuICovXHJcbi8qXHJcbmV4cG9ydCBmdW5jdGlvbiBzeW5jaHJvbml6ZUxheW91dFdpdGhDaGlsZHJlbihpbml0aWFsTGF5b3V0OiBMYXlvdXQsIGNoaWxkcmVuOiBBcnJheTxSZWFjdC5FbGVtZW50PnxSZWFjdC5FbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sczogbnVtYmVyLCB2ZXJ0aWNhbENvbXBhY3Q6IGJvb2xlYW4pOiBMYXlvdXQge1xyXG4gIC8vIGVuc3VyZSAnY2hpbGRyZW4nIGlzIGFsd2F5cyBhbiBhcnJheVxyXG4gIGlmICghQXJyYXkuaXNBcnJheShjaGlsZHJlbikpIHtcclxuICAgIGNoaWxkcmVuID0gW2NoaWxkcmVuXTtcclxuICB9XHJcbiAgaW5pdGlhbExheW91dCA9IGluaXRpYWxMYXlvdXQgfHwgW107XHJcblxyXG4gIC8vIEdlbmVyYXRlIG9uZSBsYXlvdXQgaXRlbSBwZXIgY2hpbGQuXHJcbiAgbGV0IGxheW91dDogTGF5b3V0ID0gW107XHJcbiAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGNoaWxkcmVuLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICBsZXQgbmV3SXRlbTtcclxuICAgIGNvbnN0IGNoaWxkID0gY2hpbGRyZW5baV07XHJcblxyXG4gICAgLy8gRG9uJ3Qgb3ZlcndyaXRlIGlmIGl0IGFscmVhZHkgZXhpc3RzLlxyXG4gICAgY29uc3QgZXhpc3RzID0gZ2V0TGF5b3V0SXRlbShpbml0aWFsTGF5b3V0LCBjaGlsZC5rZXkgfHwgXCIxXCIgLyEqIEZJWE1FIHNhdGlzZmllcyBGbG93ICohLyk7XHJcbiAgICBpZiAoZXhpc3RzKSB7XHJcbiAgICAgIG5ld0l0ZW0gPSBleGlzdHM7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb25zdCBnID0gY2hpbGQucHJvcHMuX2dyaWQ7XHJcblxyXG4gICAgICAvLyBIZXksIHRoaXMgaXRlbSBoYXMgYSBfZ3JpZCBwcm9wZXJ0eSwgdXNlIGl0LlxyXG4gICAgICBpZiAoZykge1xyXG4gICAgICAgIGlmICghaXNQcm9kdWN0aW9uKSB7XHJcbiAgICAgICAgICB2YWxpZGF0ZUxheW91dChbZ10sICdSZWFjdEdyaWRMYXlvdXQuY2hpbGRyZW4nKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gVmFsaWRhdGVkOyBhZGQgaXQgdG8gdGhlIGxheW91dC4gQm90dG9tICd5JyBwb3NzaWJsZSBpcyB0aGUgYm90dG9tIG9mIHRoZSBsYXlvdXQuXHJcbiAgICAgICAgLy8gVGhpcyBhbGxvd3MgeW91IHRvIGRvIG5pY2Ugc3R1ZmYgbGlrZSBzcGVjaWZ5IHt5OiBJbmZpbml0eX1cclxuICAgICAgICBpZiAodmVydGljYWxDb21wYWN0KSB7XHJcbiAgICAgICAgICBuZXdJdGVtID0gY2xvbmVMYXlvdXRJdGVtKHsuLi5nLCB5OiBNYXRoLm1pbihib3R0b20obGF5b3V0KSwgZy55KSwgaTogY2hpbGQua2V5fSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIG5ld0l0ZW0gPSBjbG9uZUxheW91dEl0ZW0oey4uLmcsIHk6IGcueSwgaTogY2hpbGQua2V5fSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIC8vIE5vdGhpbmcgcHJvdmlkZWQ6IGVuc3VyZSB0aGlzIGlzIGFkZGVkIHRvIHRoZSBib3R0b21cclxuICAgICAgZWxzZSB7XHJcbiAgICAgICAgbmV3SXRlbSA9IGNsb25lTGF5b3V0SXRlbSh7dzogMSwgaDogMSwgeDogMCwgeTogYm90dG9tKGxheW91dCksIGk6IGNoaWxkLmtleSB8fCBcIjFcIn0pO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBsYXlvdXRbaV0gPSBuZXdJdGVtO1xyXG4gIH1cclxuXHJcbiAgLy8gQ29ycmVjdCB0aGUgbGF5b3V0LlxyXG4gIGxheW91dCA9IGNvcnJlY3RCb3VuZHMobGF5b3V0LCB7Y29sczogY29sc30pO1xyXG4gIGxheW91dCA9IGNvbXBhY3QobGF5b3V0LCB2ZXJ0aWNhbENvbXBhY3QpO1xyXG5cclxuICByZXR1cm4gbGF5b3V0O1xyXG59XHJcbiovXHJcblxyXG4vKipcclxuICogVmFsaWRhdGUgYSBsYXlvdXQuIFRocm93cyBlcnJvcnMuXHJcbiAqXHJcbiAqIEBwYXJhbSAge0FycmF5fSAgbGF5b3V0ICAgICAgICBBcnJheSBvZiBsYXlvdXQgaXRlbXMuXHJcbiAqIEBwYXJhbSAge1N0cmluZ30gW2NvbnRleHROYW1lXSBDb250ZXh0IG5hbWUgZm9yIGVycm9ycy5cclxuICogQHRocm93ICB7RXJyb3J9ICAgICAgICAgICAgICAgIFZhbGlkYXRpb24gZXJyb3IuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVMYXlvdXQobGF5b3V0OiBMYXlvdXQsIGNvbnRleHROYW1lOiBzdHJpbmcpOiB2b2lkIHtcclxuICBjb250ZXh0TmFtZSA9IGNvbnRleHROYW1lIHx8IFwiTGF5b3V0XCI7XHJcbiAgY29uc3Qgc3ViUHJvcHMgPSBbJ3gnLCAneScsICd3JywgJ2gnXTtcclxuICBpZiAoIUFycmF5LmlzQXJyYXkobGF5b3V0KSkgdGhyb3cgbmV3IEVycm9yKGNvbnRleHROYW1lICsgXCIgbXVzdCBiZSBhbiBhcnJheSFcIik7XHJcbiAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGxheW91dC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgY29uc3QgaXRlbSA9IGxheW91dFtpXTtcclxuICAgIGZvciAobGV0IGogPSAwOyBqIDwgc3ViUHJvcHMubGVuZ3RoOyBqKyspIHtcclxuICAgICAgaWYgKHR5cGVvZiBpdGVtW3N1YlByb3BzW2pdXSAhPT0gJ251bWJlcicpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Z1ZUdyaWRMYXlvdXQ6ICcgKyBjb250ZXh0TmFtZSArICdbJyArIGkgKyAnXS4nICsgc3ViUHJvcHNbal0gKyAnIG11c3QgYmUgYSBudW1iZXIhJyk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIGlmIChpdGVtLmkgJiYgdHlwZW9mIGl0ZW0uaSAhPT0gJ3N0cmluZycpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdWdWVHcmlkTGF5b3V0OiAnICsgY29udGV4dE5hbWUgKyAnWycgKyBpICsgJ10uaSBtdXN0IGJlIGEgc3RyaW5nIScpO1xyXG4gICAgfVxyXG4gICAgaWYgKGl0ZW0uc3RhdGljICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIGl0ZW0uc3RhdGljICE9PSAnYm9vbGVhbicpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdWdWVHcmlkTGF5b3V0OiAnICsgY29udGV4dE5hbWUgKyAnWycgKyBpICsgJ10uc3RhdGljIG11c3QgYmUgYSBib29sZWFuIScpO1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG5cclxuLy8gRmxvdyBjYW4ndCByZWFsbHkgZmlndXJlIHRoaXMgb3V0LCBzbyB3ZSBqdXN0IHVzZSBPYmplY3RcclxuZXhwb3J0IGZ1bmN0aW9uIGF1dG9CaW5kSGFuZGxlcnMoZWw6IE9iamVjdCwgZm5zOiBBcnJheTxzdHJpbmc+KTogdm9pZCB7XHJcbiAgZm5zLmZvckVhY2goKGtleSkgPT4gZWxba2V5XSA9IGVsW2tleV0uYmluZChlbCkpO1xyXG59XHJcblxyXG5cclxuXHJcbi8qKlxyXG4gKiBDb252ZXJ0IGEgSlMgb2JqZWN0IHRvIENTUyBzdHJpbmcuIFNpbWlsYXIgdG8gUmVhY3QncyBvdXRwdXQgb2YgQ1NTLlxyXG4gKiBAcGFyYW0gb2JqXHJcbiAqIEByZXR1cm5zIHtzdHJpbmd9XHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlTWFya3VwKG9iaikge1xyXG4gICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhvYmopO1xyXG4gICAgaWYgKCFrZXlzLmxlbmd0aCkgcmV0dXJuICcnO1xyXG4gICAgdmFyIGksIGxlbiA9IGtleXMubGVuZ3RoO1xyXG4gICAgdmFyIHJlc3VsdCA9ICcnO1xyXG5cclxuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgIHZhciBrZXkgPSBrZXlzW2ldO1xyXG4gICAgICAgIHZhciB2YWwgPSBvYmpba2V5XTtcclxuICAgICAgICByZXN1bHQgKz0gaHlwaGVuYXRlKGtleSkgKyAnOicgKyBhZGRQeChrZXksIHZhbCkgKyAnOyc7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxuXHJcbi8qIFRoZSBmb2xsb3dpbmcgbGlzdCBpcyBkZWZpbmVkIGluIFJlYWN0J3MgY29yZSAqL1xyXG5leHBvcnQgdmFyIElTX1VOSVRMRVNTID0ge1xyXG4gICAgYW5pbWF0aW9uSXRlcmF0aW9uQ291bnQ6IHRydWUsXHJcbiAgICBib3hGbGV4OiB0cnVlLFxyXG4gICAgYm94RmxleEdyb3VwOiB0cnVlLFxyXG4gICAgYm94T3JkaW5hbEdyb3VwOiB0cnVlLFxyXG4gICAgY29sdW1uQ291bnQ6IHRydWUsXHJcbiAgICBmbGV4OiB0cnVlLFxyXG4gICAgZmxleEdyb3c6IHRydWUsXHJcbiAgICBmbGV4UG9zaXRpdmU6IHRydWUsXHJcbiAgICBmbGV4U2hyaW5rOiB0cnVlLFxyXG4gICAgZmxleE5lZ2F0aXZlOiB0cnVlLFxyXG4gICAgZmxleE9yZGVyOiB0cnVlLFxyXG4gICAgZ3JpZFJvdzogdHJ1ZSxcclxuICAgIGdyaWRDb2x1bW46IHRydWUsXHJcbiAgICBmb250V2VpZ2h0OiB0cnVlLFxyXG4gICAgbGluZUNsYW1wOiB0cnVlLFxyXG4gICAgbGluZUhlaWdodDogdHJ1ZSxcclxuICAgIG9wYWNpdHk6IHRydWUsXHJcbiAgICBvcmRlcjogdHJ1ZSxcclxuICAgIG9ycGhhbnM6IHRydWUsXHJcbiAgICB0YWJTaXplOiB0cnVlLFxyXG4gICAgd2lkb3dzOiB0cnVlLFxyXG4gICAgekluZGV4OiB0cnVlLFxyXG4gICAgem9vbTogdHJ1ZSxcclxuXHJcbiAgICAvLyBTVkctcmVsYXRlZCBwcm9wZXJ0aWVzXHJcbiAgICBmaWxsT3BhY2l0eTogdHJ1ZSxcclxuICAgIHN0b3BPcGFjaXR5OiB0cnVlLFxyXG4gICAgc3Ryb2tlRGFzaG9mZnNldDogdHJ1ZSxcclxuICAgIHN0cm9rZU9wYWNpdHk6IHRydWUsXHJcbiAgICBzdHJva2VXaWR0aDogdHJ1ZVxyXG59O1xyXG5cclxuXHJcbi8qKlxyXG4gKiBXaWxsIGFkZCBweCB0byB0aGUgZW5kIG9mIHN0eWxlIHZhbHVlcyB3aGljaCBhcmUgTnVtYmVycy5cclxuICogQHBhcmFtIG5hbWVcclxuICogQHBhcmFtIHZhbHVlXHJcbiAqIEByZXR1cm5zIHsqfVxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGFkZFB4KG5hbWUsIHZhbHVlKSB7XHJcbiAgICBpZih0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInICYmICFJU19VTklUTEVTU1sgbmFtZSBdKSB7XHJcbiAgICAgICAgcmV0dXJuIHZhbHVlICsgJ3B4JztcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xyXG4gICAgfVxyXG59XHJcblxyXG5cclxuLyoqXHJcbiAqIEh5cGhlbmF0ZSBhIGNhbWVsQ2FzZSBzdHJpbmcuXHJcbiAqXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcclxuICogQHJldHVybiB7U3RyaW5nfVxyXG4gKi9cclxuXHJcbmV4cG9ydCB2YXIgaHlwaGVuYXRlUkUgPSAvKFthLXpcXGRdKShbQS1aXSkvZztcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBoeXBoZW5hdGUoc3RyKSB7XHJcbiAgICByZXR1cm4gc3RyLnJlcGxhY2UoaHlwaGVuYXRlUkUsICckMS0kMicpLnRvTG93ZXJDYXNlKCk7XHJcbn1cclxuXHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZmluZEl0ZW1JbkFycmF5KGFycmF5LCBwcm9wZXJ0eSwgdmFsdWUpIHtcclxuICAgIGZvciAodmFyIGk9MDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKVxyXG4gICAgICAgIGlmIChhcnJheVtpXVtwcm9wZXJ0eV0gPT0gdmFsdWUpXHJcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG5cclxuICAgIHJldHVybiBmYWxzZTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGZpbmRBbmRSZW1vdmUoYXJyYXksIHByb3BlcnR5LCB2YWx1ZSkge1xyXG4gICAgYXJyYXkuZm9yRWFjaChmdW5jdGlvbiAocmVzdWx0LCBpbmRleCkge1xyXG4gICAgICAgIGlmIChyZXN1bHRbcHJvcGVydHldID09PSB2YWx1ZSkge1xyXG4gICAgICAgICAgICAvL1JlbW92ZSBmcm9tIGFycmF5XHJcbiAgICAgICAgICAgIGFycmF5LnNwbGljZShpbmRleCwgMSk7XHJcbiAgICAgICAgfVxyXG4gICAgfSk7XHJcbn1cclxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc3JjL3V0aWxzLmpzIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///0\n"); - -/***/ }), -/* 1 */ -/***/ (function(module, exports, __webpack_require__) { - -eval("\n/* styles */\n__webpack_require__(10)\n\nvar Component = __webpack_require__(4)(\n /* script */\n __webpack_require__(13),\n /* template */\n __webpack_require__(16),\n /* scopeId */\n null,\n /* cssModules */\n null\n)\nComponent.options.__file = \"C:\\\\projects\\\\JBAY\\\\vue-grid-layout\\\\src\\\\GridItem.vue\"\nif (Component.esModule && Object.keys(Component.esModule).some(function (key) {return key !== \"default\" && key !== \"__esModule\"})) {console.error(\"named exports are not supported in *.vue files.\")}\nif (Component.options.functional) {console.error(\"[vue-loader] GridItem.vue: functional components are not supported with templates, they should use render functions.\")}\n\n/* hot reload */\nif (false) {(function () {\n var hotAPI = require(\"vue-hot-reload-api\")\n hotAPI.install(require(\"vue\"), false)\n if (!hotAPI.compatible) return\n module.hot.accept()\n if (!module.hot.data) {\n hotAPI.createRecord(\"data-v-f2ef9cd2\", Component.options)\n } else {\n hotAPI.reload(\"data-v-f2ef9cd2\", Component.options)\n }\n})()}\n\nmodule.exports = Component.exports\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvR3JpZEl0ZW0udnVlP2RlNjMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUNBO0FBQ0Esc0JBQTRLOztBQUU1SztBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUFnRztBQUNoRztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrRUFBK0UsaURBQWlELElBQUk7QUFDcEksbUNBQW1DOztBQUVuQztBQUNBLFlBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCIsImZpbGUiOiIxLmpzIiwic291cmNlc0NvbnRlbnQiOlsiXG4vKiBzdHlsZXMgKi9cbnJlcXVpcmUoXCIhIXZ1ZS1zdHlsZS1sb2FkZXIhY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLWNvbXBpbGVyL2luZGV4P3tcXFwiaWRcXFwiOlxcXCJkYXRhLXYtZjJlZjljZDJcXFwiLFxcXCJzY29wZWRcXFwiOmZhbHNlLFxcXCJoYXNJbmxpbmVDb25maWdcXFwiOmZhbHNlfSEuLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3I/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL0dyaWRJdGVtLnZ1ZVwiKVxuXG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZShcIiEuLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvY29tcG9uZW50LW5vcm1hbGl6ZXJcIikoXG4gIC8qIHNjcmlwdCAqL1xuICByZXF1aXJlKFwiISFiYWJlbC1sb2FkZXIhLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yP3R5cGU9c2NyaXB0JmluZGV4PTAhLi9HcmlkSXRlbS52dWVcIiksXG4gIC8qIHRlbXBsYXRlICovXG4gIHJlcXVpcmUoXCIhIS4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi90ZW1wbGF0ZS1jb21waWxlci9pbmRleD97XFxcImlkXFxcIjpcXFwiZGF0YS12LWYyZWY5Y2QyXFxcIn0hLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yP3R5cGU9dGVtcGxhdGUmaW5kZXg9MCEuL0dyaWRJdGVtLnZ1ZVwiKSxcbiAgLyogc2NvcGVJZCAqL1xuICBudWxsLFxuICAvKiBjc3NNb2R1bGVzICovXG4gIG51bGxcbilcbkNvbXBvbmVudC5vcHRpb25zLl9fZmlsZSA9IFwiQzpcXFxccHJvamVjdHNcXFxcSkJBWVxcXFx2dWUtZ3JpZC1sYXlvdXRcXFxcc3JjXFxcXEdyaWRJdGVtLnZ1ZVwiXG5pZiAoQ29tcG9uZW50LmVzTW9kdWxlICYmIE9iamVjdC5rZXlzKENvbXBvbmVudC5lc01vZHVsZSkuc29tZShmdW5jdGlvbiAoa2V5KSB7cmV0dXJuIGtleSAhPT0gXCJkZWZhdWx0XCIgJiYga2V5ICE9PSBcIl9fZXNNb2R1bGVcIn0pKSB7Y29uc29sZS5lcnJvcihcIm5hbWVkIGV4cG9ydHMgYXJlIG5vdCBzdXBwb3J0ZWQgaW4gKi52dWUgZmlsZXMuXCIpfVxuaWYgKENvbXBvbmVudC5vcHRpb25zLmZ1bmN0aW9uYWwpIHtjb25zb2xlLmVycm9yKFwiW3Z1ZS1sb2FkZXJdIEdyaWRJdGVtLnZ1ZTogZnVuY3Rpb25hbCBjb21wb25lbnRzIGFyZSBub3Qgc3VwcG9ydGVkIHdpdGggdGVtcGxhdGVzLCB0aGV5IHNob3VsZCB1c2UgcmVuZGVyIGZ1bmN0aW9ucy5cIil9XG5cbi8qIGhvdCByZWxvYWQgKi9cbmlmIChtb2R1bGUuaG90KSB7KGZ1bmN0aW9uICgpIHtcbiAgdmFyIGhvdEFQSSA9IHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIilcbiAgaG90QVBJLmluc3RhbGwocmVxdWlyZShcInZ1ZVwiKSwgZmFsc2UpXG4gIGlmICghaG90QVBJLmNvbXBhdGlibGUpIHJldHVyblxuICBtb2R1bGUuaG90LmFjY2VwdCgpXG4gIGlmICghbW9kdWxlLmhvdC5kYXRhKSB7XG4gICAgaG90QVBJLmNyZWF0ZVJlY29yZChcImRhdGEtdi1mMmVmOWNkMlwiLCBDb21wb25lbnQub3B0aW9ucylcbiAgfSBlbHNlIHtcbiAgICBob3RBUEkucmVsb2FkKFwiZGF0YS12LWYyZWY5Y2QyXCIsIENvbXBvbmVudC5vcHRpb25zKVxuICB9XG59KSgpfVxuXG5tb2R1bGUuZXhwb3J0cyA9IENvbXBvbmVudC5leHBvcnRzXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9HcmlkSXRlbS52dWVcbi8vIG1vZHVsZSBpZCA9IDFcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1\n"); - -/***/ }), -/* 2 */ -/***/ (function(module, exports) { - -eval("/*\r\n\tMIT License http://www.opensource.org/licenses/mit-license.php\r\n\tAuthor Tobias Koppers @sokra\r\n*/\r\n// css base code, injected by the css-loader\r\nmodule.exports = function() {\r\n\tvar list = [];\r\n\r\n\t// return the list of modules as css string\r\n\tlist.toString = function toString() {\r\n\t\tvar result = [];\r\n\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\tvar item = this[i];\r\n\t\t\tif(item[2]) {\r\n\t\t\t\tresult.push(\"@media \" + item[2] + \"{\" + item[1] + \"}\");\r\n\t\t\t} else {\r\n\t\t\t\tresult.push(item[1]);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn result.join(\"\");\r\n\t};\r\n\r\n\t// import a list of modules into the list\r\n\tlist.i = function(modules, mediaQuery) {\r\n\t\tif(typeof modules === \"string\")\r\n\t\t\tmodules = [[null, modules, \"\"]];\r\n\t\tvar alreadyImportedModules = {};\r\n\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\tvar id = this[i][0];\r\n\t\t\tif(typeof id === \"number\")\r\n\t\t\t\talreadyImportedModules[id] = true;\r\n\t\t}\r\n\t\tfor(i = 0; i < modules.length; i++) {\r\n\t\t\tvar item = modules[i];\r\n\t\t\t// skip already imported module\r\n\t\t\t// this implementation is not 100% perfect for weird media query combinations\r\n\t\t\t// when a module is imported multiple times with different media queries.\r\n\t\t\t// I hope this will never occur (Hey this way we have smaller bundles)\r\n\t\t\tif(typeof item[0] !== \"number\" || !alreadyImportedModules[item[0]]) {\r\n\t\t\t\tif(mediaQuery && !item[2]) {\r\n\t\t\t\t\titem[2] = mediaQuery;\r\n\t\t\t\t} else if(mediaQuery) {\r\n\t\t\t\t\titem[2] = \"(\" + item[2] + \") and (\" + mediaQuery + \")\";\r\n\t\t\t\t}\r\n\t\t\t\tlist.push(item);\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\treturn list;\r\n};\r\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanM/MTU5ZiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsaUJBQWlCO0FBQ2pDO0FBQ0E7QUFDQSx3Q0FBd0MsZ0JBQWdCO0FBQ3hELElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsaUJBQWlCO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxvQkFBb0I7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6IjIuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxyXG5cdE1JVCBMaWNlbnNlIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwXHJcblx0QXV0aG9yIFRvYmlhcyBLb3BwZXJzIEBzb2tyYVxyXG4qL1xyXG4vLyBjc3MgYmFzZSBjb2RlLCBpbmplY3RlZCBieSB0aGUgY3NzLWxvYWRlclxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKCkge1xyXG5cdHZhciBsaXN0ID0gW107XHJcblxyXG5cdC8vIHJldHVybiB0aGUgbGlzdCBvZiBtb2R1bGVzIGFzIGNzcyBzdHJpbmdcclxuXHRsaXN0LnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcoKSB7XHJcblx0XHR2YXIgcmVzdWx0ID0gW107XHJcblx0XHRmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xyXG5cdFx0XHR2YXIgaXRlbSA9IHRoaXNbaV07XHJcblx0XHRcdGlmKGl0ZW1bMl0pIHtcclxuXHRcdFx0XHRyZXN1bHQucHVzaChcIkBtZWRpYSBcIiArIGl0ZW1bMl0gKyBcIntcIiArIGl0ZW1bMV0gKyBcIn1cIik7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0cmVzdWx0LnB1c2goaXRlbVsxXSk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHRcdHJldHVybiByZXN1bHQuam9pbihcIlwiKTtcclxuXHR9O1xyXG5cclxuXHQvLyBpbXBvcnQgYSBsaXN0IG9mIG1vZHVsZXMgaW50byB0aGUgbGlzdFxyXG5cdGxpc3QuaSA9IGZ1bmN0aW9uKG1vZHVsZXMsIG1lZGlhUXVlcnkpIHtcclxuXHRcdGlmKHR5cGVvZiBtb2R1bGVzID09PSBcInN0cmluZ1wiKVxyXG5cdFx0XHRtb2R1bGVzID0gW1tudWxsLCBtb2R1bGVzLCBcIlwiXV07XHJcblx0XHR2YXIgYWxyZWFkeUltcG9ydGVkTW9kdWxlcyA9IHt9O1xyXG5cdFx0Zm9yKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcclxuXHRcdFx0dmFyIGlkID0gdGhpc1tpXVswXTtcclxuXHRcdFx0aWYodHlwZW9mIGlkID09PSBcIm51bWJlclwiKVxyXG5cdFx0XHRcdGFscmVhZHlJbXBvcnRlZE1vZHVsZXNbaWRdID0gdHJ1ZTtcclxuXHRcdH1cclxuXHRcdGZvcihpID0gMDsgaSA8IG1vZHVsZXMubGVuZ3RoOyBpKyspIHtcclxuXHRcdFx0dmFyIGl0ZW0gPSBtb2R1bGVzW2ldO1xyXG5cdFx0XHQvLyBza2lwIGFscmVhZHkgaW1wb3J0ZWQgbW9kdWxlXHJcblx0XHRcdC8vIHRoaXMgaW1wbGVtZW50YXRpb24gaXMgbm90IDEwMCUgcGVyZmVjdCBmb3Igd2VpcmQgbWVkaWEgcXVlcnkgY29tYmluYXRpb25zXHJcblx0XHRcdC8vICB3aGVuIGEgbW9kdWxlIGlzIGltcG9ydGVkIG11bHRpcGxlIHRpbWVzIHdpdGggZGlmZmVyZW50IG1lZGlhIHF1ZXJpZXMuXHJcblx0XHRcdC8vICBJIGhvcGUgdGhpcyB3aWxsIG5ldmVyIG9jY3VyIChIZXkgdGhpcyB3YXkgd2UgaGF2ZSBzbWFsbGVyIGJ1bmRsZXMpXHJcblx0XHRcdGlmKHR5cGVvZiBpdGVtWzBdICE9PSBcIm51bWJlclwiIHx8ICFhbHJlYWR5SW1wb3J0ZWRNb2R1bGVzW2l0ZW1bMF1dKSB7XHJcblx0XHRcdFx0aWYobWVkaWFRdWVyeSAmJiAhaXRlbVsyXSkge1xyXG5cdFx0XHRcdFx0aXRlbVsyXSA9IG1lZGlhUXVlcnk7XHJcblx0XHRcdFx0fSBlbHNlIGlmKG1lZGlhUXVlcnkpIHtcclxuXHRcdFx0XHRcdGl0ZW1bMl0gPSBcIihcIiArIGl0ZW1bMl0gKyBcIikgYW5kIChcIiArIG1lZGlhUXVlcnkgKyBcIilcIjtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0bGlzdC5wdXNoKGl0ZW0pO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fTtcclxuXHRyZXR1cm4gbGlzdDtcclxufTtcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcbi8vIG1vZHVsZSBpZCA9IDJcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2\n"); - -/***/ }), -/* 3 */ -/***/ (function(module, exports, __webpack_require__) { - -eval("/*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n Modified by Evan You @yyx990803\n*/\n\nvar hasDocument = typeof document !== 'undefined'\n\nif (typeof DEBUG !== 'undefined' && DEBUG) {\n if (!hasDocument) {\n throw new Error(\n 'vue-style-loader cannot be used in a non-browser environment. ' +\n \"Use { target: 'node' } in your Webpack config to indicate a server-rendering environment.\"\n ) }\n}\n\nvar listToStyles = __webpack_require__(12)\n\n/*\ntype StyleObject = {\n id: number;\n parts: Array\n}\n\ntype StyleObjectPart = {\n css: string;\n media: string;\n sourceMap: ?string\n}\n*/\n\nvar stylesInDom = {/*\n [id: number]: {\n id: number,\n refs: number,\n parts: Array<(obj?: StyleObjectPart) => void>\n }\n*/}\n\nvar head = hasDocument && (document.head || document.getElementsByTagName('head')[0])\nvar singletonElement = null\nvar singletonCounter = 0\nvar isProduction = false\nvar noop = function () {}\n\n// Force single-tag solution on IE6-9, which has a hard limit on the # of \\r\\n\\r\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\n// exports\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvR3JpZEl0ZW0udnVlP2I3OTAiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTs7O0FBR0E7QUFDQSwyQ0FBNEMsaUNBQWlDLDRDQUE0QyxnQ0FBZ0MsZ0NBQWdDLHFDQUFxQyxjQUFjLGtCQUFrQixHQUFHLDJDQUEyQyxpQkFBaUIsZUFBZSxHQUFHLDJCQUEyQixtQkFBbUIsaUJBQWlCLEdBQUcseUNBQXlDLHNCQUFzQixpQkFBaUIsR0FBRyx1Q0FBdUMsc0JBQXNCLG1CQUFtQixpQ0FBaUMsaUJBQWlCLGdDQUFnQyw2QkFBNkIsNEJBQTRCLDJCQUEyQix3QkFBd0IsR0FBRywwQ0FBMEMseUJBQXlCLGtCQUFrQixtQkFBbUIsZ0JBQWdCLGVBQWUsMENBQTBDLGsxQkFBazFCLHdDQUF3QywyQkFBMkIsbUNBQW1DLHFDQUFxQyw2QkFBNkIsd0JBQXdCLEdBQUcsOENBQThDLGdCQUFnQixjQUFjLHlDQUF5Qyw2N0NBQTY3Qyx1Q0FBdUMsd0JBQXdCLG1DQUFtQyxxQ0FBcUMsd0JBQXdCLGtCQUFrQixHQUFHLFVBQVUsK0VBQStFLEtBQUssV0FBVyxXQUFXLFdBQVcsS0FBSyxLQUFLLFdBQVcsVUFBVSxVQUFVLEtBQUssS0FBSyxVQUFVLFVBQVUsS0FBSyxLQUFLLFVBQVUsVUFBVSxLQUFLLEtBQUssV0FBVyxVQUFVLEtBQUssS0FBSyxXQUFXLFVBQVUsV0FBVyxVQUFVLFdBQVcsV0FBVyxXQUFXLFdBQVcsV0FBVyxLQUFLLEtBQUssV0FBVyxVQUFVLFVBQVUsVUFBVSxVQUFVLFlBQVksV0FBVyxXQUFXLFdBQVcsV0FBVyxXQUFXLFdBQVcsS0FBSyxLQUFLLFVBQVUsVUFBVSxZQUFZLFdBQVcsV0FBVyxXQUFXLFdBQVcsV0FBVyxVQUFVLDZJQUE2SSw0SkFBNEosaVVBQWlVLHVDQUF1QyxrREFBa0QsNENBQTRDLDBDQUEwQywyQ0FBMkMsb0JBQW9CLHdCQUF3QixTQUFTLHFEQUFxRCx1QkFBdUIscUJBQXFCLFNBQVMscUNBQXFDLHlCQUF5Qix1QkFBdUIsU0FBUyxtREFBbUQsNEJBQTRCLHVCQUF1QixTQUFTLGlEQUFpRCw0QkFBNEIseUJBQXlCLHVDQUF1Qyx1QkFBdUIsc0NBQXNDLG1DQUFtQyxrQ0FBa0MsaUNBQWlDLDhCQUE4QixTQUFTLG9EQUFvRCwrQkFBK0Isd0JBQXdCLHlCQUF5QixzQkFBc0IscUJBQXFCLGdEQUFnRCxrMUJBQWsxQiw4Q0FBOEMsaUNBQWlDLHlDQUF5QywyQ0FBMkMsbUNBQW1DLDhCQUE4QixTQUFTLHdEQUF3RCxzQkFBc0Isb0JBQW9CLCtDQUErQyw2N0NBQTY3Qyw2Q0FBNkMsOEJBQThCLHlDQUF5QywyQ0FBMkMsOEJBQThCLHdCQUF3QixTQUFTLHdDQUF3QyxvRkFBb0YsZ0JBQWdCLGdCQUFnQix5REFBeUQseUJBQXlCLG1EQUFtRCxtREFBbUQsNEJBQTRCLG1EQUFtRCx5QkFBeUIsK0VBQStFLHNDQUFzQyxtRkFBbUYsOEJBQThCLCtFQUErRSwyQkFBMkIsOEVBQThFLDRCQUE0QiwrRUFBK0UsaUNBQWlDLHdIQUF3SCwrQkFBK0Isd0hBQXdILHNDQUFzQyxnRkFBZ0YsMkJBQTJCLGlIQUFpSCwyQ0FBMkMsb0hBQW9ILHdCQUF3QixvSEFBb0gsd0JBQXdCLDJIQUEySCx3QkFBd0IsMkhBQTJILHFCQUFxQixvRkFBb0YscUJBQXFCLG9GQUFvRixxQkFBcUIsb0ZBQW9GLHFCQUFxQixvRkFBb0YscUJBQXFCLG1EQUFtRCxrQ0FBa0MsOEhBQThILGlDQUFpQyx1SEFBdUgsb0NBQW9DLDhIQUE4SCxjQUFjLG1FQUFtRSx3QkFBd0IsbWxCQUFtbEIsMlJBQTJSLGFBQWEseUJBQXlCLGdDQUFnQyxrSkFBa0osNENBQTRDLGtCQUFrQiw2REFBNkQseUNBQXlDLGtCQUFrQix1RUFBdUUsb0RBQW9ELHFEQUFxRCxxQkFBcUIsa0JBQWtCLHVFQUF1RSxvREFBb0QscURBQXFELHFCQUFxQixrQkFBa0IscUVBQXFFLCtDQUErQyxrQkFBa0Isa0VBQWtFLGlNQUFpTSx1REFBdUQsbUNBQW1DLGtCQUFrQiw4RUFBOEUsa0VBQWtFLDRFQUE0RSw0RUFBNEUsNEVBQTRFLGtGQUFrRix1RUFBdUUsb0NBQW9DLGtCQUFrQixFQUFFLHVMQUF1TCxtREFBbUQsYUFBYSx1Q0FBdUMsZ0NBQWdDLDZHQUE2RyxtRUFBbUUsNkVBQTZFLDZFQUE2RSw2RUFBNkUsbUZBQW1GLGFBQWEsbUNBQW1DLGdEQUFnRCx3REFBd0QsNkZBQTZGLGlHQUFpRyxvREFBb0QsZ0RBQWdELDhEQUE4RCxpQkFBaUIsT0FBTyxzREFBc0QsaUJBQWlCLGdEQUFnRCw4REFBOEQsaUJBQWlCLE9BQU8sc0RBQXNELGlCQUFpQixzRUFBc0UsbUNBQW1DLGFBQWEscUJBQXFCLDBDQUEwQyxzREFBc0QsaUJBQWlCLHlDQUF5QyxvQ0FBb0Msc0ZBQXNGLHFFQUFxRSxxQkFBcUIseUNBQXlDLG9DQUFvQyw4SUFBOEkseURBQXlELHNEQUFzRCxtQ0FBbUMsRUFBRSxtREFBbUQscURBQXFELGdHQUFnRyx1REFBdUQsNkJBQTZCLEVBQUUseUJBQXlCLHFCQUFxQixPQUFPLG9EQUFvRCxtRUFBbUUsRUFBRSxxQkFBcUIsaUJBQWlCLDJDQUEyQyxzREFBc0QsaUJBQWlCLHlDQUF5QyxvQ0FBb0Msc0ZBQXNGLHFFQUFxRSxxQkFBcUIseUNBQXlDLG9DQUFvQywyRkFBMkYsbURBQW1ELHdGQUF3RixpRkFBaUYsbURBQW1ELHVEQUF1RCxzSUFBc0ksNkRBQTZELGlDQUFpQyxFQUFFLHlCQUF5QixxQkFBcUIsT0FBTyxvREFBb0QsbUVBQW1FLEVBQUUscUJBQXFCLGlCQUFpQix5Q0FBeUMsdUNBQXVDLGlCQUFpQixvQ0FBb0MsdUNBQXVDLGlCQUFpQiw4Q0FBOEMsdUNBQXVDLGlCQUFpQixpQ0FBaUMsdUNBQXVDLGlCQUFpQixpQ0FBaUMsdUNBQXVDLGlCQUFpQixpQ0FBaUMsdUNBQXVDLGlCQUFpQixpQ0FBaUMsdUNBQXVDLGlCQUFpQix5Q0FBeUMsdUNBQXVDLGlCQUFpQixhQUFhLHdCQUF3Qiw2QkFBNkIsNEVBQTRFLGlCQUFpQix5Q0FBeUMseUNBQXlDLCtFQUErRSxxQkFBcUIsT0FBTyxzREFBc0QscUJBQXFCLGlCQUFpQixhQUFhLHVCQUF1QiwwQ0FBMEMsc0RBQXNELG1DQUFtQywyQ0FBMkMscUJBQXFCLG9GQUFvRiw4Q0FBOEMsb0RBQW9ELHNGQUFzRiwyREFBMkQseUJBQXlCLE9BQU8sMERBQTBELHlCQUF5QixxQkFBcUIsMENBQTBDLHdEQUF3RCwwREFBMEQscUJBQXFCLGtDQUFrQyx1R0FBdUcsc0ZBQXNGLCtGQUErRix5QkFBeUIsT0FBTywyRkFBMkYseUJBQXlCLHlCQUF5QixPQUFPLHlHQUF5RywyRkFBMkYseUJBQXlCLE9BQU8seUZBQXlGLHlCQUF5QixxQkFBcUIsdUNBQXVDLHFCQUFxQixpREFBaUQsK0RBQStELDhJQUE4SSw4REFBOEQsS0FBSyxZQUFZLHlDQUF5QyxxQkFBcUIseUNBQXlDLGlHQUFpRyxvREFBb0Qsd0ZBQXdGLHNEQUFzRCx3REFBd0Qsb0RBQW9ELG1EQUFtRCxrQ0FBa0MsK0tBQStLLDJGQUEyRixpREFBaUQsdUZBQXVGLDZCQUE2QixPQUFPLHVGQUF1Riw2QkFBNkIscUZBQXFGLHNKQUFzSixvREFBb0Qsa0NBQWtDLGdMQUFnTCx3RkFBd0Ysc0RBQXNELHdEQUF3RCw0RkFBNEYsaURBQWlELG9EQUFvRCxrQ0FBa0MscUJBQXFCLDhHQUE4Ryw0Q0FBNEMsMENBQTBDLHFCQUFxQiw0Q0FBNEMsMENBQTBDLHFCQUFxQiw0Q0FBNEMsMENBQTBDLHFCQUFxQiw0Q0FBNEMsMENBQTBDLHFCQUFxQix3Q0FBd0Msa0NBQWtDLHFCQUFxQixvQ0FBb0Msa0NBQWtDLHFCQUFxQix1Q0FBdUMsbUNBQW1DLG1FQUFtRSxxRUFBcUUscUJBQXFCLG1IQUFtSCxxR0FBcUcscUJBQXFCLDJHQUEyRyxpQkFBaUIsb0NBQW9DLGdEQUFnRCxtRUFBbUUsbUpBQW1KLDhEQUE4RCxLQUFLLFlBQVksaURBQWlELHlDQUF5QyxpQkFBaUIseUNBQXlDLCtGQUErRixvREFBb0QsbUdBQW1HLGtGQUFrRixpREFBaUQsOEZBQThGLDZCQUE2QixPQUFPLHFGQUFxRiw2QkFBNkIsOEVBQThFLHdEQUF3RCxtREFBbUQsa0NBQWtDLGtHQUFrRywyRkFBMkYsOEVBQThFLDhGQUE4Riw4RkFBOEYsNkJBQTZCLE9BQU8scUZBQXFGLDZCQUE2Qiw4RUFBOEUsOEZBQThGLHdGQUF3RixpREFBaUQsb0RBQW9ELGdEQUFnRCxrQ0FBa0MscUlBQXFJLDhGQUE4Rix5RkFBeUYsNkJBQTZCLE9BQU8seUZBQXlGLDZCQUE2QixtRkFBbUYsdUdBQXVHLCtJQUErSSw4RkFBOEYsd0RBQXdELGtDQUFrQyxxQkFBcUIsOEVBQThFLGlGQUFpRixxQkFBcUIsT0FBTyxpRkFBaUYscUJBQXFCLHVDQUF1QyxtQ0FBbUMsbUVBQW1FLG1FQUFtRSxxQkFBcUIsaUhBQWlILG9FQUFvRSxxQkFBcUIseUdBQXlHLGlCQUFpQixzREFBc0QseURBQXlELCtFQUErRSxtQ0FBbUMscVJBQXFSLGdiQUFnYixxQkFBcUIsT0FBTyxtQ0FBbUMsb1JBQW9SLGdiQUFnYixxQkFBcUIsdUNBQXVDLGlCQUFpQiwySEFBMkgsT0FBTyw4RUFBOEUsT0FBTywrRUFBK0UsT0FBTyxpS0FBaUsseURBQXlELHFhQUFxYSxtR0FBbUcsdUdBQXVHLHdFQUF3RSxnQ0FBZ0MsTUFBTSxpQkFBaUIsc0ZBQXNGLDBHQUEwRywwRkFBMEYsb0NBQW9DLGlCQUFpQixzSUFBc0ksT0FBTyxxREFBcUQsT0FBTyxvREFBb0QsT0FBTyw4RUFBOEUseURBQXlELDhQQUE4UCxzR0FBc0csdUdBQXVHLHdFQUF3RSw0QkFBNEIsTUFBTSxpQkFBaUIsd0RBQXdELGdEQUFnRCxrRUFBa0UsMkNBQTJDLHFCQUFxQixpQkFBaUIsdUNBQXVDLHVDQUF1QyxpQkFBaUIsYUFBYSxVQUFVLDhDQUE4Qzs7QUFFaHZrQyIsImZpbGUiOiIxMS5qcyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikoKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIlxcbi52dWUtZ3JpZC1pdGVtIHtcXG4gICAgdHJhbnNpdGlvbjogYWxsIDIwMG1zIGVhc2U7XFxuICAgIHRyYW5zaXRpb24tcHJvcGVydHk6IGxlZnQsIHRvcCwgcmlnaHQ7XFxuICAgIC8qIGFkZCByaWdodCBmb3IgcnRsICovXFxufVxcbi52dWUtZ3JpZC1pdGVtLmNzc1RyYW5zZm9ybXMge1xcbiAgICB0cmFuc2l0aW9uLXByb3BlcnR5OiB0cmFuc2Zvcm07XFxuICAgIGxlZnQ6IDA7XFxuICAgIHJpZ2h0OiBhdXRvO1xcbn1cXG4udnVlLWdyaWQtaXRlbS5jc3NUcmFuc2Zvcm1zLnJlbmRlci1ydGwge1xcbiAgICBsZWZ0OiBhdXRvO1xcbiAgICByaWdodDogMDtcXG59XFxuLnZ1ZS1ncmlkLWl0ZW0ucmVzaXppbmcge1xcbiAgICBvcGFjaXR5OiAwLjY7XFxuICAgIHotaW5kZXg6IDM7XFxufVxcbi52dWUtZ3JpZC1pdGVtLnZ1ZS1kcmFnZ2FibGUtZHJhZ2dpbmcge1xcbiAgICB0cmFuc2l0aW9uOm5vbmU7XFxuICAgIHotaW5kZXg6IDM7XFxufVxcbi52dWUtZ3JpZC1pdGVtLnZ1ZS1ncmlkLXBsYWNlaG9sZGVyIHtcXG4gICAgYmFja2dyb3VuZDogcmVkO1xcbiAgICBvcGFjaXR5OiAwLjI7XFxuICAgIHRyYW5zaXRpb24tZHVyYXRpb246IDEwMG1zO1xcbiAgICB6LWluZGV4OiAyO1xcbiAgICAtd2Via2l0LXVzZXItc2VsZWN0OiBub25lO1xcbiAgICAtbW96LXVzZXItc2VsZWN0OiBub25lO1xcbiAgICAtbXMtdXNlci1zZWxlY3Q6IG5vbmU7XFxuICAgIC1vLXVzZXItc2VsZWN0OiBub25lO1xcbiAgICB1c2VyLXNlbGVjdDogbm9uZTtcXG59XFxuLnZ1ZS1ncmlkLWl0ZW0gPiAudnVlLXJlc2l6YWJsZS1oYW5kbGUge1xcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XFxuICAgIHdpZHRoOiAyMHB4O1xcbiAgICBoZWlnaHQ6IDIwcHg7XFxuICAgIGJvdHRvbTogMDtcXG4gICAgcmlnaHQ6IDA7XFxuICAgIGJhY2tncm91bmQ6IHVybCgnZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxQRDk0Yld3Z2RtVnljMmx2YmowaU1TNHdJaUJ6ZEdGdVpHRnNiMjVsUFNKdWJ5SS9QZzA4SVMwdElFZGxibVZ5WVhSdmNqb2dRV1J2WW1VZ1JtbHlaWGR2Y210eklFTlROaXdnUlhod2IzSjBJRk5XUnlCRmVIUmxibk5wYjI0Z1lua2dRV0Z5YjI0Z1FtVmhiR3dnS0doMGRIQTZMeTltYVhKbGQyOXlhM011WVdKbFlXeHNMbU52YlNrZ0xpQldaWEp6YVc5dU9pQXdMall1TVNBZ0xTMCtEVHdoUkU5RFZGbFFSU0J6ZG1jZ1VGVkNURWxESUNJdEx5OVhNME12TDBSVVJDQlRWa2NnTVM0eEx5OUZUaUlnSW1oMGRIQTZMeTkzZDNjdWR6TXViM0puTDBkeVlYQm9hV056TDFOV1J5OHhMakV2UkZSRUwzTjJaekV4TG1SMFpDSStEVHh6ZG1jZ2FXUTlJbFZ1ZEdsMGJHVmtMVkJoWjJVbE1qQXhJaUIyYVdWM1FtOTRQU0l3SURBZ05pQTJJaUJ6ZEhsc1pUMGlZbUZqYTJkeWIzVnVaQzFqYjJ4dmNqb2pabVptWm1abU1EQWlJSFpsY25OcGIyNDlJakV1TVNJTkNYaHRiRzV6UFNKb2RIUndPaTh2ZDNkM0xuY3pMbTl5Wnk4eU1EQXdMM04yWnlJZ2VHMXNibk02ZUd4cGJtczlJbWgwZEhBNkx5OTNkM2N1ZHpNdWIzSm5MekU1T1RrdmVHeHBibXNpSUhodGJEcHpjR0ZqWlQwaWNISmxjMlZ5ZG1VaURRbDRQU0l3Y0hnaUlIazlJakJ3ZUNJZ2QybGtkR2c5SWpad2VDSWdhR1ZwWjJoMFBTSTJjSGdpRFQ0TkNUeG5JRzl3WVdOcGRIazlJakF1TXpBeUlqNE5DUWs4Y0dGMGFDQmtQU0pOSURZZ05pQk1JREFnTmlCTUlEQWdOQzR5SUV3Z05DQTBMaklnVENBMExqSWdOQzR5SUV3Z05DNHlJREFnVENBMklEQWdUQ0EySURZZ1RDQTJJRFlnV2lJZ1ptbHNiRDBpSXpBd01EQXdNQ0l2UGcwSlBDOW5QZzA4TDNOMlp6ND0nKTtcXG4gICAgYmFja2dyb3VuZC1wb3NpdGlvbjogYm90dG9tIHJpZ2h0O1xcbiAgICBwYWRkaW5nOiAwIDNweCAzcHggMDtcXG4gICAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDtcXG4gICAgYmFja2dyb3VuZC1vcmlnaW46IGNvbnRlbnQtYm94O1xcbiAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xcbiAgICBjdXJzb3I6IHNlLXJlc2l6ZTtcXG59XFxuLnZ1ZS1ncmlkLWl0ZW0gPiAudnVlLXJ0bC1yZXNpemFibGUtaGFuZGxlIHtcXG4gICAgYm90dG9tOiAwO1xcbiAgICBsZWZ0OiAwO1xcbiAgICBiYWNrZ3JvdW5kOiB1cmwoZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxQSE4yWnlCM2FXUjBhRDBpTVRBdU1EQXdNREF3TURBd01EQXdNREF5SWlCb1pXbG5hSFE5SWpFd0xqQXdNREF3TURBd01EQXdNREF3TWlJZ2VHMXNibk05SW1oMGRIQTZMeTkzZDNjdWR6TXViM0puTHpJd01EQXZjM1puSWo0S0lEd2hMUzBnUTNKbFlYUmxaQ0IzYVhSb0lFMWxkR2h2WkNCRWNtRjNJQzBnYUhSMGNEb3ZMMmRwZEdoMVlpNWpiMjB2WkhWdmNHbDRaV3d2VFdWMGFHOWtMVVJ5WVhjdklDMHRQZ29nUEdjK0NpQWdQSFJwZEd4bFBtSmhZMnRuY205MWJtUThMM1JwZEd4bFBnb2dJRHh5WldOMElHWnBiR3c5SW01dmJtVWlJR2xrUFNKallXNTJZWE5mWW1GamEyZHliM1Z1WkNJZ2FHVnBaMmgwUFNJeE1pSWdkMmxrZEdnOUlqRXlJaUI1UFNJdE1TSWdlRDBpTFRFaUx6NEtJQ0E4WnlCa2FYTndiR0Y1UFNKdWIyNWxJaUJ2ZG1WeVpteHZkejBpZG1semFXSnNaU0lnZVQwaU1DSWdlRDBpTUNJZ2FHVnBaMmgwUFNJeE1EQWxJaUIzYVdSMGFEMGlNVEF3SlNJZ2FXUTlJbU5oYm5aaGMwZHlhV1FpUGdvZ0lDQThjbVZqZENCbWFXeHNQU0oxY213b0kyZHlhV1J3WVhSMFpYSnVLU0lnYzNSeWIydGxMWGRwWkhSb1BTSXdJaUI1UFNJd0lpQjRQU0l3SWlCb1pXbG5hSFE5SWpFd01DVWlJSGRwWkhSb1BTSXhNREFsSWk4K0NpQWdQQzluUGdvZ1BDOW5QZ29nUEdjK0NpQWdQSFJwZEd4bFBreGhlV1Z5SURFOEwzUnBkR3hsUGdvZ0lEeHNhVzVsSUdOaGJuWmhjejBpSTJabVptWm1aaUlnWTJGdWRtRnpMVzl3WVdOcGRIazlJakVpSUhOMGNtOXJaUzFzYVc1bFkyRndQU0oxYm1SbFptbHVaV1FpSUhOMGNtOXJaUzFzYVc1bGFtOXBiajBpZFc1a1pXWnBibVZrSWlCcFpEMGljM1puWHpFaUlIa3lQU0l0TnpBdU1UYzROREEzSWlCNE1qMGlNVEkwTGpRMk5ERTNOU0lnZVRFOUlpMHpPQzR6T1RJM016Y2lJSGd4UFNJeE5EUXVPREl4TWpnNUlpQnpkSEp2YTJVdGQybGtkR2c5SWpFdU5TSWdjM1J5YjJ0bFBTSWpNREF3SWlCbWFXeHNQU0p1YjI1bElpOCtDaUFnUEd4cGJtVWdjM1J5YjJ0bFBTSWpOalkyTmpZMklpQnpkSEp2YTJVdGJHbHVaV05oY0QwaWRXNWtaV1pwYm1Wa0lpQnpkSEp2YTJVdGJHbHVaV3B2YVc0OUluVnVaR1ZtYVc1bFpDSWdhV1E5SW5OMloxODFJaUI1TWowaU9TNHhNRFk1TlRjaUlIZ3lQU0l3TGprME56STBOeUlnZVRFOUlpMHdMakF4T0RFeU9DSWdlREU5SWpBdU9UUTNNalEzSWlCemRISnZhMlV0ZDJsa2RHZzlJaklpSUdacGJHdzlJbTV2Ym1VaUx6NEtJQ0E4YkdsdVpTQnpkSEp2YTJVdGJHbHVaV05oY0QwaWRXNWtaV1pwYm1Wa0lpQnpkSEp2YTJVdGJHbHVaV3B2YVc0OUluVnVaR1ZtYVc1bFpDSWdhV1E5SW5OMloxODNJaUI1TWowaU9TSWdlREk5SWpFd0xqQTNNelV5T1NJZ2VURTlJamtpSUhneFBTSXRNQzQyTlRVMk5DSWdjM1J5YjJ0bExYZHBaSFJvUFNJeUlpQnpkSEp2YTJVOUlpTTJOalkyTmpZaUlHWnBiR3c5SW01dmJtVWlMejRLSUR3dlp6NEtQQzl6ZG1jKyk7XFxuICAgIGJhY2tncm91bmQtcG9zaXRpb246IGJvdHRvbSBsZWZ0O1xcbiAgICBwYWRkaW5nLWxlZnQ6IDNweDtcXG4gICAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDtcXG4gICAgYmFja2dyb3VuZC1vcmlnaW46IGNvbnRlbnQtYm94O1xcbiAgICBjdXJzb3I6IHN3LXJlc2l6ZTtcXG4gICAgcmlnaHQ6IGF1dG87XFxufVxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi9zcmMvR3JpZEl0ZW0udnVlP2JjM2YxMWI0XCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCI7QUFZQTtJQUNBLDJCQUFBO0lBQ0Esc0NBQUE7SUFDQSx1QkFBQTtDQUNBO0FBRUE7SUFDQSwrQkFBQTtJQUNBLFFBQUE7SUFDQSxZQUFBO0NBQ0E7QUFFQTtJQUNBLFdBQUE7SUFDQSxTQUFBO0NBQ0E7QUFFQTtJQUNBLGFBQUE7SUFDQSxXQUFBO0NBQ0E7QUFFQTtJQUNBLGdCQUFBO0lBQ0EsV0FBQTtDQUNBO0FBRUE7SUFDQSxnQkFBQTtJQUNBLGFBQUE7SUFDQSwyQkFBQTtJQUNBLFdBQUE7SUFDQSwwQkFBQTtJQUNBLHVCQUFBO0lBQ0Esc0JBQUE7SUFDQSxxQkFBQTtJQUNBLGtCQUFBO0NBQ0E7QUFFQTtJQUNBLG1CQUFBO0lBQ0EsWUFBQTtJQUNBLGFBQUE7SUFDQSxVQUFBO0lBQ0EsU0FBQTtJQUNBLHMzQkFBQTtJQUNBLGtDQUFBO0lBQ0EscUJBQUE7SUFDQSw2QkFBQTtJQUNBLCtCQUFBO0lBQ0EsdUJBQUE7SUFDQSxrQkFBQTtDQUNBO0FBRUE7SUFDQSxVQUFBO0lBQ0EsUUFBQTtJQUNBLGcrQ0FBQTtJQUNBLGlDQUFBO0lBQ0Esa0JBQUE7SUFDQSw2QkFBQTtJQUNBLCtCQUFBO0lBQ0Esa0JBQUE7SUFDQSxZQUFBO0NBQ0FcIixcImZpbGVcIjpcIkdyaWRJdGVtLnZ1ZVwiLFwic291cmNlc0NvbnRlbnRcIjpbXCI8dGVtcGxhdGU+XFxyXFxuICAgIDxkaXYgcmVmPVxcXCJpdGVtXFxcIlxcclxcbiAgICAgICAgIGNsYXNzPVxcXCJ2dWUtZ3JpZC1pdGVtXFxcIlxcclxcbiAgICAgICAgIDpjbGFzcz1cXFwieyAndnVlLXJlc2l6YWJsZScgOiByZXNpemFibGUsICdyZXNpemluZycgOiBpc1Jlc2l6aW5nLCAndnVlLWRyYWdnYWJsZS1kcmFnZ2luZycgOiBpc0RyYWdnaW5nLCAnY3NzVHJhbnNmb3JtcycgOiB1c2VDc3NUcmFuc2Zvcm1zLCAncmVuZGVyLXJ0bCcgOiByZW5kZXJSdGwgfVxcXCJcXHJcXG4gICAgICAgICA6c3R5bGU9XFxcInN0eWxlXFxcIlxcclxcbiAgICA+XFxyXFxuICAgICAgICA8c2xvdD48L3Nsb3Q+XFxyXFxuICAgICAgICA8c3BhbiB2LWlmPVxcXCJyZXNpemFibGVcXFwiIHJlZj1cXFwiaGFuZGxlXFxcIiA6Y2xhc3M9XFxcInJlc2l6YWJsZUhhbmRsZUNsYXNzXFxcIj48L3NwYW4+XFxyXFxuICAgICAgICA8IS0tPHNwYW4gdi1pZj1cXFwiZHJhZ2dhYmxlXFxcIiByZWY9XFxcImRyYWdIYW5kbGVcXFwiIGNsYXNzPVxcXCJ2dWUtZHJhZ2dhYmxlLWhhbmRsZVxcXCI+PC9zcGFuPi0tPlxcclxcbiAgICA8L2Rpdj5cXHJcXG48L3RlbXBsYXRlPlxcclxcbjxzdHlsZT5cXHJcXG4gICAgLnZ1ZS1ncmlkLWl0ZW0ge1xcclxcbiAgICAgICAgdHJhbnNpdGlvbjogYWxsIDIwMG1zIGVhc2U7XFxyXFxuICAgICAgICB0cmFuc2l0aW9uLXByb3BlcnR5OiBsZWZ0LCB0b3AsIHJpZ2h0O1xcclxcbiAgICAgICAgLyogYWRkIHJpZ2h0IGZvciBydGwgKi9cXHJcXG4gICAgfVxcclxcblxcclxcbiAgICAudnVlLWdyaWQtaXRlbS5jc3NUcmFuc2Zvcm1zIHtcXHJcXG4gICAgICAgIHRyYW5zaXRpb24tcHJvcGVydHk6IHRyYW5zZm9ybTtcXHJcXG4gICAgICAgIGxlZnQ6IDA7XFxyXFxuICAgICAgICByaWdodDogYXV0bztcXHJcXG4gICAgfVxcclxcblxcclxcbiAgICAudnVlLWdyaWQtaXRlbS5jc3NUcmFuc2Zvcm1zLnJlbmRlci1ydGwge1xcclxcbiAgICAgICAgbGVmdDogYXV0bztcXHJcXG4gICAgICAgIHJpZ2h0OiAwO1xcclxcbiAgICB9XFxyXFxuXFxyXFxuICAgIC52dWUtZ3JpZC1pdGVtLnJlc2l6aW5nIHtcXHJcXG4gICAgICAgIG9wYWNpdHk6IDAuNjtcXHJcXG4gICAgICAgIHotaW5kZXg6IDM7XFxyXFxuICAgIH1cXHJcXG5cXHJcXG4gICAgLnZ1ZS1ncmlkLWl0ZW0udnVlLWRyYWdnYWJsZS1kcmFnZ2luZyB7XFxyXFxuICAgICAgICB0cmFuc2l0aW9uOm5vbmU7XFxyXFxuICAgICAgICB6LWluZGV4OiAzO1xcclxcbiAgICB9XFxyXFxuXFxyXFxuICAgIC52dWUtZ3JpZC1pdGVtLnZ1ZS1ncmlkLXBsYWNlaG9sZGVyIHtcXHJcXG4gICAgICAgIGJhY2tncm91bmQ6IHJlZDtcXHJcXG4gICAgICAgIG9wYWNpdHk6IDAuMjtcXHJcXG4gICAgICAgIHRyYW5zaXRpb24tZHVyYXRpb246IDEwMG1zO1xcclxcbiAgICAgICAgei1pbmRleDogMjtcXHJcXG4gICAgICAgIC13ZWJraXQtdXNlci1zZWxlY3Q6IG5vbmU7XFxyXFxuICAgICAgICAtbW96LXVzZXItc2VsZWN0OiBub25lO1xcclxcbiAgICAgICAgLW1zLXVzZXItc2VsZWN0OiBub25lO1xcclxcbiAgICAgICAgLW8tdXNlci1zZWxlY3Q6IG5vbmU7XFxyXFxuICAgICAgICB1c2VyLXNlbGVjdDogbm9uZTtcXHJcXG4gICAgfVxcclxcblxcclxcbiAgICAudnVlLWdyaWQtaXRlbSA+IC52dWUtcmVzaXphYmxlLWhhbmRsZSB7XFxyXFxuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XFxyXFxuICAgICAgICB3aWR0aDogMjBweDtcXHJcXG4gICAgICAgIGhlaWdodDogMjBweDtcXHJcXG4gICAgICAgIGJvdHRvbTogMDtcXHJcXG4gICAgICAgIHJpZ2h0OiAwO1xcclxcbiAgICAgICAgYmFja2dyb3VuZDogdXJsKCdkYXRhOmltYWdlL3N2Zyt4bWw7YmFzZTY0LFBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQnpkR0Z1WkdGc2IyNWxQU0p1YnlJL1BnMDhJUzB0SUVkbGJtVnlZWFJ2Y2pvZ1FXUnZZbVVnUm1seVpYZHZjbXR6SUVOVE5pd2dSWGh3YjNKMElGTldSeUJGZUhSbGJuTnBiMjRnWW5rZ1FXRnliMjRnUW1WaGJHd2dLR2gwZEhBNkx5OW1hWEpsZDI5eWEzTXVZV0psWVd4c0xtTnZiU2tnTGlCV1pYSnphVzl1T2lBd0xqWXVNU0FnTFMwK0RUd2hSRTlEVkZsUVJTQnpkbWNnVUZWQ1RFbERJQ0l0THk5WE0wTXZMMFJVUkNCVFZrY2dNUzR4THk5RlRpSWdJbWgwZEhBNkx5OTNkM2N1ZHpNdWIzSm5MMGR5WVhCb2FXTnpMMU5XUnk4eExqRXZSRlJFTDNOMlp6RXhMbVIwWkNJK0RUeHpkbWNnYVdROUlsVnVkR2wwYkdWa0xWQmhaMlVsTWpBeElpQjJhV1YzUW05NFBTSXdJREFnTmlBMklpQnpkSGxzWlQwaVltRmphMmR5YjNWdVpDMWpiMnh2Y2pvalptWm1abVptTURBaUlIWmxjbk5wYjI0OUlqRXVNU0lOQ1hodGJHNXpQU0pvZEhSd09pOHZkM2QzTG5jekxtOXlaeTh5TURBd0wzTjJaeUlnZUcxc2JuTTZlR3hwYm1zOUltaDBkSEE2THk5M2QzY3Vkek11YjNKbkx6RTVPVGt2ZUd4cGJtc2lJSGh0YkRwemNHRmpaVDBpY0hKbGMyVnlkbVVpRFFsNFBTSXdjSGdpSUhrOUlqQndlQ0lnZDJsa2RHZzlJalp3ZUNJZ2FHVnBaMmgwUFNJMmNIZ2lEVDROQ1R4bklHOXdZV05wZEhrOUlqQXVNekF5SWo0TkNRazhjR0YwYUNCa1BTSk5JRFlnTmlCTUlEQWdOaUJNSURBZ05DNHlJRXdnTkNBMExqSWdUQ0EwTGpJZ05DNHlJRXdnTkM0eUlEQWdUQ0EySURBZ1RDQTJJRFlnVENBMklEWWdXaUlnWm1sc2JEMGlJekF3TURBd01DSXZQZzBKUEM5blBnMDhMM04yWno0PScpO1xcclxcbiAgICAgICAgYmFja2dyb3VuZC1wb3NpdGlvbjogYm90dG9tIHJpZ2h0O1xcclxcbiAgICAgICAgcGFkZGluZzogMCAzcHggM3B4IDA7XFxyXFxuICAgICAgICBiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0O1xcclxcbiAgICAgICAgYmFja2dyb3VuZC1vcmlnaW46IGNvbnRlbnQtYm94O1xcclxcbiAgICAgICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcXHJcXG4gICAgICAgIGN1cnNvcjogc2UtcmVzaXplO1xcclxcbiAgICB9XFxyXFxuXFxyXFxuICAgIC52dWUtZ3JpZC1pdGVtID4gLnZ1ZS1ydGwtcmVzaXphYmxlLWhhbmRsZSB7XFxyXFxuICAgICAgICBib3R0b206IDA7XFxyXFxuICAgICAgICBsZWZ0OiAwO1xcclxcbiAgICAgICAgYmFja2dyb3VuZDogdXJsKGRhdGE6aW1hZ2Uvc3ZnK3htbDtiYXNlNjQsUEhOMlp5QjNhV1IwYUQwaU1UQXVNREF3TURBd01EQXdNREF3TURBeUlpQm9aV2xuYUhROUlqRXdMakF3TURBd01EQXdNREF3TURBd01pSWdlRzFzYm5NOUltaDBkSEE2THk5M2QzY3Vkek11YjNKbkx6SXdNREF2YzNabklqNEtJRHdoTFMwZ1EzSmxZWFJsWkNCM2FYUm9JRTFsZEdodlpDQkVjbUYzSUMwZ2FIUjBjRG92TDJkcGRHaDFZaTVqYjIwdlpIVnZjR2w0Wld3dlRXVjBhRzlrTFVSeVlYY3ZJQzB0UGdvZ1BHYytDaUFnUEhScGRHeGxQbUpoWTJ0bmNtOTFibVE4TDNScGRHeGxQZ29nSUR4eVpXTjBJR1pwYkd3OUltNXZibVVpSUdsa1BTSmpZVzUyWVhOZlltRmphMmR5YjNWdVpDSWdhR1ZwWjJoMFBTSXhNaUlnZDJsa2RHZzlJakV5SWlCNVBTSXRNU0lnZUQwaUxURWlMejRLSUNBOFp5QmthWE53YkdGNVBTSnViMjVsSWlCdmRtVnlabXh2ZHowaWRtbHphV0pzWlNJZ2VUMGlNQ0lnZUQwaU1DSWdhR1ZwWjJoMFBTSXhNREFsSWlCM2FXUjBhRDBpTVRBd0pTSWdhV1E5SW1OaGJuWmhjMGR5YVdRaVBnb2dJQ0E4Y21WamRDQm1hV3hzUFNKMWNtd29JMmR5YVdSd1lYUjBaWEp1S1NJZ2MzUnliMnRsTFhkcFpIUm9QU0l3SWlCNVBTSXdJaUI0UFNJd0lpQm9aV2xuYUhROUlqRXdNQ1VpSUhkcFpIUm9QU0l4TURBbElpOCtDaUFnUEM5blBnb2dQQzluUGdvZ1BHYytDaUFnUEhScGRHeGxQa3hoZVdWeUlERThMM1JwZEd4bFBnb2dJRHhzYVc1bElHTmhiblpoY3owaUkyWm1abVptWmlJZ1kyRnVkbUZ6TFc5d1lXTnBkSGs5SWpFaUlITjBjbTlyWlMxc2FXNWxZMkZ3UFNKMWJtUmxabWx1WldRaUlITjBjbTlyWlMxc2FXNWxhbTlwYmowaWRXNWtaV1pwYm1Wa0lpQnBaRDBpYzNablh6RWlJSGt5UFNJdE56QXVNVGM0TkRBM0lpQjRNajBpTVRJMExqUTJOREUzTlNJZ2VURTlJaTB6T0M0ek9USTNNemNpSUhneFBTSXhORFF1T0RJeE1qZzVJaUJ6ZEhKdmEyVXRkMmxrZEdnOUlqRXVOU0lnYzNSeWIydGxQU0lqTURBd0lpQm1hV3hzUFNKdWIyNWxJaTgrQ2lBZ1BHeHBibVVnYzNSeWIydGxQU0lqTmpZMk5qWTJJaUJ6ZEhKdmEyVXRiR2x1WldOaGNEMGlkVzVrWldacGJtVmtJaUJ6ZEhKdmEyVXRiR2x1WldwdmFXNDlJblZ1WkdWbWFXNWxaQ0lnYVdROUluTjJaMTgxSWlCNU1qMGlPUzR4TURZNU5UY2lJSGd5UFNJd0xqazBOekkwTnlJZ2VURTlJaTB3TGpBeE9ERXlPQ0lnZURFOUlqQXVPVFEzTWpRM0lpQnpkSEp2YTJVdGQybGtkR2c5SWpJaUlHWnBiR3c5SW01dmJtVWlMejRLSUNBOGJHbHVaU0J6ZEhKdmEyVXRiR2x1WldOaGNEMGlkVzVrWldacGJtVmtJaUJ6ZEhKdmEyVXRiR2x1WldwdmFXNDlJblZ1WkdWbWFXNWxaQ0lnYVdROUluTjJaMTgzSWlCNU1qMGlPU0lnZURJOUlqRXdMakEzTXpVeU9TSWdlVEU5SWpraUlIZ3hQU0l0TUM0Mk5UVTJOQ0lnYzNSeWIydGxMWGRwWkhSb1BTSXlJaUJ6ZEhKdmEyVTlJaU0yTmpZMk5qWWlJR1pwYkd3OUltNXZibVVpTHo0S0lEd3ZaejRLUEM5emRtYyspO1xcclxcbiAgICAgICAgYmFja2dyb3VuZC1wb3NpdGlvbjogYm90dG9tIGxlZnQ7XFxyXFxuICAgICAgICBwYWRkaW5nLWxlZnQ6IDNweDtcXHJcXG4gICAgICAgIGJhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7XFxyXFxuICAgICAgICBiYWNrZ3JvdW5kLW9yaWdpbjogY29udGVudC1ib3g7XFxyXFxuICAgICAgICBjdXJzb3I6IHN3LXJlc2l6ZTtcXHJcXG4gICAgICAgIHJpZ2h0OiBhdXRvO1xcclxcbiAgICB9XFxyXFxuPC9zdHlsZT5cXHJcXG48c2NyaXB0PlxcclxcbiAgICBpbXBvcnQge3NldFRvcExlZnQsIHNldFRvcFJpZ2h0LCBzZXRUcmFuc2Zvcm1SdGwsIHNldFRyYW5zZm9ybSwgY3JlYXRlTWFya3VwLCBnZXRMYXlvdXRJdGVtfSBmcm9tICcuL3V0aWxzJztcXHJcXG4gICAgaW1wb3J0IHtnZXRDb250cm9sUG9zaXRpb24sIG9mZnNldFhZRnJvbVBhcmVudE9mLCBjcmVhdGVDb3JlRGF0YX0gZnJvbSAnLi9kcmFnZ2FibGVVdGlscyc7XFxyXFxuICAgIC8vICAgIHZhciBldmVudEJ1cyA9IHJlcXVpcmUoJy4vZXZlbnRCdXMnKTtcXHJcXG5cXHJcXG4gICAgdmFyIGludGVyYWN0ID0gcmVxdWlyZShcXFwiaW50ZXJhY3Rqc1xcXCIpO1xcclxcblxcclxcbiAgICBleHBvcnQgZGVmYXVsdCB7XFxyXFxuICAgICAgICBuYW1lOiBcXFwiR3JpZEl0ZW1cXFwiLFxcclxcbiAgICAgICAgcHJvcHM6IHtcXHJcXG4gICAgICAgICAgICAvKmNvbHM6IHtcXHJcXG4gICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxcclxcbiAgICAgICAgICAgICByZXF1aXJlZDogdHJ1ZVxcclxcbiAgICAgICAgICAgICB9LCovXFxyXFxuICAgICAgICAgICAgLypjb250YWluZXJXaWR0aDoge1xcclxcbiAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXFxyXFxuICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlXFxyXFxuXFxyXFxuICAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgIHJvd0hlaWdodDoge1xcclxcbiAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXFxyXFxuICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlXFxyXFxuICAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgIG1hcmdpbjoge1xcclxcbiAgICAgICAgICAgICB0eXBlOiBBcnJheSxcXHJcXG4gICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcXHJcXG4gICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICAgbWF4Um93czoge1xcclxcbiAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXFxyXFxuICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlXFxyXFxuICAgICAgICAgICAgIH0sKi9cXHJcXG4gICAgICAgICAgICBpc0RyYWdnYWJsZToge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBCb29sZWFuLFxcclxcbiAgICAgICAgICAgICAgICByZXF1aXJlZDogZmFsc2UsXFxyXFxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IG51bGxcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIGlzUmVzaXphYmxlOiB7XFxyXFxuICAgICAgICAgICAgICAgIHR5cGU6IEJvb2xlYW4sXFxyXFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcXHJcXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogbnVsbFxcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgLyp1c2VDc3NUcmFuc2Zvcm1zOiB7XFxyXFxuICAgICAgICAgICAgIHR5cGU6IEJvb2xlYW4sXFxyXFxuICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlXFxyXFxuICAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgIHN0YXRpYzoge1xcclxcbiAgICAgICAgICAgICB0eXBlOiBCb29sZWFuLFxcclxcbiAgICAgICAgICAgICByZXF1aXJlZDogZmFsc2UsXFxyXFxuICAgICAgICAgICAgIGRlZmF1bHQ6IGZhbHNlXFxyXFxuICAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgICovXFxyXFxuICAgICAgICAgICAgbWluSDoge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXFxyXFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcXHJcXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogMVxcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgbWluVzoge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXFxyXFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcXHJcXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogMVxcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgbWF4SDoge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXFxyXFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcXHJcXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogSW5maW5pdHlcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIG1heFc6IHtcXHJcXG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxcclxcbiAgICAgICAgICAgICAgICByZXF1aXJlZDogZmFsc2UsXFxyXFxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IEluZmluaXR5XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICB4OiB7XFxyXFxuICAgICAgICAgICAgICAgIHR5cGU6IE51bWJlcixcXHJcXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIHk6IHtcXHJcXG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxcclxcbiAgICAgICAgICAgICAgICByZXF1aXJlZDogdHJ1ZVxcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgdzoge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXFxyXFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlXFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICBoOiB7XFxyXFxuICAgICAgICAgICAgICAgIHR5cGU6IE51bWJlcixcXHJcXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIGk6IHtcXHJcXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIGRyYWdJZ25vcmVGcm9tOiB7XFxyXFxuICAgICAgICAgICAgICAgIHR5cGU6IFN0cmluZyxcXHJcXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IGZhbHNlLFxcclxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiAnYSwgYnV0dG9uJ1xcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgZHJhZ0FsbG93RnJvbToge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBTdHJpbmcsXFxyXFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcXHJcXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogbnVsbFxcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgcmVzaXplSWdub3JlRnJvbToge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBTdHJpbmcsXFxyXFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcXHJcXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogJ2EsIGJ1dHRvbidcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgfSxcXHJcXG4gICAgICAgIGluamVjdDogW1xcXCJldmVudEJ1c1xcXCJdLFxcclxcbiAgICAgICAgZGF0YTogZnVuY3Rpb24gKCkge1xcclxcbiAgICAgICAgICAgIHJldHVybiB7XFxyXFxuICAgICAgICAgICAgICAgIGNvbHM6IDEsXFxyXFxuICAgICAgICAgICAgICAgIGNvbnRhaW5lcldpZHRoOiAxMDAsXFxyXFxuICAgICAgICAgICAgICAgIHJvd0hlaWdodDogMzAsXFxyXFxuICAgICAgICAgICAgICAgIG1hcmdpbjogWzEwLCAxMF0sXFxyXFxuICAgICAgICAgICAgICAgIG1heFJvd3M6IEluZmluaXR5LFxcclxcbiAgICAgICAgICAgICAgICBkcmFnZ2FibGU6IG51bGwsXFxyXFxuICAgICAgICAgICAgICAgIHJlc2l6YWJsZTogbnVsbCxcXHJcXG4gICAgICAgICAgICAgICAgdXNlQ3NzVHJhbnNmb3JtczogdHJ1ZSxcXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgaXNEcmFnZ2luZzogZmFsc2UsXFxyXFxuICAgICAgICAgICAgICAgIGRyYWdnaW5nOiBudWxsLFxcclxcbiAgICAgICAgICAgICAgICBpc1Jlc2l6aW5nOiBmYWxzZSxcXHJcXG4gICAgICAgICAgICAgICAgcmVzaXppbmc6IG51bGwsXFxyXFxuICAgICAgICAgICAgICAgIGxhc3RYOiBOYU4sXFxyXFxuICAgICAgICAgICAgICAgIGxhc3RZOiBOYU4sXFxyXFxuICAgICAgICAgICAgICAgIGxhc3RXOiBOYU4sXFxyXFxuICAgICAgICAgICAgICAgIGxhc3RIOiBOYU4sXFxyXFxuICAgICAgICAgICAgICAgIHN0eWxlOiB7fSxcXHJcXG4gICAgICAgICAgICAgICAgcnRsOiBmYWxzZSxcXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgZHJhZ0V2ZW50U2V0OiBmYWxzZSxcXHJcXG4gICAgICAgICAgICAgICAgcmVzaXplRXZlbnRTZXQ6IGZhbHNlLFxcclxcblxcclxcbiAgICAgICAgICAgICAgICBwcmV2aW91c1c6IG51bGwsXFxyXFxuICAgICAgICAgICAgICAgIHByZXZpb3VzSDogbnVsbCxcXHJcXG4gICAgICAgICAgICAgICAgcHJldmlvdXNYOiBudWxsLFxcclxcbiAgICAgICAgICAgICAgICBwcmV2aW91c1k6IG51bGwsXFxyXFxuICAgICAgICAgICAgfVxcclxcbiAgICAgICAgfSxcXHJcXG4gICAgICAgIGNyZWF0ZWQgKCkge1xcclxcbiAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcXHJcXG5cXHJcXG4gICAgICAgICAgICAvLyBBY2Nlc3NpYmxlIHJlZmVybmNlcyBvZiBmdW5jdGlvbnMgZm9yIHJlbW92aW5nIGluIGJlZm9yZURlc3Ryb3lcXHJcXG4gICAgICAgICAgICBzZWxmLnVwZGF0ZVdpZHRoSGFuZGxlciA9IGZ1bmN0aW9uICh3aWR0aCkge1xcclxcbiAgICAgICAgICAgICAgICBzZWxmLnVwZGF0ZVdpZHRoKHdpZHRoKTtcXHJcXG4gICAgICAgICAgICB9O1xcclxcblxcclxcbiAgICAgICAgICAgIHNlbGYuY29tcGFjdEhhbmRsZXIgPSBmdW5jdGlvbiAobGF5b3V0KSB7XFxyXFxuICAgICAgICAgICAgICAgIHNlbGYuY29tcGFjdChsYXlvdXQpO1xcclxcbiAgICAgICAgICAgIH07XFxyXFxuXFxyXFxuICAgICAgICAgICAgc2VsZi5zZXREcmFnZ2FibGVIYW5kbGVyID0gZnVuY3Rpb24gKGlzRHJhZ2dhYmxlKSB7XFxyXFxuICAgICAgICAgICAgICAgIGlmIChzZWxmLmlzRHJhZ2dhYmxlID09PSBudWxsKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICBzZWxmLmRyYWdnYWJsZSA9IGlzRHJhZ2dhYmxlO1xcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgfTtcXHJcXG5cXHJcXG4gICAgICAgICAgICBzZWxmLnNldFJlc2l6YWJsZUhhbmRsZXIgPSBmdW5jdGlvbiAoaXNSZXNpemFibGUpIHtcXHJcXG4gICAgICAgICAgICAgICAgaWYgKHNlbGYuaXNSZXNpemFibGUgPT09IG51bGwpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHNlbGYucmVzaXphYmxlID0gaXNSZXNpemFibGU7XFxyXFxuICAgICAgICAgICAgICAgIH1cXHJcXG4gICAgICAgICAgICB9O1xcclxcblxcclxcbiAgICAgICAgICAgIHNlbGYuc2V0Um93SGVpZ2h0SGFuZGxlciA9IGZ1bmN0aW9uIChyb3dIZWlnaHQpIHtcXHJcXG4gICAgICAgICAgICAgICAgc2VsZi5yb3dIZWlnaHQgPSByb3dIZWlnaHQ7XFxyXFxuICAgICAgICAgICAgfTtcXHJcXG5cXHJcXG4gICAgICAgICAgICBzZWxmLmRpcmVjdGlvbmNoYW5nZUhhbmRsZXIgPSAoZGlyZWN0aW9uKSA9PiB7XFxyXFxuICAgICAgICAgICAgICAgIHZhciBkaXJlY3Rpb24gPSAoZG9jdW1lbnQuZGlyICE9PSB1bmRlZmluZWQpID9cXHJcXG4gICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmRpciA6XFxyXFxuICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcXFwiaHRtbFxcXCIpWzBdLmdldEF0dHJpYnV0ZShcXFwiZGlyXFxcIik7XFxyXFxuICAgICAgICAgICAgICAgIHRoaXMucnRsID0gKGRpcmVjdGlvbiA9PT0gXFxcInJ0bFxcXCIpO1xcclxcbiAgICAgICAgICAgICAgICB0aGlzLmNvbXBhY3QoKTtcXHJcXG4gICAgICAgICAgICB9O1xcclxcblxcclxcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9uKCd1cGRhdGVXaWR0aCcsIHNlbGYudXBkYXRlV2lkdGhIYW5kbGVyKTtcXHJcXG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRvbignY29tcGFjdCcsIHNlbGYuY29tcGFjdEhhbmRsZXIpO1xcclxcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9uKCdzZXREcmFnZ2FibGUnLCBzZWxmLnNldERyYWdnYWJsZUhhbmRsZXIpO1xcclxcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9uKCdzZXRSZXNpemFibGUnLCBzZWxmLnNldFJlc2l6YWJsZUhhbmRsZXIpO1xcclxcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9uKCdzZXRSb3dIZWlnaHQnLCBzZWxmLnNldFJvd0hlaWdodEhhbmRsZXIpO1xcclxcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9uKCdkaXJlY3Rpb25jaGFuZ2UnLCBzZWxmLmRpcmVjdGlvbmNoYW5nZUhhbmRsZXIpO1xcclxcblxcclxcbiAgICAgICAgICAgIC8qdGhpcy5ldmVudEJ1cy4kb24oJ3NldENvbE51bScsIGZ1bmN0aW9uKGNvbE51bSkge1xcclxcbiAgICAgICAgICAgICBzZWxmLmNvbHMgPSBjb2xOdW07XFxyXFxuICAgICAgICAgICAgIH0pOyovXFxyXFxuICAgICAgICAgICAgdmFyIGRpcmVjdGlvbiA9IChkb2N1bWVudC5kaXIgIT09IHVuZGVmaW5lZCkgP1xcclxcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5kaXIgOlxcclxcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcXFwiaHRtbFxcXCIpWzBdLmdldEF0dHJpYnV0ZShcXFwiZGlyXFxcIik7XFxyXFxuICAgICAgICAgICAgdGhpcy5ydGwgPSAoZGlyZWN0aW9uID09PSBcXFwicnRsXFxcIik7XFxyXFxuICAgICAgICB9LFxcclxcbiAgICAgICAgYmVmb3JlRGVzdHJveTogZnVuY3Rpb24oKXtcXHJcXG4gICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XFxyXFxuICAgICAgICAgICAgLy9SZW1vdmUgbGlzdGVuZXJzXFxyXFxuICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kb2ZmKCd1cGRhdGVXaWR0aCcsIHNlbGYudXBkYXRlV2lkdGhIYW5kbGVyKTtcXHJcXG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRvZmYoJ2NvbXBhY3QnLCBzZWxmLmNvbXBhY3RIYW5kbGVyKTtcXHJcXG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRvZmYoJ3NldERyYWdnYWJsZScsIHNlbGYuc2V0RHJhZ2dhYmxlSGFuZGxlcik7XFxyXFxuICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kb2ZmKCdzZXRSZXNpemFibGUnLCBzZWxmLnNldFJlc2l6YWJsZUhhbmRsZXIpO1xcclxcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9mZignc2V0Um93SGVpZ2h0Jywgc2VsZi5zZXRSb3dIZWlnaHRIYW5kbGVyKTtcXHJcXG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRvZmYoJ2RpcmVjdGlvbmNoYW5nZScsIHNlbGYuZGlyZWN0aW9uY2hhbmdlSGFuZGxlcik7XFxyXFxuICAgICAgICB9LFxcclxcbiAgICAgICAgbW91bnRlZDogZnVuY3Rpb24gKCkge1xcclxcbiAgICAgICAgICAgIHRoaXMuY29scyA9IHRoaXMuJHBhcmVudC5jb2xOdW07XFxyXFxuICAgICAgICAgICAgdGhpcy5yb3dIZWlnaHQgPSB0aGlzLiRwYXJlbnQucm93SGVpZ2h0O1xcclxcbiAgICAgICAgICAgIHRoaXMuY29udGFpbmVyV2lkdGggPSB0aGlzLiRwYXJlbnQud2lkdGggIT09IG51bGwgPyB0aGlzLiRwYXJlbnQud2lkdGggOiAxMDA7XFxyXFxuICAgICAgICAgICAgdGhpcy5tYXJnaW4gPSB0aGlzLiRwYXJlbnQubWFyZ2luICE9PSB1bmRlZmluZWQgPyB0aGlzLiRwYXJlbnQubWFyZ2luIDogWzEwLCAxMF07XFxyXFxuICAgICAgICAgICAgdGhpcy5tYXhSb3dzID0gdGhpcy4kcGFyZW50Lm1heFJvd3M7XFxyXFxuICAgICAgICAgICAgaWYgKHRoaXMuaXNEcmFnZ2FibGUgPT09IG51bGwpIHtcXHJcXG4gICAgICAgICAgICAgICAgdGhpcy5kcmFnZ2FibGUgPSB0aGlzLiRwYXJlbnQuaXNEcmFnZ2FibGU7XFxyXFxuICAgICAgICAgICAgfSBlbHNlIHtcXHJcXG4gICAgICAgICAgICAgICAgdGhpcy5kcmFnZ2FibGUgPSB0aGlzLmlzRHJhZ2dhYmxlO1xcclxcbiAgICAgICAgICAgIH1cXHJcXG4gICAgICAgICAgICBpZiAodGhpcy5pc1Jlc2l6YWJsZSA9PT0gbnVsbCkge1xcclxcbiAgICAgICAgICAgICAgICB0aGlzLnJlc2l6YWJsZSA9IHRoaXMuJHBhcmVudC5pc1Jlc2l6YWJsZTtcXHJcXG4gICAgICAgICAgICB9IGVsc2Uge1xcclxcbiAgICAgICAgICAgICAgICB0aGlzLnJlc2l6YWJsZSA9IHRoaXMuaXNSZXNpemFibGU7XFxyXFxuICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgIHRoaXMudXNlQ3NzVHJhbnNmb3JtcyA9IHRoaXMuJHBhcmVudC51c2VDc3NUcmFuc2Zvcm1zO1xcclxcbiAgICAgICAgICAgIHRoaXMuY3JlYXRlU3R5bGUoKTtcXHJcXG4gICAgICAgIH0sXFxyXFxuICAgICAgICB3YXRjaDoge1xcclxcbiAgICAgICAgICAgIGlzRHJhZ2dhYmxlOiBmdW5jdGlvbiAoKSB7XFxyXFxuICAgICAgICAgICAgICAgIHRoaXMuZHJhZ2dhYmxlID0gdGhpcy5pc0RyYWdnYWJsZTtcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIGRyYWdnYWJsZTogZnVuY3Rpb24gKCkge1xcclxcbiAgICAgICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XFxyXFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmludGVyYWN0T2JqID09PSBudWxsIHx8IHRoaXMuaW50ZXJhY3RPYmogPT09IHVuZGVmaW5lZCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnRlcmFjdE9iaiA9IGludGVyYWN0KHRoaXMuJHJlZnMuaXRlbSk7XFxyXFxuICAgICAgICAgICAgICAgIH1cXHJcXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZHJhZ2dhYmxlKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICB2YXIgb3B0cyA9IHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBpZ25vcmVGcm9tOiB0aGlzLmRyYWdJZ25vcmVGcm9tLFxcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIGFsbG93RnJvbTogdGhpcy5kcmFnQWxsb3dGcm9tXFxyXFxuICAgICAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmludGVyYWN0T2JqLmRyYWdnYWJsZShvcHRzKTtcXHJcXG4gICAgICAgICAgICAgICAgICAgIC8qdGhpcy5pbnRlcmFjdE9iai5kcmFnZ2FibGUoe2FsbG93RnJvbTogJy52dWUtZHJhZ2dhYmxlLWhhbmRsZSd9KTsqL1xcclxcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLmRyYWdFdmVudFNldCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZHJhZ0V2ZW50U2V0ID0gdHJ1ZTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmludGVyYWN0T2JqLm9uKCdkcmFnc3RhcnQgZHJhZ21vdmUgZHJhZ2VuZCcsIGZ1bmN0aW9uIChldmVudCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmhhbmRsZURyYWcoZXZlbnQpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xcclxcbiAgICAgICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xcclxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnRlcmFjdE9iai5kcmFnZ2FibGUoe1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIGVuYWJsZWQ6IGZhbHNlXFxyXFxuICAgICAgICAgICAgICAgICAgICB9KTtcXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgaXNSZXNpemFibGU6IGZ1bmN0aW9uICgpIHtcXHJcXG4gICAgICAgICAgICAgICAgdGhpcy5yZXNpemFibGUgPSB0aGlzLmlzUmVzaXphYmxlO1xcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgcmVzaXphYmxlOiBmdW5jdGlvbiAoKSB7XFxyXFxuICAgICAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcXHJcXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaW50ZXJhY3RPYmogPT09IG51bGwgfHwgdGhpcy5pbnRlcmFjdE9iaiA9PT0gdW5kZWZpbmVkKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmludGVyYWN0T2JqID0gaW50ZXJhY3QodGhpcy4kcmVmcy5pdGVtKTtcXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5yZXNpemFibGUpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHZhciBvcHRzID0ge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHByZXNlcnZlQXNwZWN0UmF0aW86IGZhbHNlLFxcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIGVkZ2VzOiB7bGVmdDogZmFsc2UsIHJpZ2h0OiB0cnVlLCBib3R0b206IHRydWUsIHRvcDogZmFsc2V9LFxcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIGlnbm9yZUZyb206IHRoaXMucmVzaXplSWdub3JlRnJvbVxcclxcbiAgICAgICAgICAgICAgICAgICAgfTtcXHJcXG4gICAgICAgICAgICAgICAgICAgIFxcclxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnRlcmFjdE9iai5yZXNpemFibGUob3B0cyk7XFxyXFxuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMucmVzaXplRXZlbnRTZXQpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc2l6ZUV2ZW50U2V0ID0gdHJ1ZTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmludGVyYWN0T2JqXFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5vbigncmVzaXplc3RhcnQgcmVzaXplbW92ZSByZXNpemVlbmQnLCBmdW5jdGlvbiAoZXZlbnQpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuaGFuZGxlUmVzaXplKGV2ZW50KTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XFxyXFxuICAgICAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmludGVyYWN0T2JqLnJlc2l6YWJsZSh7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgZW5hYmxlZDogZmFsc2VcXHJcXG4gICAgICAgICAgICAgICAgICAgIH0pO1xcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICByb3dIZWlnaHQ6IGZ1bmN0aW9uICgpIHtcXHJcXG4gICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVTdHlsZSgpO1xcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgY29sczogZnVuY3Rpb24gKCkge1xcclxcbiAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVN0eWxlKCk7XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICBjb250YWluZXJXaWR0aDogZnVuY3Rpb24gKCkge1xcclxcbiAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVN0eWxlKCk7XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICB4OiBmdW5jdGlvbiAoKSB7XFxyXFxuICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRlU3R5bGUoKTtcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIHk6IGZ1bmN0aW9uICgpIHtcXHJcXG4gICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVTdHlsZSgpO1xcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgaDogZnVuY3Rpb24gKCkge1xcclxcbiAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVN0eWxlKCk7XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICB3OiBmdW5jdGlvbiAoKSB7XFxyXFxuICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRlU3R5bGUoKTtcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIHJlbmRlclJ0bDogZnVuY3Rpb24gKCkge1xcclxcbiAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVN0eWxlKCk7XFxyXFxuICAgICAgICAgICAgfVxcclxcbiAgICAgICAgfSxcXHJcXG4gICAgICAgIGNvbXB1dGVkOiB7XFxyXFxuICAgICAgICAgICAgcmVuZGVyUnRsKCkge1xcclxcbiAgICAgICAgICAgICAgICByZXR1cm4gKHRoaXMuJHBhcmVudC5pc01pcnJvcmVkKSA/ICF0aGlzLnJ0bCA6IHRoaXMucnRsO1xcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgcmVzaXphYmxlSGFuZGxlQ2xhc3MoKSB7XFxyXFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnJlbmRlclJ0bCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICd2dWUtcmVzaXphYmxlLWhhbmRsZSB2dWUtcnRsLXJlc2l6YWJsZS1oYW5kbGUnO1xcclxcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xcclxcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICd2dWUtcmVzaXphYmxlLWhhbmRsZSc7XFxyXFxuICAgICAgICAgICAgICAgIH1cXHJcXG4gICAgICAgICAgICB9XFxyXFxuICAgICAgICB9LFxcclxcbiAgICAgICAgbWV0aG9kczoge1xcclxcbiAgICAgICAgICAgIGNyZWF0ZVN0eWxlOiBmdW5jdGlvbiAoKSB7XFxyXFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnggKyB0aGlzLncgPiB0aGlzLmNvbHMpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMueCA9IDA7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLncgPSB0aGlzLmNvbHM7XFxyXFxuICAgICAgICAgICAgICAgIH1cXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgdmFyIHBvcyA9IHRoaXMuY2FsY1Bvc2l0aW9uKHRoaXMueCwgdGhpcy55LCB0aGlzLncsIHRoaXMuaCk7XFxyXFxuXFxyXFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzRHJhZ2dpbmcpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHBvcy50b3AgPSB0aGlzLmRyYWdnaW5nLnRvcDtcXHJcXG4vLyAgICAgICAgICAgICAgICAgICAgQWRkIHJ0bCBzdXBwb3J0XFxyXFxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5yZW5kZXJSdGwpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBwb3MucmlnaHQgPSB0aGlzLmRyYWdnaW5nLmxlZnQ7XFxyXFxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBvcy5sZWZ0ID0gdGhpcy5kcmFnZ2luZy5sZWZ0O1xcclxcbiAgICAgICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzUmVzaXppbmcpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHBvcy53aWR0aCA9IHRoaXMucmVzaXppbmcud2lkdGg7XFxyXFxuICAgICAgICAgICAgICAgICAgICBwb3MuaGVpZ2h0ID0gdGhpcy5yZXNpemluZy5oZWlnaHQ7XFxyXFxuICAgICAgICAgICAgICAgIH1cXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgbGV0IHN0eWxlO1xcclxcbiAgICAgICAgICAgICAgICAvLyBDU1MgVHJhbnNmb3JtcyBzdXBwb3J0IChkZWZhdWx0KVxcclxcbiAgICAgICAgICAgICAgICBpZiAodGhpcy51c2VDc3NUcmFuc2Zvcm1zKSB7XFxyXFxuLy8gICAgICAgICAgICAgICAgICAgIEFkZCBydGwgc3VwcG9ydFxcclxcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucmVuZGVyUnRsKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGUgPSBzZXRUcmFuc2Zvcm1SdGwocG9zLnRvcCwgcG9zLnJpZ2h0LCBwb3Mud2lkdGgsIHBvcy5oZWlnaHQpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZSA9IHNldFRyYW5zZm9ybShwb3MudG9wLCBwb3MubGVmdCwgcG9zLndpZHRoLCBwb3MuaGVpZ2h0KTtcXHJcXG4gICAgICAgICAgICAgICAgICAgIH1cXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgfSBlbHNlIHsgLy8gdG9wLGxlZnQgKHNsb3cpXFxyXFxuLy8gICAgICAgICAgICAgICAgICAgIEFkZCBydGwgc3VwcG9ydFxcclxcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucmVuZGVyUnRsKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGUgPSBzZXRUb3BSaWdodChwb3MudG9wLCBwb3MucmlnaHQsIHBvcy53aWR0aCwgcG9zLmhlaWdodCk7XFxyXFxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlID0gc2V0VG9wTGVmdChwb3MudG9wLCBwb3MubGVmdCwgcG9zLndpZHRoLCBwb3MuaGVpZ2h0KTtcXHJcXG4gICAgICAgICAgICAgICAgICAgIH1cXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgICAgICB0aGlzLnN0eWxlID0gc3R5bGU7XFxyXFxuXFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICBoYW5kbGVSZXNpemU6IGZ1bmN0aW9uIChldmVudCkge1xcclxcbiAgICAgICAgICAgICAgICBjb25zdCBwb3NpdGlvbiA9IGdldENvbnRyb2xQb3NpdGlvbihldmVudCk7XFxyXFxuICAgICAgICAgICAgICAgIC8vIEdldCB0aGUgY3VycmVudCBkcmFnIHBvaW50IGZyb20gdGhlIGV2ZW50LiBUaGlzIGlzIHVzZWQgYXMgdGhlIG9mZnNldC5cXHJcXG4gICAgICAgICAgICAgICAgaWYgKHBvc2l0aW9uID09IG51bGwpIHJldHVybjsgLy8gbm90IHBvc3NpYmxlIGJ1dCBzYXRpc2ZpZXMgZmxvd1xcclxcbiAgICAgICAgICAgICAgICBjb25zdCB7eCwgeX0gPSBwb3NpdGlvbjtcXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgY29uc3QgbmV3U2l6ZSA9IHt3aWR0aDogMCwgaGVpZ2h0OiAwfTtcXHJcXG4gICAgICAgICAgICAgICAgc3dpdGNoIChldmVudC50eXBlKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICBjYXNlIFxcXCJyZXNpemVzdGFydFxcXCI6XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcmV2aW91c1cgPSB0aGlzLnc7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcmV2aW91c0ggPSB0aGlzLmg7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBvcyA9IHRoaXMuY2FsY1Bvc2l0aW9uKHRoaXMueCwgdGhpcy55LCB0aGlzLncsIHRoaXMuaCk7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3U2l6ZS53aWR0aCA9IHBvcy53aWR0aDtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdTaXplLmhlaWdodCA9IHBvcy5oZWlnaHQ7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZXNpemluZyA9IG5ld1NpemU7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc1Jlc2l6aW5nID0gdHJ1ZTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcXHJcXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXFxcInJlc2l6ZW1vdmVcXFwiOlxcclxcbi8vICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXFxcIiMjIyByZXNpemUgPT4gXFxcIiArIGV2ZW50LnR5cGUgKyBcXFwiLCBsYXN0Vz1cXFwiICsgdGhpcy5sYXN0VyArIFxcXCIsIGxhc3RIPVxcXCIgKyB0aGlzLmxhc3RIKTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb3JlRXZlbnQgPSBjcmVhdGVDb3JlRGF0YSh0aGlzLmxhc3RXLCB0aGlzLmxhc3RILCB4LCB5KTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5yZW5kZXJSdGwpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3U2l6ZS53aWR0aCA9IHRoaXMucmVzaXppbmcud2lkdGggLSBjb3JlRXZlbnQuZGVsdGFYO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1NpemUud2lkdGggPSB0aGlzLnJlc2l6aW5nLndpZHRoICsgY29yZUV2ZW50LmRlbHRhWDtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3U2l6ZS5oZWlnaHQgPSB0aGlzLnJlc2l6aW5nLmhlaWdodCArIGNvcmVFdmVudC5kZWx0YVk7XFxyXFxuXFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8vY29uc29sZS5sb2coXFxcIiMjIyByZXNpemUgPT4gXFxcIiArIGV2ZW50LnR5cGUgKyBcXFwiLCBkZWx0YVg9XFxcIiArIGNvcmVFdmVudC5kZWx0YVggKyBcXFwiLCBkZWx0YVk9XFxcIiArIGNvcmVFdmVudC5kZWx0YVkpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVzaXppbmcgPSBuZXdTaXplO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xcclxcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcXFwicmVzaXplZW5kXFxcIjpcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKFxcXCIjIyMgcmVzaXplIGVuZCA9PiB4PVxcXCIgK3RoaXMueCArIFxcXCIgeT1cXFwiICsgdGhpcy55ICsgXFxcIiB3PVxcXCIgKyB0aGlzLncgKyBcXFwiIGg9XFxcIiArIHRoaXMuaCk7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBvcyA9IHRoaXMuY2FsY1Bvc2l0aW9uKHRoaXMueCwgdGhpcy55LCB0aGlzLncsIHRoaXMuaCk7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3U2l6ZS53aWR0aCA9IHBvcy53aWR0aDtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdTaXplLmhlaWdodCA9IHBvcy5oZWlnaHQ7XFxyXFxuLy8gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcXFwiIyMjIHJlc2l6ZSBlbmQgPT4gXFxcIiArIEpTT04uc3RyaW5naWZ5KG5ld1NpemUpKTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc2l6aW5nID0gbnVsbDtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzUmVzaXppbmcgPSBmYWxzZTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcblxcclxcbiAgICAgICAgICAgICAgICAvLyBHZXQgbmV3IFdIXFxyXFxuICAgICAgICAgICAgICAgIHZhciBwb3MgPSB0aGlzLmNhbGNXSChuZXdTaXplLmhlaWdodCwgbmV3U2l6ZS53aWR0aCk7XFxyXFxuICAgICAgICAgICAgICAgIGlmIChwb3MudyA8IHRoaXMubWluVykge1xcclxcbiAgICAgICAgICAgICAgICAgICAgcG9zLncgPSB0aGlzLm1pblc7XFxyXFxuICAgICAgICAgICAgICAgIH1cXHJcXG4gICAgICAgICAgICAgICAgaWYgKHBvcy53ID4gdGhpcy5tYXhXKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICBwb3MudyA9IHRoaXMubWF4VztcXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgICAgICBpZiAocG9zLmggPCB0aGlzLm1pbkgpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHBvcy5oID0gdGhpcy5taW5IO1xcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgICAgIGlmIChwb3MuaCA+IHRoaXMubWF4SCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgcG9zLmggPSB0aGlzLm1heEg7XFxyXFxuICAgICAgICAgICAgICAgIH1cXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgaWYgKHBvcy5oIDwgMSkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgcG9zLmggPSAxO1xcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgICAgIGlmIChwb3MudyA8IDEpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHBvcy53ID0gMTtcXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcblxcclxcbiAgICAgICAgICAgICAgICB0aGlzLmxhc3RXID0geDtcXHJcXG4gICAgICAgICAgICAgICAgdGhpcy5sYXN0SCA9IHk7XFxyXFxuXFxyXFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLncgIT09IHBvcy53IHx8IHRoaXMuaCAhPT0gcG9zLmgpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuJGVtaXQoXFxcInJlc2l6ZVxcXCIsIHRoaXMuaSwgcG9zLmgsIHBvcy53KTtcXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnQudHlwZSA9PT0gXFxcInJlc2l6ZWVuZFxcXCIgJiYgKHRoaXMucHJldmlvdXNXICE9PSB0aGlzLncgfHwgdGhpcy5wcmV2aW91c0ggIT09IHRoaXMuaCkpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuJGVtaXQoXFxcInJlc2l6ZWRcXFwiLCB0aGlzLmksIHBvcy5oLCBwb3MudywgbmV3U2l6ZS5oZWlnaHQsIG5ld1NpemUud2lkdGgpO1xcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJGVtaXQoXFxcInJlc2l6ZUV2ZW50XFxcIiwgZXZlbnQudHlwZSwgdGhpcy5pLCB0aGlzLngsIHRoaXMueSwgcG9zLmgsIHBvcy53KTtcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIGhhbmRsZURyYWcoZXZlbnQpIHtcXHJcXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNSZXNpemluZykgcmV0dXJuO1xcclxcblxcclxcbiAgICAgICAgICAgICAgICBjb25zdCBwb3NpdGlvbiA9IGdldENvbnRyb2xQb3NpdGlvbihldmVudCk7XFxyXFxuXFxyXFxuICAgICAgICAgICAgICAgIC8vIEdldCB0aGUgY3VycmVudCBkcmFnIHBvaW50IGZyb20gdGhlIGV2ZW50LiBUaGlzIGlzIHVzZWQgYXMgdGhlIG9mZnNldC5cXHJcXG4gICAgICAgICAgICAgICAgaWYgKHBvc2l0aW9uID09PSBudWxsKSByZXR1cm47IC8vIG5vdCBwb3NzaWJsZSBidXQgc2F0aXNmaWVzIGZsb3dcXHJcXG4gICAgICAgICAgICAgICAgY29uc3Qge3gsIHl9ID0gcG9zaXRpb247XFxyXFxuXFxyXFxuICAgICAgICAgICAgICAgIHZhciBzaG91bGRVcGRhdGUgPSBmYWxzZTtcXHJcXG4gICAgICAgICAgICAgICAgY29uc3QgbmV3UG9zaXRpb24gPSB7dG9wOiAwLCBsZWZ0OiAwfTtcXHJcXG4gICAgICAgICAgICAgICAgc3dpdGNoIChldmVudC50eXBlKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICBjYXNlIFxcXCJkcmFnc3RhcnRcXFwiOlxcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJldmlvdXNYID0gdGhpcy54O1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJldmlvdXNZID0gdGhpcy55O1xcclxcblxcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYXJlbnRSZWN0ID0gZXZlbnQudGFyZ2V0Lm9mZnNldFBhcmVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2xpZW50UmVjdCA9IGV2ZW50LnRhcmdldC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5yZW5kZXJSdGwpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3UG9zaXRpb24ubGVmdCA9IChjbGllbnRSZWN0LnJpZ2h0IC0gcGFyZW50UmVjdC5yaWdodCkgKiAtMTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdQb3NpdGlvbi5sZWZ0ID0gY2xpZW50UmVjdC5sZWZ0IC0gcGFyZW50UmVjdC5sZWZ0O1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdQb3NpdGlvbi50b3AgPSBjbGllbnRSZWN0LnRvcCAtIHBhcmVudFJlY3QudG9wO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZHJhZ2dpbmcgPSBuZXdQb3NpdGlvbjtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzRHJhZ2dpbmcgPSB0cnVlO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xcclxcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcXFwiZHJhZ2VuZFxcXCI6XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLmlzRHJhZ2dpbmcpIHJldHVybjtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnRSZWN0ID0gZXZlbnQudGFyZ2V0Lm9mZnNldFBhcmVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGllbnRSZWN0ID0gZXZlbnQudGFyZ2V0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xcclxcbi8vICAgICAgICAgICAgICAgICAgICAgICAgQWRkIHJ0bCBzdXBwb3J0XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucmVuZGVyUnRsKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1Bvc2l0aW9uLmxlZnQgPSAoY2xpZW50UmVjdC5yaWdodCAtIHBhcmVudFJlY3QucmlnaHQpICogLTE7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3UG9zaXRpb24ubGVmdCA9IGNsaWVudFJlY3QubGVmdCAtIHBhcmVudFJlY3QubGVmdDtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3UG9zaXRpb24udG9wID0gY2xpZW50UmVjdC50b3AgLSBwYXJlbnRSZWN0LnRvcDtcXHJcXG4vLyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxcXCIjIyMgZHJhZyBlbmQgPT4gXFxcIiArIEpTT04uc3RyaW5naWZ5KG5ld1Bvc2l0aW9uKSk7XFxyXFxuLy8gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcXFwiIyMjIERST1A6IFxcXCIgKyBKU09OLnN0cmluZ2lmeShuZXdQb3NpdGlvbikpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZHJhZ2dpbmcgPSBudWxsO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNEcmFnZ2luZyA9IGZhbHNlO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNob3VsZFVwZGF0ZSA9IHRydWU7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XFxyXFxuICAgICAgICAgICAgICAgICAgICBjYXNlIFxcXCJkcmFnbW92ZVxcXCI6XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY29yZUV2ZW50ID0gY3JlYXRlQ29yZURhdGEodGhpcy5sYXN0WCwgdGhpcy5sYXN0WSwgeCwgeSk7XFxyXFxuLy8gICAgICAgICAgICAgICAgICAgICAgICBBZGQgcnRsIHN1cHBvcnRcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5yZW5kZXJSdGwpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3UG9zaXRpb24ubGVmdCA9IHRoaXMuZHJhZ2dpbmcubGVmdCAtIGNvcmVFdmVudC5kZWx0YVg7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3UG9zaXRpb24ubGVmdCA9IHRoaXMuZHJhZ2dpbmcubGVmdCArIGNvcmVFdmVudC5kZWx0YVg7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1Bvc2l0aW9uLnRvcCA9IHRoaXMuZHJhZ2dpbmcudG9wICsgY29yZUV2ZW50LmRlbHRhWTtcXHJcXG4vLyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxcXCIjIyMgZHJhZyA9PiBcXFwiICsgZXZlbnQudHlwZSArIFxcXCIsIHg9XFxcIiArIHggKyBcXFwiLCB5PVxcXCIgKyB5KTtcXHJcXG4vLyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxcXCIjIyMgZHJhZyA9PiBcXFwiICsgZXZlbnQudHlwZSArIFxcXCIsIGRlbHRhWD1cXFwiICsgY29yZUV2ZW50LmRlbHRhWCArIFxcXCIsIGRlbHRhWT1cXFwiICsgY29yZUV2ZW50LmRlbHRhWSk7XFxyXFxuLy8gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcXFwiIyMjIGRyYWcgZW5kID0+IFxcXCIgKyBKU09OLnN0cmluZ2lmeShuZXdQb3NpdGlvbikpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZHJhZ2dpbmcgPSBuZXdQb3NpdGlvbjtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcblxcclxcbiAgICAgICAgICAgICAgICAvLyBHZXQgbmV3IFhZXFxyXFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnJlbmRlclJ0bCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBvcyA9IHRoaXMuY2FsY1hZKG5ld1Bvc2l0aW9uLnRvcCwgbmV3UG9zaXRpb24ubGVmdCk7XFxyXFxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICB2YXIgcG9zID0gdGhpcy5jYWxjWFkobmV3UG9zaXRpb24udG9wLCBuZXdQb3NpdGlvbi5sZWZ0KTtcXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcblxcclxcbiAgICAgICAgICAgICAgICB0aGlzLmxhc3RYID0geDtcXHJcXG4gICAgICAgICAgICAgICAgdGhpcy5sYXN0WSA9IHk7XFxyXFxuXFxyXFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnggIT09IHBvcy54IHx8IHRoaXMueSAhPT0gcG9zLnkpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuJGVtaXQoXFxcIm1vdmVcXFwiLCB0aGlzLmksIHBvcy54LCBwb3MueSk7XFxyXFxuICAgICAgICAgICAgICAgIH1cXHJcXG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50LnR5cGUgPT09IFxcXCJkcmFnZW5kXFxcIiAmJiAodGhpcy5wcmV2aW91c1ggIT09IHRoaXMueCB8fCB0aGlzLnByZXZpb3VzWSAhPT0gdGhpcy55KSkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy4kZW1pdChcXFwibW92ZWRcXFwiLCB0aGlzLmksIHBvcy54LCBwb3MueSk7XFxyXFxuICAgICAgICAgICAgICAgIH1cXHJcXG4gICAgICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kZW1pdChcXFwiZHJhZ0V2ZW50XFxcIiwgZXZlbnQudHlwZSwgdGhpcy5pLCBwb3MueCwgcG9zLnksIHRoaXMuaCwgdGhpcy53KTtcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIGNhbGNQb3NpdGlvbjogZnVuY3Rpb24gKHgsIHksIHcsIGgpIHtcXHJcXG4gICAgICAgICAgICAgICAgY29uc3QgY29sV2lkdGggPSB0aGlzLmNhbGNDb2xXaWR0aCgpO1xcclxcbiAgICAgICAgICAgICAgICAvLyBhZGQgcnRsIHN1cHBvcnRcXHJcXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMucmVuZGVyUnRsKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICB2YXIgb3V0ID0ge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJpZ2h0OiBNYXRoLnJvdW5kKGNvbFdpZHRoICogeCArICh4ICsgMSkgKiB0aGlzLm1hcmdpblswXSksXFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgdG9wOiBNYXRoLnJvdW5kKHRoaXMucm93SGVpZ2h0ICogeSArICh5ICsgMSkgKiB0aGlzLm1hcmdpblsxXSksXFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gMCAqIEluZmluaXR5ID09PSBOYU4sIHdoaWNoIGNhdXNlcyBwcm9ibGVtcyB3aXRoIHJlc2l6ZSBjb25zdHJpYW50cztcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBGaXggdGhpcyBpZiBpdCBvY2N1cnMuXFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gTm90ZSB3ZSBkbyBpdCBoZXJlIHJhdGhlciB0aGFuIGxhdGVyIGJlY2F1c2UgTWF0aC5yb3VuZChJbmZpbml0eSkgY2F1c2VzIGRlb3B0XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHcgPT09IEluZmluaXR5ID8gdyA6IE1hdGgucm91bmQoY29sV2lkdGggKiB3ICsgTWF0aC5tYXgoMCwgdyAtIDEpICogdGhpcy5tYXJnaW5bMF0pLFxcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodDogaCA9PT0gSW5maW5pdHkgPyBoIDogTWF0aC5yb3VuZCh0aGlzLnJvd0hlaWdodCAqIGggKyBNYXRoLm1heCgwLCBoIC0gMSkgKiB0aGlzLm1hcmdpblsxXSlcXHJcXG4gICAgICAgICAgICAgICAgICAgIH07XFxyXFxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICB2YXIgb3V0ID0ge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlZnQ6IE1hdGgucm91bmQoY29sV2lkdGggKiB4ICsgKHggKyAxKSAqIHRoaXMubWFyZ2luWzBdKSxcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB0b3A6IE1hdGgucm91bmQodGhpcy5yb3dIZWlnaHQgKiB5ICsgKHkgKyAxKSAqIHRoaXMubWFyZ2luWzFdKSxcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyAwICogSW5maW5pdHkgPT09IE5hTiwgd2hpY2ggY2F1c2VzIHByb2JsZW1zIHdpdGggcmVzaXplIGNvbnN0cmlhbnRzO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZpeCB0aGlzIGlmIGl0IG9jY3Vycy5cXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBOb3RlIHdlIGRvIGl0IGhlcmUgcmF0aGVyIHRoYW4gbGF0ZXIgYmVjYXVzZSBNYXRoLnJvdW5kKEluZmluaXR5KSBjYXVzZXMgZGVvcHRcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogdyA9PT0gSW5maW5pdHkgPyB3IDogTWF0aC5yb3VuZChjb2xXaWR0aCAqIHcgKyBNYXRoLm1heCgwLCB3IC0gMSkgKiB0aGlzLm1hcmdpblswXSksXFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBoID09PSBJbmZpbml0eSA/IGggOiBNYXRoLnJvdW5kKHRoaXMucm93SGVpZ2h0ICogaCArIE1hdGgubWF4KDAsIGggLSAxKSAqIHRoaXMubWFyZ2luWzFdKVxcclxcbiAgICAgICAgICAgICAgICAgICAgfTtcXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcblxcclxcblxcclxcbiAgICAgICAgICAgICAgICByZXR1cm4gb3V0O1xcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgLyoqXFxyXFxuICAgICAgICAgICAgICogVHJhbnNsYXRlIHggYW5kIHkgY29vcmRpbmF0ZXMgZnJvbSBwaXhlbHMgdG8gZ3JpZCB1bml0cy5cXHJcXG4gICAgICAgICAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9IHRvcCAgVG9wIHBvc2l0aW9uIChyZWxhdGl2ZSB0byBwYXJlbnQpIGluIHBpeGVscy5cXHJcXG4gICAgICAgICAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9IGxlZnQgTGVmdCBwb3NpdGlvbiAocmVsYXRpdmUgdG8gcGFyZW50KSBpbiBwaXhlbHMuXFxyXFxuICAgICAgICAgICAgICogQHJldHVybiB7T2JqZWN0fSB4IGFuZCB5IGluIGdyaWQgdW5pdHMuXFxyXFxuICAgICAgICAgICAgICovXFxyXFxuICAgICAgICAgICAgLy8gVE9ETyBjaGVjayBpZiB0aGlzIGZ1bmN0aW9uIG5lZWRzIGNoYW5nZSBpbiBvcmRlciB0byBzdXBwb3J0IHJ0bC5cXHJcXG4gICAgICAgICAgICBjYWxjWFkodG9wLCBsZWZ0KSB7XFxyXFxuICAgICAgICAgICAgICAgIGNvbnN0IGNvbFdpZHRoID0gdGhpcy5jYWxjQ29sV2lkdGgoKTtcXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgLy8gbGVmdCA9IGNvbFdpZHRoICogeCArIG1hcmdpbiAqICh4ICsgMSlcXHJcXG4gICAgICAgICAgICAgICAgLy8gbCA9IGN4ICsgbSh4KzEpXFxyXFxuICAgICAgICAgICAgICAgIC8vIGwgPSBjeCArIG14ICsgbVxcclxcbiAgICAgICAgICAgICAgICAvLyBsIC0gbSA9IGN4ICsgbXhcXHJcXG4gICAgICAgICAgICAgICAgLy8gbCAtIG0gPSB4KGMgKyBtKVxcclxcbiAgICAgICAgICAgICAgICAvLyAobCAtIG0pIC8gKGMgKyBtKSA9IHhcXHJcXG4gICAgICAgICAgICAgICAgLy8geCA9IChsZWZ0IC0gbWFyZ2luKSAvIChjb2xkV2lkdGggKyBtYXJnaW4pXFxyXFxuICAgICAgICAgICAgICAgIGxldCB4ID0gTWF0aC5yb3VuZCgobGVmdCAtIHRoaXMubWFyZ2luWzBdKSAvIChjb2xXaWR0aCArIHRoaXMubWFyZ2luWzBdKSk7XFxyXFxuICAgICAgICAgICAgICAgIGxldCB5ID0gTWF0aC5yb3VuZCgodG9wIC0gdGhpcy5tYXJnaW5bMV0pIC8gKHRoaXMucm93SGVpZ2h0ICsgdGhpcy5tYXJnaW5bMV0pKTtcXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgLy8gQ2FwcGluZ1xcclxcbiAgICAgICAgICAgICAgICB4ID0gTWF0aC5tYXgoTWF0aC5taW4oeCwgdGhpcy5jb2xzIC0gdGhpcy53KSwgMCk7XFxyXFxuICAgICAgICAgICAgICAgIHkgPSBNYXRoLm1heChNYXRoLm1pbih5LCB0aGlzLm1heFJvd3MgLSB0aGlzLmgpLCAwKTtcXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgcmV0dXJuIHt4LCB5fTtcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIC8vIEhlbHBlciBmb3IgZ2VuZXJhdGluZyBjb2x1bW4gd2lkdGhcXHJcXG4gICAgICAgICAgICBjYWxjQ29sV2lkdGgoKSB7XFxyXFxuICAgICAgICAgICAgICAgIHZhciBjb2xXaWR0aCA9ICh0aGlzLmNvbnRhaW5lcldpZHRoIC0gKHRoaXMubWFyZ2luWzBdICogKHRoaXMuY29scyArIDEpKSkgLyB0aGlzLmNvbHM7XFxyXFxuLy8gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXFxcIiMjIyBDT0xTPVxcXCIgKyB0aGlzLmNvbHMgKyBcXFwiIENPTCBXSURUSD1cXFwiICsgY29sV2lkdGgpO1xcclxcbiAgICAgICAgICAgICAgICByZXR1cm4gY29sV2lkdGg7XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG5cXHJcXG4gICAgICAgICAgICAvKipcXHJcXG4gICAgICAgICAgICAgKiBHaXZlbiBhIGhlaWdodCBhbmQgd2lkdGggaW4gcGl4ZWwgdmFsdWVzLCBjYWxjdWxhdGUgZ3JpZCB1bml0cy5cXHJcXG4gICAgICAgICAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9IGhlaWdodCBIZWlnaHQgaW4gcGl4ZWxzLlxcclxcbiAgICAgICAgICAgICAqIEBwYXJhbSAge051bWJlcn0gd2lkdGggIFdpZHRoIGluIHBpeGVscy5cXHJcXG4gICAgICAgICAgICAgKiBAcmV0dXJuIHtPYmplY3R9IHcsIGggYXMgZ3JpZCB1bml0cy5cXHJcXG4gICAgICAgICAgICAgKi9cXHJcXG4gICAgICAgICAgICBjYWxjV0goaGVpZ2h0LCB3aWR0aCkge1xcclxcbiAgICAgICAgICAgICAgICBjb25zdCBjb2xXaWR0aCA9IHRoaXMuY2FsY0NvbFdpZHRoKCk7XFxyXFxuXFxyXFxuICAgICAgICAgICAgICAgIC8vIHdpZHRoID0gY29sV2lkdGggKiB3IC0gKG1hcmdpbiAqICh3IC0gMSkpXFxyXFxuICAgICAgICAgICAgICAgIC8vIC4uLlxcclxcbiAgICAgICAgICAgICAgICAvLyB3ID0gKHdpZHRoICsgbWFyZ2luKSAvIChjb2xXaWR0aCArIG1hcmdpbilcXHJcXG4gICAgICAgICAgICAgICAgbGV0IHcgPSBNYXRoLnJvdW5kKCh3aWR0aCArIHRoaXMubWFyZ2luWzBdKSAvIChjb2xXaWR0aCArIHRoaXMubWFyZ2luWzBdKSk7XFxyXFxuICAgICAgICAgICAgICAgIGxldCBoID0gTWF0aC5yb3VuZCgoaGVpZ2h0ICsgdGhpcy5tYXJnaW5bMV0pIC8gKHRoaXMucm93SGVpZ2h0ICsgdGhpcy5tYXJnaW5bMV0pKTtcXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgLy8gQ2FwcGluZ1xcclxcbiAgICAgICAgICAgICAgICB3ID0gTWF0aC5tYXgoTWF0aC5taW4odywgdGhpcy5jb2xzIC0gdGhpcy54KSwgMCk7XFxyXFxuICAgICAgICAgICAgICAgIGggPSBNYXRoLm1heChNYXRoLm1pbihoLCB0aGlzLm1heFJvd3MgLSB0aGlzLnkpLCAwKTtcXHJcXG4gICAgICAgICAgICAgICAgcmV0dXJuIHt3LCBofTtcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIHVwZGF0ZVdpZHRoOiBmdW5jdGlvbiAod2lkdGgsIGNvbE51bSkge1xcclxcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnRhaW5lcldpZHRoID0gd2lkdGg7XFxyXFxuICAgICAgICAgICAgICAgIGlmIChjb2xOdW0gIT09IHVuZGVmaW5lZCAmJiBjb2xOdW0gIT09IG51bGwpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29scyA9IGNvbE51bTtcXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgY29tcGFjdDogZnVuY3Rpb24gKCkge1xcclxcbiAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVN0eWxlKCk7XFxyXFxuICAgICAgICAgICAgfVxcclxcbiAgICAgICAgfSxcXHJcXG4gICAgfVxcclxcbjwvc2NyaXB0PlxcclxcblwiXSxcInNvdXJjZVJvb3RcIjpcIndlYnBhY2s6Ly9cIn1dKTtcblxuLy8gZXhwb3J0c1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtY29tcGlsZXI/e1wiaWRcIjpcImRhdGEtdi1mMmVmOWNkMlwiLFwic2NvcGVkXCI6ZmFsc2UsXCJoYXNJbmxpbmVDb25maWdcIjpmYWxzZX0hLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL3NyYy9HcmlkSXRlbS52dWVcbi8vIG1vZHVsZSBpZCA9IDExXG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///11\n"); - -/***/ }), -/* 12 */ -/***/ (function(module, exports) { - -eval("/**\n * Translates the list format produced by css-loader into something\n * easier to manipulate.\n */\nmodule.exports = function listToStyles (parentId, list) {\n var styles = []\n var newStyles = {}\n for (var i = 0; i < list.length; i++) {\n var item = list[i]\n var id = item[0]\n var css = item[1]\n var media = item[2]\n var sourceMap = item[3]\n var part = {\n id: parentId + ':' + i,\n css: css,\n media: media,\n sourceMap: sourceMap\n }\n if (!newStyles[id]) {\n styles.push(newStyles[id] = { id: id, parts: [part] })\n } else {\n newStyles[id].parts.push(part)\n }\n }\n return styles\n}\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvdnVlLXN0eWxlLWxvYWRlci9saWIvbGlzdFRvU3R5bGVzLmpzP2I1MzUiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsaUJBQWlCO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQyx3QkFBd0I7QUFDM0QsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiMTIuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFRyYW5zbGF0ZXMgdGhlIGxpc3QgZm9ybWF0IHByb2R1Y2VkIGJ5IGNzcy1sb2FkZXIgaW50byBzb21ldGhpbmdcbiAqIGVhc2llciB0byBtYW5pcHVsYXRlLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGxpc3RUb1N0eWxlcyAocGFyZW50SWQsIGxpc3QpIHtcbiAgdmFyIHN0eWxlcyA9IFtdXG4gIHZhciBuZXdTdHlsZXMgPSB7fVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgaXRlbSA9IGxpc3RbaV1cbiAgICB2YXIgaWQgPSBpdGVtWzBdXG4gICAgdmFyIGNzcyA9IGl0ZW1bMV1cbiAgICB2YXIgbWVkaWEgPSBpdGVtWzJdXG4gICAgdmFyIHNvdXJjZU1hcCA9IGl0ZW1bM11cbiAgICB2YXIgcGFydCA9IHtcbiAgICAgIGlkOiBwYXJlbnRJZCArICc6JyArIGksXG4gICAgICBjc3M6IGNzcyxcbiAgICAgIG1lZGlhOiBtZWRpYSxcbiAgICAgIHNvdXJjZU1hcDogc291cmNlTWFwXG4gICAgfVxuICAgIGlmICghbmV3U3R5bGVzW2lkXSkge1xuICAgICAgc3R5bGVzLnB1c2gobmV3U3R5bGVzW2lkXSA9IHsgaWQ6IGlkLCBwYXJ0czogW3BhcnRdIH0pXG4gICAgfSBlbHNlIHtcbiAgICAgIG5ld1N0eWxlc1tpZF0ucGFydHMucHVzaChwYXJ0KVxuICAgIH1cbiAgfVxuICByZXR1cm4gc3R5bGVzXG59XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL25vZGVfbW9kdWxlcy92dWUtc3R5bGUtbG9hZGVyL2xpYi9saXN0VG9TdHlsZXMuanNcbi8vIG1vZHVsZSBpZCA9IDEyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///12\n"); - -/***/ }), -/* 13 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -eval("\n\nexports.__esModule = true;\n\nvar _utils = __webpack_require__(0);\n\nvar _draggableUtils = __webpack_require__(14);\n\n// var eventBus = require('./eventBus');\n\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\nvar interact = __webpack_require__(15);\n\nexports.default = {\n name: \"GridItem\",\n props: {\n /*cols: {\n type: Number,\n required: true\n },*/\n /*containerWidth: {\n type: Number,\n required: true\n },\n rowHeight: {\n type: Number,\n required: true\n },\n margin: {\n type: Array,\n required: true\n },\n maxRows: {\n type: Number,\n required: true\n },*/\n isDraggable: {\n type: Boolean,\n required: false,\n default: null\n },\n isResizable: {\n type: Boolean,\n required: false,\n default: null\n },\n /*useCssTransforms: {\n type: Boolean,\n required: true\n },\n static: {\n type: Boolean,\n required: false,\n default: false\n },\n */\n minH: {\n type: Number,\n required: false,\n default: 1\n },\n minW: {\n type: Number,\n required: false,\n default: 1\n },\n maxH: {\n type: Number,\n required: false,\n default: Infinity\n },\n maxW: {\n type: Number,\n required: false,\n default: Infinity\n },\n x: {\n type: Number,\n required: true\n },\n y: {\n type: Number,\n required: true\n },\n w: {\n type: Number,\n required: true\n },\n h: {\n type: Number,\n required: true\n },\n i: {\n required: true\n },\n dragIgnoreFrom: {\n type: String,\n required: false,\n default: 'a, button'\n },\n dragAllowFrom: {\n type: String,\n required: false,\n default: null\n },\n resizeIgnoreFrom: {\n type: String,\n required: false,\n default: 'a, button'\n }\n },\n inject: [\"eventBus\"],\n data: function data() {\n return {\n cols: 1,\n containerWidth: 100,\n rowHeight: 30,\n margin: [10, 10],\n maxRows: Infinity,\n draggable: null,\n resizable: null,\n useCssTransforms: true,\n\n isDragging: false,\n dragging: null,\n isResizing: false,\n resizing: null,\n lastX: NaN,\n lastY: NaN,\n lastW: NaN,\n lastH: NaN,\n style: {},\n rtl: false,\n\n dragEventSet: false,\n resizeEventSet: false,\n\n previousW: null,\n previousH: null,\n previousX: null,\n previousY: null\n };\n },\n created: function created() {\n var _this = this;\n\n var self = this;\n\n // Accessible refernces of functions for removing in beforeDestroy\n self.updateWidthHandler = function (width) {\n self.updateWidth(width);\n };\n\n self.compactHandler = function (layout) {\n self.compact(layout);\n };\n\n self.setDraggableHandler = function (isDraggable) {\n if (self.isDraggable === null) {\n self.draggable = isDraggable;\n }\n };\n\n self.setResizableHandler = function (isResizable) {\n if (self.isResizable === null) {\n self.resizable = isResizable;\n }\n };\n\n self.setRowHeightHandler = function (rowHeight) {\n self.rowHeight = rowHeight;\n };\n\n self.directionchangeHandler = function (direction) {\n var direction = document.dir !== undefined ? document.dir : document.getElementsByTagName(\"html\")[0].getAttribute(\"dir\");\n _this.rtl = direction === \"rtl\";\n _this.compact();\n };\n\n this.eventBus.$on('updateWidth', self.updateWidthHandler);\n this.eventBus.$on('compact', self.compactHandler);\n this.eventBus.$on('setDraggable', self.setDraggableHandler);\n this.eventBus.$on('setResizable', self.setResizableHandler);\n this.eventBus.$on('setRowHeight', self.setRowHeightHandler);\n this.eventBus.$on('directionchange', self.directionchangeHandler);\n\n /*this.eventBus.$on('setColNum', function(colNum) {\n self.cols = colNum;\n });*/\n var direction = document.dir !== undefined ? document.dir : document.getElementsByTagName(\"html\")[0].getAttribute(\"dir\");\n this.rtl = direction === \"rtl\";\n },\n\n beforeDestroy: function beforeDestroy() {\n var self = this;\n //Remove listeners\n this.eventBus.$off('updateWidth', self.updateWidthHandler);\n this.eventBus.$off('compact', self.compactHandler);\n this.eventBus.$off('setDraggable', self.setDraggableHandler);\n this.eventBus.$off('setResizable', self.setResizableHandler);\n this.eventBus.$off('setRowHeight', self.setRowHeightHandler);\n this.eventBus.$off('directionchange', self.directionchangeHandler);\n },\n mounted: function mounted() {\n this.cols = this.$parent.colNum;\n this.rowHeight = this.$parent.rowHeight;\n this.containerWidth = this.$parent.width !== null ? this.$parent.width : 100;\n this.margin = this.$parent.margin !== undefined ? this.$parent.margin : [10, 10];\n this.maxRows = this.$parent.maxRows;\n if (this.isDraggable === null) {\n this.draggable = this.$parent.isDraggable;\n } else {\n this.draggable = this.isDraggable;\n }\n if (this.isResizable === null) {\n this.resizable = this.$parent.isResizable;\n } else {\n this.resizable = this.isResizable;\n }\n this.useCssTransforms = this.$parent.useCssTransforms;\n this.createStyle();\n },\n watch: {\n isDraggable: function isDraggable() {\n this.draggable = this.isDraggable;\n },\n draggable: function draggable() {\n var self = this;\n if (this.interactObj === null || this.interactObj === undefined) {\n this.interactObj = interact(this.$refs.item);\n }\n if (this.draggable) {\n var opts = {\n ignoreFrom: this.dragIgnoreFrom,\n allowFrom: this.dragAllowFrom\n };\n this.interactObj.draggable(opts);\n /*this.interactObj.draggable({allowFrom: '.vue-draggable-handle'});*/\n if (!this.dragEventSet) {\n this.dragEventSet = true;\n this.interactObj.on('dragstart dragmove dragend', function (event) {\n self.handleDrag(event);\n });\n }\n } else {\n this.interactObj.draggable({\n enabled: false\n });\n }\n },\n isResizable: function isResizable() {\n this.resizable = this.isResizable;\n },\n resizable: function resizable() {\n var self = this;\n if (this.interactObj === null || this.interactObj === undefined) {\n this.interactObj = interact(this.$refs.item);\n }\n if (this.resizable) {\n var opts = {\n preserveAspectRatio: false,\n edges: { left: false, right: true, bottom: true, top: false },\n ignoreFrom: this.resizeIgnoreFrom\n };\n\n this.interactObj.resizable(opts);\n if (!this.resizeEventSet) {\n this.resizeEventSet = true;\n this.interactObj.on('resizestart resizemove resizeend', function (event) {\n self.handleResize(event);\n });\n }\n } else {\n this.interactObj.resizable({\n enabled: false\n });\n }\n },\n rowHeight: function rowHeight() {\n this.createStyle();\n },\n cols: function cols() {\n this.createStyle();\n },\n containerWidth: function containerWidth() {\n this.createStyle();\n },\n x: function x() {\n this.createStyle();\n },\n y: function y() {\n this.createStyle();\n },\n h: function h() {\n this.createStyle();\n },\n w: function w() {\n this.createStyle();\n },\n renderRtl: function renderRtl() {\n this.createStyle();\n }\n },\n computed: {\n renderRtl: function renderRtl() {\n return this.$parent.isMirrored ? !this.rtl : this.rtl;\n },\n resizableHandleClass: function resizableHandleClass() {\n if (this.renderRtl) {\n return 'vue-resizable-handle vue-rtl-resizable-handle';\n } else {\n return 'vue-resizable-handle';\n }\n }\n },\n methods: {\n createStyle: function createStyle() {\n if (this.x + this.w > this.cols) {\n this.x = 0;\n this.w = this.cols;\n }\n\n var pos = this.calcPosition(this.x, this.y, this.w, this.h);\n\n if (this.isDragging) {\n pos.top = this.dragging.top;\n // Add rtl support\n if (this.renderRtl) {\n pos.right = this.dragging.left;\n } else {\n pos.left = this.dragging.left;\n }\n }\n if (this.isResizing) {\n pos.width = this.resizing.width;\n pos.height = this.resizing.height;\n }\n\n var style = void 0;\n // CSS Transforms support (default)\n if (this.useCssTransforms) {\n // Add rtl support\n if (this.renderRtl) {\n style = (0, _utils.setTransformRtl)(pos.top, pos.right, pos.width, pos.height);\n } else {\n style = (0, _utils.setTransform)(pos.top, pos.left, pos.width, pos.height);\n }\n } else {\n // top,left (slow)\n // Add rtl support\n if (this.renderRtl) {\n style = (0, _utils.setTopRight)(pos.top, pos.right, pos.width, pos.height);\n } else {\n style = (0, _utils.setTopLeft)(pos.top, pos.left, pos.width, pos.height);\n }\n }\n this.style = style;\n },\n handleResize: function handleResize(event) {\n var position = (0, _draggableUtils.getControlPosition)(event);\n // Get the current drag point from the event. This is used as the offset.\n if (position == null) return; // not possible but satisfies flow\n var x = position.x,\n y = position.y;\n\n\n var newSize = { width: 0, height: 0 };\n switch (event.type) {\n case \"resizestart\":\n this.previousW = this.w;\n this.previousH = this.h;\n var pos = this.calcPosition(this.x, this.y, this.w, this.h);\n newSize.width = pos.width;\n newSize.height = pos.height;\n this.resizing = newSize;\n this.isResizing = true;\n break;\n case \"resizemove\":\n // console.log(\"### resize => \" + event.type + \", lastW=\" + this.lastW + \", lastH=\" + this.lastH);\n var coreEvent = (0, _draggableUtils.createCoreData)(this.lastW, this.lastH, x, y);\n if (this.renderRtl) {\n newSize.width = this.resizing.width - coreEvent.deltaX;\n } else {\n newSize.width = this.resizing.width + coreEvent.deltaX;\n }\n newSize.height = this.resizing.height + coreEvent.deltaY;\n\n ///console.log(\"### resize => \" + event.type + \", deltaX=\" + coreEvent.deltaX + \", deltaY=\" + coreEvent.deltaY);\n this.resizing = newSize;\n break;\n case \"resizeend\":\n //console.log(\"### resize end => x=\" +this.x + \" y=\" + this.y + \" w=\" + this.w + \" h=\" + this.h);\n var pos = this.calcPosition(this.x, this.y, this.w, this.h);\n newSize.width = pos.width;\n newSize.height = pos.height;\n // console.log(\"### resize end => \" + JSON.stringify(newSize));\n this.resizing = null;\n this.isResizing = false;\n break;\n }\n\n // Get new WH\n var pos = this.calcWH(newSize.height, newSize.width);\n if (pos.w < this.minW) {\n pos.w = this.minW;\n }\n if (pos.w > this.maxW) {\n pos.w = this.maxW;\n }\n if (pos.h < this.minH) {\n pos.h = this.minH;\n }\n if (pos.h > this.maxH) {\n pos.h = this.maxH;\n }\n\n if (pos.h < 1) {\n pos.h = 1;\n }\n if (pos.w < 1) {\n pos.w = 1;\n }\n\n this.lastW = x;\n this.lastH = y;\n\n if (this.w !== pos.w || this.h !== pos.h) {\n this.$emit(\"resize\", this.i, pos.h, pos.w);\n }\n if (event.type === \"resizeend\" && (this.previousW !== this.w || this.previousH !== this.h)) {\n this.$emit(\"resized\", this.i, pos.h, pos.w, newSize.height, newSize.width);\n }\n this.eventBus.$emit(\"resizeEvent\", event.type, this.i, this.x, this.y, pos.h, pos.w);\n },\n handleDrag: function handleDrag(event) {\n if (this.isResizing) return;\n\n var position = (0, _draggableUtils.getControlPosition)(event);\n\n // Get the current drag point from the event. This is used as the offset.\n if (position === null) return; // not possible but satisfies flow\n var x = position.x,\n y = position.y;\n\n\n var shouldUpdate = false;\n var newPosition = { top: 0, left: 0 };\n switch (event.type) {\n case \"dragstart\":\n this.previousX = this.x;\n this.previousY = this.y;\n\n var parentRect = event.target.offsetParent.getBoundingClientRect();\n var clientRect = event.target.getBoundingClientRect();\n if (this.renderRtl) {\n newPosition.left = (clientRect.right - parentRect.right) * -1;\n } else {\n newPosition.left = clientRect.left - parentRect.left;\n }\n newPosition.top = clientRect.top - parentRect.top;\n this.dragging = newPosition;\n this.isDragging = true;\n break;\n case \"dragend\":\n if (!this.isDragging) return;\n parentRect = event.target.offsetParent.getBoundingClientRect();\n clientRect = event.target.getBoundingClientRect();\n // Add rtl support\n if (this.renderRtl) {\n newPosition.left = (clientRect.right - parentRect.right) * -1;\n } else {\n newPosition.left = clientRect.left - parentRect.left;\n }\n newPosition.top = clientRect.top - parentRect.top;\n // console.log(\"### drag end => \" + JSON.stringify(newPosition));\n // console.log(\"### DROP: \" + JSON.stringify(newPosition));\n this.dragging = null;\n this.isDragging = false;\n shouldUpdate = true;\n break;\n case \"dragmove\":\n var coreEvent = (0, _draggableUtils.createCoreData)(this.lastX, this.lastY, x, y);\n // Add rtl support\n if (this.renderRtl) {\n newPosition.left = this.dragging.left - coreEvent.deltaX;\n } else {\n newPosition.left = this.dragging.left + coreEvent.deltaX;\n }\n newPosition.top = this.dragging.top + coreEvent.deltaY;\n // console.log(\"### drag => \" + event.type + \", x=\" + x + \", y=\" + y);\n // console.log(\"### drag => \" + event.type + \", deltaX=\" + coreEvent.deltaX + \", deltaY=\" + coreEvent.deltaY);\n // console.log(\"### drag end => \" + JSON.stringify(newPosition));\n this.dragging = newPosition;\n break;\n }\n\n // Get new XY\n if (this.renderRtl) {\n var pos = this.calcXY(newPosition.top, newPosition.left);\n } else {\n var pos = this.calcXY(newPosition.top, newPosition.left);\n }\n\n this.lastX = x;\n this.lastY = y;\n\n if (this.x !== pos.x || this.y !== pos.y) {\n this.$emit(\"move\", this.i, pos.x, pos.y);\n }\n if (event.type === \"dragend\" && (this.previousX !== this.x || this.previousY !== this.y)) {\n this.$emit(\"moved\", this.i, pos.x, pos.y);\n }\n this.eventBus.$emit(\"dragEvent\", event.type, this.i, pos.x, pos.y, this.h, this.w);\n },\n\n calcPosition: function calcPosition(x, y, w, h) {\n var colWidth = this.calcColWidth();\n // add rtl support\n if (this.renderRtl) {\n var out = {\n right: Math.round(colWidth * x + (x + 1) * this.margin[0]),\n top: Math.round(this.rowHeight * y + (y + 1) * this.margin[1]),\n // 0 * Infinity === NaN, which causes problems with resize constriants;\n // Fix this if it occurs.\n // Note we do it here rather than later because Math.round(Infinity) causes deopt\n width: w === Infinity ? w : Math.round(colWidth * w + Math.max(0, w - 1) * this.margin[0]),\n height: h === Infinity ? h : Math.round(this.rowHeight * h + Math.max(0, h - 1) * this.margin[1])\n };\n } else {\n var out = {\n left: Math.round(colWidth * x + (x + 1) * this.margin[0]),\n top: Math.round(this.rowHeight * y + (y + 1) * this.margin[1]),\n // 0 * Infinity === NaN, which causes problems with resize constriants;\n // Fix this if it occurs.\n // Note we do it here rather than later because Math.round(Infinity) causes deopt\n width: w === Infinity ? w : Math.round(colWidth * w + Math.max(0, w - 1) * this.margin[0]),\n height: h === Infinity ? h : Math.round(this.rowHeight * h + Math.max(0, h - 1) * this.margin[1])\n };\n }\n\n return out;\n },\n /**\n * Translate x and y coordinates from pixels to grid units.\n * @param {Number} top Top position (relative to parent) in pixels.\n * @param {Number} left Left position (relative to parent) in pixels.\n * @return {Object} x and y in grid units.\n */\n // TODO check if this function needs change in order to support rtl.\n calcXY: function calcXY(top, left) {\n var colWidth = this.calcColWidth();\n\n // left = colWidth * x + margin * (x + 1)\n // l = cx + m(x+1)\n // l = cx + mx + m\n // l - m = cx + mx\n // l - m = x(c + m)\n // (l - m) / (c + m) = x\n // x = (left - margin) / (coldWidth + margin)\n var x = Math.round((left - this.margin[0]) / (colWidth + this.margin[0]));\n var y = Math.round((top - this.margin[1]) / (this.rowHeight + this.margin[1]));\n\n // Capping\n x = Math.max(Math.min(x, this.cols - this.w), 0);\n y = Math.max(Math.min(y, this.maxRows - this.h), 0);\n\n return { x: x, y: y };\n },\n\n // Helper for generating column width\n calcColWidth: function calcColWidth() {\n var colWidth = (this.containerWidth - this.margin[0] * (this.cols + 1)) / this.cols;\n // console.log(\"### COLS=\" + this.cols + \" COL WIDTH=\" + colWidth);\n return colWidth;\n },\n\n\n /**\n * Given a height and width in pixel values, calculate grid units.\n * @param {Number} height Height in pixels.\n * @param {Number} width Width in pixels.\n * @return {Object} w, h as grid units.\n */\n calcWH: function calcWH(height, width) {\n var colWidth = this.calcColWidth();\n\n // width = colWidth * w - (margin * (w - 1))\n // ...\n // w = (width + margin) / (colWidth + margin)\n var w = Math.round((width + this.margin[0]) / (colWidth + this.margin[0]));\n var h = Math.round((height + this.margin[1]) / (this.rowHeight + this.margin[1]));\n\n // Capping\n w = Math.max(Math.min(w, this.cols - this.x), 0);\n h = Math.max(Math.min(h, this.maxRows - this.y), 0);\n return { w: w, h: h };\n },\n\n updateWidth: function updateWidth(width, colNum) {\n this.containerWidth = width;\n if (colNum !== undefined && colNum !== null) {\n this.cols = colNum;\n }\n },\n compact: function compact() {\n this.createStyle();\n }\n }\n};\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vR3JpZEl0ZW0udnVlPzdhMTYiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQWdGQTs7QUFDQTs7QUFFQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUpBOzttQ0FNQTs7O1VBRUE7O0FBS0E7Ozs7QUFpQkE7Ozs7Ozs7Ozs7Ozs7Ozs7O2tCQUVBO3NCQUNBO3FCQUVBO0FBSkE7O2tCQU1BO3NCQUNBO3FCQUVBO0FBSkE7QUFjQTs7Ozs7Ozs7Ozs7a0JBRUE7c0JBQ0E7cUJBRUE7QUFKQTs7a0JBTUE7c0JBQ0E7cUJBRUE7QUFKQTs7a0JBTUE7c0JBQ0E7cUJBRUE7QUFKQTs7a0JBTUE7c0JBQ0E7cUJBRUE7QUFKQTs7a0JBTUE7c0JBRUE7QUFIQTs7a0JBS0E7c0JBRUE7QUFIQTs7a0JBS0E7c0JBRUE7QUFIQTs7a0JBS0E7c0JBRUE7QUFIQTs7c0JBTUE7QUFGQTs7a0JBSUE7c0JBQ0E7cUJBRUE7QUFKQTs7a0JBTUE7c0JBQ0E7cUJBRUE7QUFKQTs7a0JBTUE7c0JBQ0E7cUJBR0E7QUFMQTtBQTNGQTthQWlHQTswQkFDQTs7a0JBRUE7NEJBQ0E7dUJBQ0E7eUJBQ0E7cUJBQ0E7dUJBQ0E7dUJBQ0E7OEJBRUE7O3dCQUNBO3NCQUNBO3dCQUNBO3NCQUNBO21CQUNBO21CQUNBO21CQUNBO21CQUNBO21CQUNBO2lCQUVBOzswQkFDQTs0QkFFQTs7dUJBQ0E7dUJBQ0E7dUJBQ0E7dUJBRUE7QUE1QkE7QUE2QkE7O0FBQ0E7O21CQUVBOztBQUNBO21EQUNBOzZCQUNBO0FBRUE7O2dEQUNBO3lCQUNBO0FBRUE7OzBEQUNBOzJDQUNBO2lDQUNBO0FBQ0E7QUFFQTs7MERBQ0E7MkNBQ0E7aUNBQ0E7QUFDQTtBQUVBOzt3REFDQTs2QkFDQTtBQUVBOzsyREFDQTs2Q0FDQSxxQkFDQSw0REFDQTtzQ0FDQTtrQkFDQTtBQUVBOzs4Q0FDQTswQ0FDQTsrQ0FDQTsrQ0FDQTsrQ0FDQTtrREFFQTs7QUFHQTs7O3lDQUNBLHFCQUNBLDREQUNBO2lDQUNBO0FBQ0E7OzRDQUNBO21CQUNBO0FBQ0E7K0NBQ0E7MkNBQ0E7Z0RBQ0E7Z0RBQ0E7Z0RBQ0E7bURBQ0E7QUFDQTtnQ0FDQTtpQ0FDQTtzQ0FDQTtpRkFDQTtxRkFDQTtvQ0FDQTt1Q0FDQTswQ0FDQTtlQUNBO2tDQUNBO0FBQ0E7dUNBQ0E7MENBQ0E7ZUFDQTtrQ0FDQTtBQUNBOzZDQUNBO2FBQ0E7QUFDQTs7NENBRUE7a0NBQ0E7QUFDQTt3Q0FDQTt1QkFDQTs2RUFDQTt1REFDQTtBQUNBO2dDQUNBOztxQ0FFQTtvQ0FFQTtBQUhBOzJDQUlBO0FBQ0E7d0NBQ0E7d0NBQ0E7dUZBQ0E7d0NBQ0E7QUFDQTtBQUNBO21CQUNBOzs2QkFHQTtBQUZBO0FBR0E7QUFDQTs0Q0FDQTtrQ0FDQTtBQUNBO3dDQUNBO3VCQUNBOzZFQUNBO3VEQUNBO0FBQ0E7Z0NBQ0E7O3lDQUVBOzBFQUNBO3FDQUdBO0FBTEE7OzJDQU1BOzBDQUNBOzBDQUNBO3lCQUNBLG9FQUNBOzBDQUNBO0FBQ0E7QUFDQTttQkFDQTs7NkJBR0E7QUFGQTtBQUdBO0FBQ0E7d0NBQ0E7aUJBQ0E7QUFDQTs4QkFDQTtpQkFDQTtBQUNBO2tEQUNBO2lCQUNBO0FBQ0E7d0JBQ0E7aUJBQ0E7QUFDQTt3QkFDQTtpQkFDQTtBQUNBO3dCQUNBO2lCQUNBO0FBQ0E7d0JBQ0E7aUJBQ0E7QUFDQTt3Q0FDQTtpQkFDQTtBQUVBO0FBakZBOzt3Q0FtRkE7OERBQ0E7QUFDQTs4REFDQTtnQ0FDQTt1QkFDQTttQkFDQTt1QkFDQTtBQUNBO0FBRUE7QUFYQTs7NENBYUE7NkNBQ0E7eUJBQ0E7OEJBQ0E7QUFFQTs7cUVBRUE7O2lDQUNBOztBQUVBO29DQUNBOzhDQUNBO3VCQUNBOzZDQUNBO0FBQ0E7QUFDQTtpQ0FDQTswQ0FDQTsyQ0FDQTtBQUVBOztnQkFDQTtBQUNBOztBQUVBO29DQUNBOzJGQUNBO3VCQUNBO3VGQUNBO0FBRUE7OztBQUVBO29DQUNBO3VGQUNBO3VCQUNBO3FGQUNBO0FBQ0E7QUFDQTt5QkFFQTtBQUNBOzttRUFFQTtBQUNBOzBDQUNBO0FBSEEsb0JBS0E7Ozs7OENBQ0E7MEJBQ0E7cUJBQ0E7MENBQ0E7MENBQ0E7NkVBQ0E7d0NBQ0E7eUNBQ0E7b0NBQ0E7c0NBQ0E7QUFDQTs7QUFFQTttR0FDQTt3Q0FDQTt3RUFDQTsyQkFDQTt3RUFDQTtBQUNBO3NFQUVBOztBQUNBO29DQUNBO0FBQ0E7cUJBQ0E7QUFDQTs2RUFDQTt3Q0FDQTs7QUFFQTtvQ0FDQTtzQ0FDQTtBQUdBOzs7QUFDQTswREFDQTttQ0FDQTs2QkFDQTtBQUNBO21DQUNBOzZCQUNBO0FBQ0E7bUNBQ0E7NkJBQ0E7QUFDQTttQ0FDQTs2QkFDQTtBQUVBOzsyQkFDQTt3QkFDQTtBQUNBOzJCQUNBO3dCQUNBO0FBRUE7O3lCQUNBO3lCQUVBOztzREFDQTt3REFDQTtBQUNBO3dHQUNBO29GQUNBO0FBQ0E7OEZBQ0E7QUFDQTs7aUNBR0E7O21FQUVBOztBQUNBOzJDQUNBO0FBTkEsb0JBUUE7Ozs7K0JBQ0E7OENBQ0E7MEJBQ0E7cUJBQ0E7MENBQ0E7MENBRUE7OytEQUNBO2tEQUNBO3dDQUNBO29GQUNBOzJCQUNBO3dFQUNBO0FBQ0E7a0VBQ0E7b0NBQ0E7c0NBQ0E7QUFDQTtxQkFDQTswQ0FDQTsyREFDQTs7QUFFQTt3Q0FDQTtvRkFDQTsyQkFDQTt3RUFDQTtBQUNBOztBQUNBO0FBRUE7b0NBQ0E7c0NBQ0E7bUNBQ0E7QUFDQTtxQkFDQTs7QUFFQTt3Q0FDQTswRUFDQTsyQkFDQTswRUFDQTtBQUNBOztBQUNBO0FBQ0E7QUFFQTtvQ0FDQTtBQUdBOzs7QUFDQTtnQ0FDQTttRUFDQTttQkFDQTttRUFDQTtBQUVBOzt5QkFDQTt5QkFFQTs7c0RBQ0E7c0RBQ0E7QUFDQTtzR0FDQTt1REFDQTtBQUNBOzRGQUNBO0FBQ0E7O3dEQUNBO2dDQUNBO0FBQ0E7Z0NBQ0E7OzJFQUVBOytFQUNBO0FBQ0E7QUFDQTtBQUNBOzJHQUNBO2tIQUVBO0FBUkE7bUJBU0E7OzBFQUVBOytFQUNBO0FBQ0E7QUFDQTtBQUNBOzJHQUNBO2tIQUVBO0FBUkE7QUFXQTs7bUJBQ0E7QUFDQTtBQU1BOzs7Ozs7QUFDQTsyQ0FDQTtnQ0FFQTs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtpRkFDQTtzRkFFQTs7QUFDQTswREFDQTs2REFFQTs7MkJBQ0E7QUFDQTs7QUFDQTs4Q0FDQTs7QUFFQTttQkFDQTtBQUVBOzs7QUFNQTs7Ozs7OytDQUNBO2dDQUVBOztBQUNBO0FBQ0E7QUFDQTtrRkFDQTt5RkFFQTs7QUFDQTswREFDQTs2REFDQTsyQkFDQTtBQUNBOzt5REFDQTtrQ0FDQTt5REFDQTs0QkFDQTtBQUNBO0FBQ0E7b0NBQ0E7aUJBQ0E7QUFFQTtBQTlSQTtBQWpUQSIsImZpbGUiOiIxMy5qcyIsInNvdXJjZXNDb250ZW50IjpbIjx0ZW1wbGF0ZT5cclxuICAgIDxkaXYgcmVmPVwiaXRlbVwiXHJcbiAgICAgICAgIGNsYXNzPVwidnVlLWdyaWQtaXRlbVwiXHJcbiAgICAgICAgIDpjbGFzcz1cInsgJ3Z1ZS1yZXNpemFibGUnIDogcmVzaXphYmxlLCAncmVzaXppbmcnIDogaXNSZXNpemluZywgJ3Z1ZS1kcmFnZ2FibGUtZHJhZ2dpbmcnIDogaXNEcmFnZ2luZywgJ2Nzc1RyYW5zZm9ybXMnIDogdXNlQ3NzVHJhbnNmb3JtcywgJ3JlbmRlci1ydGwnIDogcmVuZGVyUnRsIH1cIlxyXG4gICAgICAgICA6c3R5bGU9XCJzdHlsZVwiXHJcbiAgICA+XHJcbiAgICAgICAgPHNsb3Q+PC9zbG90PlxyXG4gICAgICAgIDxzcGFuIHYtaWY9XCJyZXNpemFibGVcIiByZWY9XCJoYW5kbGVcIiA6Y2xhc3M9XCJyZXNpemFibGVIYW5kbGVDbGFzc1wiPjwvc3Bhbj5cclxuICAgICAgICA8IS0tPHNwYW4gdi1pZj1cImRyYWdnYWJsZVwiIHJlZj1cImRyYWdIYW5kbGVcIiBjbGFzcz1cInZ1ZS1kcmFnZ2FibGUtaGFuZGxlXCI+PC9zcGFuPi0tPlxyXG4gICAgPC9kaXY+XHJcbjwvdGVtcGxhdGU+XHJcbjxzdHlsZT5cclxuICAgIC52dWUtZ3JpZC1pdGVtIHtcclxuICAgICAgICB0cmFuc2l0aW9uOiBhbGwgMjAwbXMgZWFzZTtcclxuICAgICAgICB0cmFuc2l0aW9uLXByb3BlcnR5OiBsZWZ0LCB0b3AsIHJpZ2h0O1xyXG4gICAgICAgIC8qIGFkZCByaWdodCBmb3IgcnRsICovXHJcbiAgICB9XHJcblxyXG4gICAgLnZ1ZS1ncmlkLWl0ZW0uY3NzVHJhbnNmb3JtcyB7XHJcbiAgICAgICAgdHJhbnNpdGlvbi1wcm9wZXJ0eTogdHJhbnNmb3JtO1xyXG4gICAgICAgIGxlZnQ6IDA7XHJcbiAgICAgICAgcmlnaHQ6IGF1dG87XHJcbiAgICB9XHJcblxyXG4gICAgLnZ1ZS1ncmlkLWl0ZW0uY3NzVHJhbnNmb3Jtcy5yZW5kZXItcnRsIHtcclxuICAgICAgICBsZWZ0OiBhdXRvO1xyXG4gICAgICAgIHJpZ2h0OiAwO1xyXG4gICAgfVxyXG5cclxuICAgIC52dWUtZ3JpZC1pdGVtLnJlc2l6aW5nIHtcclxuICAgICAgICBvcGFjaXR5OiAwLjY7XHJcbiAgICAgICAgei1pbmRleDogMztcclxuICAgIH1cclxuXHJcbiAgICAudnVlLWdyaWQtaXRlbS52dWUtZHJhZ2dhYmxlLWRyYWdnaW5nIHtcclxuICAgICAgICB0cmFuc2l0aW9uOm5vbmU7XHJcbiAgICAgICAgei1pbmRleDogMztcclxuICAgIH1cclxuXHJcbiAgICAudnVlLWdyaWQtaXRlbS52dWUtZ3JpZC1wbGFjZWhvbGRlciB7XHJcbiAgICAgICAgYmFja2dyb3VuZDogcmVkO1xyXG4gICAgICAgIG9wYWNpdHk6IDAuMjtcclxuICAgICAgICB0cmFuc2l0aW9uLWR1cmF0aW9uOiAxMDBtcztcclxuICAgICAgICB6LWluZGV4OiAyO1xyXG4gICAgICAgIC13ZWJraXQtdXNlci1zZWxlY3Q6IG5vbmU7XHJcbiAgICAgICAgLW1vei11c2VyLXNlbGVjdDogbm9uZTtcclxuICAgICAgICAtbXMtdXNlci1zZWxlY3Q6IG5vbmU7XHJcbiAgICAgICAgLW8tdXNlci1zZWxlY3Q6IG5vbmU7XHJcbiAgICAgICAgdXNlci1zZWxlY3Q6IG5vbmU7XHJcbiAgICB9XHJcblxyXG4gICAgLnZ1ZS1ncmlkLWl0ZW0gPiAudnVlLXJlc2l6YWJsZS1oYW5kbGUge1xyXG4gICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcclxuICAgICAgICB3aWR0aDogMjBweDtcclxuICAgICAgICBoZWlnaHQ6IDIwcHg7XHJcbiAgICAgICAgYm90dG9tOiAwO1xyXG4gICAgICAgIHJpZ2h0OiAwO1xyXG4gICAgICAgIGJhY2tncm91bmQ6IHVybCgnZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxQRDk0Yld3Z2RtVnljMmx2YmowaU1TNHdJaUJ6ZEdGdVpHRnNiMjVsUFNKdWJ5SS9QZzA4SVMwdElFZGxibVZ5WVhSdmNqb2dRV1J2WW1VZ1JtbHlaWGR2Y210eklFTlROaXdnUlhod2IzSjBJRk5XUnlCRmVIUmxibk5wYjI0Z1lua2dRV0Z5YjI0Z1FtVmhiR3dnS0doMGRIQTZMeTltYVhKbGQyOXlhM011WVdKbFlXeHNMbU52YlNrZ0xpQldaWEp6YVc5dU9pQXdMall1TVNBZ0xTMCtEVHdoUkU5RFZGbFFSU0J6ZG1jZ1VGVkNURWxESUNJdEx5OVhNME12TDBSVVJDQlRWa2NnTVM0eEx5OUZUaUlnSW1oMGRIQTZMeTkzZDNjdWR6TXViM0puTDBkeVlYQm9hV056TDFOV1J5OHhMakV2UkZSRUwzTjJaekV4TG1SMFpDSStEVHh6ZG1jZ2FXUTlJbFZ1ZEdsMGJHVmtMVkJoWjJVbE1qQXhJaUIyYVdWM1FtOTRQU0l3SURBZ05pQTJJaUJ6ZEhsc1pUMGlZbUZqYTJkeWIzVnVaQzFqYjJ4dmNqb2pabVptWm1abU1EQWlJSFpsY25OcGIyNDlJakV1TVNJTkNYaHRiRzV6UFNKb2RIUndPaTh2ZDNkM0xuY3pMbTl5Wnk4eU1EQXdMM04yWnlJZ2VHMXNibk02ZUd4cGJtczlJbWgwZEhBNkx5OTNkM2N1ZHpNdWIzSm5MekU1T1RrdmVHeHBibXNpSUhodGJEcHpjR0ZqWlQwaWNISmxjMlZ5ZG1VaURRbDRQU0l3Y0hnaUlIazlJakJ3ZUNJZ2QybGtkR2c5SWpad2VDSWdhR1ZwWjJoMFBTSTJjSGdpRFQ0TkNUeG5JRzl3WVdOcGRIazlJakF1TXpBeUlqNE5DUWs4Y0dGMGFDQmtQU0pOSURZZ05pQk1JREFnTmlCTUlEQWdOQzR5SUV3Z05DQTBMaklnVENBMExqSWdOQzR5SUV3Z05DNHlJREFnVENBMklEQWdUQ0EySURZZ1RDQTJJRFlnV2lJZ1ptbHNiRDBpSXpBd01EQXdNQ0l2UGcwSlBDOW5QZzA4TDNOMlp6ND0nKTtcclxuICAgICAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiBib3R0b20gcmlnaHQ7XHJcbiAgICAgICAgcGFkZGluZzogMCAzcHggM3B4IDA7XHJcbiAgICAgICAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDtcclxuICAgICAgICBiYWNrZ3JvdW5kLW9yaWdpbjogY29udGVudC1ib3g7XHJcbiAgICAgICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcclxuICAgICAgICBjdXJzb3I6IHNlLXJlc2l6ZTtcclxuICAgIH1cclxuXHJcbiAgICAudnVlLWdyaWQtaXRlbSA+IC52dWUtcnRsLXJlc2l6YWJsZS1oYW5kbGUge1xyXG4gICAgICAgIGJvdHRvbTogMDtcclxuICAgICAgICBsZWZ0OiAwO1xyXG4gICAgICAgIGJhY2tncm91bmQ6IHVybChkYXRhOmltYWdlL3N2Zyt4bWw7YmFzZTY0LFBITjJaeUIzYVdSMGFEMGlNVEF1TURBd01EQXdNREF3TURBd01EQXlJaUJvWldsbmFIUTlJakV3TGpBd01EQXdNREF3TURBd01EQXdNaUlnZUcxc2JuTTlJbWgwZEhBNkx5OTNkM2N1ZHpNdWIzSm5Mekl3TURBdmMzWm5JajRLSUR3aExTMGdRM0psWVhSbFpDQjNhWFJvSUUxbGRHaHZaQ0JFY21GM0lDMGdhSFIwY0RvdkwyZHBkR2gxWWk1amIyMHZaSFZ2Y0dsNFpXd3ZUV1YwYUc5a0xVUnlZWGN2SUMwdFBnb2dQR2MrQ2lBZ1BIUnBkR3hsUG1KaFkydG5jbTkxYm1ROEwzUnBkR3hsUGdvZ0lEeHlaV04wSUdacGJHdzlJbTV2Ym1VaUlHbGtQU0pqWVc1MllYTmZZbUZqYTJkeWIzVnVaQ0lnYUdWcFoyaDBQU0l4TWlJZ2QybGtkR2c5SWpFeUlpQjVQU0l0TVNJZ2VEMGlMVEVpTHo0S0lDQThaeUJrYVhOd2JHRjVQU0p1YjI1bElpQnZkbVZ5Wm14dmR6MGlkbWx6YVdKc1pTSWdlVDBpTUNJZ2VEMGlNQ0lnYUdWcFoyaDBQU0l4TURBbElpQjNhV1IwYUQwaU1UQXdKU0lnYVdROUltTmhiblpoYzBkeWFXUWlQZ29nSUNBOGNtVmpkQ0JtYVd4c1BTSjFjbXdvSTJkeWFXUndZWFIwWlhKdUtTSWdjM1J5YjJ0bExYZHBaSFJvUFNJd0lpQjVQU0l3SWlCNFBTSXdJaUJvWldsbmFIUTlJakV3TUNVaUlIZHBaSFJvUFNJeE1EQWxJaTgrQ2lBZ1BDOW5QZ29nUEM5blBnb2dQR2MrQ2lBZ1BIUnBkR3hsUGt4aGVXVnlJREU4TDNScGRHeGxQZ29nSUR4c2FXNWxJR05oYm5aaGN6MGlJMlptWm1abVppSWdZMkZ1ZG1GekxXOXdZV05wZEhrOUlqRWlJSE4wY205clpTMXNhVzVsWTJGd1BTSjFibVJsWm1sdVpXUWlJSE4wY205clpTMXNhVzVsYW05cGJqMGlkVzVrWldacGJtVmtJaUJwWkQwaWMzWm5YekVpSUhreVBTSXROekF1TVRjNE5EQTNJaUI0TWowaU1USTBMalEyTkRFM05TSWdlVEU5SWkwek9DNHpPVEkzTXpjaUlIZ3hQU0l4TkRRdU9ESXhNamc1SWlCemRISnZhMlV0ZDJsa2RHZzlJakV1TlNJZ2MzUnliMnRsUFNJak1EQXdJaUJtYVd4c1BTSnViMjVsSWk4K0NpQWdQR3hwYm1VZ2MzUnliMnRsUFNJak5qWTJOalkySWlCemRISnZhMlV0YkdsdVpXTmhjRDBpZFc1a1pXWnBibVZrSWlCemRISnZhMlV0YkdsdVpXcHZhVzQ5SW5WdVpHVm1hVzVsWkNJZ2FXUTlJbk4yWjE4MUlpQjVNajBpT1M0eE1EWTVOVGNpSUhneVBTSXdMamswTnpJME55SWdlVEU5SWkwd0xqQXhPREV5T0NJZ2VERTlJakF1T1RRM01qUTNJaUJ6ZEhKdmEyVXRkMmxrZEdnOUlqSWlJR1pwYkd3OUltNXZibVVpTHo0S0lDQThiR2x1WlNCemRISnZhMlV0YkdsdVpXTmhjRDBpZFc1a1pXWnBibVZrSWlCemRISnZhMlV0YkdsdVpXcHZhVzQ5SW5WdVpHVm1hVzVsWkNJZ2FXUTlJbk4yWjE4M0lpQjVNajBpT1NJZ2VESTlJakV3TGpBM016VXlPU0lnZVRFOUlqa2lJSGd4UFNJdE1DNDJOVFUyTkNJZ2MzUnliMnRsTFhkcFpIUm9QU0l5SWlCemRISnZhMlU5SWlNMk5qWTJOallpSUdacGJHdzlJbTV2Ym1VaUx6NEtJRHd2Wno0S1BDOXpkbWMrKTtcclxuICAgICAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiBib3R0b20gbGVmdDtcclxuICAgICAgICBwYWRkaW5nLWxlZnQ6IDNweDtcclxuICAgICAgICBiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0O1xyXG4gICAgICAgIGJhY2tncm91bmQtb3JpZ2luOiBjb250ZW50LWJveDtcclxuICAgICAgICBjdXJzb3I6IHN3LXJlc2l6ZTtcclxuICAgICAgICByaWdodDogYXV0bztcclxuICAgIH1cclxuPC9zdHlsZT5cclxuPHNjcmlwdD5cclxuICAgIGltcG9ydCB7c2V0VG9wTGVmdCwgc2V0VG9wUmlnaHQsIHNldFRyYW5zZm9ybVJ0bCwgc2V0VHJhbnNmb3JtLCBjcmVhdGVNYXJrdXAsIGdldExheW91dEl0ZW19IGZyb20gJy4vdXRpbHMnO1xyXG4gICAgaW1wb3J0IHtnZXRDb250cm9sUG9zaXRpb24sIG9mZnNldFhZRnJvbVBhcmVudE9mLCBjcmVhdGVDb3JlRGF0YX0gZnJvbSAnLi9kcmFnZ2FibGVVdGlscyc7XHJcbiAgICAvLyAgICB2YXIgZXZlbnRCdXMgPSByZXF1aXJlKCcuL2V2ZW50QnVzJyk7XHJcblxyXG4gICAgdmFyIGludGVyYWN0ID0gcmVxdWlyZShcImludGVyYWN0anNcIik7XHJcblxyXG4gICAgZXhwb3J0IGRlZmF1bHQge1xyXG4gICAgICAgIG5hbWU6IFwiR3JpZEl0ZW1cIixcclxuICAgICAgICBwcm9wczoge1xyXG4gICAgICAgICAgICAvKmNvbHM6IHtcclxuICAgICAgICAgICAgIHR5cGU6IE51bWJlcixcclxuICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlXHJcbiAgICAgICAgICAgICB9LCovXHJcbiAgICAgICAgICAgIC8qY29udGFpbmVyV2lkdGg6IHtcclxuICAgICAgICAgICAgIHR5cGU6IE51bWJlcixcclxuICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlXHJcblxyXG4gICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgIHJvd0hlaWdodDoge1xyXG4gICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxyXG4gICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcclxuICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICBtYXJnaW46IHtcclxuICAgICAgICAgICAgIHR5cGU6IEFycmF5LFxyXG4gICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcclxuICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICBtYXhSb3dzOiB7XHJcbiAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXHJcbiAgICAgICAgICAgICByZXF1aXJlZDogdHJ1ZVxyXG4gICAgICAgICAgICAgfSwqL1xyXG4gICAgICAgICAgICBpc0RyYWdnYWJsZToge1xyXG4gICAgICAgICAgICAgICAgdHlwZTogQm9vbGVhbixcclxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IG51bGxcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgaXNSZXNpemFibGU6IHtcclxuICAgICAgICAgICAgICAgIHR5cGU6IEJvb2xlYW4sXHJcbiAgICAgICAgICAgICAgICByZXF1aXJlZDogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiBudWxsXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIC8qdXNlQ3NzVHJhbnNmb3Jtczoge1xyXG4gICAgICAgICAgICAgdHlwZTogQm9vbGVhbixcclxuICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlXHJcbiAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgc3RhdGljOiB7XHJcbiAgICAgICAgICAgICB0eXBlOiBCb29sZWFuLFxyXG4gICAgICAgICAgICAgcmVxdWlyZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICAgZGVmYXVsdDogZmFsc2VcclxuICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBtaW5IOiB7XHJcbiAgICAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXHJcbiAgICAgICAgICAgICAgICByZXF1aXJlZDogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiAxXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIG1pblc6IHtcclxuICAgICAgICAgICAgICAgIHR5cGU6IE51bWJlcixcclxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IDFcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgbWF4SDoge1xyXG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxyXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogSW5maW5pdHlcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgbWF4Vzoge1xyXG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxyXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogSW5maW5pdHlcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgeDoge1xyXG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxyXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgeToge1xyXG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxyXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgdzoge1xyXG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxyXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgaDoge1xyXG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxyXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgaToge1xyXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgZHJhZ0lnbm9yZUZyb206IHtcclxuICAgICAgICAgICAgICAgIHR5cGU6IFN0cmluZyxcclxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6ICdhLCBidXR0b24nXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGRyYWdBbGxvd0Zyb206IHtcclxuICAgICAgICAgICAgICAgIHR5cGU6IFN0cmluZyxcclxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IG51bGxcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgcmVzaXplSWdub3JlRnJvbToge1xyXG4gICAgICAgICAgICAgICAgdHlwZTogU3RyaW5nLFxyXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogJ2EsIGJ1dHRvbidcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIGluamVjdDogW1wiZXZlbnRCdXNcIl0sXHJcbiAgICAgICAgZGF0YTogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgY29sczogMSxcclxuICAgICAgICAgICAgICAgIGNvbnRhaW5lcldpZHRoOiAxMDAsXHJcbiAgICAgICAgICAgICAgICByb3dIZWlnaHQ6IDMwLFxyXG4gICAgICAgICAgICAgICAgbWFyZ2luOiBbMTAsIDEwXSxcclxuICAgICAgICAgICAgICAgIG1heFJvd3M6IEluZmluaXR5LFxyXG4gICAgICAgICAgICAgICAgZHJhZ2dhYmxlOiBudWxsLFxyXG4gICAgICAgICAgICAgICAgcmVzaXphYmxlOiBudWxsLFxyXG4gICAgICAgICAgICAgICAgdXNlQ3NzVHJhbnNmb3JtczogdHJ1ZSxcclxuXHJcbiAgICAgICAgICAgICAgICBpc0RyYWdnaW5nOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgIGRyYWdnaW5nOiBudWxsLFxyXG4gICAgICAgICAgICAgICAgaXNSZXNpemluZzogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICByZXNpemluZzogbnVsbCxcclxuICAgICAgICAgICAgICAgIGxhc3RYOiBOYU4sXHJcbiAgICAgICAgICAgICAgICBsYXN0WTogTmFOLFxyXG4gICAgICAgICAgICAgICAgbGFzdFc6IE5hTixcclxuICAgICAgICAgICAgICAgIGxhc3RIOiBOYU4sXHJcbiAgICAgICAgICAgICAgICBzdHlsZToge30sXHJcbiAgICAgICAgICAgICAgICBydGw6IGZhbHNlLFxyXG5cclxuICAgICAgICAgICAgICAgIGRyYWdFdmVudFNldDogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICByZXNpemVFdmVudFNldDogZmFsc2UsXHJcblxyXG4gICAgICAgICAgICAgICAgcHJldmlvdXNXOiBudWxsLFxyXG4gICAgICAgICAgICAgICAgcHJldmlvdXNIOiBudWxsLFxyXG4gICAgICAgICAgICAgICAgcHJldmlvdXNYOiBudWxsLFxyXG4gICAgICAgICAgICAgICAgcHJldmlvdXNZOiBudWxsLFxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuICAgICAgICBjcmVhdGVkICgpIHtcclxuICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgICAgICAgICAgLy8gQWNjZXNzaWJsZSByZWZlcm5jZXMgb2YgZnVuY3Rpb25zIGZvciByZW1vdmluZyBpbiBiZWZvcmVEZXN0cm95XHJcbiAgICAgICAgICAgIHNlbGYudXBkYXRlV2lkdGhIYW5kbGVyID0gZnVuY3Rpb24gKHdpZHRoKSB7XHJcbiAgICAgICAgICAgICAgICBzZWxmLnVwZGF0ZVdpZHRoKHdpZHRoKTtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIHNlbGYuY29tcGFjdEhhbmRsZXIgPSBmdW5jdGlvbiAobGF5b3V0KSB7XHJcbiAgICAgICAgICAgICAgICBzZWxmLmNvbXBhY3QobGF5b3V0KTtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIHNlbGYuc2V0RHJhZ2dhYmxlSGFuZGxlciA9IGZ1bmN0aW9uIChpc0RyYWdnYWJsZSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHNlbGYuaXNEcmFnZ2FibGUgPT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmLmRyYWdnYWJsZSA9IGlzRHJhZ2dhYmxlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgc2VsZi5zZXRSZXNpemFibGVIYW5kbGVyID0gZnVuY3Rpb24gKGlzUmVzaXphYmxlKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoc2VsZi5pc1Jlc2l6YWJsZSA9PT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYucmVzaXphYmxlID0gaXNSZXNpemFibGU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBzZWxmLnNldFJvd0hlaWdodEhhbmRsZXIgPSBmdW5jdGlvbiAocm93SGVpZ2h0KSB7XHJcbiAgICAgICAgICAgICAgICBzZWxmLnJvd0hlaWdodCA9IHJvd0hlaWdodDtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIHNlbGYuZGlyZWN0aW9uY2hhbmdlSGFuZGxlciA9IChkaXJlY3Rpb24pID0+IHtcclxuICAgICAgICAgICAgICAgIHZhciBkaXJlY3Rpb24gPSAoZG9jdW1lbnQuZGlyICE9PSB1bmRlZmluZWQpID9cclxuICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5kaXIgOlxyXG4gICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiaHRtbFwiKVswXS5nZXRBdHRyaWJ1dGUoXCJkaXJcIik7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnJ0bCA9IChkaXJlY3Rpb24gPT09IFwicnRsXCIpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jb21wYWN0KCk7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRvbigndXBkYXRlV2lkdGgnLCBzZWxmLnVwZGF0ZVdpZHRoSGFuZGxlcik7XHJcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9uKCdjb21wYWN0Jywgc2VsZi5jb21wYWN0SGFuZGxlcik7XHJcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9uKCdzZXREcmFnZ2FibGUnLCBzZWxmLnNldERyYWdnYWJsZUhhbmRsZXIpO1xyXG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRvbignc2V0UmVzaXphYmxlJywgc2VsZi5zZXRSZXNpemFibGVIYW5kbGVyKTtcclxuICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kb24oJ3NldFJvd0hlaWdodCcsIHNlbGYuc2V0Um93SGVpZ2h0SGFuZGxlcik7XHJcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9uKCdkaXJlY3Rpb25jaGFuZ2UnLCBzZWxmLmRpcmVjdGlvbmNoYW5nZUhhbmRsZXIpO1xyXG5cclxuICAgICAgICAgICAgLyp0aGlzLmV2ZW50QnVzLiRvbignc2V0Q29sTnVtJywgZnVuY3Rpb24oY29sTnVtKSB7XHJcbiAgICAgICAgICAgICBzZWxmLmNvbHMgPSBjb2xOdW07XHJcbiAgICAgICAgICAgICB9KTsqL1xyXG4gICAgICAgICAgICB2YXIgZGlyZWN0aW9uID0gKGRvY3VtZW50LmRpciAhPT0gdW5kZWZpbmVkKSA/XHJcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5kaXIgOlxyXG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJodG1sXCIpWzBdLmdldEF0dHJpYnV0ZShcImRpclwiKTtcclxuICAgICAgICAgICAgdGhpcy5ydGwgPSAoZGlyZWN0aW9uID09PSBcInJ0bFwiKTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIGJlZm9yZURlc3Ryb3k6IGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICAgICAgLy9SZW1vdmUgbGlzdGVuZXJzXHJcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9mZigndXBkYXRlV2lkdGgnLCBzZWxmLnVwZGF0ZVdpZHRoSGFuZGxlcik7XHJcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9mZignY29tcGFjdCcsIHNlbGYuY29tcGFjdEhhbmRsZXIpO1xyXG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRvZmYoJ3NldERyYWdnYWJsZScsIHNlbGYuc2V0RHJhZ2dhYmxlSGFuZGxlcik7XHJcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9mZignc2V0UmVzaXphYmxlJywgc2VsZi5zZXRSZXNpemFibGVIYW5kbGVyKTtcclxuICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kb2ZmKCdzZXRSb3dIZWlnaHQnLCBzZWxmLnNldFJvd0hlaWdodEhhbmRsZXIpO1xyXG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRvZmYoJ2RpcmVjdGlvbmNoYW5nZScsIHNlbGYuZGlyZWN0aW9uY2hhbmdlSGFuZGxlcik7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBtb3VudGVkOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY29scyA9IHRoaXMuJHBhcmVudC5jb2xOdW07XHJcbiAgICAgICAgICAgIHRoaXMucm93SGVpZ2h0ID0gdGhpcy4kcGFyZW50LnJvd0hlaWdodDtcclxuICAgICAgICAgICAgdGhpcy5jb250YWluZXJXaWR0aCA9IHRoaXMuJHBhcmVudC53aWR0aCAhPT0gbnVsbCA/IHRoaXMuJHBhcmVudC53aWR0aCA6IDEwMDtcclxuICAgICAgICAgICAgdGhpcy5tYXJnaW4gPSB0aGlzLiRwYXJlbnQubWFyZ2luICE9PSB1bmRlZmluZWQgPyB0aGlzLiRwYXJlbnQubWFyZ2luIDogWzEwLCAxMF07XHJcbiAgICAgICAgICAgIHRoaXMubWF4Um93cyA9IHRoaXMuJHBhcmVudC5tYXhSb3dzO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5pc0RyYWdnYWJsZSA9PT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5kcmFnZ2FibGUgPSB0aGlzLiRwYXJlbnQuaXNEcmFnZ2FibGU7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmRyYWdnYWJsZSA9IHRoaXMuaXNEcmFnZ2FibGU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHRoaXMuaXNSZXNpemFibGUgPT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucmVzaXphYmxlID0gdGhpcy4kcGFyZW50LmlzUmVzaXphYmxlO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5yZXNpemFibGUgPSB0aGlzLmlzUmVzaXphYmxlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMudXNlQ3NzVHJhbnNmb3JtcyA9IHRoaXMuJHBhcmVudC51c2VDc3NUcmFuc2Zvcm1zO1xyXG4gICAgICAgICAgICB0aGlzLmNyZWF0ZVN0eWxlKCk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICB3YXRjaDoge1xyXG4gICAgICAgICAgICBpc0RyYWdnYWJsZTogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5kcmFnZ2FibGUgPSB0aGlzLmlzRHJhZ2dhYmxlO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBkcmFnZ2FibGU6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmludGVyYWN0T2JqID09PSBudWxsIHx8IHRoaXMuaW50ZXJhY3RPYmogPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaW50ZXJhY3RPYmogPSBpbnRlcmFjdCh0aGlzLiRyZWZzLml0ZW0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZHJhZ2dhYmxlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG9wdHMgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlnbm9yZUZyb206IHRoaXMuZHJhZ0lnbm9yZUZyb20sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFsbG93RnJvbTogdGhpcy5kcmFnQWxsb3dGcm9tXHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaW50ZXJhY3RPYmouZHJhZ2dhYmxlKG9wdHMpO1xyXG4gICAgICAgICAgICAgICAgICAgIC8qdGhpcy5pbnRlcmFjdE9iai5kcmFnZ2FibGUoe2FsbG93RnJvbTogJy52dWUtZHJhZ2dhYmxlLWhhbmRsZSd9KTsqL1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5kcmFnRXZlbnRTZXQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kcmFnRXZlbnRTZXQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmludGVyYWN0T2JqLm9uKCdkcmFnc3RhcnQgZHJhZ21vdmUgZHJhZ2VuZCcsIGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5oYW5kbGVEcmFnKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmludGVyYWN0T2JqLmRyYWdnYWJsZSh7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVuYWJsZWQ6IGZhbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGlzUmVzaXphYmxlOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnJlc2l6YWJsZSA9IHRoaXMuaXNSZXNpemFibGU7XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHJlc2l6YWJsZTogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaW50ZXJhY3RPYmogPT09IG51bGwgfHwgdGhpcy5pbnRlcmFjdE9iaiA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnRlcmFjdE9iaiA9IGludGVyYWN0KHRoaXMuJHJlZnMuaXRlbSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5yZXNpemFibGUpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgb3B0cyA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcHJlc2VydmVBc3BlY3RSYXRpbzogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVkZ2VzOiB7bGVmdDogZmFsc2UsIHJpZ2h0OiB0cnVlLCBib3R0b206IHRydWUsIHRvcDogZmFsc2V9LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZ25vcmVGcm9tOiB0aGlzLnJlc2l6ZUlnbm9yZUZyb21cclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaW50ZXJhY3RPYmoucmVzaXphYmxlKG9wdHMpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5yZXNpemVFdmVudFNldCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc2l6ZUV2ZW50U2V0ID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnRlcmFjdE9ialxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLm9uKCdyZXNpemVzdGFydCByZXNpemVtb3ZlIHJlc2l6ZWVuZCcsIGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuaGFuZGxlUmVzaXplKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnRlcmFjdE9iai5yZXNpemFibGUoe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbmFibGVkOiBmYWxzZVxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICByb3dIZWlnaHQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRlU3R5bGUoKTtcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgY29sczogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVTdHlsZSgpO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBjb250YWluZXJXaWR0aDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVTdHlsZSgpO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICB4OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVN0eWxlKCk7XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHk6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRlU3R5bGUoKTtcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgaDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVTdHlsZSgpO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICB3OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVN0eWxlKCk7XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHJlbmRlclJ0bDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVTdHlsZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuICAgICAgICBjb21wdXRlZDoge1xyXG4gICAgICAgICAgICByZW5kZXJSdGwoKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gKHRoaXMuJHBhcmVudC5pc01pcnJvcmVkKSA/ICF0aGlzLnJ0bCA6IHRoaXMucnRsO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICByZXNpemFibGVIYW5kbGVDbGFzcygpIHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnJlbmRlclJ0bCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAndnVlLXJlc2l6YWJsZS1oYW5kbGUgdnVlLXJ0bC1yZXNpemFibGUtaGFuZGxlJztcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICd2dWUtcmVzaXphYmxlLWhhbmRsZSc7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG4gICAgICAgIG1ldGhvZHM6IHtcclxuICAgICAgICAgICAgY3JlYXRlU3R5bGU6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnggKyB0aGlzLncgPiB0aGlzLmNvbHMpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnggPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudyA9IHRoaXMuY29scztcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB2YXIgcG9zID0gdGhpcy5jYWxjUG9zaXRpb24odGhpcy54LCB0aGlzLnksIHRoaXMudywgdGhpcy5oKTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5pc0RyYWdnaW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcG9zLnRvcCA9IHRoaXMuZHJhZ2dpbmcudG9wO1xyXG4vLyAgICAgICAgICAgICAgICAgICAgQWRkIHJ0bCBzdXBwb3J0XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucmVuZGVyUnRsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBvcy5yaWdodCA9IHRoaXMuZHJhZ2dpbmcubGVmdDtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwb3MubGVmdCA9IHRoaXMuZHJhZ2dpbmcubGVmdDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5pc1Jlc2l6aW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcG9zLndpZHRoID0gdGhpcy5yZXNpemluZy53aWR0aDtcclxuICAgICAgICAgICAgICAgICAgICBwb3MuaGVpZ2h0ID0gdGhpcy5yZXNpemluZy5oZWlnaHQ7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgbGV0IHN0eWxlO1xyXG4gICAgICAgICAgICAgICAgLy8gQ1NTIFRyYW5zZm9ybXMgc3VwcG9ydCAoZGVmYXVsdClcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnVzZUNzc1RyYW5zZm9ybXMpIHtcclxuLy8gICAgICAgICAgICAgICAgICAgIEFkZCBydGwgc3VwcG9ydFxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnJlbmRlclJ0bCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZSA9IHNldFRyYW5zZm9ybVJ0bChwb3MudG9wLCBwb3MucmlnaHQsIHBvcy53aWR0aCwgcG9zLmhlaWdodCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGUgPSBzZXRUcmFuc2Zvcm0ocG9zLnRvcCwgcG9zLmxlZnQsIHBvcy53aWR0aCwgcG9zLmhlaWdodCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7IC8vIHRvcCxsZWZ0IChzbG93KVxyXG4vLyAgICAgICAgICAgICAgICAgICAgQWRkIHJ0bCBzdXBwb3J0XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucmVuZGVyUnRsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlID0gc2V0VG9wUmlnaHQocG9zLnRvcCwgcG9zLnJpZ2h0LCBwb3Mud2lkdGgsIHBvcy5oZWlnaHQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlID0gc2V0VG9wTGVmdChwb3MudG9wLCBwb3MubGVmdCwgcG9zLndpZHRoLCBwb3MuaGVpZ2h0KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aGlzLnN0eWxlID0gc3R5bGU7XHJcblxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBoYW5kbGVSZXNpemU6IGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcG9zaXRpb24gPSBnZXRDb250cm9sUG9zaXRpb24oZXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgLy8gR2V0IHRoZSBjdXJyZW50IGRyYWcgcG9pbnQgZnJvbSB0aGUgZXZlbnQuIFRoaXMgaXMgdXNlZCBhcyB0aGUgb2Zmc2V0LlxyXG4gICAgICAgICAgICAgICAgaWYgKHBvc2l0aW9uID09IG51bGwpIHJldHVybjsgLy8gbm90IHBvc3NpYmxlIGJ1dCBzYXRpc2ZpZXMgZmxvd1xyXG4gICAgICAgICAgICAgICAgY29uc3Qge3gsIHl9ID0gcG9zaXRpb247XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3QgbmV3U2l6ZSA9IHt3aWR0aDogMCwgaGVpZ2h0OiAwfTtcclxuICAgICAgICAgICAgICAgIHN3aXRjaCAoZXZlbnQudHlwZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJyZXNpemVzdGFydFwiOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnByZXZpb3VzVyA9IHRoaXMudztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcmV2aW91c0ggPSB0aGlzLmg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwb3MgPSB0aGlzLmNhbGNQb3NpdGlvbih0aGlzLngsIHRoaXMueSwgdGhpcy53LCB0aGlzLmgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdTaXplLndpZHRoID0gcG9zLndpZHRoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdTaXplLmhlaWdodCA9IHBvcy5oZWlnaHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVzaXppbmcgPSBuZXdTaXplO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzUmVzaXppbmcgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwicmVzaXplbW92ZVwiOlxyXG4vLyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiIyMjIHJlc2l6ZSA9PiBcIiArIGV2ZW50LnR5cGUgKyBcIiwgbGFzdFc9XCIgKyB0aGlzLmxhc3RXICsgXCIsIGxhc3RIPVwiICsgdGhpcy5sYXN0SCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvcmVFdmVudCA9IGNyZWF0ZUNvcmVEYXRhKHRoaXMubGFzdFcsIHRoaXMubGFzdEgsIHgsIHkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5yZW5kZXJSdGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1NpemUud2lkdGggPSB0aGlzLnJlc2l6aW5nLndpZHRoIC0gY29yZUV2ZW50LmRlbHRhWDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1NpemUud2lkdGggPSB0aGlzLnJlc2l6aW5nLndpZHRoICsgY29yZUV2ZW50LmRlbHRhWDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdTaXplLmhlaWdodCA9IHRoaXMucmVzaXppbmcuaGVpZ2h0ICsgY29yZUV2ZW50LmRlbHRhWTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vL2NvbnNvbGUubG9nKFwiIyMjIHJlc2l6ZSA9PiBcIiArIGV2ZW50LnR5cGUgKyBcIiwgZGVsdGFYPVwiICsgY29yZUV2ZW50LmRlbHRhWCArIFwiLCBkZWx0YVk9XCIgKyBjb3JlRXZlbnQuZGVsdGFZKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZXNpemluZyA9IG5ld1NpemU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJyZXNpemVlbmRcIjpcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9jb25zb2xlLmxvZyhcIiMjIyByZXNpemUgZW5kID0+IHg9XCIgK3RoaXMueCArIFwiIHk9XCIgKyB0aGlzLnkgKyBcIiB3PVwiICsgdGhpcy53ICsgXCIgaD1cIiArIHRoaXMuaCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwb3MgPSB0aGlzLmNhbGNQb3NpdGlvbih0aGlzLngsIHRoaXMueSwgdGhpcy53LCB0aGlzLmgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdTaXplLndpZHRoID0gcG9zLndpZHRoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdTaXplLmhlaWdodCA9IHBvcy5oZWlnaHQ7XHJcbi8vICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCIjIyMgcmVzaXplIGVuZCA9PiBcIiArIEpTT04uc3RyaW5naWZ5KG5ld1NpemUpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZXNpemluZyA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNSZXNpemluZyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvLyBHZXQgbmV3IFdIXHJcbiAgICAgICAgICAgICAgICB2YXIgcG9zID0gdGhpcy5jYWxjV0gobmV3U2l6ZS5oZWlnaHQsIG5ld1NpemUud2lkdGgpO1xyXG4gICAgICAgICAgICAgICAgaWYgKHBvcy53IDwgdGhpcy5taW5XKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcG9zLncgPSB0aGlzLm1pblc7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAocG9zLncgPiB0aGlzLm1heFcpIHtcclxuICAgICAgICAgICAgICAgICAgICBwb3MudyA9IHRoaXMubWF4VztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChwb3MuaCA8IHRoaXMubWluSCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHBvcy5oID0gdGhpcy5taW5IO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKHBvcy5oID4gdGhpcy5tYXhIKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcG9zLmggPSB0aGlzLm1heEg7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHBvcy5oIDwgMSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHBvcy5oID0gMTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChwb3MudyA8IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICBwb3MudyA9IDE7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgdGhpcy5sYXN0VyA9IHg7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmxhc3RIID0geTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy53ICE9PSBwb3MudyB8fCB0aGlzLmggIT09IHBvcy5oKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy4kZW1pdChcInJlc2l6ZVwiLCB0aGlzLmksIHBvcy5oLCBwb3Mudyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnQudHlwZSA9PT0gXCJyZXNpemVlbmRcIiAmJiAodGhpcy5wcmV2aW91c1cgIT09IHRoaXMudyB8fCB0aGlzLnByZXZpb3VzSCAhPT0gdGhpcy5oKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuJGVtaXQoXCJyZXNpemVkXCIsIHRoaXMuaSwgcG9zLmgsIHBvcy53LCBuZXdTaXplLmhlaWdodCwgbmV3U2l6ZS53aWR0aCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRlbWl0KFwicmVzaXplRXZlbnRcIiwgZXZlbnQudHlwZSwgdGhpcy5pLCB0aGlzLngsIHRoaXMueSwgcG9zLmgsIHBvcy53KTtcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgaGFuZGxlRHJhZyhldmVudCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNSZXNpemluZykgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9uID0gZ2V0Q29udHJvbFBvc2l0aW9uKGV2ZW50KTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBHZXQgdGhlIGN1cnJlbnQgZHJhZyBwb2ludCBmcm9tIHRoZSBldmVudC4gVGhpcyBpcyB1c2VkIGFzIHRoZSBvZmZzZXQuXHJcbiAgICAgICAgICAgICAgICBpZiAocG9zaXRpb24gPT09IG51bGwpIHJldHVybjsgLy8gbm90IHBvc3NpYmxlIGJ1dCBzYXRpc2ZpZXMgZmxvd1xyXG4gICAgICAgICAgICAgICAgY29uc3Qge3gsIHl9ID0gcG9zaXRpb247XHJcblxyXG4gICAgICAgICAgICAgICAgdmFyIHNob3VsZFVwZGF0ZSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbmV3UG9zaXRpb24gPSB7dG9wOiAwLCBsZWZ0OiAwfTtcclxuICAgICAgICAgICAgICAgIHN3aXRjaCAoZXZlbnQudHlwZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJkcmFnc3RhcnRcIjpcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcmV2aW91c1ggPSB0aGlzLng7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJldmlvdXNZID0gdGhpcy55O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBhcmVudFJlY3QgPSBldmVudC50YXJnZXQub2Zmc2V0UGFyZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2xpZW50UmVjdCA9IGV2ZW50LnRhcmdldC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucmVuZGVyUnRsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdQb3NpdGlvbi5sZWZ0ID0gKGNsaWVudFJlY3QucmlnaHQgLSBwYXJlbnRSZWN0LnJpZ2h0KSAqIC0xO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3UG9zaXRpb24ubGVmdCA9IGNsaWVudFJlY3QubGVmdCAtIHBhcmVudFJlY3QubGVmdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdQb3NpdGlvbi50b3AgPSBjbGllbnRSZWN0LnRvcCAtIHBhcmVudFJlY3QudG9wO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRyYWdnaW5nID0gbmV3UG9zaXRpb247XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNEcmFnZ2luZyA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJkcmFnZW5kXCI6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5pc0RyYWdnaW5nKSByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudFJlY3QgPSBldmVudC50YXJnZXQub2Zmc2V0UGFyZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGllbnRSZWN0ID0gZXZlbnQudGFyZ2V0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4vLyAgICAgICAgICAgICAgICAgICAgICAgIEFkZCBydGwgc3VwcG9ydFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5yZW5kZXJSdGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1Bvc2l0aW9uLmxlZnQgPSAoY2xpZW50UmVjdC5yaWdodCAtIHBhcmVudFJlY3QucmlnaHQpICogLTE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdQb3NpdGlvbi5sZWZ0ID0gY2xpZW50UmVjdC5sZWZ0IC0gcGFyZW50UmVjdC5sZWZ0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1Bvc2l0aW9uLnRvcCA9IGNsaWVudFJlY3QudG9wIC0gcGFyZW50UmVjdC50b3A7XHJcbi8vICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCIjIyMgZHJhZyBlbmQgPT4gXCIgKyBKU09OLnN0cmluZ2lmeShuZXdQb3NpdGlvbikpO1xyXG4vLyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiIyMjIERST1A6IFwiICsgSlNPTi5zdHJpbmdpZnkobmV3UG9zaXRpb24pKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kcmFnZ2luZyA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNEcmFnZ2luZyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzaG91bGRVcGRhdGUgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiZHJhZ21vdmVcIjpcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY29yZUV2ZW50ID0gY3JlYXRlQ29yZURhdGEodGhpcy5sYXN0WCwgdGhpcy5sYXN0WSwgeCwgeSk7XHJcbi8vICAgICAgICAgICAgICAgICAgICAgICAgQWRkIHJ0bCBzdXBwb3J0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnJlbmRlclJ0bCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3UG9zaXRpb24ubGVmdCA9IHRoaXMuZHJhZ2dpbmcubGVmdCAtIGNvcmVFdmVudC5kZWx0YVg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdQb3NpdGlvbi5sZWZ0ID0gdGhpcy5kcmFnZ2luZy5sZWZ0ICsgY29yZUV2ZW50LmRlbHRhWDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdQb3NpdGlvbi50b3AgPSB0aGlzLmRyYWdnaW5nLnRvcCArIGNvcmVFdmVudC5kZWx0YVk7XHJcbi8vICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCIjIyMgZHJhZyA9PiBcIiArIGV2ZW50LnR5cGUgKyBcIiwgeD1cIiArIHggKyBcIiwgeT1cIiArIHkpO1xyXG4vLyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiIyMjIGRyYWcgPT4gXCIgKyBldmVudC50eXBlICsgXCIsIGRlbHRhWD1cIiArIGNvcmVFdmVudC5kZWx0YVggKyBcIiwgZGVsdGFZPVwiICsgY29yZUV2ZW50LmRlbHRhWSk7XHJcbi8vICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCIjIyMgZHJhZyBlbmQgPT4gXCIgKyBKU09OLnN0cmluZ2lmeShuZXdQb3NpdGlvbikpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRyYWdnaW5nID0gbmV3UG9zaXRpb247XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8vIEdldCBuZXcgWFlcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnJlbmRlclJ0bCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwb3MgPSB0aGlzLmNhbGNYWShuZXdQb3NpdGlvbi50b3AsIG5ld1Bvc2l0aW9uLmxlZnQpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcG9zID0gdGhpcy5jYWxjWFkobmV3UG9zaXRpb24udG9wLCBuZXdQb3NpdGlvbi5sZWZ0KTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLmxhc3RYID0geDtcclxuICAgICAgICAgICAgICAgIHRoaXMubGFzdFkgPSB5O1xyXG5cclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnggIT09IHBvcy54IHx8IHRoaXMueSAhPT0gcG9zLnkpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbWl0KFwibW92ZVwiLCB0aGlzLmksIHBvcy54LCBwb3MueSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnQudHlwZSA9PT0gXCJkcmFnZW5kXCIgJiYgKHRoaXMucHJldmlvdXNYICE9PSB0aGlzLnggfHwgdGhpcy5wcmV2aW91c1kgIT09IHRoaXMueSkpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbWl0KFwibW92ZWRcIiwgdGhpcy5pLCBwb3MueCwgcG9zLnkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kZW1pdChcImRyYWdFdmVudFwiLCBldmVudC50eXBlLCB0aGlzLmksIHBvcy54LCBwb3MueSwgdGhpcy5oLCB0aGlzLncpO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBjYWxjUG9zaXRpb246IGZ1bmN0aW9uICh4LCB5LCB3LCBoKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBjb2xXaWR0aCA9IHRoaXMuY2FsY0NvbFdpZHRoKCk7XHJcbiAgICAgICAgICAgICAgICAvLyBhZGQgcnRsIHN1cHBvcnRcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnJlbmRlclJ0bCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBvdXQgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJpZ2h0OiBNYXRoLnJvdW5kKGNvbFdpZHRoICogeCArICh4ICsgMSkgKiB0aGlzLm1hcmdpblswXSksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvcDogTWF0aC5yb3VuZCh0aGlzLnJvd0hlaWdodCAqIHkgKyAoeSArIDEpICogdGhpcy5tYXJnaW5bMV0pLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyAwICogSW5maW5pdHkgPT09IE5hTiwgd2hpY2ggY2F1c2VzIHByb2JsZW1zIHdpdGggcmVzaXplIGNvbnN0cmlhbnRzO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBGaXggdGhpcyBpZiBpdCBvY2N1cnMuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5vdGUgd2UgZG8gaXQgaGVyZSByYXRoZXIgdGhhbiBsYXRlciBiZWNhdXNlIE1hdGgucm91bmQoSW5maW5pdHkpIGNhdXNlcyBkZW9wdFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogdyA9PT0gSW5maW5pdHkgPyB3IDogTWF0aC5yb3VuZChjb2xXaWR0aCAqIHcgKyBNYXRoLm1heCgwLCB3IC0gMSkgKiB0aGlzLm1hcmdpblswXSksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodDogaCA9PT0gSW5maW5pdHkgPyBoIDogTWF0aC5yb3VuZCh0aGlzLnJvd0hlaWdodCAqIGggKyBNYXRoLm1heCgwLCBoIC0gMSkgKiB0aGlzLm1hcmdpblsxXSlcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgb3V0ID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZWZ0OiBNYXRoLnJvdW5kKGNvbFdpZHRoICogeCArICh4ICsgMSkgKiB0aGlzLm1hcmdpblswXSksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvcDogTWF0aC5yb3VuZCh0aGlzLnJvd0hlaWdodCAqIHkgKyAoeSArIDEpICogdGhpcy5tYXJnaW5bMV0pLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyAwICogSW5maW5pdHkgPT09IE5hTiwgd2hpY2ggY2F1c2VzIHByb2JsZW1zIHdpdGggcmVzaXplIGNvbnN0cmlhbnRzO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBGaXggdGhpcyBpZiBpdCBvY2N1cnMuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5vdGUgd2UgZG8gaXQgaGVyZSByYXRoZXIgdGhhbiBsYXRlciBiZWNhdXNlIE1hdGgucm91bmQoSW5maW5pdHkpIGNhdXNlcyBkZW9wdFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogdyA9PT0gSW5maW5pdHkgPyB3IDogTWF0aC5yb3VuZChjb2xXaWR0aCAqIHcgKyBNYXRoLm1heCgwLCB3IC0gMSkgKiB0aGlzLm1hcmdpblswXSksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodDogaCA9PT0gSW5maW5pdHkgPyBoIDogTWF0aC5yb3VuZCh0aGlzLnJvd0hlaWdodCAqIGggKyBNYXRoLm1heCgwLCBoIC0gMSkgKiB0aGlzLm1hcmdpblsxXSlcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gb3V0O1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogVHJhbnNsYXRlIHggYW5kIHkgY29vcmRpbmF0ZXMgZnJvbSBwaXhlbHMgdG8gZ3JpZCB1bml0cy5cclxuICAgICAgICAgICAgICogQHBhcmFtICB7TnVtYmVyfSB0b3AgIFRvcCBwb3NpdGlvbiAocmVsYXRpdmUgdG8gcGFyZW50KSBpbiBwaXhlbHMuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSAge051bWJlcn0gbGVmdCBMZWZ0IHBvc2l0aW9uIChyZWxhdGl2ZSB0byBwYXJlbnQpIGluIHBpeGVscy5cclxuICAgICAgICAgICAgICogQHJldHVybiB7T2JqZWN0fSB4IGFuZCB5IGluIGdyaWQgdW5pdHMuXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAvLyBUT0RPIGNoZWNrIGlmIHRoaXMgZnVuY3Rpb24gbmVlZHMgY2hhbmdlIGluIG9yZGVyIHRvIHN1cHBvcnQgcnRsLlxyXG4gICAgICAgICAgICBjYWxjWFkodG9wLCBsZWZ0KSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBjb2xXaWR0aCA9IHRoaXMuY2FsY0NvbFdpZHRoKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gbGVmdCA9IGNvbFdpZHRoICogeCArIG1hcmdpbiAqICh4ICsgMSlcclxuICAgICAgICAgICAgICAgIC8vIGwgPSBjeCArIG0oeCsxKVxyXG4gICAgICAgICAgICAgICAgLy8gbCA9IGN4ICsgbXggKyBtXHJcbiAgICAgICAgICAgICAgICAvLyBsIC0gbSA9IGN4ICsgbXhcclxuICAgICAgICAgICAgICAgIC8vIGwgLSBtID0geChjICsgbSlcclxuICAgICAgICAgICAgICAgIC8vIChsIC0gbSkgLyAoYyArIG0pID0geFxyXG4gICAgICAgICAgICAgICAgLy8geCA9IChsZWZ0IC0gbWFyZ2luKSAvIChjb2xkV2lkdGggKyBtYXJnaW4pXHJcbiAgICAgICAgICAgICAgICBsZXQgeCA9IE1hdGgucm91bmQoKGxlZnQgLSB0aGlzLm1hcmdpblswXSkgLyAoY29sV2lkdGggKyB0aGlzLm1hcmdpblswXSkpO1xyXG4gICAgICAgICAgICAgICAgbGV0IHkgPSBNYXRoLnJvdW5kKCh0b3AgLSB0aGlzLm1hcmdpblsxXSkgLyAodGhpcy5yb3dIZWlnaHQgKyB0aGlzLm1hcmdpblsxXSkpO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIENhcHBpbmdcclxuICAgICAgICAgICAgICAgIHggPSBNYXRoLm1heChNYXRoLm1pbih4LCB0aGlzLmNvbHMgLSB0aGlzLncpLCAwKTtcclxuICAgICAgICAgICAgICAgIHkgPSBNYXRoLm1heChNYXRoLm1pbih5LCB0aGlzLm1heFJvd3MgLSB0aGlzLmgpLCAwKTtcclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4ge3gsIHl9O1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAvLyBIZWxwZXIgZm9yIGdlbmVyYXRpbmcgY29sdW1uIHdpZHRoXHJcbiAgICAgICAgICAgIGNhbGNDb2xXaWR0aCgpIHtcclxuICAgICAgICAgICAgICAgIHZhciBjb2xXaWR0aCA9ICh0aGlzLmNvbnRhaW5lcldpZHRoIC0gKHRoaXMubWFyZ2luWzBdICogKHRoaXMuY29scyArIDEpKSkgLyB0aGlzLmNvbHM7XHJcbi8vICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiIyMjIENPTFM9XCIgKyB0aGlzLmNvbHMgKyBcIiBDT0wgV0lEVEg9XCIgKyBjb2xXaWR0aCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gY29sV2lkdGg7XHJcbiAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogR2l2ZW4gYSBoZWlnaHQgYW5kIHdpZHRoIGluIHBpeGVsIHZhbHVlcywgY2FsY3VsYXRlIGdyaWQgdW5pdHMuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSAge051bWJlcn0gaGVpZ2h0IEhlaWdodCBpbiBwaXhlbHMuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSAge051bWJlcn0gd2lkdGggIFdpZHRoIGluIHBpeGVscy5cclxuICAgICAgICAgICAgICogQHJldHVybiB7T2JqZWN0fSB3LCBoIGFzIGdyaWQgdW5pdHMuXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBjYWxjV0goaGVpZ2h0LCB3aWR0aCkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgY29sV2lkdGggPSB0aGlzLmNhbGNDb2xXaWR0aCgpO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIHdpZHRoID0gY29sV2lkdGggKiB3IC0gKG1hcmdpbiAqICh3IC0gMSkpXHJcbiAgICAgICAgICAgICAgICAvLyAuLi5cclxuICAgICAgICAgICAgICAgIC8vIHcgPSAod2lkdGggKyBtYXJnaW4pIC8gKGNvbFdpZHRoICsgbWFyZ2luKVxyXG4gICAgICAgICAgICAgICAgbGV0IHcgPSBNYXRoLnJvdW5kKCh3aWR0aCArIHRoaXMubWFyZ2luWzBdKSAvIChjb2xXaWR0aCArIHRoaXMubWFyZ2luWzBdKSk7XHJcbiAgICAgICAgICAgICAgICBsZXQgaCA9IE1hdGgucm91bmQoKGhlaWdodCArIHRoaXMubWFyZ2luWzFdKSAvICh0aGlzLnJvd0hlaWdodCArIHRoaXMubWFyZ2luWzFdKSk7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gQ2FwcGluZ1xyXG4gICAgICAgICAgICAgICAgdyA9IE1hdGgubWF4KE1hdGgubWluKHcsIHRoaXMuY29scyAtIHRoaXMueCksIDApO1xyXG4gICAgICAgICAgICAgICAgaCA9IE1hdGgubWF4KE1hdGgubWluKGgsIHRoaXMubWF4Um93cyAtIHRoaXMueSksIDApO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHt3LCBofTtcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgdXBkYXRlV2lkdGg6IGZ1bmN0aW9uICh3aWR0aCwgY29sTnVtKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnRhaW5lcldpZHRoID0gd2lkdGg7XHJcbiAgICAgICAgICAgICAgICBpZiAoY29sTnVtICE9PSB1bmRlZmluZWQgJiYgY29sTnVtICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb2xzID0gY29sTnVtO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBjb21wYWN0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVN0eWxlKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG4gICAgfVxyXG48L3NjcmlwdD5cclxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIEdyaWRJdGVtLnZ1ZT9iYzNmMTFiNCJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///13\n"); - -/***/ }), -/* 14 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.getControlPosition = getControlPosition;\nexports.offsetXYFromParentOf = offsetXYFromParentOf;\nexports.createCoreData = createCoreData;\n// Get {x, y} positions from event.\nfunction getControlPosition(e) {\n return offsetXYFromParentOf(e);\n}\n\n// Get from offsetParent\nfunction offsetXYFromParentOf(evt) {\n var offsetParent = evt.target.offsetParent || document.body;\n var offsetParentRect = evt.offsetParent === document.body ? { left: 0, top: 0 } : offsetParent.getBoundingClientRect();\n\n var x = evt.clientX + offsetParent.scrollLeft - offsetParentRect.left;\n var y = evt.clientY + offsetParent.scrollTop - offsetParentRect.top;\n\n /*const x = Math.round(evt.clientX + offsetParent.scrollLeft - offsetParentRect.left);\r\n const y = Math.round(evt.clientY + offsetParent.scrollTop - offsetParentRect.top);*/\n\n return { x: x, y: y };\n}\n\n// Create an data object exposed by 's events\nfunction createCoreData(lastX, lastY, x, y) {\n // State changes are often (but not always!) async. We want the latest value.\n var isStart = !isNum(lastX);\n\n if (isStart) {\n // If this is our first move, use the x and y as last coords.\n return {\n deltaX: 0, deltaY: 0,\n lastX: x, lastY: y,\n x: x, y: y\n };\n } else {\n // Otherwise calculate proper values.\n return {\n deltaX: x - lastX, deltaY: y - lastY,\n lastX: lastX, lastY: lastY,\n x: x, y: y\n };\n }\n}\n\nfunction isNum(num) {\n return typeof num === 'number' && !isNaN(num);\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvZHJhZ2dhYmxlVXRpbHMuanM/YWQ2NyJdLCJuYW1lcyI6WyJnZXRDb250cm9sUG9zaXRpb24iLCJvZmZzZXRYWUZyb21QYXJlbnRPZiIsImNyZWF0ZUNvcmVEYXRhIiwiZSIsImV2dCIsIm9mZnNldFBhcmVudCIsInRhcmdldCIsImRvY3VtZW50IiwiYm9keSIsIm9mZnNldFBhcmVudFJlY3QiLCJsZWZ0IiwidG9wIiwiZ2V0Qm91bmRpbmdDbGllbnRSZWN0IiwieCIsImNsaWVudFgiLCJzY3JvbGxMZWZ0IiwieSIsImNsaWVudFkiLCJzY3JvbGxUb3AiLCJsYXN0WCIsImxhc3RZIiwiaXNTdGFydCIsImlzTnVtIiwiZGVsdGFYIiwiZGVsdGFZIiwibnVtIiwiaXNOYU4iXSwibWFwcGluZ3MiOiI7Ozs7O1FBQ2dCQSxrQixHQUFBQSxrQjtRQU1BQyxvQixHQUFBQSxvQjtRQWdCQUMsYyxHQUFBQSxjO0FBdkJoQjtBQUNPLFNBQVNGLGtCQUFULENBQTRCRyxDQUE1QixFQUErQjtBQUNsQyxXQUFPRixxQkFBcUJFLENBQXJCLENBQVA7QUFDSDs7QUFHRDtBQUNPLFNBQVNGLG9CQUFULENBQThCRyxHQUE5QixFQUFtQztBQUN0QyxRQUFNQyxlQUFlRCxJQUFJRSxNQUFKLENBQVdELFlBQVgsSUFBMkJFLFNBQVNDLElBQXpEO0FBQ0EsUUFBTUMsbUJBQW1CTCxJQUFJQyxZQUFKLEtBQXFCRSxTQUFTQyxJQUE5QixHQUFxQyxFQUFDRSxNQUFNLENBQVAsRUFBVUMsS0FBSyxDQUFmLEVBQXJDLEdBQXlETixhQUFhTyxxQkFBYixFQUFsRjs7QUFFQSxRQUFNQyxJQUFJVCxJQUFJVSxPQUFKLEdBQWNULGFBQWFVLFVBQTNCLEdBQXdDTixpQkFBaUJDLElBQW5FO0FBQ0EsUUFBTU0sSUFBSVosSUFBSWEsT0FBSixHQUFjWixhQUFhYSxTQUEzQixHQUF1Q1QsaUJBQWlCRSxHQUFsRTs7QUFFQTs7O0FBSUEsV0FBTyxFQUFDRSxJQUFELEVBQUlHLElBQUosRUFBUDtBQUNIOztBQUdEO0FBQ08sU0FBU2QsY0FBVCxDQUF3QmlCLEtBQXhCLEVBQStCQyxLQUEvQixFQUFzQ1AsQ0FBdEMsRUFBeUNHLENBQXpDLEVBQTRDO0FBQy9DO0FBQ0EsUUFBTUssVUFBVSxDQUFDQyxNQUFNSCxLQUFOLENBQWpCOztBQUVBLFFBQUlFLE9BQUosRUFBYTtBQUNUO0FBQ0EsZUFBTztBQUNIRSxvQkFBUSxDQURMLEVBQ1FDLFFBQVEsQ0FEaEI7QUFFSEwsbUJBQU9OLENBRkosRUFFT08sT0FBT0osQ0FGZDtBQUdISCxlQUFHQSxDQUhBLEVBR0dHLEdBQUdBO0FBSE4sU0FBUDtBQUtILEtBUEQsTUFPTztBQUNIO0FBQ0EsZUFBTztBQUNITyxvQkFBUVYsSUFBSU0sS0FEVCxFQUNnQkssUUFBUVIsSUFBSUksS0FENUI7QUFFSEQsbUJBQU9BLEtBRkosRUFFV0MsT0FBT0EsS0FGbEI7QUFHSFAsZUFBR0EsQ0FIQSxFQUdHRyxHQUFHQTtBQUhOLFNBQVA7QUFLSDtBQUNKOztBQUdELFNBQVNNLEtBQVQsQ0FBZUcsR0FBZixFQUFxQjtBQUNqQixXQUFPLE9BQU9BLEdBQVAsS0FBZSxRQUFmLElBQTJCLENBQUNDLE1BQU1ELEdBQU4sQ0FBbkM7QUFDSCIsImZpbGUiOiIxNC5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEdldCB7eCwgeX0gcG9zaXRpb25zIGZyb20gZXZlbnQuXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRDb250cm9sUG9zaXRpb24oZSkge1xyXG4gICAgcmV0dXJuIG9mZnNldFhZRnJvbVBhcmVudE9mKGUpO1xyXG59XHJcblxyXG5cclxuLy8gR2V0IGZyb20gb2Zmc2V0UGFyZW50XHJcbmV4cG9ydCBmdW5jdGlvbiBvZmZzZXRYWUZyb21QYXJlbnRPZihldnQpIHtcclxuICAgIGNvbnN0IG9mZnNldFBhcmVudCA9IGV2dC50YXJnZXQub2Zmc2V0UGFyZW50IHx8IGRvY3VtZW50LmJvZHk7XHJcbiAgICBjb25zdCBvZmZzZXRQYXJlbnRSZWN0ID0gZXZ0Lm9mZnNldFBhcmVudCA9PT0gZG9jdW1lbnQuYm9keSA/IHtsZWZ0OiAwLCB0b3A6IDB9IDogb2Zmc2V0UGFyZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG5cclxuICAgIGNvbnN0IHggPSBldnQuY2xpZW50WCArIG9mZnNldFBhcmVudC5zY3JvbGxMZWZ0IC0gb2Zmc2V0UGFyZW50UmVjdC5sZWZ0O1xyXG4gICAgY29uc3QgeSA9IGV2dC5jbGllbnRZICsgb2Zmc2V0UGFyZW50LnNjcm9sbFRvcCAtIG9mZnNldFBhcmVudFJlY3QudG9wO1xyXG5cclxuICAgIC8qY29uc3QgeCA9IE1hdGgucm91bmQoZXZ0LmNsaWVudFggKyBvZmZzZXRQYXJlbnQuc2Nyb2xsTGVmdCAtIG9mZnNldFBhcmVudFJlY3QubGVmdCk7XHJcbiAgICBjb25zdCB5ID0gTWF0aC5yb3VuZChldnQuY2xpZW50WSArIG9mZnNldFBhcmVudC5zY3JvbGxUb3AgLSBvZmZzZXRQYXJlbnRSZWN0LnRvcCk7Ki9cclxuXHJcblxyXG4gICAgcmV0dXJuIHt4LCB5fTtcclxufVxyXG5cclxuXHJcbi8vIENyZWF0ZSBhbiBkYXRhIG9iamVjdCBleHBvc2VkIGJ5IDxEcmFnZ2FibGVDb3JlPidzIGV2ZW50c1xyXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQ29yZURhdGEobGFzdFgsIGxhc3RZLCB4LCB5KSB7XHJcbiAgICAvLyBTdGF0ZSBjaGFuZ2VzIGFyZSBvZnRlbiAoYnV0IG5vdCBhbHdheXMhKSBhc3luYy4gV2Ugd2FudCB0aGUgbGF0ZXN0IHZhbHVlLlxyXG4gICAgY29uc3QgaXNTdGFydCA9ICFpc051bShsYXN0WCk7XHJcblxyXG4gICAgaWYgKGlzU3RhcnQpIHtcclxuICAgICAgICAvLyBJZiB0aGlzIGlzIG91ciBmaXJzdCBtb3ZlLCB1c2UgdGhlIHggYW5kIHkgYXMgbGFzdCBjb29yZHMuXHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgZGVsdGFYOiAwLCBkZWx0YVk6IDAsXHJcbiAgICAgICAgICAgIGxhc3RYOiB4LCBsYXN0WTogeSxcclxuICAgICAgICAgICAgeDogeCwgeTogeVxyXG4gICAgICAgIH07XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIC8vIE90aGVyd2lzZSBjYWxjdWxhdGUgcHJvcGVyIHZhbHVlcy5cclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBkZWx0YVg6IHggLSBsYXN0WCwgZGVsdGFZOiB5IC0gbGFzdFksXHJcbiAgICAgICAgICAgIGxhc3RYOiBsYXN0WCwgbGFzdFk6IGxhc3RZLFxyXG4gICAgICAgICAgICB4OiB4LCB5OiB5XHJcbiAgICAgICAgfTtcclxuICAgIH1cclxufVxyXG5cclxuXHJcbmZ1bmN0aW9uIGlzTnVtKG51bSkgIHtcclxuICAgIHJldHVybiB0eXBlb2YgbnVtID09PSAnbnVtYmVyJyAmJiAhaXNOYU4obnVtKTtcclxufVxyXG5cclxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc3JjL2RyYWdnYWJsZVV0aWxzLmpzIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///14\n"); - -/***/ }), -/* 15 */ -/***/ (function(module, exports, __webpack_require__) { - -eval("var require;var require;/**\r\n * interact.js v1.3.0-alpha.4+sha.7970416-dirty\r\n *\r\n * Copyright (c) 2012-2017 Taye Adeyemi \r\n * Open source under the MIT License.\r\n * https://raw.github.com/taye/interact.js/master/LICENSE\r\n */\r\n(function(f){if(true){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}g.interact = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return require(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o 6 && arguments[6] !== undefined ? arguments[6] : false;\r\n\r\n _classCallCheck(this, InteractEvent);\r\n\r\n var target = interaction.target;\r\n var deltaSource = (target && target.options || defaults).deltaSource;\r\n var origin = getOriginXY(target, element, action);\r\n var starting = phase === 'start';\r\n var ending = phase === 'end';\r\n var coords = starting ? interaction.startCoords : interaction.curCoords;\r\n var prevEvent = interaction.prevEvent;\r\n\r\n element = element || interaction.element;\r\n\r\n var page = extend({}, coords.page);\r\n var client = extend({}, coords.client);\r\n\r\n page.x -= origin.x;\r\n page.y -= origin.y;\r\n\r\n client.x -= origin.x;\r\n client.y -= origin.y;\r\n\r\n this.ctrlKey = event.ctrlKey;\r\n this.altKey = event.altKey;\r\n this.shiftKey = event.shiftKey;\r\n this.metaKey = event.metaKey;\r\n this.button = event.button;\r\n this.buttons = event.buttons;\r\n this.target = element;\r\n this.currentTarget = element;\r\n this.relatedTarget = related || null;\r\n this.preEnd = preEnd;\r\n this.type = action + (phase || '');\r\n this.interaction = interaction;\r\n this.interactable = target;\r\n\r\n this.t0 = starting ? interaction.downTimes[interaction.downTimes.length - 1] : prevEvent.t0;\r\n\r\n var signalArg = {\r\n interaction: interaction,\r\n event: event,\r\n action: action,\r\n phase: phase,\r\n element: element,\r\n related: related,\r\n page: page,\r\n client: client,\r\n coords: coords,\r\n starting: starting,\r\n ending: ending,\r\n deltaSource: deltaSource,\r\n iEvent: this\r\n };\r\n\r\n signals.fire('set-xy', signalArg);\r\n\r\n if (ending) {\r\n // use previous coords when ending\r\n this.pageX = prevEvent.pageX;\r\n this.pageY = prevEvent.pageY;\r\n this.clientX = prevEvent.clientX;\r\n this.clientY = prevEvent.clientY;\r\n } else {\r\n this.pageX = page.x;\r\n this.pageY = page.y;\r\n this.clientX = client.x;\r\n this.clientY = client.y;\r\n }\r\n\r\n this.x0 = interaction.startCoords.page.x - origin.x;\r\n this.y0 = interaction.startCoords.page.y - origin.y;\r\n this.clientX0 = interaction.startCoords.client.x - origin.x;\r\n this.clientY0 = interaction.startCoords.client.y - origin.y;\r\n\r\n signals.fire('set-delta', signalArg);\r\n\r\n this.timeStamp = coords.timeStamp;\r\n this.dt = interaction.pointerDelta.timeStamp;\r\n this.duration = this.timeStamp - this.t0;\r\n\r\n // speed and velocity in pixels per second\r\n this.speed = interaction.pointerDelta[deltaSource].speed;\r\n this.velocityX = interaction.pointerDelta[deltaSource].vx;\r\n this.velocityY = interaction.pointerDelta[deltaSource].vy;\r\n\r\n this.swipe = ending || phase === 'inertiastart' ? this.getSwipe() : null;\r\n\r\n signals.fire('new', signalArg);\r\n }\r\n\r\n InteractEvent.prototype.getSwipe = function getSwipe() {\r\n var interaction = this.interaction;\r\n\r\n if (interaction.prevEvent.speed < 600 || this.timeStamp - interaction.prevEvent.timeStamp > 150) {\r\n return null;\r\n }\r\n\r\n var angle = 180 * Math.atan2(interaction.prevEvent.velocityY, interaction.prevEvent.velocityX) / Math.PI;\r\n var overlap = 22.5;\r\n\r\n if (angle < 0) {\r\n angle += 360;\r\n }\r\n\r\n var left = 135 - overlap <= angle && angle < 225 + overlap;\r\n var up = 225 - overlap <= angle && angle < 315 + overlap;\r\n\r\n var right = !left && (315 - overlap <= angle || angle < 45 + overlap);\r\n var down = !up && 45 - overlap <= angle && angle < 135 + overlap;\r\n\r\n return {\r\n up: up,\r\n down: down,\r\n left: left,\r\n right: right,\r\n angle: angle,\r\n speed: interaction.prevEvent.speed,\r\n velocity: {\r\n x: interaction.prevEvent.velocityX,\r\n y: interaction.prevEvent.velocityY\r\n }\r\n };\r\n };\r\n\r\n InteractEvent.prototype.preventDefault = function preventDefault() {};\r\n\r\n InteractEvent.prototype.stopImmediatePropagation = function stopImmediatePropagation() {\r\n this.immediatePropagationStopped = this.propagationStopped = true;\r\n };\r\n\r\n InteractEvent.prototype.stopPropagation = function stopPropagation() {\r\n this.propagationStopped = true;\r\n };\r\n\r\n return InteractEvent;\r\n}();\r\n\r\nsignals.on('set-delta', function (_ref) {\r\n var iEvent = _ref.iEvent,\r\n interaction = _ref.interaction,\r\n starting = _ref.starting,\r\n deltaSource = _ref.deltaSource;\r\n\r\n var prevEvent = starting ? iEvent : interaction.prevEvent;\r\n\r\n if (deltaSource === 'client') {\r\n iEvent.dx = iEvent.clientX - prevEvent.clientX;\r\n iEvent.dy = iEvent.clientY - prevEvent.clientY;\r\n } else {\r\n iEvent.dx = iEvent.pageX - prevEvent.pageX;\r\n iEvent.dy = iEvent.pageY - prevEvent.pageY;\r\n }\r\n});\r\n\r\nInteractEvent.signals = signals;\r\n\r\nmodule.exports = InteractEvent;\r\n\r\n},{\"./defaultOptions\":18,\"./utils/Signals\":35,\"./utils/extend\":41,\"./utils/getOriginXY\":42}],4:[function(require,module,exports){\r\n'use strict';\r\n\r\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\r\n\r\nvar is = require('./utils/is');\r\nvar events = require('./utils/events');\r\nvar extend = require('./utils/extend');\r\nvar actions = require('./actions/base');\r\nvar scope = require('./scope');\r\nvar Eventable = require('./Eventable');\r\nvar defaults = require('./defaultOptions');\r\nvar signals = require('./utils/Signals').new();\r\n\r\nvar _require = require('./utils/domUtils'),\r\n getElementRect = _require.getElementRect,\r\n nodeContains = _require.nodeContains,\r\n trySelector = _require.trySelector;\r\n\r\nvar _require2 = require('./utils/window'),\r\n getWindow = _require2.getWindow;\r\n\r\nvar _require3 = require('./utils/arr'),\r\n indexOf = _require3.indexOf,\r\n contains = _require3.contains;\r\n\r\nvar _require4 = require('./utils/browser'),\r\n wheelEvent = _require4.wheelEvent;\r\n\r\n// all set interactables\r\n\r\n\r\nscope.interactables = [];\r\n\r\n/*\\\r\n * Interactable\r\n [ property ]\r\n **\r\n * Object type returned by @interact\r\n\\*/\r\n\r\nvar Interactable = function () {\r\n function Interactable(target, options) {\r\n _classCallCheck(this, Interactable);\r\n\r\n options = options || {};\r\n\r\n this.target = target;\r\n this.events = new Eventable();\r\n this._context = options.context || scope.document;\r\n this._win = getWindow(trySelector(target) ? this._context : target);\r\n this._doc = this._win.document;\r\n\r\n signals.fire('new', {\r\n target: target,\r\n options: options,\r\n interactable: this,\r\n win: this._win\r\n });\r\n\r\n scope.addDocument(this._doc, this._win);\r\n\r\n scope.interactables.push(this);\r\n\r\n this.set(options);\r\n }\r\n\r\n Interactable.prototype.setOnEvents = function setOnEvents(action, phases) {\r\n var onAction = 'on' + action;\r\n\r\n if (is.function(phases.onstart)) {\r\n this.events[onAction + 'start'] = phases.onstart;\r\n }\r\n if (is.function(phases.onmove)) {\r\n this.events[onAction + 'move'] = phases.onmove;\r\n }\r\n if (is.function(phases.onend)) {\r\n this.events[onAction + 'end'] = phases.onend;\r\n }\r\n if (is.function(phases.oninertiastart)) {\r\n this.events[onAction + 'inertiastart'] = phases.oninertiastart;\r\n }\r\n\r\n return this;\r\n };\r\n\r\n Interactable.prototype.setPerAction = function setPerAction(action, options) {\r\n // for all the default per-action options\r\n for (var option in options) {\r\n // if this option exists for this action\r\n if (option in defaults[action]) {\r\n // if the option in the options arg is an object value\r\n if (is.object(options[option])) {\r\n // duplicate the object\r\n this.options[action][option] = extend(this.options[action][option] || {}, options[option]);\r\n\r\n if (is.object(defaults.perAction[option]) && 'enabled' in defaults.perAction[option]) {\r\n this.options[action][option].enabled = options[option].enabled === false ? false : true;\r\n }\r\n } else if (is.bool(options[option]) && is.object(defaults.perAction[option])) {\r\n this.options[action][option].enabled = options[option];\r\n } else if (options[option] !== undefined) {\r\n // or if it's not undefined, do a plain assignment\r\n this.options[action][option] = options[option];\r\n }\r\n }\r\n }\r\n };\r\n\r\n /*\\\r\n * Interactable.getRect\r\n [ method ]\r\n *\r\n * The default function to get an Interactables bounding rect. Can be\r\n * overridden using @Interactable.rectChecker.\r\n *\r\n - element (Element) #optional The element to measure.\r\n = (object) The object's bounding rectangle.\r\n o {\r\n o top : 0,\r\n o left : 0,\r\n o bottom: 0,\r\n o right : 0,\r\n o width : 0,\r\n o height: 0\r\n o }\r\n \\*/\r\n\r\n\r\n Interactable.prototype.getRect = function getRect(element) {\r\n element = element || this.target;\r\n\r\n if (is.string(this.target) && !is.element(element)) {\r\n element = this._context.querySelector(this.target);\r\n }\r\n\r\n return getElementRect(element);\r\n };\r\n\r\n /*\\\r\n * Interactable.rectChecker\r\n [ method ]\r\n *\r\n * Returns or sets the function used to calculate the interactable's\r\n * element's rectangle\r\n *\r\n - checker (function) #optional A function which returns this Interactable's bounding rectangle. See @Interactable.getRect\r\n = (function | object) The checker function or this Interactable\r\n \\*/\r\n\r\n\r\n Interactable.prototype.rectChecker = function rectChecker(checker) {\r\n if (is.function(checker)) {\r\n this.getRect = checker;\r\n\r\n return this;\r\n }\r\n\r\n if (checker === null) {\r\n delete this.options.getRect;\r\n\r\n return this;\r\n }\r\n\r\n return this.getRect;\r\n };\r\n\r\n Interactable.prototype._backCompatOption = function _backCompatOption(optionName, newValue) {\r\n if (trySelector(newValue) || is.object(newValue)) {\r\n this.options[optionName] = newValue;\r\n\r\n for (var _iterator = actions.names, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\r\n var _ref;\r\n\r\n if (_isArray) {\r\n if (_i >= _iterator.length) break;\r\n _ref = _iterator[_i++];\r\n } else {\r\n _i = _iterator.next();\r\n if (_i.done) break;\r\n _ref = _i.value;\r\n }\r\n\r\n var action = _ref;\r\n\r\n this.options[action][optionName] = newValue;\r\n }\r\n\r\n return this;\r\n }\r\n\r\n return this.options[optionName];\r\n };\r\n\r\n /*\\\r\n * Interactable.origin\r\n [ method ]\r\n *\r\n * Gets or sets the origin of the Interactable's element. The x and y\r\n * of the origin will be subtracted from action event coordinates.\r\n *\r\n - origin (object | string) #optional An object eg. { x: 0, y: 0 } or string 'parent', 'self' or any CSS selector\r\n * OR\r\n - origin (Element) #optional An HTML or SVG Element whose rect will be used\r\n **\r\n = (object) The current origin or this Interactable\r\n \\*/\r\n\r\n\r\n Interactable.prototype.origin = function origin(newValue) {\r\n return this._backCompatOption('origin', newValue);\r\n };\r\n\r\n /*\\\r\n * Interactable.deltaSource\r\n [ method ]\r\n *\r\n * Returns or sets the mouse coordinate types used to calculate the\r\n * movement of the pointer.\r\n *\r\n - newValue (string) #optional Use 'client' if you will be scrolling while interacting; Use 'page' if you want autoScroll to work\r\n = (string | object) The current deltaSource or this Interactable\r\n \\*/\r\n\r\n\r\n Interactable.prototype.deltaSource = function deltaSource(newValue) {\r\n if (newValue === 'page' || newValue === 'client') {\r\n this.options.deltaSource = newValue;\r\n\r\n return this;\r\n }\r\n\r\n return this.options.deltaSource;\r\n };\r\n\r\n /*\\\r\n * Interactable.context\r\n [ method ]\r\n *\r\n * Gets the selector context Node of the Interactable. The default is `window.document`.\r\n *\r\n = (Node) The context Node of this Interactable\r\n **\r\n \\*/\r\n\r\n\r\n Interactable.prototype.context = function context() {\r\n return this._context;\r\n };\r\n\r\n Interactable.prototype.inContext = function inContext(element) {\r\n return this._context === element.ownerDocument || nodeContains(this._context, element);\r\n };\r\n\r\n /*\\\r\n * Interactable.fire\r\n [ method ]\r\n *\r\n * Calls listeners for the given InteractEvent type bound globally\r\n * and directly to this Interactable\r\n *\r\n - iEvent (InteractEvent) The InteractEvent object to be fired on this Interactable\r\n = (Interactable) this Interactable\r\n \\*/\r\n\r\n\r\n Interactable.prototype.fire = function fire(iEvent) {\r\n this.events.fire(iEvent);\r\n\r\n return this;\r\n };\r\n\r\n Interactable.prototype._onOffMultiple = function _onOffMultiple(method, eventType, listener, options) {\r\n if (is.string(eventType) && eventType.search(' ') !== -1) {\r\n eventType = eventType.trim().split(/ +/);\r\n }\r\n\r\n if (is.array(eventType)) {\r\n for (var i = 0; i < eventType.length; i++) {\r\n this[method](eventType[i], listener, options);\r\n }\r\n\r\n return true;\r\n }\r\n\r\n if (is.object(eventType)) {\r\n for (var prop in eventType) {\r\n this[method](prop, eventType[prop], listener);\r\n }\r\n\r\n return true;\r\n }\r\n };\r\n\r\n /*\\\r\n * Interactable.on\r\n [ method ]\r\n *\r\n * Binds a listener for an InteractEvent, pointerEvent or DOM event.\r\n *\r\n - eventType (string | array | object) The types of events to listen for\r\n - listener (function) The function event (s)\r\n - options (object | boolean) #optional options object or useCapture flag for addEventListener\r\n = (object) This Interactable\r\n \\*/\r\n\r\n\r\n Interactable.prototype.on = function on(eventType, listener, options) {\r\n if (this._onOffMultiple('on', eventType, listener, options)) {\r\n return this;\r\n }\r\n\r\n if (eventType === 'wheel') {\r\n eventType = wheelEvent;\r\n }\r\n\r\n if (contains(Interactable.eventTypes, eventType)) {\r\n this.events.on(eventType, listener);\r\n }\r\n // delegated event for selector\r\n else if (is.string(this.target)) {\r\n events.addDelegate(this.target, this._context, eventType, listener, options);\r\n } else {\r\n events.add(this.target, eventType, listener, options);\r\n }\r\n\r\n return this;\r\n };\r\n\r\n /*\\\r\n * Interactable.off\r\n [ method ]\r\n *\r\n * Removes an InteractEvent, pointerEvent or DOM event listener\r\n *\r\n - eventType (string | array | object) The types of events that were listened for\r\n - listener (function) The listener function to be removed\r\n - options (object | boolean) #optional options object or useCapture flag for removeEventListener\r\n = (object) This Interactable\r\n \\*/\r\n\r\n\r\n Interactable.prototype.off = function off(eventType, listener, options) {\r\n if (this._onOffMultiple('off', eventType, listener, options)) {\r\n return this;\r\n }\r\n\r\n if (eventType === 'wheel') {\r\n eventType = wheelEvent;\r\n }\r\n\r\n // if it is an action event type\r\n if (contains(Interactable.eventTypes, eventType)) {\r\n this.events.off(eventType, listener);\r\n }\r\n // delegated event\r\n else if (is.string(this.target)) {\r\n events.removeDelegate(this.target, this._context, eventType, listener, options);\r\n }\r\n // remove listener from this Interatable's element\r\n else {\r\n events.remove(this.target, eventType, listener, options);\r\n }\r\n\r\n return this;\r\n };\r\n\r\n /*\\\r\n * Interactable.set\r\n [ method ]\r\n *\r\n * Reset the options of this Interactable\r\n - options (object) The new settings to apply\r\n = (object) This Interactable\r\n \\*/\r\n\r\n\r\n Interactable.prototype.set = function set(options) {\r\n if (!is.object(options)) {\r\n options = {};\r\n }\r\n\r\n this.options = extend({}, defaults.base);\r\n\r\n var perActions = extend({}, defaults.perAction);\r\n\r\n for (var actionName in actions.methodDict) {\r\n var methodName = actions.methodDict[actionName];\r\n\r\n this.options[actionName] = extend({}, defaults[actionName]);\r\n\r\n this.setPerAction(actionName, perActions);\r\n\r\n this[methodName](options[actionName]);\r\n }\r\n\r\n for (var _iterator2 = Interactable.settingsMethods, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {\r\n var _ref2;\r\n\r\n if (_isArray2) {\r\n if (_i2 >= _iterator2.length) break;\r\n _ref2 = _iterator2[_i2++];\r\n } else {\r\n _i2 = _iterator2.next();\r\n if (_i2.done) break;\r\n _ref2 = _i2.value;\r\n }\r\n\r\n var setting = _ref2;\r\n\r\n this.options[setting] = defaults.base[setting];\r\n\r\n if (setting in options) {\r\n this[setting](options[setting]);\r\n }\r\n }\r\n\r\n signals.fire('set', {\r\n options: options,\r\n interactable: this\r\n });\r\n\r\n return this;\r\n };\r\n\r\n /*\\\r\n * Interactable.unset\r\n [ method ]\r\n *\r\n * Remove this interactable from the list of interactables and remove\r\n * it's action capabilities and event listeners\r\n *\r\n = (object) @interact\r\n \\*/\r\n\r\n\r\n Interactable.prototype.unset = function unset() {\r\n events.remove(this.target, 'all');\r\n\r\n if (is.string(this.target)) {\r\n // remove delegated events\r\n for (var type in events.delegatedEvents) {\r\n var delegated = events.delegatedEvents[type];\r\n\r\n if (delegated.selectors[0] === this.target && delegated.contexts[0] === this._context) {\r\n\r\n delegated.selectors.splice(0, 1);\r\n delegated.contexts.splice(0, 1);\r\n delegated.listeners.splice(0, 1);\r\n\r\n // remove the arrays if they are empty\r\n if (!delegated.selectors.length) {\r\n delegated[type] = null;\r\n }\r\n }\r\n\r\n events.remove(this._context, type, events.delegateListener);\r\n events.remove(this._context, type, events.delegateUseCapture, true);\r\n }\r\n } else {\r\n events.remove(this, 'all');\r\n }\r\n\r\n signals.fire('unset', { interactable: this });\r\n\r\n scope.interactables.splice(indexOf(scope.interactables, this), 1);\r\n\r\n // Stop related interactions when an Interactable is unset\r\n for (var _iterator3 = scope.interactions || [], _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {\r\n var _ref3;\r\n\r\n if (_isArray3) {\r\n if (_i3 >= _iterator3.length) break;\r\n _ref3 = _iterator3[_i3++];\r\n } else {\r\n _i3 = _iterator3.next();\r\n if (_i3.done) break;\r\n _ref3 = _i3.value;\r\n }\r\n\r\n var interaction = _ref3;\r\n\r\n if (interaction.target === this && interaction.interacting()) {\r\n interaction.stop();\r\n }\r\n }\r\n\r\n return scope.interact;\r\n };\r\n\r\n return Interactable;\r\n}();\r\n\r\nscope.interactables.indexOfElement = function indexOfElement(target, context) {\r\n context = context || scope.document;\r\n\r\n for (var i = 0; i < this.length; i++) {\r\n var interactable = this[i];\r\n\r\n if (interactable.target === target && interactable._context === context) {\r\n return i;\r\n }\r\n }\r\n return -1;\r\n};\r\n\r\nscope.interactables.get = function interactableGet(element, options, dontCheckInContext) {\r\n var ret = this[this.indexOfElement(element, options && options.context)];\r\n\r\n return ret && (is.string(element) || dontCheckInContext || ret.inContext(element)) ? ret : null;\r\n};\r\n\r\nscope.interactables.forEachSelector = function (callback, element) {\r\n for (var i = 0; i < this.length; i++) {\r\n var interactable = this[i];\r\n\r\n // skip non CSS selector targets and out of context elements\r\n if (!is.string(interactable.target) || element && !interactable.inContext(element)) {\r\n continue;\r\n }\r\n\r\n var ret = callback(interactable, interactable.target, interactable._context, i, this);\r\n\r\n if (ret !== undefined) {\r\n return ret;\r\n }\r\n }\r\n};\r\n\r\n// all interact.js eventTypes\r\nInteractable.eventTypes = scope.eventTypes = [];\r\n\r\nInteractable.signals = signals;\r\n\r\nInteractable.settingsMethods = ['deltaSource', 'origin', 'preventDefault', 'rectChecker'];\r\n\r\nmodule.exports = Interactable;\r\n\r\n},{\"./Eventable\":2,\"./actions/base\":6,\"./defaultOptions\":18,\"./scope\":34,\"./utils/Signals\":35,\"./utils/arr\":36,\"./utils/browser\":37,\"./utils/domUtils\":39,\"./utils/events\":40,\"./utils/extend\":41,\"./utils/is\":46,\"./utils/window\":52}],5:[function(require,module,exports){\r\n'use strict';\r\n\r\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\r\n\r\nvar scope = require('./scope');\r\nvar utils = require('./utils');\r\nvar events = require('./utils/events');\r\nvar browser = require('./utils/browser');\r\nvar domObjects = require('./utils/domObjects');\r\nvar finder = require('./utils/interactionFinder');\r\nvar signals = require('./utils/Signals').new();\r\n\r\nvar listeners = {};\r\nvar methodNames = ['pointerDown', 'pointerMove', 'pointerUp', 'updatePointer', 'removePointer'];\r\n\r\n// for ignoring browser's simulated mouse events\r\nvar prevTouchTime = 0;\r\n\r\n// all active and idle interactions\r\nscope.interactions = [];\r\n\r\nvar Interaction = function () {\r\n function Interaction(_ref) {\r\n var pointerType = _ref.pointerType;\r\n\r\n _classCallCheck(this, Interaction);\r\n\r\n this.target = null; // current interactable being interacted with\r\n this.element = null; // the target element of the interactable\r\n\r\n this.prepared = { // action that's ready to be fired on next move event\r\n name: null,\r\n axis: null,\r\n edges: null\r\n };\r\n\r\n // keep track of added pointers\r\n this.pointers = [];\r\n this.pointerIds = [];\r\n this.downTargets = [];\r\n this.downTimes = [];\r\n\r\n // Previous native pointer move event coordinates\r\n this.prevCoords = {\r\n page: { x: 0, y: 0 },\r\n client: { x: 0, y: 0 },\r\n timeStamp: 0\r\n };\r\n // current native pointer move event coordinates\r\n this.curCoords = {\r\n page: { x: 0, y: 0 },\r\n client: { x: 0, y: 0 },\r\n timeStamp: 0\r\n };\r\n\r\n // Starting InteractEvent pointer coordinates\r\n this.startCoords = {\r\n page: { x: 0, y: 0 },\r\n client: { x: 0, y: 0 },\r\n timeStamp: 0\r\n };\r\n\r\n // Change in coordinates and time of the pointer\r\n this.pointerDelta = {\r\n page: { x: 0, y: 0, vx: 0, vy: 0, speed: 0 },\r\n client: { x: 0, y: 0, vx: 0, vy: 0, speed: 0 },\r\n timeStamp: 0\r\n };\r\n\r\n this.downEvent = null; // pointerdown/mousedown/touchstart event\r\n this.downPointer = {};\r\n\r\n this._eventTarget = null;\r\n this._curEventTarget = null;\r\n\r\n this.prevEvent = null; // previous action event\r\n\r\n this.pointerIsDown = false;\r\n this.pointerWasMoved = false;\r\n this._interacting = false;\r\n\r\n this.pointerType = pointerType;\r\n\r\n signals.fire('new', this);\r\n\r\n scope.interactions.push(this);\r\n }\r\n\r\n Interaction.prototype.pointerDown = function pointerDown(pointer, event, eventTarget) {\r\n var pointerIndex = this.updatePointer(pointer, event, true);\r\n\r\n signals.fire('down', {\r\n pointer: pointer,\r\n event: event,\r\n eventTarget: eventTarget,\r\n pointerIndex: pointerIndex,\r\n interaction: this\r\n });\r\n };\r\n\r\n /*\\\r\n * Interaction.start\r\n [ method ]\r\n *\r\n * Start an action with the given Interactable and Element as tartgets. The\r\n * action must be enabled for the target Interactable and an appropriate number\r\n * of pointers must be held down - 1 for drag/resize, 2 for gesture.\r\n *\r\n * Use it with `interactable.able({ manualStart: false })` to always\r\n * [start actions manually](https://github.com/taye/interact.js/issues/114)\r\n *\r\n - action (object) The action to be performed - drag, resize, etc.\r\n - target (Interactable) The Interactable to target\r\n - element (Element) The DOM Element to target\r\n = (object) interact\r\n **\r\n | interact(target)\r\n | .draggable({\r\n | // disable the default drag start by down->move\r\n | manualStart: true\r\n | })\r\n | // start dragging after the user holds the pointer down\r\n | .on('hold', function (event) {\r\n | var interaction = event.interaction;\r\n |\r\n | if (!interaction.interacting()) {\r\n | interaction.start({ name: 'drag' },\r\n | event.interactable,\r\n | event.currentTarget);\r\n | }\r\n | });\r\n \\*/\r\n\r\n\r\n Interaction.prototype.start = function start(action, target, element) {\r\n if (this.interacting() || !this.pointerIsDown || this.pointerIds.length < (action.name === 'gesture' ? 2 : 1)) {\r\n return;\r\n }\r\n\r\n // if this interaction had been removed after stopping\r\n // add it back\r\n if (utils.indexOf(scope.interactions, this) === -1) {\r\n scope.interactions.push(this);\r\n }\r\n\r\n utils.copyAction(this.prepared, action);\r\n this.target = target;\r\n this.element = element;\r\n\r\n signals.fire('action-start', {\r\n interaction: this,\r\n event: this.downEvent\r\n });\r\n };\r\n\r\n Interaction.prototype.pointerMove = function pointerMove(pointer, event, eventTarget) {\r\n if (!this.simulation) {\r\n this.updatePointer(pointer);\r\n utils.setCoords(this.curCoords, this.pointers);\r\n }\r\n\r\n var duplicateMove = this.curCoords.page.x === this.prevCoords.page.x && this.curCoords.page.y === this.prevCoords.page.y && this.curCoords.client.x === this.prevCoords.client.x && this.curCoords.client.y === this.prevCoords.client.y;\r\n\r\n var dx = void 0;\r\n var dy = void 0;\r\n\r\n // register movement greater than pointerMoveTolerance\r\n if (this.pointerIsDown && !this.pointerWasMoved) {\r\n dx = this.curCoords.client.x - this.startCoords.client.x;\r\n dy = this.curCoords.client.y - this.startCoords.client.y;\r\n\r\n this.pointerWasMoved = utils.hypot(dx, dy) > Interaction.pointerMoveTolerance;\r\n }\r\n\r\n var signalArg = {\r\n pointer: pointer,\r\n pointerIndex: this.getPointerIndex(pointer),\r\n event: event,\r\n eventTarget: eventTarget,\r\n dx: dx,\r\n dy: dy,\r\n duplicate: duplicateMove,\r\n interaction: this,\r\n interactingBeforeMove: this.interacting()\r\n };\r\n\r\n if (!duplicateMove) {\r\n // set pointer coordinate, time changes and speeds\r\n utils.setCoordDeltas(this.pointerDelta, this.prevCoords, this.curCoords);\r\n }\r\n\r\n signals.fire('move', signalArg);\r\n\r\n if (!duplicateMove) {\r\n // if interacting, fire an 'action-move' signal etc\r\n if (this.interacting()) {\r\n this.doMove(signalArg);\r\n }\r\n\r\n if (this.pointerWasMoved) {\r\n utils.copyCoords(this.prevCoords, this.curCoords);\r\n }\r\n }\r\n };\r\n\r\n /*\\\r\n * Interaction.doMove\r\n [ method ]\r\n *\r\n * Force a move of the current action at the same coordinates. Useful if\r\n * snap/restrict has been changed and you want a movement with the new\r\n * settings.\r\n *\r\n **\r\n | interact(target)\r\n | .draggable(true)\r\n | .on('dragmove', function (event) {\r\n | if (someCondition) {\r\n | // change the snap settings\r\n | event.interactable.draggable({ snap: { targets: [] }});\r\n | // fire another move event with re-calculated snap\r\n | event.interaction.doMove();\r\n | }\r\n | });\r\n \\*/\r\n\r\n\r\n Interaction.prototype.doMove = function doMove(signalArg) {\r\n signalArg = utils.extend({\r\n pointer: this.pointers[0],\r\n event: this.prevEvent,\r\n eventTarget: this._eventTarget,\r\n interaction: this\r\n }, signalArg || {});\r\n\r\n signals.fire('before-action-move', signalArg);\r\n\r\n if (!this._dontFireMove) {\r\n signals.fire('action-move', signalArg);\r\n }\r\n\r\n this._dontFireMove = false;\r\n };\r\n\r\n // End interact move events and stop auto-scroll unless simulation is running\r\n\r\n\r\n Interaction.prototype.pointerUp = function pointerUp(pointer, event, eventTarget, curEventTarget) {\r\n var pointerIndex = this.getPointerIndex(pointer);\r\n\r\n signals.fire(/cancel$/i.test(event.type) ? 'cancel' : 'up', {\r\n pointer: pointer,\r\n pointerIndex: pointerIndex,\r\n event: event,\r\n eventTarget: eventTarget,\r\n curEventTarget: curEventTarget,\r\n interaction: this\r\n });\r\n\r\n if (!this.simulation) {\r\n this.end(event);\r\n }\r\n\r\n this.pointerIsDown = false;\r\n this.removePointer(pointer, event);\r\n };\r\n\r\n /*\\\r\n * Interaction.end\r\n [ method ]\r\n *\r\n * Stop the current action and fire an end event. Inertial movement does\r\n * not happen.\r\n *\r\n - event (PointerEvent) #optional\r\n **\r\n | interact(target)\r\n | .draggable(true)\r\n | .on('move', function (event) {\r\n | if (event.pageX > 1000) {\r\n | // end the current action\r\n | event.interaction.end();\r\n | // stop all further listeners from being called\r\n | event.stopImmediatePropagation();\r\n | }\r\n | });\r\n \\*/\r\n\r\n\r\n Interaction.prototype.end = function end(event) {\r\n event = event || this.prevEvent;\r\n\r\n if (this.interacting()) {\r\n signals.fire('action-end', {\r\n event: event,\r\n interaction: this\r\n });\r\n }\r\n\r\n this.stop();\r\n };\r\n\r\n Interaction.prototype.currentAction = function currentAction() {\r\n return this._interacting ? this.prepared.name : null;\r\n };\r\n\r\n Interaction.prototype.interacting = function interacting() {\r\n return this._interacting;\r\n };\r\n\r\n Interaction.prototype.stop = function stop() {\r\n signals.fire('stop', { interaction: this });\r\n\r\n if (this._interacting) {\r\n signals.fire('stop-active', { interaction: this });\r\n signals.fire('stop-' + this.prepared.name, { interaction: this });\r\n }\r\n\r\n this.target = this.element = null;\r\n\r\n this._interacting = false;\r\n this.prepared.name = this.prevEvent = null;\r\n };\r\n\r\n Interaction.prototype.getPointerIndex = function getPointerIndex(pointer) {\r\n // mouse and pen interactions may have only one pointer\r\n if (this.pointerType === 'mouse' || this.pointerType === 'pen') {\r\n return 0;\r\n }\r\n\r\n return utils.indexOf(this.pointerIds, utils.getPointerId(pointer));\r\n };\r\n\r\n Interaction.prototype.updatePointer = function updatePointer(pointer, event) {\r\n var down = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : event && /(down|start)$/i.test(event.type);\r\n\r\n var id = utils.getPointerId(pointer);\r\n var index = this.getPointerIndex(pointer);\r\n\r\n if (index === -1) {\r\n index = this.pointerIds.length;\r\n this.pointerIds[index] = id;\r\n }\r\n\r\n if (down) {\r\n signals.fire('update-pointer-down', {\r\n pointer: pointer,\r\n event: event,\r\n down: down,\r\n pointerId: id,\r\n pointerIndex: index,\r\n interaction: this\r\n });\r\n }\r\n\r\n this.pointers[index] = pointer;\r\n\r\n return index;\r\n };\r\n\r\n Interaction.prototype.removePointer = function removePointer(pointer, event) {\r\n var index = this.getPointerIndex(pointer);\r\n\r\n if (index === -1) {\r\n return;\r\n }\r\n\r\n signals.fire('remove-pointer', {\r\n pointer: pointer,\r\n event: event,\r\n pointerIndex: index,\r\n interaction: this\r\n });\r\n\r\n this.pointers.splice(index, 1);\r\n this.pointerIds.splice(index, 1);\r\n this.downTargets.splice(index, 1);\r\n this.downTimes.splice(index, 1);\r\n };\r\n\r\n Interaction.prototype._updateEventTargets = function _updateEventTargets(target, currentTarget) {\r\n this._eventTarget = target;\r\n this._curEventTarget = currentTarget;\r\n };\r\n\r\n return Interaction;\r\n}();\r\n\r\nfor (var i = 0, len = methodNames.length; i < len; i++) {\r\n var method = methodNames[i];\r\n\r\n listeners[method] = doOnInteractions(method);\r\n}\r\n\r\nfunction doOnInteractions(method) {\r\n return function (event) {\r\n var pointerType = utils.getPointerType(event);\r\n\r\n var _utils$getEventTarget = utils.getEventTargets(event),\r\n eventTarget = _utils$getEventTarget[0],\r\n curEventTarget = _utils$getEventTarget[1];\r\n\r\n var matches = []; // [ [pointer, interaction], ...]\r\n\r\n if (browser.supportsTouch && /touch/.test(event.type)) {\r\n prevTouchTime = new Date().getTime();\r\n\r\n for (var _i = 0; _i < event.changedTouches.length; _i++) {\r\n var pointer = event.changedTouches[_i];\r\n var interaction = finder.search(pointer, event.type, eventTarget);\r\n\r\n matches.push([pointer, interaction || new Interaction({ pointerType: pointerType })]);\r\n }\r\n } else {\r\n var invalidPointer = false;\r\n\r\n if (!browser.supportsPointerEvent && /mouse/.test(event.type)) {\r\n // ignore mouse events while touch interactions are active\r\n for (var _i2 = 0; _i2 < scope.interactions.length && !invalidPointer; _i2++) {\r\n invalidPointer = scope.interactions[_i2].pointerType !== 'mouse' && scope.interactions[_i2].pointerIsDown;\r\n }\r\n\r\n // try to ignore mouse events that are simulated by the browser\r\n // after a touch event\r\n invalidPointer = invalidPointer || new Date().getTime() - prevTouchTime < 500\r\n // on iOS and Firefox Mobile, MouseEvent.timeStamp is zero if simulated\r\n || event.timeStamp === 0;\r\n }\r\n\r\n if (!invalidPointer) {\r\n var _interaction = finder.search(event, event.type, eventTarget);\r\n\r\n if (!_interaction) {\r\n _interaction = new Interaction({ pointerType: pointerType });\r\n }\r\n\r\n matches.push([event, _interaction]);\r\n }\r\n }\r\n\r\n for (var _iterator = matches, _isArray = Array.isArray(_iterator), _i3 = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\r\n var _ref2;\r\n\r\n if (_isArray) {\r\n if (_i3 >= _iterator.length) break;\r\n _ref2 = _iterator[_i3++];\r\n } else {\r\n _i3 = _iterator.next();\r\n if (_i3.done) break;\r\n _ref2 = _i3.value;\r\n }\r\n\r\n var _ref3 = _ref2,\r\n _pointer = _ref3[0],\r\n _interaction2 = _ref3[1];\r\n\r\n _interaction2._updateEventTargets(eventTarget, curEventTarget);\r\n _interaction2[method](_pointer, event, eventTarget, curEventTarget);\r\n }\r\n };\r\n}\r\n\r\nfunction endAll(event) {\r\n for (var _i4 = 0; _i4 < scope.interactions.length; _i4++) {\r\n var interaction = scope.interactions[_i4];\r\n\r\n interaction.end(event);\r\n signals.fire('endall', { event: event, interaction: interaction });\r\n }\r\n}\r\n\r\nvar docEvents = {/* 'eventType': listenerFunc */};\r\nvar pEventTypes = browser.pEventTypes;\r\n\r\nif (domObjects.PointerEvent) {\r\n docEvents[pEventTypes.down] = listeners.pointerDown;\r\n docEvents[pEventTypes.move] = listeners.pointerMove;\r\n docEvents[pEventTypes.up] = listeners.pointerUp;\r\n docEvents[pEventTypes.cancel] = listeners.pointerUp;\r\n} else {\r\n docEvents.mousedown = listeners.pointerDown;\r\n docEvents.mousemove = listeners.pointerMove;\r\n docEvents.mouseup = listeners.pointerUp;\r\n\r\n docEvents.touchstart = listeners.pointerDown;\r\n docEvents.touchmove = listeners.pointerMove;\r\n docEvents.touchend = listeners.pointerUp;\r\n docEvents.touchcancel = listeners.pointerUp;\r\n}\r\n\r\ndocEvents.blur = endAll;\r\n\r\nfunction onDocSignal(_ref4, signalName) {\r\n var doc = _ref4.doc;\r\n\r\n var eventMethod = signalName.indexOf('add') === 0 ? events.add : events.remove;\r\n\r\n // delegate event listener\r\n for (var eventType in scope.delegatedEvents) {\r\n eventMethod(doc, eventType, events.delegateListener);\r\n eventMethod(doc, eventType, events.delegateUseCapture, true);\r\n }\r\n\r\n for (var _eventType in docEvents) {\r\n eventMethod(doc, _eventType, docEvents[_eventType]);\r\n }\r\n}\r\n\r\nsignals.on('update-pointer-down', function (_ref5) {\r\n var interaction = _ref5.interaction,\r\n pointer = _ref5.pointer,\r\n pointerId = _ref5.pointerId,\r\n pointerIndex = _ref5.pointerIndex,\r\n event = _ref5.event,\r\n eventTarget = _ref5.eventTarget,\r\n down = _ref5.down;\r\n\r\n interaction.pointerIds[pointerIndex] = pointerId;\r\n interaction.pointers[pointerIndex] = pointer;\r\n\r\n if (down) {\r\n interaction.pointerIsDown = true;\r\n }\r\n\r\n if (!interaction.interacting()) {\r\n utils.setCoords(interaction.startCoords, interaction.pointers);\r\n\r\n utils.copyCoords(interaction.curCoords, interaction.startCoords);\r\n utils.copyCoords(interaction.prevCoords, interaction.startCoords);\r\n\r\n interaction.downEvent = event;\r\n interaction.downTimes[pointerIndex] = interaction.curCoords.timeStamp;\r\n interaction.downTargets[pointerIndex] = eventTarget || event && utils.getEventTargets(event)[0];\r\n interaction.pointerWasMoved = false;\r\n\r\n utils.pointerExtend(interaction.downPointer, pointer);\r\n }\r\n});\r\n\r\nscope.signals.on('add-document', onDocSignal);\r\nscope.signals.on('remove-document', onDocSignal);\r\n\r\nInteraction.pointerMoveTolerance = 1;\r\nInteraction.doOnInteractions = doOnInteractions;\r\nInteraction.endAll = endAll;\r\nInteraction.signals = signals;\r\nInteraction.docEvents = docEvents;\r\n\r\nscope.endAllInteractions = endAll;\r\n\r\nmodule.exports = Interaction;\r\n\r\n},{\"./scope\":34,\"./utils\":44,\"./utils/Signals\":35,\"./utils/browser\":37,\"./utils/domObjects\":38,\"./utils/events\":40,\"./utils/interactionFinder\":45}],6:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar Interaction = require('../Interaction');\r\nvar InteractEvent = require('../InteractEvent');\r\n\r\nvar actions = {\r\n firePrepared: firePrepared,\r\n names: [],\r\n methodDict: {}\r\n};\r\n\r\nInteraction.signals.on('action-start', function (_ref) {\r\n var interaction = _ref.interaction,\r\n event = _ref.event;\r\n\r\n interaction._interacting = true;\r\n firePrepared(interaction, event, 'start');\r\n});\r\n\r\nInteraction.signals.on('action-move', function (_ref2) {\r\n var interaction = _ref2.interaction,\r\n event = _ref2.event,\r\n preEnd = _ref2.preEnd;\r\n\r\n firePrepared(interaction, event, 'move', preEnd);\r\n\r\n // if the action was ended in a listener\r\n if (!interaction.interacting()) {\r\n return false;\r\n }\r\n});\r\n\r\nInteraction.signals.on('action-end', function (_ref3) {\r\n var interaction = _ref3.interaction,\r\n event = _ref3.event;\r\n\r\n firePrepared(interaction, event, 'end');\r\n});\r\n\r\nfunction firePrepared(interaction, event, phase, preEnd) {\r\n var actionName = interaction.prepared.name;\r\n\r\n var newEvent = new InteractEvent(interaction, event, actionName, phase, interaction.element, null, preEnd);\r\n\r\n interaction.target.fire(newEvent);\r\n interaction.prevEvent = newEvent;\r\n}\r\n\r\nmodule.exports = actions;\r\n\r\n},{\"../InteractEvent\":3,\"../Interaction\":5}],7:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar actions = require('./base');\r\nvar utils = require('../utils');\r\nvar InteractEvent = require('../InteractEvent');\r\nvar Interactable = require('../Interactable');\r\nvar Interaction = require('../Interaction');\r\nvar defaultOptions = require('../defaultOptions');\r\n\r\nvar drag = {\r\n defaults: {\r\n enabled: false,\r\n mouseButtons: null,\r\n\r\n origin: null,\r\n snap: null,\r\n restrict: null,\r\n inertia: null,\r\n autoScroll: null,\r\n\r\n startAxis: 'xy',\r\n lockAxis: 'xy'\r\n },\r\n\r\n checker: function checker(pointer, event, interactable) {\r\n var dragOptions = interactable.options.drag;\r\n\r\n return dragOptions.enabled ? { name: 'drag', axis: dragOptions.lockAxis === 'start' ? dragOptions.startAxis : dragOptions.lockAxis } : null;\r\n },\r\n\r\n getCursor: function getCursor() {\r\n return 'move';\r\n }\r\n};\r\n\r\nInteraction.signals.on('before-action-move', function (_ref) {\r\n var interaction = _ref.interaction;\r\n\r\n if (interaction.prepared.name !== 'drag') {\r\n return;\r\n }\r\n\r\n var axis = interaction.prepared.axis;\r\n\r\n if (axis === 'x') {\r\n interaction.curCoords.page.y = interaction.startCoords.page.y;\r\n interaction.curCoords.client.y = interaction.startCoords.client.y;\r\n\r\n interaction.pointerDelta.page.speed = Math.abs(interaction.pointerDelta.page.vx);\r\n interaction.pointerDelta.client.speed = Math.abs(interaction.pointerDelta.client.vx);\r\n interaction.pointerDelta.client.vy = 0;\r\n interaction.pointerDelta.page.vy = 0;\r\n } else if (axis === 'y') {\r\n interaction.curCoords.page.x = interaction.startCoords.page.x;\r\n interaction.curCoords.client.x = interaction.startCoords.client.x;\r\n\r\n interaction.pointerDelta.page.speed = Math.abs(interaction.pointerDelta.page.vy);\r\n interaction.pointerDelta.client.speed = Math.abs(interaction.pointerDelta.client.vy);\r\n interaction.pointerDelta.client.vx = 0;\r\n interaction.pointerDelta.page.vx = 0;\r\n }\r\n});\r\n\r\n// dragmove\r\nInteractEvent.signals.on('new', function (_ref2) {\r\n var iEvent = _ref2.iEvent,\r\n interaction = _ref2.interaction;\r\n\r\n if (iEvent.type !== 'dragmove') {\r\n return;\r\n }\r\n\r\n var axis = interaction.prepared.axis;\r\n\r\n if (axis === 'x') {\r\n iEvent.pageY = interaction.startCoords.page.y;\r\n iEvent.clientY = interaction.startCoords.client.y;\r\n iEvent.dy = 0;\r\n } else if (axis === 'y') {\r\n iEvent.pageX = interaction.startCoords.page.x;\r\n iEvent.clientX = interaction.startCoords.client.x;\r\n iEvent.dx = 0;\r\n }\r\n});\r\n\r\n/*\\\r\n * Interactable.draggable\r\n [ method ]\r\n *\r\n * Gets or sets whether drag actions can be performed on the\r\n * Interactable\r\n *\r\n = (boolean) Indicates if this can be the target of drag events\r\n | var isDraggable = interact('ul li').draggable();\r\n * or\r\n - options (boolean | object) #optional true/false or An object with event listeners to be fired on drag events (object makes the Interactable draggable)\r\n = (object) This Interactable\r\n | interact(element).draggable({\r\n | onstart: function (event) {},\r\n | onmove : function (event) {},\r\n | onend : function (event) {},\r\n |\r\n | // the axis in which the first movement must be\r\n | // for the drag sequence to start\r\n | // 'xy' by default - any direction\r\n | startAxis: 'x' || 'y' || 'xy',\r\n |\r\n | // 'xy' by default - don't restrict to one axis (move in any direction)\r\n | // 'x' or 'y' to restrict movement to either axis\r\n | // 'start' to restrict movement to the axis the drag started in\r\n | lockAxis: 'x' || 'y' || 'xy' || 'start',\r\n |\r\n | // max number of drags that can happen concurrently\r\n | // with elements of this Interactable. Infinity by default\r\n | max: Infinity,\r\n |\r\n | // max number of drags that can target the same element+Interactable\r\n | // 1 by default\r\n | maxPerElement: 2\r\n | });\r\n\\*/\r\nInteractable.prototype.draggable = function (options) {\r\n if (utils.is.object(options)) {\r\n this.options.drag.enabled = options.enabled === false ? false : true;\r\n this.setPerAction('drag', options);\r\n this.setOnEvents('drag', options);\r\n\r\n if (/^(xy|x|y|start)$/.test(options.lockAxis)) {\r\n this.options.drag.lockAxis = options.lockAxis;\r\n }\r\n if (/^(xy|x|y)$/.test(options.startAxis)) {\r\n this.options.drag.startAxis = options.startAxis;\r\n }\r\n\r\n return this;\r\n }\r\n\r\n if (utils.is.bool(options)) {\r\n this.options.drag.enabled = options;\r\n\r\n if (!options) {\r\n this.ondragstart = this.ondragstart = this.ondragend = null;\r\n }\r\n\r\n return this;\r\n }\r\n\r\n return this.options.drag;\r\n};\r\n\r\nactions.drag = drag;\r\nactions.names.push('drag');\r\nutils.merge(Interactable.eventTypes, ['dragstart', 'dragmove', 'draginertiastart', 'draginertiaresume', 'dragend']);\r\nactions.methodDict.drag = 'draggable';\r\n\r\ndefaultOptions.drag = drag.defaults;\r\n\r\nmodule.exports = drag;\r\n\r\n},{\"../InteractEvent\":3,\"../Interactable\":4,\"../Interaction\":5,\"../defaultOptions\":18,\"../utils\":44,\"./base\":6}],8:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar actions = require('./base');\r\nvar utils = require('../utils');\r\nvar scope = require('../scope');\r\nvar interact = require('../interact');\r\nvar InteractEvent = require('../InteractEvent');\r\nvar Interactable = require('../Interactable');\r\nvar Interaction = require('../Interaction');\r\nvar defaultOptions = require('../defaultOptions');\r\n\r\nvar drop = {\r\n defaults: {\r\n enabled: false,\r\n accept: null,\r\n overlap: 'pointer'\r\n }\r\n};\r\n\r\nvar dynamicDrop = false;\r\n\r\nInteraction.signals.on('action-start', function (_ref) {\r\n var interaction = _ref.interaction,\r\n event = _ref.event;\r\n\r\n if (interaction.prepared.name !== 'drag') {\r\n return;\r\n }\r\n\r\n // reset active dropzones\r\n interaction.activeDrops.dropzones = [];\r\n interaction.activeDrops.elements = [];\r\n interaction.activeDrops.rects = [];\r\n\r\n interaction.dropEvents = null;\r\n\r\n if (!interaction.dynamicDrop) {\r\n setActiveDrops(interaction, interaction.element);\r\n }\r\n\r\n var dragEvent = interaction.prevEvent;\r\n var dropEvents = getDropEvents(interaction, event, dragEvent);\r\n\r\n if (dropEvents.activate) {\r\n fireActiveDrops(interaction, dropEvents.activate);\r\n }\r\n});\r\n\r\nInteractEvent.signals.on('new', function (_ref2) {\r\n var interaction = _ref2.interaction,\r\n iEvent = _ref2.iEvent,\r\n event = _ref2.event;\r\n\r\n if (iEvent.type !== 'dragmove' && iEvent.type !== 'dragend') {\r\n return;\r\n }\r\n\r\n var draggableElement = interaction.element;\r\n var dragEvent = iEvent;\r\n var dropResult = getDrop(dragEvent, event, draggableElement);\r\n\r\n interaction.dropTarget = dropResult.dropzone;\r\n interaction.dropElement = dropResult.element;\r\n\r\n interaction.dropEvents = getDropEvents(interaction, event, dragEvent);\r\n});\r\n\r\nInteraction.signals.on('action-move', function (_ref3) {\r\n var interaction = _ref3.interaction;\r\n\r\n if (interaction.prepared.name !== 'drag') {\r\n return;\r\n }\r\n\r\n fireDropEvents(interaction, interaction.dropEvents);\r\n});\r\n\r\nInteraction.signals.on('action-end', function (_ref4) {\r\n var interaction = _ref4.interaction;\r\n\r\n if (interaction.prepared.name === 'drag') {\r\n fireDropEvents(interaction, interaction.dropEvents);\r\n }\r\n});\r\n\r\nInteraction.signals.on('stop-drag', function (_ref5) {\r\n var interaction = _ref5.interaction;\r\n\r\n interaction.activeDrops.dropzones = interaction.activeDrops.elements = interaction.activeDrops.rects = interaction.dropEvents = null;\r\n});\r\n\r\nfunction collectDrops(interaction, element) {\r\n var drops = [];\r\n var elements = [];\r\n\r\n element = element || interaction.element;\r\n\r\n // collect all dropzones and their elements which qualify for a drop\r\n for (var _iterator = scope.interactables, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\r\n var _ref6;\r\n\r\n if (_isArray) {\r\n if (_i >= _iterator.length) break;\r\n _ref6 = _iterator[_i++];\r\n } else {\r\n _i = _iterator.next();\r\n if (_i.done) break;\r\n _ref6 = _i.value;\r\n }\r\n\r\n var current = _ref6;\r\n\r\n if (!current.options.drop.enabled) {\r\n continue;\r\n }\r\n\r\n var accept = current.options.drop.accept;\r\n\r\n // test the draggable element against the dropzone's accept setting\r\n if (utils.is.element(accept) && accept !== element || utils.is.string(accept) && !utils.matchesSelector(element, accept)) {\r\n\r\n continue;\r\n }\r\n\r\n // query for new elements if necessary\r\n var dropElements = utils.is.string(current.target) ? current._context.querySelectorAll(current.target) : [current.target];\r\n\r\n for (var i = 0; i < dropElements.length; i++) {\r\n var currentElement = dropElements[i];\r\n\r\n if (currentElement !== element) {\r\n drops.push(current);\r\n elements.push(currentElement);\r\n }\r\n }\r\n }\r\n\r\n return {\r\n elements: elements,\r\n dropzones: drops\r\n };\r\n}\r\n\r\nfunction fireActiveDrops(interaction, event) {\r\n var prevElement = void 0;\r\n\r\n // loop through all active dropzones and trigger event\r\n for (var i = 0; i < interaction.activeDrops.dropzones.length; i++) {\r\n var current = interaction.activeDrops.dropzones[i];\r\n var currentElement = interaction.activeDrops.elements[i];\r\n\r\n // prevent trigger of duplicate events on same element\r\n if (currentElement !== prevElement) {\r\n // set current element as event target\r\n event.target = currentElement;\r\n current.fire(event);\r\n }\r\n prevElement = currentElement;\r\n }\r\n}\r\n\r\n// Collect a new set of possible drops and save them in activeDrops.\r\n// setActiveDrops should always be called when a drag has just started or a\r\n// drag event happens while dynamicDrop is true\r\nfunction setActiveDrops(interaction, dragElement) {\r\n // get dropzones and their elements that could receive the draggable\r\n var possibleDrops = collectDrops(interaction, dragElement, true);\r\n\r\n interaction.activeDrops.dropzones = possibleDrops.dropzones;\r\n interaction.activeDrops.elements = possibleDrops.elements;\r\n interaction.activeDrops.rects = [];\r\n\r\n for (var i = 0; i < interaction.activeDrops.dropzones.length; i++) {\r\n interaction.activeDrops.rects[i] = interaction.activeDrops.dropzones[i].getRect(interaction.activeDrops.elements[i]);\r\n }\r\n}\r\n\r\nfunction getDrop(dragEvent, event, dragElement) {\r\n var interaction = dragEvent.interaction;\r\n var validDrops = [];\r\n\r\n if (dynamicDrop) {\r\n setActiveDrops(interaction, dragElement);\r\n }\r\n\r\n // collect all dropzones and their elements which qualify for a drop\r\n for (var j = 0; j < interaction.activeDrops.dropzones.length; j++) {\r\n var current = interaction.activeDrops.dropzones[j];\r\n var currentElement = interaction.activeDrops.elements[j];\r\n var rect = interaction.activeDrops.rects[j];\r\n\r\n validDrops.push(current.dropCheck(dragEvent, event, interaction.target, dragElement, currentElement, rect) ? currentElement : null);\r\n }\r\n\r\n // get the most appropriate dropzone based on DOM depth and order\r\n var dropIndex = utils.indexOfDeepestElement(validDrops);\r\n\r\n return {\r\n dropzone: interaction.activeDrops.dropzones[dropIndex] || null,\r\n element: interaction.activeDrops.elements[dropIndex] || null\r\n };\r\n}\r\n\r\nfunction getDropEvents(interaction, pointerEvent, dragEvent) {\r\n var dropEvents = {\r\n enter: null,\r\n leave: null,\r\n activate: null,\r\n deactivate: null,\r\n move: null,\r\n drop: null\r\n };\r\n\r\n var tmpl = {\r\n dragEvent: dragEvent,\r\n interaction: interaction,\r\n target: interaction.dropElement,\r\n dropzone: interaction.dropTarget,\r\n relatedTarget: dragEvent.target,\r\n draggable: dragEvent.interactable,\r\n timeStamp: dragEvent.timeStamp\r\n };\r\n\r\n if (interaction.dropElement !== interaction.prevDropElement) {\r\n // if there was a prevDropTarget, create a dragleave event\r\n if (interaction.prevDropTarget) {\r\n dropEvents.leave = utils.extend({ type: 'dragleave' }, tmpl);\r\n\r\n dragEvent.dragLeave = dropEvents.leave.target = interaction.prevDropElement;\r\n dragEvent.prevDropzone = dropEvents.leave.dropzone = interaction.prevDropTarget;\r\n }\r\n // if the dropTarget is not null, create a dragenter event\r\n if (interaction.dropTarget) {\r\n dropEvents.enter = {\r\n dragEvent: dragEvent,\r\n interaction: interaction,\r\n target: interaction.dropElement,\r\n dropzone: interaction.dropTarget,\r\n relatedTarget: dragEvent.target,\r\n draggable: dragEvent.interactable,\r\n timeStamp: dragEvent.timeStamp,\r\n type: 'dragenter'\r\n };\r\n\r\n dragEvent.dragEnter = interaction.dropElement;\r\n dragEvent.dropzone = interaction.dropTarget;\r\n }\r\n }\r\n\r\n if (dragEvent.type === 'dragend' && interaction.dropTarget) {\r\n dropEvents.drop = utils.extend({ type: 'drop' }, tmpl);\r\n\r\n dragEvent.dropzone = interaction.dropTarget;\r\n dragEvent.relatedTarget = interaction.dropElement;\r\n }\r\n if (dragEvent.type === 'dragstart') {\r\n dropEvents.activate = utils.extend({ type: 'dropactivate' }, tmpl);\r\n\r\n dropEvents.activate.target = null;\r\n dropEvents.activate.dropzone = null;\r\n }\r\n if (dragEvent.type === 'dragend') {\r\n dropEvents.deactivate = utils.extend({ type: 'dropdeactivate' }, tmpl);\r\n\r\n dropEvents.deactivate.target = null;\r\n dropEvents.deactivate.dropzone = null;\r\n }\r\n if (dragEvent.type === 'dragmove' && interaction.dropTarget) {\r\n dropEvents.move = utils.extend({\r\n dragmove: dragEvent,\r\n type: 'dropmove'\r\n }, tmpl);\r\n\r\n dragEvent.dropzone = interaction.dropTarget;\r\n }\r\n\r\n return dropEvents;\r\n}\r\n\r\nfunction fireDropEvents(interaction, dropEvents) {\r\n if (dropEvents.leave) {\r\n interaction.prevDropTarget.fire(dropEvents.leave);\r\n }\r\n if (dropEvents.move) {\r\n interaction.dropTarget.fire(dropEvents.move);\r\n }\r\n if (dropEvents.enter) {\r\n interaction.dropTarget.fire(dropEvents.enter);\r\n }\r\n if (dropEvents.drop) {\r\n interaction.dropTarget.fire(dropEvents.drop);\r\n }\r\n if (dropEvents.deactivate) {\r\n fireActiveDrops(interaction, dropEvents.deactivate);\r\n }\r\n\r\n interaction.prevDropTarget = interaction.dropTarget;\r\n interaction.prevDropElement = interaction.dropElement;\r\n}\r\n\r\n/*\\\r\n * Interactable.dropzone\r\n [ method ]\r\n *\r\n * Returns or sets whether elements can be dropped onto this\r\n * Interactable to trigger drop events\r\n *\r\n * Dropzones can receive the following events:\r\n * - `dropactivate` and `dropdeactivate` when an acceptable drag starts and ends\r\n * - `dragenter` and `dragleave` when a draggable enters and leaves the dropzone\r\n * - `dragmove` when a draggable that has entered the dropzone is moved\r\n * - `drop` when a draggable is dropped into this dropzone\r\n *\r\n * Use the `accept` option to allow only elements that match the given CSS\r\n * selector or element. The value can be:\r\n *\r\n * - **an Element** - only that element can be dropped into this dropzone.\r\n * - **a string**, - the element being dragged must match it as a CSS selector.\r\n * - **`null`** - accept options is cleared - it accepts any element.\r\n *\r\n * Use the `overlap` option to set how drops are checked for. The allowed\r\n * values are:\r\n *\r\n * - `'pointer'`, the pointer must be over the dropzone (default)\r\n * - `'center'`, the draggable element's center must be over the dropzone\r\n * - a number from 0-1 which is the `(intersection area) / (draggable area)`.\r\n * e.g. `0.5` for drop to happen when half of the area of the draggable is\r\n * over the dropzone\r\n *\r\n * Use the `checker` option to specify a function to check if a dragged\r\n * element is over this Interactable.\r\n *\r\n | interact(target)\r\n | .dropChecker(function(dragEvent, // related dragmove or dragend event\r\n | event, // TouchEvent/PointerEvent/MouseEvent\r\n | dropped, // bool result of the default checker\r\n | dropzone, // dropzone Interactable\r\n | dropElement, // dropzone elemnt\r\n | draggable, // draggable Interactable\r\n | draggableElement) {// draggable element\r\n |\r\n | return dropped && event.target.hasAttribute('allow-drop');\r\n | }\r\n *\r\n *\r\n - options (boolean | object | null) #optional The new value to be set.\r\n | interact('.drop').dropzone({\r\n | accept: '.can-drop' || document.getElementById('single-drop'),\r\n | overlap: 'pointer' || 'center' || zeroToOne\r\n | }\r\n = (boolean | object) The current setting or this Interactable\r\n\\*/\r\nInteractable.prototype.dropzone = function (options) {\r\n if (utils.is.object(options)) {\r\n this.options.drop.enabled = options.enabled === false ? false : true;\r\n\r\n if (utils.is.function(options.ondrop)) {\r\n this.events.ondrop = options.ondrop;\r\n }\r\n if (utils.is.function(options.ondropactivate)) {\r\n this.events.ondropactivate = options.ondropactivate;\r\n }\r\n if (utils.is.function(options.ondropdeactivate)) {\r\n this.events.ondropdeactivate = options.ondropdeactivate;\r\n }\r\n if (utils.is.function(options.ondragenter)) {\r\n this.events.ondragenter = options.ondragenter;\r\n }\r\n if (utils.is.function(options.ondragleave)) {\r\n this.events.ondragleave = options.ondragleave;\r\n }\r\n if (utils.is.function(options.ondropmove)) {\r\n this.events.ondropmove = options.ondropmove;\r\n }\r\n\r\n if (/^(pointer|center)$/.test(options.overlap)) {\r\n this.options.drop.overlap = options.overlap;\r\n } else if (utils.is.number(options.overlap)) {\r\n this.options.drop.overlap = Math.max(Math.min(1, options.overlap), 0);\r\n }\r\n if ('accept' in options) {\r\n this.options.drop.accept = options.accept;\r\n }\r\n if ('checker' in options) {\r\n this.options.drop.checker = options.checker;\r\n }\r\n\r\n return this;\r\n }\r\n\r\n if (utils.is.bool(options)) {\r\n this.options.drop.enabled = options;\r\n\r\n if (!options) {\r\n this.ondragenter = this.ondragleave = this.ondrop = this.ondropactivate = this.ondropdeactivate = null;\r\n }\r\n\r\n return this;\r\n }\r\n\r\n return this.options.drop;\r\n};\r\n\r\nInteractable.prototype.dropCheck = function (dragEvent, event, draggable, draggableElement, dropElement, rect) {\r\n var dropped = false;\r\n\r\n // if the dropzone has no rect (eg. display: none)\r\n // call the custom dropChecker or just return false\r\n if (!(rect = rect || this.getRect(dropElement))) {\r\n return this.options.drop.checker ? this.options.drop.checker(dragEvent, event, dropped, this, dropElement, draggable, draggableElement) : false;\r\n }\r\n\r\n var dropOverlap = this.options.drop.overlap;\r\n\r\n if (dropOverlap === 'pointer') {\r\n var origin = utils.getOriginXY(draggable, draggableElement, 'drag');\r\n var page = utils.getPageXY(dragEvent);\r\n\r\n page.x += origin.x;\r\n page.y += origin.y;\r\n\r\n var horizontal = page.x > rect.left && page.x < rect.right;\r\n var vertical = page.y > rect.top && page.y < rect.bottom;\r\n\r\n dropped = horizontal && vertical;\r\n }\r\n\r\n var dragRect = draggable.getRect(draggableElement);\r\n\r\n if (dragRect && dropOverlap === 'center') {\r\n var cx = dragRect.left + dragRect.width / 2;\r\n var cy = dragRect.top + dragRect.height / 2;\r\n\r\n dropped = cx >= rect.left && cx <= rect.right && cy >= rect.top && cy <= rect.bottom;\r\n }\r\n\r\n if (dragRect && utils.is.number(dropOverlap)) {\r\n var overlapArea = Math.max(0, Math.min(rect.right, dragRect.right) - Math.max(rect.left, dragRect.left)) * Math.max(0, Math.min(rect.bottom, dragRect.bottom) - Math.max(rect.top, dragRect.top));\r\n\r\n var overlapRatio = overlapArea / (dragRect.width * dragRect.height);\r\n\r\n dropped = overlapRatio >= dropOverlap;\r\n }\r\n\r\n if (this.options.drop.checker) {\r\n dropped = this.options.drop.checker(dragEvent, event, dropped, this, dropElement, draggable, draggableElement);\r\n }\r\n\r\n return dropped;\r\n};\r\n\r\nInteractable.signals.on('unset', function (_ref7) {\r\n var interactable = _ref7.interactable;\r\n\r\n interactable.dropzone(false);\r\n});\r\n\r\nInteractable.settingsMethods.push('dropChecker');\r\n\r\nInteraction.signals.on('new', function (interaction) {\r\n interaction.dropTarget = null; // the dropzone a drag target might be dropped into\r\n interaction.dropElement = null; // the element at the time of checking\r\n interaction.prevDropTarget = null; // the dropzone that was recently dragged away from\r\n interaction.prevDropElement = null; // the element at the time of checking\r\n interaction.dropEvents = null; // the dropEvents related to the current drag event\r\n\r\n interaction.activeDrops = {\r\n dropzones: [], // the dropzones that are mentioned below\r\n elements: [], // elements of dropzones that accept the target draggable\r\n rects: [] // the rects of the elements mentioned above\r\n };\r\n});\r\n\r\nInteraction.signals.on('stop', function (_ref8) {\r\n var interaction = _ref8.interaction;\r\n\r\n interaction.dropTarget = interaction.dropElement = interaction.prevDropTarget = interaction.prevDropElement = null;\r\n});\r\n\r\n/*\\\r\n * interact.dynamicDrop\r\n [ method ]\r\n *\r\n * Returns or sets whether the dimensions of dropzone elements are\r\n * calculated on every dragmove or only on dragstart for the default\r\n * dropChecker\r\n *\r\n - newValue (boolean) #optional True to check on each move. False to check only before start\r\n = (boolean | interact) The current setting or interact\r\n\\*/\r\ninteract.dynamicDrop = function (newValue) {\r\n if (utils.is.bool(newValue)) {\r\n //if (dragging && dynamicDrop !== newValue && !newValue) {\r\n //calcRects(dropzones);\r\n //}\r\n\r\n dynamicDrop = newValue;\r\n\r\n return interact;\r\n }\r\n return dynamicDrop;\r\n};\r\n\r\nutils.merge(Interactable.eventTypes, ['dragenter', 'dragleave', 'dropactivate', 'dropdeactivate', 'dropmove', 'drop']);\r\nactions.methodDict.drop = 'dropzone';\r\n\r\ndefaultOptions.drop = drop.defaults;\r\n\r\nmodule.exports = drop;\r\n\r\n},{\"../InteractEvent\":3,\"../Interactable\":4,\"../Interaction\":5,\"../defaultOptions\":18,\"../interact\":21,\"../scope\":34,\"../utils\":44,\"./base\":6}],9:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar actions = require('./base');\r\nvar utils = require('../utils');\r\nvar InteractEvent = require('../InteractEvent');\r\nvar Interactable = require('../Interactable');\r\nvar Interaction = require('../Interaction');\r\nvar defaultOptions = require('../defaultOptions');\r\n\r\nvar gesture = {\r\n defaults: {\r\n enabled: false,\r\n origin: null,\r\n restrict: null\r\n },\r\n\r\n checker: function checker(pointer, event, interactable, element, interaction) {\r\n if (interaction.pointerIds.length >= 2) {\r\n return { name: 'gesture' };\r\n }\r\n\r\n return null;\r\n },\r\n\r\n getCursor: function getCursor() {\r\n return '';\r\n }\r\n};\r\n\r\nInteractEvent.signals.on('new', function (_ref) {\r\n var iEvent = _ref.iEvent,\r\n interaction = _ref.interaction;\r\n\r\n if (iEvent.type !== 'gesturestart') {\r\n return;\r\n }\r\n iEvent.ds = 0;\r\n\r\n interaction.gesture.startDistance = interaction.gesture.prevDistance = iEvent.distance;\r\n interaction.gesture.startAngle = interaction.gesture.prevAngle = iEvent.angle;\r\n interaction.gesture.scale = 1;\r\n});\r\n\r\nInteractEvent.signals.on('new', function (_ref2) {\r\n var iEvent = _ref2.iEvent,\r\n interaction = _ref2.interaction;\r\n\r\n if (iEvent.type !== 'gesturemove') {\r\n return;\r\n }\r\n\r\n iEvent.ds = iEvent.scale - interaction.gesture.scale;\r\n\r\n interaction.target.fire(iEvent);\r\n\r\n interaction.gesture.prevAngle = iEvent.angle;\r\n interaction.gesture.prevDistance = iEvent.distance;\r\n\r\n if (iEvent.scale !== Infinity && iEvent.scale !== null && iEvent.scale !== undefined && !isNaN(iEvent.scale)) {\r\n\r\n interaction.gesture.scale = iEvent.scale;\r\n }\r\n});\r\n\r\n/*\\\r\n * Interactable.gesturable\r\n [ method ]\r\n *\r\n * Gets or sets whether multitouch gestures can be performed on the\r\n * Interactable's element\r\n *\r\n = (boolean) Indicates if this can be the target of gesture events\r\n | var isGestureable = interact(element).gesturable();\r\n * or\r\n - options (boolean | object) #optional true/false or An object with event listeners to be fired on gesture events (makes the Interactable gesturable)\r\n = (object) this Interactable\r\n | interact(element).gesturable({\r\n | onstart: function (event) {},\r\n | onmove : function (event) {},\r\n | onend : function (event) {},\r\n |\r\n | // limit multiple gestures.\r\n | // See the explanation in @Interactable.draggable example\r\n | max: Infinity,\r\n | maxPerElement: 1,\r\n | });\r\n\\*/\r\nInteractable.prototype.gesturable = function (options) {\r\n if (utils.is.object(options)) {\r\n this.options.gesture.enabled = options.enabled === false ? false : true;\r\n this.setPerAction('gesture', options);\r\n this.setOnEvents('gesture', options);\r\n\r\n return this;\r\n }\r\n\r\n if (utils.is.bool(options)) {\r\n this.options.gesture.enabled = options;\r\n\r\n if (!options) {\r\n this.ongesturestart = this.ongesturestart = this.ongestureend = null;\r\n }\r\n\r\n return this;\r\n }\r\n\r\n return this.options.gesture;\r\n};\r\n\r\nInteractEvent.signals.on('set-delta', function (_ref3) {\r\n var interaction = _ref3.interaction,\r\n iEvent = _ref3.iEvent,\r\n action = _ref3.action,\r\n event = _ref3.event,\r\n starting = _ref3.starting,\r\n ending = _ref3.ending,\r\n deltaSource = _ref3.deltaSource;\r\n\r\n if (action !== 'gesture') {\r\n return;\r\n }\r\n\r\n var pointers = interaction.pointers;\r\n\r\n iEvent.touches = [pointers[0], pointers[1]];\r\n\r\n if (starting) {\r\n iEvent.distance = utils.touchDistance(pointers, deltaSource);\r\n iEvent.box = utils.touchBBox(pointers);\r\n iEvent.scale = 1;\r\n iEvent.ds = 0;\r\n iEvent.angle = utils.touchAngle(pointers, undefined, deltaSource);\r\n iEvent.da = 0;\r\n } else if (ending || event instanceof InteractEvent) {\r\n iEvent.distance = interaction.prevEvent.distance;\r\n iEvent.box = interaction.prevEvent.box;\r\n iEvent.scale = interaction.prevEvent.scale;\r\n iEvent.ds = iEvent.scale - 1;\r\n iEvent.angle = interaction.prevEvent.angle;\r\n iEvent.da = iEvent.angle - interaction.gesture.startAngle;\r\n } else {\r\n iEvent.distance = utils.touchDistance(pointers, deltaSource);\r\n iEvent.box = utils.touchBBox(pointers);\r\n iEvent.scale = iEvent.distance / interaction.gesture.startDistance;\r\n iEvent.angle = utils.touchAngle(pointers, interaction.gesture.prevAngle, deltaSource);\r\n\r\n iEvent.ds = iEvent.scale - interaction.gesture.prevScale;\r\n iEvent.da = iEvent.angle - interaction.gesture.prevAngle;\r\n }\r\n});\r\n\r\nInteraction.signals.on('new', function (interaction) {\r\n interaction.gesture = {\r\n start: { x: 0, y: 0 },\r\n\r\n startDistance: 0, // distance between two touches of touchStart\r\n prevDistance: 0,\r\n distance: 0,\r\n\r\n scale: 1, // gesture.distance / gesture.startDistance\r\n\r\n startAngle: 0, // angle of line joining two touches\r\n prevAngle: 0 // angle of the previous gesture event\r\n };\r\n});\r\n\r\nactions.gesture = gesture;\r\nactions.names.push('gesture');\r\nutils.merge(Interactable.eventTypes, ['gesturestart', 'gesturemove', 'gestureend']);\r\nactions.methodDict.gesture = 'gesturable';\r\n\r\ndefaultOptions.gesture = gesture.defaults;\r\n\r\nmodule.exports = gesture;\r\n\r\n},{\"../InteractEvent\":3,\"../Interactable\":4,\"../Interaction\":5,\"../defaultOptions\":18,\"../utils\":44,\"./base\":6}],10:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar actions = require('./base');\r\nvar utils = require('../utils');\r\nvar browser = require('../utils/browser');\r\nvar InteractEvent = require('../InteractEvent');\r\nvar Interactable = require('../Interactable');\r\nvar Interaction = require('../Interaction');\r\nvar defaultOptions = require('../defaultOptions');\r\n\r\n// Less Precision with touch input\r\nvar defaultMargin = browser.supportsTouch || browser.supportsPointerEvent ? 20 : 10;\r\n\r\nvar resize = {\r\n defaults: {\r\n enabled: false,\r\n mouseButtons: null,\r\n\r\n origin: null,\r\n snap: null,\r\n restrict: null,\r\n inertia: null,\r\n autoScroll: null,\r\n\r\n square: false,\r\n preserveAspectRatio: false,\r\n axis: 'xy',\r\n\r\n // use default margin\r\n margin: NaN,\r\n\r\n // object with props left, right, top, bottom which are\r\n // true/false values to resize when the pointer is over that edge,\r\n // CSS selectors to match the handles for each direction\r\n // or the Elements for each handle\r\n edges: null,\r\n\r\n // a value of 'none' will limit the resize rect to a minimum of 0x0\r\n // 'negate' will alow the rect to have negative width/height\r\n // 'reposition' will keep the width/height positive by swapping\r\n // the top and bottom edges and/or swapping the left and right edges\r\n invert: 'none'\r\n },\r\n\r\n checker: function checker(pointer, event, interactable, element, interaction, rect) {\r\n if (!rect) {\r\n return null;\r\n }\r\n\r\n var page = utils.extend({}, interaction.curCoords.page);\r\n var options = interactable.options;\r\n\r\n if (options.resize.enabled) {\r\n var resizeOptions = options.resize;\r\n var resizeEdges = { left: false, right: false, top: false, bottom: false };\r\n\r\n // if using resize.edges\r\n if (utils.is.object(resizeOptions.edges)) {\r\n for (var edge in resizeEdges) {\r\n resizeEdges[edge] = checkResizeEdge(edge, resizeOptions.edges[edge], page, interaction._eventTarget, element, rect, resizeOptions.margin || defaultMargin);\r\n }\r\n\r\n resizeEdges.left = resizeEdges.left && !resizeEdges.right;\r\n resizeEdges.top = resizeEdges.top && !resizeEdges.bottom;\r\n\r\n if (resizeEdges.left || resizeEdges.right || resizeEdges.top || resizeEdges.bottom) {\r\n return {\r\n name: 'resize',\r\n edges: resizeEdges\r\n };\r\n }\r\n } else {\r\n var right = options.resize.axis !== 'y' && page.x > rect.right - defaultMargin;\r\n var bottom = options.resize.axis !== 'x' && page.y > rect.bottom - defaultMargin;\r\n\r\n if (right || bottom) {\r\n return {\r\n name: 'resize',\r\n axes: (right ? 'x' : '') + (bottom ? 'y' : '')\r\n };\r\n }\r\n }\r\n }\r\n\r\n return null;\r\n },\r\n\r\n cursors: browser.isIe9OrOlder ? {\r\n x: 'e-resize',\r\n y: 's-resize',\r\n xy: 'se-resize',\r\n\r\n top: 'n-resize',\r\n left: 'w-resize',\r\n bottom: 's-resize',\r\n right: 'e-resize',\r\n topleft: 'se-resize',\r\n bottomright: 'se-resize',\r\n topright: 'ne-resize',\r\n bottomleft: 'ne-resize'\r\n } : {\r\n x: 'ew-resize',\r\n y: 'ns-resize',\r\n xy: 'nwse-resize',\r\n\r\n top: 'ns-resize',\r\n left: 'ew-resize',\r\n bottom: 'ns-resize',\r\n right: 'ew-resize',\r\n topleft: 'nwse-resize',\r\n bottomright: 'nwse-resize',\r\n topright: 'nesw-resize',\r\n bottomleft: 'nesw-resize'\r\n },\r\n\r\n getCursor: function getCursor(action) {\r\n if (action.axis) {\r\n return resize.cursors[action.name + action.axis];\r\n } else if (action.edges) {\r\n var cursorKey = '';\r\n var edgeNames = ['top', 'bottom', 'left', 'right'];\r\n\r\n for (var i = 0; i < 4; i++) {\r\n if (action.edges[edgeNames[i]]) {\r\n cursorKey += edgeNames[i];\r\n }\r\n }\r\n\r\n return resize.cursors[cursorKey];\r\n }\r\n }\r\n};\r\n\r\n// resizestart\r\nInteractEvent.signals.on('new', function (_ref) {\r\n var iEvent = _ref.iEvent,\r\n interaction = _ref.interaction;\r\n\r\n if (iEvent.type !== 'resizestart' || !interaction.prepared.edges) {\r\n return;\r\n }\r\n\r\n var startRect = interaction.target.getRect(interaction.element);\r\n var resizeOptions = interaction.target.options.resize;\r\n\r\n /*\r\n * When using the `resizable.square` or `resizable.preserveAspectRatio` options, resizing from one edge\r\n * will affect another. E.g. with `resizable.square`, resizing to make the right edge larger will make\r\n * the bottom edge larger by the same amount. We call these 'linked' edges. Any linked edges will depend\r\n * on the active edges and the edge being interacted with.\r\n */\r\n if (resizeOptions.square || resizeOptions.preserveAspectRatio) {\r\n var linkedEdges = utils.extend({}, interaction.prepared.edges);\r\n\r\n linkedEdges.top = linkedEdges.top || linkedEdges.left && !linkedEdges.bottom;\r\n linkedEdges.left = linkedEdges.left || linkedEdges.top && !linkedEdges.right;\r\n linkedEdges.bottom = linkedEdges.bottom || linkedEdges.right && !linkedEdges.top;\r\n linkedEdges.right = linkedEdges.right || linkedEdges.bottom && !linkedEdges.left;\r\n\r\n interaction.prepared._linkedEdges = linkedEdges;\r\n } else {\r\n interaction.prepared._linkedEdges = null;\r\n }\r\n\r\n // if using `resizable.preserveAspectRatio` option, record aspect ratio at the start of the resize\r\n if (resizeOptions.preserveAspectRatio) {\r\n interaction.resizeStartAspectRatio = startRect.width / startRect.height;\r\n }\r\n\r\n interaction.resizeRects = {\r\n start: startRect,\r\n current: utils.extend({}, startRect),\r\n inverted: utils.extend({}, startRect),\r\n previous: utils.extend({}, startRect),\r\n delta: {\r\n left: 0, right: 0, width: 0,\r\n top: 0, bottom: 0, height: 0\r\n }\r\n };\r\n\r\n iEvent.rect = interaction.resizeRects.inverted;\r\n iEvent.deltaRect = interaction.resizeRects.delta;\r\n});\r\n\r\n// resizemove\r\nInteractEvent.signals.on('new', function (_ref2) {\r\n var iEvent = _ref2.iEvent,\r\n phase = _ref2.phase,\r\n interaction = _ref2.interaction;\r\n\r\n if (phase !== 'move' || !interaction.prepared.edges) {\r\n return;\r\n }\r\n\r\n var resizeOptions = interaction.target.options.resize;\r\n var invert = resizeOptions.invert;\r\n var invertible = invert === 'reposition' || invert === 'negate';\r\n\r\n var edges = interaction.prepared.edges;\r\n\r\n var start = interaction.resizeRects.start;\r\n var current = interaction.resizeRects.current;\r\n var inverted = interaction.resizeRects.inverted;\r\n var delta = interaction.resizeRects.delta;\r\n var previous = utils.extend(interaction.resizeRects.previous, inverted);\r\n var originalEdges = edges;\r\n\r\n var dx = iEvent.dx;\r\n var dy = iEvent.dy;\r\n\r\n if (resizeOptions.preserveAspectRatio || resizeOptions.square) {\r\n // `resize.preserveAspectRatio` takes precedence over `resize.square`\r\n var startAspectRatio = resizeOptions.preserveAspectRatio ? interaction.resizeStartAspectRatio : 1;\r\n\r\n edges = interaction.prepared._linkedEdges;\r\n\r\n if (originalEdges.left && originalEdges.bottom || originalEdges.right && originalEdges.top) {\r\n dy = -dx / startAspectRatio;\r\n } else if (originalEdges.left || originalEdges.right) {\r\n dy = dx / startAspectRatio;\r\n } else if (originalEdges.top || originalEdges.bottom) {\r\n dx = dy * startAspectRatio;\r\n }\r\n }\r\n\r\n // update the 'current' rect without modifications\r\n if (edges.top) {\r\n current.top += dy;\r\n }\r\n if (edges.bottom) {\r\n current.bottom += dy;\r\n }\r\n if (edges.left) {\r\n current.left += dx;\r\n }\r\n if (edges.right) {\r\n current.right += dx;\r\n }\r\n\r\n if (invertible) {\r\n // if invertible, copy the current rect\r\n utils.extend(inverted, current);\r\n\r\n if (invert === 'reposition') {\r\n // swap edge values if necessary to keep width/height positive\r\n var swap = void 0;\r\n\r\n if (inverted.top > inverted.bottom) {\r\n swap = inverted.top;\r\n\r\n inverted.top = inverted.bottom;\r\n inverted.bottom = swap;\r\n }\r\n if (inverted.left > inverted.right) {\r\n swap = inverted.left;\r\n\r\n inverted.left = inverted.right;\r\n inverted.right = swap;\r\n }\r\n }\r\n } else {\r\n // if not invertible, restrict to minimum of 0x0 rect\r\n inverted.top = Math.min(current.top, start.bottom);\r\n inverted.bottom = Math.max(current.bottom, start.top);\r\n inverted.left = Math.min(current.left, start.right);\r\n inverted.right = Math.max(current.right, start.left);\r\n }\r\n\r\n inverted.width = inverted.right - inverted.left;\r\n inverted.height = inverted.bottom - inverted.top;\r\n\r\n for (var edge in inverted) {\r\n delta[edge] = inverted[edge] - previous[edge];\r\n }\r\n\r\n iEvent.edges = interaction.prepared.edges;\r\n iEvent.rect = inverted;\r\n iEvent.deltaRect = delta;\r\n});\r\n\r\n/*\\\r\n * Interactable.resizable\r\n [ method ]\r\n *\r\n * Gets or sets whether resize actions can be performed on the\r\n * Interactable\r\n *\r\n = (boolean) Indicates if this can be the target of resize elements\r\n | var isResizeable = interact('input[type=text]').resizable();\r\n * or\r\n - options (boolean | object) #optional true/false or An object with event listeners to be fired on resize events (object makes the Interactable resizable)\r\n = (object) This Interactable\r\n | interact(element).resizable({\r\n | onstart: function (event) {},\r\n | onmove : function (event) {},\r\n | onend : function (event) {},\r\n |\r\n | edges: {\r\n | top : true, // Use pointer coords to check for resize.\r\n | left : false, // Disable resizing from left edge.\r\n | bottom: '.resize-s',// Resize if pointer target matches selector\r\n | right : handleEl // Resize if pointer target is the given Element\r\n | },\r\n |\r\n | // Width and height can be adjusted independently. When `true`, width and\r\n | // height are adjusted at a 1:1 ratio.\r\n | square: false,\r\n |\r\n | // Width and height can be adjusted independently. When `true`, width and\r\n | // height maintain the aspect ratio they had when resizing started.\r\n | preserveAspectRatio: false,\r\n |\r\n | // a value of 'none' will limit the resize rect to a minimum of 0x0\r\n | // 'negate' will allow the rect to have negative width/height\r\n | // 'reposition' will keep the width/height positive by swapping\r\n | // the top and bottom edges and/or swapping the left and right edges\r\n | invert: 'none' || 'negate' || 'reposition'\r\n |\r\n | // limit multiple resizes.\r\n | // See the explanation in the @Interactable.draggable example\r\n | max: Infinity,\r\n | maxPerElement: 1,\r\n | });\r\n \\*/\r\nInteractable.prototype.resizable = function (options) {\r\n if (utils.is.object(options)) {\r\n this.options.resize.enabled = options.enabled === false ? false : true;\r\n this.setPerAction('resize', options);\r\n this.setOnEvents('resize', options);\r\n\r\n if (/^x$|^y$|^xy$/.test(options.axis)) {\r\n this.options.resize.axis = options.axis;\r\n } else if (options.axis === null) {\r\n this.options.resize.axis = defaultOptions.resize.axis;\r\n }\r\n\r\n if (utils.is.bool(options.preserveAspectRatio)) {\r\n this.options.resize.preserveAspectRatio = options.preserveAspectRatio;\r\n } else if (utils.is.bool(options.square)) {\r\n this.options.resize.square = options.square;\r\n }\r\n\r\n return this;\r\n }\r\n if (utils.is.bool(options)) {\r\n this.options.resize.enabled = options;\r\n\r\n if (!options) {\r\n this.onresizestart = this.onresizestart = this.onresizeend = null;\r\n }\r\n\r\n return this;\r\n }\r\n return this.options.resize;\r\n};\r\n\r\nfunction checkResizeEdge(name, value, page, element, interactableElement, rect, margin) {\r\n // false, '', undefined, null\r\n if (!value) {\r\n return false;\r\n }\r\n\r\n // true value, use pointer coords and element rect\r\n if (value === true) {\r\n // if dimensions are negative, \"switch\" edges\r\n var width = utils.is.number(rect.width) ? rect.width : rect.right - rect.left;\r\n var height = utils.is.number(rect.height) ? rect.height : rect.bottom - rect.top;\r\n\r\n if (width < 0) {\r\n if (name === 'left') {\r\n name = 'right';\r\n } else if (name === 'right') {\r\n name = 'left';\r\n }\r\n }\r\n if (height < 0) {\r\n if (name === 'top') {\r\n name = 'bottom';\r\n } else if (name === 'bottom') {\r\n name = 'top';\r\n }\r\n }\r\n\r\n if (name === 'left') {\r\n return page.x < (width >= 0 ? rect.left : rect.right) + margin;\r\n }\r\n if (name === 'top') {\r\n return page.y < (height >= 0 ? rect.top : rect.bottom) + margin;\r\n }\r\n\r\n if (name === 'right') {\r\n return page.x > (width >= 0 ? rect.right : rect.left) - margin;\r\n }\r\n if (name === 'bottom') {\r\n return page.y > (height >= 0 ? rect.bottom : rect.top) - margin;\r\n }\r\n }\r\n\r\n // the remaining checks require an element\r\n if (!utils.is.element(element)) {\r\n return false;\r\n }\r\n\r\n return utils.is.element(value)\r\n // the value is an element to use as a resize handle\r\n ? value === element\r\n // otherwise check if element matches value as selector\r\n : utils.matchesUpTo(element, value, interactableElement);\r\n}\r\n\r\nInteraction.signals.on('new', function (interaction) {\r\n interaction.resizeAxes = 'xy';\r\n});\r\n\r\nInteractEvent.signals.on('set-delta', function (_ref3) {\r\n var interaction = _ref3.interaction,\r\n iEvent = _ref3.iEvent,\r\n action = _ref3.action;\r\n\r\n if (action !== 'resize' || !interaction.resizeAxes) {\r\n return;\r\n }\r\n\r\n var options = interaction.target.options;\r\n\r\n if (options.resize.square) {\r\n if (interaction.resizeAxes === 'y') {\r\n iEvent.dx = iEvent.dy;\r\n } else {\r\n iEvent.dy = iEvent.dx;\r\n }\r\n iEvent.axes = 'xy';\r\n } else {\r\n iEvent.axes = interaction.resizeAxes;\r\n\r\n if (interaction.resizeAxes === 'x') {\r\n iEvent.dy = 0;\r\n } else if (interaction.resizeAxes === 'y') {\r\n iEvent.dx = 0;\r\n }\r\n }\r\n});\r\n\r\nactions.resize = resize;\r\nactions.names.push('resize');\r\nutils.merge(Interactable.eventTypes, ['resizestart', 'resizemove', 'resizeinertiastart', 'resizeinertiaresume', 'resizeend']);\r\nactions.methodDict.resize = 'resizable';\r\n\r\ndefaultOptions.resize = resize.defaults;\r\n\r\nmodule.exports = resize;\r\n\r\n},{\"../InteractEvent\":3,\"../Interactable\":4,\"../Interaction\":5,\"../defaultOptions\":18,\"../utils\":44,\"../utils/browser\":37,\"./base\":6}],11:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar raf = require('./utils/raf');\r\nvar getWindow = require('./utils/window').getWindow;\r\nvar is = require('./utils/is');\r\nvar domUtils = require('./utils/domUtils');\r\nvar Interaction = require('./Interaction');\r\nvar defaultOptions = require('./defaultOptions');\r\n\r\nvar autoScroll = {\r\n defaults: {\r\n enabled: false,\r\n container: null, // the item that is scrolled (Window or HTMLElement)\r\n margin: 60,\r\n speed: 300 // the scroll speed in pixels per second\r\n },\r\n\r\n interaction: null,\r\n i: null, // the handle returned by window.setInterval\r\n x: 0, y: 0, // Direction each pulse is to scroll in\r\n\r\n isScrolling: false,\r\n prevTime: 0,\r\n\r\n start: function start(interaction) {\r\n autoScroll.isScrolling = true;\r\n raf.cancel(autoScroll.i);\r\n\r\n autoScroll.interaction = interaction;\r\n autoScroll.prevTime = new Date().getTime();\r\n autoScroll.i = raf.request(autoScroll.scroll);\r\n },\r\n\r\n stop: function stop() {\r\n autoScroll.isScrolling = false;\r\n raf.cancel(autoScroll.i);\r\n },\r\n\r\n // scroll the window by the values in scroll.x/y\r\n scroll: function scroll() {\r\n var options = autoScroll.interaction.target.options[autoScroll.interaction.prepared.name].autoScroll;\r\n var container = options.container || getWindow(autoScroll.interaction.element);\r\n var now = new Date().getTime();\r\n // change in time in seconds\r\n var dt = (now - autoScroll.prevTime) / 1000;\r\n // displacement\r\n var s = options.speed * dt;\r\n\r\n if (s >= 1) {\r\n if (is.window(container)) {\r\n container.scrollBy(autoScroll.x * s, autoScroll.y * s);\r\n } else if (container) {\r\n container.scrollLeft += autoScroll.x * s;\r\n container.scrollTop += autoScroll.y * s;\r\n }\r\n\r\n autoScroll.prevTime = now;\r\n }\r\n\r\n if (autoScroll.isScrolling) {\r\n raf.cancel(autoScroll.i);\r\n autoScroll.i = raf.request(autoScroll.scroll);\r\n }\r\n },\r\n check: function check(interactable, actionName) {\r\n var options = interactable.options;\r\n\r\n return options[actionName].autoScroll && options[actionName].autoScroll.enabled;\r\n },\r\n onInteractionMove: function onInteractionMove(_ref) {\r\n var interaction = _ref.interaction,\r\n pointer = _ref.pointer;\r\n\r\n if (!(interaction.interacting() && autoScroll.check(interaction.target, interaction.prepared.name))) {\r\n return;\r\n }\r\n\r\n if (interaction.simulation) {\r\n autoScroll.x = autoScroll.y = 0;\r\n return;\r\n }\r\n\r\n var top = void 0;\r\n var right = void 0;\r\n var bottom = void 0;\r\n var left = void 0;\r\n\r\n var options = interaction.target.options[interaction.prepared.name].autoScroll;\r\n var container = options.container || getWindow(interaction.element);\r\n\r\n if (is.window(container)) {\r\n left = pointer.clientX < autoScroll.margin;\r\n top = pointer.clientY < autoScroll.margin;\r\n right = pointer.clientX > container.innerWidth - autoScroll.margin;\r\n bottom = pointer.clientY > container.innerHeight - autoScroll.margin;\r\n } else {\r\n var rect = domUtils.getElementClientRect(container);\r\n\r\n left = pointer.clientX < rect.left + autoScroll.margin;\r\n top = pointer.clientY < rect.top + autoScroll.margin;\r\n right = pointer.clientX > rect.right - autoScroll.margin;\r\n bottom = pointer.clientY > rect.bottom - autoScroll.margin;\r\n }\r\n\r\n autoScroll.x = right ? 1 : left ? -1 : 0;\r\n autoScroll.y = bottom ? 1 : top ? -1 : 0;\r\n\r\n if (!autoScroll.isScrolling) {\r\n // set the autoScroll properties to those of the target\r\n autoScroll.margin = options.margin;\r\n autoScroll.speed = options.speed;\r\n\r\n autoScroll.start(interaction);\r\n }\r\n }\r\n};\r\n\r\nInteraction.signals.on('stop-active', function () {\r\n autoScroll.stop();\r\n});\r\n\r\nInteraction.signals.on('action-move', autoScroll.onInteractionMove);\r\n\r\ndefaultOptions.perAction.autoScroll = autoScroll.defaults;\r\n\r\nmodule.exports = autoScroll;\r\n\r\n},{\"./Interaction\":5,\"./defaultOptions\":18,\"./utils/domUtils\":39,\"./utils/is\":46,\"./utils/raf\":50,\"./utils/window\":52}],12:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar Interactable = require('../Interactable');\r\nvar actions = require('../actions/base');\r\nvar is = require('../utils/is');\r\nvar domUtils = require('../utils/domUtils');\r\n\r\nInteractable.prototype.getAction = function (pointer, event, interaction, element) {\r\n var action = this.defaultActionChecker(pointer, event, interaction, element);\r\n\r\n if (this.options.actionChecker) {\r\n return this.options.actionChecker(pointer, event, action, this, element, interaction);\r\n }\r\n\r\n return action;\r\n};\r\n\r\n/*\\\r\n * Interactable.ignoreFrom\r\n [ method ]\r\n *\r\n * If the target of the `mousedown`, `pointerdown` or `touchstart`\r\n * event or any of it's parents match the given CSS selector or\r\n * Element, no drag/resize/gesture is started.\r\n *\r\n - newValue (string | Element | null) #optional a CSS selector string, an Element or `null` to not ignore any elements\r\n = (string | Element | object) The current ignoreFrom value or this Interactable\r\n **\r\n | interact(element, { ignoreFrom: document.getElementById('no-action') });\r\n | // or\r\n | interact(element).ignoreFrom('input, textarea, a');\r\n\\*/\r\nInteractable.prototype.ignoreFrom = function (newValue) {\r\n return this._backCompatOption('ignoreFrom', newValue);\r\n};\r\n\r\n/*\\\r\n * Interactable.allowFrom\r\n [ method ]\r\n *\r\n * A drag/resize/gesture is started only If the target of the\r\n * `mousedown`, `pointerdown` or `touchstart` event or any of it's\r\n * parents match the given CSS selector or Element.\r\n *\r\n - newValue (string | Element | null) #optional a CSS selector string, an Element or `null` to allow from any element\r\n = (string | Element | object) The current allowFrom value or this Interactable\r\n **\r\n | interact(element, { allowFrom: document.getElementById('drag-handle') });\r\n | // or\r\n | interact(element).allowFrom('.handle');\r\n\\*/\r\nInteractable.prototype.allowFrom = function (newValue) {\r\n return this._backCompatOption('allowFrom', newValue);\r\n};\r\n\r\nInteractable.prototype.testIgnore = function (ignoreFrom, interactableElement, element) {\r\n if (!ignoreFrom || !is.element(element)) {\r\n return false;\r\n }\r\n\r\n if (is.string(ignoreFrom)) {\r\n return domUtils.matchesUpTo(element, ignoreFrom, interactableElement);\r\n } else if (is.element(ignoreFrom)) {\r\n return domUtils.nodeContains(ignoreFrom, element);\r\n }\r\n\r\n return false;\r\n};\r\n\r\nInteractable.prototype.testAllow = function (allowFrom, interactableElement, element) {\r\n if (!allowFrom) {\r\n return true;\r\n }\r\n\r\n if (!is.element(element)) {\r\n return false;\r\n }\r\n\r\n if (is.string(allowFrom)) {\r\n return domUtils.matchesUpTo(element, allowFrom, interactableElement);\r\n } else if (is.element(allowFrom)) {\r\n return domUtils.nodeContains(allowFrom, element);\r\n }\r\n\r\n return false;\r\n};\r\n\r\nInteractable.prototype.testIgnoreAllow = function (options, interactableElement, eventTarget) {\r\n return !this.testIgnore(options.ignoreFrom, interactableElement, eventTarget) && this.testAllow(options.allowFrom, interactableElement, eventTarget);\r\n};\r\n\r\n/*\\\r\n * Interactable.actionChecker\r\n [ method ]\r\n *\r\n * Gets or sets the function used to check action to be performed on\r\n * pointerDown\r\n *\r\n - checker (function | null) #optional A function which takes a pointer event, defaultAction string, interactable, element and interaction as parameters and returns an object with name property 'drag' 'resize' or 'gesture' and optionally an `edges` object with boolean 'top', 'left', 'bottom' and right props.\r\n = (Function | Interactable) The checker function or this Interactable\r\n *\r\n | interact('.resize-drag')\r\n | .resizable(true)\r\n | .draggable(true)\r\n | .actionChecker(function (pointer, event, action, interactable, element, interaction) {\r\n |\r\n | if (interact.matchesSelector(event.target, '.drag-handle') {\r\n | // force drag with handle target\r\n | action.name = drag;\r\n | }\r\n | else {\r\n | // resize from the top and right edges\r\n | action.name = 'resize';\r\n | action.edges = { top: true, right: true };\r\n | }\r\n |\r\n | return action;\r\n | });\r\n\\*/\r\nInteractable.prototype.actionChecker = function (checker) {\r\n if (is.function(checker)) {\r\n this.options.actionChecker = checker;\r\n\r\n return this;\r\n }\r\n\r\n if (checker === null) {\r\n delete this.options.actionChecker;\r\n\r\n return this;\r\n }\r\n\r\n return this.options.actionChecker;\r\n};\r\n\r\n/*\\\r\n * Interactable.styleCursor\r\n [ method ]\r\n *\r\n * Returns or sets whether the the cursor should be changed depending on the\r\n * action that would be performed if the mouse were pressed and dragged.\r\n *\r\n - newValue (boolean) #optional\r\n = (boolean | Interactable) The current setting or this Interactable\r\n\\*/\r\nInteractable.prototype.styleCursor = function (newValue) {\r\n if (is.bool(newValue)) {\r\n this.options.styleCursor = newValue;\r\n\r\n return this;\r\n }\r\n\r\n if (newValue === null) {\r\n delete this.options.styleCursor;\r\n\r\n return this;\r\n }\r\n\r\n return this.options.styleCursor;\r\n};\r\n\r\nInteractable.prototype.defaultActionChecker = function (pointer, event, interaction, element) {\r\n var rect = this.getRect(element);\r\n var action = null;\r\n\r\n for (var _iterator = actions.names, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\r\n var _ref;\r\n\r\n if (_isArray) {\r\n if (_i >= _iterator.length) break;\r\n _ref = _iterator[_i++];\r\n } else {\r\n _i = _iterator.next();\r\n if (_i.done) break;\r\n _ref = _i.value;\r\n }\r\n\r\n var actionName = _ref;\r\n\r\n // check mouseButton setting if the pointer is down\r\n if (interaction.pointerIsDown && interaction.mouse && (event.buttons & this.options[actionName].mouseButtons) === 0) {\r\n continue;\r\n }\r\n\r\n action = actions[actionName].checker(pointer, event, this, element, interaction, rect);\r\n\r\n if (action) {\r\n return action;\r\n }\r\n }\r\n};\r\n\r\n},{\"../Interactable\":4,\"../actions/base\":6,\"../utils/domUtils\":39,\"../utils/is\":46}],13:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar interact = require('../interact');\r\nvar Interactable = require('../Interactable');\r\nvar Interaction = require('../Interaction');\r\nvar actions = require('../actions/base');\r\nvar defaultOptions = require('../defaultOptions');\r\nvar browser = require('../utils/browser');\r\nvar scope = require('../scope');\r\nvar utils = require('../utils');\r\nvar signals = require('../utils/Signals').new();\r\n\r\nrequire('./InteractableMethods');\r\n\r\nvar autoStart = {\r\n signals: signals,\r\n withinInteractionLimit: withinInteractionLimit,\r\n // Allow this many interactions to happen simultaneously\r\n maxInteractions: Infinity,\r\n defaults: {\r\n perAction: {\r\n manualStart: false,\r\n max: Infinity,\r\n maxPerElement: 1,\r\n allowFrom: null,\r\n ignoreFrom: null\r\n }\r\n },\r\n setActionDefaults: function setActionDefaults(action) {\r\n utils.extend(action.defaults, autoStart.defaults.perAction);\r\n }\r\n};\r\n\r\n// set cursor style on mousedown\r\nInteraction.signals.on('down', function (_ref) {\r\n var interaction = _ref.interaction,\r\n pointer = _ref.pointer,\r\n event = _ref.event,\r\n eventTarget = _ref.eventTarget;\r\n\r\n if (interaction.interacting()) {\r\n return;\r\n }\r\n\r\n var actionInfo = getActionInfo(interaction, pointer, event, eventTarget);\r\n prepare(interaction, actionInfo);\r\n});\r\n\r\n// set cursor style on mousemove\r\nInteraction.signals.on('move', function (_ref2) {\r\n var interaction = _ref2.interaction,\r\n pointer = _ref2.pointer,\r\n event = _ref2.event,\r\n eventTarget = _ref2.eventTarget;\r\n\r\n if (!interaction.mouse || interaction.pointerIsDown || interaction.interacting()) {\r\n return;\r\n }\r\n\r\n var actionInfo = getActionInfo(interaction, pointer, event, eventTarget);\r\n prepare(interaction, actionInfo);\r\n});\r\n\r\nInteraction.signals.on('move', function (arg) {\r\n var interaction = arg.interaction,\r\n event = arg.event;\r\n\r\n\r\n if (!interaction.pointerIsDown || interaction.interacting() || !interaction.pointerWasMoved || !interaction.prepared.name) {\r\n return;\r\n }\r\n\r\n signals.fire('before-start', arg);\r\n\r\n var target = interaction.target;\r\n\r\n if (interaction.prepared.name && target) {\r\n // check manualStart and interaction limit\r\n if (target.options[interaction.prepared.name].manualStart || !withinInteractionLimit(target, interaction.element, interaction.prepared)) {\r\n interaction.stop(event);\r\n } else {\r\n interaction.start(interaction.prepared, target, interaction.element);\r\n }\r\n }\r\n});\r\n\r\n// Check if the current target supports the action.\r\n// If so, return the validated action. Otherwise, return null\r\nfunction validateAction(action, interactable, element, eventTarget) {\r\n if (utils.is.object(action) && interactable.testIgnoreAllow(interactable.options[action.name], element, eventTarget) && interactable.options[action.name].enabled && withinInteractionLimit(interactable, element, action)) {\r\n return action;\r\n }\r\n\r\n return null;\r\n}\r\n\r\nfunction validateSelector(interaction, pointer, event, matches, matchElements, eventTarget) {\r\n for (var i = 0, len = matches.length; i < len; i++) {\r\n var match = matches[i];\r\n var matchElement = matchElements[i];\r\n var action = validateAction(match.getAction(pointer, event, interaction, matchElement), match, matchElement, eventTarget);\r\n\r\n if (action) {\r\n return {\r\n action: action,\r\n target: match,\r\n element: matchElement\r\n };\r\n }\r\n }\r\n\r\n return {};\r\n}\r\n\r\nfunction getActionInfo(interaction, pointer, event, eventTarget) {\r\n var matches = [];\r\n var matchElements = [];\r\n\r\n var element = eventTarget;\r\n var action = null;\r\n\r\n function pushMatches(interactable, selector, context) {\r\n var elements = browser.useMatchesSelectorPolyfill ? context.querySelectorAll(selector) : undefined;\r\n\r\n if (utils.matchesSelector(element, selector, elements)) {\r\n\r\n matches.push(interactable);\r\n matchElements.push(element);\r\n }\r\n }\r\n\r\n while (utils.is.element(element)) {\r\n matches = [];\r\n matchElements = [];\r\n\r\n var elementInteractable = scope.interactables.get(element);\r\n\r\n if (elementInteractable && (action = validateAction(elementInteractable.getAction(pointer, event, interaction, element, eventTarget), elementInteractable, element, eventTarget)) && !elementInteractable.options[action.name].manualStart) {\r\n return {\r\n element: element,\r\n action: action,\r\n target: elementInteractable\r\n };\r\n } else {\r\n scope.interactables.forEachSelector(pushMatches, element);\r\n\r\n var actionInfo = validateSelector(interaction, pointer, event, matches, matchElements, eventTarget);\r\n\r\n if (actionInfo.action && !actionInfo.target.options[actionInfo.action.name].manualStart) {\r\n return actionInfo;\r\n }\r\n }\r\n\r\n element = utils.parentNode(element);\r\n }\r\n\r\n return {};\r\n}\r\n\r\nfunction prepare(interaction, _ref3) {\r\n var action = _ref3.action,\r\n target = _ref3.target,\r\n element = _ref3.element;\r\n\r\n action = action || {};\r\n\r\n if (interaction.target && interaction.target.options.styleCursor) {\r\n interaction.target._doc.documentElement.style.cursor = '';\r\n }\r\n\r\n interaction.target = target;\r\n interaction.element = element;\r\n utils.copyAction(interaction.prepared, action);\r\n\r\n if (target && target.options.styleCursor) {\r\n var cursor = action ? actions[action.name].getCursor(action) : '';\r\n interaction.target._doc.documentElement.style.cursor = cursor;\r\n }\r\n\r\n signals.fire('prepared', { interaction: interaction });\r\n}\r\n\r\nInteraction.signals.on('stop', function (_ref4) {\r\n var interaction = _ref4.interaction;\r\n\r\n var target = interaction.target;\r\n\r\n if (target && target.options.styleCursor) {\r\n target._doc.documentElement.style.cursor = '';\r\n }\r\n});\r\n\r\nInteractable.prototype.getAction = function (pointer, event, interaction, element) {\r\n var action = this.defaultActionChecker(pointer, event, interaction, element);\r\n\r\n if (this.options.actionChecker) {\r\n return this.options.actionChecker(pointer, event, action, this, element, interaction);\r\n }\r\n\r\n return action;\r\n};\r\n\r\n/*\\\r\n * Interactable.actionChecker\r\n [ method ]\r\n *\r\n * Gets or sets the function used to check action to be performed on\r\n * pointerDown\r\n *\r\n - checker (function | null) #optional A function which takes a pointer event, defaultAction string, interactable, element and interaction as parameters and returns an object with name property 'drag' 'resize' or 'gesture' and optionally an `edges` object with boolean 'top', 'left', 'bottom' and right props.\r\n = (Function | Interactable) The checker function or this Interactable\r\n *\r\n | interact('.resize-drag')\r\n | .resizable(true)\r\n | .draggable(true)\r\n | .actionChecker(function (pointer, event, action, interactable, element, interaction) {\r\n |\r\n | if (interact.matchesSelector(event.target, '.drag-handle') {\r\n | // force drag with handle target\r\n | action.name = drag;\r\n | }\r\n | else {\r\n | // resize from the top and right edges\r\n | action.name = 'resize';\r\n | action.edges = { top: true, right: true };\r\n | }\r\n |\r\n | return action;\r\n | });\r\n\\*/\r\nInteractable.prototype.actionChecker = function (checker) {\r\n if (utils.is.function(checker)) {\r\n this.options.actionChecker = checker;\r\n\r\n return this;\r\n }\r\n\r\n if (checker === null) {\r\n delete this.options.actionChecker;\r\n\r\n return this;\r\n }\r\n\r\n return this.options.actionChecker;\r\n};\r\n\r\n/*\\\r\n * Interactable.styleCursor\r\n [ method ]\r\n *\r\n * Returns or sets whether the the cursor should be changed depending on the\r\n * action that would be performed if the mouse were pressed and dragged.\r\n *\r\n - newValue (boolean) #optional\r\n = (boolean | Interactable) The current setting or this Interactable\r\n\\*/\r\nInteractable.prototype.styleCursor = function (newValue) {\r\n if (utils.is.bool(newValue)) {\r\n this.options.styleCursor = newValue;\r\n\r\n return this;\r\n }\r\n\r\n if (newValue === null) {\r\n delete this.options.styleCursor;\r\n\r\n return this;\r\n }\r\n\r\n return this.options.styleCursor;\r\n};\r\n\r\nInteractable.prototype.defaultActionChecker = function (pointer, event, interaction, element) {\r\n var rect = this.getRect(element);\r\n var buttons = event.buttons || {\r\n 0: 1,\r\n 1: 4,\r\n 3: 8,\r\n 4: 16\r\n }[event.button];\r\n var action = null;\r\n\r\n for (var _iterator = actions.names, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\r\n var _ref5;\r\n\r\n if (_isArray) {\r\n if (_i >= _iterator.length) break;\r\n _ref5 = _iterator[_i++];\r\n } else {\r\n _i = _iterator.next();\r\n if (_i.done) break;\r\n _ref5 = _i.value;\r\n }\r\n\r\n var actionName = _ref5;\r\n\r\n // check mouseButton setting if the pointer is down\r\n if (interaction.pointerIsDown && interaction.mouse && (buttons & this.options[actionName].mouseButtons) === 0) {\r\n continue;\r\n }\r\n\r\n action = actions[actionName].checker(pointer, event, this, element, interaction, rect);\r\n\r\n if (action) {\r\n return action;\r\n }\r\n }\r\n};\r\n\r\nfunction withinInteractionLimit(interactable, element, action) {\r\n var options = interactable.options;\r\n var maxActions = options[action.name].max;\r\n var maxPerElement = options[action.name].maxPerElement;\r\n var activeInteractions = 0;\r\n var targetCount = 0;\r\n var targetElementCount = 0;\r\n\r\n // no actions if any of these values == 0\r\n if (!(maxActions && maxPerElement && autoStart.maxInteractions)) {\r\n return;\r\n }\r\n\r\n for (var i = 0, len = scope.interactions.length; i < len; i++) {\r\n var interaction = scope.interactions[i];\r\n var otherAction = interaction.prepared.name;\r\n\r\n if (!interaction.interacting()) {\r\n continue;\r\n }\r\n\r\n activeInteractions++;\r\n\r\n if (activeInteractions >= autoStart.maxInteractions) {\r\n return false;\r\n }\r\n\r\n if (interaction.target !== interactable) {\r\n continue;\r\n }\r\n\r\n targetCount += otherAction === action.name | 0;\r\n\r\n if (targetCount >= maxActions) {\r\n return false;\r\n }\r\n\r\n if (interaction.element === element) {\r\n targetElementCount++;\r\n\r\n if (otherAction !== action.name || targetElementCount >= maxPerElement) {\r\n return false;\r\n }\r\n }\r\n }\r\n\r\n return autoStart.maxInteractions > 0;\r\n}\r\n\r\n/*\\\r\n * interact.maxInteractions\r\n [ method ]\r\n **\r\n * Returns or sets the maximum number of concurrent interactions allowed.\r\n * By default only 1 interaction is allowed at a time (for backwards\r\n * compatibility). To allow multiple interactions on the same Interactables\r\n * and elements, you need to enable it in the draggable, resizable and\r\n * gesturable `'max'` and `'maxPerElement'` options.\r\n **\r\n - newValue (number) #optional Any number. newValue <= 0 means no interactions.\r\n\\*/\r\ninteract.maxInteractions = function (newValue) {\r\n if (utils.is.number(newValue)) {\r\n autoStart.maxInteractions = newValue;\r\n\r\n return this;\r\n }\r\n\r\n return autoStart.maxInteractions;\r\n};\r\n\r\nInteractable.settingsMethods.push('styleCursor');\r\nInteractable.settingsMethods.push('actionChecker');\r\nInteractable.settingsMethods.push('ignoreFrom');\r\nInteractable.settingsMethods.push('allowFrom');\r\n\r\ndefaultOptions.base.actionChecker = null;\r\ndefaultOptions.base.styleCursor = true;\r\n\r\nutils.extend(defaultOptions.perAction, autoStart.defaults.perAction);\r\n\r\nmodule.exports = autoStart;\r\n\r\n},{\"../Interactable\":4,\"../Interaction\":5,\"../actions/base\":6,\"../defaultOptions\":18,\"../interact\":21,\"../scope\":34,\"../utils\":44,\"../utils/Signals\":35,\"../utils/browser\":37,\"./InteractableMethods\":12}],14:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar autoStart = require('./base');\r\nvar Interaction = require('../Interaction');\r\n\r\nInteraction.signals.on('new', function (interaction) {\r\n interaction.delayTimer = null;\r\n});\r\n\r\nautoStart.signals.on('prepared', function (_ref) {\r\n var interaction = _ref.interaction;\r\n\r\n var actionName = interaction.prepared.name;\r\n\r\n if (!actionName) {\r\n return;\r\n }\r\n\r\n var delay = interaction.target.options[actionName].delay;\r\n\r\n if (delay > 0) {\r\n interaction.delayTimer = setTimeout(function () {\r\n interaction.start(interaction.prepared, interaction.target, interaction.element);\r\n }, delay);\r\n }\r\n});\r\n\r\nInteraction.signals.on('move', function (_ref2) {\r\n var interaction = _ref2.interaction,\r\n duplicate = _ref2.duplicate;\r\n\r\n if (interaction.pointerWasMoved && !duplicate) {\r\n clearTimeout(interaction.delayTimer);\r\n }\r\n});\r\n\r\n// prevent regular down->move autoStart\r\nautoStart.signals.on('before-start', function (_ref3) {\r\n var interaction = _ref3.interaction;\r\n\r\n var actionName = interaction.prepared.name;\r\n\r\n if (!actionName) {\r\n return;\r\n }\r\n\r\n var delay = interaction.target.options[actionName].delay;\r\n\r\n if (delay > 0) {\r\n interaction.prepared.name = null;\r\n }\r\n});\r\n\r\n},{\"../Interaction\":5,\"./base\":13}],15:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar autoStart = require('./base');\r\nvar scope = require('../scope');\r\nvar browser = require('../utils/browser');\r\nvar is = require('../utils/is');\r\n\r\nvar _require = require('../utils/domUtils'),\r\n matchesSelector = _require.matchesSelector,\r\n parentNode = _require.parentNode;\r\n\r\nautoStart.setActionDefaults(require('../actions/drag'));\r\n\r\nautoStart.signals.on('before-start', function (_ref) {\r\n var interaction = _ref.interaction,\r\n eventTarget = _ref.eventTarget,\r\n dx = _ref.dx,\r\n dy = _ref.dy;\r\n\r\n if (interaction.prepared.name !== 'drag') {\r\n return;\r\n }\r\n\r\n // check if a drag is in the correct axis\r\n var absX = Math.abs(dx);\r\n var absY = Math.abs(dy);\r\n var options = interaction.target.options.drag;\r\n var startAxis = options.startAxis;\r\n var currentAxis = absX > absY ? 'x' : absX < absY ? 'y' : 'xy';\r\n\r\n interaction.prepared.axis = options.lockAxis === 'start' ? currentAxis[0] // always lock to one axis even if currentAxis === 'xy'\r\n : options.lockAxis;\r\n\r\n // if the movement isn't in the startAxis of the interactable\r\n if (currentAxis !== 'xy' && startAxis !== 'xy' && startAxis !== currentAxis) {\r\n // cancel the prepared action\r\n interaction.prepared.name = null;\r\n\r\n // then try to get a drag from another ineractable\r\n\r\n if (!interaction.prepared.name) {\r\n\r\n var element = eventTarget;\r\n\r\n var getDraggable = function getDraggable(interactable, selector, context) {\r\n var elements = browser.useMatchesSelectorPolyfill ? context.querySelectorAll(selector) : undefined;\r\n\r\n if (interactable === interaction.target) {\r\n return;\r\n }\r\n\r\n if (!options.manualStart && !interactable.testIgnoreAllow(options, element, eventTarget) && matchesSelector(element, selector, elements)) {\r\n\r\n var _action = interactable.getAction(interaction.downPointer, interaction.downEvent, interaction, element);\r\n\r\n if (_action && _action.name === 'drag' && checkStartAxis(currentAxis, interactable) && autoStart.validateAction(_action, interactable, element, eventTarget)) {\r\n\r\n return interactable;\r\n }\r\n }\r\n };\r\n\r\n var action = null;\r\n\r\n // check all interactables\r\n while (is.element(element)) {\r\n var elementInteractable = scope.interactables.get(element);\r\n\r\n if (elementInteractable && elementInteractable !== interaction.target && !elementInteractable.options.drag.manualStart) {\r\n\r\n action = elementInteractable.getAction(interaction.downPointer, interaction.downEvent, interaction, element);\r\n }\r\n if (action && action.name === 'drag' && checkStartAxis(currentAxis, elementInteractable)) {\r\n\r\n interaction.prepared.name = 'drag';\r\n interaction.target = elementInteractable;\r\n interaction.element = element;\r\n break;\r\n }\r\n\r\n var selectorInteractable = scope.interactables.forEachSelector(getDraggable, element);\r\n\r\n if (selectorInteractable) {\r\n interaction.prepared.name = 'drag';\r\n interaction.target = selectorInteractable;\r\n interaction.element = element;\r\n break;\r\n }\r\n\r\n element = parentNode(element);\r\n }\r\n }\r\n }\r\n});\r\n\r\nfunction checkStartAxis(startAxis, interactable) {\r\n if (!interactable) {\r\n return false;\r\n }\r\n\r\n var thisAxis = interactable.options.drag.startAxis;\r\n\r\n return startAxis === 'xy' || thisAxis === 'xy' || thisAxis === startAxis;\r\n}\r\n\r\n},{\"../actions/drag\":7,\"../scope\":34,\"../utils/browser\":37,\"../utils/domUtils\":39,\"../utils/is\":46,\"./base\":13}],16:[function(require,module,exports){\r\n'use strict';\r\n\r\nrequire('./base').setActionDefaults(require('../actions/gesture'));\r\n\r\n},{\"../actions/gesture\":9,\"./base\":13}],17:[function(require,module,exports){\r\n'use strict';\r\n\r\nrequire('./base').setActionDefaults(require('../actions/resize'));\r\n\r\n},{\"../actions/resize\":10,\"./base\":13}],18:[function(require,module,exports){\r\n'use strict';\r\n\r\nmodule.exports = {\r\n base: {\r\n accept: null,\r\n preventDefault: 'auto',\r\n deltaSource: 'page'\r\n },\r\n\r\n perAction: {\r\n origin: { x: 0, y: 0 },\r\n\r\n // only allow left button by default\r\n // see https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons#Return_value\r\n mouseButtons: 1,\r\n\r\n inertia: {\r\n enabled: false,\r\n resistance: 10, // the lambda in exponential decay\r\n minSpeed: 100, // target speed must be above this for inertia to start\r\n endSpeed: 10, // the speed at which inertia is slow enough to stop\r\n allowResume: true, // allow resuming an action in inertia phase\r\n smoothEndDuration: 300 // animate to snap/restrict endOnly if there's no inertia\r\n }\r\n }\r\n};\r\n\r\n},{}],19:[function(require,module,exports){\r\n'use strict';\r\n\r\n/* browser entry point */\r\n\r\n// Legacy browser support\r\nrequire('./legacyBrowsers');\r\n\r\n// inertia\r\nrequire('./inertia');\r\n\r\n// modifiers\r\nrequire('./modifiers/snap');\r\nrequire('./modifiers/restrict');\r\n\r\n// pointerEvents\r\nrequire('./pointerEvents/base');\r\nrequire('./pointerEvents/holdRepeat');\r\nrequire('./pointerEvents/interactableTargets');\r\n\r\n// delay\r\nrequire('./autoStart/delay');\r\n\r\n// actions\r\nrequire('./actions/gesture');\r\nrequire('./actions/resize');\r\nrequire('./actions/drag');\r\nrequire('./actions/drop');\r\n\r\n// load these modifiers after resize is loaded\r\nrequire('./modifiers/snapSize');\r\nrequire('./modifiers/restrictEdges');\r\nrequire('./modifiers/restrictSize');\r\n\r\n// autoStart actions\r\nrequire('./autoStart/gesture');\r\nrequire('./autoStart/resize');\r\nrequire('./autoStart/drag');\r\n\r\n// Interactable preventDefault setting\r\nrequire('./interactablePreventDefault.js');\r\n\r\n// autoScroll\r\nrequire('./autoScroll');\r\n\r\n// export interact\r\nmodule.exports = require('./interact');\r\n\r\n},{\"./actions/drag\":7,\"./actions/drop\":8,\"./actions/gesture\":9,\"./actions/resize\":10,\"./autoScroll\":11,\"./autoStart/delay\":14,\"./autoStart/drag\":15,\"./autoStart/gesture\":16,\"./autoStart/resize\":17,\"./inertia\":20,\"./interact\":21,\"./interactablePreventDefault.js\":22,\"./legacyBrowsers\":23,\"./modifiers/restrict\":25,\"./modifiers/restrictEdges\":26,\"./modifiers/restrictSize\":27,\"./modifiers/snap\":28,\"./modifiers/snapSize\":29,\"./pointerEvents/base\":31,\"./pointerEvents/holdRepeat\":32,\"./pointerEvents/interactableTargets\":33}],20:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar InteractEvent = require('./InteractEvent');\r\nvar Interaction = require('./Interaction');\r\nvar modifiers = require('./modifiers');\r\nvar utils = require('./utils');\r\nvar animationFrame = require('./utils/raf');\r\n\r\nInteraction.signals.on('new', function (interaction) {\r\n interaction.inertiaStatus = {\r\n active: false,\r\n smoothEnd: false,\r\n allowResume: false,\r\n\r\n startEvent: null,\r\n upCoords: {},\r\n\r\n xe: 0, ye: 0,\r\n sx: 0, sy: 0,\r\n\r\n t0: 0,\r\n vx0: 0, vys: 0,\r\n duration: 0,\r\n\r\n lambda_v0: 0,\r\n one_ve_v0: 0,\r\n i: null\r\n };\r\n\r\n interaction.boundInertiaFrame = function () {\r\n return inertiaFrame.apply(interaction);\r\n };\r\n interaction.boundSmoothEndFrame = function () {\r\n return smoothEndFrame.apply(interaction);\r\n };\r\n});\r\n\r\nInteraction.signals.on('down', function (_ref) {\r\n var interaction = _ref.interaction,\r\n event = _ref.event,\r\n pointer = _ref.pointer,\r\n eventTarget = _ref.eventTarget;\r\n\r\n var status = interaction.inertiaStatus;\r\n\r\n // Check if the down event hits the current inertia target\r\n if (status.active) {\r\n var element = eventTarget;\r\n\r\n // climb up the DOM tree from the event target\r\n while (utils.is.element(element)) {\r\n\r\n // if interaction element is the current inertia target element\r\n if (element === interaction.element) {\r\n // stop inertia\r\n animationFrame.cancel(status.i);\r\n status.active = false;\r\n interaction.simulation = null;\r\n\r\n // update pointers to the down event's coordinates\r\n interaction.updatePointer(pointer);\r\n utils.setCoords(interaction.curCoords, interaction.pointers);\r\n\r\n // fire appropriate signals\r\n var signalArg = { interaction: interaction };\r\n Interaction.signals.fire('before-action-move', signalArg);\r\n Interaction.signals.fire('action-resume', signalArg);\r\n\r\n // fire a reume event\r\n var resumeEvent = new InteractEvent(interaction, event, interaction.prepared.name, 'inertiaresume', interaction.element);\r\n\r\n interaction.target.fire(resumeEvent);\r\n interaction.prevEvent = resumeEvent;\r\n modifiers.resetStatuses(interaction.modifierStatuses);\r\n\r\n utils.copyCoords(interaction.prevCoords, interaction.curCoords);\r\n break;\r\n }\r\n\r\n element = utils.parentNode(element);\r\n }\r\n }\r\n});\r\n\r\nInteraction.signals.on('up', function (_ref2) {\r\n var interaction = _ref2.interaction,\r\n event = _ref2.event;\r\n\r\n var status = interaction.inertiaStatus;\r\n\r\n if (!interaction.interacting() || status.active) {\r\n return;\r\n }\r\n\r\n var target = interaction.target;\r\n var options = target && target.options;\r\n var inertiaOptions = options && interaction.prepared.name && options[interaction.prepared.name].inertia;\r\n\r\n var now = new Date().getTime();\r\n var statuses = {};\r\n var page = utils.extend({}, interaction.curCoords.page);\r\n var pointerSpeed = interaction.pointerDelta.client.speed;\r\n\r\n var smoothEnd = false;\r\n var modifierResult = void 0;\r\n\r\n // check if inertia should be started\r\n var inertiaPossible = inertiaOptions && inertiaOptions.enabled && interaction.prepared.name !== 'gesture' && event !== status.startEvent;\r\n\r\n var inertia = inertiaPossible && now - interaction.curCoords.timeStamp < 50 && pointerSpeed > inertiaOptions.minSpeed && pointerSpeed > inertiaOptions.endSpeed;\r\n\r\n var modifierArg = {\r\n interaction: interaction,\r\n pageCoords: page,\r\n statuses: statuses,\r\n preEnd: true,\r\n requireEndOnly: true\r\n };\r\n\r\n // smoothEnd\r\n if (inertiaPossible && !inertia) {\r\n modifiers.resetStatuses(statuses);\r\n\r\n modifierResult = modifiers.setAll(modifierArg);\r\n\r\n if (modifierResult.shouldMove && modifierResult.locked) {\r\n smoothEnd = true;\r\n }\r\n }\r\n\r\n if (!(inertia || smoothEnd)) {\r\n return;\r\n }\r\n\r\n utils.copyCoords(status.upCoords, interaction.curCoords);\r\n\r\n interaction.pointers[0] = status.startEvent = new InteractEvent(interaction, event, interaction.prepared.name, 'inertiastart', interaction.element);\r\n\r\n status.t0 = now;\r\n\r\n status.active = true;\r\n status.allowResume = inertiaOptions.allowResume;\r\n interaction.simulation = status;\r\n\r\n target.fire(status.startEvent);\r\n\r\n if (inertia) {\r\n status.vx0 = interaction.pointerDelta.client.vx;\r\n status.vy0 = interaction.pointerDelta.client.vy;\r\n status.v0 = pointerSpeed;\r\n\r\n calcInertia(interaction, status);\r\n\r\n utils.extend(page, interaction.curCoords.page);\r\n\r\n page.x += status.xe;\r\n page.y += status.ye;\r\n\r\n modifiers.resetStatuses(statuses);\r\n\r\n modifierResult = modifiers.setAll(modifierArg);\r\n\r\n status.modifiedXe += modifierResult.dx;\r\n status.modifiedYe += modifierResult.dy;\r\n\r\n status.i = animationFrame.request(interaction.boundInertiaFrame);\r\n } else {\r\n status.smoothEnd = true;\r\n status.xe = modifierResult.dx;\r\n status.ye = modifierResult.dy;\r\n\r\n status.sx = status.sy = 0;\r\n\r\n status.i = animationFrame.request(interaction.boundSmoothEndFrame);\r\n }\r\n});\r\n\r\nInteraction.signals.on('stop-active', function (_ref3) {\r\n var interaction = _ref3.interaction;\r\n\r\n var status = interaction.inertiaStatus;\r\n\r\n if (status.active) {\r\n animationFrame.cancel(status.i);\r\n status.active = false;\r\n interaction.simulation = null;\r\n }\r\n});\r\n\r\nfunction calcInertia(interaction, status) {\r\n var inertiaOptions = interaction.target.options[interaction.prepared.name].inertia;\r\n var lambda = inertiaOptions.resistance;\r\n var inertiaDur = -Math.log(inertiaOptions.endSpeed / status.v0) / lambda;\r\n\r\n status.x0 = interaction.prevEvent.pageX;\r\n status.y0 = interaction.prevEvent.pageY;\r\n status.t0 = status.startEvent.timeStamp / 1000;\r\n status.sx = status.sy = 0;\r\n\r\n status.modifiedXe = status.xe = (status.vx0 - inertiaDur) / lambda;\r\n status.modifiedYe = status.ye = (status.vy0 - inertiaDur) / lambda;\r\n status.te = inertiaDur;\r\n\r\n status.lambda_v0 = lambda / status.v0;\r\n status.one_ve_v0 = 1 - inertiaOptions.endSpeed / status.v0;\r\n}\r\n\r\nfunction inertiaFrame() {\r\n updateInertiaCoords(this);\r\n utils.setCoordDeltas(this.pointerDelta, this.prevCoords, this.curCoords);\r\n\r\n var status = this.inertiaStatus;\r\n var options = this.target.options[this.prepared.name].inertia;\r\n var lambda = options.resistance;\r\n var t = new Date().getTime() / 1000 - status.t0;\r\n\r\n if (t < status.te) {\r\n\r\n var progress = 1 - (Math.exp(-lambda * t) - status.lambda_v0) / status.one_ve_v0;\r\n\r\n if (status.modifiedXe === status.xe && status.modifiedYe === status.ye) {\r\n status.sx = status.xe * progress;\r\n status.sy = status.ye * progress;\r\n } else {\r\n var quadPoint = utils.getQuadraticCurvePoint(0, 0, status.xe, status.ye, status.modifiedXe, status.modifiedYe, progress);\r\n\r\n status.sx = quadPoint.x;\r\n status.sy = quadPoint.y;\r\n }\r\n\r\n this.doMove();\r\n\r\n status.i = animationFrame.request(this.boundInertiaFrame);\r\n } else {\r\n status.sx = status.modifiedXe;\r\n status.sy = status.modifiedYe;\r\n\r\n this.doMove();\r\n this.end(status.startEvent);\r\n status.active = false;\r\n this.simulation = null;\r\n }\r\n\r\n utils.copyCoords(this.prevCoords, this.curCoords);\r\n}\r\n\r\nfunction smoothEndFrame() {\r\n updateInertiaCoords(this);\r\n\r\n var status = this.inertiaStatus;\r\n var t = new Date().getTime() - status.t0;\r\n var duration = this.target.options[this.prepared.name].inertia.smoothEndDuration;\r\n\r\n if (t < duration) {\r\n status.sx = utils.easeOutQuad(t, 0, status.xe, duration);\r\n status.sy = utils.easeOutQuad(t, 0, status.ye, duration);\r\n\r\n this.pointerMove(status.startEvent, status.startEvent);\r\n\r\n status.i = animationFrame.request(this.boundSmoothEndFrame);\r\n } else {\r\n status.sx = status.xe;\r\n status.sy = status.ye;\r\n\r\n this.pointerMove(status.startEvent, status.startEvent);\r\n this.end(status.startEvent);\r\n\r\n status.smoothEnd = status.active = false;\r\n this.simulation = null;\r\n }\r\n}\r\n\r\nfunction updateInertiaCoords(interaction) {\r\n var status = interaction.inertiaStatus;\r\n\r\n // return if inertia isn't running\r\n if (!status.active) {\r\n return;\r\n }\r\n\r\n var pageUp = status.upCoords.page;\r\n var clientUp = status.upCoords.client;\r\n\r\n utils.setCoords(interaction.curCoords, [{\r\n pageX: pageUp.x + status.sx,\r\n pageY: pageUp.y + status.sy,\r\n clientX: clientUp.x + status.sx,\r\n clientY: clientUp.y + status.sy\r\n }]);\r\n}\r\n\r\n},{\"./InteractEvent\":3,\"./Interaction\":5,\"./modifiers\":24,\"./utils\":44,\"./utils/raf\":50}],21:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar browser = require('./utils/browser');\r\nvar events = require('./utils/events');\r\nvar utils = require('./utils');\r\nvar scope = require('./scope');\r\nvar Interactable = require('./Interactable');\r\nvar Interaction = require('./Interaction');\r\n\r\nvar globalEvents = {};\r\n\r\n/*\\\r\n * interact\r\n [ method ]\r\n *\r\n * The methods of this variable can be used to set elements as\r\n * interactables and also to change various default settings.\r\n *\r\n * Calling it as a function and passing an element or a valid CSS selector\r\n * string returns an Interactable object which has various methods to\r\n * configure it.\r\n *\r\n - element (Element | string) The HTML or SVG Element to interact with or CSS selector\r\n = (object) An @Interactable\r\n *\r\n > Usage\r\n | interact('#draggable').draggable(true);\r\n |\r\n | var rectables = interact('rect');\r\n | rectables\r\n | .gesturable(true)\r\n | .on('gesturemove', function (event) {\r\n | // ...\r\n | });\r\n\\*/\r\nfunction interact(element, options) {\r\n var interactable = scope.interactables.get(element, options);\r\n\r\n if (!interactable) {\r\n interactable = new Interactable(element, options);\r\n interactable.events.global = globalEvents;\r\n }\r\n\r\n return interactable;\r\n}\r\n\r\n/*\\\r\n * interact.isSet\r\n [ method ]\r\n *\r\n * Check if an element has been set\r\n - element (Element) The Element being searched for\r\n = (boolean) Indicates if the element or CSS selector was previously passed to interact\r\n\\*/\r\ninteract.isSet = function (element, options) {\r\n return scope.interactables.indexOfElement(element, options && options.context) !== -1;\r\n};\r\n\r\n/*\\\r\n * interact.on\r\n [ method ]\r\n *\r\n * Adds a global listener for an InteractEvent or adds a DOM event to\r\n * `document`\r\n *\r\n - type (string | array | object) The types of events to listen for\r\n - listener (function) The function event (s)\r\n - options (object | boolean) #optional options object or useCapture flag for addEventListener\r\n = (object) interact\r\n\\*/\r\ninteract.on = function (type, listener, options) {\r\n if (utils.is.string(type) && type.search(' ') !== -1) {\r\n type = type.trim().split(/ +/);\r\n }\r\n\r\n if (utils.is.array(type)) {\r\n for (var _iterator = type, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\r\n var _ref;\r\n\r\n if (_isArray) {\r\n if (_i >= _iterator.length) break;\r\n _ref = _iterator[_i++];\r\n } else {\r\n _i = _iterator.next();\r\n if (_i.done) break;\r\n _ref = _i.value;\r\n }\r\n\r\n var eventType = _ref;\r\n\r\n interact.on(eventType, listener, options);\r\n }\r\n\r\n return interact;\r\n }\r\n\r\n if (utils.is.object(type)) {\r\n for (var prop in type) {\r\n interact.on(prop, type[prop], listener);\r\n }\r\n\r\n return interact;\r\n }\r\n\r\n // if it is an InteractEvent type, add listener to globalEvents\r\n if (utils.contains(Interactable.eventTypes, type)) {\r\n // if this type of event was never bound\r\n if (!globalEvents[type]) {\r\n globalEvents[type] = [listener];\r\n } else {\r\n globalEvents[type].push(listener);\r\n }\r\n }\r\n // If non InteractEvent type, addEventListener to document\r\n else {\r\n events.add(scope.document, type, listener, { options: options });\r\n }\r\n\r\n return interact;\r\n};\r\n\r\n/*\\\r\n * interact.off\r\n [ method ]\r\n *\r\n * Removes a global InteractEvent listener or DOM event from `document`\r\n *\r\n - type (string | array | object) The types of events that were listened for\r\n - listener (function) The listener function to be removed\r\n - options (object | boolean) #optional options object or useCapture flag for removeEventListener\r\n = (object) interact\r\n \\*/\r\ninteract.off = function (type, listener, options) {\r\n if (utils.is.string(type) && type.search(' ') !== -1) {\r\n type = type.trim().split(/ +/);\r\n }\r\n\r\n if (utils.is.array(type)) {\r\n for (var _iterator2 = type, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {\r\n var _ref2;\r\n\r\n if (_isArray2) {\r\n if (_i2 >= _iterator2.length) break;\r\n _ref2 = _iterator2[_i2++];\r\n } else {\r\n _i2 = _iterator2.next();\r\n if (_i2.done) break;\r\n _ref2 = _i2.value;\r\n }\r\n\r\n var eventType = _ref2;\r\n\r\n interact.off(eventType, listener, options);\r\n }\r\n\r\n return interact;\r\n }\r\n\r\n if (utils.is.object(type)) {\r\n for (var prop in type) {\r\n interact.off(prop, type[prop], listener);\r\n }\r\n\r\n return interact;\r\n }\r\n\r\n if (!utils.contains(Interactable.eventTypes, type)) {\r\n events.remove(scope.document, type, listener, options);\r\n } else {\r\n var index = void 0;\r\n\r\n if (type in globalEvents && (index = utils.indexOf(globalEvents[type], listener)) !== -1) {\r\n globalEvents[type].splice(index, 1);\r\n }\r\n }\r\n\r\n return interact;\r\n};\r\n\r\n/*\\\r\n * interact.debug\r\n [ method ]\r\n *\r\n * Returns an object which exposes internal data\r\n = (object) An object with properties that outline the current state and expose internal functions and variables\r\n\\*/\r\ninteract.debug = function () {\r\n return scope;\r\n};\r\n\r\n// expose the functions used to calculate multi-touch properties\r\ninteract.getPointerAverage = utils.pointerAverage;\r\ninteract.getTouchBBox = utils.touchBBox;\r\ninteract.getTouchDistance = utils.touchDistance;\r\ninteract.getTouchAngle = utils.touchAngle;\r\n\r\ninteract.getElementRect = utils.getElementRect;\r\ninteract.getElementClientRect = utils.getElementClientRect;\r\ninteract.matchesSelector = utils.matchesSelector;\r\ninteract.closest = utils.closest;\r\n\r\n/*\\\r\n * interact.supportsTouch\r\n [ method ]\r\n *\r\n = (boolean) Whether or not the browser supports touch input\r\n\\*/\r\ninteract.supportsTouch = function () {\r\n return browser.supportsTouch;\r\n};\r\n\r\n/*\\\r\n * interact.supportsPointerEvent\r\n [ method ]\r\n *\r\n = (boolean) Whether or not the browser supports PointerEvents\r\n\\*/\r\ninteract.supportsPointerEvent = function () {\r\n return browser.supportsPointerEvent;\r\n};\r\n\r\n/*\\\r\n * interact.stop\r\n [ method ]\r\n *\r\n * Cancels all interactions (end events are not fired)\r\n *\r\n - event (Event) An event on which to call preventDefault()\r\n = (object) interact\r\n\\*/\r\ninteract.stop = function (event) {\r\n for (var i = scope.interactions.length - 1; i >= 0; i--) {\r\n scope.interactions[i].stop(event);\r\n }\r\n\r\n return interact;\r\n};\r\n\r\n/*\\\r\n * interact.pointerMoveTolerance\r\n [ method ]\r\n * Returns or sets the distance the pointer must be moved before an action\r\n * sequence occurs. This also affects tolerance for tap events.\r\n *\r\n - newValue (number) #optional The movement from the start position must be greater than this value\r\n = (number | Interactable) The current setting or interact\r\n\\*/\r\ninteract.pointerMoveTolerance = function (newValue) {\r\n if (utils.is.number(newValue)) {\r\n Interaction.pointerMoveTolerance = newValue;\r\n\r\n return this;\r\n }\r\n\r\n return Interaction.pointerMoveTolerance;\r\n};\r\n\r\ninteract.addDocument = scope.addDocument;\r\ninteract.removeDocument = scope.removeDocument;\r\n\r\nscope.interact = interact;\r\n\r\nmodule.exports = interact;\r\n\r\n},{\"./Interactable\":4,\"./Interaction\":5,\"./scope\":34,\"./utils\":44,\"./utils/browser\":37,\"./utils/events\":40}],22:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar Interactable = require('./Interactable');\r\nvar Interaction = require('./Interaction');\r\nvar scope = require('./scope');\r\nvar is = require('./utils/is');\r\nvar events = require('./utils/events');\r\n\r\nvar _require = require('./utils/domUtils'),\r\n nodeContains = _require.nodeContains,\r\n matchesSelector = _require.matchesSelector;\r\n\r\n/*\\\r\n * Interactable.preventDefault\r\n [ method ]\r\n *\r\n * Returns or sets whether to prevent the browser's default behaviour\r\n * in response to pointer events. Can be set to:\r\n * - `'always'` to always prevent\r\n * - `'never'` to never prevent\r\n * - `'auto'` to let interact.js try to determine what would be best\r\n *\r\n - newValue (string) #optional `true`, `false` or `'auto'`\r\n = (string | Interactable) The current setting or this Interactable\r\n\\*/\r\n\r\n\r\nInteractable.prototype.preventDefault = function (newValue) {\r\n if (/^(always|never|auto)$/.test(newValue)) {\r\n this.options.preventDefault = newValue;\r\n return this;\r\n }\r\n\r\n if (is.bool(newValue)) {\r\n this.options.preventDefault = newValue ? 'always' : 'never';\r\n return this;\r\n }\r\n\r\n return this.options.preventDefault;\r\n};\r\n\r\nInteractable.prototype.checkAndPreventDefault = function (event) {\r\n var setting = this.options.preventDefault;\r\n\r\n if (setting === 'never') {\r\n return;\r\n }\r\n\r\n if (setting === 'always') {\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n // setting === 'auto'\r\n\r\n // don't preventDefault if the browser supports passiveEvents\r\n // CSS touch-action and user-selecct should be used instead\r\n if (events.supportsOptions) {\r\n return;\r\n }\r\n\r\n // don't preventDefault of pointerdown events\r\n if (/^(mouse|pointer|touch)*(down|start)/i.test(event.type)) {\r\n return;\r\n }\r\n\r\n // don't preventDefault on editable elements\r\n if (is.element(event.target) && matchesSelector(event.target, 'input,select,textarea,[contenteditable=true],[contenteditable=true] *')) {\r\n return;\r\n }\r\n\r\n event.preventDefault();\r\n};\r\n\r\nfunction onInteractionEvent(_ref) {\r\n var interaction = _ref.interaction,\r\n event = _ref.event;\r\n\r\n if (interaction.target) {\r\n interaction.target.checkAndPreventDefault(event);\r\n }\r\n}\r\n\r\nvar _arr = ['down', 'move', 'up', 'cancel'];\r\nfor (var _i = 0; _i < _arr.length; _i++) {\r\n var eventSignal = _arr[_i];\r\n Interaction.signals.on(eventSignal, onInteractionEvent);\r\n}\r\n\r\n// prevent native HTML5 drag on interact.js target elements\r\nInteraction.docEvents.dragstart = function preventNativeDrag(event) {\r\n for (var _iterator = scope.interactions, _isArray = Array.isArray(_iterator), _i2 = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\r\n var _ref2;\r\n\r\n if (_isArray) {\r\n if (_i2 >= _iterator.length) break;\r\n _ref2 = _iterator[_i2++];\r\n } else {\r\n _i2 = _iterator.next();\r\n if (_i2.done) break;\r\n _ref2 = _i2.value;\r\n }\r\n\r\n var interaction = _ref2;\r\n\r\n\r\n if (interaction.element && (interaction.element === event.target || nodeContains(interaction.element, event.target))) {\r\n\r\n interaction.target.checkAndPreventDefault(event);\r\n return;\r\n }\r\n }\r\n};\r\n\r\n},{\"./Interactable\":4,\"./Interaction\":5,\"./scope\":34,\"./utils/domUtils\":39,\"./utils/events\":40,\"./utils/is\":46}],23:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar scope = require('./scope');\r\nvar events = require('./utils/events');\r\nvar browser = require('./utils/browser');\r\nvar iFinder = require('./utils/interactionFinder');\r\nvar pointerEvents = require('./pointerEvents/base');\r\n\r\nvar _require = require('./utils/window'),\r\n window = _require.window;\r\n\r\nvar toString = Object.prototype.toString;\r\n\r\nif (!window.Array.isArray) {\r\n window.Array.isArray = function (obj) {\r\n return toString.call(obj) === '[object Array]';\r\n };\r\n}\r\n\r\nif (!String.prototype.trim) {\r\n String.prototype.trim = function () {\r\n return this.replace(/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g, '');\r\n };\r\n}\r\n\r\n// http://www.quirksmode.org/dom/events/click.html\r\n// >Events leading to dblclick\r\n//\r\n// IE8 doesn't fire down event before dblclick.\r\n// This workaround tries to fire a tap and doubletap after dblclick\r\nfunction onIE8Dblclick(event) {\r\n var eventTarget = event.target;\r\n var interaction = iFinder.search(event, event.type, eventTarget);\r\n\r\n if (!interaction) {\r\n return;\r\n }\r\n\r\n if (interaction.prevTap && event.clientX === interaction.prevTap.clientX && event.clientY === interaction.prevTap.clientY && eventTarget === interaction.prevTap.target) {\r\n\r\n interaction.downTargets[0] = eventTarget;\r\n interaction.downTimes[0] = new Date().getTime();\r\n\r\n pointerEvents.fire({\r\n interaction: interaction,\r\n event: event,\r\n eventTarget: eventTarget,\r\n pointer: event,\r\n type: 'tap'\r\n });\r\n }\r\n}\r\n\r\nif (browser.isIE8) {\r\n var selectFix = function selectFix(event) {\r\n for (var _iterator = scope.interactions, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\r\n var _ref;\r\n\r\n if (_isArray) {\r\n if (_i >= _iterator.length) break;\r\n _ref = _iterator[_i++];\r\n } else {\r\n _i = _iterator.next();\r\n if (_i.done) break;\r\n _ref = _i.value;\r\n }\r\n\r\n var interaction = _ref;\r\n\r\n if (interaction.interacting()) {\r\n interaction.target.checkAndPreventDefault(event);\r\n }\r\n }\r\n };\r\n\r\n var onDocIE8 = function onDocIE8(_ref2, signalName) {\r\n var doc = _ref2.doc,\r\n win = _ref2.win;\r\n\r\n var eventMethod = signalName.indexOf('listen') === 0 ? events.add : events.remove;\r\n\r\n // For IE's lack of Event#preventDefault\r\n eventMethod(doc, 'selectstart', selectFix);\r\n\r\n if (pointerEvents) {\r\n eventMethod(doc, 'dblclick', onIE8Dblclick);\r\n }\r\n };\r\n\r\n scope.signals.on('add-document', onDocIE8);\r\n scope.signals.on('remove-document', onDocIE8);\r\n}\r\n\r\nmodule.exports = null;\r\n\r\n},{\"./pointerEvents/base\":31,\"./scope\":34,\"./utils/browser\":37,\"./utils/events\":40,\"./utils/interactionFinder\":45,\"./utils/window\":52}],24:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar InteractEvent = require('../InteractEvent');\r\nvar Interaction = require('../Interaction');\r\nvar extend = require('../utils/extend');\r\n\r\nvar modifiers = {\r\n names: [],\r\n\r\n setOffsets: function setOffsets(arg) {\r\n var interaction = arg.interaction,\r\n page = arg.pageCoords;\r\n var target = interaction.target,\r\n element = interaction.element,\r\n startOffset = interaction.startOffset;\r\n\r\n var rect = target.getRect(element);\r\n\r\n if (rect) {\r\n startOffset.left = page.x - rect.left;\r\n startOffset.top = page.y - rect.top;\r\n\r\n startOffset.right = rect.right - page.x;\r\n startOffset.bottom = rect.bottom - page.y;\r\n\r\n if (!('width' in rect)) {\r\n rect.width = rect.right - rect.left;\r\n }\r\n if (!('height' in rect)) {\r\n rect.height = rect.bottom - rect.top;\r\n }\r\n } else {\r\n startOffset.left = startOffset.top = startOffset.right = startOffset.bottom = 0;\r\n }\r\n\r\n arg.rect = rect;\r\n arg.interactable = target;\r\n arg.element = element;\r\n\r\n for (var i = 0; i < modifiers.names.length; i++) {\r\n var modifierName = modifiers.names[i];\r\n\r\n arg.options = target.options[interaction.prepared.name][modifierName];\r\n\r\n if (!arg.options) {\r\n continue;\r\n }\r\n\r\n interaction.modifierOffsets[modifierName] = modifiers[modifierName].setOffset(arg);\r\n }\r\n },\r\n\r\n setAll: function setAll(arg) {\r\n var interaction = arg.interaction,\r\n statuses = arg.statuses,\r\n preEnd = arg.preEnd,\r\n requireEndOnly = arg.requireEndOnly;\r\n\r\n var coords = extend({}, arg.pageCoords);\r\n var result = {\r\n dx: 0,\r\n dy: 0,\r\n changed: false,\r\n locked: false,\r\n shouldMove: true\r\n };\r\n\r\n for (var _iterator = modifiers.names, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\r\n var _ref;\r\n\r\n if (_isArray) {\r\n if (_i >= _iterator.length) break;\r\n _ref = _iterator[_i++];\r\n } else {\r\n _i = _iterator.next();\r\n if (_i.done) break;\r\n _ref = _i.value;\r\n }\r\n\r\n var modifierName = _ref;\r\n\r\n var modifier = modifiers[modifierName];\r\n var options = interaction.target.options[interaction.prepared.name][modifierName];\r\n\r\n if (!shouldDo(options, preEnd, requireEndOnly)) {\r\n continue;\r\n }\r\n\r\n arg.status = arg.status = statuses[modifierName];\r\n arg.options = options;\r\n arg.offset = arg.interaction.modifierOffsets[modifierName];\r\n\r\n modifier.set(arg);\r\n\r\n if (arg.status.locked) {\r\n coords.x += arg.status.dx;\r\n coords.y += arg.status.dy;\r\n\r\n result.dx += arg.status.dx;\r\n result.dy += arg.status.dy;\r\n\r\n result.locked = true;\r\n }\r\n }\r\n\r\n // a move should be fired if:\r\n // - there are no modifiers enabled,\r\n // - no modifiers are \"locked\" i.e. have changed the pointer's coordinates, or\r\n // - the locked coords have changed since the last pointer move\r\n result.shouldMove = !arg.status || !result.locked || arg.status.changed;\r\n\r\n return result;\r\n },\r\n\r\n resetStatuses: function resetStatuses(statuses) {\r\n for (var _iterator2 = modifiers.names, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {\r\n var _ref2;\r\n\r\n if (_isArray2) {\r\n if (_i2 >= _iterator2.length) break;\r\n _ref2 = _iterator2[_i2++];\r\n } else {\r\n _i2 = _iterator2.next();\r\n if (_i2.done) break;\r\n _ref2 = _i2.value;\r\n }\r\n\r\n var modifierName = _ref2;\r\n\r\n var status = statuses[modifierName] || {};\r\n\r\n status.dx = status.dy = 0;\r\n status.modifiedX = status.modifiedY = NaN;\r\n status.locked = false;\r\n status.changed = true;\r\n\r\n statuses[modifierName] = status;\r\n }\r\n\r\n return statuses;\r\n },\r\n\r\n start: function start(_ref3, signalName) {\r\n var interaction = _ref3.interaction;\r\n\r\n var arg = {\r\n interaction: interaction,\r\n pageCoords: (signalName === 'action-resume' ? interaction.curCoords : interaction.startCoords).page,\r\n startOffset: interaction.startOffset,\r\n statuses: interaction.modifierStatuses,\r\n preEnd: false,\r\n requireEndOnly: false\r\n };\r\n\r\n modifiers.setOffsets(arg);\r\n modifiers.resetStatuses(arg.statuses);\r\n\r\n arg.pageCoords = extend({}, interaction.startCoords.page);\r\n interaction.modifierResult = modifiers.setAll(arg);\r\n }\r\n};\r\n\r\nInteraction.signals.on('new', function (interaction) {\r\n interaction.startOffset = { left: 0, right: 0, top: 0, bottom: 0 };\r\n interaction.modifierOffsets = {};\r\n interaction.modifierStatuses = modifiers.resetStatuses({});\r\n interaction.modifierResult = null;\r\n});\r\n\r\nInteraction.signals.on('action-start', modifiers.start);\r\nInteraction.signals.on('action-resume', modifiers.start);\r\n\r\nInteraction.signals.on('before-action-move', function (_ref4) {\r\n var interaction = _ref4.interaction,\r\n preEnd = _ref4.preEnd,\r\n interactingBeforeMove = _ref4.interactingBeforeMove;\r\n\r\n var modifierResult = modifiers.setAll({\r\n interaction: interaction,\r\n preEnd: preEnd,\r\n pageCoords: interaction.curCoords.page,\r\n statuses: interaction.modifierStatuses,\r\n requireEndOnly: false\r\n });\r\n\r\n // don't fire an action move if a modifier would keep the event in the same\r\n // cordinates as before\r\n if (!modifierResult.shouldMove && interactingBeforeMove) {\r\n interaction._dontFireMove = true;\r\n }\r\n\r\n interaction.modifierResult = modifierResult;\r\n});\r\n\r\nInteraction.signals.on('action-end', function (_ref5) {\r\n var interaction = _ref5.interaction,\r\n event = _ref5.event;\r\n\r\n for (var i = 0; i < modifiers.names.length; i++) {\r\n var options = interaction.target.options[interaction.prepared.name][modifiers.names[i]];\r\n\r\n // if the endOnly option is true for any modifier\r\n if (shouldDo(options, true, true)) {\r\n // fire a move event at the modified coordinates\r\n interaction.doMove({ event: event, preEnd: true });\r\n break;\r\n }\r\n }\r\n});\r\n\r\nInteractEvent.signals.on('set-xy', function (arg) {\r\n var iEvent = arg.iEvent,\r\n interaction = arg.interaction;\r\n\r\n var modifierArg = extend({}, arg);\r\n\r\n for (var i = 0; i < modifiers.names.length; i++) {\r\n var modifierName = modifiers.names[i];\r\n modifierArg.options = interaction.target.options[interaction.prepared.name][modifierName];\r\n\r\n if (!modifierArg.options) {\r\n continue;\r\n }\r\n\r\n var modifier = modifiers[modifierName];\r\n\r\n modifierArg.status = interaction.modifierStatuses[modifierName];\r\n\r\n iEvent[modifierName] = modifier.modifyCoords(modifierArg);\r\n }\r\n});\r\n\r\nfunction shouldDo(options, preEnd, requireEndOnly) {\r\n return options && options.enabled && (preEnd || !options.endOnly) && (!requireEndOnly || options.endOnly);\r\n}\r\n\r\nmodule.exports = modifiers;\r\n\r\n},{\"../InteractEvent\":3,\"../Interaction\":5,\"../utils/extend\":41}],25:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar modifiers = require('./index');\r\nvar utils = require('../utils');\r\nvar defaultOptions = require('../defaultOptions');\r\n\r\nvar restrict = {\r\n defaults: {\r\n enabled: false,\r\n endOnly: false,\r\n restriction: null,\r\n elementRect: null\r\n },\r\n\r\n setOffset: function setOffset(_ref) {\r\n var rect = _ref.rect,\r\n startOffset = _ref.startOffset,\r\n options = _ref.options;\r\n\r\n var elementRect = options && options.elementRect;\r\n var offset = {};\r\n\r\n if (rect && elementRect) {\r\n offset.left = startOffset.left - rect.width * elementRect.left;\r\n offset.top = startOffset.top - rect.height * elementRect.top;\r\n\r\n offset.right = startOffset.right - rect.width * (1 - elementRect.right);\r\n offset.bottom = startOffset.bottom - rect.height * (1 - elementRect.bottom);\r\n } else {\r\n offset.left = offset.top = offset.right = offset.bottom = 0;\r\n }\r\n\r\n return offset;\r\n },\r\n\r\n set: function set(_ref2) {\r\n var pageCoords = _ref2.pageCoords,\r\n interaction = _ref2.interaction,\r\n status = _ref2.status,\r\n options = _ref2.options;\r\n\r\n if (!options) {\r\n return status;\r\n }\r\n\r\n var page = status.useStatusXY ? { x: status.x, y: status.y } : utils.extend({}, pageCoords);\r\n\r\n var restriction = getRestrictionRect(options.restriction, interaction, page);\r\n\r\n if (!restriction) {\r\n return status;\r\n }\r\n\r\n status.dx = 0;\r\n status.dy = 0;\r\n status.locked = false;\r\n\r\n var rect = restriction;\r\n var modifiedX = page.x;\r\n var modifiedY = page.y;\r\n\r\n var offset = interaction.modifierOffsets.restrict;\r\n\r\n // object is assumed to have\r\n // x, y, width, height or\r\n // left, top, right, bottom\r\n if ('x' in restriction && 'y' in restriction) {\r\n modifiedX = Math.max(Math.min(rect.x + rect.width - offset.right, page.x), rect.x + offset.left);\r\n modifiedY = Math.max(Math.min(rect.y + rect.height - offset.bottom, page.y), rect.y + offset.top);\r\n } else {\r\n modifiedX = Math.max(Math.min(rect.right - offset.right, page.x), rect.left + offset.left);\r\n modifiedY = Math.max(Math.min(rect.bottom - offset.bottom, page.y), rect.top + offset.top);\r\n }\r\n\r\n status.dx = modifiedX - page.x;\r\n status.dy = modifiedY - page.y;\r\n\r\n status.changed = status.modifiedX !== modifiedX || status.modifiedY !== modifiedY;\r\n status.locked = !!(status.dx || status.dy);\r\n\r\n status.modifiedX = modifiedX;\r\n status.modifiedY = modifiedY;\r\n },\r\n\r\n modifyCoords: function modifyCoords(_ref3) {\r\n var page = _ref3.page,\r\n client = _ref3.client,\r\n status = _ref3.status,\r\n phase = _ref3.phase,\r\n options = _ref3.options;\r\n\r\n var elementRect = options && options.elementRect;\r\n\r\n if (options && options.enabled && !(phase === 'start' && elementRect && status.locked)) {\r\n\r\n if (status.locked) {\r\n page.x += status.dx;\r\n page.y += status.dy;\r\n client.x += status.dx;\r\n client.y += status.dy;\r\n\r\n return {\r\n dx: status.dx,\r\n dy: status.dy\r\n };\r\n }\r\n }\r\n },\r\n\r\n getRestrictionRect: getRestrictionRect\r\n};\r\n\r\nfunction getRestrictionRect(value, interaction, page) {\r\n if (utils.is.function(value)) {\r\n return utils.resolveRectLike(value, interaction.target, interaction.element, [page.x, page.y, interaction]);\r\n } else {\r\n return utils.resolveRectLike(value, interaction.target, interaction.element);\r\n }\r\n}\r\n\r\nmodifiers.restrict = restrict;\r\nmodifiers.names.push('restrict');\r\n\r\ndefaultOptions.perAction.restrict = restrict.defaults;\r\n\r\nmodule.exports = restrict;\r\n\r\n},{\"../defaultOptions\":18,\"../utils\":44,\"./index\":24}],26:[function(require,module,exports){\r\n'use strict';\r\n\r\n// This module adds the options.resize.restrictEdges setting which sets min and\r\n// max for the top, left, bottom and right edges of the target being resized.\r\n//\r\n// interact(target).resize({\r\n// edges: { top: true, left: true },\r\n// restrictEdges: {\r\n// inner: { top: 200, left: 200, right: 400, bottom: 400 },\r\n// outer: { top: 0, left: 0, right: 600, bottom: 600 },\r\n// },\r\n// });\r\n\r\nvar modifiers = require('./index');\r\nvar utils = require('../utils');\r\nvar rectUtils = require('../utils/rect');\r\nvar defaultOptions = require('../defaultOptions');\r\nvar resize = require('../actions/resize');\r\n\r\nvar _require = require('./restrict'),\r\n getRestrictionRect = _require.getRestrictionRect;\r\n\r\nvar noInner = { top: +Infinity, left: +Infinity, bottom: -Infinity, right: -Infinity };\r\nvar noOuter = { top: -Infinity, left: -Infinity, bottom: +Infinity, right: +Infinity };\r\n\r\nvar restrictEdges = {\r\n defaults: {\r\n enabled: false,\r\n endOnly: false,\r\n min: null,\r\n max: null,\r\n offset: null\r\n },\r\n\r\n setOffset: function setOffset(_ref) {\r\n var interaction = _ref.interaction,\r\n startOffset = _ref.startOffset,\r\n options = _ref.options;\r\n\r\n if (!options) {\r\n return utils.extend({}, startOffset);\r\n }\r\n\r\n var offset = getRestrictionRect(options.offset, interaction, interaction.startCoords.page);\r\n\r\n if (offset) {\r\n return {\r\n top: startOffset.top + offset.y,\r\n left: startOffset.left + offset.x,\r\n bottom: startOffset.bottom + offset.y,\r\n right: startOffset.right + offset.x\r\n };\r\n }\r\n\r\n return startOffset;\r\n },\r\n\r\n set: function set(_ref2) {\r\n var pageCoords = _ref2.pageCoords,\r\n interaction = _ref2.interaction,\r\n status = _ref2.status,\r\n offset = _ref2.offset,\r\n options = _ref2.options;\r\n\r\n var edges = interaction.prepared.linkedEdges || interaction.prepared.edges;\r\n\r\n if (!interaction.interacting() || !edges) {\r\n return;\r\n }\r\n\r\n var page = status.useStatusXY ? { x: status.x, y: status.y } : utils.extend({}, pageCoords);\r\n var inner = rectUtils.xywhToTlbr(getRestrictionRect(options.inner, interaction, page)) || noInner;\r\n var outer = rectUtils.xywhToTlbr(getRestrictionRect(options.outer, interaction, page)) || noOuter;\r\n\r\n var modifiedX = page.x;\r\n var modifiedY = page.y;\r\n\r\n status.dx = 0;\r\n status.dy = 0;\r\n status.locked = false;\r\n\r\n if (edges.top) {\r\n modifiedY = Math.min(Math.max(outer.top + offset.top, page.y), inner.top + offset.top);\r\n } else if (edges.bottom) {\r\n modifiedY = Math.max(Math.min(outer.bottom - offset.bottom, page.y), inner.bottom - offset.bottom);\r\n }\r\n if (edges.left) {\r\n modifiedX = Math.min(Math.max(outer.left + offset.left, page.x), inner.left + offset.left);\r\n } else if (edges.right) {\r\n modifiedX = Math.max(Math.min(outer.right - offset.right, page.x), inner.right - offset.right);\r\n }\r\n\r\n status.dx = modifiedX - page.x;\r\n status.dy = modifiedY - page.y;\r\n\r\n status.changed = status.modifiedX !== modifiedX || status.modifiedY !== modifiedY;\r\n status.locked = !!(status.dx || status.dy);\r\n\r\n status.modifiedX = modifiedX;\r\n status.modifiedY = modifiedY;\r\n },\r\n\r\n modifyCoords: function modifyCoords(_ref3) {\r\n var page = _ref3.page,\r\n client = _ref3.client,\r\n status = _ref3.status,\r\n phase = _ref3.phase,\r\n options = _ref3.options;\r\n\r\n if (options && options.enabled && !(phase === 'start' && status.locked)) {\r\n\r\n if (status.locked) {\r\n page.x += status.dx;\r\n page.y += status.dy;\r\n client.x += status.dx;\r\n client.y += status.dy;\r\n\r\n return {\r\n dx: status.dx,\r\n dy: status.dy\r\n };\r\n }\r\n }\r\n },\r\n\r\n noInner: noInner,\r\n noOuter: noOuter,\r\n getRestrictionRect: getRestrictionRect\r\n};\r\n\r\nmodifiers.restrictEdges = restrictEdges;\r\nmodifiers.names.push('restrictEdges');\r\n\r\ndefaultOptions.perAction.restrictEdges = restrictEdges.defaults;\r\nresize.defaults.restrictEdges = restrictEdges.defaults;\r\n\r\nmodule.exports = restrictEdges;\r\n\r\n},{\"../actions/resize\":10,\"../defaultOptions\":18,\"../utils\":44,\"../utils/rect\":51,\"./index\":24,\"./restrict\":25}],27:[function(require,module,exports){\r\n'use strict';\r\n\r\n// This module adds the options.resize.restrictSize setting which sets min and\r\n// max width and height for the target being resized.\r\n//\r\n// interact(target).resize({\r\n// edges: { top: true, left: true },\r\n// restrictSize: {\r\n// min: { width: -600, height: -600 },\r\n// max: { width: 600, height: 600 },\r\n// },\r\n// });\r\n\r\nvar modifiers = require('./index');\r\nvar restrictEdges = require('./restrictEdges');\r\nvar utils = require('../utils');\r\nvar rectUtils = require('../utils/rect');\r\nvar defaultOptions = require('../defaultOptions');\r\nvar resize = require('../actions/resize');\r\n\r\nvar noMin = { width: -Infinity, height: -Infinity };\r\nvar noMax = { width: +Infinity, height: +Infinity };\r\n\r\nvar restrictSize = {\r\n defaults: {\r\n enabled: false,\r\n endOnly: false,\r\n min: null,\r\n max: null\r\n },\r\n\r\n setOffset: function setOffset(_ref) {\r\n var interaction = _ref.interaction;\r\n\r\n return interaction.startOffset;\r\n },\r\n\r\n set: function set(arg) {\r\n var interaction = arg.interaction,\r\n options = arg.options;\r\n\r\n var edges = interaction.prepared.linkedEdges || interaction.prepared.edges;\r\n\r\n if (!interaction.interacting() || !edges) {\r\n return;\r\n }\r\n\r\n var rect = rectUtils.xywhToTlbr(interaction.resizeRects.inverted);\r\n\r\n var minSize = rectUtils.tlbrToXywh(restrictEdges.getRestrictionRect(options.min, interaction)) || noMin;\r\n var maxSize = rectUtils.tlbrToXywh(restrictEdges.getRestrictionRect(options.max, interaction)) || noMax;\r\n\r\n arg.options = {\r\n enabled: options.enabled,\r\n endOnly: options.endOnly,\r\n inner: utils.extend({}, restrictEdges.noInner),\r\n outer: utils.extend({}, restrictEdges.noOuter)\r\n };\r\n\r\n if (edges.top) {\r\n arg.options.inner.top = rect.bottom - minSize.height;\r\n arg.options.outer.top = rect.bottom - maxSize.height;\r\n } else if (edges.bottom) {\r\n arg.options.inner.bottom = rect.top + minSize.height;\r\n arg.options.outer.bottom = rect.top + maxSize.height;\r\n }\r\n if (edges.left) {\r\n arg.options.inner.left = rect.right - minSize.width;\r\n arg.options.outer.left = rect.right - maxSize.width;\r\n } else if (edges.right) {\r\n arg.options.inner.right = rect.left + minSize.width;\r\n arg.options.outer.right = rect.left + maxSize.width;\r\n }\r\n\r\n restrictEdges.set(arg);\r\n },\r\n\r\n modifyCoords: restrictEdges.modifyCoords\r\n};\r\n\r\nmodifiers.restrictSize = restrictSize;\r\nmodifiers.names.push('restrictSize');\r\n\r\ndefaultOptions.perAction.restrictSize = restrictSize.defaults;\r\nresize.defaults.restrictSize = restrictSize.defaults;\r\n\r\nmodule.exports = restrictSize;\r\n\r\n},{\"../actions/resize\":10,\"../defaultOptions\":18,\"../utils\":44,\"../utils/rect\":51,\"./index\":24,\"./restrictEdges\":26}],28:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar modifiers = require('./index');\r\nvar interact = require('../interact');\r\nvar utils = require('../utils');\r\nvar defaultOptions = require('../defaultOptions');\r\n\r\nvar snap = {\r\n defaults: {\r\n enabled: false,\r\n endOnly: false,\r\n range: Infinity,\r\n targets: null,\r\n offsets: null,\r\n\r\n relativePoints: null\r\n },\r\n\r\n setOffset: function setOffset(_ref) {\r\n var interaction = _ref.interaction,\r\n interactable = _ref.interactable,\r\n element = _ref.element,\r\n rect = _ref.rect,\r\n startOffset = _ref.startOffset,\r\n options = _ref.options;\r\n\r\n var offsets = [];\r\n var optionsOrigin = utils.rectToXY(utils.resolveRectLike(options.origin));\r\n var origin = optionsOrigin || utils.getOriginXY(interactable, element, interaction.prepared.name);\r\n options = options || interactable.options[interaction.prepared.name].snap || {};\r\n\r\n var snapOffset = void 0;\r\n\r\n if (options.offset === 'startCoords') {\r\n snapOffset = {\r\n x: interaction.startCoords.page.x - origin.x,\r\n y: interaction.startCoords.page.y - origin.y\r\n };\r\n } else {\r\n var offsetRect = utils.resolveRectLike(options.offset, interactable, element, [interaction]);\r\n\r\n snapOffset = utils.rectToXY(offsetRect) || { x: 0, y: 0 };\r\n }\r\n\r\n if (rect && options.relativePoints && options.relativePoints.length) {\r\n for (var _iterator = options.relativePoints, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\r\n var _ref2;\r\n\r\n if (_isArray) {\r\n if (_i >= _iterator.length) break;\r\n _ref2 = _iterator[_i++];\r\n } else {\r\n _i = _iterator.next();\r\n if (_i.done) break;\r\n _ref2 = _i.value;\r\n }\r\n\r\n var _ref3 = _ref2,\r\n relativeX = _ref3.x,\r\n relativeY = _ref3.y;\r\n\r\n offsets.push({\r\n x: startOffset.left - rect.width * relativeX + snapOffset.x,\r\n y: startOffset.top - rect.height * relativeY + snapOffset.y\r\n });\r\n }\r\n } else {\r\n offsets.push(snapOffset);\r\n }\r\n\r\n return offsets;\r\n },\r\n\r\n set: function set(_ref4) {\r\n var interaction = _ref4.interaction,\r\n pageCoords = _ref4.pageCoords,\r\n status = _ref4.status,\r\n options = _ref4.options,\r\n offsets = _ref4.offset;\r\n\r\n var targets = [];\r\n var target = void 0;\r\n var page = void 0;\r\n var i = void 0;\r\n\r\n if (status.useStatusXY) {\r\n page = { x: status.x, y: status.y };\r\n } else {\r\n var origin = utils.getOriginXY(interaction.target, interaction.element, interaction.prepared.name);\r\n\r\n page = utils.extend({}, pageCoords);\r\n\r\n page.x -= origin.x;\r\n page.y -= origin.y;\r\n }\r\n\r\n status.realX = page.x;\r\n status.realY = page.y;\r\n\r\n var len = options.targets ? options.targets.length : 0;\r\n\r\n for (var _iterator2 = offsets, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {\r\n var _ref5;\r\n\r\n if (_isArray2) {\r\n if (_i2 >= _iterator2.length) break;\r\n _ref5 = _iterator2[_i2++];\r\n } else {\r\n _i2 = _iterator2.next();\r\n if (_i2.done) break;\r\n _ref5 = _i2.value;\r\n }\r\n\r\n var _ref6 = _ref5,\r\n offsetX = _ref6.x,\r\n offsetY = _ref6.y;\r\n\r\n var relativeX = page.x - offsetX;\r\n var relativeY = page.y - offsetY;\r\n\r\n for (var _iterator3 = options.targets, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {\r\n var _ref7;\r\n\r\n if (_isArray3) {\r\n if (_i3 >= _iterator3.length) break;\r\n _ref7 = _iterator3[_i3++];\r\n } else {\r\n _i3 = _iterator3.next();\r\n if (_i3.done) break;\r\n _ref7 = _i3.value;\r\n }\r\n\r\n var snapTarget = _ref7;\r\n\r\n if (utils.is.function(snapTarget)) {\r\n target = snapTarget(relativeX, relativeY, interaction);\r\n } else {\r\n target = snapTarget;\r\n }\r\n\r\n if (!target) {\r\n continue;\r\n }\r\n\r\n targets.push({\r\n x: utils.is.number(target.x) ? target.x + offsetX : relativeX,\r\n y: utils.is.number(target.y) ? target.y + offsetY : relativeY,\r\n\r\n range: utils.is.number(target.range) ? target.range : options.range\r\n });\r\n }\r\n }\r\n\r\n var closest = {\r\n target: null,\r\n inRange: false,\r\n distance: 0,\r\n range: 0,\r\n dx: 0,\r\n dy: 0\r\n };\r\n\r\n for (i = 0, len = targets.length; i < len; i++) {\r\n target = targets[i];\r\n\r\n var range = target.range;\r\n var dx = target.x - page.x;\r\n var dy = target.y - page.y;\r\n var distance = utils.hypot(dx, dy);\r\n var inRange = distance <= range;\r\n\r\n // Infinite targets count as being out of range\r\n // compared to non infinite ones that are in range\r\n if (range === Infinity && closest.inRange && closest.range !== Infinity) {\r\n inRange = false;\r\n }\r\n\r\n if (!closest.target || (inRange\r\n // is the closest target in range?\r\n ? closest.inRange && range !== Infinity\r\n // the pointer is relatively deeper in this target\r\n ? distance / range < closest.distance / closest.range\r\n // this target has Infinite range and the closest doesn't\r\n : range === Infinity && closest.range !== Infinity ||\r\n // OR this target is closer that the previous closest\r\n distance < closest.distance :\r\n // The other is not in range and the pointer is closer to this target\r\n !closest.inRange && distance < closest.distance)) {\r\n\r\n closest.target = target;\r\n closest.distance = distance;\r\n closest.range = range;\r\n closest.inRange = inRange;\r\n closest.dx = dx;\r\n closest.dy = dy;\r\n\r\n status.range = range;\r\n }\r\n }\r\n\r\n var snapChanged = void 0;\r\n\r\n if (closest.target) {\r\n snapChanged = status.modifiedX !== closest.target.x || status.modifiedY !== closest.target.y;\r\n\r\n status.modifiedX = closest.target.x;\r\n status.modifiedY = closest.target.y;\r\n } else {\r\n snapChanged = true;\r\n\r\n status.modifiedX = NaN;\r\n status.modifiedY = NaN;\r\n }\r\n\r\n status.dx = closest.dx;\r\n status.dy = closest.dy;\r\n\r\n status.changed = snapChanged || closest.inRange && !status.locked;\r\n status.locked = closest.inRange;\r\n },\r\n\r\n modifyCoords: function modifyCoords(_ref8) {\r\n var page = _ref8.page,\r\n client = _ref8.client,\r\n status = _ref8.status,\r\n phase = _ref8.phase,\r\n options = _ref8.options;\r\n\r\n var relativePoints = options && options.relativePoints;\r\n\r\n if (options && options.enabled && !(phase === 'start' && relativePoints && relativePoints.length)) {\r\n\r\n if (status.locked) {\r\n page.x += status.dx;\r\n page.y += status.dy;\r\n client.x += status.dx;\r\n client.y += status.dy;\r\n }\r\n\r\n return {\r\n range: status.range,\r\n locked: status.locked,\r\n x: status.modifiedX,\r\n y: status.modifiedY,\r\n realX: status.realX,\r\n realY: status.realY,\r\n dx: status.dx,\r\n dy: status.dy\r\n };\r\n }\r\n }\r\n};\r\n\r\ninteract.createSnapGrid = function (grid) {\r\n return function (x, y) {\r\n var limits = grid.limits || {\r\n left: -Infinity,\r\n right: Infinity,\r\n top: -Infinity,\r\n bottom: Infinity\r\n };\r\n var offsetX = 0;\r\n var offsetY = 0;\r\n\r\n if (utils.is.object(grid.offset)) {\r\n offsetX = grid.offset.x;\r\n offsetY = grid.offset.y;\r\n }\r\n\r\n var gridx = Math.round((x - offsetX) / grid.x);\r\n var gridy = Math.round((y - offsetY) / grid.y);\r\n\r\n var newX = Math.max(limits.left, Math.min(limits.right, gridx * grid.x + offsetX));\r\n var newY = Math.max(limits.top, Math.min(limits.bottom, gridy * grid.y + offsetY));\r\n\r\n return {\r\n x: newX,\r\n y: newY,\r\n range: grid.range\r\n };\r\n };\r\n};\r\n\r\nmodifiers.snap = snap;\r\nmodifiers.names.push('snap');\r\n\r\ndefaultOptions.perAction.snap = snap.defaults;\r\n\r\nmodule.exports = snap;\r\n\r\n},{\"../defaultOptions\":18,\"../interact\":21,\"../utils\":44,\"./index\":24}],29:[function(require,module,exports){\r\n'use strict';\r\n\r\n// This module allows snapping of the size of targets during resize\r\n// interactions.\r\n\r\nvar modifiers = require('./index');\r\nvar snap = require('./snap');\r\nvar defaultOptions = require('../defaultOptions');\r\nvar resize = require('../actions/resize');\r\nvar utils = require('../utils/');\r\n\r\nvar snapSize = {\r\n defaults: {\r\n enabled: false,\r\n endOnly: false,\r\n range: Infinity,\r\n targets: null,\r\n offsets: null\r\n },\r\n\r\n setOffset: function setOffset(arg) {\r\n var interaction = arg.interaction,\r\n options = arg.options;\r\n\r\n var edges = interaction.prepared.edges;\r\n\r\n if (!edges) {\r\n return;\r\n }\r\n\r\n arg.options = {\r\n relativePoints: [{\r\n x: edges.left ? 0 : 1,\r\n y: edges.top ? 0 : 1\r\n }],\r\n origin: { x: 0, y: 0 },\r\n offset: 'self',\r\n range: options.range\r\n };\r\n\r\n var offsets = snap.setOffset(arg);\r\n arg.options = options;\r\n\r\n return offsets;\r\n },\r\n\r\n set: function set(arg) {\r\n var interaction = arg.interaction,\r\n options = arg.options,\r\n offset = arg.offset,\r\n pageCoords = arg.pageCoords;\r\n\r\n var page = utils.extend({}, pageCoords);\r\n var relativeX = page.x - offset[0].x;\r\n var relativeY = page.y - offset[0].y;\r\n\r\n arg.options = utils.extend({}, options);\r\n arg.options.targets = [];\r\n\r\n for (var _iterator = options.targets, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\r\n var _ref;\r\n\r\n if (_isArray) {\r\n if (_i >= _iterator.length) break;\r\n _ref = _iterator[_i++];\r\n } else {\r\n _i = _iterator.next();\r\n if (_i.done) break;\r\n _ref = _i.value;\r\n }\r\n\r\n var snapTarget = _ref;\r\n\r\n var target = void 0;\r\n\r\n if (utils.is.function(snapTarget)) {\r\n target = snapTarget(relativeX, relativeY, interaction);\r\n } else {\r\n target = snapTarget;\r\n }\r\n\r\n if (!target) {\r\n continue;\r\n }\r\n\r\n if ('width' in target && 'height' in target) {\r\n target.x = target.width;\r\n target.y = target.height;\r\n }\r\n\r\n arg.options.targets.push(target);\r\n }\r\n\r\n snap.set(arg);\r\n },\r\n\r\n modifyCoords: function modifyCoords(arg) {\r\n var options = arg.options;\r\n\r\n\r\n arg.options = utils.extend({}, options);\r\n arg.options.enabled = options.enabled;\r\n arg.options.relativePoints = [null];\r\n\r\n snap.modifyCoords(arg);\r\n }\r\n};\r\n\r\nmodifiers.snapSize = snapSize;\r\nmodifiers.names.push('snapSize');\r\n\r\ndefaultOptions.perAction.snapSize = snapSize.defaults;\r\nresize.defaults.snapSize = snapSize.defaults;\r\n\r\nmodule.exports = snapSize;\r\n\r\n},{\"../actions/resize\":10,\"../defaultOptions\":18,\"../utils/\":44,\"./index\":24,\"./snap\":28}],30:[function(require,module,exports){\r\n'use strict';\r\n\r\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\r\n\r\nvar pointerUtils = require('../utils/pointerUtils');\r\n\r\nmodule.exports = function () {\r\n function PointerEvent(type, pointer, event, eventTarget, interaction) {\r\n _classCallCheck(this, PointerEvent);\r\n\r\n pointerUtils.pointerExtend(this, event);\r\n\r\n if (event !== pointer) {\r\n pointerUtils.pointerExtend(this, pointer);\r\n }\r\n\r\n this.interaction = interaction;\r\n\r\n this.timeStamp = new Date().getTime();\r\n this.originalEvent = event;\r\n this.type = type;\r\n this.pointerId = pointerUtils.getPointerId(pointer);\r\n this.pointerType = pointerUtils.getPointerType(pointer);\r\n this.target = eventTarget;\r\n this.currentTarget = null;\r\n\r\n if (type === 'tap') {\r\n var pointerIndex = interaction.getPointerIndex(pointer);\r\n this.dt = this.timeStamp - interaction.downTimes[pointerIndex];\r\n\r\n var interval = this.timeStamp - interaction.tapTime;\r\n\r\n this.double = !!(interaction.prevTap && interaction.prevTap.type !== 'doubletap' && interaction.prevTap.target === this.target && interval < 500);\r\n } else if (type === 'doubletap') {\r\n this.dt = pointer.timeStamp - interaction.tapTime;\r\n }\r\n }\r\n\r\n PointerEvent.prototype.subtractOrigin = function subtractOrigin(_ref) {\r\n var originX = _ref.x,\r\n originY = _ref.y;\r\n\r\n this.pageX -= originX;\r\n this.pageY -= originY;\r\n this.clientX -= originX;\r\n this.clientY -= originY;\r\n\r\n return this;\r\n };\r\n\r\n PointerEvent.prototype.addOrigin = function addOrigin(_ref2) {\r\n var originX = _ref2.x,\r\n originY = _ref2.y;\r\n\r\n this.pageX += originX;\r\n this.pageY += originY;\r\n this.clientX += originX;\r\n this.clientY += originY;\r\n\r\n return this;\r\n };\r\n\r\n PointerEvent.prototype.preventDefault = function preventDefault() {\r\n this.originalEvent.preventDefault();\r\n };\r\n\r\n PointerEvent.prototype.stopPropagation = function stopPropagation() {\r\n this.propagationStopped = true;\r\n };\r\n\r\n PointerEvent.prototype.stopImmediatePropagation = function stopImmediatePropagation() {\r\n this.immediatePropagationStopped = this.propagationStopped = true;\r\n };\r\n\r\n return PointerEvent;\r\n}();\r\n\r\n},{\"../utils/pointerUtils\":49}],31:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar PointerEvent = require('./PointerEvent');\r\nvar Interaction = require('../Interaction');\r\nvar utils = require('../utils');\r\nvar browser = require('../utils/browser');\r\nvar defaults = require('../defaultOptions');\r\nvar signals = require('../utils/Signals').new();\r\n\r\nvar _require = require('../utils/arr'),\r\n filter = _require.filter;\r\n\r\nvar simpleSignals = ['down', 'up', 'cancel'];\r\nvar simpleEvents = ['down', 'up', 'cancel'];\r\n\r\nvar pointerEvents = {\r\n PointerEvent: PointerEvent,\r\n fire: fire,\r\n collectEventTargets: collectEventTargets,\r\n signals: signals,\r\n defaults: {\r\n holdDuration: 600,\r\n ignoreFrom: null,\r\n allowFrom: null,\r\n origin: { x: 0, y: 0 }\r\n },\r\n types: ['down', 'move', 'up', 'cancel', 'tap', 'doubletap', 'hold']\r\n};\r\n\r\nfunction fire(arg) {\r\n var interaction = arg.interaction,\r\n pointer = arg.pointer,\r\n event = arg.event,\r\n eventTarget = arg.eventTarget,\r\n _arg$type = arg.type,\r\n type = _arg$type === undefined ? arg.pointerEvent.type : _arg$type,\r\n _arg$targets = arg.targets,\r\n targets = _arg$targets === undefined ? collectEventTargets(arg) : _arg$targets,\r\n _arg$pointerEvent = arg.pointerEvent,\r\n pointerEvent = _arg$pointerEvent === undefined ? new PointerEvent(type, pointer, event, eventTarget, interaction) : _arg$pointerEvent;\r\n\r\n\r\n var signalArg = {\r\n interaction: interaction,\r\n pointer: pointer,\r\n event: event,\r\n eventTarget: eventTarget,\r\n targets: targets,\r\n type: type,\r\n pointerEvent: pointerEvent\r\n };\r\n\r\n for (var i = 0; i < targets.length; i++) {\r\n var target = targets[i];\r\n\r\n for (var prop in target.props || {}) {\r\n pointerEvent[prop] = target.props[prop];\r\n }\r\n\r\n var origin = utils.getOriginXY(target.eventable, target.element);\r\n\r\n pointerEvent.subtractOrigin(origin);\r\n pointerEvent.eventable = target.eventable;\r\n pointerEvent.currentTarget = target.element;\r\n\r\n target.eventable.fire(pointerEvent);\r\n\r\n pointerEvent.addOrigin(origin);\r\n\r\n if (pointerEvent.immediatePropagationStopped || pointerEvent.propagationStopped && i + 1 < targets.length && targets[i + 1].element !== pointerEvent.currentTarget) {\r\n break;\r\n }\r\n }\r\n\r\n signals.fire('fired', signalArg);\r\n\r\n if (type === 'tap') {\r\n // if pointerEvent should make a double tap, create and fire a doubletap\r\n // PointerEvent and use that as the prevTap\r\n var prevTap = pointerEvent.double ? fire({\r\n interaction: interaction, pointer: pointer, event: event, eventTarget: eventTarget,\r\n type: 'doubletap'\r\n }) : pointerEvent;\r\n\r\n interaction.prevTap = prevTap;\r\n interaction.tapTime = prevTap.timeStamp;\r\n }\r\n\r\n return pointerEvent;\r\n}\r\n\r\nfunction collectEventTargets(_ref) {\r\n var interaction = _ref.interaction,\r\n pointer = _ref.pointer,\r\n event = _ref.event,\r\n eventTarget = _ref.eventTarget,\r\n type = _ref.type;\r\n\r\n var pointerIndex = interaction.getPointerIndex(pointer);\r\n\r\n // do not fire a tap event if the pointer was moved before being lifted\r\n if (type === 'tap' && (interaction.pointerWasMoved\r\n // or if the pointerup target is different to the pointerdown target\r\n || !(interaction.downTargets[pointerIndex] && interaction.downTargets[pointerIndex] === eventTarget))) {\r\n return [];\r\n }\r\n\r\n var path = utils.getPath(eventTarget);\r\n var signalArg = {\r\n interaction: interaction,\r\n pointer: pointer,\r\n event: event,\r\n eventTarget: eventTarget,\r\n type: type,\r\n path: path,\r\n targets: [],\r\n element: null\r\n };\r\n\r\n for (var _iterator = path, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\r\n var _ref2;\r\n\r\n if (_isArray) {\r\n if (_i >= _iterator.length) break;\r\n _ref2 = _iterator[_i++];\r\n } else {\r\n _i = _iterator.next();\r\n if (_i.done) break;\r\n _ref2 = _i.value;\r\n }\r\n\r\n var element = _ref2;\r\n\r\n signalArg.element = element;\r\n\r\n signals.fire('collect-targets', signalArg);\r\n }\r\n\r\n if (type === 'hold') {\r\n signalArg.targets = filter(signalArg.targets, function (target) {\r\n return target.eventable.options.holdDuration === interaction.holdTimers[pointerIndex].duration;\r\n });\r\n }\r\n\r\n return signalArg.targets;\r\n}\r\n\r\nInteraction.signals.on('update-pointer-down', function (_ref3) {\r\n var interaction = _ref3.interaction,\r\n pointerIndex = _ref3.pointerIndex;\r\n\r\n interaction.holdTimers[pointerIndex] = { duration: Infinity, timeout: null };\r\n});\r\n\r\nInteraction.signals.on('remove-pointer', function (_ref4) {\r\n var interaction = _ref4.interaction,\r\n pointerIndex = _ref4.pointerIndex;\r\n\r\n interaction.holdTimers.splice(pointerIndex, 1);\r\n});\r\n\r\nInteraction.signals.on('move', function (_ref5) {\r\n var interaction = _ref5.interaction,\r\n pointer = _ref5.pointer,\r\n event = _ref5.event,\r\n eventTarget = _ref5.eventTarget,\r\n duplicateMove = _ref5.duplicateMove;\r\n\r\n var pointerIndex = interaction.getPointerIndex(pointer);\r\n\r\n if (!duplicateMove && (!interaction.pointerIsDown || interaction.pointerWasMoved)) {\r\n if (interaction.pointerIsDown) {\r\n clearTimeout(interaction.holdTimers[pointerIndex].timeout);\r\n }\r\n\r\n fire({\r\n interaction: interaction, pointer: pointer, event: event, eventTarget: eventTarget,\r\n type: 'move'\r\n });\r\n }\r\n});\r\n\r\nInteraction.signals.on('down', function (_ref6) {\r\n var interaction = _ref6.interaction,\r\n pointer = _ref6.pointer,\r\n event = _ref6.event,\r\n eventTarget = _ref6.eventTarget,\r\n pointerIndex = _ref6.pointerIndex;\r\n\r\n // copy event to be used in timeout for IE8\r\n var eventCopy = browser.isIE8 ? utils.extend({}, event) : event;\r\n\r\n var timer = interaction.holdTimers[pointerIndex];\r\n var path = utils.getPath(eventTarget);\r\n var signalArg = {\r\n interaction: interaction,\r\n pointer: pointer,\r\n event: event,\r\n eventTarget: eventTarget,\r\n type: 'hold',\r\n targets: [],\r\n path: path,\r\n element: null\r\n };\r\n\r\n for (var _iterator2 = path, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {\r\n var _ref7;\r\n\r\n if (_isArray2) {\r\n if (_i2 >= _iterator2.length) break;\r\n _ref7 = _iterator2[_i2++];\r\n } else {\r\n _i2 = _iterator2.next();\r\n if (_i2.done) break;\r\n _ref7 = _i2.value;\r\n }\r\n\r\n var element = _ref7;\r\n\r\n signalArg.element = element;\r\n\r\n signals.fire('collect-targets', signalArg);\r\n }\r\n\r\n if (!signalArg.targets.length) {\r\n return;\r\n }\r\n\r\n var minDuration = Infinity;\r\n\r\n for (var i = 0; i < signalArg.targets.length; i++) {\r\n var target = signalArg.targets[i];\r\n var holdDuration = target.eventable.options.holdDuration;\r\n\r\n if (holdDuration < minDuration) {\r\n minDuration = holdDuration;\r\n }\r\n }\r\n\r\n timer.duration = minDuration;\r\n timer.timeout = setTimeout(function () {\r\n fire({\r\n interaction: interaction,\r\n eventTarget: eventTarget,\r\n pointer: browser.isIE8 ? eventCopy : pointer,\r\n event: eventCopy,\r\n type: 'hold'\r\n });\r\n }, minDuration);\r\n});\r\n\r\nInteraction.signals.on('up', function (_ref8) {\r\n var interaction = _ref8.interaction,\r\n pointer = _ref8.pointer,\r\n event = _ref8.event,\r\n eventTarget = _ref8.eventTarget;\r\n\r\n if (!interaction.pointerWasMoved) {\r\n fire({ interaction: interaction, eventTarget: eventTarget, pointer: pointer, event: event, type: 'tap' });\r\n }\r\n});\r\n\r\n['up', 'cancel'].forEach(function (signalName) {\r\n Interaction.signals.on(signalName, function (_ref9) {\r\n var interaction = _ref9.interaction,\r\n pointerIndex = _ref9.pointerIndex;\r\n\r\n if (interaction.holdTimers[pointerIndex]) {\r\n clearTimeout(interaction.holdTimers[pointerIndex].timeout);\r\n }\r\n });\r\n});\r\n\r\nfunction createSignalListener(type) {\r\n return function (_ref10) {\r\n var interaction = _ref10.interaction,\r\n pointer = _ref10.pointer,\r\n event = _ref10.event,\r\n eventTarget = _ref10.eventTarget;\r\n\r\n fire({ interaction: interaction, eventTarget: eventTarget, pointer: pointer, event: event, type: type });\r\n };\r\n}\r\n\r\nfor (var i = 0; i < simpleSignals.length; i++) {\r\n Interaction.signals.on(simpleSignals[i], createSignalListener(simpleEvents[i]));\r\n}\r\n\r\nInteraction.signals.on('new', function (interaction) {\r\n interaction.prevTap = null; // the most recent tap event on this interaction\r\n interaction.tapTime = 0; // time of the most recent tap event\r\n interaction.holdTimers = []; // [{ duration, timeout }]\r\n});\r\n\r\ndefaults.pointerEvents = pointerEvents.defaults;\r\nmodule.exports = pointerEvents;\r\n\r\n},{\"../Interaction\":5,\"../defaultOptions\":18,\"../utils\":44,\"../utils/Signals\":35,\"../utils/arr\":36,\"../utils/browser\":37,\"./PointerEvent\":30}],32:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar pointerEvents = require('./base');\r\nvar Interaction = require('../Interaction');\r\n\r\npointerEvents.signals.on('new', onNew);\r\npointerEvents.signals.on('fired', onFired);\r\n\r\nvar _arr = ['move', 'up', 'cancel', 'endall'];\r\nfor (var _i = 0; _i < _arr.length; _i++) {\r\n var signal = _arr[_i];\r\n Interaction.signals.on(signal, endHoldRepeat);\r\n}\r\n\r\nfunction onNew(_ref) {\r\n var pointerEvent = _ref.pointerEvent;\r\n\r\n if (pointerEvent.type !== 'hold') {\r\n return;\r\n }\r\n\r\n pointerEvent.count = (pointerEvent.count || 0) + 1;\r\n}\r\n\r\nfunction onFired(_ref2) {\r\n var interaction = _ref2.interaction,\r\n pointerEvent = _ref2.pointerEvent,\r\n eventTarget = _ref2.eventTarget,\r\n targets = _ref2.targets;\r\n\r\n if (pointerEvent.type !== 'hold' || !targets.length) {\r\n return;\r\n }\r\n\r\n // get the repeat interval from the first eventable\r\n var interval = targets[0].eventable.options.holdRepeatInterval;\r\n\r\n // don't repeat if the interval is 0 or less\r\n if (interval <= 0) {\r\n return;\r\n }\r\n\r\n // set a timeout to fire the holdrepeat event\r\n interaction.holdIntervalHandle = setTimeout(function () {\r\n pointerEvents.fire({\r\n interaction: interaction,\r\n eventTarget: eventTarget,\r\n type: 'hold',\r\n pointer: pointerEvent,\r\n event: pointerEvent\r\n });\r\n }, interval);\r\n}\r\n\r\nfunction endHoldRepeat(_ref3) {\r\n var interaction = _ref3.interaction;\r\n\r\n // set the interaction's holdStopTime property\r\n // to stop further holdRepeat events\r\n if (interaction.holdIntervalHandle) {\r\n clearInterval(interaction.holdIntervalHandle);\r\n interaction.holdIntervalHandle = null;\r\n }\r\n}\r\n\r\n// don't repeat by default\r\npointerEvents.defaults.holdRepeatInterval = 0;\r\npointerEvents.types.push('holdrepeat');\r\n\r\nmodule.exports = {\r\n onNew: onNew,\r\n onFired: onFired,\r\n endHoldRepeat: endHoldRepeat\r\n};\r\n\r\n},{\"../Interaction\":5,\"./base\":31}],33:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar pointerEvents = require('./base');\r\nvar Interactable = require('../Interactable');\r\nvar browser = require('../utils/browser');\r\nvar is = require('../utils/is');\r\nvar domUtils = require('../utils/domUtils');\r\nvar scope = require('../scope');\r\nvar extend = require('../utils/extend');\r\n\r\nvar _require = require('../utils/arr'),\r\n merge = _require.merge;\r\n\r\npointerEvents.signals.on('collect-targets', function (_ref) {\r\n var targets = _ref.targets,\r\n element = _ref.element,\r\n type = _ref.type,\r\n eventTarget = _ref.eventTarget;\r\n\r\n function collectSelectors(interactable, selector, context) {\r\n var els = browser.useMatchesSelectorPolyfill ? context.querySelectorAll(selector) : undefined;\r\n\r\n var eventable = interactable.events;\r\n var options = eventable.options;\r\n\r\n if (eventable[type] && is.element(element) && domUtils.matchesSelector(element, selector, els) && interactable.testIgnoreAllow(options, element, eventTarget)) {\r\n\r\n targets.push({\r\n element: element,\r\n eventable: eventable,\r\n props: { interactable: interactable }\r\n });\r\n }\r\n }\r\n\r\n var interactable = scope.interactables.get(element);\r\n\r\n if (interactable) {\r\n var eventable = interactable.events;\r\n var options = eventable.options;\r\n\r\n if (eventable[type] && interactable.testIgnoreAllow(options, element, eventTarget)) {\r\n targets.push({\r\n element: element,\r\n eventable: eventable,\r\n props: { interactable: interactable }\r\n });\r\n }\r\n }\r\n\r\n scope.interactables.forEachSelector(collectSelectors, element);\r\n});\r\n\r\nInteractable.signals.on('new', function (_ref2) {\r\n var interactable = _ref2.interactable;\r\n\r\n interactable.events.getRect = function (element) {\r\n return interactable.getRect(element);\r\n };\r\n});\r\n\r\nInteractable.signals.on('set', function (_ref3) {\r\n var interactable = _ref3.interactable,\r\n options = _ref3.options;\r\n\r\n extend(interactable.events.options, pointerEvents.defaults);\r\n extend(interactable.events.options, options);\r\n});\r\n\r\nmerge(Interactable.eventTypes, pointerEvents.types);\r\n\r\nInteractable.prototype.pointerEvents = function (options) {\r\n extend(this.events.options, options);\r\n\r\n return this;\r\n};\r\n\r\nvar __backCompatOption = Interactable.prototype._backCompatOption;\r\n\r\nInteractable.prototype._backCompatOption = function (optionName, newValue) {\r\n var ret = __backCompatOption.call(this, optionName, newValue);\r\n\r\n if (ret === this) {\r\n this.events.options[optionName] = newValue;\r\n }\r\n\r\n return ret;\r\n};\r\n\r\nInteractable.settingsMethods.push('pointerEvents');\r\n\r\n},{\"../Interactable\":4,\"../scope\":34,\"../utils/arr\":36,\"../utils/browser\":37,\"../utils/domUtils\":39,\"../utils/extend\":41,\"../utils/is\":46,\"./base\":31}],34:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar utils = require('./utils');\r\nvar events = require('./utils/events');\r\nvar signals = require('./utils/Signals').new();\r\n\r\nvar scope = {\r\n signals: signals,\r\n events: events,\r\n utils: utils,\r\n\r\n // main document\r\n document: require('./utils/domObjects').document,\r\n // all documents being listened to\r\n documents: [],\r\n\r\n addDocument: function addDocument(doc, win) {\r\n // do nothing if document is already known\r\n if (utils.contains(scope.documents, doc)) {\r\n return false;\r\n }\r\n\r\n win = win || scope.getWindow(doc);\r\n\r\n scope.documents.push(doc);\r\n events.documents.push(doc);\r\n\r\n // don't add an unload event for the main document\r\n // so that the page may be cached in browser history\r\n if (doc !== scope.document) {\r\n events.add(win, 'unload', scope.onWindowUnload);\r\n }\r\n\r\n signals.fire('add-document', { doc: doc, win: win });\r\n },\r\n\r\n removeDocument: function removeDocument(doc, win) {\r\n var index = utils.indexOf(scope.documents, doc);\r\n\r\n win = win || scope.getWindow(doc);\r\n\r\n events.remove(win, 'unload', scope.onWindowUnload);\r\n\r\n scope.documents.splice(index, 1);\r\n events.documents.splice(index, 1);\r\n\r\n signals.fire('remove-document', { win: win, doc: doc });\r\n },\r\n\r\n onWindowUnload: function onWindowUnload() {\r\n scope.removeDocument(this.document, this);\r\n }\r\n};\r\n\r\nmodule.exports = scope;\r\n\r\n},{\"./utils\":44,\"./utils/Signals\":35,\"./utils/domObjects\":38,\"./utils/events\":40}],35:[function(require,module,exports){\r\n'use strict';\r\n\r\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\r\n\r\nvar _require = require('./arr'),\r\n indexOf = _require.indexOf;\r\n\r\nvar Signals = function () {\r\n function Signals() {\r\n _classCallCheck(this, Signals);\r\n\r\n this.listeners = {\r\n // signalName: [listeners],\r\n };\r\n }\r\n\r\n Signals.prototype.on = function on(name, listener) {\r\n if (!this.listeners[name]) {\r\n this.listeners[name] = [listener];\r\n return;\r\n }\r\n\r\n this.listeners[name].push(listener);\r\n };\r\n\r\n Signals.prototype.off = function off(name, listener) {\r\n if (!this.listeners[name]) {\r\n return;\r\n }\r\n\r\n var index = indexOf(this.listeners[name], listener);\r\n\r\n if (index !== -1) {\r\n this.listeners[name].splice(index, 1);\r\n }\r\n };\r\n\r\n Signals.prototype.fire = function fire(name, arg) {\r\n var targetListeners = this.listeners[name];\r\n\r\n if (!targetListeners) {\r\n return;\r\n }\r\n\r\n for (var i = 0; i < targetListeners.length; i++) {\r\n if (targetListeners[i](arg, name) === false) {\r\n return;\r\n }\r\n }\r\n };\r\n\r\n return Signals;\r\n}();\r\n\r\nSignals.new = function () {\r\n return new Signals();\r\n};\r\n\r\nmodule.exports = Signals;\r\n\r\n},{\"./arr\":36}],36:[function(require,module,exports){\r\n\"use strict\";\r\n\r\nfunction indexOf(array, target) {\r\n for (var i = 0, len = array.length; i < len; i++) {\r\n if (array[i] === target) {\r\n return i;\r\n }\r\n }\r\n\r\n return -1;\r\n}\r\n\r\nfunction contains(array, target) {\r\n return indexOf(array, target) !== -1;\r\n}\r\n\r\nfunction merge(target, source) {\r\n for (var i = 0; i < source.length; i++) {\r\n target.push(source[i]);\r\n }\r\n\r\n return target;\r\n}\r\n\r\nfunction filter(array, test) {\r\n var result = [];\r\n\r\n for (var i = 0; i < array.length; i++) {\r\n if (test(array[i])) {\r\n result.push(array[i]);\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n\r\nmodule.exports = {\r\n indexOf: indexOf,\r\n contains: contains,\r\n merge: merge,\r\n filter: filter\r\n};\r\n\r\n},{}],37:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar _require = require('./window'),\r\n window = _require.window;\r\n\r\nvar is = require('./is');\r\nvar domObjects = require('./domObjects');\r\n\r\nvar Element = domObjects.Element;\r\nvar navigator = window.navigator;\r\n\r\nvar browser = {\r\n // Does the browser support touch input?\r\n supportsTouch: !!('ontouchstart' in window || is.function(window.DocumentTouch) && domObjects.document instanceof window.DocumentTouch),\r\n\r\n // Does the browser support PointerEvents\r\n supportsPointerEvent: !!domObjects.PointerEvent,\r\n\r\n isIE8: 'attachEvent' in window && !('addEventListener' in window),\r\n\r\n // Opera Mobile must be handled differently\r\n isOperaMobile: navigator.appName === 'Opera' && browser.supportsTouch && navigator.userAgent.match('Presto'),\r\n\r\n // scrolling doesn't change the result of getClientRects on iOS 7\r\n isIOS7: /iP(hone|od|ad)/.test(navigator.platform) && /OS 7[^\\d]/.test(navigator.appVersion),\r\n\r\n isIe9OrOlder: /MSIE (8|9)/.test(navigator.userAgent),\r\n\r\n // prefix matchesSelector\r\n prefixedMatchesSelector: 'matches' in Element.prototype ? 'matches' : 'webkitMatchesSelector' in Element.prototype ? 'webkitMatchesSelector' : 'mozMatchesSelector' in Element.prototype ? 'mozMatchesSelector' : 'oMatchesSelector' in Element.prototype ? 'oMatchesSelector' : 'msMatchesSelector',\r\n\r\n useMatchesSelectorPolyfill: false,\r\n\r\n pEventTypes: domObjects.PointerEvent ? domObjects.PointerEvent === window.MSPointerEvent ? {\r\n up: 'MSPointerUp',\r\n down: 'MSPointerDown',\r\n over: 'mouseover',\r\n out: 'mouseout',\r\n move: 'MSPointerMove',\r\n cancel: 'MSPointerCancel'\r\n } : {\r\n up: 'pointerup',\r\n down: 'pointerdown',\r\n over: 'pointerover',\r\n out: 'pointerout',\r\n move: 'pointermove',\r\n cancel: 'pointercancel'\r\n } : null,\r\n\r\n // because Webkit and Opera still use 'mousewheel' event type\r\n wheelEvent: 'onmousewheel' in domObjects.document ? 'mousewheel' : 'wheel'\r\n\r\n};\r\n\r\nbrowser.useMatchesSelectorPolyfill = !is.function(Element.prototype[browser.prefixedMatchesSelector]);\r\n\r\nmodule.exports = browser;\r\n\r\n},{\"./domObjects\":38,\"./is\":46,\"./window\":52}],38:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar domObjects = {};\r\nvar win = require('./window').window;\r\n\r\nfunction blank() {}\r\n\r\ndomObjects.document = win.document;\r\ndomObjects.DocumentFragment = win.DocumentFragment || blank;\r\ndomObjects.SVGElement = win.SVGElement || blank;\r\ndomObjects.SVGSVGElement = win.SVGSVGElement || blank;\r\ndomObjects.SVGElementInstance = win.SVGElementInstance || blank;\r\ndomObjects.Element = win.Element || blank;\r\ndomObjects.HTMLElement = win.HTMLElement || domObjects.Element;\r\n\r\ndomObjects.Event = win.Event;\r\ndomObjects.Touch = win.Touch || blank;\r\ndomObjects.PointerEvent = win.PointerEvent || win.MSPointerEvent;\r\n\r\nmodule.exports = domObjects;\r\n\r\n},{\"./window\":52}],39:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar win = require('./window');\r\nvar browser = require('./browser');\r\nvar is = require('./is');\r\nvar domObjects = require('./domObjects');\r\n\r\nvar domUtils = {\r\n nodeContains: function nodeContains(parent, child) {\r\n while (child) {\r\n if (child === parent) {\r\n return true;\r\n }\r\n\r\n child = child.parentNode;\r\n }\r\n\r\n return false;\r\n },\r\n\r\n closest: function closest(element, selector) {\r\n while (is.element(element)) {\r\n if (domUtils.matchesSelector(element, selector)) {\r\n return element;\r\n }\r\n\r\n element = domUtils.parentNode(element);\r\n }\r\n\r\n return null;\r\n },\r\n\r\n parentNode: function parentNode(node) {\r\n var parent = node.parentNode;\r\n\r\n if (is.docFrag(parent)) {\r\n // skip past #shado-root fragments\r\n while ((parent = parent.host) && is.docFrag(parent)) {\r\n continue;\r\n }\r\n\r\n return parent;\r\n }\r\n\r\n return parent;\r\n },\r\n\r\n // taken from http://tanalin.com/en/blog/2012/12/matches-selector-ie8/ and modified\r\n matchesSelectorPolyfill: browser.useMatchesSelectorPolyfill ? function (element, selector, elems) {\r\n elems = elems || element.parentNode.querySelectorAll(selector);\r\n\r\n for (var i = 0, len = elems.length; i < len; i++) {\r\n if (elems[i] === element) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n } : null,\r\n\r\n matchesSelector: function matchesSelector(element, selector, nodeList) {\r\n if (browser.useMatchesSelectorPolyfill) {\r\n return domUtils.matchesSelectorPolyfill(element, selector, nodeList);\r\n }\r\n\r\n // remove /deep/ from selectors if shadowDOM polyfill is used\r\n if (win.window !== win.realWindow) {\r\n selector = selector.replace(/\\/deep\\//g, ' ');\r\n }\r\n\r\n return element[browser.prefixedMatchesSelector](selector);\r\n },\r\n\r\n // Test for the element that's \"above\" all other qualifiers\r\n indexOfDeepestElement: function indexOfDeepestElement(elements) {\r\n var deepestZoneParents = [];\r\n var dropzoneParents = [];\r\n var dropzone = void 0;\r\n var deepestZone = elements[0];\r\n var index = deepestZone ? 0 : -1;\r\n var parent = void 0;\r\n var child = void 0;\r\n var i = void 0;\r\n var n = void 0;\r\n\r\n for (i = 1; i < elements.length; i++) {\r\n dropzone = elements[i];\r\n\r\n // an element might belong to multiple selector dropzones\r\n if (!dropzone || dropzone === deepestZone) {\r\n continue;\r\n }\r\n\r\n if (!deepestZone) {\r\n deepestZone = dropzone;\r\n index = i;\r\n continue;\r\n }\r\n\r\n // check if the deepest or current are document.documentElement or document.rootElement\r\n // - if the current dropzone is, do nothing and continue\r\n if (dropzone.parentNode === dropzone.ownerDocument) {\r\n continue;\r\n }\r\n // - if deepest is, update with the current dropzone and continue to next\r\n else if (deepestZone.parentNode === dropzone.ownerDocument) {\r\n deepestZone = dropzone;\r\n index = i;\r\n continue;\r\n }\r\n\r\n if (!deepestZoneParents.length) {\r\n parent = deepestZone;\r\n while (parent.parentNode && parent.parentNode !== parent.ownerDocument) {\r\n deepestZoneParents.unshift(parent);\r\n parent = parent.parentNode;\r\n }\r\n }\r\n\r\n // if this element is an svg element and the current deepest is\r\n // an HTMLElement\r\n if (deepestZone instanceof domObjects.HTMLElement && dropzone instanceof domObjects.SVGElement && !(dropzone instanceof domObjects.SVGSVGElement)) {\r\n\r\n if (dropzone === deepestZone.parentNode) {\r\n continue;\r\n }\r\n\r\n parent = dropzone.ownerSVGElement;\r\n } else {\r\n parent = dropzone;\r\n }\r\n\r\n dropzoneParents = [];\r\n\r\n while (parent.parentNode !== parent.ownerDocument) {\r\n dropzoneParents.unshift(parent);\r\n parent = parent.parentNode;\r\n }\r\n\r\n n = 0;\r\n\r\n // get (position of last common ancestor) + 1\r\n while (dropzoneParents[n] && dropzoneParents[n] === deepestZoneParents[n]) {\r\n n++;\r\n }\r\n\r\n var parents = [dropzoneParents[n - 1], dropzoneParents[n], deepestZoneParents[n]];\r\n\r\n child = parents[0].lastChild;\r\n\r\n while (child) {\r\n if (child === parents[1]) {\r\n deepestZone = dropzone;\r\n index = i;\r\n deepestZoneParents = [];\r\n\r\n break;\r\n } else if (child === parents[2]) {\r\n break;\r\n }\r\n\r\n child = child.previousSibling;\r\n }\r\n }\r\n\r\n return index;\r\n },\r\n\r\n matchesUpTo: function matchesUpTo(element, selector, limit) {\r\n while (is.element(element)) {\r\n if (domUtils.matchesSelector(element, selector)) {\r\n return true;\r\n }\r\n\r\n element = domUtils.parentNode(element);\r\n\r\n if (element === limit) {\r\n return domUtils.matchesSelector(element, selector);\r\n }\r\n }\r\n\r\n return false;\r\n },\r\n\r\n getActualElement: function getActualElement(element) {\r\n return element instanceof domObjects.SVGElementInstance ? element.correspondingUseElement : element;\r\n },\r\n\r\n getScrollXY: function getScrollXY(relevantWindow) {\r\n relevantWindow = relevantWindow || win.window;\r\n return {\r\n x: relevantWindow.scrollX || relevantWindow.document.documentElement.scrollLeft,\r\n y: relevantWindow.scrollY || relevantWindow.document.documentElement.scrollTop\r\n };\r\n },\r\n\r\n getElementClientRect: function getElementClientRect(element) {\r\n var clientRect = element instanceof domObjects.SVGElement ? element.getBoundingClientRect() : element.getClientRects()[0];\r\n\r\n return clientRect && {\r\n left: clientRect.left,\r\n right: clientRect.right,\r\n top: clientRect.top,\r\n bottom: clientRect.bottom,\r\n width: clientRect.width || clientRect.right - clientRect.left,\r\n height: clientRect.height || clientRect.bottom - clientRect.top\r\n };\r\n },\r\n\r\n getElementRect: function getElementRect(element) {\r\n var clientRect = domUtils.getElementClientRect(element);\r\n\r\n if (!browser.isIOS7 && clientRect) {\r\n var scroll = domUtils.getScrollXY(win.getWindow(element));\r\n\r\n clientRect.left += scroll.x;\r\n clientRect.right += scroll.x;\r\n clientRect.top += scroll.y;\r\n clientRect.bottom += scroll.y;\r\n }\r\n\r\n return clientRect;\r\n },\r\n\r\n getPath: function getPath(element) {\r\n var path = [];\r\n\r\n while (element) {\r\n path.push(element);\r\n element = domUtils.parentNode(element);\r\n }\r\n\r\n return path;\r\n },\r\n\r\n trySelector: function trySelector(value) {\r\n if (!is.string(value)) {\r\n return false;\r\n }\r\n\r\n // an exception will be raised if it is invalid\r\n domObjects.document.querySelector(value);\r\n return true;\r\n }\r\n};\r\n\r\nmodule.exports = domUtils;\r\n\r\n},{\"./browser\":37,\"./domObjects\":38,\"./is\":46,\"./window\":52}],40:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar is = require('./is');\r\nvar domUtils = require('./domUtils');\r\nvar pExtend = require('./pointerExtend');\r\n\r\nvar _require = require('./window'),\r\n window = _require.window,\r\n getWindow = _require.getWindow;\r\n\r\nvar _require2 = require('./arr'),\r\n indexOf = _require2.indexOf,\r\n contains = _require2.contains;\r\n\r\nvar useAttachEvent = 'attachEvent' in window && !('addEventListener' in window);\r\nvar addEvent = useAttachEvent ? 'attachEvent' : 'addEventListener';\r\nvar removeEvent = useAttachEvent ? 'detachEvent' : 'removeEventListener';\r\nvar on = useAttachEvent ? 'on' : '';\r\n\r\nvar elements = [];\r\nvar targets = [];\r\nvar attachedListeners = [];\r\n\r\n// {\r\n// type: {\r\n// selectors: ['selector', ...],\r\n// contexts : [document, ...],\r\n// listeners: [[listener, capture, passive], ...]\r\n// }\r\n// }\r\nvar delegatedEvents = {};\r\n\r\nvar documents = [];\r\n\r\nvar supportsOptions = !useAttachEvent && function () {\r\n var supported = false;\r\n\r\n window.document.createElement('div').addEventListener('test', null, {\r\n get capture() {\r\n supported = true;\r\n }\r\n });\r\n\r\n return supported;\r\n}();\r\n\r\nfunction add(element, type, listener, optionalArg) {\r\n var options = getOptions(optionalArg);\r\n var elementIndex = indexOf(elements, element);\r\n var target = targets[elementIndex];\r\n\r\n if (!target) {\r\n target = {\r\n events: {},\r\n typeCount: 0\r\n };\r\n\r\n elementIndex = elements.push(element) - 1;\r\n targets.push(target);\r\n\r\n attachedListeners.push(useAttachEvent ? {\r\n supplied: [],\r\n wrapped: [],\r\n useCount: []\r\n } : null);\r\n }\r\n\r\n if (!target.events[type]) {\r\n target.events[type] = [];\r\n target.typeCount++;\r\n }\r\n\r\n if (!contains(target.events[type], listener)) {\r\n var ret = void 0;\r\n\r\n if (useAttachEvent) {\r\n var _attachedListeners$el = attachedListeners[elementIndex],\r\n supplied = _attachedListeners$el.supplied,\r\n wrapped = _attachedListeners$el.wrapped,\r\n useCount = _attachedListeners$el.useCount;\r\n\r\n var listenerIndex = indexOf(supplied, listener);\r\n\r\n var wrappedListener = wrapped[listenerIndex] || function (event) {\r\n if (!event.immediatePropagationStopped) {\r\n event.target = event.srcElement;\r\n event.currentTarget = element;\r\n\r\n event.preventDefault = event.preventDefault || preventDef;\r\n event.stopPropagation = event.stopPropagation || stopProp;\r\n event.stopImmediatePropagation = event.stopImmediatePropagation || stopImmProp;\r\n\r\n if (/mouse|click/.test(event.type)) {\r\n event.pageX = event.clientX + getWindow(element).document.documentElement.scrollLeft;\r\n event.pageY = event.clientY + getWindow(element).document.documentElement.scrollTop;\r\n }\r\n\r\n listener(event);\r\n }\r\n };\r\n\r\n ret = element[addEvent](on + type, wrappedListener, !!options.capture);\r\n\r\n if (listenerIndex === -1) {\r\n supplied.push(listener);\r\n wrapped.push(wrappedListener);\r\n useCount.push(1);\r\n } else {\r\n useCount[listenerIndex]++;\r\n }\r\n } else {\r\n ret = element[addEvent](type, listener, supportsOptions ? options : !!options.capture);\r\n }\r\n target.events[type].push(listener);\r\n\r\n return ret;\r\n }\r\n}\r\n\r\nfunction remove(element, type, listener, optionalArg) {\r\n var options = getOptions(optionalArg);\r\n var elementIndex = indexOf(elements, element);\r\n var target = targets[elementIndex];\r\n\r\n if (!target || !target.events) {\r\n return;\r\n }\r\n\r\n var wrappedListener = listener;\r\n var listeners = void 0;\r\n var listenerIndex = void 0;\r\n\r\n if (useAttachEvent) {\r\n listeners = attachedListeners[elementIndex];\r\n listenerIndex = indexOf(listeners.supplied, listener);\r\n wrappedListener = listeners.wrapped[listenerIndex];\r\n }\r\n\r\n if (type === 'all') {\r\n for (type in target.events) {\r\n if (target.events.hasOwnProperty(type)) {\r\n remove(element, type, 'all');\r\n }\r\n }\r\n return;\r\n }\r\n\r\n if (target.events[type]) {\r\n var len = target.events[type].length;\r\n\r\n if (listener === 'all') {\r\n for (var i = 0; i < len; i++) {\r\n remove(element, type, target.events[type][i], options);\r\n }\r\n return;\r\n } else {\r\n for (var _i = 0; _i < len; _i++) {\r\n if (target.events[type][_i] === listener) {\r\n element[removeEvent](on + type, wrappedListener, supportsOptions ? options : !!options.capture);\r\n target.events[type].splice(_i, 1);\r\n\r\n if (useAttachEvent && listeners) {\r\n listeners.useCount[listenerIndex]--;\r\n if (listeners.useCount[listenerIndex] === 0) {\r\n listeners.supplied.splice(listenerIndex, 1);\r\n listeners.wrapped.splice(listenerIndex, 1);\r\n listeners.useCount.splice(listenerIndex, 1);\r\n }\r\n }\r\n\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if (target.events[type] && target.events[type].length === 0) {\r\n target.events[type] = null;\r\n target.typeCount--;\r\n }\r\n }\r\n\r\n if (!target.typeCount) {\r\n targets.splice(elementIndex, 1);\r\n elements.splice(elementIndex, 1);\r\n attachedListeners.splice(elementIndex, 1);\r\n }\r\n}\r\n\r\nfunction addDelegate(selector, context, type, listener, optionalArg) {\r\n var options = getOptions(optionalArg);\r\n if (!delegatedEvents[type]) {\r\n delegatedEvents[type] = {\r\n selectors: [],\r\n contexts: [],\r\n listeners: []\r\n };\r\n\r\n // add delegate listener functions\r\n for (var i = 0; i < documents.length; i++) {\r\n add(documents[i], type, delegateListener);\r\n add(documents[i], type, delegateUseCapture, true);\r\n }\r\n }\r\n\r\n var delegated = delegatedEvents[type];\r\n var index = void 0;\r\n\r\n for (index = delegated.selectors.length - 1; index >= 0; index--) {\r\n if (delegated.selectors[index] === selector && delegated.contexts[index] === context) {\r\n break;\r\n }\r\n }\r\n\r\n if (index === -1) {\r\n index = delegated.selectors.length;\r\n\r\n delegated.selectors.push(selector);\r\n delegated.contexts.push(context);\r\n delegated.listeners.push([]);\r\n }\r\n\r\n // keep listener and capture and passive flags\r\n delegated.listeners[index].push([listener, !!options.capture, options.passive]);\r\n}\r\n\r\nfunction removeDelegate(selector, context, type, listener, optionalArg) {\r\n var options = getOptions(optionalArg);\r\n var delegated = delegatedEvents[type];\r\n var matchFound = false;\r\n var index = void 0;\r\n\r\n if (!delegated) {\r\n return;\r\n }\r\n\r\n // count from last index of delegated to 0\r\n for (index = delegated.selectors.length - 1; index >= 0; index--) {\r\n // look for matching selector and context Node\r\n if (delegated.selectors[index] === selector && delegated.contexts[index] === context) {\r\n\r\n var listeners = delegated.listeners[index];\r\n\r\n // each item of the listeners array is an array: [function, capture, passive]\r\n for (var i = listeners.length - 1; i >= 0; i--) {\r\n var _listeners$i = listeners[i],\r\n fn = _listeners$i[0],\r\n capture = _listeners$i[1],\r\n passive = _listeners$i[2];\r\n\r\n // check if the listener functions and capture and passive flags match\r\n\r\n if (fn === listener && capture === !!options.capture && passive === options.passive) {\r\n // remove the listener from the array of listeners\r\n listeners.splice(i, 1);\r\n\r\n // if all listeners for this interactable have been removed\r\n // remove the interactable from the delegated arrays\r\n if (!listeners.length) {\r\n delegated.selectors.splice(index, 1);\r\n delegated.contexts.splice(index, 1);\r\n delegated.listeners.splice(index, 1);\r\n\r\n // remove delegate function from context\r\n remove(context, type, delegateListener);\r\n remove(context, type, delegateUseCapture, true);\r\n\r\n // remove the arrays if they are empty\r\n if (!delegated.selectors.length) {\r\n delegatedEvents[type] = null;\r\n }\r\n }\r\n\r\n // only remove one listener\r\n matchFound = true;\r\n break;\r\n }\r\n }\r\n\r\n if (matchFound) {\r\n break;\r\n }\r\n }\r\n }\r\n}\r\n\r\n// bound to the interactable context when a DOM event\r\n// listener is added to a selector interactable\r\nfunction delegateListener(event, optionalArg) {\r\n var options = getOptions(optionalArg);\r\n var fakeEvent = {};\r\n var delegated = delegatedEvents[event.type];\r\n var eventTarget = domUtils.getActualElement(event.path ? event.path[0] : event.target);\r\n var element = eventTarget;\r\n\r\n // duplicate the event so that currentTarget can be changed\r\n pExtend(fakeEvent, event);\r\n\r\n fakeEvent.originalEvent = event;\r\n fakeEvent.preventDefault = preventOriginalDefault;\r\n\r\n // climb up document tree looking for selector matches\r\n while (is.element(element)) {\r\n for (var i = 0; i < delegated.selectors.length; i++) {\r\n var selector = delegated.selectors[i];\r\n var context = delegated.contexts[i];\r\n\r\n if (domUtils.matchesSelector(element, selector) && domUtils.nodeContains(context, eventTarget) && domUtils.nodeContains(context, element)) {\r\n\r\n var listeners = delegated.listeners[i];\r\n\r\n fakeEvent.currentTarget = element;\r\n\r\n for (var j = 0; j < listeners.length; j++) {\r\n var _listeners$j = listeners[j],\r\n fn = _listeners$j[0],\r\n capture = _listeners$j[1],\r\n passive = _listeners$j[2];\r\n\r\n\r\n if (capture === !!options.capture && passive === options.passive) {\r\n fn(fakeEvent);\r\n }\r\n }\r\n }\r\n }\r\n\r\n element = domUtils.parentNode(element);\r\n }\r\n}\r\n\r\nfunction delegateUseCapture(event) {\r\n return delegateListener.call(this, event, true);\r\n}\r\n\r\nfunction preventDef() {\r\n this.returnValue = false;\r\n}\r\n\r\nfunction preventOriginalDefault() {\r\n this.originalEvent.preventDefault();\r\n}\r\n\r\nfunction stopProp() {\r\n this.cancelBubble = true;\r\n}\r\n\r\nfunction stopImmProp() {\r\n this.cancelBubble = true;\r\n this.immediatePropagationStopped = true;\r\n}\r\n\r\nfunction getOptions(param) {\r\n return is.object(param) ? param : { capture: param };\r\n}\r\n\r\nmodule.exports = {\r\n add: add,\r\n remove: remove,\r\n\r\n addDelegate: addDelegate,\r\n removeDelegate: removeDelegate,\r\n\r\n delegateListener: delegateListener,\r\n delegateUseCapture: delegateUseCapture,\r\n delegatedEvents: delegatedEvents,\r\n documents: documents,\r\n\r\n useAttachEvent: useAttachEvent,\r\n supportsOptions: supportsOptions,\r\n\r\n _elements: elements,\r\n _targets: targets,\r\n _attachedListeners: attachedListeners\r\n};\r\n\r\n},{\"./arr\":36,\"./domUtils\":39,\"./is\":46,\"./pointerExtend\":48,\"./window\":52}],41:[function(require,module,exports){\r\n\"use strict\";\r\n\r\nmodule.exports = function extend(dest, source) {\r\n for (var prop in source) {\r\n dest[prop] = source[prop];\r\n }\r\n return dest;\r\n};\r\n\r\n},{}],42:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar _require = require('./rect'),\r\n resolveRectLike = _require.resolveRectLike,\r\n rectToXY = _require.rectToXY;\r\n\r\nmodule.exports = function (target, element, action) {\r\n var actionOptions = target.options[action];\r\n var actionOrigin = actionOptions && actionOptions.origin;\r\n var origin = actionOrigin || target.options.origin;\r\n\r\n var originRect = resolveRectLike(origin, target, element, [target && element]);\r\n\r\n return rectToXY(originRect) || { x: 0, y: 0 };\r\n};\r\n\r\n},{\"./rect\":51}],43:[function(require,module,exports){\r\n\"use strict\";\r\n\r\nmodule.exports = function (x, y) {\r\n return Math.sqrt(x * x + y * y);\r\n};\r\n\r\n},{}],44:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar extend = require('./extend');\r\nvar win = require('./window');\r\n\r\nvar utils = {\r\n warnOnce: function warnOnce(method, message) {\r\n var warned = false;\r\n\r\n return function () {\r\n if (!warned) {\r\n win.window.console.warn(message);\r\n warned = true;\r\n }\r\n\r\n return method.apply(this, arguments);\r\n };\r\n },\r\n\r\n // http://stackoverflow.com/a/5634528/2280888\r\n _getQBezierValue: function _getQBezierValue(t, p1, p2, p3) {\r\n var iT = 1 - t;\r\n return iT * iT * p1 + 2 * iT * t * p2 + t * t * p3;\r\n },\r\n\r\n getQuadraticCurvePoint: function getQuadraticCurvePoint(startX, startY, cpX, cpY, endX, endY, position) {\r\n return {\r\n x: utils._getQBezierValue(position, startX, cpX, endX),\r\n y: utils._getQBezierValue(position, startY, cpY, endY)\r\n };\r\n },\r\n\r\n // http://gizma.com/easing/\r\n easeOutQuad: function easeOutQuad(t, b, c, d) {\r\n t /= d;\r\n return -c * t * (t - 2) + b;\r\n },\r\n\r\n copyAction: function copyAction(dest, src) {\r\n dest.name = src.name;\r\n dest.axis = src.axis;\r\n dest.edges = src.edges;\r\n\r\n return dest;\r\n },\r\n\r\n is: require('./is'),\r\n extend: extend,\r\n hypot: require('./hypot'),\r\n getOriginXY: require('./getOriginXY')\r\n};\r\n\r\nextend(utils, require('./arr'));\r\nextend(utils, require('./domUtils'));\r\nextend(utils, require('./pointerUtils'));\r\nextend(utils, require('./rect'));\r\n\r\nmodule.exports = utils;\r\n\r\n},{\"./arr\":36,\"./domUtils\":39,\"./extend\":41,\"./getOriginXY\":42,\"./hypot\":43,\"./is\":46,\"./pointerUtils\":49,\"./rect\":51,\"./window\":52}],45:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar scope = require('../scope');\r\nvar utils = require('./index');\r\n\r\nvar finder = {\r\n methodOrder: ['simulationResume', 'mouseOrPen', 'hasPointer', 'idle'],\r\n\r\n search: function search(pointer, eventType, eventTarget) {\r\n var pointerType = utils.getPointerType(pointer);\r\n var pointerId = utils.getPointerId(pointer);\r\n var details = { pointer: pointer, pointerId: pointerId, pointerType: pointerType, eventType: eventType, eventTarget: eventTarget };\r\n\r\n for (var _iterator = finder.methodOrder, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\r\n var _ref;\r\n\r\n if (_isArray) {\r\n if (_i >= _iterator.length) break;\r\n _ref = _iterator[_i++];\r\n } else {\r\n _i = _iterator.next();\r\n if (_i.done) break;\r\n _ref = _i.value;\r\n }\r\n\r\n var method = _ref;\r\n\r\n var interaction = finder[method](details);\r\n\r\n if (interaction) {\r\n return interaction;\r\n }\r\n }\r\n },\r\n\r\n // try to resume simulation with a new pointer\r\n simulationResume: function simulationResume(_ref2) {\r\n var pointerType = _ref2.pointerType,\r\n eventType = _ref2.eventType,\r\n eventTarget = _ref2.eventTarget;\r\n\r\n if (!/down|start/i.test(eventType)) {\r\n return null;\r\n }\r\n\r\n for (var _iterator2 = scope.interactions, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {\r\n var _ref3;\r\n\r\n if (_isArray2) {\r\n if (_i2 >= _iterator2.length) break;\r\n _ref3 = _iterator2[_i2++];\r\n } else {\r\n _i2 = _iterator2.next();\r\n if (_i2.done) break;\r\n _ref3 = _i2.value;\r\n }\r\n\r\n var interaction = _ref3;\r\n\r\n var element = eventTarget;\r\n\r\n if (interaction.simulation && interaction.simulation.allowResume && interaction.pointerType === pointerType) {\r\n while (element) {\r\n // if the element is the interaction element\r\n if (element === interaction.element) {\r\n return interaction;\r\n }\r\n element = utils.parentNode(element);\r\n }\r\n }\r\n }\r\n\r\n return null;\r\n },\r\n\r\n // if it's a mouse or pen interaction\r\n mouseOrPen: function mouseOrPen(_ref4) {\r\n var pointerId = _ref4.pointerId,\r\n pointerType = _ref4.pointerType,\r\n eventType = _ref4.eventType;\r\n\r\n if (pointerType !== 'mouse' && pointerType !== 'pen') {\r\n return null;\r\n }\r\n\r\n var firstNonActive = void 0;\r\n\r\n for (var _iterator3 = scope.interactions, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {\r\n var _ref5;\r\n\r\n if (_isArray3) {\r\n if (_i3 >= _iterator3.length) break;\r\n _ref5 = _iterator3[_i3++];\r\n } else {\r\n _i3 = _iterator3.next();\r\n if (_i3.done) break;\r\n _ref5 = _i3.value;\r\n }\r\n\r\n var interaction = _ref5;\r\n\r\n if (interaction.pointerType === pointerType) {\r\n // if it's a down event, skip interactions with running simulations\r\n if (interaction.simulation && !utils.contains(interaction.pointerIds, pointerId)) {\r\n continue;\r\n }\r\n\r\n // if the interaction is active, return it immediately\r\n if (interaction.interacting()) {\r\n return interaction;\r\n }\r\n // otherwise save it and look for another active interaction\r\n else if (!firstNonActive) {\r\n firstNonActive = interaction;\r\n }\r\n }\r\n }\r\n\r\n // if no active mouse interaction was found use the first inactive mouse\r\n // interaction\r\n if (firstNonActive) {\r\n return firstNonActive;\r\n }\r\n\r\n // find any mouse or pen interaction.\r\n // ignore the interaction if the eventType is a *down, and a simulation\r\n // is active\r\n for (var _iterator4 = scope.interactions, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) {\r\n var _ref6;\r\n\r\n if (_isArray4) {\r\n if (_i4 >= _iterator4.length) break;\r\n _ref6 = _iterator4[_i4++];\r\n } else {\r\n _i4 = _iterator4.next();\r\n if (_i4.done) break;\r\n _ref6 = _i4.value;\r\n }\r\n\r\n var _interaction = _ref6;\r\n\r\n if (_interaction.pointerType === pointerType && !(/down/i.test(eventType) && _interaction.simulation)) {\r\n return _interaction;\r\n }\r\n }\r\n\r\n return null;\r\n },\r\n\r\n // get interaction that has this pointer\r\n hasPointer: function hasPointer(_ref7) {\r\n var pointerId = _ref7.pointerId;\r\n\r\n for (var _iterator5 = scope.interactions, _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) {\r\n var _ref8;\r\n\r\n if (_isArray5) {\r\n if (_i5 >= _iterator5.length) break;\r\n _ref8 = _iterator5[_i5++];\r\n } else {\r\n _i5 = _iterator5.next();\r\n if (_i5.done) break;\r\n _ref8 = _i5.value;\r\n }\r\n\r\n var interaction = _ref8;\r\n\r\n if (utils.contains(interaction.pointerIds, pointerId)) {\r\n return interaction;\r\n }\r\n }\r\n },\r\n\r\n // get first idle interaction with a matching pointerType\r\n idle: function idle(_ref9) {\r\n var pointerType = _ref9.pointerType;\r\n\r\n for (var _iterator6 = scope.interactions, _isArray6 = Array.isArray(_iterator6), _i6 = 0, _iterator6 = _isArray6 ? _iterator6 : _iterator6[Symbol.iterator]();;) {\r\n var _ref10;\r\n\r\n if (_isArray6) {\r\n if (_i6 >= _iterator6.length) break;\r\n _ref10 = _iterator6[_i6++];\r\n } else {\r\n _i6 = _iterator6.next();\r\n if (_i6.done) break;\r\n _ref10 = _i6.value;\r\n }\r\n\r\n var interaction = _ref10;\r\n\r\n // if there's already a pointer held down\r\n if (interaction.pointerIds.length === 1) {\r\n var target = interaction.target;\r\n // don't add this pointer if there is a target interactable and it\r\n // isn't gesturable\r\n if (target && !target.options.gesture.enabled) {\r\n continue;\r\n }\r\n }\r\n // maximum of 2 pointers per interaction\r\n else if (interaction.pointerIds.length >= 2) {\r\n continue;\r\n }\r\n\r\n if (!interaction.interacting() && pointerType === interaction.pointerType) {\r\n return interaction;\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n};\r\n\r\nmodule.exports = finder;\r\n\r\n},{\"../scope\":34,\"./index\":44}],46:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\r\n\r\nvar win = require('./window');\r\nvar isWindow = require('./isWindow');\r\n\r\nvar is = {\r\n array: function array() {},\r\n\r\n window: function window(thing) {\r\n return thing === win.window || isWindow(thing);\r\n },\r\n\r\n docFrag: function docFrag(thing) {\r\n return is.object(thing) && thing.nodeType === 11;\r\n },\r\n\r\n object: function object(thing) {\r\n return !!thing && (typeof thing === 'undefined' ? 'undefined' : _typeof(thing)) === 'object';\r\n },\r\n\r\n function: function _function(thing) {\r\n return typeof thing === 'function';\r\n },\r\n\r\n number: function number(thing) {\r\n return typeof thing === 'number';\r\n },\r\n\r\n bool: function bool(thing) {\r\n return typeof thing === 'boolean';\r\n },\r\n\r\n string: function string(thing) {\r\n return typeof thing === 'string';\r\n },\r\n\r\n element: function element(thing) {\r\n if (!thing || (typeof thing === 'undefined' ? 'undefined' : _typeof(thing)) !== 'object') {\r\n return false;\r\n }\r\n\r\n var _window = win.getWindow(thing) || win.window;\r\n\r\n return (/object|function/.test(_typeof(_window.Element)) ? thing instanceof _window.Element //DOM2\r\n : thing.nodeType === 1 && typeof thing.nodeName === 'string'\r\n );\r\n }\r\n};\r\n\r\nis.array = function (thing) {\r\n return is.object(thing) && typeof thing.length !== 'undefined' && is.function(thing.splice);\r\n};\r\n\r\nmodule.exports = is;\r\n\r\n},{\"./isWindow\":47,\"./window\":52}],47:[function(require,module,exports){\r\n\"use strict\";\r\n\r\nmodule.exports = function (thing) {\r\n return !!(thing && thing.Window) && thing instanceof thing.Window;\r\n};\r\n\r\n},{}],48:[function(require,module,exports){\r\n'use strict';\r\n\r\nfunction pointerExtend(dest, source) {\r\n for (var prop in source) {\r\n var prefixedPropREs = module.exports.prefixedPropREs;\r\n var deprecated = false;\r\n\r\n // skip deprecated prefixed properties\r\n for (var vendor in prefixedPropREs) {\r\n if (prop.indexOf(vendor) === 0 && prefixedPropREs[vendor].test(prop)) {\r\n deprecated = true;\r\n break;\r\n }\r\n }\r\n\r\n if (!deprecated && typeof source[prop] !== 'function') {\r\n dest[prop] = source[prop];\r\n }\r\n }\r\n return dest;\r\n}\r\n\r\npointerExtend.prefixedPropREs = {\r\n webkit: /(Movement[XY]|Radius[XY]|RotationAngle|Force)$/\r\n};\r\n\r\nmodule.exports = pointerExtend;\r\n\r\n},{}],49:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar hypot = require('./hypot');\r\nvar browser = require('./browser');\r\nvar dom = require('./domObjects');\r\nvar domUtils = require('./domUtils');\r\nvar domObjects = require('./domObjects');\r\nvar is = require('./is');\r\nvar pointerExtend = require('./pointerExtend');\r\n\r\nvar pointerUtils = {\r\n copyCoords: function copyCoords(dest, src) {\r\n dest.page = dest.page || {};\r\n dest.page.x = src.page.x;\r\n dest.page.y = src.page.y;\r\n\r\n dest.client = dest.client || {};\r\n dest.client.x = src.client.x;\r\n dest.client.y = src.client.y;\r\n\r\n dest.timeStamp = src.timeStamp;\r\n },\r\n\r\n setCoordDeltas: function setCoordDeltas(targetObj, prev, cur) {\r\n targetObj.page.x = cur.page.x - prev.page.x;\r\n targetObj.page.y = cur.page.y - prev.page.y;\r\n targetObj.client.x = cur.client.x - prev.client.x;\r\n targetObj.client.y = cur.client.y - prev.client.y;\r\n targetObj.timeStamp = cur.timeStamp - prev.timeStamp;\r\n\r\n // set pointer velocity\r\n var dt = Math.max(targetObj.timeStamp / 1000, 0.001);\r\n\r\n targetObj.page.speed = hypot(targetObj.page.x, targetObj.page.y) / dt;\r\n targetObj.page.vx = targetObj.page.x / dt;\r\n targetObj.page.vy = targetObj.page.y / dt;\r\n\r\n targetObj.client.speed = hypot(targetObj.client.x, targetObj.page.y) / dt;\r\n targetObj.client.vx = targetObj.client.x / dt;\r\n targetObj.client.vy = targetObj.client.y / dt;\r\n },\r\n\r\n isNativePointer: function isNativePointer(pointer) {\r\n return pointer instanceof dom.Event || pointer instanceof dom.Touch;\r\n },\r\n\r\n // Get specified X/Y coords for mouse or event.touches[0]\r\n getXY: function getXY(type, pointer, xy) {\r\n xy = xy || {};\r\n type = type || 'page';\r\n\r\n xy.x = pointer[type + 'X'];\r\n xy.y = pointer[type + 'Y'];\r\n\r\n return xy;\r\n },\r\n\r\n getPageXY: function getPageXY(pointer, page) {\r\n page = page || {};\r\n\r\n // Opera Mobile handles the viewport and scrolling oddly\r\n if (browser.isOperaMobile && pointerUtils.isNativePointer(pointer)) {\r\n pointerUtils.getXY('screen', pointer, page);\r\n\r\n page.x += window.scrollX;\r\n page.y += window.scrollY;\r\n } else {\r\n pointerUtils.getXY('page', pointer, page);\r\n }\r\n\r\n return page;\r\n },\r\n\r\n getClientXY: function getClientXY(pointer, client) {\r\n client = client || {};\r\n\r\n if (browser.isOperaMobile && pointerUtils.isNativePointer(pointer)) {\r\n // Opera Mobile handles the viewport and scrolling oddly\r\n pointerUtils.getXY('screen', pointer, client);\r\n } else {\r\n pointerUtils.getXY('client', pointer, client);\r\n }\r\n\r\n return client;\r\n },\r\n\r\n getPointerId: function getPointerId(pointer) {\r\n return is.number(pointer.pointerId) ? pointer.pointerId : pointer.identifier;\r\n },\r\n\r\n setCoords: function setCoords(targetObj, pointers, timeStamp) {\r\n var pointer = pointers.length > 1 ? pointerUtils.pointerAverage(pointers) : pointers[0];\r\n\r\n var tmpXY = {};\r\n\r\n pointerUtils.getPageXY(pointer, tmpXY);\r\n targetObj.page.x = tmpXY.x;\r\n targetObj.page.y = tmpXY.y;\r\n\r\n pointerUtils.getClientXY(pointer, tmpXY);\r\n targetObj.client.x = tmpXY.x;\r\n targetObj.client.y = tmpXY.y;\r\n\r\n targetObj.timeStamp = is.number(timeStamp) ? timeStamp : new Date().getTime();\r\n },\r\n\r\n pointerExtend: pointerExtend,\r\n\r\n getTouchPair: function getTouchPair(event) {\r\n var touches = [];\r\n\r\n // array of touches is supplied\r\n if (is.array(event)) {\r\n touches[0] = event[0];\r\n touches[1] = event[1];\r\n }\r\n // an event\r\n else {\r\n if (event.type === 'touchend') {\r\n if (event.touches.length === 1) {\r\n touches[0] = event.touches[0];\r\n touches[1] = event.changedTouches[0];\r\n } else if (event.touches.length === 0) {\r\n touches[0] = event.changedTouches[0];\r\n touches[1] = event.changedTouches[1];\r\n }\r\n } else {\r\n touches[0] = event.touches[0];\r\n touches[1] = event.touches[1];\r\n }\r\n }\r\n\r\n return touches;\r\n },\r\n\r\n pointerAverage: function pointerAverage(pointers) {\r\n var average = {\r\n pageX: 0,\r\n pageY: 0,\r\n clientX: 0,\r\n clientY: 0,\r\n screenX: 0,\r\n screenY: 0\r\n };\r\n\r\n for (var _iterator = pointers, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\r\n var _ref;\r\n\r\n if (_isArray) {\r\n if (_i >= _iterator.length) break;\r\n _ref = _iterator[_i++];\r\n } else {\r\n _i = _iterator.next();\r\n if (_i.done) break;\r\n _ref = _i.value;\r\n }\r\n\r\n var pointer = _ref;\r\n\r\n for (var _prop in average) {\r\n average[_prop] += pointer[_prop];\r\n }\r\n }\r\n for (var prop in average) {\r\n average[prop] /= pointers.length;\r\n }\r\n\r\n return average;\r\n },\r\n\r\n touchBBox: function touchBBox(event) {\r\n if (!event.length && !(event.touches && event.touches.length > 1)) {\r\n return;\r\n }\r\n\r\n var touches = pointerUtils.getTouchPair(event);\r\n var minX = Math.min(touches[0].pageX, touches[1].pageX);\r\n var minY = Math.min(touches[0].pageY, touches[1].pageY);\r\n var maxX = Math.max(touches[0].pageX, touches[1].pageX);\r\n var maxY = Math.max(touches[0].pageY, touches[1].pageY);\r\n\r\n return {\r\n x: minX,\r\n y: minY,\r\n left: minX,\r\n top: minY,\r\n width: maxX - minX,\r\n height: maxY - minY\r\n };\r\n },\r\n\r\n touchDistance: function touchDistance(event, deltaSource) {\r\n var sourceX = deltaSource + 'X';\r\n var sourceY = deltaSource + 'Y';\r\n var touches = pointerUtils.getTouchPair(event);\r\n\r\n var dx = touches[0][sourceX] - touches[1][sourceX];\r\n var dy = touches[0][sourceY] - touches[1][sourceY];\r\n\r\n return hypot(dx, dy);\r\n },\r\n\r\n touchAngle: function touchAngle(event, prevAngle, deltaSource) {\r\n var sourceX = deltaSource + 'X';\r\n var sourceY = deltaSource + 'Y';\r\n var touches = pointerUtils.getTouchPair(event);\r\n var dx = touches[1][sourceX] - touches[0][sourceX];\r\n var dy = touches[1][sourceY] - touches[0][sourceY];\r\n var angle = 180 * Math.atan2(dy, dx) / Math.PI;\r\n\r\n return angle;\r\n },\r\n\r\n getPointerType: function getPointerType(pointer) {\r\n return is.string(pointer.pointerType) ? pointer.pointerType : is.number(pointer.pointerType) ? [undefined, undefined, 'touch', 'pen', 'mouse'][pointer.pointerType]\r\n // if the PointerEvent API isn't available, then the \"pointer\" must\r\n // be either a MouseEvent, TouchEvent, or Touch object\r\n : /touch/.test(pointer.type) || pointer instanceof domObjects.Touch ? 'touch' : 'mouse';\r\n },\r\n\r\n // [ event.target, event.currentTarget ]\r\n getEventTargets: function getEventTargets(event) {\r\n return [domUtils.getActualElement(event.path ? event.path[0] : event.target), domUtils.getActualElement(event.currentTarget)];\r\n }\r\n};\r\n\r\nmodule.exports = pointerUtils;\r\n\r\n},{\"./browser\":37,\"./domObjects\":38,\"./domUtils\":39,\"./hypot\":43,\"./is\":46,\"./pointerExtend\":48}],50:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar _require = require('./window'),\r\n window = _require.window;\r\n\r\nvar vendors = ['ms', 'moz', 'webkit', 'o'];\r\nvar lastTime = 0;\r\nvar request = void 0;\r\nvar cancel = void 0;\r\n\r\nfor (var x = 0; x < vendors.length && !window.requestAnimationFrame; x++) {\r\n request = window[vendors[x] + 'RequestAnimationFrame'];\r\n cancel = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame'];\r\n}\r\n\r\nif (!request) {\r\n request = function request(callback) {\r\n var currTime = new Date().getTime();\r\n var timeToCall = Math.max(0, 16 - (currTime - lastTime));\r\n var id = setTimeout(function () {\r\n callback(currTime + timeToCall);\r\n }, timeToCall);\r\n\r\n lastTime = currTime + timeToCall;\r\n return id;\r\n };\r\n}\r\n\r\nif (!cancel) {\r\n cancel = function cancel(id) {\r\n clearTimeout(id);\r\n };\r\n}\r\n\r\nmodule.exports = {\r\n request: request,\r\n cancel: cancel\r\n};\r\n\r\n},{\"./window\":52}],51:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar extend = require('./extend');\r\nvar is = require('./is');\r\n\r\nvar _require = require('./domUtils'),\r\n closest = _require.closest,\r\n parentNode = _require.parentNode,\r\n getElementRect = _require.getElementRect;\r\n\r\nvar rectUtils = {\r\n getStringOptionResult: function getStringOptionResult(value, interactable, element) {\r\n if (!is.string(value)) {\r\n return null;\r\n }\r\n\r\n if (value === 'parent') {\r\n value = parentNode(element);\r\n } else if (value === 'self') {\r\n value = interactable.getRect(element);\r\n } else {\r\n value = closest(element, value);\r\n }\r\n\r\n return value;\r\n },\r\n\r\n resolveRectLike: function resolveRectLike(value, interactable, element, functionArgs) {\r\n value = rectUtils.getStringOptionResult(value, interactable, element) || value;\r\n\r\n if (is.function(value)) {\r\n value = value.apply(null, functionArgs);\r\n }\r\n\r\n if (is.element(value)) {\r\n value = getElementRect(value);\r\n }\r\n\r\n return value;\r\n },\r\n\r\n rectToXY: function rectToXY(rect) {\r\n return rect && {\r\n x: 'x' in rect ? rect.x : rect.left,\r\n y: 'y' in rect ? rect.y : rect.top\r\n };\r\n },\r\n\r\n xywhToTlbr: function xywhToTlbr(rect) {\r\n if (rect && !('left' in rect && 'top' in rect)) {\r\n rect = extend({}, rect);\r\n\r\n rect.left = rect.x || 0;\r\n rect.top = rect.y || 0;\r\n rect.right = rect.right || rect.left + rect.width;\r\n rect.bottom = rect.bottom || rect.top + rect.height;\r\n }\r\n\r\n return rect;\r\n },\r\n\r\n tlbrToXywh: function tlbrToXywh(rect) {\r\n if (rect && !('x' in rect && 'y' in rect)) {\r\n rect = extend({}, rect);\r\n\r\n rect.x = rect.left || 0;\r\n rect.top = rect.top || 0;\r\n rect.width = rect.width || rect.right - rect.x;\r\n rect.height = rect.height || rect.bottom - rect.y;\r\n }\r\n\r\n return rect;\r\n }\r\n};\r\n\r\nmodule.exports = rectUtils;\r\n\r\n},{\"./domUtils\":39,\"./extend\":41,\"./is\":46}],52:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar win = module.exports;\r\nvar isWindow = require('./isWindow');\r\n\r\nfunction init(window) {\r\n // get wrapped window if using Shadow DOM polyfill\r\n\r\n win.realWindow = window;\r\n\r\n // create a TextNode\r\n var el = window.document.createTextNode('');\r\n\r\n // check if it's wrapped by a polyfill\r\n if (el.ownerDocument !== window.document && typeof window.wrap === 'function' && window.wrap(el) === el) {\r\n // use wrapped window\r\n window = window.wrap(window);\r\n }\r\n\r\n win.window = window;\r\n}\r\n\r\nif (typeof window === 'undefined') {\r\n win.window = undefined;\r\n win.realWindow = undefined;\r\n} else {\r\n init(window);\r\n}\r\n\r\nwin.getWindow = function getWindow(node) {\r\n if (isWindow(node)) {\r\n return node;\r\n }\r\n\r\n var rootNode = node.ownerDocument || node;\r\n\r\n return rootNode.defaultView || rootNode.parentWindow || win.window;\r\n};\r\n\r\nwin.init = init;\r\n\r\n},{\"./isWindow\":47}]},{},[1])(1)\r\n});\r\n\r\n\r\n//# sourceMappingURL=interact.js.map\r\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvaW50ZXJhY3Rqcy9kaXN0L2ludGVyYWN0LmpzP2JiZmUiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IllBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLFNBQTJELG1CQUFtQixnREFBZ0QsYUFBYSxLQUFLLE1BQU0sZ0NBQWdDLFNBQVMscUNBQXFDLFNBQVMsbUNBQW1DLE9BQU8sS0FBSyxPQUFPLGtCQUFrQixhQUFhLDBCQUEwQiwwQkFBMEIsZ0JBQWdCLFVBQVUsVUFBVSwwQ0FBMEMsOEJBQXdCLG9CQUFvQiw4Q0FBOEMsa0NBQWtDLFlBQVksWUFBWSxtQ0FBbUMsaUJBQWlCLGdCQUFnQixzQkFBc0Isb0JBQW9CLDBDQUEwQyxZQUFZLFdBQVcsWUFBWSxTQUFTLEdBQUc7QUFDNXlCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBOztBQUVBLENBQUMsRUFBRSx5Q0FBeUM7QUFDNUM7O0FBRUEsaURBQWlELDBDQUEwQywwREFBMEQsRUFBRTs7QUFFdko7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLHlDQUF5QywrQ0FBK0M7QUFDeEY7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSw0QkFBNEIsZUFBZTtBQUMzQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEOztBQUVBLENBQUMsRUFBRSx3Q0FBd0M7QUFDM0M7O0FBRUEsaURBQWlELDBDQUEwQywwREFBMEQsRUFBRTs7QUFFdko7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLHdCQUF3QjtBQUN4QiwwQkFBMEI7O0FBRTFCO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLHdGQUF3RjtBQUMzRjs7QUFFQSxpREFBaUQsMENBQTBDLDBEQUEwRCxFQUFFOztBQUV2SjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7OztBQUdBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtGQUFrRjs7QUFFbEY7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSx3SkFBd0o7QUFDeEo7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdURBQXVELGFBQWE7QUFDcEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUZBQXlGO0FBQ3pGO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxxQkFBcUIsc0JBQXNCO0FBQzNDO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDRCQUE0Qjs7QUFFNUIsOEJBQThCOztBQUU5QjtBQUNBOztBQUVBLDBDQUEwQzs7QUFFMUM7O0FBRUE7QUFDQTs7QUFFQSw2S0FBNks7QUFDN0s7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUEsMkJBQTJCLHFCQUFxQjs7QUFFaEQ7O0FBRUE7QUFDQSx5S0FBeUs7QUFDeks7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEO0FBQ0E7O0FBRUEsaUJBQWlCLGlCQUFpQjtBQUNsQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsaUJBQWlCLGlCQUFpQjtBQUNsQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLG1PQUFtTztBQUN0Tzs7QUFFQSxpREFBaUQsMENBQTBDLDBEQUEwRCxFQUFFOztBQUV2SjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsdUJBQXVCO0FBQ3ZCLHdCQUF3Qjs7QUFFeEIscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGFBQWEsYUFBYTtBQUMxQixlQUFlLGFBQWE7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLGFBQWE7QUFDMUIsZUFBZSxhQUFhO0FBQzVCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGFBQWEsYUFBYTtBQUMxQixlQUFlLGFBQWE7QUFDNUI7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsYUFBYSxxQ0FBcUM7QUFDbEQsZUFBZSxxQ0FBcUM7QUFDcEQ7QUFDQTs7QUFFQSwwQkFBMEI7QUFDMUI7O0FBRUE7QUFDQTs7QUFFQSwwQkFBMEI7O0FBRTFCO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkMscUJBQXFCO0FBQ2xFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhCQUE4QixlQUFlO0FBQzdDO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5Q0FBeUMsUUFBUSxlQUFlO0FBQ2hFO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSyxpQkFBaUI7O0FBRXRCOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwwQkFBMEIsb0JBQW9COztBQUU5QztBQUNBLG1DQUFtQyxvQkFBb0I7QUFDdkQsa0RBQWtELG9CQUFvQjtBQUN0RTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLENBQUM7O0FBRUQseUNBQXlDLFNBQVM7QUFDbEQ7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLHFCQUFxQjs7QUFFckI7QUFDQTs7QUFFQSxzQkFBc0Isa0NBQWtDO0FBQ3hEO0FBQ0E7O0FBRUEsK0RBQStELDJCQUEyQjtBQUMxRjtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0EseUJBQXlCLG9EQUFvRDtBQUM3RTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsMENBQTBDLDJCQUEyQjtBQUNyRTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsaUpBQWlKO0FBQ2pKOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLG1CQUFtQixpQ0FBaUM7QUFDcEQ7O0FBRUE7QUFDQSw0QkFBNEIseUNBQXlDO0FBQ3JFO0FBQ0E7O0FBRUEsaUJBQWlCO0FBQ2pCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQSxDQUFDLEVBQUUsK0lBQStJO0FBQ2xKOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLHdDQUF3QztBQUMzQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBOztBQUVBLGtDQUFrQyxzR0FBc0c7QUFDeEksR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DO0FBQ25DLG1DQUFtQztBQUNuQyxtQ0FBbUM7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLDRHQUE0RztBQUMvRzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTs7QUFFQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsMEpBQTBKO0FBQzFKOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsbUJBQW1CLHlCQUF5QjtBQUM1Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsaUJBQWlCLDhDQUE4QztBQUMvRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLGlCQUFpQiw4Q0FBOEM7QUFDL0Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUIsOENBQThDO0FBQy9EO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHVDQUF1QyxvQkFBb0I7O0FBRTNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLG9DQUFvQyxlQUFlOztBQUVuRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3Qyx1QkFBdUI7O0FBRS9EO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMENBQTBDLHlCQUF5Qjs7QUFFbkU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNENBQTRDO0FBQzVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEOztBQUVBO0FBQ0EsZ0NBQWdDO0FBQ2hDLGlDQUFpQztBQUNqQyxvQ0FBb0M7QUFDcEMscUNBQXFDO0FBQ3JDLGdDQUFnQzs7QUFFaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTs7QUFFQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQSxDQUFDLEVBQUUsMklBQTJJO0FBQzlJOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0EsY0FBYztBQUNkOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUM7QUFDbkMsbUNBQW1DO0FBQ25DLG1DQUFtQztBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0EsWUFBWSxhQUFhOztBQUV6QjtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQSxDQUFDLEVBQUUsNEdBQTRHO0FBQy9HOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDhCQUE4QjtBQUM5Qjs7QUFFQTtBQUNBO0FBQ0EseUJBQXlCOztBQUV6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUEscUJBQXFCLE9BQU87QUFDNUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQ0FBcUM7O0FBRXJDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDRCQUE0QjtBQUM1Qiw2QkFBNkI7QUFDN0IsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQztBQUNuQyxtQ0FBbUM7QUFDbkMsbUNBQW1DO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBLENBQUMsRUFBRSxrSUFBa0k7QUFDckk7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxDQUFDOztBQUVEOztBQUVBOztBQUVBOztBQUVBLENBQUMsRUFBRSxtSEFBbUg7QUFDdEg7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCLG1EQUFtRDtBQUN6RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQixvREFBb0Q7QUFDMUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUI7QUFDdkI7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsb0pBQW9KO0FBQ3BKOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLENBQUMsRUFBRSxnRkFBZ0Y7QUFDbkY7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsdUNBQXVDLFNBQVM7QUFDaEQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsNEJBQTRCLDJCQUEyQjtBQUN2RDs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QjtBQUN2QjtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBLG9KQUFvSjtBQUNwSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxrREFBa0QsU0FBUztBQUMzRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLHNNQUFzTTtBQUN6TTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELENBQUMsRUFBRSwrQkFBK0I7QUFDbEM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUEsQ0FBQyxFQUFFLDRHQUE0RztBQUMvRzs7QUFFQTs7QUFFQSxDQUFDLEVBQUUsbUNBQW1DO0FBQ3RDOztBQUVBOztBQUVBLENBQUMsRUFBRSxtQ0FBbUM7QUFDdEM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQSxhQUFhLGFBQWE7O0FBRTFCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxDQUFDLEdBQUc7QUFDSjs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxDQUFDLEVBQUUsc2dCQUFzZ0I7QUFDemdCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGdCQUFnQjs7QUFFaEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsNEJBQTRCO0FBQzVCOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBLENBQUMsRUFBRSxxRkFBcUY7QUFDeEY7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw2SUFBNkk7QUFDN0k7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtEQUFrRCxtQkFBbUI7QUFDckU7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxxSkFBcUo7QUFDcko7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkMsUUFBUTtBQUNyRDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBLENBQUMsRUFBRSx3R0FBd0c7QUFDM0c7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZ0JBQWdCLGtCQUFrQjtBQUNsQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDBKQUEwSjtBQUMxSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7OztBQUdBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsQ0FBQyxFQUFFLDRHQUE0RztBQUMvRzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDJKQUEySjtBQUMzSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLG1JQUFtSTtBQUN0STs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLG1CQUFtQiw0QkFBNEI7QUFDL0M7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsMEJBQTBCO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHdKQUF3SjtBQUN4Sjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBLGdLQUFnSztBQUNoSzs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsOEJBQThCO0FBQzlCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBLDJEQUEyRDtBQUMzRDtBQUNBLENBQUM7O0FBRUQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTs7QUFFQSxpQkFBaUIsNEJBQTRCO0FBQzdDOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDBCQUEwQiw2QkFBNkI7QUFDdkQ7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7O0FBRUEsNkJBQTZCOztBQUU3QixpQkFBaUIsNEJBQTRCO0FBQzdDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxDQUFDLEVBQUUsNkRBQTZEO0FBQ2hFOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEscUNBQXFDLDJCQUEyQixrQkFBa0I7O0FBRWxGOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLGtEQUFrRDtBQUNyRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWEsd0JBQXdCO0FBQ3JDO0FBQ0EsZUFBZSwrQ0FBK0M7QUFDOUQsZUFBZSwrQ0FBK0M7QUFDOUQsTUFBTTtBQUNOLElBQUk7O0FBRUo7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLGVBQWU7QUFDZixlQUFlOztBQUVmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDRCQUE0QjtBQUM1Qjs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBLHFDQUFxQywyQkFBMkIsa0JBQWtCO0FBQ2xGO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQSxDQUFDLEVBQUUsNEdBQTRHO0FBQy9HOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSx3QkFBd0I7QUFDckM7QUFDQSxhQUFhLDRCQUE0QjtBQUN6QyxhQUFhLDRCQUE0QjtBQUN6QyxNQUFNO0FBQ04sSUFBSTs7QUFFSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsYUFBYTtBQUNiLGFBQWE7O0FBRWI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCO0FBQzVCLDRCQUE0QjtBQUM1Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLGlIQUFpSDtBQUNwSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQSxrREFBa0Q7QUFDbEQ7O0FBRUE7QUFDQSxpS0FBaUs7QUFDaks7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsY0FBYztBQUNkLEtBQUs7QUFDTDs7QUFFQSw0QkFBNEI7O0FBRTVCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBLHdKQUF3SjtBQUN4Sjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsa0tBQWtLO0FBQ2xLOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFNBQVM7QUFDVDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEscUNBQXFDLFNBQVM7QUFDOUM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQSxDQUFDLEVBQUUsbUVBQW1FO0FBQ3RFOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxlQUFlLGFBQWE7QUFDNUI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsOEJBQThCO0FBQzlCO0FBQ0E7O0FBRUEsaUNBQWlDO0FBQ2pDOztBQUVBLHdKQUF3SjtBQUN4Sjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBOzs7QUFHQSxpQ0FBaUM7QUFDakM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBLENBQUMsRUFBRSxzRkFBc0Y7QUFDekY7O0FBRUEsaURBQWlELDBDQUEwQywwREFBMEQsRUFBRTs7QUFFdko7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsQ0FBQzs7QUFFRCxDQUFDLEVBQUUsMkJBQTJCO0FBQzlCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxpQkFBaUIsb0JBQW9CO0FBQ3JDOztBQUVBLHVDQUF1QztBQUN2QztBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSwySUFBMkk7QUFDM0k7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLDBDQUEwQztBQUMxQyxDQUFDOztBQUVEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsaURBQWlEOztBQUVqRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsbUpBQW1KO0FBQ25KOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxpQkFBaUIsOEJBQThCO0FBQy9DO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxHQUFHO0FBQ0gsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsVUFBVSxrR0FBa0c7QUFDNUc7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxVQUFVLGlHQUFpRztBQUMzRztBQUNBOztBQUVBLGVBQWUsMEJBQTBCO0FBQ3pDO0FBQ0E7O0FBRUE7QUFDQSw2QkFBNkI7QUFDN0IsMEJBQTBCO0FBQzFCLDhCQUE4QixNQUFNLG9CQUFvQjtBQUN4RCxDQUFDOztBQUVEO0FBQ0E7O0FBRUEsQ0FBQyxFQUFFLDBJQUEwSTtBQUM3STs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxnQkFBZ0Isa0JBQWtCO0FBQ2xDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxHQUFHO0FBQ0g7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxDQUFDLEVBQUUsK0JBQStCO0FBQ2xDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCLE9BQU87QUFDUDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQixPQUFPO0FBQ1A7QUFDQTs7QUFFQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQSxDQUFDLEVBQUUsbUpBQW1KO0FBQ3RKOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxrQ0FBa0MscUJBQXFCO0FBQ3ZELEdBQUc7O0FBRUg7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBLHFDQUFxQyxxQkFBcUI7QUFDMUQsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxDQUFDLEVBQUUsOEVBQThFO0FBQ2pGOztBQUVBLGlEQUFpRCwwQ0FBMEMsMERBQTBELEVBQUU7O0FBRXZKO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxtQkFBbUIsNEJBQTRCO0FBQy9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxDQUFDLEVBQUUsV0FBVztBQUNkOztBQUVBO0FBQ0EscUNBQXFDLFNBQVM7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUIsbUJBQW1CO0FBQ3BDO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBLGlCQUFpQixrQkFBa0I7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsQ0FBQyxHQUFHO0FBQ0o7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBLENBQUMsRUFBRSwwQ0FBMEM7QUFDN0M7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLGNBQWM7QUFDakI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTs7QUFFQSx1Q0FBdUMsU0FBUztBQUNoRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsZUFBZSxxQkFBcUI7QUFDcEM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxPQUFPO0FBQ1A7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLHlEQUF5RDtBQUM1RDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxxQkFBcUIsU0FBUztBQUM5QjtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsc0JBQXNCLFVBQVU7QUFDaEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLG1CQUFtQixzQkFBc0I7QUFDekM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSw4Q0FBOEMsWUFBWTtBQUMxRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDhDQUE4QyxZQUFZO0FBQzFEO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSx3Q0FBd0MsUUFBUTtBQUNoRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxtQkFBbUIsZ0NBQWdDO0FBQ25EO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUEsdUJBQXVCLHNCQUFzQjtBQUM3QztBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxxQ0FBcUM7QUFDckM7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxDQUFDLEVBQUUsd0VBQXdFO0FBQzNFOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxDQUFDLEdBQUc7QUFDSjs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsa0NBQWtDO0FBQ2xDOztBQUVBLENBQUMsRUFBRSxZQUFZO0FBQ2Y7O0FBRUE7QUFDQTtBQUNBOztBQUVBLENBQUMsR0FBRztBQUNKOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxDQUFDLEVBQUUsaUlBQWlJO0FBQ3BJOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUI7O0FBRW5CLDJKQUEySjtBQUMzSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLG1LQUFtSztBQUNuSzs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBLG1LQUFtSztBQUNuSzs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLG1LQUFtSztBQUNuSzs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTs7QUFFQSxtS0FBbUs7QUFDbks7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7O0FBRUEsbUtBQW1LO0FBQ25LOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLDJCQUEyQjtBQUM5Qjs7QUFFQSxvR0FBb0csbUJBQW1CLEVBQUUsbUJBQW1CLDhIQUE4SDs7QUFFMVE7QUFDQTs7QUFFQTtBQUNBLDRCQUE0Qjs7QUFFNUI7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLDhCQUE4QjtBQUNqQzs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsQ0FBQyxHQUFHO0FBQ0o7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxDQUFDLEdBQUc7QUFDSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxpSkFBaUo7QUFDako7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLENBQUMsRUFBRSw2RkFBNkY7QUFDaEc7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxlQUFlLHFEQUFxRDtBQUNwRTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLENBQUMsRUFBRSxjQUFjO0FBQ2pCOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLHNCQUFzQjs7QUFFdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLHNCQUFzQjs7QUFFdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLHdDQUF3QztBQUMzQzs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQSxDQUFDLEVBQUUsZ0JBQWdCLEVBQUUsR0FBRztBQUN4QixDQUFDOzs7QUFHRCIsImZpbGUiOiIxNS5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxyXG4gKiBpbnRlcmFjdC5qcyB2MS4zLjAtYWxwaGEuNCtzaGEuNzk3MDQxNi1kaXJ0eVxyXG4gKlxyXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTItMjAxNyBUYXllIEFkZXllbWkgPGRldkB0YXllLm1lPlxyXG4gKiBPcGVuIHNvdXJjZSB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXHJcbiAqIGh0dHBzOi8vcmF3LmdpdGh1Yi5jb20vdGF5ZS9pbnRlcmFjdC5qcy9tYXN0ZXIvTElDRU5TRVxyXG4gKi9cclxuKGZ1bmN0aW9uKGYpe2lmKHR5cGVvZiBleHBvcnRzPT09XCJvYmplY3RcIiYmdHlwZW9mIG1vZHVsZSE9PVwidW5kZWZpbmVkXCIpe21vZHVsZS5leHBvcnRzPWYoKX1lbHNlIGlmKHR5cGVvZiBkZWZpbmU9PT1cImZ1bmN0aW9uXCImJmRlZmluZS5hbWQpe2RlZmluZShbXSxmKX1lbHNle3ZhciBnO2lmKHR5cGVvZiB3aW5kb3chPT1cInVuZGVmaW5lZFwiKXtnPXdpbmRvd31lbHNlIGlmKHR5cGVvZiBnbG9iYWwhPT1cInVuZGVmaW5lZFwiKXtnPWdsb2JhbH1lbHNlIGlmKHR5cGVvZiBzZWxmIT09XCJ1bmRlZmluZWRcIil7Zz1zZWxmfWVsc2V7Zz10aGlzfWcuaW50ZXJhY3QgPSBmKCl9fSkoZnVuY3Rpb24oKXt2YXIgZGVmaW5lLG1vZHVsZSxleHBvcnRzO3JldHVybiAoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSh7MTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbi8qXHJcbiAqIEluIGEgKHdpbmRvd2xlc3MpIHNlcnZlciBlbnZpcm9ubWVudCB0aGlzIGZpbGUgZXhwb3J0cyBhIGZhY3RvcnkgZnVuY3Rpb25cclxuICogdGhhdCB0YWtlcyB0aGUgd2luZG93IHRvIHVzZS5cclxuICpcclxuICogICAgIHZhciBpbnRlcmFjdCA9IHJlcXVpcmUoJ2ludGVyYWN0LmpzJykod2luZG93T2JqZWN0KTtcclxuICpcclxuICogU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS90YXllL2ludGVyYWN0LmpzL2lzc3Vlcy8xODdcclxuICovXHJcbmlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykge1xyXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHdpbmRvdykge1xyXG4gICAgcmVxdWlyZSgnLi9zcmMvdXRpbHMvd2luZG93JykuaW5pdCh3aW5kb3cpO1xyXG5cclxuICAgIHJldHVybiByZXF1aXJlKCcuL3NyYy9pbmRleCcpO1xyXG4gIH07XHJcbn0gZWxzZSB7XHJcbiAgbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL3NyYy9pbmRleCcpO1xyXG59XHJcblxyXG59LHtcIi4vc3JjL2luZGV4XCI6MTksXCIuL3NyYy91dGlscy93aW5kb3dcIjo1Mn1dLDI6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xyXG4ndXNlIHN0cmljdCc7XHJcblxyXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxyXG5cclxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnLi91dGlscy9hcnInKSxcclxuICAgIGluZGV4T2YgPSBfcmVxdWlyZS5pbmRleE9mO1xyXG5cclxudmFyIGV4dGVuZCA9IHJlcXVpcmUoJy4vdXRpbHMvZXh0ZW5kLmpzJyk7XHJcblxyXG5mdW5jdGlvbiBmaXJlVW50aWxJbW1lZGlhdGVTdG9wcGVkKGV2ZW50LCBsaXN0ZW5lcnMpIHtcclxuICBmb3IgKHZhciBpID0gMCwgbGVuID0gbGlzdGVuZXJzLmxlbmd0aDsgaSA8IGxlbiAmJiAhZXZlbnQuaW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkOyBpKyspIHtcclxuICAgIGxpc3RlbmVyc1tpXShldmVudCk7XHJcbiAgfVxyXG59XHJcblxyXG52YXIgRXZlbnRhYmxlID0gZnVuY3Rpb24gKCkge1xyXG4gIGZ1bmN0aW9uIEV2ZW50YWJsZShvcHRpb25zKSB7XHJcbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgRXZlbnRhYmxlKTtcclxuXHJcbiAgICB0aGlzLm9wdGlvbnMgPSBleHRlbmQoe30sIG9wdGlvbnMgfHwge30pO1xyXG4gIH1cclxuXHJcbiAgRXZlbnRhYmxlLnByb3RvdHlwZS5maXJlID0gZnVuY3Rpb24gZmlyZShldmVudCkge1xyXG4gICAgdmFyIGxpc3RlbmVycyA9IHZvaWQgMDtcclxuICAgIHZhciBvbkV2ZW50ID0gJ29uJyArIGV2ZW50LnR5cGU7XHJcbiAgICB2YXIgZ2xvYmFsID0gdGhpcy5nbG9iYWw7XHJcblxyXG4gICAgLy8gSW50ZXJhY3RhYmxlI29uKCkgbGlzdGVuZXJzXHJcbiAgICBpZiAobGlzdGVuZXJzID0gdGhpc1tldmVudC50eXBlXSkge1xyXG4gICAgICBmaXJlVW50aWxJbW1lZGlhdGVTdG9wcGVkKGV2ZW50LCBsaXN0ZW5lcnMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGludGVyYWN0YWJsZS5vbmV2ZW50IGxpc3RlbmVyXHJcbiAgICBpZiAodGhpc1tvbkV2ZW50XSkge1xyXG4gICAgICB0aGlzW29uRXZlbnRdKGV2ZW50KTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBpbnRlcmFjdC5vbigpIGxpc3RlbmVyc1xyXG4gICAgaWYgKCFldmVudC5wcm9wYWdhdGlvblN0b3BwZWQgJiYgZ2xvYmFsICYmIChsaXN0ZW5lcnMgPSBnbG9iYWxbZXZlbnQudHlwZV0pKSB7XHJcbiAgICAgIGZpcmVVbnRpbEltbWVkaWF0ZVN0b3BwZWQoZXZlbnQsIGxpc3RlbmVycyk7XHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgRXZlbnRhYmxlLnByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIG9uKGV2ZW50VHlwZSwgbGlzdGVuZXIpIHtcclxuICAgIC8vIGlmIHRoaXMgdHlwZSBvZiBldmVudCB3YXMgbmV2ZXIgYm91bmRcclxuICAgIGlmICh0aGlzW2V2ZW50VHlwZV0pIHtcclxuICAgICAgdGhpc1tldmVudFR5cGVdLnB1c2gobGlzdGVuZXIpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpc1tldmVudFR5cGVdID0gW2xpc3RlbmVyXTtcclxuICAgIH1cclxuICB9O1xyXG5cclxuICBFdmVudGFibGUucHJvdG90eXBlLm9mZiA9IGZ1bmN0aW9uIG9mZihldmVudFR5cGUsIGxpc3RlbmVyKSB7XHJcbiAgICAvLyBpZiBpdCBpcyBhbiBhY3Rpb24gZXZlbnQgdHlwZVxyXG4gICAgdmFyIGV2ZW50TGlzdCA9IHRoaXNbZXZlbnRUeXBlXTtcclxuICAgIHZhciBpbmRleCA9IGV2ZW50TGlzdCA/IGluZGV4T2YoZXZlbnRMaXN0LCBsaXN0ZW5lcikgOiAtMTtcclxuXHJcbiAgICBpZiAoaW5kZXggIT09IC0xKSB7XHJcbiAgICAgIGV2ZW50TGlzdC5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChldmVudExpc3QgJiYgZXZlbnRMaXN0Lmxlbmd0aCA9PT0gMCB8fCAhbGlzdGVuZXIpIHtcclxuICAgICAgdGhpc1tldmVudFR5cGVdID0gbGlzdGVuZXI7XHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgcmV0dXJuIEV2ZW50YWJsZTtcclxufSgpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBFdmVudGFibGU7XHJcblxyXG59LHtcIi4vdXRpbHMvYXJyXCI6MzYsXCIuL3V0aWxzL2V4dGVuZC5qc1wiOjQxfV0sMzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XHJcblxyXG52YXIgZXh0ZW5kID0gcmVxdWlyZSgnLi91dGlscy9leHRlbmQnKTtcclxudmFyIGdldE9yaWdpblhZID0gcmVxdWlyZSgnLi91dGlscy9nZXRPcmlnaW5YWScpO1xyXG52YXIgZGVmYXVsdHMgPSByZXF1aXJlKCcuL2RlZmF1bHRPcHRpb25zJyk7XHJcbnZhciBzaWduYWxzID0gcmVxdWlyZSgnLi91dGlscy9TaWduYWxzJykubmV3KCk7XHJcblxyXG52YXIgSW50ZXJhY3RFdmVudCA9IGZ1bmN0aW9uICgpIHtcclxuICBmdW5jdGlvbiBJbnRlcmFjdEV2ZW50KGludGVyYWN0aW9uLCBldmVudCwgYWN0aW9uLCBwaGFzZSwgZWxlbWVudCwgcmVsYXRlZCkge1xyXG4gICAgdmFyIHByZUVuZCA9IGFyZ3VtZW50cy5sZW5ndGggPiA2ICYmIGFyZ3VtZW50c1s2XSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzZdIDogZmFsc2U7XHJcblxyXG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEludGVyYWN0RXZlbnQpO1xyXG5cclxuICAgIHZhciB0YXJnZXQgPSBpbnRlcmFjdGlvbi50YXJnZXQ7XHJcbiAgICB2YXIgZGVsdGFTb3VyY2UgPSAodGFyZ2V0ICYmIHRhcmdldC5vcHRpb25zIHx8IGRlZmF1bHRzKS5kZWx0YVNvdXJjZTtcclxuICAgIHZhciBvcmlnaW4gPSBnZXRPcmlnaW5YWSh0YXJnZXQsIGVsZW1lbnQsIGFjdGlvbik7XHJcbiAgICB2YXIgc3RhcnRpbmcgPSBwaGFzZSA9PT0gJ3N0YXJ0JztcclxuICAgIHZhciBlbmRpbmcgPSBwaGFzZSA9PT0gJ2VuZCc7XHJcbiAgICB2YXIgY29vcmRzID0gc3RhcnRpbmcgPyBpbnRlcmFjdGlvbi5zdGFydENvb3JkcyA6IGludGVyYWN0aW9uLmN1ckNvb3JkcztcclxuICAgIHZhciBwcmV2RXZlbnQgPSBpbnRlcmFjdGlvbi5wcmV2RXZlbnQ7XHJcblxyXG4gICAgZWxlbWVudCA9IGVsZW1lbnQgfHwgaW50ZXJhY3Rpb24uZWxlbWVudDtcclxuXHJcbiAgICB2YXIgcGFnZSA9IGV4dGVuZCh7fSwgY29vcmRzLnBhZ2UpO1xyXG4gICAgdmFyIGNsaWVudCA9IGV4dGVuZCh7fSwgY29vcmRzLmNsaWVudCk7XHJcblxyXG4gICAgcGFnZS54IC09IG9yaWdpbi54O1xyXG4gICAgcGFnZS55IC09IG9yaWdpbi55O1xyXG5cclxuICAgIGNsaWVudC54IC09IG9yaWdpbi54O1xyXG4gICAgY2xpZW50LnkgLT0gb3JpZ2luLnk7XHJcblxyXG4gICAgdGhpcy5jdHJsS2V5ID0gZXZlbnQuY3RybEtleTtcclxuICAgIHRoaXMuYWx0S2V5ID0gZXZlbnQuYWx0S2V5O1xyXG4gICAgdGhpcy5zaGlmdEtleSA9IGV2ZW50LnNoaWZ0S2V5O1xyXG4gICAgdGhpcy5tZXRhS2V5ID0gZXZlbnQubWV0YUtleTtcclxuICAgIHRoaXMuYnV0dG9uID0gZXZlbnQuYnV0dG9uO1xyXG4gICAgdGhpcy5idXR0b25zID0gZXZlbnQuYnV0dG9ucztcclxuICAgIHRoaXMudGFyZ2V0ID0gZWxlbWVudDtcclxuICAgIHRoaXMuY3VycmVudFRhcmdldCA9IGVsZW1lbnQ7XHJcbiAgICB0aGlzLnJlbGF0ZWRUYXJnZXQgPSByZWxhdGVkIHx8IG51bGw7XHJcbiAgICB0aGlzLnByZUVuZCA9IHByZUVuZDtcclxuICAgIHRoaXMudHlwZSA9IGFjdGlvbiArIChwaGFzZSB8fCAnJyk7XHJcbiAgICB0aGlzLmludGVyYWN0aW9uID0gaW50ZXJhY3Rpb247XHJcbiAgICB0aGlzLmludGVyYWN0YWJsZSA9IHRhcmdldDtcclxuXHJcbiAgICB0aGlzLnQwID0gc3RhcnRpbmcgPyBpbnRlcmFjdGlvbi5kb3duVGltZXNbaW50ZXJhY3Rpb24uZG93blRpbWVzLmxlbmd0aCAtIDFdIDogcHJldkV2ZW50LnQwO1xyXG5cclxuICAgIHZhciBzaWduYWxBcmcgPSB7XHJcbiAgICAgIGludGVyYWN0aW9uOiBpbnRlcmFjdGlvbixcclxuICAgICAgZXZlbnQ6IGV2ZW50LFxyXG4gICAgICBhY3Rpb246IGFjdGlvbixcclxuICAgICAgcGhhc2U6IHBoYXNlLFxyXG4gICAgICBlbGVtZW50OiBlbGVtZW50LFxyXG4gICAgICByZWxhdGVkOiByZWxhdGVkLFxyXG4gICAgICBwYWdlOiBwYWdlLFxyXG4gICAgICBjbGllbnQ6IGNsaWVudCxcclxuICAgICAgY29vcmRzOiBjb29yZHMsXHJcbiAgICAgIHN0YXJ0aW5nOiBzdGFydGluZyxcclxuICAgICAgZW5kaW5nOiBlbmRpbmcsXHJcbiAgICAgIGRlbHRhU291cmNlOiBkZWx0YVNvdXJjZSxcclxuICAgICAgaUV2ZW50OiB0aGlzXHJcbiAgICB9O1xyXG5cclxuICAgIHNpZ25hbHMuZmlyZSgnc2V0LXh5Jywgc2lnbmFsQXJnKTtcclxuXHJcbiAgICBpZiAoZW5kaW5nKSB7XHJcbiAgICAgIC8vIHVzZSBwcmV2aW91cyBjb29yZHMgd2hlbiBlbmRpbmdcclxuICAgICAgdGhpcy5wYWdlWCA9IHByZXZFdmVudC5wYWdlWDtcclxuICAgICAgdGhpcy5wYWdlWSA9IHByZXZFdmVudC5wYWdlWTtcclxuICAgICAgdGhpcy5jbGllbnRYID0gcHJldkV2ZW50LmNsaWVudFg7XHJcbiAgICAgIHRoaXMuY2xpZW50WSA9IHByZXZFdmVudC5jbGllbnRZO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5wYWdlWCA9IHBhZ2UueDtcclxuICAgICAgdGhpcy5wYWdlWSA9IHBhZ2UueTtcclxuICAgICAgdGhpcy5jbGllbnRYID0gY2xpZW50Lng7XHJcbiAgICAgIHRoaXMuY2xpZW50WSA9IGNsaWVudC55O1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMueDAgPSBpbnRlcmFjdGlvbi5zdGFydENvb3Jkcy5wYWdlLnggLSBvcmlnaW4ueDtcclxuICAgIHRoaXMueTAgPSBpbnRlcmFjdGlvbi5zdGFydENvb3Jkcy5wYWdlLnkgLSBvcmlnaW4ueTtcclxuICAgIHRoaXMuY2xpZW50WDAgPSBpbnRlcmFjdGlvbi5zdGFydENvb3Jkcy5jbGllbnQueCAtIG9yaWdpbi54O1xyXG4gICAgdGhpcy5jbGllbnRZMCA9IGludGVyYWN0aW9uLnN0YXJ0Q29vcmRzLmNsaWVudC55IC0gb3JpZ2luLnk7XHJcblxyXG4gICAgc2lnbmFscy5maXJlKCdzZXQtZGVsdGEnLCBzaWduYWxBcmcpO1xyXG5cclxuICAgIHRoaXMudGltZVN0YW1wID0gY29vcmRzLnRpbWVTdGFtcDtcclxuICAgIHRoaXMuZHQgPSBpbnRlcmFjdGlvbi5wb2ludGVyRGVsdGEudGltZVN0YW1wO1xyXG4gICAgdGhpcy5kdXJhdGlvbiA9IHRoaXMudGltZVN0YW1wIC0gdGhpcy50MDtcclxuXHJcbiAgICAvLyBzcGVlZCBhbmQgdmVsb2NpdHkgaW4gcGl4ZWxzIHBlciBzZWNvbmRcclxuICAgIHRoaXMuc3BlZWQgPSBpbnRlcmFjdGlvbi5wb2ludGVyRGVsdGFbZGVsdGFTb3VyY2VdLnNwZWVkO1xyXG4gICAgdGhpcy52ZWxvY2l0eVggPSBpbnRlcmFjdGlvbi5wb2ludGVyRGVsdGFbZGVsdGFTb3VyY2VdLnZ4O1xyXG4gICAgdGhpcy52ZWxvY2l0eVkgPSBpbnRlcmFjdGlvbi5wb2ludGVyRGVsdGFbZGVsdGFTb3VyY2VdLnZ5O1xyXG5cclxuICAgIHRoaXMuc3dpcGUgPSBlbmRpbmcgfHwgcGhhc2UgPT09ICdpbmVydGlhc3RhcnQnID8gdGhpcy5nZXRTd2lwZSgpIDogbnVsbDtcclxuXHJcbiAgICBzaWduYWxzLmZpcmUoJ25ldycsIHNpZ25hbEFyZyk7XHJcbiAgfVxyXG5cclxuICBJbnRlcmFjdEV2ZW50LnByb3RvdHlwZS5nZXRTd2lwZSA9IGZ1bmN0aW9uIGdldFN3aXBlKCkge1xyXG4gICAgdmFyIGludGVyYWN0aW9uID0gdGhpcy5pbnRlcmFjdGlvbjtcclxuXHJcbiAgICBpZiAoaW50ZXJhY3Rpb24ucHJldkV2ZW50LnNwZWVkIDwgNjAwIHx8IHRoaXMudGltZVN0YW1wIC0gaW50ZXJhY3Rpb24ucHJldkV2ZW50LnRpbWVTdGFtcCA+IDE1MCkge1xyXG4gICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgYW5nbGUgPSAxODAgKiBNYXRoLmF0YW4yKGludGVyYWN0aW9uLnByZXZFdmVudC52ZWxvY2l0eVksIGludGVyYWN0aW9uLnByZXZFdmVudC52ZWxvY2l0eVgpIC8gTWF0aC5QSTtcclxuICAgIHZhciBvdmVybGFwID0gMjIuNTtcclxuXHJcbiAgICBpZiAoYW5nbGUgPCAwKSB7XHJcbiAgICAgIGFuZ2xlICs9IDM2MDtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgbGVmdCA9IDEzNSAtIG92ZXJsYXAgPD0gYW5nbGUgJiYgYW5nbGUgPCAyMjUgKyBvdmVybGFwO1xyXG4gICAgdmFyIHVwID0gMjI1IC0gb3ZlcmxhcCA8PSBhbmdsZSAmJiBhbmdsZSA8IDMxNSArIG92ZXJsYXA7XHJcblxyXG4gICAgdmFyIHJpZ2h0ID0gIWxlZnQgJiYgKDMxNSAtIG92ZXJsYXAgPD0gYW5nbGUgfHwgYW5nbGUgPCA0NSArIG92ZXJsYXApO1xyXG4gICAgdmFyIGRvd24gPSAhdXAgJiYgNDUgLSBvdmVybGFwIDw9IGFuZ2xlICYmIGFuZ2xlIDwgMTM1ICsgb3ZlcmxhcDtcclxuXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICB1cDogdXAsXHJcbiAgICAgIGRvd246IGRvd24sXHJcbiAgICAgIGxlZnQ6IGxlZnQsXHJcbiAgICAgIHJpZ2h0OiByaWdodCxcclxuICAgICAgYW5nbGU6IGFuZ2xlLFxyXG4gICAgICBzcGVlZDogaW50ZXJhY3Rpb24ucHJldkV2ZW50LnNwZWVkLFxyXG4gICAgICB2ZWxvY2l0eToge1xyXG4gICAgICAgIHg6IGludGVyYWN0aW9uLnByZXZFdmVudC52ZWxvY2l0eVgsXHJcbiAgICAgICAgeTogaW50ZXJhY3Rpb24ucHJldkV2ZW50LnZlbG9jaXR5WVxyXG4gICAgICB9XHJcbiAgICB9O1xyXG4gIH07XHJcblxyXG4gIEludGVyYWN0RXZlbnQucHJvdG90eXBlLnByZXZlbnREZWZhdWx0ID0gZnVuY3Rpb24gcHJldmVudERlZmF1bHQoKSB7fTtcclxuXHJcbiAgSW50ZXJhY3RFdmVudC5wcm90b3R5cGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uID0gZnVuY3Rpb24gc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCkge1xyXG4gICAgdGhpcy5pbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQgPSB0aGlzLnByb3BhZ2F0aW9uU3RvcHBlZCA9IHRydWU7XHJcbiAgfTtcclxuXHJcbiAgSW50ZXJhY3RFdmVudC5wcm90b3R5cGUuc3RvcFByb3BhZ2F0aW9uID0gZnVuY3Rpb24gc3RvcFByb3BhZ2F0aW9uKCkge1xyXG4gICAgdGhpcy5wcm9wYWdhdGlvblN0b3BwZWQgPSB0cnVlO1xyXG4gIH07XHJcblxyXG4gIHJldHVybiBJbnRlcmFjdEV2ZW50O1xyXG59KCk7XHJcblxyXG5zaWduYWxzLm9uKCdzZXQtZGVsdGEnLCBmdW5jdGlvbiAoX3JlZikge1xyXG4gIHZhciBpRXZlbnQgPSBfcmVmLmlFdmVudCxcclxuICAgICAgaW50ZXJhY3Rpb24gPSBfcmVmLmludGVyYWN0aW9uLFxyXG4gICAgICBzdGFydGluZyA9IF9yZWYuc3RhcnRpbmcsXHJcbiAgICAgIGRlbHRhU291cmNlID0gX3JlZi5kZWx0YVNvdXJjZTtcclxuXHJcbiAgdmFyIHByZXZFdmVudCA9IHN0YXJ0aW5nID8gaUV2ZW50IDogaW50ZXJhY3Rpb24ucHJldkV2ZW50O1xyXG5cclxuICBpZiAoZGVsdGFTb3VyY2UgPT09ICdjbGllbnQnKSB7XHJcbiAgICBpRXZlbnQuZHggPSBpRXZlbnQuY2xpZW50WCAtIHByZXZFdmVudC5jbGllbnRYO1xyXG4gICAgaUV2ZW50LmR5ID0gaUV2ZW50LmNsaWVudFkgLSBwcmV2RXZlbnQuY2xpZW50WTtcclxuICB9IGVsc2Uge1xyXG4gICAgaUV2ZW50LmR4ID0gaUV2ZW50LnBhZ2VYIC0gcHJldkV2ZW50LnBhZ2VYO1xyXG4gICAgaUV2ZW50LmR5ID0gaUV2ZW50LnBhZ2VZIC0gcHJldkV2ZW50LnBhZ2VZO1xyXG4gIH1cclxufSk7XHJcblxyXG5JbnRlcmFjdEV2ZW50LnNpZ25hbHMgPSBzaWduYWxzO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBJbnRlcmFjdEV2ZW50O1xyXG5cclxufSx7XCIuL2RlZmF1bHRPcHRpb25zXCI6MTgsXCIuL3V0aWxzL1NpZ25hbHNcIjozNSxcIi4vdXRpbHMvZXh0ZW5kXCI6NDEsXCIuL3V0aWxzL2dldE9yaWdpblhZXCI6NDJ9XSw0OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cclxuXHJcbnZhciBpcyA9IHJlcXVpcmUoJy4vdXRpbHMvaXMnKTtcclxudmFyIGV2ZW50cyA9IHJlcXVpcmUoJy4vdXRpbHMvZXZlbnRzJyk7XHJcbnZhciBleHRlbmQgPSByZXF1aXJlKCcuL3V0aWxzL2V4dGVuZCcpO1xyXG52YXIgYWN0aW9ucyA9IHJlcXVpcmUoJy4vYWN0aW9ucy9iYXNlJyk7XHJcbnZhciBzY29wZSA9IHJlcXVpcmUoJy4vc2NvcGUnKTtcclxudmFyIEV2ZW50YWJsZSA9IHJlcXVpcmUoJy4vRXZlbnRhYmxlJyk7XHJcbnZhciBkZWZhdWx0cyA9IHJlcXVpcmUoJy4vZGVmYXVsdE9wdGlvbnMnKTtcclxudmFyIHNpZ25hbHMgPSByZXF1aXJlKCcuL3V0aWxzL1NpZ25hbHMnKS5uZXcoKTtcclxuXHJcbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJy4vdXRpbHMvZG9tVXRpbHMnKSxcclxuICAgIGdldEVsZW1lbnRSZWN0ID0gX3JlcXVpcmUuZ2V0RWxlbWVudFJlY3QsXHJcbiAgICBub2RlQ29udGFpbnMgPSBfcmVxdWlyZS5ub2RlQ29udGFpbnMsXHJcbiAgICB0cnlTZWxlY3RvciA9IF9yZXF1aXJlLnRyeVNlbGVjdG9yO1xyXG5cclxudmFyIF9yZXF1aXJlMiA9IHJlcXVpcmUoJy4vdXRpbHMvd2luZG93JyksXHJcbiAgICBnZXRXaW5kb3cgPSBfcmVxdWlyZTIuZ2V0V2luZG93O1xyXG5cclxudmFyIF9yZXF1aXJlMyA9IHJlcXVpcmUoJy4vdXRpbHMvYXJyJyksXHJcbiAgICBpbmRleE9mID0gX3JlcXVpcmUzLmluZGV4T2YsXHJcbiAgICBjb250YWlucyA9IF9yZXF1aXJlMy5jb250YWlucztcclxuXHJcbnZhciBfcmVxdWlyZTQgPSByZXF1aXJlKCcuL3V0aWxzL2Jyb3dzZXInKSxcclxuICAgIHdoZWVsRXZlbnQgPSBfcmVxdWlyZTQud2hlZWxFdmVudDtcclxuXHJcbi8vIGFsbCBzZXQgaW50ZXJhY3RhYmxlc1xyXG5cclxuXHJcbnNjb3BlLmludGVyYWN0YWJsZXMgPSBbXTtcclxuXHJcbi8qXFxcclxuICogSW50ZXJhY3RhYmxlXHJcbiBbIHByb3BlcnR5IF1cclxuICoqXHJcbiAqIE9iamVjdCB0eXBlIHJldHVybmVkIGJ5IEBpbnRlcmFjdFxyXG5cXCovXHJcblxyXG52YXIgSW50ZXJhY3RhYmxlID0gZnVuY3Rpb24gKCkge1xyXG4gIGZ1bmN0aW9uIEludGVyYWN0YWJsZSh0YXJnZXQsIG9wdGlvbnMpIHtcclxuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBJbnRlcmFjdGFibGUpO1xyXG5cclxuICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xyXG5cclxuICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0O1xyXG4gICAgdGhpcy5ldmVudHMgPSBuZXcgRXZlbnRhYmxlKCk7XHJcbiAgICB0aGlzLl9jb250ZXh0ID0gb3B0aW9ucy5jb250ZXh0IHx8IHNjb3BlLmRvY3VtZW50O1xyXG4gICAgdGhpcy5fd2luID0gZ2V0V2luZG93KHRyeVNlbGVjdG9yKHRhcmdldCkgPyB0aGlzLl9jb250ZXh0IDogdGFyZ2V0KTtcclxuICAgIHRoaXMuX2RvYyA9IHRoaXMuX3dpbi5kb2N1bWVudDtcclxuXHJcbiAgICBzaWduYWxzLmZpcmUoJ25ldycsIHtcclxuICAgICAgdGFyZ2V0OiB0YXJnZXQsXHJcbiAgICAgIG9wdGlvbnM6IG9wdGlvbnMsXHJcbiAgICAgIGludGVyYWN0YWJsZTogdGhpcyxcclxuICAgICAgd2luOiB0aGlzLl93aW5cclxuICAgIH0pO1xyXG5cclxuICAgIHNjb3BlLmFkZERvY3VtZW50KHRoaXMuX2RvYywgdGhpcy5fd2luKTtcclxuXHJcbiAgICBzY29wZS5pbnRlcmFjdGFibGVzLnB1c2godGhpcyk7XHJcblxyXG4gICAgdGhpcy5zZXQob3B0aW9ucyk7XHJcbiAgfVxyXG5cclxuICBJbnRlcmFjdGFibGUucHJvdG90eXBlLnNldE9uRXZlbnRzID0gZnVuY3Rpb24gc2V0T25FdmVudHMoYWN0aW9uLCBwaGFzZXMpIHtcclxuICAgIHZhciBvbkFjdGlvbiA9ICdvbicgKyBhY3Rpb247XHJcblxyXG4gICAgaWYgKGlzLmZ1bmN0aW9uKHBoYXNlcy5vbnN0YXJ0KSkge1xyXG4gICAgICB0aGlzLmV2ZW50c1tvbkFjdGlvbiArICdzdGFydCddID0gcGhhc2VzLm9uc3RhcnQ7XHJcbiAgICB9XHJcbiAgICBpZiAoaXMuZnVuY3Rpb24ocGhhc2VzLm9ubW92ZSkpIHtcclxuICAgICAgdGhpcy5ldmVudHNbb25BY3Rpb24gKyAnbW92ZSddID0gcGhhc2VzLm9ubW92ZTtcclxuICAgIH1cclxuICAgIGlmIChpcy5mdW5jdGlvbihwaGFzZXMub25lbmQpKSB7XHJcbiAgICAgIHRoaXMuZXZlbnRzW29uQWN0aW9uICsgJ2VuZCddID0gcGhhc2VzLm9uZW5kO1xyXG4gICAgfVxyXG4gICAgaWYgKGlzLmZ1bmN0aW9uKHBoYXNlcy5vbmluZXJ0aWFzdGFydCkpIHtcclxuICAgICAgdGhpcy5ldmVudHNbb25BY3Rpb24gKyAnaW5lcnRpYXN0YXJ0J10gPSBwaGFzZXMub25pbmVydGlhc3RhcnQ7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfTtcclxuXHJcbiAgSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5zZXRQZXJBY3Rpb24gPSBmdW5jdGlvbiBzZXRQZXJBY3Rpb24oYWN0aW9uLCBvcHRpb25zKSB7XHJcbiAgICAvLyBmb3IgYWxsIHRoZSBkZWZhdWx0IHBlci1hY3Rpb24gb3B0aW9uc1xyXG4gICAgZm9yICh2YXIgb3B0aW9uIGluIG9wdGlvbnMpIHtcclxuICAgICAgLy8gaWYgdGhpcyBvcHRpb24gZXhpc3RzIGZvciB0aGlzIGFjdGlvblxyXG4gICAgICBpZiAob3B0aW9uIGluIGRlZmF1bHRzW2FjdGlvbl0pIHtcclxuICAgICAgICAvLyBpZiB0aGUgb3B0aW9uIGluIHRoZSBvcHRpb25zIGFyZyBpcyBhbiBvYmplY3QgdmFsdWVcclxuICAgICAgICBpZiAoaXMub2JqZWN0KG9wdGlvbnNbb3B0aW9uXSkpIHtcclxuICAgICAgICAgIC8vIGR1cGxpY2F0ZSB0aGUgb2JqZWN0XHJcbiAgICAgICAgICB0aGlzLm9wdGlvbnNbYWN0aW9uXVtvcHRpb25dID0gZXh0ZW5kKHRoaXMub3B0aW9uc1thY3Rpb25dW29wdGlvbl0gfHwge30sIG9wdGlvbnNbb3B0aW9uXSk7XHJcblxyXG4gICAgICAgICAgaWYgKGlzLm9iamVjdChkZWZhdWx0cy5wZXJBY3Rpb25bb3B0aW9uXSkgJiYgJ2VuYWJsZWQnIGluIGRlZmF1bHRzLnBlckFjdGlvbltvcHRpb25dKSB7XHJcbiAgICAgICAgICAgIHRoaXMub3B0aW9uc1thY3Rpb25dW29wdGlvbl0uZW5hYmxlZCA9IG9wdGlvbnNbb3B0aW9uXS5lbmFibGVkID09PSBmYWxzZSA/IGZhbHNlIDogdHJ1ZTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2UgaWYgKGlzLmJvb2wob3B0aW9uc1tvcHRpb25dKSAmJiBpcy5vYmplY3QoZGVmYXVsdHMucGVyQWN0aW9uW29wdGlvbl0pKSB7XHJcbiAgICAgICAgICB0aGlzLm9wdGlvbnNbYWN0aW9uXVtvcHRpb25dLmVuYWJsZWQgPSBvcHRpb25zW29wdGlvbl07XHJcbiAgICAgICAgfSBlbHNlIGlmIChvcHRpb25zW29wdGlvbl0gIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgLy8gb3IgaWYgaXQncyBub3QgdW5kZWZpbmVkLCBkbyBhIHBsYWluIGFzc2lnbm1lbnRcclxuICAgICAgICAgIHRoaXMub3B0aW9uc1thY3Rpb25dW29wdGlvbl0gPSBvcHRpb25zW29wdGlvbl07XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgLypcXFxyXG4gICAqIEludGVyYWN0YWJsZS5nZXRSZWN0XHJcbiAgIFsgbWV0aG9kIF1cclxuICAgKlxyXG4gICAqIFRoZSBkZWZhdWx0IGZ1bmN0aW9uIHRvIGdldCBhbiBJbnRlcmFjdGFibGVzIGJvdW5kaW5nIHJlY3QuIENhbiBiZVxyXG4gICAqIG92ZXJyaWRkZW4gdXNpbmcgQEludGVyYWN0YWJsZS5yZWN0Q2hlY2tlci5cclxuICAgKlxyXG4gICAtIGVsZW1lbnQgKEVsZW1lbnQpICNvcHRpb25hbCBUaGUgZWxlbWVudCB0byBtZWFzdXJlLlxyXG4gICA9IChvYmplY3QpIFRoZSBvYmplY3QncyBib3VuZGluZyByZWN0YW5nbGUuXHJcbiAgIG8ge1xyXG4gICBvICAgICB0b3AgICA6IDAsXHJcbiAgIG8gICAgIGxlZnQgIDogMCxcclxuICAgbyAgICAgYm90dG9tOiAwLFxyXG4gICBvICAgICByaWdodCA6IDAsXHJcbiAgIG8gICAgIHdpZHRoIDogMCxcclxuICAgbyAgICAgaGVpZ2h0OiAwXHJcbiAgIG8gfVxyXG4gIFxcKi9cclxuXHJcblxyXG4gIEludGVyYWN0YWJsZS5wcm90b3R5cGUuZ2V0UmVjdCA9IGZ1bmN0aW9uIGdldFJlY3QoZWxlbWVudCkge1xyXG4gICAgZWxlbWVudCA9IGVsZW1lbnQgfHwgdGhpcy50YXJnZXQ7XHJcblxyXG4gICAgaWYgKGlzLnN0cmluZyh0aGlzLnRhcmdldCkgJiYgIWlzLmVsZW1lbnQoZWxlbWVudCkpIHtcclxuICAgICAgZWxlbWVudCA9IHRoaXMuX2NvbnRleHQucXVlcnlTZWxlY3Rvcih0aGlzLnRhcmdldCk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGdldEVsZW1lbnRSZWN0KGVsZW1lbnQpO1xyXG4gIH07XHJcblxyXG4gIC8qXFxcclxuICAgKiBJbnRlcmFjdGFibGUucmVjdENoZWNrZXJcclxuICAgWyBtZXRob2QgXVxyXG4gICAqXHJcbiAgICogUmV0dXJucyBvciBzZXRzIHRoZSBmdW5jdGlvbiB1c2VkIHRvIGNhbGN1bGF0ZSB0aGUgaW50ZXJhY3RhYmxlJ3NcclxuICAgKiBlbGVtZW50J3MgcmVjdGFuZ2xlXHJcbiAgICpcclxuICAgLSBjaGVja2VyIChmdW5jdGlvbikgI29wdGlvbmFsIEEgZnVuY3Rpb24gd2hpY2ggcmV0dXJucyB0aGlzIEludGVyYWN0YWJsZSdzIGJvdW5kaW5nIHJlY3RhbmdsZS4gU2VlIEBJbnRlcmFjdGFibGUuZ2V0UmVjdFxyXG4gICA9IChmdW5jdGlvbiB8IG9iamVjdCkgVGhlIGNoZWNrZXIgZnVuY3Rpb24gb3IgdGhpcyBJbnRlcmFjdGFibGVcclxuICBcXCovXHJcblxyXG5cclxuICBJbnRlcmFjdGFibGUucHJvdG90eXBlLnJlY3RDaGVja2VyID0gZnVuY3Rpb24gcmVjdENoZWNrZXIoY2hlY2tlcikge1xyXG4gICAgaWYgKGlzLmZ1bmN0aW9uKGNoZWNrZXIpKSB7XHJcbiAgICAgIHRoaXMuZ2V0UmVjdCA9IGNoZWNrZXI7XHJcblxyXG4gICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuXHJcbiAgICBpZiAoY2hlY2tlciA9PT0gbnVsbCkge1xyXG4gICAgICBkZWxldGUgdGhpcy5vcHRpb25zLmdldFJlY3Q7XHJcblxyXG4gICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdGhpcy5nZXRSZWN0O1xyXG4gIH07XHJcblxyXG4gIEludGVyYWN0YWJsZS5wcm90b3R5cGUuX2JhY2tDb21wYXRPcHRpb24gPSBmdW5jdGlvbiBfYmFja0NvbXBhdE9wdGlvbihvcHRpb25OYW1lLCBuZXdWYWx1ZSkge1xyXG4gICAgaWYgKHRyeVNlbGVjdG9yKG5ld1ZhbHVlKSB8fCBpcy5vYmplY3QobmV3VmFsdWUpKSB7XHJcbiAgICAgIHRoaXMub3B0aW9uc1tvcHRpb25OYW1lXSA9IG5ld1ZhbHVlO1xyXG5cclxuICAgICAgZm9yICh2YXIgX2l0ZXJhdG9yID0gYWN0aW9ucy5uYW1lcywgX2lzQXJyYXkgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvciksIF9pID0gMCwgX2l0ZXJhdG9yID0gX2lzQXJyYXkgPyBfaXRlcmF0b3IgOiBfaXRlcmF0b3JbU3ltYm9sLml0ZXJhdG9yXSgpOzspIHtcclxuICAgICAgICB2YXIgX3JlZjtcclxuXHJcbiAgICAgICAgaWYgKF9pc0FycmF5KSB7XHJcbiAgICAgICAgICBpZiAoX2kgPj0gX2l0ZXJhdG9yLmxlbmd0aCkgYnJlYWs7XHJcbiAgICAgICAgICBfcmVmID0gX2l0ZXJhdG9yW19pKytdO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBfaSA9IF9pdGVyYXRvci5uZXh0KCk7XHJcbiAgICAgICAgICBpZiAoX2kuZG9uZSkgYnJlYWs7XHJcbiAgICAgICAgICBfcmVmID0gX2kudmFsdWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB2YXIgYWN0aW9uID0gX3JlZjtcclxuXHJcbiAgICAgICAgdGhpcy5vcHRpb25zW2FjdGlvbl1bb3B0aW9uTmFtZV0gPSBuZXdWYWx1ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRoaXMub3B0aW9uc1tvcHRpb25OYW1lXTtcclxuICB9O1xyXG5cclxuICAvKlxcXHJcbiAgICogSW50ZXJhY3RhYmxlLm9yaWdpblxyXG4gICBbIG1ldGhvZCBdXHJcbiAgICpcclxuICAgKiBHZXRzIG9yIHNldHMgdGhlIG9yaWdpbiBvZiB0aGUgSW50ZXJhY3RhYmxlJ3MgZWxlbWVudC4gIFRoZSB4IGFuZCB5XHJcbiAgICogb2YgdGhlIG9yaWdpbiB3aWxsIGJlIHN1YnRyYWN0ZWQgZnJvbSBhY3Rpb24gZXZlbnQgY29vcmRpbmF0ZXMuXHJcbiAgICpcclxuICAgLSBvcmlnaW4gKG9iamVjdCB8IHN0cmluZykgI29wdGlvbmFsIEFuIG9iamVjdCBlZy4geyB4OiAwLCB5OiAwIH0gb3Igc3RyaW5nICdwYXJlbnQnLCAnc2VsZicgb3IgYW55IENTUyBzZWxlY3RvclxyXG4gICAqIE9SXHJcbiAgIC0gb3JpZ2luIChFbGVtZW50KSAjb3B0aW9uYWwgQW4gSFRNTCBvciBTVkcgRWxlbWVudCB3aG9zZSByZWN0IHdpbGwgYmUgdXNlZFxyXG4gICAqKlxyXG4gICA9IChvYmplY3QpIFRoZSBjdXJyZW50IG9yaWdpbiBvciB0aGlzIEludGVyYWN0YWJsZVxyXG4gIFxcKi9cclxuXHJcblxyXG4gIEludGVyYWN0YWJsZS5wcm90b3R5cGUub3JpZ2luID0gZnVuY3Rpb24gb3JpZ2luKG5ld1ZhbHVlKSB7XHJcbiAgICByZXR1cm4gdGhpcy5fYmFja0NvbXBhdE9wdGlvbignb3JpZ2luJywgbmV3VmFsdWUpO1xyXG4gIH07XHJcblxyXG4gIC8qXFxcclxuICAgKiBJbnRlcmFjdGFibGUuZGVsdGFTb3VyY2VcclxuICAgWyBtZXRob2QgXVxyXG4gICAqXHJcbiAgICogUmV0dXJucyBvciBzZXRzIHRoZSBtb3VzZSBjb29yZGluYXRlIHR5cGVzIHVzZWQgdG8gY2FsY3VsYXRlIHRoZVxyXG4gICAqIG1vdmVtZW50IG9mIHRoZSBwb2ludGVyLlxyXG4gICAqXHJcbiAgIC0gbmV3VmFsdWUgKHN0cmluZykgI29wdGlvbmFsIFVzZSAnY2xpZW50JyBpZiB5b3Ugd2lsbCBiZSBzY3JvbGxpbmcgd2hpbGUgaW50ZXJhY3Rpbmc7IFVzZSAncGFnZScgaWYgeW91IHdhbnQgYXV0b1Njcm9sbCB0byB3b3JrXHJcbiAgID0gKHN0cmluZyB8IG9iamVjdCkgVGhlIGN1cnJlbnQgZGVsdGFTb3VyY2Ugb3IgdGhpcyBJbnRlcmFjdGFibGVcclxuICBcXCovXHJcblxyXG5cclxuICBJbnRlcmFjdGFibGUucHJvdG90eXBlLmRlbHRhU291cmNlID0gZnVuY3Rpb24gZGVsdGFTb3VyY2UobmV3VmFsdWUpIHtcclxuICAgIGlmIChuZXdWYWx1ZSA9PT0gJ3BhZ2UnIHx8IG5ld1ZhbHVlID09PSAnY2xpZW50Jykge1xyXG4gICAgICB0aGlzLm9wdGlvbnMuZGVsdGFTb3VyY2UgPSBuZXdWYWx1ZTtcclxuXHJcbiAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0aGlzLm9wdGlvbnMuZGVsdGFTb3VyY2U7XHJcbiAgfTtcclxuXHJcbiAgLypcXFxyXG4gICAqIEludGVyYWN0YWJsZS5jb250ZXh0XHJcbiAgIFsgbWV0aG9kIF1cclxuICAgKlxyXG4gICAqIEdldHMgdGhlIHNlbGVjdG9yIGNvbnRleHQgTm9kZSBvZiB0aGUgSW50ZXJhY3RhYmxlLiBUaGUgZGVmYXVsdCBpcyBgd2luZG93LmRvY3VtZW50YC5cclxuICAgKlxyXG4gICA9IChOb2RlKSBUaGUgY29udGV4dCBOb2RlIG9mIHRoaXMgSW50ZXJhY3RhYmxlXHJcbiAgICoqXHJcbiAgXFwqL1xyXG5cclxuXHJcbiAgSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5jb250ZXh0ID0gZnVuY3Rpb24gY29udGV4dCgpIHtcclxuICAgIHJldHVybiB0aGlzLl9jb250ZXh0O1xyXG4gIH07XHJcblxyXG4gIEludGVyYWN0YWJsZS5wcm90b3R5cGUuaW5Db250ZXh0ID0gZnVuY3Rpb24gaW5Db250ZXh0KGVsZW1lbnQpIHtcclxuICAgIHJldHVybiB0aGlzLl9jb250ZXh0ID09PSBlbGVtZW50Lm93bmVyRG9jdW1lbnQgfHwgbm9kZUNvbnRhaW5zKHRoaXMuX2NvbnRleHQsIGVsZW1lbnQpO1xyXG4gIH07XHJcblxyXG4gIC8qXFxcclxuICAgKiBJbnRlcmFjdGFibGUuZmlyZVxyXG4gICBbIG1ldGhvZCBdXHJcbiAgICpcclxuICAgKiBDYWxscyBsaXN0ZW5lcnMgZm9yIHRoZSBnaXZlbiBJbnRlcmFjdEV2ZW50IHR5cGUgYm91bmQgZ2xvYmFsbHlcclxuICAgKiBhbmQgZGlyZWN0bHkgdG8gdGhpcyBJbnRlcmFjdGFibGVcclxuICAgKlxyXG4gICAtIGlFdmVudCAoSW50ZXJhY3RFdmVudCkgVGhlIEludGVyYWN0RXZlbnQgb2JqZWN0IHRvIGJlIGZpcmVkIG9uIHRoaXMgSW50ZXJhY3RhYmxlXHJcbiAgID0gKEludGVyYWN0YWJsZSkgdGhpcyBJbnRlcmFjdGFibGVcclxuICBcXCovXHJcblxyXG5cclxuICBJbnRlcmFjdGFibGUucHJvdG90eXBlLmZpcmUgPSBmdW5jdGlvbiBmaXJlKGlFdmVudCkge1xyXG4gICAgdGhpcy5ldmVudHMuZmlyZShpRXZlbnQpO1xyXG5cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH07XHJcblxyXG4gIEludGVyYWN0YWJsZS5wcm90b3R5cGUuX29uT2ZmTXVsdGlwbGUgPSBmdW5jdGlvbiBfb25PZmZNdWx0aXBsZShtZXRob2QsIGV2ZW50VHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpIHtcclxuICAgIGlmIChpcy5zdHJpbmcoZXZlbnRUeXBlKSAmJiBldmVudFR5cGUuc2VhcmNoKCcgJykgIT09IC0xKSB7XHJcbiAgICAgIGV2ZW50VHlwZSA9IGV2ZW50VHlwZS50cmltKCkuc3BsaXQoLyArLyk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGlzLmFycmF5KGV2ZW50VHlwZSkpIHtcclxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBldmVudFR5cGUubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICB0aGlzW21ldGhvZF0oZXZlbnRUeXBlW2ldLCBsaXN0ZW5lciwgb3B0aW9ucyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChpcy5vYmplY3QoZXZlbnRUeXBlKSkge1xyXG4gICAgICBmb3IgKHZhciBwcm9wIGluIGV2ZW50VHlwZSkge1xyXG4gICAgICAgIHRoaXNbbWV0aG9kXShwcm9wLCBldmVudFR5cGVbcHJvcF0sIGxpc3RlbmVyKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgLypcXFxyXG4gICAqIEludGVyYWN0YWJsZS5vblxyXG4gICBbIG1ldGhvZCBdXHJcbiAgICpcclxuICAgKiBCaW5kcyBhIGxpc3RlbmVyIGZvciBhbiBJbnRlcmFjdEV2ZW50LCBwb2ludGVyRXZlbnQgb3IgRE9NIGV2ZW50LlxyXG4gICAqXHJcbiAgIC0gZXZlbnRUeXBlICAoc3RyaW5nIHwgYXJyYXkgfCBvYmplY3QpIFRoZSB0eXBlcyBvZiBldmVudHMgdG8gbGlzdGVuIGZvclxyXG4gICAtIGxpc3RlbmVyICAgKGZ1bmN0aW9uKSBUaGUgZnVuY3Rpb24gZXZlbnQgKHMpXHJcbiAgIC0gb3B0aW9ucyAgICAob2JqZWN0IHwgYm9vbGVhbikgI29wdGlvbmFsIG9wdGlvbnMgb2JqZWN0IG9yIHVzZUNhcHR1cmUgZmxhZyBmb3IgYWRkRXZlbnRMaXN0ZW5lclxyXG4gICA9IChvYmplY3QpIFRoaXMgSW50ZXJhY3RhYmxlXHJcbiAgXFwqL1xyXG5cclxuXHJcbiAgSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIG9uKGV2ZW50VHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpIHtcclxuICAgIGlmICh0aGlzLl9vbk9mZk11bHRpcGxlKCdvbicsIGV2ZW50VHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpKSB7XHJcbiAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChldmVudFR5cGUgPT09ICd3aGVlbCcpIHtcclxuICAgICAgZXZlbnRUeXBlID0gd2hlZWxFdmVudDtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoY29udGFpbnMoSW50ZXJhY3RhYmxlLmV2ZW50VHlwZXMsIGV2ZW50VHlwZSkpIHtcclxuICAgICAgdGhpcy5ldmVudHMub24oZXZlbnRUeXBlLCBsaXN0ZW5lcik7XHJcbiAgICB9XHJcbiAgICAvLyBkZWxlZ2F0ZWQgZXZlbnQgZm9yIHNlbGVjdG9yXHJcbiAgICBlbHNlIGlmIChpcy5zdHJpbmcodGhpcy50YXJnZXQpKSB7XHJcbiAgICAgICAgZXZlbnRzLmFkZERlbGVnYXRlKHRoaXMudGFyZ2V0LCB0aGlzLl9jb250ZXh0LCBldmVudFR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBldmVudHMuYWRkKHRoaXMudGFyZ2V0LCBldmVudFR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKTtcclxuICAgICAgfVxyXG5cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH07XHJcblxyXG4gIC8qXFxcclxuICAgKiBJbnRlcmFjdGFibGUub2ZmXHJcbiAgIFsgbWV0aG9kIF1cclxuICAgKlxyXG4gICAqIFJlbW92ZXMgYW4gSW50ZXJhY3RFdmVudCwgcG9pbnRlckV2ZW50IG9yIERPTSBldmVudCBsaXN0ZW5lclxyXG4gICAqXHJcbiAgIC0gZXZlbnRUeXBlICAoc3RyaW5nIHwgYXJyYXkgfCBvYmplY3QpIFRoZSB0eXBlcyBvZiBldmVudHMgdGhhdCB3ZXJlIGxpc3RlbmVkIGZvclxyXG4gICAtIGxpc3RlbmVyICAgKGZ1bmN0aW9uKSBUaGUgbGlzdGVuZXIgZnVuY3Rpb24gdG8gYmUgcmVtb3ZlZFxyXG4gICAtIG9wdGlvbnMgICAgKG9iamVjdCB8IGJvb2xlYW4pICNvcHRpb25hbCBvcHRpb25zIG9iamVjdCBvciB1c2VDYXB0dXJlIGZsYWcgZm9yIHJlbW92ZUV2ZW50TGlzdGVuZXJcclxuICAgPSAob2JqZWN0KSBUaGlzIEludGVyYWN0YWJsZVxyXG4gIFxcKi9cclxuXHJcblxyXG4gIEludGVyYWN0YWJsZS5wcm90b3R5cGUub2ZmID0gZnVuY3Rpb24gb2ZmKGV2ZW50VHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpIHtcclxuICAgIGlmICh0aGlzLl9vbk9mZk11bHRpcGxlKCdvZmYnLCBldmVudFR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKSkge1xyXG4gICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuXHJcbiAgICBpZiAoZXZlbnRUeXBlID09PSAnd2hlZWwnKSB7XHJcbiAgICAgIGV2ZW50VHlwZSA9IHdoZWVsRXZlbnQ7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gaWYgaXQgaXMgYW4gYWN0aW9uIGV2ZW50IHR5cGVcclxuICAgIGlmIChjb250YWlucyhJbnRlcmFjdGFibGUuZXZlbnRUeXBlcywgZXZlbnRUeXBlKSkge1xyXG4gICAgICB0aGlzLmV2ZW50cy5vZmYoZXZlbnRUeXBlLCBsaXN0ZW5lcik7XHJcbiAgICB9XHJcbiAgICAvLyBkZWxlZ2F0ZWQgZXZlbnRcclxuICAgIGVsc2UgaWYgKGlzLnN0cmluZyh0aGlzLnRhcmdldCkpIHtcclxuICAgICAgICBldmVudHMucmVtb3ZlRGVsZWdhdGUodGhpcy50YXJnZXQsIHRoaXMuX2NvbnRleHQsIGV2ZW50VHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpO1xyXG4gICAgICB9XHJcbiAgICAgIC8vIHJlbW92ZSBsaXN0ZW5lciBmcm9tIHRoaXMgSW50ZXJhdGFibGUncyBlbGVtZW50XHJcbiAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgZXZlbnRzLnJlbW92ZSh0aGlzLnRhcmdldCwgZXZlbnRUeXBlLCBsaXN0ZW5lciwgb3B0aW9ucyk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH07XHJcblxyXG4gIC8qXFxcclxuICAgKiBJbnRlcmFjdGFibGUuc2V0XHJcbiAgIFsgbWV0aG9kIF1cclxuICAgKlxyXG4gICAqIFJlc2V0IHRoZSBvcHRpb25zIG9mIHRoaXMgSW50ZXJhY3RhYmxlXHJcbiAgIC0gb3B0aW9ucyAob2JqZWN0KSBUaGUgbmV3IHNldHRpbmdzIHRvIGFwcGx5XHJcbiAgID0gKG9iamVjdCkgVGhpcyBJbnRlcmFjdGFibGVcclxuICBcXCovXHJcblxyXG5cclxuICBJbnRlcmFjdGFibGUucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uIHNldChvcHRpb25zKSB7XHJcbiAgICBpZiAoIWlzLm9iamVjdChvcHRpb25zKSkge1xyXG4gICAgICBvcHRpb25zID0ge307XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5vcHRpb25zID0gZXh0ZW5kKHt9LCBkZWZhdWx0cy5iYXNlKTtcclxuXHJcbiAgICB2YXIgcGVyQWN0aW9ucyA9IGV4dGVuZCh7fSwgZGVmYXVsdHMucGVyQWN0aW9uKTtcclxuXHJcbiAgICBmb3IgKHZhciBhY3Rpb25OYW1lIGluIGFjdGlvbnMubWV0aG9kRGljdCkge1xyXG4gICAgICB2YXIgbWV0aG9kTmFtZSA9IGFjdGlvbnMubWV0aG9kRGljdFthY3Rpb25OYW1lXTtcclxuXHJcbiAgICAgIHRoaXMub3B0aW9uc1thY3Rpb25OYW1lXSA9IGV4dGVuZCh7fSwgZGVmYXVsdHNbYWN0aW9uTmFtZV0pO1xyXG5cclxuICAgICAgdGhpcy5zZXRQZXJBY3Rpb24oYWN0aW9uTmFtZSwgcGVyQWN0aW9ucyk7XHJcblxyXG4gICAgICB0aGlzW21ldGhvZE5hbWVdKG9wdGlvbnNbYWN0aW9uTmFtZV0pO1xyXG4gICAgfVxyXG5cclxuICAgIGZvciAodmFyIF9pdGVyYXRvcjIgPSBJbnRlcmFjdGFibGUuc2V0dGluZ3NNZXRob2RzLCBfaXNBcnJheTIgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvcjIpLCBfaTIgPSAwLCBfaXRlcmF0b3IyID0gX2lzQXJyYXkyID8gX2l0ZXJhdG9yMiA6IF9pdGVyYXRvcjJbU3ltYm9sLml0ZXJhdG9yXSgpOzspIHtcclxuICAgICAgdmFyIF9yZWYyO1xyXG5cclxuICAgICAgaWYgKF9pc0FycmF5Mikge1xyXG4gICAgICAgIGlmIChfaTIgPj0gX2l0ZXJhdG9yMi5sZW5ndGgpIGJyZWFrO1xyXG4gICAgICAgIF9yZWYyID0gX2l0ZXJhdG9yMltfaTIrK107XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgX2kyID0gX2l0ZXJhdG9yMi5uZXh0KCk7XHJcbiAgICAgICAgaWYgKF9pMi5kb25lKSBicmVhaztcclxuICAgICAgICBfcmVmMiA9IF9pMi52YWx1ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIHNldHRpbmcgPSBfcmVmMjtcclxuXHJcbiAgICAgIHRoaXMub3B0aW9uc1tzZXR0aW5nXSA9IGRlZmF1bHRzLmJhc2Vbc2V0dGluZ107XHJcblxyXG4gICAgICBpZiAoc2V0dGluZyBpbiBvcHRpb25zKSB7XHJcbiAgICAgICAgdGhpc1tzZXR0aW5nXShvcHRpb25zW3NldHRpbmddKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHNpZ25hbHMuZmlyZSgnc2V0Jywge1xyXG4gICAgICBvcHRpb25zOiBvcHRpb25zLFxyXG4gICAgICBpbnRlcmFjdGFibGU6IHRoaXNcclxuICAgIH0pO1xyXG5cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH07XHJcblxyXG4gIC8qXFxcclxuICAgKiBJbnRlcmFjdGFibGUudW5zZXRcclxuICAgWyBtZXRob2QgXVxyXG4gICAqXHJcbiAgICogUmVtb3ZlIHRoaXMgaW50ZXJhY3RhYmxlIGZyb20gdGhlIGxpc3Qgb2YgaW50ZXJhY3RhYmxlcyBhbmQgcmVtb3ZlXHJcbiAgICogaXQncyBhY3Rpb24gY2FwYWJpbGl0aWVzIGFuZCBldmVudCBsaXN0ZW5lcnNcclxuICAgKlxyXG4gICA9IChvYmplY3QpIEBpbnRlcmFjdFxyXG4gIFxcKi9cclxuXHJcblxyXG4gIEludGVyYWN0YWJsZS5wcm90b3R5cGUudW5zZXQgPSBmdW5jdGlvbiB1bnNldCgpIHtcclxuICAgIGV2ZW50cy5yZW1vdmUodGhpcy50YXJnZXQsICdhbGwnKTtcclxuXHJcbiAgICBpZiAoaXMuc3RyaW5nKHRoaXMudGFyZ2V0KSkge1xyXG4gICAgICAvLyByZW1vdmUgZGVsZWdhdGVkIGV2ZW50c1xyXG4gICAgICBmb3IgKHZhciB0eXBlIGluIGV2ZW50cy5kZWxlZ2F0ZWRFdmVudHMpIHtcclxuICAgICAgICB2YXIgZGVsZWdhdGVkID0gZXZlbnRzLmRlbGVnYXRlZEV2ZW50c1t0eXBlXTtcclxuXHJcbiAgICAgICAgaWYgKGRlbGVnYXRlZC5zZWxlY3RvcnNbMF0gPT09IHRoaXMudGFyZ2V0ICYmIGRlbGVnYXRlZC5jb250ZXh0c1swXSA9PT0gdGhpcy5fY29udGV4dCkge1xyXG5cclxuICAgICAgICAgIGRlbGVnYXRlZC5zZWxlY3RvcnMuc3BsaWNlKDAsIDEpO1xyXG4gICAgICAgICAgZGVsZWdhdGVkLmNvbnRleHRzLnNwbGljZSgwLCAxKTtcclxuICAgICAgICAgIGRlbGVnYXRlZC5saXN0ZW5lcnMuc3BsaWNlKDAsIDEpO1xyXG5cclxuICAgICAgICAgIC8vIHJlbW92ZSB0aGUgYXJyYXlzIGlmIHRoZXkgYXJlIGVtcHR5XHJcbiAgICAgICAgICBpZiAoIWRlbGVnYXRlZC5zZWxlY3RvcnMubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIGRlbGVnYXRlZFt0eXBlXSA9IG51bGw7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBldmVudHMucmVtb3ZlKHRoaXMuX2NvbnRleHQsIHR5cGUsIGV2ZW50cy5kZWxlZ2F0ZUxpc3RlbmVyKTtcclxuICAgICAgICBldmVudHMucmVtb3ZlKHRoaXMuX2NvbnRleHQsIHR5cGUsIGV2ZW50cy5kZWxlZ2F0ZVVzZUNhcHR1cmUsIHRydWUpO1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBldmVudHMucmVtb3ZlKHRoaXMsICdhbGwnKTtcclxuICAgIH1cclxuXHJcbiAgICBzaWduYWxzLmZpcmUoJ3Vuc2V0JywgeyBpbnRlcmFjdGFibGU6IHRoaXMgfSk7XHJcblxyXG4gICAgc2NvcGUuaW50ZXJhY3RhYmxlcy5zcGxpY2UoaW5kZXhPZihzY29wZS5pbnRlcmFjdGFibGVzLCB0aGlzKSwgMSk7XHJcblxyXG4gICAgLy8gU3RvcCByZWxhdGVkIGludGVyYWN0aW9ucyB3aGVuIGFuIEludGVyYWN0YWJsZSBpcyB1bnNldFxyXG4gICAgZm9yICh2YXIgX2l0ZXJhdG9yMyA9IHNjb3BlLmludGVyYWN0aW9ucyB8fCBbXSwgX2lzQXJyYXkzID0gQXJyYXkuaXNBcnJheShfaXRlcmF0b3IzKSwgX2kzID0gMCwgX2l0ZXJhdG9yMyA9IF9pc0FycmF5MyA/IF9pdGVyYXRvcjMgOiBfaXRlcmF0b3IzW1N5bWJvbC5pdGVyYXRvcl0oKTs7KSB7XHJcbiAgICAgIHZhciBfcmVmMztcclxuXHJcbiAgICAgIGlmIChfaXNBcnJheTMpIHtcclxuICAgICAgICBpZiAoX2kzID49IF9pdGVyYXRvcjMubGVuZ3RoKSBicmVhaztcclxuICAgICAgICBfcmVmMyA9IF9pdGVyYXRvcjNbX2kzKytdO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIF9pMyA9IF9pdGVyYXRvcjMubmV4dCgpO1xyXG4gICAgICAgIGlmIChfaTMuZG9uZSkgYnJlYWs7XHJcbiAgICAgICAgX3JlZjMgPSBfaTMudmFsdWU7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYzO1xyXG5cclxuICAgICAgaWYgKGludGVyYWN0aW9uLnRhcmdldCA9PT0gdGhpcyAmJiBpbnRlcmFjdGlvbi5pbnRlcmFjdGluZygpKSB7XHJcbiAgICAgICAgaW50ZXJhY3Rpb24uc3RvcCgpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHNjb3BlLmludGVyYWN0O1xyXG4gIH07XHJcblxyXG4gIHJldHVybiBJbnRlcmFjdGFibGU7XHJcbn0oKTtcclxuXHJcbnNjb3BlLmludGVyYWN0YWJsZXMuaW5kZXhPZkVsZW1lbnQgPSBmdW5jdGlvbiBpbmRleE9mRWxlbWVudCh0YXJnZXQsIGNvbnRleHQpIHtcclxuICBjb250ZXh0ID0gY29udGV4dCB8fCBzY29wZS5kb2N1bWVudDtcclxuXHJcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICB2YXIgaW50ZXJhY3RhYmxlID0gdGhpc1tpXTtcclxuXHJcbiAgICBpZiAoaW50ZXJhY3RhYmxlLnRhcmdldCA9PT0gdGFyZ2V0ICYmIGludGVyYWN0YWJsZS5fY29udGV4dCA9PT0gY29udGV4dCkge1xyXG4gICAgICByZXR1cm4gaTtcclxuICAgIH1cclxuICB9XHJcbiAgcmV0dXJuIC0xO1xyXG59O1xyXG5cclxuc2NvcGUuaW50ZXJhY3RhYmxlcy5nZXQgPSBmdW5jdGlvbiBpbnRlcmFjdGFibGVHZXQoZWxlbWVudCwgb3B0aW9ucywgZG9udENoZWNrSW5Db250ZXh0KSB7XHJcbiAgdmFyIHJldCA9IHRoaXNbdGhpcy5pbmRleE9mRWxlbWVudChlbGVtZW50LCBvcHRpb25zICYmIG9wdGlvbnMuY29udGV4dCldO1xyXG5cclxuICByZXR1cm4gcmV0ICYmIChpcy5zdHJpbmcoZWxlbWVudCkgfHwgZG9udENoZWNrSW5Db250ZXh0IHx8IHJldC5pbkNvbnRleHQoZWxlbWVudCkpID8gcmV0IDogbnVsbDtcclxufTtcclxuXHJcbnNjb3BlLmludGVyYWN0YWJsZXMuZm9yRWFjaFNlbGVjdG9yID0gZnVuY3Rpb24gKGNhbGxiYWNrLCBlbGVtZW50KSB7XHJcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICB2YXIgaW50ZXJhY3RhYmxlID0gdGhpc1tpXTtcclxuXHJcbiAgICAvLyBza2lwIG5vbiBDU1Mgc2VsZWN0b3IgdGFyZ2V0cyBhbmQgb3V0IG9mIGNvbnRleHQgZWxlbWVudHNcclxuICAgIGlmICghaXMuc3RyaW5nKGludGVyYWN0YWJsZS50YXJnZXQpIHx8IGVsZW1lbnQgJiYgIWludGVyYWN0YWJsZS5pbkNvbnRleHQoZWxlbWVudCkpIHtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIHJldCA9IGNhbGxiYWNrKGludGVyYWN0YWJsZSwgaW50ZXJhY3RhYmxlLnRhcmdldCwgaW50ZXJhY3RhYmxlLl9jb250ZXh0LCBpLCB0aGlzKTtcclxuXHJcbiAgICBpZiAocmV0ICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgcmV0dXJuIHJldDtcclxuICAgIH1cclxuICB9XHJcbn07XHJcblxyXG4vLyBhbGwgaW50ZXJhY3QuanMgZXZlbnRUeXBlc1xyXG5JbnRlcmFjdGFibGUuZXZlbnRUeXBlcyA9IHNjb3BlLmV2ZW50VHlwZXMgPSBbXTtcclxuXHJcbkludGVyYWN0YWJsZS5zaWduYWxzID0gc2lnbmFscztcclxuXHJcbkludGVyYWN0YWJsZS5zZXR0aW5nc01ldGhvZHMgPSBbJ2RlbHRhU291cmNlJywgJ29yaWdpbicsICdwcmV2ZW50RGVmYXVsdCcsICdyZWN0Q2hlY2tlciddO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBJbnRlcmFjdGFibGU7XHJcblxyXG59LHtcIi4vRXZlbnRhYmxlXCI6MixcIi4vYWN0aW9ucy9iYXNlXCI6NixcIi4vZGVmYXVsdE9wdGlvbnNcIjoxOCxcIi4vc2NvcGVcIjozNCxcIi4vdXRpbHMvU2lnbmFsc1wiOjM1LFwiLi91dGlscy9hcnJcIjozNixcIi4vdXRpbHMvYnJvd3NlclwiOjM3LFwiLi91dGlscy9kb21VdGlsc1wiOjM5LFwiLi91dGlscy9ldmVudHNcIjo0MCxcIi4vdXRpbHMvZXh0ZW5kXCI6NDEsXCIuL3V0aWxzL2lzXCI6NDYsXCIuL3V0aWxzL3dpbmRvd1wiOjUyfV0sNTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XHJcblxyXG52YXIgc2NvcGUgPSByZXF1aXJlKCcuL3Njb3BlJyk7XHJcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcclxudmFyIGV2ZW50cyA9IHJlcXVpcmUoJy4vdXRpbHMvZXZlbnRzJyk7XHJcbnZhciBicm93c2VyID0gcmVxdWlyZSgnLi91dGlscy9icm93c2VyJyk7XHJcbnZhciBkb21PYmplY3RzID0gcmVxdWlyZSgnLi91dGlscy9kb21PYmplY3RzJyk7XHJcbnZhciBmaW5kZXIgPSByZXF1aXJlKCcuL3V0aWxzL2ludGVyYWN0aW9uRmluZGVyJyk7XHJcbnZhciBzaWduYWxzID0gcmVxdWlyZSgnLi91dGlscy9TaWduYWxzJykubmV3KCk7XHJcblxyXG52YXIgbGlzdGVuZXJzID0ge307XHJcbnZhciBtZXRob2ROYW1lcyA9IFsncG9pbnRlckRvd24nLCAncG9pbnRlck1vdmUnLCAncG9pbnRlclVwJywgJ3VwZGF0ZVBvaW50ZXInLCAncmVtb3ZlUG9pbnRlciddO1xyXG5cclxuLy8gZm9yIGlnbm9yaW5nIGJyb3dzZXIncyBzaW11bGF0ZWQgbW91c2UgZXZlbnRzXHJcbnZhciBwcmV2VG91Y2hUaW1lID0gMDtcclxuXHJcbi8vIGFsbCBhY3RpdmUgYW5kIGlkbGUgaW50ZXJhY3Rpb25zXHJcbnNjb3BlLmludGVyYWN0aW9ucyA9IFtdO1xyXG5cclxudmFyIEludGVyYWN0aW9uID0gZnVuY3Rpb24gKCkge1xyXG4gIGZ1bmN0aW9uIEludGVyYWN0aW9uKF9yZWYpIHtcclxuICAgIHZhciBwb2ludGVyVHlwZSA9IF9yZWYucG9pbnRlclR5cGU7XHJcblxyXG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEludGVyYWN0aW9uKTtcclxuXHJcbiAgICB0aGlzLnRhcmdldCA9IG51bGw7IC8vIGN1cnJlbnQgaW50ZXJhY3RhYmxlIGJlaW5nIGludGVyYWN0ZWQgd2l0aFxyXG4gICAgdGhpcy5lbGVtZW50ID0gbnVsbDsgLy8gdGhlIHRhcmdldCBlbGVtZW50IG9mIHRoZSBpbnRlcmFjdGFibGVcclxuXHJcbiAgICB0aGlzLnByZXBhcmVkID0geyAvLyBhY3Rpb24gdGhhdCdzIHJlYWR5IHRvIGJlIGZpcmVkIG9uIG5leHQgbW92ZSBldmVudFxyXG4gICAgICBuYW1lOiBudWxsLFxyXG4gICAgICBheGlzOiBudWxsLFxyXG4gICAgICBlZGdlczogbnVsbFxyXG4gICAgfTtcclxuXHJcbiAgICAvLyBrZWVwIHRyYWNrIG9mIGFkZGVkIHBvaW50ZXJzXHJcbiAgICB0aGlzLnBvaW50ZXJzID0gW107XHJcbiAgICB0aGlzLnBvaW50ZXJJZHMgPSBbXTtcclxuICAgIHRoaXMuZG93blRhcmdldHMgPSBbXTtcclxuICAgIHRoaXMuZG93blRpbWVzID0gW107XHJcblxyXG4gICAgLy8gUHJldmlvdXMgbmF0aXZlIHBvaW50ZXIgbW92ZSBldmVudCBjb29yZGluYXRlc1xyXG4gICAgdGhpcy5wcmV2Q29vcmRzID0ge1xyXG4gICAgICBwYWdlOiB7IHg6IDAsIHk6IDAgfSxcclxuICAgICAgY2xpZW50OiB7IHg6IDAsIHk6IDAgfSxcclxuICAgICAgdGltZVN0YW1wOiAwXHJcbiAgICB9O1xyXG4gICAgLy8gY3VycmVudCBuYXRpdmUgcG9pbnRlciBtb3ZlIGV2ZW50IGNvb3JkaW5hdGVzXHJcbiAgICB0aGlzLmN1ckNvb3JkcyA9IHtcclxuICAgICAgcGFnZTogeyB4OiAwLCB5OiAwIH0sXHJcbiAgICAgIGNsaWVudDogeyB4OiAwLCB5OiAwIH0sXHJcbiAgICAgIHRpbWVTdGFtcDogMFxyXG4gICAgfTtcclxuXHJcbiAgICAvLyBTdGFydGluZyBJbnRlcmFjdEV2ZW50IHBvaW50ZXIgY29vcmRpbmF0ZXNcclxuICAgIHRoaXMuc3RhcnRDb29yZHMgPSB7XHJcbiAgICAgIHBhZ2U6IHsgeDogMCwgeTogMCB9LFxyXG4gICAgICBjbGllbnQ6IHsgeDogMCwgeTogMCB9LFxyXG4gICAgICB0aW1lU3RhbXA6IDBcclxuICAgIH07XHJcblxyXG4gICAgLy8gQ2hhbmdlIGluIGNvb3JkaW5hdGVzIGFuZCB0aW1lIG9mIHRoZSBwb2ludGVyXHJcbiAgICB0aGlzLnBvaW50ZXJEZWx0YSA9IHtcclxuICAgICAgcGFnZTogeyB4OiAwLCB5OiAwLCB2eDogMCwgdnk6IDAsIHNwZWVkOiAwIH0sXHJcbiAgICAgIGNsaWVudDogeyB4OiAwLCB5OiAwLCB2eDogMCwgdnk6IDAsIHNwZWVkOiAwIH0sXHJcbiAgICAgIHRpbWVTdGFtcDogMFxyXG4gICAgfTtcclxuXHJcbiAgICB0aGlzLmRvd25FdmVudCA9IG51bGw7IC8vIHBvaW50ZXJkb3duL21vdXNlZG93bi90b3VjaHN0YXJ0IGV2ZW50XHJcbiAgICB0aGlzLmRvd25Qb2ludGVyID0ge307XHJcblxyXG4gICAgdGhpcy5fZXZlbnRUYXJnZXQgPSBudWxsO1xyXG4gICAgdGhpcy5fY3VyRXZlbnRUYXJnZXQgPSBudWxsO1xyXG5cclxuICAgIHRoaXMucHJldkV2ZW50ID0gbnVsbDsgLy8gcHJldmlvdXMgYWN0aW9uIGV2ZW50XHJcblxyXG4gICAgdGhpcy5wb2ludGVySXNEb3duID0gZmFsc2U7XHJcbiAgICB0aGlzLnBvaW50ZXJXYXNNb3ZlZCA9IGZhbHNlO1xyXG4gICAgdGhpcy5faW50ZXJhY3RpbmcgPSBmYWxzZTtcclxuXHJcbiAgICB0aGlzLnBvaW50ZXJUeXBlID0gcG9pbnRlclR5cGU7XHJcblxyXG4gICAgc2lnbmFscy5maXJlKCduZXcnLCB0aGlzKTtcclxuXHJcbiAgICBzY29wZS5pbnRlcmFjdGlvbnMucHVzaCh0aGlzKTtcclxuICB9XHJcblxyXG4gIEludGVyYWN0aW9uLnByb3RvdHlwZS5wb2ludGVyRG93biA9IGZ1bmN0aW9uIHBvaW50ZXJEb3duKHBvaW50ZXIsIGV2ZW50LCBldmVudFRhcmdldCkge1xyXG4gICAgdmFyIHBvaW50ZXJJbmRleCA9IHRoaXMudXBkYXRlUG9pbnRlcihwb2ludGVyLCBldmVudCwgdHJ1ZSk7XHJcblxyXG4gICAgc2lnbmFscy5maXJlKCdkb3duJywge1xyXG4gICAgICBwb2ludGVyOiBwb2ludGVyLFxyXG4gICAgICBldmVudDogZXZlbnQsXHJcbiAgICAgIGV2ZW50VGFyZ2V0OiBldmVudFRhcmdldCxcclxuICAgICAgcG9pbnRlckluZGV4OiBwb2ludGVySW5kZXgsXHJcbiAgICAgIGludGVyYWN0aW9uOiB0aGlzXHJcbiAgICB9KTtcclxuICB9O1xyXG5cclxuICAvKlxcXHJcbiAgICogSW50ZXJhY3Rpb24uc3RhcnRcclxuICAgWyBtZXRob2QgXVxyXG4gICAqXHJcbiAgICogU3RhcnQgYW4gYWN0aW9uIHdpdGggdGhlIGdpdmVuIEludGVyYWN0YWJsZSBhbmQgRWxlbWVudCBhcyB0YXJ0Z2V0cy4gVGhlXHJcbiAgICogYWN0aW9uIG11c3QgYmUgZW5hYmxlZCBmb3IgdGhlIHRhcmdldCBJbnRlcmFjdGFibGUgYW5kIGFuIGFwcHJvcHJpYXRlIG51bWJlclxyXG4gICAqIG9mIHBvaW50ZXJzIG11c3QgYmUgaGVsZCBkb3duIC0gMSBmb3IgZHJhZy9yZXNpemUsIDIgZm9yIGdlc3R1cmUuXHJcbiAgICpcclxuICAgKiBVc2UgaXQgd2l0aCBgaW50ZXJhY3RhYmxlLjxhY3Rpb24+YWJsZSh7IG1hbnVhbFN0YXJ0OiBmYWxzZSB9KWAgdG8gYWx3YXlzXHJcbiAgICogW3N0YXJ0IGFjdGlvbnMgbWFudWFsbHldKGh0dHBzOi8vZ2l0aHViLmNvbS90YXllL2ludGVyYWN0LmpzL2lzc3Vlcy8xMTQpXHJcbiAgICpcclxuICAgLSBhY3Rpb24gIChvYmplY3QpICBUaGUgYWN0aW9uIHRvIGJlIHBlcmZvcm1lZCAtIGRyYWcsIHJlc2l6ZSwgZXRjLlxyXG4gICAtIHRhcmdldCAgKEludGVyYWN0YWJsZSkgVGhlIEludGVyYWN0YWJsZSB0byB0YXJnZXRcclxuICAgLSBlbGVtZW50IChFbGVtZW50KSBUaGUgRE9NIEVsZW1lbnQgdG8gdGFyZ2V0XHJcbiAgID0gKG9iamVjdCkgaW50ZXJhY3RcclxuICAgKipcclxuICAgfCBpbnRlcmFjdCh0YXJnZXQpXHJcbiAgIHwgICAuZHJhZ2dhYmxlKHtcclxuICAgfCAgICAgLy8gZGlzYWJsZSB0aGUgZGVmYXVsdCBkcmFnIHN0YXJ0IGJ5IGRvd24tPm1vdmVcclxuICAgfCAgICAgbWFudWFsU3RhcnQ6IHRydWVcclxuICAgfCAgIH0pXHJcbiAgIHwgICAvLyBzdGFydCBkcmFnZ2luZyBhZnRlciB0aGUgdXNlciBob2xkcyB0aGUgcG9pbnRlciBkb3duXHJcbiAgIHwgICAub24oJ2hvbGQnLCBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgfCAgICAgdmFyIGludGVyYWN0aW9uID0gZXZlbnQuaW50ZXJhY3Rpb247XHJcbiAgIHxcclxuICAgfCAgICAgaWYgKCFpbnRlcmFjdGlvbi5pbnRlcmFjdGluZygpKSB7XHJcbiAgIHwgICAgICAgaW50ZXJhY3Rpb24uc3RhcnQoeyBuYW1lOiAnZHJhZycgfSxcclxuICAgfCAgICAgICAgICAgICAgICAgICAgICAgICBldmVudC5pbnRlcmFjdGFibGUsXHJcbiAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQuY3VycmVudFRhcmdldCk7XHJcbiAgIHwgICAgIH1cclxuICAgfCB9KTtcclxuICAgXFwqL1xyXG5cclxuXHJcbiAgSW50ZXJhY3Rpb24ucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24gc3RhcnQoYWN0aW9uLCB0YXJnZXQsIGVsZW1lbnQpIHtcclxuICAgIGlmICh0aGlzLmludGVyYWN0aW5nKCkgfHwgIXRoaXMucG9pbnRlcklzRG93biB8fCB0aGlzLnBvaW50ZXJJZHMubGVuZ3RoIDwgKGFjdGlvbi5uYW1lID09PSAnZ2VzdHVyZScgPyAyIDogMSkpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGlmIHRoaXMgaW50ZXJhY3Rpb24gaGFkIGJlZW4gcmVtb3ZlZCBhZnRlciBzdG9wcGluZ1xyXG4gICAgLy8gYWRkIGl0IGJhY2tcclxuICAgIGlmICh1dGlscy5pbmRleE9mKHNjb3BlLmludGVyYWN0aW9ucywgdGhpcykgPT09IC0xKSB7XHJcbiAgICAgIHNjb3BlLmludGVyYWN0aW9ucy5wdXNoKHRoaXMpO1xyXG4gICAgfVxyXG5cclxuICAgIHV0aWxzLmNvcHlBY3Rpb24odGhpcy5wcmVwYXJlZCwgYWN0aW9uKTtcclxuICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0O1xyXG4gICAgdGhpcy5lbGVtZW50ID0gZWxlbWVudDtcclxuXHJcbiAgICBzaWduYWxzLmZpcmUoJ2FjdGlvbi1zdGFydCcsIHtcclxuICAgICAgaW50ZXJhY3Rpb246IHRoaXMsXHJcbiAgICAgIGV2ZW50OiB0aGlzLmRvd25FdmVudFxyXG4gICAgfSk7XHJcbiAgfTtcclxuXHJcbiAgSW50ZXJhY3Rpb24ucHJvdG90eXBlLnBvaW50ZXJNb3ZlID0gZnVuY3Rpb24gcG9pbnRlck1vdmUocG9pbnRlciwgZXZlbnQsIGV2ZW50VGFyZ2V0KSB7XHJcbiAgICBpZiAoIXRoaXMuc2ltdWxhdGlvbikge1xyXG4gICAgICB0aGlzLnVwZGF0ZVBvaW50ZXIocG9pbnRlcik7XHJcbiAgICAgIHV0aWxzLnNldENvb3Jkcyh0aGlzLmN1ckNvb3JkcywgdGhpcy5wb2ludGVycyk7XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIGR1cGxpY2F0ZU1vdmUgPSB0aGlzLmN1ckNvb3Jkcy5wYWdlLnggPT09IHRoaXMucHJldkNvb3Jkcy5wYWdlLnggJiYgdGhpcy5jdXJDb29yZHMucGFnZS55ID09PSB0aGlzLnByZXZDb29yZHMucGFnZS55ICYmIHRoaXMuY3VyQ29vcmRzLmNsaWVudC54ID09PSB0aGlzLnByZXZDb29yZHMuY2xpZW50LnggJiYgdGhpcy5jdXJDb29yZHMuY2xpZW50LnkgPT09IHRoaXMucHJldkNvb3Jkcy5jbGllbnQueTtcclxuXHJcbiAgICB2YXIgZHggPSB2b2lkIDA7XHJcbiAgICB2YXIgZHkgPSB2b2lkIDA7XHJcblxyXG4gICAgLy8gcmVnaXN0ZXIgbW92ZW1lbnQgZ3JlYXRlciB0aGFuIHBvaW50ZXJNb3ZlVG9sZXJhbmNlXHJcbiAgICBpZiAodGhpcy5wb2ludGVySXNEb3duICYmICF0aGlzLnBvaW50ZXJXYXNNb3ZlZCkge1xyXG4gICAgICBkeCA9IHRoaXMuY3VyQ29vcmRzLmNsaWVudC54IC0gdGhpcy5zdGFydENvb3Jkcy5jbGllbnQueDtcclxuICAgICAgZHkgPSB0aGlzLmN1ckNvb3Jkcy5jbGllbnQueSAtIHRoaXMuc3RhcnRDb29yZHMuY2xpZW50Lnk7XHJcblxyXG4gICAgICB0aGlzLnBvaW50ZXJXYXNNb3ZlZCA9IHV0aWxzLmh5cG90KGR4LCBkeSkgPiBJbnRlcmFjdGlvbi5wb2ludGVyTW92ZVRvbGVyYW5jZTtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgc2lnbmFsQXJnID0ge1xyXG4gICAgICBwb2ludGVyOiBwb2ludGVyLFxyXG4gICAgICBwb2ludGVySW5kZXg6IHRoaXMuZ2V0UG9pbnRlckluZGV4KHBvaW50ZXIpLFxyXG4gICAgICBldmVudDogZXZlbnQsXHJcbiAgICAgIGV2ZW50VGFyZ2V0OiBldmVudFRhcmdldCxcclxuICAgICAgZHg6IGR4LFxyXG4gICAgICBkeTogZHksXHJcbiAgICAgIGR1cGxpY2F0ZTogZHVwbGljYXRlTW92ZSxcclxuICAgICAgaW50ZXJhY3Rpb246IHRoaXMsXHJcbiAgICAgIGludGVyYWN0aW5nQmVmb3JlTW92ZTogdGhpcy5pbnRlcmFjdGluZygpXHJcbiAgICB9O1xyXG5cclxuICAgIGlmICghZHVwbGljYXRlTW92ZSkge1xyXG4gICAgICAvLyBzZXQgcG9pbnRlciBjb29yZGluYXRlLCB0aW1lIGNoYW5nZXMgYW5kIHNwZWVkc1xyXG4gICAgICB1dGlscy5zZXRDb29yZERlbHRhcyh0aGlzLnBvaW50ZXJEZWx0YSwgdGhpcy5wcmV2Q29vcmRzLCB0aGlzLmN1ckNvb3Jkcyk7XHJcbiAgICB9XHJcblxyXG4gICAgc2lnbmFscy5maXJlKCdtb3ZlJywgc2lnbmFsQXJnKTtcclxuXHJcbiAgICBpZiAoIWR1cGxpY2F0ZU1vdmUpIHtcclxuICAgICAgLy8gaWYgaW50ZXJhY3RpbmcsIGZpcmUgYW4gJ2FjdGlvbi1tb3ZlJyBzaWduYWwgZXRjXHJcbiAgICAgIGlmICh0aGlzLmludGVyYWN0aW5nKCkpIHtcclxuICAgICAgICB0aGlzLmRvTW92ZShzaWduYWxBcmcpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAodGhpcy5wb2ludGVyV2FzTW92ZWQpIHtcclxuICAgICAgICB1dGlscy5jb3B5Q29vcmRzKHRoaXMucHJldkNvb3JkcywgdGhpcy5jdXJDb29yZHMpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgLypcXFxyXG4gICAqIEludGVyYWN0aW9uLmRvTW92ZVxyXG4gICBbIG1ldGhvZCBdXHJcbiAgICpcclxuICAgKiBGb3JjZSBhIG1vdmUgb2YgdGhlIGN1cnJlbnQgYWN0aW9uIGF0IHRoZSBzYW1lIGNvb3JkaW5hdGVzLiBVc2VmdWwgaWZcclxuICAgKiBzbmFwL3Jlc3RyaWN0IGhhcyBiZWVuIGNoYW5nZWQgYW5kIHlvdSB3YW50IGEgbW92ZW1lbnQgd2l0aCB0aGUgbmV3XHJcbiAgICogc2V0dGluZ3MuXHJcbiAgICpcclxuICAgKipcclxuICAgfCBpbnRlcmFjdCh0YXJnZXQpXHJcbiAgIHwgICAuZHJhZ2dhYmxlKHRydWUpXHJcbiAgIHwgICAub24oJ2RyYWdtb3ZlJywgZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgIHwgICAgIGlmIChzb21lQ29uZGl0aW9uKSB7XHJcbiAgIHwgICAgICAgLy8gY2hhbmdlIHRoZSBzbmFwIHNldHRpbmdzXHJcbiAgIHwgICAgICAgZXZlbnQuaW50ZXJhY3RhYmxlLmRyYWdnYWJsZSh7IHNuYXA6IHsgdGFyZ2V0czogW10gfX0pO1xyXG4gICB8ICAgICAgIC8vIGZpcmUgYW5vdGhlciBtb3ZlIGV2ZW50IHdpdGggcmUtY2FsY3VsYXRlZCBzbmFwXHJcbiAgIHwgICAgICAgZXZlbnQuaW50ZXJhY3Rpb24uZG9Nb3ZlKCk7XHJcbiAgIHwgICAgIH1cclxuICAgfCAgIH0pO1xyXG4gICBcXCovXHJcblxyXG5cclxuICBJbnRlcmFjdGlvbi5wcm90b3R5cGUuZG9Nb3ZlID0gZnVuY3Rpb24gZG9Nb3ZlKHNpZ25hbEFyZykge1xyXG4gICAgc2lnbmFsQXJnID0gdXRpbHMuZXh0ZW5kKHtcclxuICAgICAgcG9pbnRlcjogdGhpcy5wb2ludGVyc1swXSxcclxuICAgICAgZXZlbnQ6IHRoaXMucHJldkV2ZW50LFxyXG4gICAgICBldmVudFRhcmdldDogdGhpcy5fZXZlbnRUYXJnZXQsXHJcbiAgICAgIGludGVyYWN0aW9uOiB0aGlzXHJcbiAgICB9LCBzaWduYWxBcmcgfHwge30pO1xyXG5cclxuICAgIHNpZ25hbHMuZmlyZSgnYmVmb3JlLWFjdGlvbi1tb3ZlJywgc2lnbmFsQXJnKTtcclxuXHJcbiAgICBpZiAoIXRoaXMuX2RvbnRGaXJlTW92ZSkge1xyXG4gICAgICBzaWduYWxzLmZpcmUoJ2FjdGlvbi1tb3ZlJywgc2lnbmFsQXJnKTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLl9kb250RmlyZU1vdmUgPSBmYWxzZTtcclxuICB9O1xyXG5cclxuICAvLyBFbmQgaW50ZXJhY3QgbW92ZSBldmVudHMgYW5kIHN0b3AgYXV0by1zY3JvbGwgdW5sZXNzIHNpbXVsYXRpb24gaXMgcnVubmluZ1xyXG5cclxuXHJcbiAgSW50ZXJhY3Rpb24ucHJvdG90eXBlLnBvaW50ZXJVcCA9IGZ1bmN0aW9uIHBvaW50ZXJVcChwb2ludGVyLCBldmVudCwgZXZlbnRUYXJnZXQsIGN1ckV2ZW50VGFyZ2V0KSB7XHJcbiAgICB2YXIgcG9pbnRlckluZGV4ID0gdGhpcy5nZXRQb2ludGVySW5kZXgocG9pbnRlcik7XHJcblxyXG4gICAgc2lnbmFscy5maXJlKC9jYW5jZWwkL2kudGVzdChldmVudC50eXBlKSA/ICdjYW5jZWwnIDogJ3VwJywge1xyXG4gICAgICBwb2ludGVyOiBwb2ludGVyLFxyXG4gICAgICBwb2ludGVySW5kZXg6IHBvaW50ZXJJbmRleCxcclxuICAgICAgZXZlbnQ6IGV2ZW50LFxyXG4gICAgICBldmVudFRhcmdldDogZXZlbnRUYXJnZXQsXHJcbiAgICAgIGN1ckV2ZW50VGFyZ2V0OiBjdXJFdmVudFRhcmdldCxcclxuICAgICAgaW50ZXJhY3Rpb246IHRoaXNcclxuICAgIH0pO1xyXG5cclxuICAgIGlmICghdGhpcy5zaW11bGF0aW9uKSB7XHJcbiAgICAgIHRoaXMuZW5kKGV2ZW50KTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLnBvaW50ZXJJc0Rvd24gPSBmYWxzZTtcclxuICAgIHRoaXMucmVtb3ZlUG9pbnRlcihwb2ludGVyLCBldmVudCk7XHJcbiAgfTtcclxuXHJcbiAgLypcXFxyXG4gICAqIEludGVyYWN0aW9uLmVuZFxyXG4gICBbIG1ldGhvZCBdXHJcbiAgICpcclxuICAgKiBTdG9wIHRoZSBjdXJyZW50IGFjdGlvbiBhbmQgZmlyZSBhbiBlbmQgZXZlbnQuIEluZXJ0aWFsIG1vdmVtZW50IGRvZXNcclxuICAgKiBub3QgaGFwcGVuLlxyXG4gICAqXHJcbiAgIC0gZXZlbnQgKFBvaW50ZXJFdmVudCkgI29wdGlvbmFsXHJcbiAgICoqXHJcbiAgIHwgaW50ZXJhY3QodGFyZ2V0KVxyXG4gICB8ICAgLmRyYWdnYWJsZSh0cnVlKVxyXG4gICB8ICAgLm9uKCdtb3ZlJywgZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgIHwgICAgIGlmIChldmVudC5wYWdlWCA+IDEwMDApIHtcclxuICAgfCAgICAgICAvLyBlbmQgdGhlIGN1cnJlbnQgYWN0aW9uXHJcbiAgIHwgICAgICAgZXZlbnQuaW50ZXJhY3Rpb24uZW5kKCk7XHJcbiAgIHwgICAgICAgLy8gc3RvcCBhbGwgZnVydGhlciBsaXN0ZW5lcnMgZnJvbSBiZWluZyBjYWxsZWRcclxuICAgfCAgICAgICBldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcclxuICAgfCAgICAgfVxyXG4gICB8ICAgfSk7XHJcbiAgIFxcKi9cclxuXHJcblxyXG4gIEludGVyYWN0aW9uLnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbiBlbmQoZXZlbnQpIHtcclxuICAgIGV2ZW50ID0gZXZlbnQgfHwgdGhpcy5wcmV2RXZlbnQ7XHJcblxyXG4gICAgaWYgKHRoaXMuaW50ZXJhY3RpbmcoKSkge1xyXG4gICAgICBzaWduYWxzLmZpcmUoJ2FjdGlvbi1lbmQnLCB7XHJcbiAgICAgICAgZXZlbnQ6IGV2ZW50LFxyXG4gICAgICAgIGludGVyYWN0aW9uOiB0aGlzXHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuc3RvcCgpO1xyXG4gIH07XHJcblxyXG4gIEludGVyYWN0aW9uLnByb3RvdHlwZS5jdXJyZW50QWN0aW9uID0gZnVuY3Rpb24gY3VycmVudEFjdGlvbigpIHtcclxuICAgIHJldHVybiB0aGlzLl9pbnRlcmFjdGluZyA/IHRoaXMucHJlcGFyZWQubmFtZSA6IG51bGw7XHJcbiAgfTtcclxuXHJcbiAgSW50ZXJhY3Rpb24ucHJvdG90eXBlLmludGVyYWN0aW5nID0gZnVuY3Rpb24gaW50ZXJhY3RpbmcoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5faW50ZXJhY3Rpbmc7XHJcbiAgfTtcclxuXHJcbiAgSW50ZXJhY3Rpb24ucHJvdG90eXBlLnN0b3AgPSBmdW5jdGlvbiBzdG9wKCkge1xyXG4gICAgc2lnbmFscy5maXJlKCdzdG9wJywgeyBpbnRlcmFjdGlvbjogdGhpcyB9KTtcclxuXHJcbiAgICBpZiAodGhpcy5faW50ZXJhY3RpbmcpIHtcclxuICAgICAgc2lnbmFscy5maXJlKCdzdG9wLWFjdGl2ZScsIHsgaW50ZXJhY3Rpb246IHRoaXMgfSk7XHJcbiAgICAgIHNpZ25hbHMuZmlyZSgnc3RvcC0nICsgdGhpcy5wcmVwYXJlZC5uYW1lLCB7IGludGVyYWN0aW9uOiB0aGlzIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMudGFyZ2V0ID0gdGhpcy5lbGVtZW50ID0gbnVsbDtcclxuXHJcbiAgICB0aGlzLl9pbnRlcmFjdGluZyA9IGZhbHNlO1xyXG4gICAgdGhpcy5wcmVwYXJlZC5uYW1lID0gdGhpcy5wcmV2RXZlbnQgPSBudWxsO1xyXG4gIH07XHJcblxyXG4gIEludGVyYWN0aW9uLnByb3RvdHlwZS5nZXRQb2ludGVySW5kZXggPSBmdW5jdGlvbiBnZXRQb2ludGVySW5kZXgocG9pbnRlcikge1xyXG4gICAgLy8gbW91c2UgYW5kIHBlbiBpbnRlcmFjdGlvbnMgbWF5IGhhdmUgb25seSBvbmUgcG9pbnRlclxyXG4gICAgaWYgKHRoaXMucG9pbnRlclR5cGUgPT09ICdtb3VzZScgfHwgdGhpcy5wb2ludGVyVHlwZSA9PT0gJ3BlbicpIHtcclxuICAgICAgcmV0dXJuIDA7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHV0aWxzLmluZGV4T2YodGhpcy5wb2ludGVySWRzLCB1dGlscy5nZXRQb2ludGVySWQocG9pbnRlcikpO1xyXG4gIH07XHJcblxyXG4gIEludGVyYWN0aW9uLnByb3RvdHlwZS51cGRhdGVQb2ludGVyID0gZnVuY3Rpb24gdXBkYXRlUG9pbnRlcihwb2ludGVyLCBldmVudCkge1xyXG4gICAgdmFyIGRvd24gPSBhcmd1bWVudHMubGVuZ3RoID4gMiAmJiBhcmd1bWVudHNbMl0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1syXSA6IGV2ZW50ICYmIC8oZG93bnxzdGFydCkkL2kudGVzdChldmVudC50eXBlKTtcclxuXHJcbiAgICB2YXIgaWQgPSB1dGlscy5nZXRQb2ludGVySWQocG9pbnRlcik7XHJcbiAgICB2YXIgaW5kZXggPSB0aGlzLmdldFBvaW50ZXJJbmRleChwb2ludGVyKTtcclxuXHJcbiAgICBpZiAoaW5kZXggPT09IC0xKSB7XHJcbiAgICAgIGluZGV4ID0gdGhpcy5wb2ludGVySWRzLmxlbmd0aDtcclxuICAgICAgdGhpcy5wb2ludGVySWRzW2luZGV4XSA9IGlkO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChkb3duKSB7XHJcbiAgICAgIHNpZ25hbHMuZmlyZSgndXBkYXRlLXBvaW50ZXItZG93bicsIHtcclxuICAgICAgICBwb2ludGVyOiBwb2ludGVyLFxyXG4gICAgICAgIGV2ZW50OiBldmVudCxcclxuICAgICAgICBkb3duOiBkb3duLFxyXG4gICAgICAgIHBvaW50ZXJJZDogaWQsXHJcbiAgICAgICAgcG9pbnRlckluZGV4OiBpbmRleCxcclxuICAgICAgICBpbnRlcmFjdGlvbjogdGhpc1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLnBvaW50ZXJzW2luZGV4XSA9IHBvaW50ZXI7XHJcblxyXG4gICAgcmV0dXJuIGluZGV4O1xyXG4gIH07XHJcblxyXG4gIEludGVyYWN0aW9uLnByb3RvdHlwZS5yZW1vdmVQb2ludGVyID0gZnVuY3Rpb24gcmVtb3ZlUG9pbnRlcihwb2ludGVyLCBldmVudCkge1xyXG4gICAgdmFyIGluZGV4ID0gdGhpcy5nZXRQb2ludGVySW5kZXgocG9pbnRlcik7XHJcblxyXG4gICAgaWYgKGluZGV4ID09PSAtMSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgc2lnbmFscy5maXJlKCdyZW1vdmUtcG9pbnRlcicsIHtcclxuICAgICAgcG9pbnRlcjogcG9pbnRlcixcclxuICAgICAgZXZlbnQ6IGV2ZW50LFxyXG4gICAgICBwb2ludGVySW5kZXg6IGluZGV4LFxyXG4gICAgICBpbnRlcmFjdGlvbjogdGhpc1xyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5wb2ludGVycy5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gICAgdGhpcy5wb2ludGVySWRzLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICB0aGlzLmRvd25UYXJnZXRzLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICB0aGlzLmRvd25UaW1lcy5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gIH07XHJcblxyXG4gIEludGVyYWN0aW9uLnByb3RvdHlwZS5fdXBkYXRlRXZlbnRUYXJnZXRzID0gZnVuY3Rpb24gX3VwZGF0ZUV2ZW50VGFyZ2V0cyh0YXJnZXQsIGN1cnJlbnRUYXJnZXQpIHtcclxuICAgIHRoaXMuX2V2ZW50VGFyZ2V0ID0gdGFyZ2V0O1xyXG4gICAgdGhpcy5fY3VyRXZlbnRUYXJnZXQgPSBjdXJyZW50VGFyZ2V0O1xyXG4gIH07XHJcblxyXG4gIHJldHVybiBJbnRlcmFjdGlvbjtcclxufSgpO1xyXG5cclxuZm9yICh2YXIgaSA9IDAsIGxlbiA9IG1ldGhvZE5hbWVzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgdmFyIG1ldGhvZCA9IG1ldGhvZE5hbWVzW2ldO1xyXG5cclxuICBsaXN0ZW5lcnNbbWV0aG9kXSA9IGRvT25JbnRlcmFjdGlvbnMobWV0aG9kKTtcclxufVxyXG5cclxuZnVuY3Rpb24gZG9PbkludGVyYWN0aW9ucyhtZXRob2QpIHtcclxuICByZXR1cm4gZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgICB2YXIgcG9pbnRlclR5cGUgPSB1dGlscy5nZXRQb2ludGVyVHlwZShldmVudCk7XHJcblxyXG4gICAgdmFyIF91dGlscyRnZXRFdmVudFRhcmdldCA9IHV0aWxzLmdldEV2ZW50VGFyZ2V0cyhldmVudCksXHJcbiAgICAgICAgZXZlbnRUYXJnZXQgPSBfdXRpbHMkZ2V0RXZlbnRUYXJnZXRbMF0sXHJcbiAgICAgICAgY3VyRXZlbnRUYXJnZXQgPSBfdXRpbHMkZ2V0RXZlbnRUYXJnZXRbMV07XHJcblxyXG4gICAgdmFyIG1hdGNoZXMgPSBbXTsgLy8gWyBbcG9pbnRlciwgaW50ZXJhY3Rpb25dLCAuLi5dXHJcblxyXG4gICAgaWYgKGJyb3dzZXIuc3VwcG9ydHNUb3VjaCAmJiAvdG91Y2gvLnRlc3QoZXZlbnQudHlwZSkpIHtcclxuICAgICAgcHJldlRvdWNoVGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xyXG5cclxuICAgICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGV2ZW50LmNoYW5nZWRUb3VjaGVzLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgIHZhciBwb2ludGVyID0gZXZlbnQuY2hhbmdlZFRvdWNoZXNbX2ldO1xyXG4gICAgICAgIHZhciBpbnRlcmFjdGlvbiA9IGZpbmRlci5zZWFyY2gocG9pbnRlciwgZXZlbnQudHlwZSwgZXZlbnRUYXJnZXQpO1xyXG5cclxuICAgICAgICBtYXRjaGVzLnB1c2goW3BvaW50ZXIsIGludGVyYWN0aW9uIHx8IG5ldyBJbnRlcmFjdGlvbih7IHBvaW50ZXJUeXBlOiBwb2ludGVyVHlwZSB9KV0pO1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB2YXIgaW52YWxpZFBvaW50ZXIgPSBmYWxzZTtcclxuXHJcbiAgICAgIGlmICghYnJvd3Nlci5zdXBwb3J0c1BvaW50ZXJFdmVudCAmJiAvbW91c2UvLnRlc3QoZXZlbnQudHlwZSkpIHtcclxuICAgICAgICAvLyBpZ25vcmUgbW91c2UgZXZlbnRzIHdoaWxlIHRvdWNoIGludGVyYWN0aW9ucyBhcmUgYWN0aXZlXHJcbiAgICAgICAgZm9yICh2YXIgX2kyID0gMDsgX2kyIDwgc2NvcGUuaW50ZXJhY3Rpb25zLmxlbmd0aCAmJiAhaW52YWxpZFBvaW50ZXI7IF9pMisrKSB7XHJcbiAgICAgICAgICBpbnZhbGlkUG9pbnRlciA9IHNjb3BlLmludGVyYWN0aW9uc1tfaTJdLnBvaW50ZXJUeXBlICE9PSAnbW91c2UnICYmIHNjb3BlLmludGVyYWN0aW9uc1tfaTJdLnBvaW50ZXJJc0Rvd247XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyB0cnkgdG8gaWdub3JlIG1vdXNlIGV2ZW50cyB0aGF0IGFyZSBzaW11bGF0ZWQgYnkgdGhlIGJyb3dzZXJcclxuICAgICAgICAvLyBhZnRlciBhIHRvdWNoIGV2ZW50XHJcbiAgICAgICAgaW52YWxpZFBvaW50ZXIgPSBpbnZhbGlkUG9pbnRlciB8fCBuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIHByZXZUb3VjaFRpbWUgPCA1MDBcclxuICAgICAgICAvLyBvbiBpT1MgYW5kIEZpcmVmb3ggTW9iaWxlLCBNb3VzZUV2ZW50LnRpbWVTdGFtcCBpcyB6ZXJvIGlmIHNpbXVsYXRlZFxyXG4gICAgICAgIHx8IGV2ZW50LnRpbWVTdGFtcCA9PT0gMDtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKCFpbnZhbGlkUG9pbnRlcikge1xyXG4gICAgICAgIHZhciBfaW50ZXJhY3Rpb24gPSBmaW5kZXIuc2VhcmNoKGV2ZW50LCBldmVudC50eXBlLCBldmVudFRhcmdldCk7XHJcblxyXG4gICAgICAgIGlmICghX2ludGVyYWN0aW9uKSB7XHJcbiAgICAgICAgICBfaW50ZXJhY3Rpb24gPSBuZXcgSW50ZXJhY3Rpb24oeyBwb2ludGVyVHlwZTogcG9pbnRlclR5cGUgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBtYXRjaGVzLnB1c2goW2V2ZW50LCBfaW50ZXJhY3Rpb25dKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGZvciAodmFyIF9pdGVyYXRvciA9IG1hdGNoZXMsIF9pc0FycmF5ID0gQXJyYXkuaXNBcnJheShfaXRlcmF0b3IpLCBfaTMgPSAwLCBfaXRlcmF0b3IgPSBfaXNBcnJheSA/IF9pdGVyYXRvciA6IF9pdGVyYXRvcltTeW1ib2wuaXRlcmF0b3JdKCk7Oykge1xyXG4gICAgICB2YXIgX3JlZjI7XHJcblxyXG4gICAgICBpZiAoX2lzQXJyYXkpIHtcclxuICAgICAgICBpZiAoX2kzID49IF9pdGVyYXRvci5sZW5ndGgpIGJyZWFrO1xyXG4gICAgICAgIF9yZWYyID0gX2l0ZXJhdG9yW19pMysrXTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBfaTMgPSBfaXRlcmF0b3IubmV4dCgpO1xyXG4gICAgICAgIGlmIChfaTMuZG9uZSkgYnJlYWs7XHJcbiAgICAgICAgX3JlZjIgPSBfaTMudmFsdWU7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHZhciBfcmVmMyA9IF9yZWYyLFxyXG4gICAgICAgICAgX3BvaW50ZXIgPSBfcmVmM1swXSxcclxuICAgICAgICAgIF9pbnRlcmFjdGlvbjIgPSBfcmVmM1sxXTtcclxuXHJcbiAgICAgIF9pbnRlcmFjdGlvbjIuX3VwZGF0ZUV2ZW50VGFyZ2V0cyhldmVudFRhcmdldCwgY3VyRXZlbnRUYXJnZXQpO1xyXG4gICAgICBfaW50ZXJhY3Rpb24yW21ldGhvZF0oX3BvaW50ZXIsIGV2ZW50LCBldmVudFRhcmdldCwgY3VyRXZlbnRUYXJnZXQpO1xyXG4gICAgfVxyXG4gIH07XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGVuZEFsbChldmVudCkge1xyXG4gIGZvciAodmFyIF9pNCA9IDA7IF9pNCA8IHNjb3BlLmludGVyYWN0aW9ucy5sZW5ndGg7IF9pNCsrKSB7XHJcbiAgICB2YXIgaW50ZXJhY3Rpb24gPSBzY29wZS5pbnRlcmFjdGlvbnNbX2k0XTtcclxuXHJcbiAgICBpbnRlcmFjdGlvbi5lbmQoZXZlbnQpO1xyXG4gICAgc2lnbmFscy5maXJlKCdlbmRhbGwnLCB7IGV2ZW50OiBldmVudCwgaW50ZXJhY3Rpb246IGludGVyYWN0aW9uIH0pO1xyXG4gIH1cclxufVxyXG5cclxudmFyIGRvY0V2ZW50cyA9IHsvKiAnZXZlbnRUeXBlJzogbGlzdGVuZXJGdW5jICovfTtcclxudmFyIHBFdmVudFR5cGVzID0gYnJvd3Nlci5wRXZlbnRUeXBlcztcclxuXHJcbmlmIChkb21PYmplY3RzLlBvaW50ZXJFdmVudCkge1xyXG4gIGRvY0V2ZW50c1twRXZlbnRUeXBlcy5kb3duXSA9IGxpc3RlbmVycy5wb2ludGVyRG93bjtcclxuICBkb2NFdmVudHNbcEV2ZW50VHlwZXMubW92ZV0gPSBsaXN0ZW5lcnMucG9pbnRlck1vdmU7XHJcbiAgZG9jRXZlbnRzW3BFdmVudFR5cGVzLnVwXSA9IGxpc3RlbmVycy5wb2ludGVyVXA7XHJcbiAgZG9jRXZlbnRzW3BFdmVudFR5cGVzLmNhbmNlbF0gPSBsaXN0ZW5lcnMucG9pbnRlclVwO1xyXG59IGVsc2Uge1xyXG4gIGRvY0V2ZW50cy5tb3VzZWRvd24gPSBsaXN0ZW5lcnMucG9pbnRlckRvd247XHJcbiAgZG9jRXZlbnRzLm1vdXNlbW92ZSA9IGxpc3RlbmVycy5wb2ludGVyTW92ZTtcclxuICBkb2NFdmVudHMubW91c2V1cCA9IGxpc3RlbmVycy5wb2ludGVyVXA7XHJcblxyXG4gIGRvY0V2ZW50cy50b3VjaHN0YXJ0ID0gbGlzdGVuZXJzLnBvaW50ZXJEb3duO1xyXG4gIGRvY0V2ZW50cy50b3VjaG1vdmUgPSBsaXN0ZW5lcnMucG9pbnRlck1vdmU7XHJcbiAgZG9jRXZlbnRzLnRvdWNoZW5kID0gbGlzdGVuZXJzLnBvaW50ZXJVcDtcclxuICBkb2NFdmVudHMudG91Y2hjYW5jZWwgPSBsaXN0ZW5lcnMucG9pbnRlclVwO1xyXG59XHJcblxyXG5kb2NFdmVudHMuYmx1ciA9IGVuZEFsbDtcclxuXHJcbmZ1bmN0aW9uIG9uRG9jU2lnbmFsKF9yZWY0LCBzaWduYWxOYW1lKSB7XHJcbiAgdmFyIGRvYyA9IF9yZWY0LmRvYztcclxuXHJcbiAgdmFyIGV2ZW50TWV0aG9kID0gc2lnbmFsTmFtZS5pbmRleE9mKCdhZGQnKSA9PT0gMCA/IGV2ZW50cy5hZGQgOiBldmVudHMucmVtb3ZlO1xyXG5cclxuICAvLyBkZWxlZ2F0ZSBldmVudCBsaXN0ZW5lclxyXG4gIGZvciAodmFyIGV2ZW50VHlwZSBpbiBzY29wZS5kZWxlZ2F0ZWRFdmVudHMpIHtcclxuICAgIGV2ZW50TWV0aG9kKGRvYywgZXZlbnRUeXBlLCBldmVudHMuZGVsZWdhdGVMaXN0ZW5lcik7XHJcbiAgICBldmVudE1ldGhvZChkb2MsIGV2ZW50VHlwZSwgZXZlbnRzLmRlbGVnYXRlVXNlQ2FwdHVyZSwgdHJ1ZSk7XHJcbiAgfVxyXG5cclxuICBmb3IgKHZhciBfZXZlbnRUeXBlIGluIGRvY0V2ZW50cykge1xyXG4gICAgZXZlbnRNZXRob2QoZG9jLCBfZXZlbnRUeXBlLCBkb2NFdmVudHNbX2V2ZW50VHlwZV0pO1xyXG4gIH1cclxufVxyXG5cclxuc2lnbmFscy5vbigndXBkYXRlLXBvaW50ZXItZG93bicsIGZ1bmN0aW9uIChfcmVmNSkge1xyXG4gIHZhciBpbnRlcmFjdGlvbiA9IF9yZWY1LmludGVyYWN0aW9uLFxyXG4gICAgICBwb2ludGVyID0gX3JlZjUucG9pbnRlcixcclxuICAgICAgcG9pbnRlcklkID0gX3JlZjUucG9pbnRlcklkLFxyXG4gICAgICBwb2ludGVySW5kZXggPSBfcmVmNS5wb2ludGVySW5kZXgsXHJcbiAgICAgIGV2ZW50ID0gX3JlZjUuZXZlbnQsXHJcbiAgICAgIGV2ZW50VGFyZ2V0ID0gX3JlZjUuZXZlbnRUYXJnZXQsXHJcbiAgICAgIGRvd24gPSBfcmVmNS5kb3duO1xyXG5cclxuICBpbnRlcmFjdGlvbi5wb2ludGVySWRzW3BvaW50ZXJJbmRleF0gPSBwb2ludGVySWQ7XHJcbiAgaW50ZXJhY3Rpb24ucG9pbnRlcnNbcG9pbnRlckluZGV4XSA9IHBvaW50ZXI7XHJcblxyXG4gIGlmIChkb3duKSB7XHJcbiAgICBpbnRlcmFjdGlvbi5wb2ludGVySXNEb3duID0gdHJ1ZTtcclxuICB9XHJcblxyXG4gIGlmICghaW50ZXJhY3Rpb24uaW50ZXJhY3RpbmcoKSkge1xyXG4gICAgdXRpbHMuc2V0Q29vcmRzKGludGVyYWN0aW9uLnN0YXJ0Q29vcmRzLCBpbnRlcmFjdGlvbi5wb2ludGVycyk7XHJcblxyXG4gICAgdXRpbHMuY29weUNvb3JkcyhpbnRlcmFjdGlvbi5jdXJDb29yZHMsIGludGVyYWN0aW9uLnN0YXJ0Q29vcmRzKTtcclxuICAgIHV0aWxzLmNvcHlDb29yZHMoaW50ZXJhY3Rpb24ucHJldkNvb3JkcywgaW50ZXJhY3Rpb24uc3RhcnRDb29yZHMpO1xyXG5cclxuICAgIGludGVyYWN0aW9uLmRvd25FdmVudCA9IGV2ZW50O1xyXG4gICAgaW50ZXJhY3Rpb24uZG93blRpbWVzW3BvaW50ZXJJbmRleF0gPSBpbnRlcmFjdGlvbi5jdXJDb29yZHMudGltZVN0YW1wO1xyXG4gICAgaW50ZXJhY3Rpb24uZG93blRhcmdldHNbcG9pbnRlckluZGV4XSA9IGV2ZW50VGFyZ2V0IHx8IGV2ZW50ICYmIHV0aWxzLmdldEV2ZW50VGFyZ2V0cyhldmVudClbMF07XHJcbiAgICBpbnRlcmFjdGlvbi5wb2ludGVyV2FzTW92ZWQgPSBmYWxzZTtcclxuXHJcbiAgICB1dGlscy5wb2ludGVyRXh0ZW5kKGludGVyYWN0aW9uLmRvd25Qb2ludGVyLCBwb2ludGVyKTtcclxuICB9XHJcbn0pO1xyXG5cclxuc2NvcGUuc2lnbmFscy5vbignYWRkLWRvY3VtZW50Jywgb25Eb2NTaWduYWwpO1xyXG5zY29wZS5zaWduYWxzLm9uKCdyZW1vdmUtZG9jdW1lbnQnLCBvbkRvY1NpZ25hbCk7XHJcblxyXG5JbnRlcmFjdGlvbi5wb2ludGVyTW92ZVRvbGVyYW5jZSA9IDE7XHJcbkludGVyYWN0aW9uLmRvT25JbnRlcmFjdGlvbnMgPSBkb09uSW50ZXJhY3Rpb25zO1xyXG5JbnRlcmFjdGlvbi5lbmRBbGwgPSBlbmRBbGw7XHJcbkludGVyYWN0aW9uLnNpZ25hbHMgPSBzaWduYWxzO1xyXG5JbnRlcmFjdGlvbi5kb2NFdmVudHMgPSBkb2NFdmVudHM7XHJcblxyXG5zY29wZS5lbmRBbGxJbnRlcmFjdGlvbnMgPSBlbmRBbGw7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IEludGVyYWN0aW9uO1xyXG5cclxufSx7XCIuL3Njb3BlXCI6MzQsXCIuL3V0aWxzXCI6NDQsXCIuL3V0aWxzL1NpZ25hbHNcIjozNSxcIi4vdXRpbHMvYnJvd3NlclwiOjM3LFwiLi91dGlscy9kb21PYmplY3RzXCI6MzgsXCIuL3V0aWxzL2V2ZW50c1wiOjQwLFwiLi91dGlscy9pbnRlcmFjdGlvbkZpbmRlclwiOjQ1fV0sNjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBJbnRlcmFjdGlvbiA9IHJlcXVpcmUoJy4uL0ludGVyYWN0aW9uJyk7XHJcbnZhciBJbnRlcmFjdEV2ZW50ID0gcmVxdWlyZSgnLi4vSW50ZXJhY3RFdmVudCcpO1xyXG5cclxudmFyIGFjdGlvbnMgPSB7XHJcbiAgZmlyZVByZXBhcmVkOiBmaXJlUHJlcGFyZWQsXHJcbiAgbmFtZXM6IFtdLFxyXG4gIG1ldGhvZERpY3Q6IHt9XHJcbn07XHJcblxyXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdhY3Rpb24tc3RhcnQnLCBmdW5jdGlvbiAoX3JlZikge1xyXG4gIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYuaW50ZXJhY3Rpb24sXHJcbiAgICAgIGV2ZW50ID0gX3JlZi5ldmVudDtcclxuXHJcbiAgaW50ZXJhY3Rpb24uX2ludGVyYWN0aW5nID0gdHJ1ZTtcclxuICBmaXJlUHJlcGFyZWQoaW50ZXJhY3Rpb24sIGV2ZW50LCAnc3RhcnQnKTtcclxufSk7XHJcblxyXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdhY3Rpb24tbW92ZScsIGZ1bmN0aW9uIChfcmVmMikge1xyXG4gIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYyLmludGVyYWN0aW9uLFxyXG4gICAgICBldmVudCA9IF9yZWYyLmV2ZW50LFxyXG4gICAgICBwcmVFbmQgPSBfcmVmMi5wcmVFbmQ7XHJcblxyXG4gIGZpcmVQcmVwYXJlZChpbnRlcmFjdGlvbiwgZXZlbnQsICdtb3ZlJywgcHJlRW5kKTtcclxuXHJcbiAgLy8gaWYgdGhlIGFjdGlvbiB3YXMgZW5kZWQgaW4gYSBsaXN0ZW5lclxyXG4gIGlmICghaW50ZXJhY3Rpb24uaW50ZXJhY3RpbmcoKSkge1xyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG4gIH1cclxufSk7XHJcblxyXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdhY3Rpb24tZW5kJywgZnVuY3Rpb24gKF9yZWYzKSB7XHJcbiAgdmFyIGludGVyYWN0aW9uID0gX3JlZjMuaW50ZXJhY3Rpb24sXHJcbiAgICAgIGV2ZW50ID0gX3JlZjMuZXZlbnQ7XHJcblxyXG4gIGZpcmVQcmVwYXJlZChpbnRlcmFjdGlvbiwgZXZlbnQsICdlbmQnKTtcclxufSk7XHJcblxyXG5mdW5jdGlvbiBmaXJlUHJlcGFyZWQoaW50ZXJhY3Rpb24sIGV2ZW50LCBwaGFzZSwgcHJlRW5kKSB7XHJcbiAgdmFyIGFjdGlvbk5hbWUgPSBpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lO1xyXG5cclxuICB2YXIgbmV3RXZlbnQgPSBuZXcgSW50ZXJhY3RFdmVudChpbnRlcmFjdGlvbiwgZXZlbnQsIGFjdGlvbk5hbWUsIHBoYXNlLCBpbnRlcmFjdGlvbi5lbGVtZW50LCBudWxsLCBwcmVFbmQpO1xyXG5cclxuICBpbnRlcmFjdGlvbi50YXJnZXQuZmlyZShuZXdFdmVudCk7XHJcbiAgaW50ZXJhY3Rpb24ucHJldkV2ZW50ID0gbmV3RXZlbnQ7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gYWN0aW9ucztcclxuXHJcbn0se1wiLi4vSW50ZXJhY3RFdmVudFwiOjMsXCIuLi9JbnRlcmFjdGlvblwiOjV9XSw3OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGFjdGlvbnMgPSByZXF1aXJlKCcuL2Jhc2UnKTtcclxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcclxudmFyIEludGVyYWN0RXZlbnQgPSByZXF1aXJlKCcuLi9JbnRlcmFjdEV2ZW50Jyk7XHJcbnZhciBJbnRlcmFjdGFibGUgPSByZXF1aXJlKCcuLi9JbnRlcmFjdGFibGUnKTtcclxudmFyIEludGVyYWN0aW9uID0gcmVxdWlyZSgnLi4vSW50ZXJhY3Rpb24nKTtcclxudmFyIGRlZmF1bHRPcHRpb25zID0gcmVxdWlyZSgnLi4vZGVmYXVsdE9wdGlvbnMnKTtcclxuXHJcbnZhciBkcmFnID0ge1xyXG4gIGRlZmF1bHRzOiB7XHJcbiAgICBlbmFibGVkOiBmYWxzZSxcclxuICAgIG1vdXNlQnV0dG9uczogbnVsbCxcclxuXHJcbiAgICBvcmlnaW46IG51bGwsXHJcbiAgICBzbmFwOiBudWxsLFxyXG4gICAgcmVzdHJpY3Q6IG51bGwsXHJcbiAgICBpbmVydGlhOiBudWxsLFxyXG4gICAgYXV0b1Njcm9sbDogbnVsbCxcclxuXHJcbiAgICBzdGFydEF4aXM6ICd4eScsXHJcbiAgICBsb2NrQXhpczogJ3h5J1xyXG4gIH0sXHJcblxyXG4gIGNoZWNrZXI6IGZ1bmN0aW9uIGNoZWNrZXIocG9pbnRlciwgZXZlbnQsIGludGVyYWN0YWJsZSkge1xyXG4gICAgdmFyIGRyYWdPcHRpb25zID0gaW50ZXJhY3RhYmxlLm9wdGlvbnMuZHJhZztcclxuXHJcbiAgICByZXR1cm4gZHJhZ09wdGlvbnMuZW5hYmxlZCA/IHsgbmFtZTogJ2RyYWcnLCBheGlzOiBkcmFnT3B0aW9ucy5sb2NrQXhpcyA9PT0gJ3N0YXJ0JyA/IGRyYWdPcHRpb25zLnN0YXJ0QXhpcyA6IGRyYWdPcHRpb25zLmxvY2tBeGlzIH0gOiBudWxsO1xyXG4gIH0sXHJcblxyXG4gIGdldEN1cnNvcjogZnVuY3Rpb24gZ2V0Q3Vyc29yKCkge1xyXG4gICAgcmV0dXJuICdtb3ZlJztcclxuICB9XHJcbn07XHJcblxyXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdiZWZvcmUtYWN0aW9uLW1vdmUnLCBmdW5jdGlvbiAoX3JlZikge1xyXG4gIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYuaW50ZXJhY3Rpb247XHJcblxyXG4gIGlmIChpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lICE9PSAnZHJhZycpIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIHZhciBheGlzID0gaW50ZXJhY3Rpb24ucHJlcGFyZWQuYXhpcztcclxuXHJcbiAgaWYgKGF4aXMgPT09ICd4Jykge1xyXG4gICAgaW50ZXJhY3Rpb24uY3VyQ29vcmRzLnBhZ2UueSA9IGludGVyYWN0aW9uLnN0YXJ0Q29vcmRzLnBhZ2UueTtcclxuICAgIGludGVyYWN0aW9uLmN1ckNvb3Jkcy5jbGllbnQueSA9IGludGVyYWN0aW9uLnN0YXJ0Q29vcmRzLmNsaWVudC55O1xyXG5cclxuICAgIGludGVyYWN0aW9uLnBvaW50ZXJEZWx0YS5wYWdlLnNwZWVkID0gTWF0aC5hYnMoaW50ZXJhY3Rpb24ucG9pbnRlckRlbHRhLnBhZ2UudngpO1xyXG4gICAgaW50ZXJhY3Rpb24ucG9pbnRlckRlbHRhLmNsaWVudC5zcGVlZCA9IE1hdGguYWJzKGludGVyYWN0aW9uLnBvaW50ZXJEZWx0YS5jbGllbnQudngpO1xyXG4gICAgaW50ZXJhY3Rpb24ucG9pbnRlckRlbHRhLmNsaWVudC52eSA9IDA7XHJcbiAgICBpbnRlcmFjdGlvbi5wb2ludGVyRGVsdGEucGFnZS52eSA9IDA7XHJcbiAgfSBlbHNlIGlmIChheGlzID09PSAneScpIHtcclxuICAgIGludGVyYWN0aW9uLmN1ckNvb3Jkcy5wYWdlLnggPSBpbnRlcmFjdGlvbi5zdGFydENvb3Jkcy5wYWdlLng7XHJcbiAgICBpbnRlcmFjdGlvbi5jdXJDb29yZHMuY2xpZW50LnggPSBpbnRlcmFjdGlvbi5zdGFydENvb3Jkcy5jbGllbnQueDtcclxuXHJcbiAgICBpbnRlcmFjdGlvbi5wb2ludGVyRGVsdGEucGFnZS5zcGVlZCA9IE1hdGguYWJzKGludGVyYWN0aW9uLnBvaW50ZXJEZWx0YS5wYWdlLnZ5KTtcclxuICAgIGludGVyYWN0aW9uLnBvaW50ZXJEZWx0YS5jbGllbnQuc3BlZWQgPSBNYXRoLmFicyhpbnRlcmFjdGlvbi5wb2ludGVyRGVsdGEuY2xpZW50LnZ5KTtcclxuICAgIGludGVyYWN0aW9uLnBvaW50ZXJEZWx0YS5jbGllbnQudnggPSAwO1xyXG4gICAgaW50ZXJhY3Rpb24ucG9pbnRlckRlbHRhLnBhZ2UudnggPSAwO1xyXG4gIH1cclxufSk7XHJcblxyXG4vLyBkcmFnbW92ZVxyXG5JbnRlcmFjdEV2ZW50LnNpZ25hbHMub24oJ25ldycsIGZ1bmN0aW9uIChfcmVmMikge1xyXG4gIHZhciBpRXZlbnQgPSBfcmVmMi5pRXZlbnQsXHJcbiAgICAgIGludGVyYWN0aW9uID0gX3JlZjIuaW50ZXJhY3Rpb247XHJcblxyXG4gIGlmIChpRXZlbnQudHlwZSAhPT0gJ2RyYWdtb3ZlJykge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgdmFyIGF4aXMgPSBpbnRlcmFjdGlvbi5wcmVwYXJlZC5heGlzO1xyXG5cclxuICBpZiAoYXhpcyA9PT0gJ3gnKSB7XHJcbiAgICBpRXZlbnQucGFnZVkgPSBpbnRlcmFjdGlvbi5zdGFydENvb3Jkcy5wYWdlLnk7XHJcbiAgICBpRXZlbnQuY2xpZW50WSA9IGludGVyYWN0aW9uLnN0YXJ0Q29vcmRzLmNsaWVudC55O1xyXG4gICAgaUV2ZW50LmR5ID0gMDtcclxuICB9IGVsc2UgaWYgKGF4aXMgPT09ICd5Jykge1xyXG4gICAgaUV2ZW50LnBhZ2VYID0gaW50ZXJhY3Rpb24uc3RhcnRDb29yZHMucGFnZS54O1xyXG4gICAgaUV2ZW50LmNsaWVudFggPSBpbnRlcmFjdGlvbi5zdGFydENvb3Jkcy5jbGllbnQueDtcclxuICAgIGlFdmVudC5keCA9IDA7XHJcbiAgfVxyXG59KTtcclxuXHJcbi8qXFxcclxuICogSW50ZXJhY3RhYmxlLmRyYWdnYWJsZVxyXG4gWyBtZXRob2QgXVxyXG4gKlxyXG4gKiBHZXRzIG9yIHNldHMgd2hldGhlciBkcmFnIGFjdGlvbnMgY2FuIGJlIHBlcmZvcm1lZCBvbiB0aGVcclxuICogSW50ZXJhY3RhYmxlXHJcbiAqXHJcbiA9IChib29sZWFuKSBJbmRpY2F0ZXMgaWYgdGhpcyBjYW4gYmUgdGhlIHRhcmdldCBvZiBkcmFnIGV2ZW50c1xyXG4gfCB2YXIgaXNEcmFnZ2FibGUgPSBpbnRlcmFjdCgndWwgbGknKS5kcmFnZ2FibGUoKTtcclxuICogb3JcclxuIC0gb3B0aW9ucyAoYm9vbGVhbiB8IG9iamVjdCkgI29wdGlvbmFsIHRydWUvZmFsc2Ugb3IgQW4gb2JqZWN0IHdpdGggZXZlbnQgbGlzdGVuZXJzIHRvIGJlIGZpcmVkIG9uIGRyYWcgZXZlbnRzIChvYmplY3QgbWFrZXMgdGhlIEludGVyYWN0YWJsZSBkcmFnZ2FibGUpXHJcbiA9IChvYmplY3QpIFRoaXMgSW50ZXJhY3RhYmxlXHJcbiB8IGludGVyYWN0KGVsZW1lbnQpLmRyYWdnYWJsZSh7XHJcbiB8ICAgICBvbnN0YXJ0OiBmdW5jdGlvbiAoZXZlbnQpIHt9LFxyXG4gfCAgICAgb25tb3ZlIDogZnVuY3Rpb24gKGV2ZW50KSB7fSxcclxuIHwgICAgIG9uZW5kICA6IGZ1bmN0aW9uIChldmVudCkge30sXHJcbiB8XHJcbiB8ICAgICAvLyB0aGUgYXhpcyBpbiB3aGljaCB0aGUgZmlyc3QgbW92ZW1lbnQgbXVzdCBiZVxyXG4gfCAgICAgLy8gZm9yIHRoZSBkcmFnIHNlcXVlbmNlIHRvIHN0YXJ0XHJcbiB8ICAgICAvLyAneHknIGJ5IGRlZmF1bHQgLSBhbnkgZGlyZWN0aW9uXHJcbiB8ICAgICBzdGFydEF4aXM6ICd4JyB8fCAneScgfHwgJ3h5JyxcclxuIHxcclxuIHwgICAgIC8vICd4eScgYnkgZGVmYXVsdCAtIGRvbid0IHJlc3RyaWN0IHRvIG9uZSBheGlzIChtb3ZlIGluIGFueSBkaXJlY3Rpb24pXHJcbiB8ICAgICAvLyAneCcgb3IgJ3knIHRvIHJlc3RyaWN0IG1vdmVtZW50IHRvIGVpdGhlciBheGlzXHJcbiB8ICAgICAvLyAnc3RhcnQnIHRvIHJlc3RyaWN0IG1vdmVtZW50IHRvIHRoZSBheGlzIHRoZSBkcmFnIHN0YXJ0ZWQgaW5cclxuIHwgICAgIGxvY2tBeGlzOiAneCcgfHwgJ3knIHx8ICd4eScgfHwgJ3N0YXJ0JyxcclxuIHxcclxuIHwgICAgIC8vIG1heCBudW1iZXIgb2YgZHJhZ3MgdGhhdCBjYW4gaGFwcGVuIGNvbmN1cnJlbnRseVxyXG4gfCAgICAgLy8gd2l0aCBlbGVtZW50cyBvZiB0aGlzIEludGVyYWN0YWJsZS4gSW5maW5pdHkgYnkgZGVmYXVsdFxyXG4gfCAgICAgbWF4OiBJbmZpbml0eSxcclxuIHxcclxuIHwgICAgIC8vIG1heCBudW1iZXIgb2YgZHJhZ3MgdGhhdCBjYW4gdGFyZ2V0IHRoZSBzYW1lIGVsZW1lbnQrSW50ZXJhY3RhYmxlXHJcbiB8ICAgICAvLyAxIGJ5IGRlZmF1bHRcclxuIHwgICAgIG1heFBlckVsZW1lbnQ6IDJcclxuIHwgfSk7XHJcblxcKi9cclxuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5kcmFnZ2FibGUgPSBmdW5jdGlvbiAob3B0aW9ucykge1xyXG4gIGlmICh1dGlscy5pcy5vYmplY3Qob3B0aW9ucykpIHtcclxuICAgIHRoaXMub3B0aW9ucy5kcmFnLmVuYWJsZWQgPSBvcHRpb25zLmVuYWJsZWQgPT09IGZhbHNlID8gZmFsc2UgOiB0cnVlO1xyXG4gICAgdGhpcy5zZXRQZXJBY3Rpb24oJ2RyYWcnLCBvcHRpb25zKTtcclxuICAgIHRoaXMuc2V0T25FdmVudHMoJ2RyYWcnLCBvcHRpb25zKTtcclxuXHJcbiAgICBpZiAoL14oeHl8eHx5fHN0YXJ0KSQvLnRlc3Qob3B0aW9ucy5sb2NrQXhpcykpIHtcclxuICAgICAgdGhpcy5vcHRpb25zLmRyYWcubG9ja0F4aXMgPSBvcHRpb25zLmxvY2tBeGlzO1xyXG4gICAgfVxyXG4gICAgaWYgKC9eKHh5fHh8eSkkLy50ZXN0KG9wdGlvbnMuc3RhcnRBeGlzKSkge1xyXG4gICAgICB0aGlzLm9wdGlvbnMuZHJhZy5zdGFydEF4aXMgPSBvcHRpb25zLnN0YXJ0QXhpcztcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIGlmICh1dGlscy5pcy5ib29sKG9wdGlvbnMpKSB7XHJcbiAgICB0aGlzLm9wdGlvbnMuZHJhZy5lbmFibGVkID0gb3B0aW9ucztcclxuXHJcbiAgICBpZiAoIW9wdGlvbnMpIHtcclxuICAgICAgdGhpcy5vbmRyYWdzdGFydCA9IHRoaXMub25kcmFnc3RhcnQgPSB0aGlzLm9uZHJhZ2VuZCA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gdGhpcy5vcHRpb25zLmRyYWc7XHJcbn07XHJcblxyXG5hY3Rpb25zLmRyYWcgPSBkcmFnO1xyXG5hY3Rpb25zLm5hbWVzLnB1c2goJ2RyYWcnKTtcclxudXRpbHMubWVyZ2UoSW50ZXJhY3RhYmxlLmV2ZW50VHlwZXMsIFsnZHJhZ3N0YXJ0JywgJ2RyYWdtb3ZlJywgJ2RyYWdpbmVydGlhc3RhcnQnLCAnZHJhZ2luZXJ0aWFyZXN1bWUnLCAnZHJhZ2VuZCddKTtcclxuYWN0aW9ucy5tZXRob2REaWN0LmRyYWcgPSAnZHJhZ2dhYmxlJztcclxuXHJcbmRlZmF1bHRPcHRpb25zLmRyYWcgPSBkcmFnLmRlZmF1bHRzO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBkcmFnO1xyXG5cclxufSx7XCIuLi9JbnRlcmFjdEV2ZW50XCI6MyxcIi4uL0ludGVyYWN0YWJsZVwiOjQsXCIuLi9JbnRlcmFjdGlvblwiOjUsXCIuLi9kZWZhdWx0T3B0aW9uc1wiOjE4LFwiLi4vdXRpbHNcIjo0NCxcIi4vYmFzZVwiOjZ9XSw4OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGFjdGlvbnMgPSByZXF1aXJlKCcuL2Jhc2UnKTtcclxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcclxudmFyIHNjb3BlID0gcmVxdWlyZSgnLi4vc2NvcGUnKTtcclxudmFyIGludGVyYWN0ID0gcmVxdWlyZSgnLi4vaW50ZXJhY3QnKTtcclxudmFyIEludGVyYWN0RXZlbnQgPSByZXF1aXJlKCcuLi9JbnRlcmFjdEV2ZW50Jyk7XHJcbnZhciBJbnRlcmFjdGFibGUgPSByZXF1aXJlKCcuLi9JbnRlcmFjdGFibGUnKTtcclxudmFyIEludGVyYWN0aW9uID0gcmVxdWlyZSgnLi4vSW50ZXJhY3Rpb24nKTtcclxudmFyIGRlZmF1bHRPcHRpb25zID0gcmVxdWlyZSgnLi4vZGVmYXVsdE9wdGlvbnMnKTtcclxuXHJcbnZhciBkcm9wID0ge1xyXG4gIGRlZmF1bHRzOiB7XHJcbiAgICBlbmFibGVkOiBmYWxzZSxcclxuICAgIGFjY2VwdDogbnVsbCxcclxuICAgIG92ZXJsYXA6ICdwb2ludGVyJ1xyXG4gIH1cclxufTtcclxuXHJcbnZhciBkeW5hbWljRHJvcCA9IGZhbHNlO1xyXG5cclxuSW50ZXJhY3Rpb24uc2lnbmFscy5vbignYWN0aW9uLXN0YXJ0JywgZnVuY3Rpb24gKF9yZWYpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmLmludGVyYWN0aW9uLFxyXG4gICAgICBldmVudCA9IF9yZWYuZXZlbnQ7XHJcblxyXG4gIGlmIChpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lICE9PSAnZHJhZycpIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIC8vIHJlc2V0IGFjdGl2ZSBkcm9wem9uZXNcclxuICBpbnRlcmFjdGlvbi5hY3RpdmVEcm9wcy5kcm9wem9uZXMgPSBbXTtcclxuICBpbnRlcmFjdGlvbi5hY3RpdmVEcm9wcy5lbGVtZW50cyA9IFtdO1xyXG4gIGludGVyYWN0aW9uLmFjdGl2ZURyb3BzLnJlY3RzID0gW107XHJcblxyXG4gIGludGVyYWN0aW9uLmRyb3BFdmVudHMgPSBudWxsO1xyXG5cclxuICBpZiAoIWludGVyYWN0aW9uLmR5bmFtaWNEcm9wKSB7XHJcbiAgICBzZXRBY3RpdmVEcm9wcyhpbnRlcmFjdGlvbiwgaW50ZXJhY3Rpb24uZWxlbWVudCk7XHJcbiAgfVxyXG5cclxuICB2YXIgZHJhZ0V2ZW50ID0gaW50ZXJhY3Rpb24ucHJldkV2ZW50O1xyXG4gIHZhciBkcm9wRXZlbnRzID0gZ2V0RHJvcEV2ZW50cyhpbnRlcmFjdGlvbiwgZXZlbnQsIGRyYWdFdmVudCk7XHJcblxyXG4gIGlmIChkcm9wRXZlbnRzLmFjdGl2YXRlKSB7XHJcbiAgICBmaXJlQWN0aXZlRHJvcHMoaW50ZXJhY3Rpb24sIGRyb3BFdmVudHMuYWN0aXZhdGUpO1xyXG4gIH1cclxufSk7XHJcblxyXG5JbnRlcmFjdEV2ZW50LnNpZ25hbHMub24oJ25ldycsIGZ1bmN0aW9uIChfcmVmMikge1xyXG4gIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYyLmludGVyYWN0aW9uLFxyXG4gICAgICBpRXZlbnQgPSBfcmVmMi5pRXZlbnQsXHJcbiAgICAgIGV2ZW50ID0gX3JlZjIuZXZlbnQ7XHJcblxyXG4gIGlmIChpRXZlbnQudHlwZSAhPT0gJ2RyYWdtb3ZlJyAmJiBpRXZlbnQudHlwZSAhPT0gJ2RyYWdlbmQnKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICB2YXIgZHJhZ2dhYmxlRWxlbWVudCA9IGludGVyYWN0aW9uLmVsZW1lbnQ7XHJcbiAgdmFyIGRyYWdFdmVudCA9IGlFdmVudDtcclxuICB2YXIgZHJvcFJlc3VsdCA9IGdldERyb3AoZHJhZ0V2ZW50LCBldmVudCwgZHJhZ2dhYmxlRWxlbWVudCk7XHJcblxyXG4gIGludGVyYWN0aW9uLmRyb3BUYXJnZXQgPSBkcm9wUmVzdWx0LmRyb3B6b25lO1xyXG4gIGludGVyYWN0aW9uLmRyb3BFbGVtZW50ID0gZHJvcFJlc3VsdC5lbGVtZW50O1xyXG5cclxuICBpbnRlcmFjdGlvbi5kcm9wRXZlbnRzID0gZ2V0RHJvcEV2ZW50cyhpbnRlcmFjdGlvbiwgZXZlbnQsIGRyYWdFdmVudCk7XHJcbn0pO1xyXG5cclxuSW50ZXJhY3Rpb24uc2lnbmFscy5vbignYWN0aW9uLW1vdmUnLCBmdW5jdGlvbiAoX3JlZjMpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmMy5pbnRlcmFjdGlvbjtcclxuXHJcbiAgaWYgKGludGVyYWN0aW9uLnByZXBhcmVkLm5hbWUgIT09ICdkcmFnJykge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgZmlyZURyb3BFdmVudHMoaW50ZXJhY3Rpb24sIGludGVyYWN0aW9uLmRyb3BFdmVudHMpO1xyXG59KTtcclxuXHJcbkludGVyYWN0aW9uLnNpZ25hbHMub24oJ2FjdGlvbi1lbmQnLCBmdW5jdGlvbiAoX3JlZjQpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmNC5pbnRlcmFjdGlvbjtcclxuXHJcbiAgaWYgKGludGVyYWN0aW9uLnByZXBhcmVkLm5hbWUgPT09ICdkcmFnJykge1xyXG4gICAgZmlyZURyb3BFdmVudHMoaW50ZXJhY3Rpb24sIGludGVyYWN0aW9uLmRyb3BFdmVudHMpO1xyXG4gIH1cclxufSk7XHJcblxyXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdzdG9wLWRyYWcnLCBmdW5jdGlvbiAoX3JlZjUpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmNS5pbnRlcmFjdGlvbjtcclxuXHJcbiAgaW50ZXJhY3Rpb24uYWN0aXZlRHJvcHMuZHJvcHpvbmVzID0gaW50ZXJhY3Rpb24uYWN0aXZlRHJvcHMuZWxlbWVudHMgPSBpbnRlcmFjdGlvbi5hY3RpdmVEcm9wcy5yZWN0cyA9IGludGVyYWN0aW9uLmRyb3BFdmVudHMgPSBudWxsO1xyXG59KTtcclxuXHJcbmZ1bmN0aW9uIGNvbGxlY3REcm9wcyhpbnRlcmFjdGlvbiwgZWxlbWVudCkge1xyXG4gIHZhciBkcm9wcyA9IFtdO1xyXG4gIHZhciBlbGVtZW50cyA9IFtdO1xyXG5cclxuICBlbGVtZW50ID0gZWxlbWVudCB8fCBpbnRlcmFjdGlvbi5lbGVtZW50O1xyXG5cclxuICAvLyBjb2xsZWN0IGFsbCBkcm9wem9uZXMgYW5kIHRoZWlyIGVsZW1lbnRzIHdoaWNoIHF1YWxpZnkgZm9yIGEgZHJvcFxyXG4gIGZvciAodmFyIF9pdGVyYXRvciA9IHNjb3BlLmludGVyYWN0YWJsZXMsIF9pc0FycmF5ID0gQXJyYXkuaXNBcnJheShfaXRlcmF0b3IpLCBfaSA9IDAsIF9pdGVyYXRvciA9IF9pc0FycmF5ID8gX2l0ZXJhdG9yIDogX2l0ZXJhdG9yW1N5bWJvbC5pdGVyYXRvcl0oKTs7KSB7XHJcbiAgICB2YXIgX3JlZjY7XHJcblxyXG4gICAgaWYgKF9pc0FycmF5KSB7XHJcbiAgICAgIGlmIChfaSA+PSBfaXRlcmF0b3IubGVuZ3RoKSBicmVhaztcclxuICAgICAgX3JlZjYgPSBfaXRlcmF0b3JbX2krK107XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBfaSA9IF9pdGVyYXRvci5uZXh0KCk7XHJcbiAgICAgIGlmIChfaS5kb25lKSBicmVhaztcclxuICAgICAgX3JlZjYgPSBfaS52YWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgY3VycmVudCA9IF9yZWY2O1xyXG5cclxuICAgIGlmICghY3VycmVudC5vcHRpb25zLmRyb3AuZW5hYmxlZCkge1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgYWNjZXB0ID0gY3VycmVudC5vcHRpb25zLmRyb3AuYWNjZXB0O1xyXG5cclxuICAgIC8vIHRlc3QgdGhlIGRyYWdnYWJsZSBlbGVtZW50IGFnYWluc3QgdGhlIGRyb3B6b25lJ3MgYWNjZXB0IHNldHRpbmdcclxuICAgIGlmICh1dGlscy5pcy5lbGVtZW50KGFjY2VwdCkgJiYgYWNjZXB0ICE9PSBlbGVtZW50IHx8IHV0aWxzLmlzLnN0cmluZyhhY2NlcHQpICYmICF1dGlscy5tYXRjaGVzU2VsZWN0b3IoZWxlbWVudCwgYWNjZXB0KSkge1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gcXVlcnkgZm9yIG5ldyBlbGVtZW50cyBpZiBuZWNlc3NhcnlcclxuICAgIHZhciBkcm9wRWxlbWVudHMgPSB1dGlscy5pcy5zdHJpbmcoY3VycmVudC50YXJnZXQpID8gY3VycmVudC5fY29udGV4dC5xdWVyeVNlbGVjdG9yQWxsKGN1cnJlbnQudGFyZ2V0KSA6IFtjdXJyZW50LnRhcmdldF07XHJcblxyXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkcm9wRWxlbWVudHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgdmFyIGN1cnJlbnRFbGVtZW50ID0gZHJvcEVsZW1lbnRzW2ldO1xyXG5cclxuICAgICAgaWYgKGN1cnJlbnRFbGVtZW50ICE9PSBlbGVtZW50KSB7XHJcbiAgICAgICAgZHJvcHMucHVzaChjdXJyZW50KTtcclxuICAgICAgICBlbGVtZW50cy5wdXNoKGN1cnJlbnRFbGVtZW50KTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcmV0dXJuIHtcclxuICAgIGVsZW1lbnRzOiBlbGVtZW50cyxcclxuICAgIGRyb3B6b25lczogZHJvcHNcclxuICB9O1xyXG59XHJcblxyXG5mdW5jdGlvbiBmaXJlQWN0aXZlRHJvcHMoaW50ZXJhY3Rpb24sIGV2ZW50KSB7XHJcbiAgdmFyIHByZXZFbGVtZW50ID0gdm9pZCAwO1xyXG5cclxuICAvLyBsb29wIHRocm91Z2ggYWxsIGFjdGl2ZSBkcm9wem9uZXMgYW5kIHRyaWdnZXIgZXZlbnRcclxuICBmb3IgKHZhciBpID0gMDsgaSA8IGludGVyYWN0aW9uLmFjdGl2ZURyb3BzLmRyb3B6b25lcy5sZW5ndGg7IGkrKykge1xyXG4gICAgdmFyIGN1cnJlbnQgPSBpbnRlcmFjdGlvbi5hY3RpdmVEcm9wcy5kcm9wem9uZXNbaV07XHJcbiAgICB2YXIgY3VycmVudEVsZW1lbnQgPSBpbnRlcmFjdGlvbi5hY3RpdmVEcm9wcy5lbGVtZW50c1tpXTtcclxuXHJcbiAgICAvLyBwcmV2ZW50IHRyaWdnZXIgb2YgZHVwbGljYXRlIGV2ZW50cyBvbiBzYW1lIGVsZW1lbnRcclxuICAgIGlmIChjdXJyZW50RWxlbWVudCAhPT0gcHJldkVsZW1lbnQpIHtcclxuICAgICAgLy8gc2V0IGN1cnJlbnQgZWxlbWVudCBhcyBldmVudCB0YXJnZXRcclxuICAgICAgZXZlbnQudGFyZ2V0ID0gY3VycmVudEVsZW1lbnQ7XHJcbiAgICAgIGN1cnJlbnQuZmlyZShldmVudCk7XHJcbiAgICB9XHJcbiAgICBwcmV2RWxlbWVudCA9IGN1cnJlbnRFbGVtZW50O1xyXG4gIH1cclxufVxyXG5cclxuLy8gQ29sbGVjdCBhIG5ldyBzZXQgb2YgcG9zc2libGUgZHJvcHMgYW5kIHNhdmUgdGhlbSBpbiBhY3RpdmVEcm9wcy5cclxuLy8gc2V0QWN0aXZlRHJvcHMgc2hvdWxkIGFsd2F5cyBiZSBjYWxsZWQgd2hlbiBhIGRyYWcgaGFzIGp1c3Qgc3RhcnRlZCBvciBhXHJcbi8vIGRyYWcgZXZlbnQgaGFwcGVucyB3aGlsZSBkeW5hbWljRHJvcCBpcyB0cnVlXHJcbmZ1bmN0aW9uIHNldEFjdGl2ZURyb3BzKGludGVyYWN0aW9uLCBkcmFnRWxlbWVudCkge1xyXG4gIC8vIGdldCBkcm9wem9uZXMgYW5kIHRoZWlyIGVsZW1lbnRzIHRoYXQgY291bGQgcmVjZWl2ZSB0aGUgZHJhZ2dhYmxlXHJcbiAgdmFyIHBvc3NpYmxlRHJvcHMgPSBjb2xsZWN0RHJvcHMoaW50ZXJhY3Rpb24sIGRyYWdFbGVtZW50LCB0cnVlKTtcclxuXHJcbiAgaW50ZXJhY3Rpb24uYWN0aXZlRHJvcHMuZHJvcHpvbmVzID0gcG9zc2libGVEcm9wcy5kcm9wem9uZXM7XHJcbiAgaW50ZXJhY3Rpb24uYWN0aXZlRHJvcHMuZWxlbWVudHMgPSBwb3NzaWJsZURyb3BzLmVsZW1lbnRzO1xyXG4gIGludGVyYWN0aW9uLmFjdGl2ZURyb3BzLnJlY3RzID0gW107XHJcblxyXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgaW50ZXJhY3Rpb24uYWN0aXZlRHJvcHMuZHJvcHpvbmVzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICBpbnRlcmFjdGlvbi5hY3RpdmVEcm9wcy5yZWN0c1tpXSA9IGludGVyYWN0aW9uLmFjdGl2ZURyb3BzLmRyb3B6b25lc1tpXS5nZXRSZWN0KGludGVyYWN0aW9uLmFjdGl2ZURyb3BzLmVsZW1lbnRzW2ldKTtcclxuICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldERyb3AoZHJhZ0V2ZW50LCBldmVudCwgZHJhZ0VsZW1lbnQpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBkcmFnRXZlbnQuaW50ZXJhY3Rpb247XHJcbiAgdmFyIHZhbGlkRHJvcHMgPSBbXTtcclxuXHJcbiAgaWYgKGR5bmFtaWNEcm9wKSB7XHJcbiAgICBzZXRBY3RpdmVEcm9wcyhpbnRlcmFjdGlvbiwgZHJhZ0VsZW1lbnQpO1xyXG4gIH1cclxuXHJcbiAgLy8gY29sbGVjdCBhbGwgZHJvcHpvbmVzIGFuZCB0aGVpciBlbGVtZW50cyB3aGljaCBxdWFsaWZ5IGZvciBhIGRyb3BcclxuICBmb3IgKHZhciBqID0gMDsgaiA8IGludGVyYWN0aW9uLmFjdGl2ZURyb3BzLmRyb3B6b25lcy5sZW5ndGg7IGorKykge1xyXG4gICAgdmFyIGN1cnJlbnQgPSBpbnRlcmFjdGlvbi5hY3RpdmVEcm9wcy5kcm9wem9uZXNbal07XHJcbiAgICB2YXIgY3VycmVudEVsZW1lbnQgPSBpbnRlcmFjdGlvbi5hY3RpdmVEcm9wcy5lbGVtZW50c1tqXTtcclxuICAgIHZhciByZWN0ID0gaW50ZXJhY3Rpb24uYWN0aXZlRHJvcHMucmVjdHNbal07XHJcblxyXG4gICAgdmFsaWREcm9wcy5wdXNoKGN1cnJlbnQuZHJvcENoZWNrKGRyYWdFdmVudCwgZXZlbnQsIGludGVyYWN0aW9uLnRhcmdldCwgZHJhZ0VsZW1lbnQsIGN1cnJlbnRFbGVtZW50LCByZWN0KSA/IGN1cnJlbnRFbGVtZW50IDogbnVsbCk7XHJcbiAgfVxyXG5cclxuICAvLyBnZXQgdGhlIG1vc3QgYXBwcm9wcmlhdGUgZHJvcHpvbmUgYmFzZWQgb24gRE9NIGRlcHRoIGFuZCBvcmRlclxyXG4gIHZhciBkcm9wSW5kZXggPSB1dGlscy5pbmRleE9mRGVlcGVzdEVsZW1lbnQodmFsaWREcm9wcyk7XHJcblxyXG4gIHJldHVybiB7XHJcbiAgICBkcm9wem9uZTogaW50ZXJhY3Rpb24uYWN0aXZlRHJvcHMuZHJvcHpvbmVzW2Ryb3BJbmRleF0gfHwgbnVsbCxcclxuICAgIGVsZW1lbnQ6IGludGVyYWN0aW9uLmFjdGl2ZURyb3BzLmVsZW1lbnRzW2Ryb3BJbmRleF0gfHwgbnVsbFxyXG4gIH07XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldERyb3BFdmVudHMoaW50ZXJhY3Rpb24sIHBvaW50ZXJFdmVudCwgZHJhZ0V2ZW50KSB7XHJcbiAgdmFyIGRyb3BFdmVudHMgPSB7XHJcbiAgICBlbnRlcjogbnVsbCxcclxuICAgIGxlYXZlOiBudWxsLFxyXG4gICAgYWN0aXZhdGU6IG51bGwsXHJcbiAgICBkZWFjdGl2YXRlOiBudWxsLFxyXG4gICAgbW92ZTogbnVsbCxcclxuICAgIGRyb3A6IG51bGxcclxuICB9O1xyXG5cclxuICB2YXIgdG1wbCA9IHtcclxuICAgIGRyYWdFdmVudDogZHJhZ0V2ZW50LFxyXG4gICAgaW50ZXJhY3Rpb246IGludGVyYWN0aW9uLFxyXG4gICAgdGFyZ2V0OiBpbnRlcmFjdGlvbi5kcm9wRWxlbWVudCxcclxuICAgIGRyb3B6b25lOiBpbnRlcmFjdGlvbi5kcm9wVGFyZ2V0LFxyXG4gICAgcmVsYXRlZFRhcmdldDogZHJhZ0V2ZW50LnRhcmdldCxcclxuICAgIGRyYWdnYWJsZTogZHJhZ0V2ZW50LmludGVyYWN0YWJsZSxcclxuICAgIHRpbWVTdGFtcDogZHJhZ0V2ZW50LnRpbWVTdGFtcFxyXG4gIH07XHJcblxyXG4gIGlmIChpbnRlcmFjdGlvbi5kcm9wRWxlbWVudCAhPT0gaW50ZXJhY3Rpb24ucHJldkRyb3BFbGVtZW50KSB7XHJcbiAgICAvLyBpZiB0aGVyZSB3YXMgYSBwcmV2RHJvcFRhcmdldCwgY3JlYXRlIGEgZHJhZ2xlYXZlIGV2ZW50XHJcbiAgICBpZiAoaW50ZXJhY3Rpb24ucHJldkRyb3BUYXJnZXQpIHtcclxuICAgICAgZHJvcEV2ZW50cy5sZWF2ZSA9IHV0aWxzLmV4dGVuZCh7IHR5cGU6ICdkcmFnbGVhdmUnIH0sIHRtcGwpO1xyXG5cclxuICAgICAgZHJhZ0V2ZW50LmRyYWdMZWF2ZSA9IGRyb3BFdmVudHMubGVhdmUudGFyZ2V0ID0gaW50ZXJhY3Rpb24ucHJldkRyb3BFbGVtZW50O1xyXG4gICAgICBkcmFnRXZlbnQucHJldkRyb3B6b25lID0gZHJvcEV2ZW50cy5sZWF2ZS5kcm9wem9uZSA9IGludGVyYWN0aW9uLnByZXZEcm9wVGFyZ2V0O1xyXG4gICAgfVxyXG4gICAgLy8gaWYgdGhlIGRyb3BUYXJnZXQgaXMgbm90IG51bGwsIGNyZWF0ZSBhIGRyYWdlbnRlciBldmVudFxyXG4gICAgaWYgKGludGVyYWN0aW9uLmRyb3BUYXJnZXQpIHtcclxuICAgICAgZHJvcEV2ZW50cy5lbnRlciA9IHtcclxuICAgICAgICBkcmFnRXZlbnQ6IGRyYWdFdmVudCxcclxuICAgICAgICBpbnRlcmFjdGlvbjogaW50ZXJhY3Rpb24sXHJcbiAgICAgICAgdGFyZ2V0OiBpbnRlcmFjdGlvbi5kcm9wRWxlbWVudCxcclxuICAgICAgICBkcm9wem9uZTogaW50ZXJhY3Rpb24uZHJvcFRhcmdldCxcclxuICAgICAgICByZWxhdGVkVGFyZ2V0OiBkcmFnRXZlbnQudGFyZ2V0LFxyXG4gICAgICAgIGRyYWdnYWJsZTogZHJhZ0V2ZW50LmludGVyYWN0YWJsZSxcclxuICAgICAgICB0aW1lU3RhbXA6IGRyYWdFdmVudC50aW1lU3RhbXAsXHJcbiAgICAgICAgdHlwZTogJ2RyYWdlbnRlcidcclxuICAgICAgfTtcclxuXHJcbiAgICAgIGRyYWdFdmVudC5kcmFnRW50ZXIgPSBpbnRlcmFjdGlvbi5kcm9wRWxlbWVudDtcclxuICAgICAgZHJhZ0V2ZW50LmRyb3B6b25lID0gaW50ZXJhY3Rpb24uZHJvcFRhcmdldDtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGlmIChkcmFnRXZlbnQudHlwZSA9PT0gJ2RyYWdlbmQnICYmIGludGVyYWN0aW9uLmRyb3BUYXJnZXQpIHtcclxuICAgIGRyb3BFdmVudHMuZHJvcCA9IHV0aWxzLmV4dGVuZCh7IHR5cGU6ICdkcm9wJyB9LCB0bXBsKTtcclxuXHJcbiAgICBkcmFnRXZlbnQuZHJvcHpvbmUgPSBpbnRlcmFjdGlvbi5kcm9wVGFyZ2V0O1xyXG4gICAgZHJhZ0V2ZW50LnJlbGF0ZWRUYXJnZXQgPSBpbnRlcmFjdGlvbi5kcm9wRWxlbWVudDtcclxuICB9XHJcbiAgaWYgKGRyYWdFdmVudC50eXBlID09PSAnZHJhZ3N0YXJ0Jykge1xyXG4gICAgZHJvcEV2ZW50cy5hY3RpdmF0ZSA9IHV0aWxzLmV4dGVuZCh7IHR5cGU6ICdkcm9wYWN0aXZhdGUnIH0sIHRtcGwpO1xyXG5cclxuICAgIGRyb3BFdmVudHMuYWN0aXZhdGUudGFyZ2V0ID0gbnVsbDtcclxuICAgIGRyb3BFdmVudHMuYWN0aXZhdGUuZHJvcHpvbmUgPSBudWxsO1xyXG4gIH1cclxuICBpZiAoZHJhZ0V2ZW50LnR5cGUgPT09ICdkcmFnZW5kJykge1xyXG4gICAgZHJvcEV2ZW50cy5kZWFjdGl2YXRlID0gdXRpbHMuZXh0ZW5kKHsgdHlwZTogJ2Ryb3BkZWFjdGl2YXRlJyB9LCB0bXBsKTtcclxuXHJcbiAgICBkcm9wRXZlbnRzLmRlYWN0aXZhdGUudGFyZ2V0ID0gbnVsbDtcclxuICAgIGRyb3BFdmVudHMuZGVhY3RpdmF0ZS5kcm9wem9uZSA9IG51bGw7XHJcbiAgfVxyXG4gIGlmIChkcmFnRXZlbnQudHlwZSA9PT0gJ2RyYWdtb3ZlJyAmJiBpbnRlcmFjdGlvbi5kcm9wVGFyZ2V0KSB7XHJcbiAgICBkcm9wRXZlbnRzLm1vdmUgPSB1dGlscy5leHRlbmQoe1xyXG4gICAgICBkcmFnbW92ZTogZHJhZ0V2ZW50LFxyXG4gICAgICB0eXBlOiAnZHJvcG1vdmUnXHJcbiAgICB9LCB0bXBsKTtcclxuXHJcbiAgICBkcmFnRXZlbnQuZHJvcHpvbmUgPSBpbnRlcmFjdGlvbi5kcm9wVGFyZ2V0O1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIGRyb3BFdmVudHM7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGZpcmVEcm9wRXZlbnRzKGludGVyYWN0aW9uLCBkcm9wRXZlbnRzKSB7XHJcbiAgaWYgKGRyb3BFdmVudHMubGVhdmUpIHtcclxuICAgIGludGVyYWN0aW9uLnByZXZEcm9wVGFyZ2V0LmZpcmUoZHJvcEV2ZW50cy5sZWF2ZSk7XHJcbiAgfVxyXG4gIGlmIChkcm9wRXZlbnRzLm1vdmUpIHtcclxuICAgIGludGVyYWN0aW9uLmRyb3BUYXJnZXQuZmlyZShkcm9wRXZlbnRzLm1vdmUpO1xyXG4gIH1cclxuICBpZiAoZHJvcEV2ZW50cy5lbnRlcikge1xyXG4gICAgaW50ZXJhY3Rpb24uZHJvcFRhcmdldC5maXJlKGRyb3BFdmVudHMuZW50ZXIpO1xyXG4gIH1cclxuICBpZiAoZHJvcEV2ZW50cy5kcm9wKSB7XHJcbiAgICBpbnRlcmFjdGlvbi5kcm9wVGFyZ2V0LmZpcmUoZHJvcEV2ZW50cy5kcm9wKTtcclxuICB9XHJcbiAgaWYgKGRyb3BFdmVudHMuZGVhY3RpdmF0ZSkge1xyXG4gICAgZmlyZUFjdGl2ZURyb3BzKGludGVyYWN0aW9uLCBkcm9wRXZlbnRzLmRlYWN0aXZhdGUpO1xyXG4gIH1cclxuXHJcbiAgaW50ZXJhY3Rpb24ucHJldkRyb3BUYXJnZXQgPSBpbnRlcmFjdGlvbi5kcm9wVGFyZ2V0O1xyXG4gIGludGVyYWN0aW9uLnByZXZEcm9wRWxlbWVudCA9IGludGVyYWN0aW9uLmRyb3BFbGVtZW50O1xyXG59XHJcblxyXG4vKlxcXHJcbiAqIEludGVyYWN0YWJsZS5kcm9wem9uZVxyXG4gWyBtZXRob2QgXVxyXG4gKlxyXG4gKiBSZXR1cm5zIG9yIHNldHMgd2hldGhlciBlbGVtZW50cyBjYW4gYmUgZHJvcHBlZCBvbnRvIHRoaXNcclxuICogSW50ZXJhY3RhYmxlIHRvIHRyaWdnZXIgZHJvcCBldmVudHNcclxuICpcclxuICogRHJvcHpvbmVzIGNhbiByZWNlaXZlIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxyXG4gKiAgLSBgZHJvcGFjdGl2YXRlYCBhbmQgYGRyb3BkZWFjdGl2YXRlYCB3aGVuIGFuIGFjY2VwdGFibGUgZHJhZyBzdGFydHMgYW5kIGVuZHNcclxuICogIC0gYGRyYWdlbnRlcmAgYW5kIGBkcmFnbGVhdmVgIHdoZW4gYSBkcmFnZ2FibGUgZW50ZXJzIGFuZCBsZWF2ZXMgdGhlIGRyb3B6b25lXHJcbiAqICAtIGBkcmFnbW92ZWAgd2hlbiBhIGRyYWdnYWJsZSB0aGF0IGhhcyBlbnRlcmVkIHRoZSBkcm9wem9uZSBpcyBtb3ZlZFxyXG4gKiAgLSBgZHJvcGAgd2hlbiBhIGRyYWdnYWJsZSBpcyBkcm9wcGVkIGludG8gdGhpcyBkcm9wem9uZVxyXG4gKlxyXG4gKiBVc2UgdGhlIGBhY2NlcHRgIG9wdGlvbiB0byBhbGxvdyBvbmx5IGVsZW1lbnRzIHRoYXQgbWF0Y2ggdGhlIGdpdmVuIENTU1xyXG4gKiBzZWxlY3RvciBvciBlbGVtZW50LiBUaGUgdmFsdWUgY2FuIGJlOlxyXG4gKlxyXG4gKiAgLSAqKmFuIEVsZW1lbnQqKiAtIG9ubHkgdGhhdCBlbGVtZW50IGNhbiBiZSBkcm9wcGVkIGludG8gdGhpcyBkcm9wem9uZS5cclxuICogIC0gKiphIHN0cmluZyoqLCAtIHRoZSBlbGVtZW50IGJlaW5nIGRyYWdnZWQgbXVzdCBtYXRjaCBpdCBhcyBhIENTUyBzZWxlY3Rvci5cclxuICogIC0gKipgbnVsbGAqKiAtIGFjY2VwdCBvcHRpb25zIGlzIGNsZWFyZWQgLSBpdCBhY2NlcHRzIGFueSBlbGVtZW50LlxyXG4gKlxyXG4gKiBVc2UgdGhlIGBvdmVybGFwYCBvcHRpb24gdG8gc2V0IGhvdyBkcm9wcyBhcmUgY2hlY2tlZCBmb3IuIFRoZSBhbGxvd2VkXHJcbiAqIHZhbHVlcyBhcmU6XHJcbiAqXHJcbiAqICAgLSBgJ3BvaW50ZXInYCwgdGhlIHBvaW50ZXIgbXVzdCBiZSBvdmVyIHRoZSBkcm9wem9uZSAoZGVmYXVsdClcclxuICogICAtIGAnY2VudGVyJ2AsIHRoZSBkcmFnZ2FibGUgZWxlbWVudCdzIGNlbnRlciBtdXN0IGJlIG92ZXIgdGhlIGRyb3B6b25lXHJcbiAqICAgLSBhIG51bWJlciBmcm9tIDAtMSB3aGljaCBpcyB0aGUgYChpbnRlcnNlY3Rpb24gYXJlYSkgLyAoZHJhZ2dhYmxlIGFyZWEpYC5cclxuICogICBlLmcuIGAwLjVgIGZvciBkcm9wIHRvIGhhcHBlbiB3aGVuIGhhbGYgb2YgdGhlIGFyZWEgb2YgdGhlIGRyYWdnYWJsZSBpc1xyXG4gKiAgIG92ZXIgdGhlIGRyb3B6b25lXHJcbiAqXHJcbiAqIFVzZSB0aGUgYGNoZWNrZXJgIG9wdGlvbiB0byBzcGVjaWZ5IGEgZnVuY3Rpb24gdG8gY2hlY2sgaWYgYSBkcmFnZ2VkXHJcbiAqIGVsZW1lbnQgaXMgb3ZlciB0aGlzIEludGVyYWN0YWJsZS5cclxuICpcclxuIHwgaW50ZXJhY3QodGFyZ2V0KVxyXG4gfCAuZHJvcENoZWNrZXIoZnVuY3Rpb24oZHJhZ0V2ZW50LCAgICAgICAgIC8vIHJlbGF0ZWQgZHJhZ21vdmUgb3IgZHJhZ2VuZCBldmVudFxyXG4gfCAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQsICAgICAgICAgICAgIC8vIFRvdWNoRXZlbnQvUG9pbnRlckV2ZW50L01vdXNlRXZlbnRcclxuIHwgICAgICAgICAgICAgICAgICAgICAgIGRyb3BwZWQsICAgICAgICAgICAvLyBib29sIHJlc3VsdCBvZiB0aGUgZGVmYXVsdCBjaGVja2VyXHJcbiB8ICAgICAgICAgICAgICAgICAgICAgICBkcm9wem9uZSwgICAgICAgICAgLy8gZHJvcHpvbmUgSW50ZXJhY3RhYmxlXHJcbiB8ICAgICAgICAgICAgICAgICAgICAgICBkcm9wRWxlbWVudCwgICAgICAgLy8gZHJvcHpvbmUgZWxlbW50XHJcbiB8ICAgICAgICAgICAgICAgICAgICAgICBkcmFnZ2FibGUsICAgICAgICAgLy8gZHJhZ2dhYmxlIEludGVyYWN0YWJsZVxyXG4gfCAgICAgICAgICAgICAgICAgICAgICAgZHJhZ2dhYmxlRWxlbWVudCkgey8vIGRyYWdnYWJsZSBlbGVtZW50XHJcbiB8XHJcbiB8ICAgcmV0dXJuIGRyb3BwZWQgJiYgZXZlbnQudGFyZ2V0Lmhhc0F0dHJpYnV0ZSgnYWxsb3ctZHJvcCcpO1xyXG4gfCB9XHJcbiAqXHJcbiAqXHJcbiAtIG9wdGlvbnMgKGJvb2xlYW4gfCBvYmplY3QgfCBudWxsKSAjb3B0aW9uYWwgVGhlIG5ldyB2YWx1ZSB0byBiZSBzZXQuXHJcbiB8IGludGVyYWN0KCcuZHJvcCcpLmRyb3B6b25lKHtcclxuIHwgICBhY2NlcHQ6ICcuY2FuLWRyb3AnIHx8IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzaW5nbGUtZHJvcCcpLFxyXG4gfCAgIG92ZXJsYXA6ICdwb2ludGVyJyB8fCAnY2VudGVyJyB8fCB6ZXJvVG9PbmVcclxuIHwgfVxyXG4gPSAoYm9vbGVhbiB8IG9iamVjdCkgVGhlIGN1cnJlbnQgc2V0dGluZyBvciB0aGlzIEludGVyYWN0YWJsZVxyXG5cXCovXHJcbkludGVyYWN0YWJsZS5wcm90b3R5cGUuZHJvcHpvbmUgPSBmdW5jdGlvbiAob3B0aW9ucykge1xyXG4gIGlmICh1dGlscy5pcy5vYmplY3Qob3B0aW9ucykpIHtcclxuICAgIHRoaXMub3B0aW9ucy5kcm9wLmVuYWJsZWQgPSBvcHRpb25zLmVuYWJsZWQgPT09IGZhbHNlID8gZmFsc2UgOiB0cnVlO1xyXG5cclxuICAgIGlmICh1dGlscy5pcy5mdW5jdGlvbihvcHRpb25zLm9uZHJvcCkpIHtcclxuICAgICAgdGhpcy5ldmVudHMub25kcm9wID0gb3B0aW9ucy5vbmRyb3A7XHJcbiAgICB9XHJcbiAgICBpZiAodXRpbHMuaXMuZnVuY3Rpb24ob3B0aW9ucy5vbmRyb3BhY3RpdmF0ZSkpIHtcclxuICAgICAgdGhpcy5ldmVudHMub25kcm9wYWN0aXZhdGUgPSBvcHRpb25zLm9uZHJvcGFjdGl2YXRlO1xyXG4gICAgfVxyXG4gICAgaWYgKHV0aWxzLmlzLmZ1bmN0aW9uKG9wdGlvbnMub25kcm9wZGVhY3RpdmF0ZSkpIHtcclxuICAgICAgdGhpcy5ldmVudHMub25kcm9wZGVhY3RpdmF0ZSA9IG9wdGlvbnMub25kcm9wZGVhY3RpdmF0ZTtcclxuICAgIH1cclxuICAgIGlmICh1dGlscy5pcy5mdW5jdGlvbihvcHRpb25zLm9uZHJhZ2VudGVyKSkge1xyXG4gICAgICB0aGlzLmV2ZW50cy5vbmRyYWdlbnRlciA9IG9wdGlvbnMub25kcmFnZW50ZXI7XHJcbiAgICB9XHJcbiAgICBpZiAodXRpbHMuaXMuZnVuY3Rpb24ob3B0aW9ucy5vbmRyYWdsZWF2ZSkpIHtcclxuICAgICAgdGhpcy5ldmVudHMub25kcmFnbGVhdmUgPSBvcHRpb25zLm9uZHJhZ2xlYXZlO1xyXG4gICAgfVxyXG4gICAgaWYgKHV0aWxzLmlzLmZ1bmN0aW9uKG9wdGlvbnMub25kcm9wbW92ZSkpIHtcclxuICAgICAgdGhpcy5ldmVudHMub25kcm9wbW92ZSA9IG9wdGlvbnMub25kcm9wbW92ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoL14ocG9pbnRlcnxjZW50ZXIpJC8udGVzdChvcHRpb25zLm92ZXJsYXApKSB7XHJcbiAgICAgIHRoaXMub3B0aW9ucy5kcm9wLm92ZXJsYXAgPSBvcHRpb25zLm92ZXJsYXA7XHJcbiAgICB9IGVsc2UgaWYgKHV0aWxzLmlzLm51bWJlcihvcHRpb25zLm92ZXJsYXApKSB7XHJcbiAgICAgIHRoaXMub3B0aW9ucy5kcm9wLm92ZXJsYXAgPSBNYXRoLm1heChNYXRoLm1pbigxLCBvcHRpb25zLm92ZXJsYXApLCAwKTtcclxuICAgIH1cclxuICAgIGlmICgnYWNjZXB0JyBpbiBvcHRpb25zKSB7XHJcbiAgICAgIHRoaXMub3B0aW9ucy5kcm9wLmFjY2VwdCA9IG9wdGlvbnMuYWNjZXB0O1xyXG4gICAgfVxyXG4gICAgaWYgKCdjaGVja2VyJyBpbiBvcHRpb25zKSB7XHJcbiAgICAgIHRoaXMub3B0aW9ucy5kcm9wLmNoZWNrZXIgPSBvcHRpb25zLmNoZWNrZXI7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICBpZiAodXRpbHMuaXMuYm9vbChvcHRpb25zKSkge1xyXG4gICAgdGhpcy5vcHRpb25zLmRyb3AuZW5hYmxlZCA9IG9wdGlvbnM7XHJcblxyXG4gICAgaWYgKCFvcHRpb25zKSB7XHJcbiAgICAgIHRoaXMub25kcmFnZW50ZXIgPSB0aGlzLm9uZHJhZ2xlYXZlID0gdGhpcy5vbmRyb3AgPSB0aGlzLm9uZHJvcGFjdGl2YXRlID0gdGhpcy5vbmRyb3BkZWFjdGl2YXRlID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIHJldHVybiB0aGlzLm9wdGlvbnMuZHJvcDtcclxufTtcclxuXHJcbkludGVyYWN0YWJsZS5wcm90b3R5cGUuZHJvcENoZWNrID0gZnVuY3Rpb24gKGRyYWdFdmVudCwgZXZlbnQsIGRyYWdnYWJsZSwgZHJhZ2dhYmxlRWxlbWVudCwgZHJvcEVsZW1lbnQsIHJlY3QpIHtcclxuICB2YXIgZHJvcHBlZCA9IGZhbHNlO1xyXG5cclxuICAvLyBpZiB0aGUgZHJvcHpvbmUgaGFzIG5vIHJlY3QgKGVnLiBkaXNwbGF5OiBub25lKVxyXG4gIC8vIGNhbGwgdGhlIGN1c3RvbSBkcm9wQ2hlY2tlciBvciBqdXN0IHJldHVybiBmYWxzZVxyXG4gIGlmICghKHJlY3QgPSByZWN0IHx8IHRoaXMuZ2V0UmVjdChkcm9wRWxlbWVudCkpKSB7XHJcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zLmRyb3AuY2hlY2tlciA/IHRoaXMub3B0aW9ucy5kcm9wLmNoZWNrZXIoZHJhZ0V2ZW50LCBldmVudCwgZHJvcHBlZCwgdGhpcywgZHJvcEVsZW1lbnQsIGRyYWdnYWJsZSwgZHJhZ2dhYmxlRWxlbWVudCkgOiBmYWxzZTtcclxuICB9XHJcblxyXG4gIHZhciBkcm9wT3ZlcmxhcCA9IHRoaXMub3B0aW9ucy5kcm9wLm92ZXJsYXA7XHJcblxyXG4gIGlmIChkcm9wT3ZlcmxhcCA9PT0gJ3BvaW50ZXInKSB7XHJcbiAgICB2YXIgb3JpZ2luID0gdXRpbHMuZ2V0T3JpZ2luWFkoZHJhZ2dhYmxlLCBkcmFnZ2FibGVFbGVtZW50LCAnZHJhZycpO1xyXG4gICAgdmFyIHBhZ2UgPSB1dGlscy5nZXRQYWdlWFkoZHJhZ0V2ZW50KTtcclxuXHJcbiAgICBwYWdlLnggKz0gb3JpZ2luLng7XHJcbiAgICBwYWdlLnkgKz0gb3JpZ2luLnk7XHJcblxyXG4gICAgdmFyIGhvcml6b250YWwgPSBwYWdlLnggPiByZWN0LmxlZnQgJiYgcGFnZS54IDwgcmVjdC5yaWdodDtcclxuICAgIHZhciB2ZXJ0aWNhbCA9IHBhZ2UueSA+IHJlY3QudG9wICYmIHBhZ2UueSA8IHJlY3QuYm90dG9tO1xyXG5cclxuICAgIGRyb3BwZWQgPSBob3Jpem9udGFsICYmIHZlcnRpY2FsO1xyXG4gIH1cclxuXHJcbiAgdmFyIGRyYWdSZWN0ID0gZHJhZ2dhYmxlLmdldFJlY3QoZHJhZ2dhYmxlRWxlbWVudCk7XHJcblxyXG4gIGlmIChkcmFnUmVjdCAmJiBkcm9wT3ZlcmxhcCA9PT0gJ2NlbnRlcicpIHtcclxuICAgIHZhciBjeCA9IGRyYWdSZWN0LmxlZnQgKyBkcmFnUmVjdC53aWR0aCAvIDI7XHJcbiAgICB2YXIgY3kgPSBkcmFnUmVjdC50b3AgKyBkcmFnUmVjdC5oZWlnaHQgLyAyO1xyXG5cclxuICAgIGRyb3BwZWQgPSBjeCA+PSByZWN0LmxlZnQgJiYgY3ggPD0gcmVjdC5yaWdodCAmJiBjeSA+PSByZWN0LnRvcCAmJiBjeSA8PSByZWN0LmJvdHRvbTtcclxuICB9XHJcblxyXG4gIGlmIChkcmFnUmVjdCAmJiB1dGlscy5pcy5udW1iZXIoZHJvcE92ZXJsYXApKSB7XHJcbiAgICB2YXIgb3ZlcmxhcEFyZWEgPSBNYXRoLm1heCgwLCBNYXRoLm1pbihyZWN0LnJpZ2h0LCBkcmFnUmVjdC5yaWdodCkgLSBNYXRoLm1heChyZWN0LmxlZnQsIGRyYWdSZWN0LmxlZnQpKSAqIE1hdGgubWF4KDAsIE1hdGgubWluKHJlY3QuYm90dG9tLCBkcmFnUmVjdC5ib3R0b20pIC0gTWF0aC5tYXgocmVjdC50b3AsIGRyYWdSZWN0LnRvcCkpO1xyXG5cclxuICAgIHZhciBvdmVybGFwUmF0aW8gPSBvdmVybGFwQXJlYSAvIChkcmFnUmVjdC53aWR0aCAqIGRyYWdSZWN0LmhlaWdodCk7XHJcblxyXG4gICAgZHJvcHBlZCA9IG92ZXJsYXBSYXRpbyA+PSBkcm9wT3ZlcmxhcDtcclxuICB9XHJcblxyXG4gIGlmICh0aGlzLm9wdGlvbnMuZHJvcC5jaGVja2VyKSB7XHJcbiAgICBkcm9wcGVkID0gdGhpcy5vcHRpb25zLmRyb3AuY2hlY2tlcihkcmFnRXZlbnQsIGV2ZW50LCBkcm9wcGVkLCB0aGlzLCBkcm9wRWxlbWVudCwgZHJhZ2dhYmxlLCBkcmFnZ2FibGVFbGVtZW50KTtcclxuICB9XHJcblxyXG4gIHJldHVybiBkcm9wcGVkO1xyXG59O1xyXG5cclxuSW50ZXJhY3RhYmxlLnNpZ25hbHMub24oJ3Vuc2V0JywgZnVuY3Rpb24gKF9yZWY3KSB7XHJcbiAgdmFyIGludGVyYWN0YWJsZSA9IF9yZWY3LmludGVyYWN0YWJsZTtcclxuXHJcbiAgaW50ZXJhY3RhYmxlLmRyb3B6b25lKGZhbHNlKTtcclxufSk7XHJcblxyXG5JbnRlcmFjdGFibGUuc2V0dGluZ3NNZXRob2RzLnB1c2goJ2Ryb3BDaGVja2VyJyk7XHJcblxyXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCduZXcnLCBmdW5jdGlvbiAoaW50ZXJhY3Rpb24pIHtcclxuICBpbnRlcmFjdGlvbi5kcm9wVGFyZ2V0ID0gbnVsbDsgLy8gdGhlIGRyb3B6b25lIGEgZHJhZyB0YXJnZXQgbWlnaHQgYmUgZHJvcHBlZCBpbnRvXHJcbiAgaW50ZXJhY3Rpb24uZHJvcEVsZW1lbnQgPSBudWxsOyAvLyB0aGUgZWxlbWVudCBhdCB0aGUgdGltZSBvZiBjaGVja2luZ1xyXG4gIGludGVyYWN0aW9uLnByZXZEcm9wVGFyZ2V0ID0gbnVsbDsgLy8gdGhlIGRyb3B6b25lIHRoYXQgd2FzIHJlY2VudGx5IGRyYWdnZWQgYXdheSBmcm9tXHJcbiAgaW50ZXJhY3Rpb24ucHJldkRyb3BFbGVtZW50ID0gbnVsbDsgLy8gdGhlIGVsZW1lbnQgYXQgdGhlIHRpbWUgb2YgY2hlY2tpbmdcclxuICBpbnRlcmFjdGlvbi5kcm9wRXZlbnRzID0gbnVsbDsgLy8gdGhlIGRyb3BFdmVudHMgcmVsYXRlZCB0byB0aGUgY3VycmVudCBkcmFnIGV2ZW50XHJcblxyXG4gIGludGVyYWN0aW9uLmFjdGl2ZURyb3BzID0ge1xyXG4gICAgZHJvcHpvbmVzOiBbXSwgLy8gdGhlIGRyb3B6b25lcyB0aGF0IGFyZSBtZW50aW9uZWQgYmVsb3dcclxuICAgIGVsZW1lbnRzOiBbXSwgLy8gZWxlbWVudHMgb2YgZHJvcHpvbmVzIHRoYXQgYWNjZXB0IHRoZSB0YXJnZXQgZHJhZ2dhYmxlXHJcbiAgICByZWN0czogW10gLy8gdGhlIHJlY3RzIG9mIHRoZSBlbGVtZW50cyBtZW50aW9uZWQgYWJvdmVcclxuICB9O1xyXG59KTtcclxuXHJcbkludGVyYWN0aW9uLnNpZ25hbHMub24oJ3N0b3AnLCBmdW5jdGlvbiAoX3JlZjgpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmOC5pbnRlcmFjdGlvbjtcclxuXHJcbiAgaW50ZXJhY3Rpb24uZHJvcFRhcmdldCA9IGludGVyYWN0aW9uLmRyb3BFbGVtZW50ID0gaW50ZXJhY3Rpb24ucHJldkRyb3BUYXJnZXQgPSBpbnRlcmFjdGlvbi5wcmV2RHJvcEVsZW1lbnQgPSBudWxsO1xyXG59KTtcclxuXHJcbi8qXFxcclxuICogaW50ZXJhY3QuZHluYW1pY0Ryb3BcclxuIFsgbWV0aG9kIF1cclxuICpcclxuICogUmV0dXJucyBvciBzZXRzIHdoZXRoZXIgdGhlIGRpbWVuc2lvbnMgb2YgZHJvcHpvbmUgZWxlbWVudHMgYXJlXHJcbiAqIGNhbGN1bGF0ZWQgb24gZXZlcnkgZHJhZ21vdmUgb3Igb25seSBvbiBkcmFnc3RhcnQgZm9yIHRoZSBkZWZhdWx0XHJcbiAqIGRyb3BDaGVja2VyXHJcbiAqXHJcbiAtIG5ld1ZhbHVlIChib29sZWFuKSAjb3B0aW9uYWwgVHJ1ZSB0byBjaGVjayBvbiBlYWNoIG1vdmUuIEZhbHNlIHRvIGNoZWNrIG9ubHkgYmVmb3JlIHN0YXJ0XHJcbiA9IChib29sZWFuIHwgaW50ZXJhY3QpIFRoZSBjdXJyZW50IHNldHRpbmcgb3IgaW50ZXJhY3RcclxuXFwqL1xyXG5pbnRlcmFjdC5keW5hbWljRHJvcCA9IGZ1bmN0aW9uIChuZXdWYWx1ZSkge1xyXG4gIGlmICh1dGlscy5pcy5ib29sKG5ld1ZhbHVlKSkge1xyXG4gICAgLy9pZiAoZHJhZ2dpbmcgJiYgZHluYW1pY0Ryb3AgIT09IG5ld1ZhbHVlICYmICFuZXdWYWx1ZSkge1xyXG4gICAgLy9jYWxjUmVjdHMoZHJvcHpvbmVzKTtcclxuICAgIC8vfVxyXG5cclxuICAgIGR5bmFtaWNEcm9wID0gbmV3VmFsdWU7XHJcblxyXG4gICAgcmV0dXJuIGludGVyYWN0O1xyXG4gIH1cclxuICByZXR1cm4gZHluYW1pY0Ryb3A7XHJcbn07XHJcblxyXG51dGlscy5tZXJnZShJbnRlcmFjdGFibGUuZXZlbnRUeXBlcywgWydkcmFnZW50ZXInLCAnZHJhZ2xlYXZlJywgJ2Ryb3BhY3RpdmF0ZScsICdkcm9wZGVhY3RpdmF0ZScsICdkcm9wbW92ZScsICdkcm9wJ10pO1xyXG5hY3Rpb25zLm1ldGhvZERpY3QuZHJvcCA9ICdkcm9wem9uZSc7XHJcblxyXG5kZWZhdWx0T3B0aW9ucy5kcm9wID0gZHJvcC5kZWZhdWx0cztcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZHJvcDtcclxuXHJcbn0se1wiLi4vSW50ZXJhY3RFdmVudFwiOjMsXCIuLi9JbnRlcmFjdGFibGVcIjo0LFwiLi4vSW50ZXJhY3Rpb25cIjo1LFwiLi4vZGVmYXVsdE9wdGlvbnNcIjoxOCxcIi4uL2ludGVyYWN0XCI6MjEsXCIuLi9zY29wZVwiOjM0LFwiLi4vdXRpbHNcIjo0NCxcIi4vYmFzZVwiOjZ9XSw5OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGFjdGlvbnMgPSByZXF1aXJlKCcuL2Jhc2UnKTtcclxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcclxudmFyIEludGVyYWN0RXZlbnQgPSByZXF1aXJlKCcuLi9JbnRlcmFjdEV2ZW50Jyk7XHJcbnZhciBJbnRlcmFjdGFibGUgPSByZXF1aXJlKCcuLi9JbnRlcmFjdGFibGUnKTtcclxudmFyIEludGVyYWN0aW9uID0gcmVxdWlyZSgnLi4vSW50ZXJhY3Rpb24nKTtcclxudmFyIGRlZmF1bHRPcHRpb25zID0gcmVxdWlyZSgnLi4vZGVmYXVsdE9wdGlvbnMnKTtcclxuXHJcbnZhciBnZXN0dXJlID0ge1xyXG4gIGRlZmF1bHRzOiB7XHJcbiAgICBlbmFibGVkOiBmYWxzZSxcclxuICAgIG9yaWdpbjogbnVsbCxcclxuICAgIHJlc3RyaWN0OiBudWxsXHJcbiAgfSxcclxuXHJcbiAgY2hlY2tlcjogZnVuY3Rpb24gY2hlY2tlcihwb2ludGVyLCBldmVudCwgaW50ZXJhY3RhYmxlLCBlbGVtZW50LCBpbnRlcmFjdGlvbikge1xyXG4gICAgaWYgKGludGVyYWN0aW9uLnBvaW50ZXJJZHMubGVuZ3RoID49IDIpIHtcclxuICAgICAgcmV0dXJuIHsgbmFtZTogJ2dlc3R1cmUnIH07XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIG51bGw7XHJcbiAgfSxcclxuXHJcbiAgZ2V0Q3Vyc29yOiBmdW5jdGlvbiBnZXRDdXJzb3IoKSB7XHJcbiAgICByZXR1cm4gJyc7XHJcbiAgfVxyXG59O1xyXG5cclxuSW50ZXJhY3RFdmVudC5zaWduYWxzLm9uKCduZXcnLCBmdW5jdGlvbiAoX3JlZikge1xyXG4gIHZhciBpRXZlbnQgPSBfcmVmLmlFdmVudCxcclxuICAgICAgaW50ZXJhY3Rpb24gPSBfcmVmLmludGVyYWN0aW9uO1xyXG5cclxuICBpZiAoaUV2ZW50LnR5cGUgIT09ICdnZXN0dXJlc3RhcnQnKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG4gIGlFdmVudC5kcyA9IDA7XHJcblxyXG4gIGludGVyYWN0aW9uLmdlc3R1cmUuc3RhcnREaXN0YW5jZSA9IGludGVyYWN0aW9uLmdlc3R1cmUucHJldkRpc3RhbmNlID0gaUV2ZW50LmRpc3RhbmNlO1xyXG4gIGludGVyYWN0aW9uLmdlc3R1cmUuc3RhcnRBbmdsZSA9IGludGVyYWN0aW9uLmdlc3R1cmUucHJldkFuZ2xlID0gaUV2ZW50LmFuZ2xlO1xyXG4gIGludGVyYWN0aW9uLmdlc3R1cmUuc2NhbGUgPSAxO1xyXG59KTtcclxuXHJcbkludGVyYWN0RXZlbnQuc2lnbmFscy5vbignbmV3JywgZnVuY3Rpb24gKF9yZWYyKSB7XHJcbiAgdmFyIGlFdmVudCA9IF9yZWYyLmlFdmVudCxcclxuICAgICAgaW50ZXJhY3Rpb24gPSBfcmVmMi5pbnRlcmFjdGlvbjtcclxuXHJcbiAgaWYgKGlFdmVudC50eXBlICE9PSAnZ2VzdHVyZW1vdmUnKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICBpRXZlbnQuZHMgPSBpRXZlbnQuc2NhbGUgLSBpbnRlcmFjdGlvbi5nZXN0dXJlLnNjYWxlO1xyXG5cclxuICBpbnRlcmFjdGlvbi50YXJnZXQuZmlyZShpRXZlbnQpO1xyXG5cclxuICBpbnRlcmFjdGlvbi5nZXN0dXJlLnByZXZBbmdsZSA9IGlFdmVudC5hbmdsZTtcclxuICBpbnRlcmFjdGlvbi5nZXN0dXJlLnByZXZEaXN0YW5jZSA9IGlFdmVudC5kaXN0YW5jZTtcclxuXHJcbiAgaWYgKGlFdmVudC5zY2FsZSAhPT0gSW5maW5pdHkgJiYgaUV2ZW50LnNjYWxlICE9PSBudWxsICYmIGlFdmVudC5zY2FsZSAhPT0gdW5kZWZpbmVkICYmICFpc05hTihpRXZlbnQuc2NhbGUpKSB7XHJcblxyXG4gICAgaW50ZXJhY3Rpb24uZ2VzdHVyZS5zY2FsZSA9IGlFdmVudC5zY2FsZTtcclxuICB9XHJcbn0pO1xyXG5cclxuLypcXFxyXG4gKiBJbnRlcmFjdGFibGUuZ2VzdHVyYWJsZVxyXG4gWyBtZXRob2QgXVxyXG4gKlxyXG4gKiBHZXRzIG9yIHNldHMgd2hldGhlciBtdWx0aXRvdWNoIGdlc3R1cmVzIGNhbiBiZSBwZXJmb3JtZWQgb24gdGhlXHJcbiAqIEludGVyYWN0YWJsZSdzIGVsZW1lbnRcclxuICpcclxuID0gKGJvb2xlYW4pIEluZGljYXRlcyBpZiB0aGlzIGNhbiBiZSB0aGUgdGFyZ2V0IG9mIGdlc3R1cmUgZXZlbnRzXHJcbiAgIHwgdmFyIGlzR2VzdHVyZWFibGUgPSBpbnRlcmFjdChlbGVtZW50KS5nZXN0dXJhYmxlKCk7XHJcbiAqIG9yXHJcbiAtIG9wdGlvbnMgKGJvb2xlYW4gfCBvYmplY3QpICNvcHRpb25hbCB0cnVlL2ZhbHNlIG9yIEFuIG9iamVjdCB3aXRoIGV2ZW50IGxpc3RlbmVycyB0byBiZSBmaXJlZCBvbiBnZXN0dXJlIGV2ZW50cyAobWFrZXMgdGhlIEludGVyYWN0YWJsZSBnZXN0dXJhYmxlKVxyXG4gPSAob2JqZWN0KSB0aGlzIEludGVyYWN0YWJsZVxyXG4gfCBpbnRlcmFjdChlbGVtZW50KS5nZXN0dXJhYmxlKHtcclxuIHwgICAgIG9uc3RhcnQ6IGZ1bmN0aW9uIChldmVudCkge30sXHJcbiB8ICAgICBvbm1vdmUgOiBmdW5jdGlvbiAoZXZlbnQpIHt9LFxyXG4gfCAgICAgb25lbmQgIDogZnVuY3Rpb24gKGV2ZW50KSB7fSxcclxuIHxcclxuIHwgICAgIC8vIGxpbWl0IG11bHRpcGxlIGdlc3R1cmVzLlxyXG4gfCAgICAgLy8gU2VlIHRoZSBleHBsYW5hdGlvbiBpbiBASW50ZXJhY3RhYmxlLmRyYWdnYWJsZSBleGFtcGxlXHJcbiB8ICAgICBtYXg6IEluZmluaXR5LFxyXG4gfCAgICAgbWF4UGVyRWxlbWVudDogMSxcclxuIHwgfSk7XHJcblxcKi9cclxuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5nZXN0dXJhYmxlID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcclxuICBpZiAodXRpbHMuaXMub2JqZWN0KG9wdGlvbnMpKSB7XHJcbiAgICB0aGlzLm9wdGlvbnMuZ2VzdHVyZS5lbmFibGVkID0gb3B0aW9ucy5lbmFibGVkID09PSBmYWxzZSA/IGZhbHNlIDogdHJ1ZTtcclxuICAgIHRoaXMuc2V0UGVyQWN0aW9uKCdnZXN0dXJlJywgb3B0aW9ucyk7XHJcbiAgICB0aGlzLnNldE9uRXZlbnRzKCdnZXN0dXJlJywgb3B0aW9ucyk7XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICBpZiAodXRpbHMuaXMuYm9vbChvcHRpb25zKSkge1xyXG4gICAgdGhpcy5vcHRpb25zLmdlc3R1cmUuZW5hYmxlZCA9IG9wdGlvbnM7XHJcblxyXG4gICAgaWYgKCFvcHRpb25zKSB7XHJcbiAgICAgIHRoaXMub25nZXN0dXJlc3RhcnQgPSB0aGlzLm9uZ2VzdHVyZXN0YXJ0ID0gdGhpcy5vbmdlc3R1cmVlbmQgPSBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIHRoaXMub3B0aW9ucy5nZXN0dXJlO1xyXG59O1xyXG5cclxuSW50ZXJhY3RFdmVudC5zaWduYWxzLm9uKCdzZXQtZGVsdGEnLCBmdW5jdGlvbiAoX3JlZjMpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmMy5pbnRlcmFjdGlvbixcclxuICAgICAgaUV2ZW50ID0gX3JlZjMuaUV2ZW50LFxyXG4gICAgICBhY3Rpb24gPSBfcmVmMy5hY3Rpb24sXHJcbiAgICAgIGV2ZW50ID0gX3JlZjMuZXZlbnQsXHJcbiAgICAgIHN0YXJ0aW5nID0gX3JlZjMuc3RhcnRpbmcsXHJcbiAgICAgIGVuZGluZyA9IF9yZWYzLmVuZGluZyxcclxuICAgICAgZGVsdGFTb3VyY2UgPSBfcmVmMy5kZWx0YVNvdXJjZTtcclxuXHJcbiAgaWYgKGFjdGlvbiAhPT0gJ2dlc3R1cmUnKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICB2YXIgcG9pbnRlcnMgPSBpbnRlcmFjdGlvbi5wb2ludGVycztcclxuXHJcbiAgaUV2ZW50LnRvdWNoZXMgPSBbcG9pbnRlcnNbMF0sIHBvaW50ZXJzWzFdXTtcclxuXHJcbiAgaWYgKHN0YXJ0aW5nKSB7XHJcbiAgICBpRXZlbnQuZGlzdGFuY2UgPSB1dGlscy50b3VjaERpc3RhbmNlKHBvaW50ZXJzLCBkZWx0YVNvdXJjZSk7XHJcbiAgICBpRXZlbnQuYm94ID0gdXRpbHMudG91Y2hCQm94KHBvaW50ZXJzKTtcclxuICAgIGlFdmVudC5zY2FsZSA9IDE7XHJcbiAgICBpRXZlbnQuZHMgPSAwO1xyXG4gICAgaUV2ZW50LmFuZ2xlID0gdXRpbHMudG91Y2hBbmdsZShwb2ludGVycywgdW5kZWZpbmVkLCBkZWx0YVNvdXJjZSk7XHJcbiAgICBpRXZlbnQuZGEgPSAwO1xyXG4gIH0gZWxzZSBpZiAoZW5kaW5nIHx8IGV2ZW50IGluc3RhbmNlb2YgSW50ZXJhY3RFdmVudCkge1xyXG4gICAgaUV2ZW50LmRpc3RhbmNlID0gaW50ZXJhY3Rpb24ucHJldkV2ZW50LmRpc3RhbmNlO1xyXG4gICAgaUV2ZW50LmJveCA9IGludGVyYWN0aW9uLnByZXZFdmVudC5ib3g7XHJcbiAgICBpRXZlbnQuc2NhbGUgPSBpbnRlcmFjdGlvbi5wcmV2RXZlbnQuc2NhbGU7XHJcbiAgICBpRXZlbnQuZHMgPSBpRXZlbnQuc2NhbGUgLSAxO1xyXG4gICAgaUV2ZW50LmFuZ2xlID0gaW50ZXJhY3Rpb24ucHJldkV2ZW50LmFuZ2xlO1xyXG4gICAgaUV2ZW50LmRhID0gaUV2ZW50LmFuZ2xlIC0gaW50ZXJhY3Rpb24uZ2VzdHVyZS5zdGFydEFuZ2xlO1xyXG4gIH0gZWxzZSB7XHJcbiAgICBpRXZlbnQuZGlzdGFuY2UgPSB1dGlscy50b3VjaERpc3RhbmNlKHBvaW50ZXJzLCBkZWx0YVNvdXJjZSk7XHJcbiAgICBpRXZlbnQuYm94ID0gdXRpbHMudG91Y2hCQm94KHBvaW50ZXJzKTtcclxuICAgIGlFdmVudC5zY2FsZSA9IGlFdmVudC5kaXN0YW5jZSAvIGludGVyYWN0aW9uLmdlc3R1cmUuc3RhcnREaXN0YW5jZTtcclxuICAgIGlFdmVudC5hbmdsZSA9IHV0aWxzLnRvdWNoQW5nbGUocG9pbnRlcnMsIGludGVyYWN0aW9uLmdlc3R1cmUucHJldkFuZ2xlLCBkZWx0YVNvdXJjZSk7XHJcblxyXG4gICAgaUV2ZW50LmRzID0gaUV2ZW50LnNjYWxlIC0gaW50ZXJhY3Rpb24uZ2VzdHVyZS5wcmV2U2NhbGU7XHJcbiAgICBpRXZlbnQuZGEgPSBpRXZlbnQuYW5nbGUgLSBpbnRlcmFjdGlvbi5nZXN0dXJlLnByZXZBbmdsZTtcclxuICB9XHJcbn0pO1xyXG5cclxuSW50ZXJhY3Rpb24uc2lnbmFscy5vbignbmV3JywgZnVuY3Rpb24gKGludGVyYWN0aW9uKSB7XHJcbiAgaW50ZXJhY3Rpb24uZ2VzdHVyZSA9IHtcclxuICAgIHN0YXJ0OiB7IHg6IDAsIHk6IDAgfSxcclxuXHJcbiAgICBzdGFydERpc3RhbmNlOiAwLCAvLyBkaXN0YW5jZSBiZXR3ZWVuIHR3byB0b3VjaGVzIG9mIHRvdWNoU3RhcnRcclxuICAgIHByZXZEaXN0YW5jZTogMCxcclxuICAgIGRpc3RhbmNlOiAwLFxyXG5cclxuICAgIHNjYWxlOiAxLCAvLyBnZXN0dXJlLmRpc3RhbmNlIC8gZ2VzdHVyZS5zdGFydERpc3RhbmNlXHJcblxyXG4gICAgc3RhcnRBbmdsZTogMCwgLy8gYW5nbGUgb2YgbGluZSBqb2luaW5nIHR3byB0b3VjaGVzXHJcbiAgICBwcmV2QW5nbGU6IDAgLy8gYW5nbGUgb2YgdGhlIHByZXZpb3VzIGdlc3R1cmUgZXZlbnRcclxuICB9O1xyXG59KTtcclxuXHJcbmFjdGlvbnMuZ2VzdHVyZSA9IGdlc3R1cmU7XHJcbmFjdGlvbnMubmFtZXMucHVzaCgnZ2VzdHVyZScpO1xyXG51dGlscy5tZXJnZShJbnRlcmFjdGFibGUuZXZlbnRUeXBlcywgWydnZXN0dXJlc3RhcnQnLCAnZ2VzdHVyZW1vdmUnLCAnZ2VzdHVyZWVuZCddKTtcclxuYWN0aW9ucy5tZXRob2REaWN0Lmdlc3R1cmUgPSAnZ2VzdHVyYWJsZSc7XHJcblxyXG5kZWZhdWx0T3B0aW9ucy5nZXN0dXJlID0gZ2VzdHVyZS5kZWZhdWx0cztcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZ2VzdHVyZTtcclxuXHJcbn0se1wiLi4vSW50ZXJhY3RFdmVudFwiOjMsXCIuLi9JbnRlcmFjdGFibGVcIjo0LFwiLi4vSW50ZXJhY3Rpb25cIjo1LFwiLi4vZGVmYXVsdE9wdGlvbnNcIjoxOCxcIi4uL3V0aWxzXCI6NDQsXCIuL2Jhc2VcIjo2fV0sMTA6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xyXG4ndXNlIHN0cmljdCc7XHJcblxyXG52YXIgYWN0aW9ucyA9IHJlcXVpcmUoJy4vYmFzZScpO1xyXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xyXG52YXIgYnJvd3NlciA9IHJlcXVpcmUoJy4uL3V0aWxzL2Jyb3dzZXInKTtcclxudmFyIEludGVyYWN0RXZlbnQgPSByZXF1aXJlKCcuLi9JbnRlcmFjdEV2ZW50Jyk7XHJcbnZhciBJbnRlcmFjdGFibGUgPSByZXF1aXJlKCcuLi9JbnRlcmFjdGFibGUnKTtcclxudmFyIEludGVyYWN0aW9uID0gcmVxdWlyZSgnLi4vSW50ZXJhY3Rpb24nKTtcclxudmFyIGRlZmF1bHRPcHRpb25zID0gcmVxdWlyZSgnLi4vZGVmYXVsdE9wdGlvbnMnKTtcclxuXHJcbi8vIExlc3MgUHJlY2lzaW9uIHdpdGggdG91Y2ggaW5wdXRcclxudmFyIGRlZmF1bHRNYXJnaW4gPSBicm93c2VyLnN1cHBvcnRzVG91Y2ggfHwgYnJvd3Nlci5zdXBwb3J0c1BvaW50ZXJFdmVudCA/IDIwIDogMTA7XHJcblxyXG52YXIgcmVzaXplID0ge1xyXG4gIGRlZmF1bHRzOiB7XHJcbiAgICBlbmFibGVkOiBmYWxzZSxcclxuICAgIG1vdXNlQnV0dG9uczogbnVsbCxcclxuXHJcbiAgICBvcmlnaW46IG51bGwsXHJcbiAgICBzbmFwOiBudWxsLFxyXG4gICAgcmVzdHJpY3Q6IG51bGwsXHJcbiAgICBpbmVydGlhOiBudWxsLFxyXG4gICAgYXV0b1Njcm9sbDogbnVsbCxcclxuXHJcbiAgICBzcXVhcmU6IGZhbHNlLFxyXG4gICAgcHJlc2VydmVBc3BlY3RSYXRpbzogZmFsc2UsXHJcbiAgICBheGlzOiAneHknLFxyXG5cclxuICAgIC8vIHVzZSBkZWZhdWx0IG1hcmdpblxyXG4gICAgbWFyZ2luOiBOYU4sXHJcblxyXG4gICAgLy8gb2JqZWN0IHdpdGggcHJvcHMgbGVmdCwgcmlnaHQsIHRvcCwgYm90dG9tIHdoaWNoIGFyZVxyXG4gICAgLy8gdHJ1ZS9mYWxzZSB2YWx1ZXMgdG8gcmVzaXplIHdoZW4gdGhlIHBvaW50ZXIgaXMgb3ZlciB0aGF0IGVkZ2UsXHJcbiAgICAvLyBDU1Mgc2VsZWN0b3JzIHRvIG1hdGNoIHRoZSBoYW5kbGVzIGZvciBlYWNoIGRpcmVjdGlvblxyXG4gICAgLy8gb3IgdGhlIEVsZW1lbnRzIGZvciBlYWNoIGhhbmRsZVxyXG4gICAgZWRnZXM6IG51bGwsXHJcblxyXG4gICAgLy8gYSB2YWx1ZSBvZiAnbm9uZScgd2lsbCBsaW1pdCB0aGUgcmVzaXplIHJlY3QgdG8gYSBtaW5pbXVtIG9mIDB4MFxyXG4gICAgLy8gJ25lZ2F0ZScgd2lsbCBhbG93IHRoZSByZWN0IHRvIGhhdmUgbmVnYXRpdmUgd2lkdGgvaGVpZ2h0XHJcbiAgICAvLyAncmVwb3NpdGlvbicgd2lsbCBrZWVwIHRoZSB3aWR0aC9oZWlnaHQgcG9zaXRpdmUgYnkgc3dhcHBpbmdcclxuICAgIC8vIHRoZSB0b3AgYW5kIGJvdHRvbSBlZGdlcyBhbmQvb3Igc3dhcHBpbmcgdGhlIGxlZnQgYW5kIHJpZ2h0IGVkZ2VzXHJcbiAgICBpbnZlcnQ6ICdub25lJ1xyXG4gIH0sXHJcblxyXG4gIGNoZWNrZXI6IGZ1bmN0aW9uIGNoZWNrZXIocG9pbnRlciwgZXZlbnQsIGludGVyYWN0YWJsZSwgZWxlbWVudCwgaW50ZXJhY3Rpb24sIHJlY3QpIHtcclxuICAgIGlmICghcmVjdCkge1xyXG4gICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgcGFnZSA9IHV0aWxzLmV4dGVuZCh7fSwgaW50ZXJhY3Rpb24uY3VyQ29vcmRzLnBhZ2UpO1xyXG4gICAgdmFyIG9wdGlvbnMgPSBpbnRlcmFjdGFibGUub3B0aW9ucztcclxuXHJcbiAgICBpZiAob3B0aW9ucy5yZXNpemUuZW5hYmxlZCkge1xyXG4gICAgICB2YXIgcmVzaXplT3B0aW9ucyA9IG9wdGlvbnMucmVzaXplO1xyXG4gICAgICB2YXIgcmVzaXplRWRnZXMgPSB7IGxlZnQ6IGZhbHNlLCByaWdodDogZmFsc2UsIHRvcDogZmFsc2UsIGJvdHRvbTogZmFsc2UgfTtcclxuXHJcbiAgICAgIC8vIGlmIHVzaW5nIHJlc2l6ZS5lZGdlc1xyXG4gICAgICBpZiAodXRpbHMuaXMub2JqZWN0KHJlc2l6ZU9wdGlvbnMuZWRnZXMpKSB7XHJcbiAgICAgICAgZm9yICh2YXIgZWRnZSBpbiByZXNpemVFZGdlcykge1xyXG4gICAgICAgICAgcmVzaXplRWRnZXNbZWRnZV0gPSBjaGVja1Jlc2l6ZUVkZ2UoZWRnZSwgcmVzaXplT3B0aW9ucy5lZGdlc1tlZGdlXSwgcGFnZSwgaW50ZXJhY3Rpb24uX2V2ZW50VGFyZ2V0LCBlbGVtZW50LCByZWN0LCByZXNpemVPcHRpb25zLm1hcmdpbiB8fCBkZWZhdWx0TWFyZ2luKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJlc2l6ZUVkZ2VzLmxlZnQgPSByZXNpemVFZGdlcy5sZWZ0ICYmICFyZXNpemVFZGdlcy5yaWdodDtcclxuICAgICAgICByZXNpemVFZGdlcy50b3AgPSByZXNpemVFZGdlcy50b3AgJiYgIXJlc2l6ZUVkZ2VzLmJvdHRvbTtcclxuXHJcbiAgICAgICAgaWYgKHJlc2l6ZUVkZ2VzLmxlZnQgfHwgcmVzaXplRWRnZXMucmlnaHQgfHwgcmVzaXplRWRnZXMudG9wIHx8IHJlc2l6ZUVkZ2VzLmJvdHRvbSkge1xyXG4gICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgbmFtZTogJ3Jlc2l6ZScsXHJcbiAgICAgICAgICAgIGVkZ2VzOiByZXNpemVFZGdlc1xyXG4gICAgICAgICAgfTtcclxuICAgICAgICB9XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdmFyIHJpZ2h0ID0gb3B0aW9ucy5yZXNpemUuYXhpcyAhPT0gJ3knICYmIHBhZ2UueCA+IHJlY3QucmlnaHQgLSBkZWZhdWx0TWFyZ2luO1xyXG4gICAgICAgIHZhciBib3R0b20gPSBvcHRpb25zLnJlc2l6ZS5heGlzICE9PSAneCcgJiYgcGFnZS55ID4gcmVjdC5ib3R0b20gLSBkZWZhdWx0TWFyZ2luO1xyXG5cclxuICAgICAgICBpZiAocmlnaHQgfHwgYm90dG9tKSB7XHJcbiAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBuYW1lOiAncmVzaXplJyxcclxuICAgICAgICAgICAgYXhlczogKHJpZ2h0ID8gJ3gnIDogJycpICsgKGJvdHRvbSA/ICd5JyA6ICcnKVxyXG4gICAgICAgICAgfTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gbnVsbDtcclxuICB9LFxyXG5cclxuICBjdXJzb3JzOiBicm93c2VyLmlzSWU5T3JPbGRlciA/IHtcclxuICAgIHg6ICdlLXJlc2l6ZScsXHJcbiAgICB5OiAncy1yZXNpemUnLFxyXG4gICAgeHk6ICdzZS1yZXNpemUnLFxyXG5cclxuICAgIHRvcDogJ24tcmVzaXplJyxcclxuICAgIGxlZnQ6ICd3LXJlc2l6ZScsXHJcbiAgICBib3R0b206ICdzLXJlc2l6ZScsXHJcbiAgICByaWdodDogJ2UtcmVzaXplJyxcclxuICAgIHRvcGxlZnQ6ICdzZS1yZXNpemUnLFxyXG4gICAgYm90dG9tcmlnaHQ6ICdzZS1yZXNpemUnLFxyXG4gICAgdG9wcmlnaHQ6ICduZS1yZXNpemUnLFxyXG4gICAgYm90dG9tbGVmdDogJ25lLXJlc2l6ZSdcclxuICB9IDoge1xyXG4gICAgeDogJ2V3LXJlc2l6ZScsXHJcbiAgICB5OiAnbnMtcmVzaXplJyxcclxuICAgIHh5OiAnbndzZS1yZXNpemUnLFxyXG5cclxuICAgIHRvcDogJ25zLXJlc2l6ZScsXHJcbiAgICBsZWZ0OiAnZXctcmVzaXplJyxcclxuICAgIGJvdHRvbTogJ25zLXJlc2l6ZScsXHJcbiAgICByaWdodDogJ2V3LXJlc2l6ZScsXHJcbiAgICB0b3BsZWZ0OiAnbndzZS1yZXNpemUnLFxyXG4gICAgYm90dG9tcmlnaHQ6ICdud3NlLXJlc2l6ZScsXHJcbiAgICB0b3ByaWdodDogJ25lc3ctcmVzaXplJyxcclxuICAgIGJvdHRvbWxlZnQ6ICduZXN3LXJlc2l6ZSdcclxuICB9LFxyXG5cclxuICBnZXRDdXJzb3I6IGZ1bmN0aW9uIGdldEN1cnNvcihhY3Rpb24pIHtcclxuICAgIGlmIChhY3Rpb24uYXhpcykge1xyXG4gICAgICByZXR1cm4gcmVzaXplLmN1cnNvcnNbYWN0aW9uLm5hbWUgKyBhY3Rpb24uYXhpc107XHJcbiAgICB9IGVsc2UgaWYgKGFjdGlvbi5lZGdlcykge1xyXG4gICAgICB2YXIgY3Vyc29yS2V5ID0gJyc7XHJcbiAgICAgIHZhciBlZGdlTmFtZXMgPSBbJ3RvcCcsICdib3R0b20nLCAnbGVmdCcsICdyaWdodCddO1xyXG5cclxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyBpKyspIHtcclxuICAgICAgICBpZiAoYWN0aW9uLmVkZ2VzW2VkZ2VOYW1lc1tpXV0pIHtcclxuICAgICAgICAgIGN1cnNvcktleSArPSBlZGdlTmFtZXNbaV07XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gcmVzaXplLmN1cnNvcnNbY3Vyc29yS2V5XTtcclxuICAgIH1cclxuICB9XHJcbn07XHJcblxyXG4vLyByZXNpemVzdGFydFxyXG5JbnRlcmFjdEV2ZW50LnNpZ25hbHMub24oJ25ldycsIGZ1bmN0aW9uIChfcmVmKSB7XHJcbiAgdmFyIGlFdmVudCA9IF9yZWYuaUV2ZW50LFxyXG4gICAgICBpbnRlcmFjdGlvbiA9IF9yZWYuaW50ZXJhY3Rpb247XHJcblxyXG4gIGlmIChpRXZlbnQudHlwZSAhPT0gJ3Jlc2l6ZXN0YXJ0JyB8fCAhaW50ZXJhY3Rpb24ucHJlcGFyZWQuZWRnZXMpIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIHZhciBzdGFydFJlY3QgPSBpbnRlcmFjdGlvbi50YXJnZXQuZ2V0UmVjdChpbnRlcmFjdGlvbi5lbGVtZW50KTtcclxuICB2YXIgcmVzaXplT3B0aW9ucyA9IGludGVyYWN0aW9uLnRhcmdldC5vcHRpb25zLnJlc2l6ZTtcclxuXHJcbiAgLypcclxuICAgKiBXaGVuIHVzaW5nIHRoZSBgcmVzaXphYmxlLnNxdWFyZWAgb3IgYHJlc2l6YWJsZS5wcmVzZXJ2ZUFzcGVjdFJhdGlvYCBvcHRpb25zLCByZXNpemluZyBmcm9tIG9uZSBlZGdlXHJcbiAgICogd2lsbCBhZmZlY3QgYW5vdGhlci4gRS5nLiB3aXRoIGByZXNpemFibGUuc3F1YXJlYCwgcmVzaXppbmcgdG8gbWFrZSB0aGUgcmlnaHQgZWRnZSBsYXJnZXIgd2lsbCBtYWtlXHJcbiAgICogdGhlIGJvdHRvbSBlZGdlIGxhcmdlciBieSB0aGUgc2FtZSBhbW91bnQuIFdlIGNhbGwgdGhlc2UgJ2xpbmtlZCcgZWRnZXMuIEFueSBsaW5rZWQgZWRnZXMgd2lsbCBkZXBlbmRcclxuICAgKiBvbiB0aGUgYWN0aXZlIGVkZ2VzIGFuZCB0aGUgZWRnZSBiZWluZyBpbnRlcmFjdGVkIHdpdGguXHJcbiAgICovXHJcbiAgaWYgKHJlc2l6ZU9wdGlvbnMuc3F1YXJlIHx8IHJlc2l6ZU9wdGlvbnMucHJlc2VydmVBc3BlY3RSYXRpbykge1xyXG4gICAgdmFyIGxpbmtlZEVkZ2VzID0gdXRpbHMuZXh0ZW5kKHt9LCBpbnRlcmFjdGlvbi5wcmVwYXJlZC5lZGdlcyk7XHJcblxyXG4gICAgbGlua2VkRWRnZXMudG9wID0gbGlua2VkRWRnZXMudG9wIHx8IGxpbmtlZEVkZ2VzLmxlZnQgJiYgIWxpbmtlZEVkZ2VzLmJvdHRvbTtcclxuICAgIGxpbmtlZEVkZ2VzLmxlZnQgPSBsaW5rZWRFZGdlcy5sZWZ0IHx8IGxpbmtlZEVkZ2VzLnRvcCAmJiAhbGlua2VkRWRnZXMucmlnaHQ7XHJcbiAgICBsaW5rZWRFZGdlcy5ib3R0b20gPSBsaW5rZWRFZGdlcy5ib3R0b20gfHwgbGlua2VkRWRnZXMucmlnaHQgJiYgIWxpbmtlZEVkZ2VzLnRvcDtcclxuICAgIGxpbmtlZEVkZ2VzLnJpZ2h0ID0gbGlua2VkRWRnZXMucmlnaHQgfHwgbGlua2VkRWRnZXMuYm90dG9tICYmICFsaW5rZWRFZGdlcy5sZWZ0O1xyXG5cclxuICAgIGludGVyYWN0aW9uLnByZXBhcmVkLl9saW5rZWRFZGdlcyA9IGxpbmtlZEVkZ2VzO1xyXG4gIH0gZWxzZSB7XHJcbiAgICBpbnRlcmFjdGlvbi5wcmVwYXJlZC5fbGlua2VkRWRnZXMgPSBudWxsO1xyXG4gIH1cclxuXHJcbiAgLy8gaWYgdXNpbmcgYHJlc2l6YWJsZS5wcmVzZXJ2ZUFzcGVjdFJhdGlvYCBvcHRpb24sIHJlY29yZCBhc3BlY3QgcmF0aW8gYXQgdGhlIHN0YXJ0IG9mIHRoZSByZXNpemVcclxuICBpZiAocmVzaXplT3B0aW9ucy5wcmVzZXJ2ZUFzcGVjdFJhdGlvKSB7XHJcbiAgICBpbnRlcmFjdGlvbi5yZXNpemVTdGFydEFzcGVjdFJhdGlvID0gc3RhcnRSZWN0LndpZHRoIC8gc3RhcnRSZWN0LmhlaWdodDtcclxuICB9XHJcblxyXG4gIGludGVyYWN0aW9uLnJlc2l6ZVJlY3RzID0ge1xyXG4gICAgc3RhcnQ6IHN0YXJ0UmVjdCxcclxuICAgIGN1cnJlbnQ6IHV0aWxzLmV4dGVuZCh7fSwgc3RhcnRSZWN0KSxcclxuICAgIGludmVydGVkOiB1dGlscy5leHRlbmQoe30sIHN0YXJ0UmVjdCksXHJcbiAgICBwcmV2aW91czogdXRpbHMuZXh0ZW5kKHt9LCBzdGFydFJlY3QpLFxyXG4gICAgZGVsdGE6IHtcclxuICAgICAgbGVmdDogMCwgcmlnaHQ6IDAsIHdpZHRoOiAwLFxyXG4gICAgICB0b3A6IDAsIGJvdHRvbTogMCwgaGVpZ2h0OiAwXHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgaUV2ZW50LnJlY3QgPSBpbnRlcmFjdGlvbi5yZXNpemVSZWN0cy5pbnZlcnRlZDtcclxuICBpRXZlbnQuZGVsdGFSZWN0ID0gaW50ZXJhY3Rpb24ucmVzaXplUmVjdHMuZGVsdGE7XHJcbn0pO1xyXG5cclxuLy8gcmVzaXplbW92ZVxyXG5JbnRlcmFjdEV2ZW50LnNpZ25hbHMub24oJ25ldycsIGZ1bmN0aW9uIChfcmVmMikge1xyXG4gIHZhciBpRXZlbnQgPSBfcmVmMi5pRXZlbnQsXHJcbiAgICAgIHBoYXNlID0gX3JlZjIucGhhc2UsXHJcbiAgICAgIGludGVyYWN0aW9uID0gX3JlZjIuaW50ZXJhY3Rpb247XHJcblxyXG4gIGlmIChwaGFzZSAhPT0gJ21vdmUnIHx8ICFpbnRlcmFjdGlvbi5wcmVwYXJlZC5lZGdlcykge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgdmFyIHJlc2l6ZU9wdGlvbnMgPSBpbnRlcmFjdGlvbi50YXJnZXQub3B0aW9ucy5yZXNpemU7XHJcbiAgdmFyIGludmVydCA9IHJlc2l6ZU9wdGlvbnMuaW52ZXJ0O1xyXG4gIHZhciBpbnZlcnRpYmxlID0gaW52ZXJ0ID09PSAncmVwb3NpdGlvbicgfHwgaW52ZXJ0ID09PSAnbmVnYXRlJztcclxuXHJcbiAgdmFyIGVkZ2VzID0gaW50ZXJhY3Rpb24ucHJlcGFyZWQuZWRnZXM7XHJcblxyXG4gIHZhciBzdGFydCA9IGludGVyYWN0aW9uLnJlc2l6ZVJlY3RzLnN0YXJ0O1xyXG4gIHZhciBjdXJyZW50ID0gaW50ZXJhY3Rpb24ucmVzaXplUmVjdHMuY3VycmVudDtcclxuICB2YXIgaW52ZXJ0ZWQgPSBpbnRlcmFjdGlvbi5yZXNpemVSZWN0cy5pbnZlcnRlZDtcclxuICB2YXIgZGVsdGEgPSBpbnRlcmFjdGlvbi5yZXNpemVSZWN0cy5kZWx0YTtcclxuICB2YXIgcHJldmlvdXMgPSB1dGlscy5leHRlbmQoaW50ZXJhY3Rpb24ucmVzaXplUmVjdHMucHJldmlvdXMsIGludmVydGVkKTtcclxuICB2YXIgb3JpZ2luYWxFZGdlcyA9IGVkZ2VzO1xyXG5cclxuICB2YXIgZHggPSBpRXZlbnQuZHg7XHJcbiAgdmFyIGR5ID0gaUV2ZW50LmR5O1xyXG5cclxuICBpZiAocmVzaXplT3B0aW9ucy5wcmVzZXJ2ZUFzcGVjdFJhdGlvIHx8IHJlc2l6ZU9wdGlvbnMuc3F1YXJlKSB7XHJcbiAgICAvLyBgcmVzaXplLnByZXNlcnZlQXNwZWN0UmF0aW9gIHRha2VzIHByZWNlZGVuY2Ugb3ZlciBgcmVzaXplLnNxdWFyZWBcclxuICAgIHZhciBzdGFydEFzcGVjdFJhdGlvID0gcmVzaXplT3B0aW9ucy5wcmVzZXJ2ZUFzcGVjdFJhdGlvID8gaW50ZXJhY3Rpb24ucmVzaXplU3RhcnRBc3BlY3RSYXRpbyA6IDE7XHJcblxyXG4gICAgZWRnZXMgPSBpbnRlcmFjdGlvbi5wcmVwYXJlZC5fbGlua2VkRWRnZXM7XHJcblxyXG4gICAgaWYgKG9yaWdpbmFsRWRnZXMubGVmdCAmJiBvcmlnaW5hbEVkZ2VzLmJvdHRvbSB8fCBvcmlnaW5hbEVkZ2VzLnJpZ2h0ICYmIG9yaWdpbmFsRWRnZXMudG9wKSB7XHJcbiAgICAgIGR5ID0gLWR4IC8gc3RhcnRBc3BlY3RSYXRpbztcclxuICAgIH0gZWxzZSBpZiAob3JpZ2luYWxFZGdlcy5sZWZ0IHx8IG9yaWdpbmFsRWRnZXMucmlnaHQpIHtcclxuICAgICAgZHkgPSBkeCAvIHN0YXJ0QXNwZWN0UmF0aW87XHJcbiAgICB9IGVsc2UgaWYgKG9yaWdpbmFsRWRnZXMudG9wIHx8IG9yaWdpbmFsRWRnZXMuYm90dG9tKSB7XHJcbiAgICAgIGR4ID0gZHkgKiBzdGFydEFzcGVjdFJhdGlvO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy8gdXBkYXRlIHRoZSAnY3VycmVudCcgcmVjdCB3aXRob3V0IG1vZGlmaWNhdGlvbnNcclxuICBpZiAoZWRnZXMudG9wKSB7XHJcbiAgICBjdXJyZW50LnRvcCArPSBkeTtcclxuICB9XHJcbiAgaWYgKGVkZ2VzLmJvdHRvbSkge1xyXG4gICAgY3VycmVudC5ib3R0b20gKz0gZHk7XHJcbiAgfVxyXG4gIGlmIChlZGdlcy5sZWZ0KSB7XHJcbiAgICBjdXJyZW50LmxlZnQgKz0gZHg7XHJcbiAgfVxyXG4gIGlmIChlZGdlcy5yaWdodCkge1xyXG4gICAgY3VycmVudC5yaWdodCArPSBkeDtcclxuICB9XHJcblxyXG4gIGlmIChpbnZlcnRpYmxlKSB7XHJcbiAgICAvLyBpZiBpbnZlcnRpYmxlLCBjb3B5IHRoZSBjdXJyZW50IHJlY3RcclxuICAgIHV0aWxzLmV4dGVuZChpbnZlcnRlZCwgY3VycmVudCk7XHJcblxyXG4gICAgaWYgKGludmVydCA9PT0gJ3JlcG9zaXRpb24nKSB7XHJcbiAgICAgIC8vIHN3YXAgZWRnZSB2YWx1ZXMgaWYgbmVjZXNzYXJ5IHRvIGtlZXAgd2lkdGgvaGVpZ2h0IHBvc2l0aXZlXHJcbiAgICAgIHZhciBzd2FwID0gdm9pZCAwO1xyXG5cclxuICAgICAgaWYgKGludmVydGVkLnRvcCA+IGludmVydGVkLmJvdHRvbSkge1xyXG4gICAgICAgIHN3YXAgPSBpbnZlcnRlZC50b3A7XHJcblxyXG4gICAgICAgIGludmVydGVkLnRvcCA9IGludmVydGVkLmJvdHRvbTtcclxuICAgICAgICBpbnZlcnRlZC5ib3R0b20gPSBzd2FwO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChpbnZlcnRlZC5sZWZ0ID4gaW52ZXJ0ZWQucmlnaHQpIHtcclxuICAgICAgICBzd2FwID0gaW52ZXJ0ZWQubGVmdDtcclxuXHJcbiAgICAgICAgaW52ZXJ0ZWQubGVmdCA9IGludmVydGVkLnJpZ2h0O1xyXG4gICAgICAgIGludmVydGVkLnJpZ2h0ID0gc3dhcDtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH0gZWxzZSB7XHJcbiAgICAvLyBpZiBub3QgaW52ZXJ0aWJsZSwgcmVzdHJpY3QgdG8gbWluaW11bSBvZiAweDAgcmVjdFxyXG4gICAgaW52ZXJ0ZWQudG9wID0gTWF0aC5taW4oY3VycmVudC50b3AsIHN0YXJ0LmJvdHRvbSk7XHJcbiAgICBpbnZlcnRlZC5ib3R0b20gPSBNYXRoLm1heChjdXJyZW50LmJvdHRvbSwgc3RhcnQudG9wKTtcclxuICAgIGludmVydGVkLmxlZnQgPSBNYXRoLm1pbihjdXJyZW50LmxlZnQsIHN0YXJ0LnJpZ2h0KTtcclxuICAgIGludmVydGVkLnJpZ2h0ID0gTWF0aC5tYXgoY3VycmVudC5yaWdodCwgc3RhcnQubGVmdCk7XHJcbiAgfVxyXG5cclxuICBpbnZlcnRlZC53aWR0aCA9IGludmVydGVkLnJpZ2h0IC0gaW52ZXJ0ZWQubGVmdDtcclxuICBpbnZlcnRlZC5oZWlnaHQgPSBpbnZlcnRlZC5ib3R0b20gLSBpbnZlcnRlZC50b3A7XHJcblxyXG4gIGZvciAodmFyIGVkZ2UgaW4gaW52ZXJ0ZWQpIHtcclxuICAgIGRlbHRhW2VkZ2VdID0gaW52ZXJ0ZWRbZWRnZV0gLSBwcmV2aW91c1tlZGdlXTtcclxuICB9XHJcblxyXG4gIGlFdmVudC5lZGdlcyA9IGludGVyYWN0aW9uLnByZXBhcmVkLmVkZ2VzO1xyXG4gIGlFdmVudC5yZWN0ID0gaW52ZXJ0ZWQ7XHJcbiAgaUV2ZW50LmRlbHRhUmVjdCA9IGRlbHRhO1xyXG59KTtcclxuXHJcbi8qXFxcclxuICogSW50ZXJhY3RhYmxlLnJlc2l6YWJsZVxyXG4gWyBtZXRob2QgXVxyXG4gKlxyXG4gKiBHZXRzIG9yIHNldHMgd2hldGhlciByZXNpemUgYWN0aW9ucyBjYW4gYmUgcGVyZm9ybWVkIG9uIHRoZVxyXG4gKiBJbnRlcmFjdGFibGVcclxuICpcclxuID0gKGJvb2xlYW4pIEluZGljYXRlcyBpZiB0aGlzIGNhbiBiZSB0aGUgdGFyZ2V0IG9mIHJlc2l6ZSBlbGVtZW50c1xyXG4gICB8IHZhciBpc1Jlc2l6ZWFibGUgPSBpbnRlcmFjdCgnaW5wdXRbdHlwZT10ZXh0XScpLnJlc2l6YWJsZSgpO1xyXG4gKiBvclxyXG4gLSBvcHRpb25zIChib29sZWFuIHwgb2JqZWN0KSAjb3B0aW9uYWwgdHJ1ZS9mYWxzZSBvciBBbiBvYmplY3Qgd2l0aCBldmVudCBsaXN0ZW5lcnMgdG8gYmUgZmlyZWQgb24gcmVzaXplIGV2ZW50cyAob2JqZWN0IG1ha2VzIHRoZSBJbnRlcmFjdGFibGUgcmVzaXphYmxlKVxyXG4gPSAob2JqZWN0KSBUaGlzIEludGVyYWN0YWJsZVxyXG4gICB8IGludGVyYWN0KGVsZW1lbnQpLnJlc2l6YWJsZSh7XHJcbiAgIHwgICBvbnN0YXJ0OiBmdW5jdGlvbiAoZXZlbnQpIHt9LFxyXG4gICB8ICAgb25tb3ZlIDogZnVuY3Rpb24gKGV2ZW50KSB7fSxcclxuICAgfCAgIG9uZW5kICA6IGZ1bmN0aW9uIChldmVudCkge30sXHJcbiAgIHxcclxuICAgfCAgIGVkZ2VzOiB7XHJcbiAgIHwgICAgIHRvcCAgIDogdHJ1ZSwgICAgICAgLy8gVXNlIHBvaW50ZXIgY29vcmRzIHRvIGNoZWNrIGZvciByZXNpemUuXHJcbiAgIHwgICAgIGxlZnQgIDogZmFsc2UsICAgICAgLy8gRGlzYWJsZSByZXNpemluZyBmcm9tIGxlZnQgZWRnZS5cclxuICAgfCAgICAgYm90dG9tOiAnLnJlc2l6ZS1zJywvLyBSZXNpemUgaWYgcG9pbnRlciB0YXJnZXQgbWF0Y2hlcyBzZWxlY3RvclxyXG4gICB8ICAgICByaWdodCA6IGhhbmRsZUVsICAgIC8vIFJlc2l6ZSBpZiBwb2ludGVyIHRhcmdldCBpcyB0aGUgZ2l2ZW4gRWxlbWVudFxyXG4gICB8ICAgfSxcclxuICAgfFxyXG4gICB8ICAgICAvLyBXaWR0aCBhbmQgaGVpZ2h0IGNhbiBiZSBhZGp1c3RlZCBpbmRlcGVuZGVudGx5LiBXaGVuIGB0cnVlYCwgd2lkdGggYW5kXHJcbiAgIHwgICAgIC8vIGhlaWdodCBhcmUgYWRqdXN0ZWQgYXQgYSAxOjEgcmF0aW8uXHJcbiAgIHwgICAgIHNxdWFyZTogZmFsc2UsXHJcbiAgIHxcclxuICAgfCAgICAgLy8gV2lkdGggYW5kIGhlaWdodCBjYW4gYmUgYWRqdXN0ZWQgaW5kZXBlbmRlbnRseS4gV2hlbiBgdHJ1ZWAsIHdpZHRoIGFuZFxyXG4gICB8ICAgICAvLyBoZWlnaHQgbWFpbnRhaW4gdGhlIGFzcGVjdCByYXRpbyB0aGV5IGhhZCB3aGVuIHJlc2l6aW5nIHN0YXJ0ZWQuXHJcbiAgIHwgICAgIHByZXNlcnZlQXNwZWN0UmF0aW86IGZhbHNlLFxyXG4gICB8XHJcbiAgIHwgICAvLyBhIHZhbHVlIG9mICdub25lJyB3aWxsIGxpbWl0IHRoZSByZXNpemUgcmVjdCB0byBhIG1pbmltdW0gb2YgMHgwXHJcbiAgIHwgICAvLyAnbmVnYXRlJyB3aWxsIGFsbG93IHRoZSByZWN0IHRvIGhhdmUgbmVnYXRpdmUgd2lkdGgvaGVpZ2h0XHJcbiAgIHwgICAvLyAncmVwb3NpdGlvbicgd2lsbCBrZWVwIHRoZSB3aWR0aC9oZWlnaHQgcG9zaXRpdmUgYnkgc3dhcHBpbmdcclxuICAgfCAgIC8vIHRoZSB0b3AgYW5kIGJvdHRvbSBlZGdlcyBhbmQvb3Igc3dhcHBpbmcgdGhlIGxlZnQgYW5kIHJpZ2h0IGVkZ2VzXHJcbiAgIHwgICBpbnZlcnQ6ICdub25lJyB8fCAnbmVnYXRlJyB8fCAncmVwb3NpdGlvbidcclxuICAgfFxyXG4gICB8ICAgLy8gbGltaXQgbXVsdGlwbGUgcmVzaXplcy5cclxuICAgfCAgIC8vIFNlZSB0aGUgZXhwbGFuYXRpb24gaW4gdGhlIEBJbnRlcmFjdGFibGUuZHJhZ2dhYmxlIGV4YW1wbGVcclxuICAgfCAgIG1heDogSW5maW5pdHksXHJcbiAgIHwgICBtYXhQZXJFbGVtZW50OiAxLFxyXG4gICB8IH0pO1xyXG4gIFxcKi9cclxuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5yZXNpemFibGUgPSBmdW5jdGlvbiAob3B0aW9ucykge1xyXG4gIGlmICh1dGlscy5pcy5vYmplY3Qob3B0aW9ucykpIHtcclxuICAgIHRoaXMub3B0aW9ucy5yZXNpemUuZW5hYmxlZCA9IG9wdGlvbnMuZW5hYmxlZCA9PT0gZmFsc2UgPyBmYWxzZSA6IHRydWU7XHJcbiAgICB0aGlzLnNldFBlckFjdGlvbigncmVzaXplJywgb3B0aW9ucyk7XHJcbiAgICB0aGlzLnNldE9uRXZlbnRzKCdyZXNpemUnLCBvcHRpb25zKTtcclxuXHJcbiAgICBpZiAoL154JHxeeSR8Xnh5JC8udGVzdChvcHRpb25zLmF4aXMpKSB7XHJcbiAgICAgIHRoaXMub3B0aW9ucy5yZXNpemUuYXhpcyA9IG9wdGlvbnMuYXhpcztcclxuICAgIH0gZWxzZSBpZiAob3B0aW9ucy5heGlzID09PSBudWxsKSB7XHJcbiAgICAgIHRoaXMub3B0aW9ucy5yZXNpemUuYXhpcyA9IGRlZmF1bHRPcHRpb25zLnJlc2l6ZS5heGlzO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh1dGlscy5pcy5ib29sKG9wdGlvbnMucHJlc2VydmVBc3BlY3RSYXRpbykpIHtcclxuICAgICAgdGhpcy5vcHRpb25zLnJlc2l6ZS5wcmVzZXJ2ZUFzcGVjdFJhdGlvID0gb3B0aW9ucy5wcmVzZXJ2ZUFzcGVjdFJhdGlvO1xyXG4gICAgfSBlbHNlIGlmICh1dGlscy5pcy5ib29sKG9wdGlvbnMuc3F1YXJlKSkge1xyXG4gICAgICB0aGlzLm9wdGlvbnMucmVzaXplLnNxdWFyZSA9IG9wdGlvbnMuc3F1YXJlO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuICBpZiAodXRpbHMuaXMuYm9vbChvcHRpb25zKSkge1xyXG4gICAgdGhpcy5vcHRpb25zLnJlc2l6ZS5lbmFibGVkID0gb3B0aW9ucztcclxuXHJcbiAgICBpZiAoIW9wdGlvbnMpIHtcclxuICAgICAgdGhpcy5vbnJlc2l6ZXN0YXJ0ID0gdGhpcy5vbnJlc2l6ZXN0YXJ0ID0gdGhpcy5vbnJlc2l6ZWVuZCA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG4gIHJldHVybiB0aGlzLm9wdGlvbnMucmVzaXplO1xyXG59O1xyXG5cclxuZnVuY3Rpb24gY2hlY2tSZXNpemVFZGdlKG5hbWUsIHZhbHVlLCBwYWdlLCBlbGVtZW50LCBpbnRlcmFjdGFibGVFbGVtZW50LCByZWN0LCBtYXJnaW4pIHtcclxuICAvLyBmYWxzZSwgJycsIHVuZGVmaW5lZCwgbnVsbFxyXG4gIGlmICghdmFsdWUpIHtcclxuICAgIHJldHVybiBmYWxzZTtcclxuICB9XHJcblxyXG4gIC8vIHRydWUgdmFsdWUsIHVzZSBwb2ludGVyIGNvb3JkcyBhbmQgZWxlbWVudCByZWN0XHJcbiAgaWYgKHZhbHVlID09PSB0cnVlKSB7XHJcbiAgICAvLyBpZiBkaW1lbnNpb25zIGFyZSBuZWdhdGl2ZSwgXCJzd2l0Y2hcIiBlZGdlc1xyXG4gICAgdmFyIHdpZHRoID0gdXRpbHMuaXMubnVtYmVyKHJlY3Qud2lkdGgpID8gcmVjdC53aWR0aCA6IHJlY3QucmlnaHQgLSByZWN0LmxlZnQ7XHJcbiAgICB2YXIgaGVpZ2h0ID0gdXRpbHMuaXMubnVtYmVyKHJlY3QuaGVpZ2h0KSA/IHJlY3QuaGVpZ2h0IDogcmVjdC5ib3R0b20gLSByZWN0LnRvcDtcclxuXHJcbiAgICBpZiAod2lkdGggPCAwKSB7XHJcbiAgICAgIGlmIChuYW1lID09PSAnbGVmdCcpIHtcclxuICAgICAgICBuYW1lID0gJ3JpZ2h0JztcclxuICAgICAgfSBlbHNlIGlmIChuYW1lID09PSAncmlnaHQnKSB7XHJcbiAgICAgICAgbmFtZSA9ICdsZWZ0JztcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKGhlaWdodCA8IDApIHtcclxuICAgICAgaWYgKG5hbWUgPT09ICd0b3AnKSB7XHJcbiAgICAgICAgbmFtZSA9ICdib3R0b20nO1xyXG4gICAgICB9IGVsc2UgaWYgKG5hbWUgPT09ICdib3R0b20nKSB7XHJcbiAgICAgICAgbmFtZSA9ICd0b3AnO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKG5hbWUgPT09ICdsZWZ0Jykge1xyXG4gICAgICByZXR1cm4gcGFnZS54IDwgKHdpZHRoID49IDAgPyByZWN0LmxlZnQgOiByZWN0LnJpZ2h0KSArIG1hcmdpbjtcclxuICAgIH1cclxuICAgIGlmIChuYW1lID09PSAndG9wJykge1xyXG4gICAgICByZXR1cm4gcGFnZS55IDwgKGhlaWdodCA+PSAwID8gcmVjdC50b3AgOiByZWN0LmJvdHRvbSkgKyBtYXJnaW47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKG5hbWUgPT09ICdyaWdodCcpIHtcclxuICAgICAgcmV0dXJuIHBhZ2UueCA+ICh3aWR0aCA+PSAwID8gcmVjdC5yaWdodCA6IHJlY3QubGVmdCkgLSBtYXJnaW47XHJcbiAgICB9XHJcbiAgICBpZiAobmFtZSA9PT0gJ2JvdHRvbScpIHtcclxuICAgICAgcmV0dXJuIHBhZ2UueSA+IChoZWlnaHQgPj0gMCA/IHJlY3QuYm90dG9tIDogcmVjdC50b3ApIC0gbWFyZ2luO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy8gdGhlIHJlbWFpbmluZyBjaGVja3MgcmVxdWlyZSBhbiBlbGVtZW50XHJcbiAgaWYgKCF1dGlscy5pcy5lbGVtZW50KGVsZW1lbnQpKSB7XHJcbiAgICByZXR1cm4gZmFsc2U7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gdXRpbHMuaXMuZWxlbWVudCh2YWx1ZSlcclxuICAvLyB0aGUgdmFsdWUgaXMgYW4gZWxlbWVudCB0byB1c2UgYXMgYSByZXNpemUgaGFuZGxlXHJcbiAgPyB2YWx1ZSA9PT0gZWxlbWVudFxyXG4gIC8vIG90aGVyd2lzZSBjaGVjayBpZiBlbGVtZW50IG1hdGNoZXMgdmFsdWUgYXMgc2VsZWN0b3JcclxuICA6IHV0aWxzLm1hdGNoZXNVcFRvKGVsZW1lbnQsIHZhbHVlLCBpbnRlcmFjdGFibGVFbGVtZW50KTtcclxufVxyXG5cclxuSW50ZXJhY3Rpb24uc2lnbmFscy5vbignbmV3JywgZnVuY3Rpb24gKGludGVyYWN0aW9uKSB7XHJcbiAgaW50ZXJhY3Rpb24ucmVzaXplQXhlcyA9ICd4eSc7XHJcbn0pO1xyXG5cclxuSW50ZXJhY3RFdmVudC5zaWduYWxzLm9uKCdzZXQtZGVsdGEnLCBmdW5jdGlvbiAoX3JlZjMpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmMy5pbnRlcmFjdGlvbixcclxuICAgICAgaUV2ZW50ID0gX3JlZjMuaUV2ZW50LFxyXG4gICAgICBhY3Rpb24gPSBfcmVmMy5hY3Rpb247XHJcblxyXG4gIGlmIChhY3Rpb24gIT09ICdyZXNpemUnIHx8ICFpbnRlcmFjdGlvbi5yZXNpemVBeGVzKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICB2YXIgb3B0aW9ucyA9IGludGVyYWN0aW9uLnRhcmdldC5vcHRpb25zO1xyXG5cclxuICBpZiAob3B0aW9ucy5yZXNpemUuc3F1YXJlKSB7XHJcbiAgICBpZiAoaW50ZXJhY3Rpb24ucmVzaXplQXhlcyA9PT0gJ3knKSB7XHJcbiAgICAgIGlFdmVudC5keCA9IGlFdmVudC5keTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGlFdmVudC5keSA9IGlFdmVudC5keDtcclxuICAgIH1cclxuICAgIGlFdmVudC5heGVzID0gJ3h5JztcclxuICB9IGVsc2Uge1xyXG4gICAgaUV2ZW50LmF4ZXMgPSBpbnRlcmFjdGlvbi5yZXNpemVBeGVzO1xyXG5cclxuICAgIGlmIChpbnRlcmFjdGlvbi5yZXNpemVBeGVzID09PSAneCcpIHtcclxuICAgICAgaUV2ZW50LmR5ID0gMDtcclxuICAgIH0gZWxzZSBpZiAoaW50ZXJhY3Rpb24ucmVzaXplQXhlcyA9PT0gJ3knKSB7XHJcbiAgICAgIGlFdmVudC5keCA9IDA7XHJcbiAgICB9XHJcbiAgfVxyXG59KTtcclxuXHJcbmFjdGlvbnMucmVzaXplID0gcmVzaXplO1xyXG5hY3Rpb25zLm5hbWVzLnB1c2goJ3Jlc2l6ZScpO1xyXG51dGlscy5tZXJnZShJbnRlcmFjdGFibGUuZXZlbnRUeXBlcywgWydyZXNpemVzdGFydCcsICdyZXNpemVtb3ZlJywgJ3Jlc2l6ZWluZXJ0aWFzdGFydCcsICdyZXNpemVpbmVydGlhcmVzdW1lJywgJ3Jlc2l6ZWVuZCddKTtcclxuYWN0aW9ucy5tZXRob2REaWN0LnJlc2l6ZSA9ICdyZXNpemFibGUnO1xyXG5cclxuZGVmYXVsdE9wdGlvbnMucmVzaXplID0gcmVzaXplLmRlZmF1bHRzO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSByZXNpemU7XHJcblxyXG59LHtcIi4uL0ludGVyYWN0RXZlbnRcIjozLFwiLi4vSW50ZXJhY3RhYmxlXCI6NCxcIi4uL0ludGVyYWN0aW9uXCI6NSxcIi4uL2RlZmF1bHRPcHRpb25zXCI6MTgsXCIuLi91dGlsc1wiOjQ0LFwiLi4vdXRpbHMvYnJvd3NlclwiOjM3LFwiLi9iYXNlXCI6Nn1dLDExOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIHJhZiA9IHJlcXVpcmUoJy4vdXRpbHMvcmFmJyk7XHJcbnZhciBnZXRXaW5kb3cgPSByZXF1aXJlKCcuL3V0aWxzL3dpbmRvdycpLmdldFdpbmRvdztcclxudmFyIGlzID0gcmVxdWlyZSgnLi91dGlscy9pcycpO1xyXG52YXIgZG9tVXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzL2RvbVV0aWxzJyk7XHJcbnZhciBJbnRlcmFjdGlvbiA9IHJlcXVpcmUoJy4vSW50ZXJhY3Rpb24nKTtcclxudmFyIGRlZmF1bHRPcHRpb25zID0gcmVxdWlyZSgnLi9kZWZhdWx0T3B0aW9ucycpO1xyXG5cclxudmFyIGF1dG9TY3JvbGwgPSB7XHJcbiAgZGVmYXVsdHM6IHtcclxuICAgIGVuYWJsZWQ6IGZhbHNlLFxyXG4gICAgY29udGFpbmVyOiBudWxsLCAvLyB0aGUgaXRlbSB0aGF0IGlzIHNjcm9sbGVkIChXaW5kb3cgb3IgSFRNTEVsZW1lbnQpXHJcbiAgICBtYXJnaW46IDYwLFxyXG4gICAgc3BlZWQ6IDMwMCAvLyB0aGUgc2Nyb2xsIHNwZWVkIGluIHBpeGVscyBwZXIgc2Vjb25kXHJcbiAgfSxcclxuXHJcbiAgaW50ZXJhY3Rpb246IG51bGwsXHJcbiAgaTogbnVsbCwgLy8gdGhlIGhhbmRsZSByZXR1cm5lZCBieSB3aW5kb3cuc2V0SW50ZXJ2YWxcclxuICB4OiAwLCB5OiAwLCAvLyBEaXJlY3Rpb24gZWFjaCBwdWxzZSBpcyB0byBzY3JvbGwgaW5cclxuXHJcbiAgaXNTY3JvbGxpbmc6IGZhbHNlLFxyXG4gIHByZXZUaW1lOiAwLFxyXG5cclxuICBzdGFydDogZnVuY3Rpb24gc3RhcnQoaW50ZXJhY3Rpb24pIHtcclxuICAgIGF1dG9TY3JvbGwuaXNTY3JvbGxpbmcgPSB0cnVlO1xyXG4gICAgcmFmLmNhbmNlbChhdXRvU2Nyb2xsLmkpO1xyXG5cclxuICAgIGF1dG9TY3JvbGwuaW50ZXJhY3Rpb24gPSBpbnRlcmFjdGlvbjtcclxuICAgIGF1dG9TY3JvbGwucHJldlRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcclxuICAgIGF1dG9TY3JvbGwuaSA9IHJhZi5yZXF1ZXN0KGF1dG9TY3JvbGwuc2Nyb2xsKTtcclxuICB9LFxyXG5cclxuICBzdG9wOiBmdW5jdGlvbiBzdG9wKCkge1xyXG4gICAgYXV0b1Njcm9sbC5pc1Njcm9sbGluZyA9IGZhbHNlO1xyXG4gICAgcmFmLmNhbmNlbChhdXRvU2Nyb2xsLmkpO1xyXG4gIH0sXHJcblxyXG4gIC8vIHNjcm9sbCB0aGUgd2luZG93IGJ5IHRoZSB2YWx1ZXMgaW4gc2Nyb2xsLngveVxyXG4gIHNjcm9sbDogZnVuY3Rpb24gc2Nyb2xsKCkge1xyXG4gICAgdmFyIG9wdGlvbnMgPSBhdXRvU2Nyb2xsLmludGVyYWN0aW9uLnRhcmdldC5vcHRpb25zW2F1dG9TY3JvbGwuaW50ZXJhY3Rpb24ucHJlcGFyZWQubmFtZV0uYXV0b1Njcm9sbDtcclxuICAgIHZhciBjb250YWluZXIgPSBvcHRpb25zLmNvbnRhaW5lciB8fCBnZXRXaW5kb3coYXV0b1Njcm9sbC5pbnRlcmFjdGlvbi5lbGVtZW50KTtcclxuICAgIHZhciBub3cgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcclxuICAgIC8vIGNoYW5nZSBpbiB0aW1lIGluIHNlY29uZHNcclxuICAgIHZhciBkdCA9IChub3cgLSBhdXRvU2Nyb2xsLnByZXZUaW1lKSAvIDEwMDA7XHJcbiAgICAvLyBkaXNwbGFjZW1lbnRcclxuICAgIHZhciBzID0gb3B0aW9ucy5zcGVlZCAqIGR0O1xyXG5cclxuICAgIGlmIChzID49IDEpIHtcclxuICAgICAgaWYgKGlzLndpbmRvdyhjb250YWluZXIpKSB7XHJcbiAgICAgICAgY29udGFpbmVyLnNjcm9sbEJ5KGF1dG9TY3JvbGwueCAqIHMsIGF1dG9TY3JvbGwueSAqIHMpO1xyXG4gICAgICB9IGVsc2UgaWYgKGNvbnRhaW5lcikge1xyXG4gICAgICAgIGNvbnRhaW5lci5zY3JvbGxMZWZ0ICs9IGF1dG9TY3JvbGwueCAqIHM7XHJcbiAgICAgICAgY29udGFpbmVyLnNjcm9sbFRvcCArPSBhdXRvU2Nyb2xsLnkgKiBzO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBhdXRvU2Nyb2xsLnByZXZUaW1lID0gbm93O1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChhdXRvU2Nyb2xsLmlzU2Nyb2xsaW5nKSB7XHJcbiAgICAgIHJhZi5jYW5jZWwoYXV0b1Njcm9sbC5pKTtcclxuICAgICAgYXV0b1Njcm9sbC5pID0gcmFmLnJlcXVlc3QoYXV0b1Njcm9sbC5zY3JvbGwpO1xyXG4gICAgfVxyXG4gIH0sXHJcbiAgY2hlY2s6IGZ1bmN0aW9uIGNoZWNrKGludGVyYWN0YWJsZSwgYWN0aW9uTmFtZSkge1xyXG4gICAgdmFyIG9wdGlvbnMgPSBpbnRlcmFjdGFibGUub3B0aW9ucztcclxuXHJcbiAgICByZXR1cm4gb3B0aW9uc1thY3Rpb25OYW1lXS5hdXRvU2Nyb2xsICYmIG9wdGlvbnNbYWN0aW9uTmFtZV0uYXV0b1Njcm9sbC5lbmFibGVkO1xyXG4gIH0sXHJcbiAgb25JbnRlcmFjdGlvbk1vdmU6IGZ1bmN0aW9uIG9uSW50ZXJhY3Rpb25Nb3ZlKF9yZWYpIHtcclxuICAgIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYuaW50ZXJhY3Rpb24sXHJcbiAgICAgICAgcG9pbnRlciA9IF9yZWYucG9pbnRlcjtcclxuXHJcbiAgICBpZiAoIShpbnRlcmFjdGlvbi5pbnRlcmFjdGluZygpICYmIGF1dG9TY3JvbGwuY2hlY2soaW50ZXJhY3Rpb24udGFyZ2V0LCBpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lKSkpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChpbnRlcmFjdGlvbi5zaW11bGF0aW9uKSB7XHJcbiAgICAgIGF1dG9TY3JvbGwueCA9IGF1dG9TY3JvbGwueSA9IDA7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgdG9wID0gdm9pZCAwO1xyXG4gICAgdmFyIHJpZ2h0ID0gdm9pZCAwO1xyXG4gICAgdmFyIGJvdHRvbSA9IHZvaWQgMDtcclxuICAgIHZhciBsZWZ0ID0gdm9pZCAwO1xyXG5cclxuICAgIHZhciBvcHRpb25zID0gaW50ZXJhY3Rpb24udGFyZ2V0Lm9wdGlvbnNbaW50ZXJhY3Rpb24ucHJlcGFyZWQubmFtZV0uYXV0b1Njcm9sbDtcclxuICAgIHZhciBjb250YWluZXIgPSBvcHRpb25zLmNvbnRhaW5lciB8fCBnZXRXaW5kb3coaW50ZXJhY3Rpb24uZWxlbWVudCk7XHJcblxyXG4gICAgaWYgKGlzLndpbmRvdyhjb250YWluZXIpKSB7XHJcbiAgICAgIGxlZnQgPSBwb2ludGVyLmNsaWVudFggPCBhdXRvU2Nyb2xsLm1hcmdpbjtcclxuICAgICAgdG9wID0gcG9pbnRlci5jbGllbnRZIDwgYXV0b1Njcm9sbC5tYXJnaW47XHJcbiAgICAgIHJpZ2h0ID0gcG9pbnRlci5jbGllbnRYID4gY29udGFpbmVyLmlubmVyV2lkdGggLSBhdXRvU2Nyb2xsLm1hcmdpbjtcclxuICAgICAgYm90dG9tID0gcG9pbnRlci5jbGllbnRZID4gY29udGFpbmVyLmlubmVySGVpZ2h0IC0gYXV0b1Njcm9sbC5tYXJnaW47XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB2YXIgcmVjdCA9IGRvbVV0aWxzLmdldEVsZW1lbnRDbGllbnRSZWN0KGNvbnRhaW5lcik7XHJcblxyXG4gICAgICBsZWZ0ID0gcG9pbnRlci5jbGllbnRYIDwgcmVjdC5sZWZ0ICsgYXV0b1Njcm9sbC5tYXJnaW47XHJcbiAgICAgIHRvcCA9IHBvaW50ZXIuY2xpZW50WSA8IHJlY3QudG9wICsgYXV0b1Njcm9sbC5tYXJnaW47XHJcbiAgICAgIHJpZ2h0ID0gcG9pbnRlci5jbGllbnRYID4gcmVjdC5yaWdodCAtIGF1dG9TY3JvbGwubWFyZ2luO1xyXG4gICAgICBib3R0b20gPSBwb2ludGVyLmNsaWVudFkgPiByZWN0LmJvdHRvbSAtIGF1dG9TY3JvbGwubWFyZ2luO1xyXG4gICAgfVxyXG5cclxuICAgIGF1dG9TY3JvbGwueCA9IHJpZ2h0ID8gMSA6IGxlZnQgPyAtMSA6IDA7XHJcbiAgICBhdXRvU2Nyb2xsLnkgPSBib3R0b20gPyAxIDogdG9wID8gLTEgOiAwO1xyXG5cclxuICAgIGlmICghYXV0b1Njcm9sbC5pc1Njcm9sbGluZykge1xyXG4gICAgICAvLyBzZXQgdGhlIGF1dG9TY3JvbGwgcHJvcGVydGllcyB0byB0aG9zZSBvZiB0aGUgdGFyZ2V0XHJcbiAgICAgIGF1dG9TY3JvbGwubWFyZ2luID0gb3B0aW9ucy5tYXJnaW47XHJcbiAgICAgIGF1dG9TY3JvbGwuc3BlZWQgPSBvcHRpb25zLnNwZWVkO1xyXG5cclxuICAgICAgYXV0b1Njcm9sbC5zdGFydChpbnRlcmFjdGlvbik7XHJcbiAgICB9XHJcbiAgfVxyXG59O1xyXG5cclxuSW50ZXJhY3Rpb24uc2lnbmFscy5vbignc3RvcC1hY3RpdmUnLCBmdW5jdGlvbiAoKSB7XHJcbiAgYXV0b1Njcm9sbC5zdG9wKCk7XHJcbn0pO1xyXG5cclxuSW50ZXJhY3Rpb24uc2lnbmFscy5vbignYWN0aW9uLW1vdmUnLCBhdXRvU2Nyb2xsLm9uSW50ZXJhY3Rpb25Nb3ZlKTtcclxuXHJcbmRlZmF1bHRPcHRpb25zLnBlckFjdGlvbi5hdXRvU2Nyb2xsID0gYXV0b1Njcm9sbC5kZWZhdWx0cztcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gYXV0b1Njcm9sbDtcclxuXHJcbn0se1wiLi9JbnRlcmFjdGlvblwiOjUsXCIuL2RlZmF1bHRPcHRpb25zXCI6MTgsXCIuL3V0aWxzL2RvbVV0aWxzXCI6MzksXCIuL3V0aWxzL2lzXCI6NDYsXCIuL3V0aWxzL3JhZlwiOjUwLFwiLi91dGlscy93aW5kb3dcIjo1Mn1dLDEyOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIEludGVyYWN0YWJsZSA9IHJlcXVpcmUoJy4uL0ludGVyYWN0YWJsZScpO1xyXG52YXIgYWN0aW9ucyA9IHJlcXVpcmUoJy4uL2FjdGlvbnMvYmFzZScpO1xyXG52YXIgaXMgPSByZXF1aXJlKCcuLi91dGlscy9pcycpO1xyXG52YXIgZG9tVXRpbHMgPSByZXF1aXJlKCcuLi91dGlscy9kb21VdGlscycpO1xyXG5cclxuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5nZXRBY3Rpb24gPSBmdW5jdGlvbiAocG9pbnRlciwgZXZlbnQsIGludGVyYWN0aW9uLCBlbGVtZW50KSB7XHJcbiAgdmFyIGFjdGlvbiA9IHRoaXMuZGVmYXVsdEFjdGlvbkNoZWNrZXIocG9pbnRlciwgZXZlbnQsIGludGVyYWN0aW9uLCBlbGVtZW50KTtcclxuXHJcbiAgaWYgKHRoaXMub3B0aW9ucy5hY3Rpb25DaGVja2VyKSB7XHJcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zLmFjdGlvbkNoZWNrZXIocG9pbnRlciwgZXZlbnQsIGFjdGlvbiwgdGhpcywgZWxlbWVudCwgaW50ZXJhY3Rpb24pO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIGFjdGlvbjtcclxufTtcclxuXHJcbi8qXFxcclxuICogSW50ZXJhY3RhYmxlLmlnbm9yZUZyb21cclxuIFsgbWV0aG9kIF1cclxuICpcclxuICogSWYgdGhlIHRhcmdldCBvZiB0aGUgYG1vdXNlZG93bmAsIGBwb2ludGVyZG93bmAgb3IgYHRvdWNoc3RhcnRgXHJcbiAqIGV2ZW50IG9yIGFueSBvZiBpdCdzIHBhcmVudHMgbWF0Y2ggdGhlIGdpdmVuIENTUyBzZWxlY3RvciBvclxyXG4gKiBFbGVtZW50LCBubyBkcmFnL3Jlc2l6ZS9nZXN0dXJlIGlzIHN0YXJ0ZWQuXHJcbiAqXHJcbiAtIG5ld1ZhbHVlIChzdHJpbmcgfCBFbGVtZW50IHwgbnVsbCkgI29wdGlvbmFsIGEgQ1NTIHNlbGVjdG9yIHN0cmluZywgYW4gRWxlbWVudCBvciBgbnVsbGAgdG8gbm90IGlnbm9yZSBhbnkgZWxlbWVudHNcclxuID0gKHN0cmluZyB8IEVsZW1lbnQgfCBvYmplY3QpIFRoZSBjdXJyZW50IGlnbm9yZUZyb20gdmFsdWUgb3IgdGhpcyBJbnRlcmFjdGFibGVcclxuICoqXHJcbiB8IGludGVyYWN0KGVsZW1lbnQsIHsgaWdub3JlRnJvbTogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ25vLWFjdGlvbicpIH0pO1xyXG4gfCAvLyBvclxyXG4gfCBpbnRlcmFjdChlbGVtZW50KS5pZ25vcmVGcm9tKCdpbnB1dCwgdGV4dGFyZWEsIGEnKTtcclxuXFwqL1xyXG5JbnRlcmFjdGFibGUucHJvdG90eXBlLmlnbm9yZUZyb20gPSBmdW5jdGlvbiAobmV3VmFsdWUpIHtcclxuICByZXR1cm4gdGhpcy5fYmFja0NvbXBhdE9wdGlvbignaWdub3JlRnJvbScsIG5ld1ZhbHVlKTtcclxufTtcclxuXHJcbi8qXFxcclxuICogSW50ZXJhY3RhYmxlLmFsbG93RnJvbVxyXG4gWyBtZXRob2QgXVxyXG4gKlxyXG4gKiBBIGRyYWcvcmVzaXplL2dlc3R1cmUgaXMgc3RhcnRlZCBvbmx5IElmIHRoZSB0YXJnZXQgb2YgdGhlXHJcbiAqIGBtb3VzZWRvd25gLCBgcG9pbnRlcmRvd25gIG9yIGB0b3VjaHN0YXJ0YCBldmVudCBvciBhbnkgb2YgaXQnc1xyXG4gKiBwYXJlbnRzIG1hdGNoIHRoZSBnaXZlbiBDU1Mgc2VsZWN0b3Igb3IgRWxlbWVudC5cclxuICpcclxuIC0gbmV3VmFsdWUgKHN0cmluZyB8IEVsZW1lbnQgfCBudWxsKSAjb3B0aW9uYWwgYSBDU1Mgc2VsZWN0b3Igc3RyaW5nLCBhbiBFbGVtZW50IG9yIGBudWxsYCB0byBhbGxvdyBmcm9tIGFueSBlbGVtZW50XHJcbiA9IChzdHJpbmcgfCBFbGVtZW50IHwgb2JqZWN0KSBUaGUgY3VycmVudCBhbGxvd0Zyb20gdmFsdWUgb3IgdGhpcyBJbnRlcmFjdGFibGVcclxuICoqXHJcbiB8IGludGVyYWN0KGVsZW1lbnQsIHsgYWxsb3dGcm9tOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZHJhZy1oYW5kbGUnKSB9KTtcclxuIHwgLy8gb3JcclxuIHwgaW50ZXJhY3QoZWxlbWVudCkuYWxsb3dGcm9tKCcuaGFuZGxlJyk7XHJcblxcKi9cclxuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5hbGxvd0Zyb20gPSBmdW5jdGlvbiAobmV3VmFsdWUpIHtcclxuICByZXR1cm4gdGhpcy5fYmFja0NvbXBhdE9wdGlvbignYWxsb3dGcm9tJywgbmV3VmFsdWUpO1xyXG59O1xyXG5cclxuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS50ZXN0SWdub3JlID0gZnVuY3Rpb24gKGlnbm9yZUZyb20sIGludGVyYWN0YWJsZUVsZW1lbnQsIGVsZW1lbnQpIHtcclxuICBpZiAoIWlnbm9yZUZyb20gfHwgIWlzLmVsZW1lbnQoZWxlbWVudCkpIHtcclxuICAgIHJldHVybiBmYWxzZTtcclxuICB9XHJcblxyXG4gIGlmIChpcy5zdHJpbmcoaWdub3JlRnJvbSkpIHtcclxuICAgIHJldHVybiBkb21VdGlscy5tYXRjaGVzVXBUbyhlbGVtZW50LCBpZ25vcmVGcm9tLCBpbnRlcmFjdGFibGVFbGVtZW50KTtcclxuICB9IGVsc2UgaWYgKGlzLmVsZW1lbnQoaWdub3JlRnJvbSkpIHtcclxuICAgIHJldHVybiBkb21VdGlscy5ub2RlQ29udGFpbnMoaWdub3JlRnJvbSwgZWxlbWVudCk7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gZmFsc2U7XHJcbn07XHJcblxyXG5JbnRlcmFjdGFibGUucHJvdG90eXBlLnRlc3RBbGxvdyA9IGZ1bmN0aW9uIChhbGxvd0Zyb20sIGludGVyYWN0YWJsZUVsZW1lbnQsIGVsZW1lbnQpIHtcclxuICBpZiAoIWFsbG93RnJvbSkge1xyXG4gICAgcmV0dXJuIHRydWU7XHJcbiAgfVxyXG5cclxuICBpZiAoIWlzLmVsZW1lbnQoZWxlbWVudCkpIHtcclxuICAgIHJldHVybiBmYWxzZTtcclxuICB9XHJcblxyXG4gIGlmIChpcy5zdHJpbmcoYWxsb3dGcm9tKSkge1xyXG4gICAgcmV0dXJuIGRvbVV0aWxzLm1hdGNoZXNVcFRvKGVsZW1lbnQsIGFsbG93RnJvbSwgaW50ZXJhY3RhYmxlRWxlbWVudCk7XHJcbiAgfSBlbHNlIGlmIChpcy5lbGVtZW50KGFsbG93RnJvbSkpIHtcclxuICAgIHJldHVybiBkb21VdGlscy5ub2RlQ29udGFpbnMoYWxsb3dGcm9tLCBlbGVtZW50KTtcclxuICB9XHJcblxyXG4gIHJldHVybiBmYWxzZTtcclxufTtcclxuXHJcbkludGVyYWN0YWJsZS5wcm90b3R5cGUudGVzdElnbm9yZUFsbG93ID0gZnVuY3Rpb24gKG9wdGlvbnMsIGludGVyYWN0YWJsZUVsZW1lbnQsIGV2ZW50VGFyZ2V0KSB7XHJcbiAgcmV0dXJuICF0aGlzLnRlc3RJZ25vcmUob3B0aW9ucy5pZ25vcmVGcm9tLCBpbnRlcmFjdGFibGVFbGVtZW50LCBldmVudFRhcmdldCkgJiYgdGhpcy50ZXN0QWxsb3cob3B0aW9ucy5hbGxvd0Zyb20sIGludGVyYWN0YWJsZUVsZW1lbnQsIGV2ZW50VGFyZ2V0KTtcclxufTtcclxuXHJcbi8qXFxcclxuICogSW50ZXJhY3RhYmxlLmFjdGlvbkNoZWNrZXJcclxuIFsgbWV0aG9kIF1cclxuICpcclxuICogR2V0cyBvciBzZXRzIHRoZSBmdW5jdGlvbiB1c2VkIHRvIGNoZWNrIGFjdGlvbiB0byBiZSBwZXJmb3JtZWQgb25cclxuICogcG9pbnRlckRvd25cclxuICpcclxuIC0gY2hlY2tlciAoZnVuY3Rpb24gfCBudWxsKSAjb3B0aW9uYWwgQSBmdW5jdGlvbiB3aGljaCB0YWtlcyBhIHBvaW50ZXIgZXZlbnQsIGRlZmF1bHRBY3Rpb24gc3RyaW5nLCBpbnRlcmFjdGFibGUsIGVsZW1lbnQgYW5kIGludGVyYWN0aW9uIGFzIHBhcmFtZXRlcnMgYW5kIHJldHVybnMgYW4gb2JqZWN0IHdpdGggbmFtZSBwcm9wZXJ0eSAnZHJhZycgJ3Jlc2l6ZScgb3IgJ2dlc3R1cmUnIGFuZCBvcHRpb25hbGx5IGFuIGBlZGdlc2Agb2JqZWN0IHdpdGggYm9vbGVhbiAndG9wJywgJ2xlZnQnLCAnYm90dG9tJyBhbmQgcmlnaHQgcHJvcHMuXHJcbiA9IChGdW5jdGlvbiB8IEludGVyYWN0YWJsZSkgVGhlIGNoZWNrZXIgZnVuY3Rpb24gb3IgdGhpcyBJbnRlcmFjdGFibGVcclxuICpcclxuIHwgaW50ZXJhY3QoJy5yZXNpemUtZHJhZycpXHJcbiB8ICAgLnJlc2l6YWJsZSh0cnVlKVxyXG4gfCAgIC5kcmFnZ2FibGUodHJ1ZSlcclxuIHwgICAuYWN0aW9uQ2hlY2tlcihmdW5jdGlvbiAocG9pbnRlciwgZXZlbnQsIGFjdGlvbiwgaW50ZXJhY3RhYmxlLCBlbGVtZW50LCBpbnRlcmFjdGlvbikge1xyXG4gfFxyXG4gfCAgIGlmIChpbnRlcmFjdC5tYXRjaGVzU2VsZWN0b3IoZXZlbnQudGFyZ2V0LCAnLmRyYWctaGFuZGxlJykge1xyXG4gfCAgICAgLy8gZm9yY2UgZHJhZyB3aXRoIGhhbmRsZSB0YXJnZXRcclxuIHwgICAgIGFjdGlvbi5uYW1lID0gZHJhZztcclxuIHwgICB9XHJcbiB8ICAgZWxzZSB7XHJcbiB8ICAgICAvLyByZXNpemUgZnJvbSB0aGUgdG9wIGFuZCByaWdodCBlZGdlc1xyXG4gfCAgICAgYWN0aW9uLm5hbWUgID0gJ3Jlc2l6ZSc7XHJcbiB8ICAgICBhY3Rpb24uZWRnZXMgPSB7IHRvcDogdHJ1ZSwgcmlnaHQ6IHRydWUgfTtcclxuIHwgICB9XHJcbiB8XHJcbiB8ICAgcmV0dXJuIGFjdGlvbjtcclxuIHwgfSk7XHJcblxcKi9cclxuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5hY3Rpb25DaGVja2VyID0gZnVuY3Rpb24gKGNoZWNrZXIpIHtcclxuICBpZiAoaXMuZnVuY3Rpb24oY2hlY2tlcikpIHtcclxuICAgIHRoaXMub3B0aW9ucy5hY3Rpb25DaGVja2VyID0gY2hlY2tlcjtcclxuXHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIGlmIChjaGVja2VyID09PSBudWxsKSB7XHJcbiAgICBkZWxldGUgdGhpcy5vcHRpb25zLmFjdGlvbkNoZWNrZXI7XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gdGhpcy5vcHRpb25zLmFjdGlvbkNoZWNrZXI7XHJcbn07XHJcblxyXG4vKlxcXHJcbiAqIEludGVyYWN0YWJsZS5zdHlsZUN1cnNvclxyXG4gWyBtZXRob2QgXVxyXG4gKlxyXG4gKiBSZXR1cm5zIG9yIHNldHMgd2hldGhlciB0aGUgdGhlIGN1cnNvciBzaG91bGQgYmUgY2hhbmdlZCBkZXBlbmRpbmcgb24gdGhlXHJcbiAqIGFjdGlvbiB0aGF0IHdvdWxkIGJlIHBlcmZvcm1lZCBpZiB0aGUgbW91c2Ugd2VyZSBwcmVzc2VkIGFuZCBkcmFnZ2VkLlxyXG4gKlxyXG4gLSBuZXdWYWx1ZSAoYm9vbGVhbikgI29wdGlvbmFsXHJcbiA9IChib29sZWFuIHwgSW50ZXJhY3RhYmxlKSBUaGUgY3VycmVudCBzZXR0aW5nIG9yIHRoaXMgSW50ZXJhY3RhYmxlXHJcblxcKi9cclxuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5zdHlsZUN1cnNvciA9IGZ1bmN0aW9uIChuZXdWYWx1ZSkge1xyXG4gIGlmIChpcy5ib29sKG5ld1ZhbHVlKSkge1xyXG4gICAgdGhpcy5vcHRpb25zLnN0eWxlQ3Vyc29yID0gbmV3VmFsdWU7XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICBpZiAobmV3VmFsdWUgPT09IG51bGwpIHtcclxuICAgIGRlbGV0ZSB0aGlzLm9wdGlvbnMuc3R5bGVDdXJzb3I7XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gdGhpcy5vcHRpb25zLnN0eWxlQ3Vyc29yO1xyXG59O1xyXG5cclxuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5kZWZhdWx0QWN0aW9uQ2hlY2tlciA9IGZ1bmN0aW9uIChwb2ludGVyLCBldmVudCwgaW50ZXJhY3Rpb24sIGVsZW1lbnQpIHtcclxuICB2YXIgcmVjdCA9IHRoaXMuZ2V0UmVjdChlbGVtZW50KTtcclxuICB2YXIgYWN0aW9uID0gbnVsbDtcclxuXHJcbiAgZm9yICh2YXIgX2l0ZXJhdG9yID0gYWN0aW9ucy5uYW1lcywgX2lzQXJyYXkgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvciksIF9pID0gMCwgX2l0ZXJhdG9yID0gX2lzQXJyYXkgPyBfaXRlcmF0b3IgOiBfaXRlcmF0b3JbU3ltYm9sLml0ZXJhdG9yXSgpOzspIHtcclxuICAgIHZhciBfcmVmO1xyXG5cclxuICAgIGlmIChfaXNBcnJheSkge1xyXG4gICAgICBpZiAoX2kgPj0gX2l0ZXJhdG9yLmxlbmd0aCkgYnJlYWs7XHJcbiAgICAgIF9yZWYgPSBfaXRlcmF0b3JbX2krK107XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBfaSA9IF9pdGVyYXRvci5uZXh0KCk7XHJcbiAgICAgIGlmIChfaS5kb25lKSBicmVhaztcclxuICAgICAgX3JlZiA9IF9pLnZhbHVlO1xyXG4gICAgfVxyXG5cclxuICAgIHZhciBhY3Rpb25OYW1lID0gX3JlZjtcclxuXHJcbiAgICAvLyBjaGVjayBtb3VzZUJ1dHRvbiBzZXR0aW5nIGlmIHRoZSBwb2ludGVyIGlzIGRvd25cclxuICAgIGlmIChpbnRlcmFjdGlvbi5wb2ludGVySXNEb3duICYmIGludGVyYWN0aW9uLm1vdXNlICYmIChldmVudC5idXR0b25zICYgdGhpcy5vcHRpb25zW2FjdGlvbk5hbWVdLm1vdXNlQnV0dG9ucykgPT09IDApIHtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgYWN0aW9uID0gYWN0aW9uc1thY3Rpb25OYW1lXS5jaGVja2VyKHBvaW50ZXIsIGV2ZW50LCB0aGlzLCBlbGVtZW50LCBpbnRlcmFjdGlvbiwgcmVjdCk7XHJcblxyXG4gICAgaWYgKGFjdGlvbikge1xyXG4gICAgICByZXR1cm4gYWN0aW9uO1xyXG4gICAgfVxyXG4gIH1cclxufTtcclxuXHJcbn0se1wiLi4vSW50ZXJhY3RhYmxlXCI6NCxcIi4uL2FjdGlvbnMvYmFzZVwiOjYsXCIuLi91dGlscy9kb21VdGlsc1wiOjM5LFwiLi4vdXRpbHMvaXNcIjo0Nn1dLDEzOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGludGVyYWN0ID0gcmVxdWlyZSgnLi4vaW50ZXJhY3QnKTtcclxudmFyIEludGVyYWN0YWJsZSA9IHJlcXVpcmUoJy4uL0ludGVyYWN0YWJsZScpO1xyXG52YXIgSW50ZXJhY3Rpb24gPSByZXF1aXJlKCcuLi9JbnRlcmFjdGlvbicpO1xyXG52YXIgYWN0aW9ucyA9IHJlcXVpcmUoJy4uL2FjdGlvbnMvYmFzZScpO1xyXG52YXIgZGVmYXVsdE9wdGlvbnMgPSByZXF1aXJlKCcuLi9kZWZhdWx0T3B0aW9ucycpO1xyXG52YXIgYnJvd3NlciA9IHJlcXVpcmUoJy4uL3V0aWxzL2Jyb3dzZXInKTtcclxudmFyIHNjb3BlID0gcmVxdWlyZSgnLi4vc2NvcGUnKTtcclxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcclxudmFyIHNpZ25hbHMgPSByZXF1aXJlKCcuLi91dGlscy9TaWduYWxzJykubmV3KCk7XHJcblxyXG5yZXF1aXJlKCcuL0ludGVyYWN0YWJsZU1ldGhvZHMnKTtcclxuXHJcbnZhciBhdXRvU3RhcnQgPSB7XHJcbiAgc2lnbmFsczogc2lnbmFscyxcclxuICB3aXRoaW5JbnRlcmFjdGlvbkxpbWl0OiB3aXRoaW5JbnRlcmFjdGlvbkxpbWl0LFxyXG4gIC8vIEFsbG93IHRoaXMgbWFueSBpbnRlcmFjdGlvbnMgdG8gaGFwcGVuIHNpbXVsdGFuZW91c2x5XHJcbiAgbWF4SW50ZXJhY3Rpb25zOiBJbmZpbml0eSxcclxuICBkZWZhdWx0czoge1xyXG4gICAgcGVyQWN0aW9uOiB7XHJcbiAgICAgIG1hbnVhbFN0YXJ0OiBmYWxzZSxcclxuICAgICAgbWF4OiBJbmZpbml0eSxcclxuICAgICAgbWF4UGVyRWxlbWVudDogMSxcclxuICAgICAgYWxsb3dGcm9tOiBudWxsLFxyXG4gICAgICBpZ25vcmVGcm9tOiBudWxsXHJcbiAgICB9XHJcbiAgfSxcclxuICBzZXRBY3Rpb25EZWZhdWx0czogZnVuY3Rpb24gc2V0QWN0aW9uRGVmYXVsdHMoYWN0aW9uKSB7XHJcbiAgICB1dGlscy5leHRlbmQoYWN0aW9uLmRlZmF1bHRzLCBhdXRvU3RhcnQuZGVmYXVsdHMucGVyQWN0aW9uKTtcclxuICB9XHJcbn07XHJcblxyXG4vLyBzZXQgY3Vyc29yIHN0eWxlIG9uIG1vdXNlZG93blxyXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdkb3duJywgZnVuY3Rpb24gKF9yZWYpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmLmludGVyYWN0aW9uLFxyXG4gICAgICBwb2ludGVyID0gX3JlZi5wb2ludGVyLFxyXG4gICAgICBldmVudCA9IF9yZWYuZXZlbnQsXHJcbiAgICAgIGV2ZW50VGFyZ2V0ID0gX3JlZi5ldmVudFRhcmdldDtcclxuXHJcbiAgaWYgKGludGVyYWN0aW9uLmludGVyYWN0aW5nKCkpIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIHZhciBhY3Rpb25JbmZvID0gZ2V0QWN0aW9uSW5mbyhpbnRlcmFjdGlvbiwgcG9pbnRlciwgZXZlbnQsIGV2ZW50VGFyZ2V0KTtcclxuICBwcmVwYXJlKGludGVyYWN0aW9uLCBhY3Rpb25JbmZvKTtcclxufSk7XHJcblxyXG4vLyBzZXQgY3Vyc29yIHN0eWxlIG9uIG1vdXNlbW92ZVxyXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdtb3ZlJywgZnVuY3Rpb24gKF9yZWYyKSB7XHJcbiAgdmFyIGludGVyYWN0aW9uID0gX3JlZjIuaW50ZXJhY3Rpb24sXHJcbiAgICAgIHBvaW50ZXIgPSBfcmVmMi5wb2ludGVyLFxyXG4gICAgICBldmVudCA9IF9yZWYyLmV2ZW50LFxyXG4gICAgICBldmVudFRhcmdldCA9IF9yZWYyLmV2ZW50VGFyZ2V0O1xyXG5cclxuICBpZiAoIWludGVyYWN0aW9uLm1vdXNlIHx8IGludGVyYWN0aW9uLnBvaW50ZXJJc0Rvd24gfHwgaW50ZXJhY3Rpb24uaW50ZXJhY3RpbmcoKSkge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgdmFyIGFjdGlvbkluZm8gPSBnZXRBY3Rpb25JbmZvKGludGVyYWN0aW9uLCBwb2ludGVyLCBldmVudCwgZXZlbnRUYXJnZXQpO1xyXG4gIHByZXBhcmUoaW50ZXJhY3Rpb24sIGFjdGlvbkluZm8pO1xyXG59KTtcclxuXHJcbkludGVyYWN0aW9uLnNpZ25hbHMub24oJ21vdmUnLCBmdW5jdGlvbiAoYXJnKSB7XHJcbiAgdmFyIGludGVyYWN0aW9uID0gYXJnLmludGVyYWN0aW9uLFxyXG4gICAgICBldmVudCA9IGFyZy5ldmVudDtcclxuXHJcblxyXG4gIGlmICghaW50ZXJhY3Rpb24ucG9pbnRlcklzRG93biB8fCBpbnRlcmFjdGlvbi5pbnRlcmFjdGluZygpIHx8ICFpbnRlcmFjdGlvbi5wb2ludGVyV2FzTW92ZWQgfHwgIWludGVyYWN0aW9uLnByZXBhcmVkLm5hbWUpIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIHNpZ25hbHMuZmlyZSgnYmVmb3JlLXN0YXJ0JywgYXJnKTtcclxuXHJcbiAgdmFyIHRhcmdldCA9IGludGVyYWN0aW9uLnRhcmdldDtcclxuXHJcbiAgaWYgKGludGVyYWN0aW9uLnByZXBhcmVkLm5hbWUgJiYgdGFyZ2V0KSB7XHJcbiAgICAvLyBjaGVjayBtYW51YWxTdGFydCBhbmQgaW50ZXJhY3Rpb24gbGltaXRcclxuICAgIGlmICh0YXJnZXQub3B0aW9uc1tpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lXS5tYW51YWxTdGFydCB8fCAhd2l0aGluSW50ZXJhY3Rpb25MaW1pdCh0YXJnZXQsIGludGVyYWN0aW9uLmVsZW1lbnQsIGludGVyYWN0aW9uLnByZXBhcmVkKSkge1xyXG4gICAgICBpbnRlcmFjdGlvbi5zdG9wKGV2ZW50KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGludGVyYWN0aW9uLnN0YXJ0KGludGVyYWN0aW9uLnByZXBhcmVkLCB0YXJnZXQsIGludGVyYWN0aW9uLmVsZW1lbnQpO1xyXG4gICAgfVxyXG4gIH1cclxufSk7XHJcblxyXG4vLyBDaGVjayBpZiB0aGUgY3VycmVudCB0YXJnZXQgc3VwcG9ydHMgdGhlIGFjdGlvbi5cclxuLy8gSWYgc28sIHJldHVybiB0aGUgdmFsaWRhdGVkIGFjdGlvbi4gT3RoZXJ3aXNlLCByZXR1cm4gbnVsbFxyXG5mdW5jdGlvbiB2YWxpZGF0ZUFjdGlvbihhY3Rpb24sIGludGVyYWN0YWJsZSwgZWxlbWVudCwgZXZlbnRUYXJnZXQpIHtcclxuICBpZiAodXRpbHMuaXMub2JqZWN0KGFjdGlvbikgJiYgaW50ZXJhY3RhYmxlLnRlc3RJZ25vcmVBbGxvdyhpbnRlcmFjdGFibGUub3B0aW9uc1thY3Rpb24ubmFtZV0sIGVsZW1lbnQsIGV2ZW50VGFyZ2V0KSAmJiBpbnRlcmFjdGFibGUub3B0aW9uc1thY3Rpb24ubmFtZV0uZW5hYmxlZCAmJiB3aXRoaW5JbnRlcmFjdGlvbkxpbWl0KGludGVyYWN0YWJsZSwgZWxlbWVudCwgYWN0aW9uKSkge1xyXG4gICAgcmV0dXJuIGFjdGlvbjtcclxuICB9XHJcblxyXG4gIHJldHVybiBudWxsO1xyXG59XHJcblxyXG5mdW5jdGlvbiB2YWxpZGF0ZVNlbGVjdG9yKGludGVyYWN0aW9uLCBwb2ludGVyLCBldmVudCwgbWF0Y2hlcywgbWF0Y2hFbGVtZW50cywgZXZlbnRUYXJnZXQpIHtcclxuICBmb3IgKHZhciBpID0gMCwgbGVuID0gbWF0Y2hlcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgdmFyIG1hdGNoID0gbWF0Y2hlc1tpXTtcclxuICAgIHZhciBtYXRjaEVsZW1lbnQgPSBtYXRjaEVsZW1lbnRzW2ldO1xyXG4gICAgdmFyIGFjdGlvbiA9IHZhbGlkYXRlQWN0aW9uKG1hdGNoLmdldEFjdGlvbihwb2ludGVyLCBldmVudCwgaW50ZXJhY3Rpb24sIG1hdGNoRWxlbWVudCksIG1hdGNoLCBtYXRjaEVsZW1lbnQsIGV2ZW50VGFyZ2V0KTtcclxuXHJcbiAgICBpZiAoYWN0aW9uKSB7XHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgYWN0aW9uOiBhY3Rpb24sXHJcbiAgICAgICAgdGFyZ2V0OiBtYXRjaCxcclxuICAgICAgICBlbGVtZW50OiBtYXRjaEVsZW1lbnRcclxuICAgICAgfTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHJldHVybiB7fTtcclxufVxyXG5cclxuZnVuY3Rpb24gZ2V0QWN0aW9uSW5mbyhpbnRlcmFjdGlvbiwgcG9pbnRlciwgZXZlbnQsIGV2ZW50VGFyZ2V0KSB7XHJcbiAgdmFyIG1hdGNoZXMgPSBbXTtcclxuICB2YXIgbWF0Y2hFbGVtZW50cyA9IFtdO1xyXG5cclxuICB2YXIgZWxlbWVudCA9IGV2ZW50VGFyZ2V0O1xyXG4gIHZhciBhY3Rpb24gPSBudWxsO1xyXG5cclxuICBmdW5jdGlvbiBwdXNoTWF0Y2hlcyhpbnRlcmFjdGFibGUsIHNlbGVjdG9yLCBjb250ZXh0KSB7XHJcbiAgICB2YXIgZWxlbWVudHMgPSBicm93c2VyLnVzZU1hdGNoZXNTZWxlY3RvclBvbHlmaWxsID8gY29udGV4dC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKSA6IHVuZGVmaW5lZDtcclxuXHJcbiAgICBpZiAodXRpbHMubWF0Y2hlc1NlbGVjdG9yKGVsZW1lbnQsIHNlbGVjdG9yLCBlbGVtZW50cykpIHtcclxuXHJcbiAgICAgIG1hdGNoZXMucHVzaChpbnRlcmFjdGFibGUpO1xyXG4gICAgICBtYXRjaEVsZW1lbnRzLnB1c2goZWxlbWVudCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICB3aGlsZSAodXRpbHMuaXMuZWxlbWVudChlbGVtZW50KSkge1xyXG4gICAgbWF0Y2hlcyA9IFtdO1xyXG4gICAgbWF0Y2hFbGVtZW50cyA9IFtdO1xyXG5cclxuICAgIHZhciBlbGVtZW50SW50ZXJhY3RhYmxlID0gc2NvcGUuaW50ZXJhY3RhYmxlcy5nZXQoZWxlbWVudCk7XHJcblxyXG4gICAgaWYgKGVsZW1lbnRJbnRlcmFjdGFibGUgJiYgKGFjdGlvbiA9IHZhbGlkYXRlQWN0aW9uKGVsZW1lbnRJbnRlcmFjdGFibGUuZ2V0QWN0aW9uKHBvaW50ZXIsIGV2ZW50LCBpbnRlcmFjdGlvbiwgZWxlbWVudCwgZXZlbnRUYXJnZXQpLCBlbGVtZW50SW50ZXJhY3RhYmxlLCBlbGVtZW50LCBldmVudFRhcmdldCkpICYmICFlbGVtZW50SW50ZXJhY3RhYmxlLm9wdGlvbnNbYWN0aW9uLm5hbWVdLm1hbnVhbFN0YXJ0KSB7XHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgZWxlbWVudDogZWxlbWVudCxcclxuICAgICAgICBhY3Rpb246IGFjdGlvbixcclxuICAgICAgICB0YXJnZXQ6IGVsZW1lbnRJbnRlcmFjdGFibGVcclxuICAgICAgfTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHNjb3BlLmludGVyYWN0YWJsZXMuZm9yRWFjaFNlbGVjdG9yKHB1c2hNYXRjaGVzLCBlbGVtZW50KTtcclxuXHJcbiAgICAgIHZhciBhY3Rpb25JbmZvID0gdmFsaWRhdGVTZWxlY3RvcihpbnRlcmFjdGlvbiwgcG9pbnRlciwgZXZlbnQsIG1hdGNoZXMsIG1hdGNoRWxlbWVudHMsIGV2ZW50VGFyZ2V0KTtcclxuXHJcbiAgICAgIGlmIChhY3Rpb25JbmZvLmFjdGlvbiAmJiAhYWN0aW9uSW5mby50YXJnZXQub3B0aW9uc1thY3Rpb25JbmZvLmFjdGlvbi5uYW1lXS5tYW51YWxTdGFydCkge1xyXG4gICAgICAgIHJldHVybiBhY3Rpb25JbmZvO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZWxlbWVudCA9IHV0aWxzLnBhcmVudE5vZGUoZWxlbWVudCk7XHJcbiAgfVxyXG5cclxuICByZXR1cm4ge307XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHByZXBhcmUoaW50ZXJhY3Rpb24sIF9yZWYzKSB7XHJcbiAgdmFyIGFjdGlvbiA9IF9yZWYzLmFjdGlvbixcclxuICAgICAgdGFyZ2V0ID0gX3JlZjMudGFyZ2V0LFxyXG4gICAgICBlbGVtZW50ID0gX3JlZjMuZWxlbWVudDtcclxuXHJcbiAgYWN0aW9uID0gYWN0aW9uIHx8IHt9O1xyXG5cclxuICBpZiAoaW50ZXJhY3Rpb24udGFyZ2V0ICYmIGludGVyYWN0aW9uLnRhcmdldC5vcHRpb25zLnN0eWxlQ3Vyc29yKSB7XHJcbiAgICBpbnRlcmFjdGlvbi50YXJnZXQuX2RvYy5kb2N1bWVudEVsZW1lbnQuc3R5bGUuY3Vyc29yID0gJyc7XHJcbiAgfVxyXG5cclxuICBpbnRlcmFjdGlvbi50YXJnZXQgPSB0YXJnZXQ7XHJcbiAgaW50ZXJhY3Rpb24uZWxlbWVudCA9IGVsZW1lbnQ7XHJcbiAgdXRpbHMuY29weUFjdGlvbihpbnRlcmFjdGlvbi5wcmVwYXJlZCwgYWN0aW9uKTtcclxuXHJcbiAgaWYgKHRhcmdldCAmJiB0YXJnZXQub3B0aW9ucy5zdHlsZUN1cnNvcikge1xyXG4gICAgdmFyIGN1cnNvciA9IGFjdGlvbiA/IGFjdGlvbnNbYWN0aW9uLm5hbWVdLmdldEN1cnNvcihhY3Rpb24pIDogJyc7XHJcbiAgICBpbnRlcmFjdGlvbi50YXJnZXQuX2RvYy5kb2N1bWVudEVsZW1lbnQuc3R5bGUuY3Vyc29yID0gY3Vyc29yO1xyXG4gIH1cclxuXHJcbiAgc2lnbmFscy5maXJlKCdwcmVwYXJlZCcsIHsgaW50ZXJhY3Rpb246IGludGVyYWN0aW9uIH0pO1xyXG59XHJcblxyXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdzdG9wJywgZnVuY3Rpb24gKF9yZWY0KSB7XHJcbiAgdmFyIGludGVyYWN0aW9uID0gX3JlZjQuaW50ZXJhY3Rpb247XHJcblxyXG4gIHZhciB0YXJnZXQgPSBpbnRlcmFjdGlvbi50YXJnZXQ7XHJcblxyXG4gIGlmICh0YXJnZXQgJiYgdGFyZ2V0Lm9wdGlvbnMuc3R5bGVDdXJzb3IpIHtcclxuICAgIHRhcmdldC5fZG9jLmRvY3VtZW50RWxlbWVudC5zdHlsZS5jdXJzb3IgPSAnJztcclxuICB9XHJcbn0pO1xyXG5cclxuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5nZXRBY3Rpb24gPSBmdW5jdGlvbiAocG9pbnRlciwgZXZlbnQsIGludGVyYWN0aW9uLCBlbGVtZW50KSB7XHJcbiAgdmFyIGFjdGlvbiA9IHRoaXMuZGVmYXVsdEFjdGlvbkNoZWNrZXIocG9pbnRlciwgZXZlbnQsIGludGVyYWN0aW9uLCBlbGVtZW50KTtcclxuXHJcbiAgaWYgKHRoaXMub3B0aW9ucy5hY3Rpb25DaGVja2VyKSB7XHJcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zLmFjdGlvbkNoZWNrZXIocG9pbnRlciwgZXZlbnQsIGFjdGlvbiwgdGhpcywgZWxlbWVudCwgaW50ZXJhY3Rpb24pO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIGFjdGlvbjtcclxufTtcclxuXHJcbi8qXFxcclxuICogSW50ZXJhY3RhYmxlLmFjdGlvbkNoZWNrZXJcclxuIFsgbWV0aG9kIF1cclxuICpcclxuICogR2V0cyBvciBzZXRzIHRoZSBmdW5jdGlvbiB1c2VkIHRvIGNoZWNrIGFjdGlvbiB0byBiZSBwZXJmb3JtZWQgb25cclxuICogcG9pbnRlckRvd25cclxuICpcclxuIC0gY2hlY2tlciAoZnVuY3Rpb24gfCBudWxsKSAjb3B0aW9uYWwgQSBmdW5jdGlvbiB3aGljaCB0YWtlcyBhIHBvaW50ZXIgZXZlbnQsIGRlZmF1bHRBY3Rpb24gc3RyaW5nLCBpbnRlcmFjdGFibGUsIGVsZW1lbnQgYW5kIGludGVyYWN0aW9uIGFzIHBhcmFtZXRlcnMgYW5kIHJldHVybnMgYW4gb2JqZWN0IHdpdGggbmFtZSBwcm9wZXJ0eSAnZHJhZycgJ3Jlc2l6ZScgb3IgJ2dlc3R1cmUnIGFuZCBvcHRpb25hbGx5IGFuIGBlZGdlc2Agb2JqZWN0IHdpdGggYm9vbGVhbiAndG9wJywgJ2xlZnQnLCAnYm90dG9tJyBhbmQgcmlnaHQgcHJvcHMuXHJcbiA9IChGdW5jdGlvbiB8IEludGVyYWN0YWJsZSkgVGhlIGNoZWNrZXIgZnVuY3Rpb24gb3IgdGhpcyBJbnRlcmFjdGFibGVcclxuICpcclxuIHwgaW50ZXJhY3QoJy5yZXNpemUtZHJhZycpXHJcbiB8ICAgLnJlc2l6YWJsZSh0cnVlKVxyXG4gfCAgIC5kcmFnZ2FibGUodHJ1ZSlcclxuIHwgICAuYWN0aW9uQ2hlY2tlcihmdW5jdGlvbiAocG9pbnRlciwgZXZlbnQsIGFjdGlvbiwgaW50ZXJhY3RhYmxlLCBlbGVtZW50LCBpbnRlcmFjdGlvbikge1xyXG4gfFxyXG4gfCAgIGlmIChpbnRlcmFjdC5tYXRjaGVzU2VsZWN0b3IoZXZlbnQudGFyZ2V0LCAnLmRyYWctaGFuZGxlJykge1xyXG4gfCAgICAgLy8gZm9yY2UgZHJhZyB3aXRoIGhhbmRsZSB0YXJnZXRcclxuIHwgICAgIGFjdGlvbi5uYW1lID0gZHJhZztcclxuIHwgICB9XHJcbiB8ICAgZWxzZSB7XHJcbiB8ICAgICAvLyByZXNpemUgZnJvbSB0aGUgdG9wIGFuZCByaWdodCBlZGdlc1xyXG4gfCAgICAgYWN0aW9uLm5hbWUgID0gJ3Jlc2l6ZSc7XHJcbiB8ICAgICBhY3Rpb24uZWRnZXMgPSB7IHRvcDogdHJ1ZSwgcmlnaHQ6IHRydWUgfTtcclxuIHwgICB9XHJcbiB8XHJcbiB8ICAgcmV0dXJuIGFjdGlvbjtcclxuIHwgfSk7XHJcblxcKi9cclxuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5hY3Rpb25DaGVja2VyID0gZnVuY3Rpb24gKGNoZWNrZXIpIHtcclxuICBpZiAodXRpbHMuaXMuZnVuY3Rpb24oY2hlY2tlcikpIHtcclxuICAgIHRoaXMub3B0aW9ucy5hY3Rpb25DaGVja2VyID0gY2hlY2tlcjtcclxuXHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIGlmIChjaGVja2VyID09PSBudWxsKSB7XHJcbiAgICBkZWxldGUgdGhpcy5vcHRpb25zLmFjdGlvbkNoZWNrZXI7XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gdGhpcy5vcHRpb25zLmFjdGlvbkNoZWNrZXI7XHJcbn07XHJcblxyXG4vKlxcXHJcbiAqIEludGVyYWN0YWJsZS5zdHlsZUN1cnNvclxyXG4gWyBtZXRob2QgXVxyXG4gKlxyXG4gKiBSZXR1cm5zIG9yIHNldHMgd2hldGhlciB0aGUgdGhlIGN1cnNvciBzaG91bGQgYmUgY2hhbmdlZCBkZXBlbmRpbmcgb24gdGhlXHJcbiAqIGFjdGlvbiB0aGF0IHdvdWxkIGJlIHBlcmZvcm1lZCBpZiB0aGUgbW91c2Ugd2VyZSBwcmVzc2VkIGFuZCBkcmFnZ2VkLlxyXG4gKlxyXG4gLSBuZXdWYWx1ZSAoYm9vbGVhbikgI29wdGlvbmFsXHJcbiA9IChib29sZWFuIHwgSW50ZXJhY3RhYmxlKSBUaGUgY3VycmVudCBzZXR0aW5nIG9yIHRoaXMgSW50ZXJhY3RhYmxlXHJcblxcKi9cclxuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5zdHlsZUN1cnNvciA9IGZ1bmN0aW9uIChuZXdWYWx1ZSkge1xyXG4gIGlmICh1dGlscy5pcy5ib29sKG5ld1ZhbHVlKSkge1xyXG4gICAgdGhpcy5vcHRpb25zLnN0eWxlQ3Vyc29yID0gbmV3VmFsdWU7XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICBpZiAobmV3VmFsdWUgPT09IG51bGwpIHtcclxuICAgIGRlbGV0ZSB0aGlzLm9wdGlvbnMuc3R5bGVDdXJzb3I7XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gdGhpcy5vcHRpb25zLnN0eWxlQ3Vyc29yO1xyXG59O1xyXG5cclxuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5kZWZhdWx0QWN0aW9uQ2hlY2tlciA9IGZ1bmN0aW9uIChwb2ludGVyLCBldmVudCwgaW50ZXJhY3Rpb24sIGVsZW1lbnQpIHtcclxuICB2YXIgcmVjdCA9IHRoaXMuZ2V0UmVjdChlbGVtZW50KTtcclxuICB2YXIgYnV0dG9ucyA9IGV2ZW50LmJ1dHRvbnMgfHwge1xyXG4gICAgMDogMSxcclxuICAgIDE6IDQsXHJcbiAgICAzOiA4LFxyXG4gICAgNDogMTZcclxuICB9W2V2ZW50LmJ1dHRvbl07XHJcbiAgdmFyIGFjdGlvbiA9IG51bGw7XHJcblxyXG4gIGZvciAodmFyIF9pdGVyYXRvciA9IGFjdGlvbnMubmFtZXMsIF9pc0FycmF5ID0gQXJyYXkuaXNBcnJheShfaXRlcmF0b3IpLCBfaSA9IDAsIF9pdGVyYXRvciA9IF9pc0FycmF5ID8gX2l0ZXJhdG9yIDogX2l0ZXJhdG9yW1N5bWJvbC5pdGVyYXRvcl0oKTs7KSB7XHJcbiAgICB2YXIgX3JlZjU7XHJcblxyXG4gICAgaWYgKF9pc0FycmF5KSB7XHJcbiAgICAgIGlmIChfaSA+PSBfaXRlcmF0b3IubGVuZ3RoKSBicmVhaztcclxuICAgICAgX3JlZjUgPSBfaXRlcmF0b3JbX2krK107XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBfaSA9IF9pdGVyYXRvci5uZXh0KCk7XHJcbiAgICAgIGlmIChfaS5kb25lKSBicmVhaztcclxuICAgICAgX3JlZjUgPSBfaS52YWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgYWN0aW9uTmFtZSA9IF9yZWY1O1xyXG5cclxuICAgIC8vIGNoZWNrIG1vdXNlQnV0dG9uIHNldHRpbmcgaWYgdGhlIHBvaW50ZXIgaXMgZG93blxyXG4gICAgaWYgKGludGVyYWN0aW9uLnBvaW50ZXJJc0Rvd24gJiYgaW50ZXJhY3Rpb24ubW91c2UgJiYgKGJ1dHRvbnMgJiB0aGlzLm9wdGlvbnNbYWN0aW9uTmFtZV0ubW91c2VCdXR0b25zKSA9PT0gMCkge1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBhY3Rpb24gPSBhY3Rpb25zW2FjdGlvbk5hbWVdLmNoZWNrZXIocG9pbnRlciwgZXZlbnQsIHRoaXMsIGVsZW1lbnQsIGludGVyYWN0aW9uLCByZWN0KTtcclxuXHJcbiAgICBpZiAoYWN0aW9uKSB7XHJcbiAgICAgIHJldHVybiBhY3Rpb247XHJcbiAgICB9XHJcbiAgfVxyXG59O1xyXG5cclxuZnVuY3Rpb24gd2l0aGluSW50ZXJhY3Rpb25MaW1pdChpbnRlcmFjdGFibGUsIGVsZW1lbnQsIGFjdGlvbikge1xyXG4gIHZhciBvcHRpb25zID0gaW50ZXJhY3RhYmxlLm9wdGlvbnM7XHJcbiAgdmFyIG1heEFjdGlvbnMgPSBvcHRpb25zW2FjdGlvbi5uYW1lXS5tYXg7XHJcbiAgdmFyIG1heFBlckVsZW1lbnQgPSBvcHRpb25zW2FjdGlvbi5uYW1lXS5tYXhQZXJFbGVtZW50O1xyXG4gIHZhciBhY3RpdmVJbnRlcmFjdGlvbnMgPSAwO1xyXG4gIHZhciB0YXJnZXRDb3VudCA9IDA7XHJcbiAgdmFyIHRhcmdldEVsZW1lbnRDb3VudCA9IDA7XHJcblxyXG4gIC8vIG5vIGFjdGlvbnMgaWYgYW55IG9mIHRoZXNlIHZhbHVlcyA9PSAwXHJcbiAgaWYgKCEobWF4QWN0aW9ucyAmJiBtYXhQZXJFbGVtZW50ICYmIGF1dG9TdGFydC5tYXhJbnRlcmFjdGlvbnMpKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICBmb3IgKHZhciBpID0gMCwgbGVuID0gc2NvcGUuaW50ZXJhY3Rpb25zLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICB2YXIgaW50ZXJhY3Rpb24gPSBzY29wZS5pbnRlcmFjdGlvbnNbaV07XHJcbiAgICB2YXIgb3RoZXJBY3Rpb24gPSBpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lO1xyXG5cclxuICAgIGlmICghaW50ZXJhY3Rpb24uaW50ZXJhY3RpbmcoKSkge1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBhY3RpdmVJbnRlcmFjdGlvbnMrKztcclxuXHJcbiAgICBpZiAoYWN0aXZlSW50ZXJhY3Rpb25zID49IGF1dG9TdGFydC5tYXhJbnRlcmFjdGlvbnMpIHtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChpbnRlcmFjdGlvbi50YXJnZXQgIT09IGludGVyYWN0YWJsZSkge1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICB0YXJnZXRDb3VudCArPSBvdGhlckFjdGlvbiA9PT0gYWN0aW9uLm5hbWUgfCAwO1xyXG5cclxuICAgIGlmICh0YXJnZXRDb3VudCA+PSBtYXhBY3Rpb25zKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoaW50ZXJhY3Rpb24uZWxlbWVudCA9PT0gZWxlbWVudCkge1xyXG4gICAgICB0YXJnZXRFbGVtZW50Q291bnQrKztcclxuXHJcbiAgICAgIGlmIChvdGhlckFjdGlvbiAhPT0gYWN0aW9uLm5hbWUgfHwgdGFyZ2V0RWxlbWVudENvdW50ID49IG1heFBlckVsZW1lbnQpIHtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIHJldHVybiBhdXRvU3RhcnQubWF4SW50ZXJhY3Rpb25zID4gMDtcclxufVxyXG5cclxuLypcXFxyXG4gKiBpbnRlcmFjdC5tYXhJbnRlcmFjdGlvbnNcclxuIFsgbWV0aG9kIF1cclxuICoqXHJcbiAqIFJldHVybnMgb3Igc2V0cyB0aGUgbWF4aW11bSBudW1iZXIgb2YgY29uY3VycmVudCBpbnRlcmFjdGlvbnMgYWxsb3dlZC5cclxuICogQnkgZGVmYXVsdCBvbmx5IDEgaW50ZXJhY3Rpb24gaXMgYWxsb3dlZCBhdCBhIHRpbWUgKGZvciBiYWNrd2FyZHNcclxuICogY29tcGF0aWJpbGl0eSkuIFRvIGFsbG93IG11bHRpcGxlIGludGVyYWN0aW9ucyBvbiB0aGUgc2FtZSBJbnRlcmFjdGFibGVzXHJcbiAqIGFuZCBlbGVtZW50cywgeW91IG5lZWQgdG8gZW5hYmxlIGl0IGluIHRoZSBkcmFnZ2FibGUsIHJlc2l6YWJsZSBhbmRcclxuICogZ2VzdHVyYWJsZSBgJ21heCdgIGFuZCBgJ21heFBlckVsZW1lbnQnYCBvcHRpb25zLlxyXG4gKipcclxuIC0gbmV3VmFsdWUgKG51bWJlcikgI29wdGlvbmFsIEFueSBudW1iZXIuIG5ld1ZhbHVlIDw9IDAgbWVhbnMgbm8gaW50ZXJhY3Rpb25zLlxyXG5cXCovXHJcbmludGVyYWN0Lm1heEludGVyYWN0aW9ucyA9IGZ1bmN0aW9uIChuZXdWYWx1ZSkge1xyXG4gIGlmICh1dGlscy5pcy5udW1iZXIobmV3VmFsdWUpKSB7XHJcbiAgICBhdXRvU3RhcnQubWF4SW50ZXJhY3Rpb25zID0gbmV3VmFsdWU7XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gYXV0b1N0YXJ0Lm1heEludGVyYWN0aW9ucztcclxufTtcclxuXHJcbkludGVyYWN0YWJsZS5zZXR0aW5nc01ldGhvZHMucHVzaCgnc3R5bGVDdXJzb3InKTtcclxuSW50ZXJhY3RhYmxlLnNldHRpbmdzTWV0aG9kcy5wdXNoKCdhY3Rpb25DaGVja2VyJyk7XHJcbkludGVyYWN0YWJsZS5zZXR0aW5nc01ldGhvZHMucHVzaCgnaWdub3JlRnJvbScpO1xyXG5JbnRlcmFjdGFibGUuc2V0dGluZ3NNZXRob2RzLnB1c2goJ2FsbG93RnJvbScpO1xyXG5cclxuZGVmYXVsdE9wdGlvbnMuYmFzZS5hY3Rpb25DaGVja2VyID0gbnVsbDtcclxuZGVmYXVsdE9wdGlvbnMuYmFzZS5zdHlsZUN1cnNvciA9IHRydWU7XHJcblxyXG51dGlscy5leHRlbmQoZGVmYXVsdE9wdGlvbnMucGVyQWN0aW9uLCBhdXRvU3RhcnQuZGVmYXVsdHMucGVyQWN0aW9uKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gYXV0b1N0YXJ0O1xyXG5cclxufSx7XCIuLi9JbnRlcmFjdGFibGVcIjo0LFwiLi4vSW50ZXJhY3Rpb25cIjo1LFwiLi4vYWN0aW9ucy9iYXNlXCI6NixcIi4uL2RlZmF1bHRPcHRpb25zXCI6MTgsXCIuLi9pbnRlcmFjdFwiOjIxLFwiLi4vc2NvcGVcIjozNCxcIi4uL3V0aWxzXCI6NDQsXCIuLi91dGlscy9TaWduYWxzXCI6MzUsXCIuLi91dGlscy9icm93c2VyXCI6MzcsXCIuL0ludGVyYWN0YWJsZU1ldGhvZHNcIjoxMn1dLDE0OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGF1dG9TdGFydCA9IHJlcXVpcmUoJy4vYmFzZScpO1xyXG52YXIgSW50ZXJhY3Rpb24gPSByZXF1aXJlKCcuLi9JbnRlcmFjdGlvbicpO1xyXG5cclxuSW50ZXJhY3Rpb24uc2lnbmFscy5vbignbmV3JywgZnVuY3Rpb24gKGludGVyYWN0aW9uKSB7XHJcbiAgaW50ZXJhY3Rpb24uZGVsYXlUaW1lciA9IG51bGw7XHJcbn0pO1xyXG5cclxuYXV0b1N0YXJ0LnNpZ25hbHMub24oJ3ByZXBhcmVkJywgZnVuY3Rpb24gKF9yZWYpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmLmludGVyYWN0aW9uO1xyXG5cclxuICB2YXIgYWN0aW9uTmFtZSA9IGludGVyYWN0aW9uLnByZXBhcmVkLm5hbWU7XHJcblxyXG4gIGlmICghYWN0aW9uTmFtZSkge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgdmFyIGRlbGF5ID0gaW50ZXJhY3Rpb24udGFyZ2V0Lm9wdGlvbnNbYWN0aW9uTmFtZV0uZGVsYXk7XHJcblxyXG4gIGlmIChkZWxheSA+IDApIHtcclxuICAgIGludGVyYWN0aW9uLmRlbGF5VGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgaW50ZXJhY3Rpb24uc3RhcnQoaW50ZXJhY3Rpb24ucHJlcGFyZWQsIGludGVyYWN0aW9uLnRhcmdldCwgaW50ZXJhY3Rpb24uZWxlbWVudCk7XHJcbiAgICB9LCBkZWxheSk7XHJcbiAgfVxyXG59KTtcclxuXHJcbkludGVyYWN0aW9uLnNpZ25hbHMub24oJ21vdmUnLCBmdW5jdGlvbiAoX3JlZjIpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmMi5pbnRlcmFjdGlvbixcclxuICAgICAgZHVwbGljYXRlID0gX3JlZjIuZHVwbGljYXRlO1xyXG5cclxuICBpZiAoaW50ZXJhY3Rpb24ucG9pbnRlcldhc01vdmVkICYmICFkdXBsaWNhdGUpIHtcclxuICAgIGNsZWFyVGltZW91dChpbnRlcmFjdGlvbi5kZWxheVRpbWVyKTtcclxuICB9XHJcbn0pO1xyXG5cclxuLy8gcHJldmVudCByZWd1bGFyIGRvd24tPm1vdmUgYXV0b1N0YXJ0XHJcbmF1dG9TdGFydC5zaWduYWxzLm9uKCdiZWZvcmUtc3RhcnQnLCBmdW5jdGlvbiAoX3JlZjMpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmMy5pbnRlcmFjdGlvbjtcclxuXHJcbiAgdmFyIGFjdGlvbk5hbWUgPSBpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lO1xyXG5cclxuICBpZiAoIWFjdGlvbk5hbWUpIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIHZhciBkZWxheSA9IGludGVyYWN0aW9uLnRhcmdldC5vcHRpb25zW2FjdGlvbk5hbWVdLmRlbGF5O1xyXG5cclxuICBpZiAoZGVsYXkgPiAwKSB7XHJcbiAgICBpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lID0gbnVsbDtcclxuICB9XHJcbn0pO1xyXG5cclxufSx7XCIuLi9JbnRlcmFjdGlvblwiOjUsXCIuL2Jhc2VcIjoxM31dLDE1OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGF1dG9TdGFydCA9IHJlcXVpcmUoJy4vYmFzZScpO1xyXG52YXIgc2NvcGUgPSByZXF1aXJlKCcuLi9zY29wZScpO1xyXG52YXIgYnJvd3NlciA9IHJlcXVpcmUoJy4uL3V0aWxzL2Jyb3dzZXInKTtcclxudmFyIGlzID0gcmVxdWlyZSgnLi4vdXRpbHMvaXMnKTtcclxuXHJcbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJy4uL3V0aWxzL2RvbVV0aWxzJyksXHJcbiAgICBtYXRjaGVzU2VsZWN0b3IgPSBfcmVxdWlyZS5tYXRjaGVzU2VsZWN0b3IsXHJcbiAgICBwYXJlbnROb2RlID0gX3JlcXVpcmUucGFyZW50Tm9kZTtcclxuXHJcbmF1dG9TdGFydC5zZXRBY3Rpb25EZWZhdWx0cyhyZXF1aXJlKCcuLi9hY3Rpb25zL2RyYWcnKSk7XHJcblxyXG5hdXRvU3RhcnQuc2lnbmFscy5vbignYmVmb3JlLXN0YXJ0JywgZnVuY3Rpb24gKF9yZWYpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmLmludGVyYWN0aW9uLFxyXG4gICAgICBldmVudFRhcmdldCA9IF9yZWYuZXZlbnRUYXJnZXQsXHJcbiAgICAgIGR4ID0gX3JlZi5keCxcclxuICAgICAgZHkgPSBfcmVmLmR5O1xyXG5cclxuICBpZiAoaW50ZXJhY3Rpb24ucHJlcGFyZWQubmFtZSAhPT0gJ2RyYWcnKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICAvLyBjaGVjayBpZiBhIGRyYWcgaXMgaW4gdGhlIGNvcnJlY3QgYXhpc1xyXG4gIHZhciBhYnNYID0gTWF0aC5hYnMoZHgpO1xyXG4gIHZhciBhYnNZID0gTWF0aC5hYnMoZHkpO1xyXG4gIHZhciBvcHRpb25zID0gaW50ZXJhY3Rpb24udGFyZ2V0Lm9wdGlvbnMuZHJhZztcclxuICB2YXIgc3RhcnRBeGlzID0gb3B0aW9ucy5zdGFydEF4aXM7XHJcbiAgdmFyIGN1cnJlbnRBeGlzID0gYWJzWCA+IGFic1kgPyAneCcgOiBhYnNYIDwgYWJzWSA/ICd5JyA6ICd4eSc7XHJcblxyXG4gIGludGVyYWN0aW9uLnByZXBhcmVkLmF4aXMgPSBvcHRpb25zLmxvY2tBeGlzID09PSAnc3RhcnQnID8gY3VycmVudEF4aXNbMF0gLy8gYWx3YXlzIGxvY2sgdG8gb25lIGF4aXMgZXZlbiBpZiBjdXJyZW50QXhpcyA9PT0gJ3h5J1xyXG4gIDogb3B0aW9ucy5sb2NrQXhpcztcclxuXHJcbiAgLy8gaWYgdGhlIG1vdmVtZW50IGlzbid0IGluIHRoZSBzdGFydEF4aXMgb2YgdGhlIGludGVyYWN0YWJsZVxyXG4gIGlmIChjdXJyZW50QXhpcyAhPT0gJ3h5JyAmJiBzdGFydEF4aXMgIT09ICd4eScgJiYgc3RhcnRBeGlzICE9PSBjdXJyZW50QXhpcykge1xyXG4gICAgLy8gY2FuY2VsIHRoZSBwcmVwYXJlZCBhY3Rpb25cclxuICAgIGludGVyYWN0aW9uLnByZXBhcmVkLm5hbWUgPSBudWxsO1xyXG5cclxuICAgIC8vIHRoZW4gdHJ5IHRvIGdldCBhIGRyYWcgZnJvbSBhbm90aGVyIGluZXJhY3RhYmxlXHJcblxyXG4gICAgaWYgKCFpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lKSB7XHJcblxyXG4gICAgICB2YXIgZWxlbWVudCA9IGV2ZW50VGFyZ2V0O1xyXG5cclxuICAgICAgdmFyIGdldERyYWdnYWJsZSA9IGZ1bmN0aW9uIGdldERyYWdnYWJsZShpbnRlcmFjdGFibGUsIHNlbGVjdG9yLCBjb250ZXh0KSB7XHJcbiAgICAgICAgdmFyIGVsZW1lbnRzID0gYnJvd3Nlci51c2VNYXRjaGVzU2VsZWN0b3JQb2x5ZmlsbCA/IGNvbnRleHQucXVlcnlTZWxlY3RvckFsbChzZWxlY3RvcikgOiB1bmRlZmluZWQ7XHJcblxyXG4gICAgICAgIGlmIChpbnRlcmFjdGFibGUgPT09IGludGVyYWN0aW9uLnRhcmdldCkge1xyXG4gICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCFvcHRpb25zLm1hbnVhbFN0YXJ0ICYmICFpbnRlcmFjdGFibGUudGVzdElnbm9yZUFsbG93KG9wdGlvbnMsIGVsZW1lbnQsIGV2ZW50VGFyZ2V0KSAmJiBtYXRjaGVzU2VsZWN0b3IoZWxlbWVudCwgc2VsZWN0b3IsIGVsZW1lbnRzKSkge1xyXG5cclxuICAgICAgICAgIHZhciBfYWN0aW9uID0gaW50ZXJhY3RhYmxlLmdldEFjdGlvbihpbnRlcmFjdGlvbi5kb3duUG9pbnRlciwgaW50ZXJhY3Rpb24uZG93bkV2ZW50LCBpbnRlcmFjdGlvbiwgZWxlbWVudCk7XHJcblxyXG4gICAgICAgICAgaWYgKF9hY3Rpb24gJiYgX2FjdGlvbi5uYW1lID09PSAnZHJhZycgJiYgY2hlY2tTdGFydEF4aXMoY3VycmVudEF4aXMsIGludGVyYWN0YWJsZSkgJiYgYXV0b1N0YXJ0LnZhbGlkYXRlQWN0aW9uKF9hY3Rpb24sIGludGVyYWN0YWJsZSwgZWxlbWVudCwgZXZlbnRUYXJnZXQpKSB7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gaW50ZXJhY3RhYmxlO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfTtcclxuXHJcbiAgICAgIHZhciBhY3Rpb24gPSBudWxsO1xyXG5cclxuICAgICAgLy8gY2hlY2sgYWxsIGludGVyYWN0YWJsZXNcclxuICAgICAgd2hpbGUgKGlzLmVsZW1lbnQoZWxlbWVudCkpIHtcclxuICAgICAgICB2YXIgZWxlbWVudEludGVyYWN0YWJsZSA9IHNjb3BlLmludGVyYWN0YWJsZXMuZ2V0KGVsZW1lbnQpO1xyXG5cclxuICAgICAgICBpZiAoZWxlbWVudEludGVyYWN0YWJsZSAmJiBlbGVtZW50SW50ZXJhY3RhYmxlICE9PSBpbnRlcmFjdGlvbi50YXJnZXQgJiYgIWVsZW1lbnRJbnRlcmFjdGFibGUub3B0aW9ucy5kcmFnLm1hbnVhbFN0YXJ0KSB7XHJcblxyXG4gICAgICAgICAgYWN0aW9uID0gZWxlbWVudEludGVyYWN0YWJsZS5nZXRBY3Rpb24oaW50ZXJhY3Rpb24uZG93blBvaW50ZXIsIGludGVyYWN0aW9uLmRvd25FdmVudCwgaW50ZXJhY3Rpb24sIGVsZW1lbnQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoYWN0aW9uICYmIGFjdGlvbi5uYW1lID09PSAnZHJhZycgJiYgY2hlY2tTdGFydEF4aXMoY3VycmVudEF4aXMsIGVsZW1lbnRJbnRlcmFjdGFibGUpKSB7XHJcblxyXG4gICAgICAgICAgaW50ZXJhY3Rpb24ucHJlcGFyZWQubmFtZSA9ICdkcmFnJztcclxuICAgICAgICAgIGludGVyYWN0aW9uLnRhcmdldCA9IGVsZW1lbnRJbnRlcmFjdGFibGU7XHJcbiAgICAgICAgICBpbnRlcmFjdGlvbi5lbGVtZW50ID0gZWxlbWVudDtcclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIHNlbGVjdG9ySW50ZXJhY3RhYmxlID0gc2NvcGUuaW50ZXJhY3RhYmxlcy5mb3JFYWNoU2VsZWN0b3IoZ2V0RHJhZ2dhYmxlLCBlbGVtZW50KTtcclxuXHJcbiAgICAgICAgaWYgKHNlbGVjdG9ySW50ZXJhY3RhYmxlKSB7XHJcbiAgICAgICAgICBpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lID0gJ2RyYWcnO1xyXG4gICAgICAgICAgaW50ZXJhY3Rpb24udGFyZ2V0ID0gc2VsZWN0b3JJbnRlcmFjdGFibGU7XHJcbiAgICAgICAgICBpbnRlcmFjdGlvbi5lbGVtZW50ID0gZWxlbWVudDtcclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZWxlbWVudCA9IHBhcmVudE5vZGUoZWxlbWVudCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcbn0pO1xyXG5cclxuZnVuY3Rpb24gY2hlY2tTdGFydEF4aXMoc3RhcnRBeGlzLCBpbnRlcmFjdGFibGUpIHtcclxuICBpZiAoIWludGVyYWN0YWJsZSkge1xyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG4gIH1cclxuXHJcbiAgdmFyIHRoaXNBeGlzID0gaW50ZXJhY3RhYmxlLm9wdGlvbnMuZHJhZy5zdGFydEF4aXM7XHJcblxyXG4gIHJldHVybiBzdGFydEF4aXMgPT09ICd4eScgfHwgdGhpc0F4aXMgPT09ICd4eScgfHwgdGhpc0F4aXMgPT09IHN0YXJ0QXhpcztcclxufVxyXG5cclxufSx7XCIuLi9hY3Rpb25zL2RyYWdcIjo3LFwiLi4vc2NvcGVcIjozNCxcIi4uL3V0aWxzL2Jyb3dzZXJcIjozNyxcIi4uL3V0aWxzL2RvbVV0aWxzXCI6MzksXCIuLi91dGlscy9pc1wiOjQ2LFwiLi9iYXNlXCI6MTN9XSwxNjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbnJlcXVpcmUoJy4vYmFzZScpLnNldEFjdGlvbkRlZmF1bHRzKHJlcXVpcmUoJy4uL2FjdGlvbnMvZ2VzdHVyZScpKTtcclxuXHJcbn0se1wiLi4vYWN0aW9ucy9nZXN0dXJlXCI6OSxcIi4vYmFzZVwiOjEzfV0sMTc6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xyXG4ndXNlIHN0cmljdCc7XHJcblxyXG5yZXF1aXJlKCcuL2Jhc2UnKS5zZXRBY3Rpb25EZWZhdWx0cyhyZXF1aXJlKCcuLi9hY3Rpb25zL3Jlc2l6ZScpKTtcclxuXHJcbn0se1wiLi4vYWN0aW9ucy9yZXNpemVcIjoxMCxcIi4vYmFzZVwiOjEzfV0sMTg6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xyXG4ndXNlIHN0cmljdCc7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHtcclxuICBiYXNlOiB7XHJcbiAgICBhY2NlcHQ6IG51bGwsXHJcbiAgICBwcmV2ZW50RGVmYXVsdDogJ2F1dG8nLFxyXG4gICAgZGVsdGFTb3VyY2U6ICdwYWdlJ1xyXG4gIH0sXHJcblxyXG4gIHBlckFjdGlvbjoge1xyXG4gICAgb3JpZ2luOiB7IHg6IDAsIHk6IDAgfSxcclxuXHJcbiAgICAvLyBvbmx5IGFsbG93IGxlZnQgYnV0dG9uIGJ5IGRlZmF1bHRcclxuICAgIC8vIHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvTW91c2VFdmVudC9idXR0b25zI1JldHVybl92YWx1ZVxyXG4gICAgbW91c2VCdXR0b25zOiAxLFxyXG5cclxuICAgIGluZXJ0aWE6IHtcclxuICAgICAgZW5hYmxlZDogZmFsc2UsXHJcbiAgICAgIHJlc2lzdGFuY2U6IDEwLCAvLyB0aGUgbGFtYmRhIGluIGV4cG9uZW50aWFsIGRlY2F5XHJcbiAgICAgIG1pblNwZWVkOiAxMDAsIC8vIHRhcmdldCBzcGVlZCBtdXN0IGJlIGFib3ZlIHRoaXMgZm9yIGluZXJ0aWEgdG8gc3RhcnRcclxuICAgICAgZW5kU3BlZWQ6IDEwLCAvLyB0aGUgc3BlZWQgYXQgd2hpY2ggaW5lcnRpYSBpcyBzbG93IGVub3VnaCB0byBzdG9wXHJcbiAgICAgIGFsbG93UmVzdW1lOiB0cnVlLCAvLyBhbGxvdyByZXN1bWluZyBhbiBhY3Rpb24gaW4gaW5lcnRpYSBwaGFzZVxyXG4gICAgICBzbW9vdGhFbmREdXJhdGlvbjogMzAwIC8vIGFuaW1hdGUgdG8gc25hcC9yZXN0cmljdCBlbmRPbmx5IGlmIHRoZXJlJ3Mgbm8gaW5lcnRpYVxyXG4gICAgfVxyXG4gIH1cclxufTtcclxuXHJcbn0se31dLDE5OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxuLyogYnJvd3NlciBlbnRyeSBwb2ludCAqL1xyXG5cclxuLy8gTGVnYWN5IGJyb3dzZXIgc3VwcG9ydFxyXG5yZXF1aXJlKCcuL2xlZ2FjeUJyb3dzZXJzJyk7XHJcblxyXG4vLyBpbmVydGlhXHJcbnJlcXVpcmUoJy4vaW5lcnRpYScpO1xyXG5cclxuLy8gbW9kaWZpZXJzXHJcbnJlcXVpcmUoJy4vbW9kaWZpZXJzL3NuYXAnKTtcclxucmVxdWlyZSgnLi9tb2RpZmllcnMvcmVzdHJpY3QnKTtcclxuXHJcbi8vIHBvaW50ZXJFdmVudHNcclxucmVxdWlyZSgnLi9wb2ludGVyRXZlbnRzL2Jhc2UnKTtcclxucmVxdWlyZSgnLi9wb2ludGVyRXZlbnRzL2hvbGRSZXBlYXQnKTtcclxucmVxdWlyZSgnLi9wb2ludGVyRXZlbnRzL2ludGVyYWN0YWJsZVRhcmdldHMnKTtcclxuXHJcbi8vIGRlbGF5XHJcbnJlcXVpcmUoJy4vYXV0b1N0YXJ0L2RlbGF5Jyk7XHJcblxyXG4vLyBhY3Rpb25zXHJcbnJlcXVpcmUoJy4vYWN0aW9ucy9nZXN0dXJlJyk7XHJcbnJlcXVpcmUoJy4vYWN0aW9ucy9yZXNpemUnKTtcclxucmVxdWlyZSgnLi9hY3Rpb25zL2RyYWcnKTtcclxucmVxdWlyZSgnLi9hY3Rpb25zL2Ryb3AnKTtcclxuXHJcbi8vIGxvYWQgdGhlc2UgbW9kaWZpZXJzIGFmdGVyIHJlc2l6ZSBpcyBsb2FkZWRcclxucmVxdWlyZSgnLi9tb2RpZmllcnMvc25hcFNpemUnKTtcclxucmVxdWlyZSgnLi9tb2RpZmllcnMvcmVzdHJpY3RFZGdlcycpO1xyXG5yZXF1aXJlKCcuL21vZGlmaWVycy9yZXN0cmljdFNpemUnKTtcclxuXHJcbi8vIGF1dG9TdGFydCBhY3Rpb25zXHJcbnJlcXVpcmUoJy4vYXV0b1N0YXJ0L2dlc3R1cmUnKTtcclxucmVxdWlyZSgnLi9hdXRvU3RhcnQvcmVzaXplJyk7XHJcbnJlcXVpcmUoJy4vYXV0b1N0YXJ0L2RyYWcnKTtcclxuXHJcbi8vIEludGVyYWN0YWJsZSBwcmV2ZW50RGVmYXVsdCBzZXR0aW5nXHJcbnJlcXVpcmUoJy4vaW50ZXJhY3RhYmxlUHJldmVudERlZmF1bHQuanMnKTtcclxuXHJcbi8vIGF1dG9TY3JvbGxcclxucmVxdWlyZSgnLi9hdXRvU2Nyb2xsJyk7XHJcblxyXG4vLyBleHBvcnQgaW50ZXJhY3RcclxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2ludGVyYWN0Jyk7XHJcblxyXG59LHtcIi4vYWN0aW9ucy9kcmFnXCI6NyxcIi4vYWN0aW9ucy9kcm9wXCI6OCxcIi4vYWN0aW9ucy9nZXN0dXJlXCI6OSxcIi4vYWN0aW9ucy9yZXNpemVcIjoxMCxcIi4vYXV0b1Njcm9sbFwiOjExLFwiLi9hdXRvU3RhcnQvZGVsYXlcIjoxNCxcIi4vYXV0b1N0YXJ0L2RyYWdcIjoxNSxcIi4vYXV0b1N0YXJ0L2dlc3R1cmVcIjoxNixcIi4vYXV0b1N0YXJ0L3Jlc2l6ZVwiOjE3LFwiLi9pbmVydGlhXCI6MjAsXCIuL2ludGVyYWN0XCI6MjEsXCIuL2ludGVyYWN0YWJsZVByZXZlbnREZWZhdWx0LmpzXCI6MjIsXCIuL2xlZ2FjeUJyb3dzZXJzXCI6MjMsXCIuL21vZGlmaWVycy9yZXN0cmljdFwiOjI1LFwiLi9tb2RpZmllcnMvcmVzdHJpY3RFZGdlc1wiOjI2LFwiLi9tb2RpZmllcnMvcmVzdHJpY3RTaXplXCI6MjcsXCIuL21vZGlmaWVycy9zbmFwXCI6MjgsXCIuL21vZGlmaWVycy9zbmFwU2l6ZVwiOjI5LFwiLi9wb2ludGVyRXZlbnRzL2Jhc2VcIjozMSxcIi4vcG9pbnRlckV2ZW50cy9ob2xkUmVwZWF0XCI6MzIsXCIuL3BvaW50ZXJFdmVudHMvaW50ZXJhY3RhYmxlVGFyZ2V0c1wiOjMzfV0sMjA6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xyXG4ndXNlIHN0cmljdCc7XHJcblxyXG52YXIgSW50ZXJhY3RFdmVudCA9IHJlcXVpcmUoJy4vSW50ZXJhY3RFdmVudCcpO1xyXG52YXIgSW50ZXJhY3Rpb24gPSByZXF1aXJlKCcuL0ludGVyYWN0aW9uJyk7XHJcbnZhciBtb2RpZmllcnMgPSByZXF1aXJlKCcuL21vZGlmaWVycycpO1xyXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XHJcbnZhciBhbmltYXRpb25GcmFtZSA9IHJlcXVpcmUoJy4vdXRpbHMvcmFmJyk7XHJcblxyXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCduZXcnLCBmdW5jdGlvbiAoaW50ZXJhY3Rpb24pIHtcclxuICBpbnRlcmFjdGlvbi5pbmVydGlhU3RhdHVzID0ge1xyXG4gICAgYWN0aXZlOiBmYWxzZSxcclxuICAgIHNtb290aEVuZDogZmFsc2UsXHJcbiAgICBhbGxvd1Jlc3VtZTogZmFsc2UsXHJcblxyXG4gICAgc3RhcnRFdmVudDogbnVsbCxcclxuICAgIHVwQ29vcmRzOiB7fSxcclxuXHJcbiAgICB4ZTogMCwgeWU6IDAsXHJcbiAgICBzeDogMCwgc3k6IDAsXHJcblxyXG4gICAgdDA6IDAsXHJcbiAgICB2eDA6IDAsIHZ5czogMCxcclxuICAgIGR1cmF0aW9uOiAwLFxyXG5cclxuICAgIGxhbWJkYV92MDogMCxcclxuICAgIG9uZV92ZV92MDogMCxcclxuICAgIGk6IG51bGxcclxuICB9O1xyXG5cclxuICBpbnRlcmFjdGlvbi5ib3VuZEluZXJ0aWFGcmFtZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHJldHVybiBpbmVydGlhRnJhbWUuYXBwbHkoaW50ZXJhY3Rpb24pO1xyXG4gIH07XHJcbiAgaW50ZXJhY3Rpb24uYm91bmRTbW9vdGhFbmRGcmFtZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHJldHVybiBzbW9vdGhFbmRGcmFtZS5hcHBseShpbnRlcmFjdGlvbik7XHJcbiAgfTtcclxufSk7XHJcblxyXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdkb3duJywgZnVuY3Rpb24gKF9yZWYpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmLmludGVyYWN0aW9uLFxyXG4gICAgICBldmVudCA9IF9yZWYuZXZlbnQsXHJcbiAgICAgIHBvaW50ZXIgPSBfcmVmLnBvaW50ZXIsXHJcbiAgICAgIGV2ZW50VGFyZ2V0ID0gX3JlZi5ldmVudFRhcmdldDtcclxuXHJcbiAgdmFyIHN0YXR1cyA9IGludGVyYWN0aW9uLmluZXJ0aWFTdGF0dXM7XHJcblxyXG4gIC8vIENoZWNrIGlmIHRoZSBkb3duIGV2ZW50IGhpdHMgdGhlIGN1cnJlbnQgaW5lcnRpYSB0YXJnZXRcclxuICBpZiAoc3RhdHVzLmFjdGl2ZSkge1xyXG4gICAgdmFyIGVsZW1lbnQgPSBldmVudFRhcmdldDtcclxuXHJcbiAgICAvLyBjbGltYiB1cCB0aGUgRE9NIHRyZWUgZnJvbSB0aGUgZXZlbnQgdGFyZ2V0XHJcbiAgICB3aGlsZSAodXRpbHMuaXMuZWxlbWVudChlbGVtZW50KSkge1xyXG5cclxuICAgICAgLy8gaWYgaW50ZXJhY3Rpb24gZWxlbWVudCBpcyB0aGUgY3VycmVudCBpbmVydGlhIHRhcmdldCBlbGVtZW50XHJcbiAgICAgIGlmIChlbGVtZW50ID09PSBpbnRlcmFjdGlvbi5lbGVtZW50KSB7XHJcbiAgICAgICAgLy8gc3RvcCBpbmVydGlhXHJcbiAgICAgICAgYW5pbWF0aW9uRnJhbWUuY2FuY2VsKHN0YXR1cy5pKTtcclxuICAgICAgICBzdGF0dXMuYWN0aXZlID0gZmFsc2U7XHJcbiAgICAgICAgaW50ZXJhY3Rpb24uc2ltdWxhdGlvbiA9IG51bGw7XHJcblxyXG4gICAgICAgIC8vIHVwZGF0ZSBwb2ludGVycyB0byB0aGUgZG93biBldmVudCdzIGNvb3JkaW5hdGVzXHJcbiAgICAgICAgaW50ZXJhY3Rpb24udXBkYXRlUG9pbnRlcihwb2ludGVyKTtcclxuICAgICAgICB1dGlscy5zZXRDb29yZHMoaW50ZXJhY3Rpb24uY3VyQ29vcmRzLCBpbnRlcmFjdGlvbi5wb2ludGVycyk7XHJcblxyXG4gICAgICAgIC8vIGZpcmUgYXBwcm9wcmlhdGUgc2lnbmFsc1xyXG4gICAgICAgIHZhciBzaWduYWxBcmcgPSB7IGludGVyYWN0aW9uOiBpbnRlcmFjdGlvbiB9O1xyXG4gICAgICAgIEludGVyYWN0aW9uLnNpZ25hbHMuZmlyZSgnYmVmb3JlLWFjdGlvbi1tb3ZlJywgc2lnbmFsQXJnKTtcclxuICAgICAgICBJbnRlcmFjdGlvbi5zaWduYWxzLmZpcmUoJ2FjdGlvbi1yZXN1bWUnLCBzaWduYWxBcmcpO1xyXG5cclxuICAgICAgICAvLyBmaXJlIGEgcmV1bWUgZXZlbnRcclxuICAgICAgICB2YXIgcmVzdW1lRXZlbnQgPSBuZXcgSW50ZXJhY3RFdmVudChpbnRlcmFjdGlvbiwgZXZlbnQsIGludGVyYWN0aW9uLnByZXBhcmVkLm5hbWUsICdpbmVydGlhcmVzdW1lJywgaW50ZXJhY3Rpb24uZWxlbWVudCk7XHJcblxyXG4gICAgICAgIGludGVyYWN0aW9uLnRhcmdldC5maXJlKHJlc3VtZUV2ZW50KTtcclxuICAgICAgICBpbnRlcmFjdGlvbi5wcmV2RXZlbnQgPSByZXN1bWVFdmVudDtcclxuICAgICAgICBtb2RpZmllcnMucmVzZXRTdGF0dXNlcyhpbnRlcmFjdGlvbi5tb2RpZmllclN0YXR1c2VzKTtcclxuXHJcbiAgICAgICAgdXRpbHMuY29weUNvb3JkcyhpbnRlcmFjdGlvbi5wcmV2Q29vcmRzLCBpbnRlcmFjdGlvbi5jdXJDb29yZHMpO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBlbGVtZW50ID0gdXRpbHMucGFyZW50Tm9kZShlbGVtZW50KTtcclxuICAgIH1cclxuICB9XHJcbn0pO1xyXG5cclxuSW50ZXJhY3Rpb24uc2lnbmFscy5vbigndXAnLCBmdW5jdGlvbiAoX3JlZjIpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmMi5pbnRlcmFjdGlvbixcclxuICAgICAgZXZlbnQgPSBfcmVmMi5ldmVudDtcclxuXHJcbiAgdmFyIHN0YXR1cyA9IGludGVyYWN0aW9uLmluZXJ0aWFTdGF0dXM7XHJcblxyXG4gIGlmICghaW50ZXJhY3Rpb24uaW50ZXJhY3RpbmcoKSB8fCBzdGF0dXMuYWN0aXZlKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICB2YXIgdGFyZ2V0ID0gaW50ZXJhY3Rpb24udGFyZ2V0O1xyXG4gIHZhciBvcHRpb25zID0gdGFyZ2V0ICYmIHRhcmdldC5vcHRpb25zO1xyXG4gIHZhciBpbmVydGlhT3B0aW9ucyA9IG9wdGlvbnMgJiYgaW50ZXJhY3Rpb24ucHJlcGFyZWQubmFtZSAmJiBvcHRpb25zW2ludGVyYWN0aW9uLnByZXBhcmVkLm5hbWVdLmluZXJ0aWE7XHJcblxyXG4gIHZhciBub3cgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcclxuICB2YXIgc3RhdHVzZXMgPSB7fTtcclxuICB2YXIgcGFnZSA9IHV0aWxzLmV4dGVuZCh7fSwgaW50ZXJhY3Rpb24uY3VyQ29vcmRzLnBhZ2UpO1xyXG4gIHZhciBwb2ludGVyU3BlZWQgPSBpbnRlcmFjdGlvbi5wb2ludGVyRGVsdGEuY2xpZW50LnNwZWVkO1xyXG5cclxuICB2YXIgc21vb3RoRW5kID0gZmFsc2U7XHJcbiAgdmFyIG1vZGlmaWVyUmVzdWx0ID0gdm9pZCAwO1xyXG5cclxuICAvLyBjaGVjayBpZiBpbmVydGlhIHNob3VsZCBiZSBzdGFydGVkXHJcbiAgdmFyIGluZXJ0aWFQb3NzaWJsZSA9IGluZXJ0aWFPcHRpb25zICYmIGluZXJ0aWFPcHRpb25zLmVuYWJsZWQgJiYgaW50ZXJhY3Rpb24ucHJlcGFyZWQubmFtZSAhPT0gJ2dlc3R1cmUnICYmIGV2ZW50ICE9PSBzdGF0dXMuc3RhcnRFdmVudDtcclxuXHJcbiAgdmFyIGluZXJ0aWEgPSBpbmVydGlhUG9zc2libGUgJiYgbm93IC0gaW50ZXJhY3Rpb24uY3VyQ29vcmRzLnRpbWVTdGFtcCA8IDUwICYmIHBvaW50ZXJTcGVlZCA+IGluZXJ0aWFPcHRpb25zLm1pblNwZWVkICYmIHBvaW50ZXJTcGVlZCA+IGluZXJ0aWFPcHRpb25zLmVuZFNwZWVkO1xyXG5cclxuICB2YXIgbW9kaWZpZXJBcmcgPSB7XHJcbiAgICBpbnRlcmFjdGlvbjogaW50ZXJhY3Rpb24sXHJcbiAgICBwYWdlQ29vcmRzOiBwYWdlLFxyXG4gICAgc3RhdHVzZXM6IHN0YXR1c2VzLFxyXG4gICAgcHJlRW5kOiB0cnVlLFxyXG4gICAgcmVxdWlyZUVuZE9ubHk6IHRydWVcclxuICB9O1xyXG5cclxuICAvLyBzbW9vdGhFbmRcclxuICBpZiAoaW5lcnRpYVBvc3NpYmxlICYmICFpbmVydGlhKSB7XHJcbiAgICBtb2RpZmllcnMucmVzZXRTdGF0dXNlcyhzdGF0dXNlcyk7XHJcblxyXG4gICAgbW9kaWZpZXJSZXN1bHQgPSBtb2RpZmllcnMuc2V0QWxsKG1vZGlmaWVyQXJnKTtcclxuXHJcbiAgICBpZiAobW9kaWZpZXJSZXN1bHQuc2hvdWxkTW92ZSAmJiBtb2RpZmllclJlc3VsdC5sb2NrZWQpIHtcclxuICAgICAgc21vb3RoRW5kID0gdHJ1ZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGlmICghKGluZXJ0aWEgfHwgc21vb3RoRW5kKSkge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgdXRpbHMuY29weUNvb3JkcyhzdGF0dXMudXBDb29yZHMsIGludGVyYWN0aW9uLmN1ckNvb3Jkcyk7XHJcblxyXG4gIGludGVyYWN0aW9uLnBvaW50ZXJzWzBdID0gc3RhdHVzLnN0YXJ0RXZlbnQgPSBuZXcgSW50ZXJhY3RFdmVudChpbnRlcmFjdGlvbiwgZXZlbnQsIGludGVyYWN0aW9uLnByZXBhcmVkLm5hbWUsICdpbmVydGlhc3RhcnQnLCBpbnRlcmFjdGlvbi5lbGVtZW50KTtcclxuXHJcbiAgc3RhdHVzLnQwID0gbm93O1xyXG5cclxuICBzdGF0dXMuYWN0aXZlID0gdHJ1ZTtcclxuICBzdGF0dXMuYWxsb3dSZXN1bWUgPSBpbmVydGlhT3B0aW9ucy5hbGxvd1Jlc3VtZTtcclxuICBpbnRlcmFjdGlvbi5zaW11bGF0aW9uID0gc3RhdHVzO1xyXG5cclxuICB0YXJnZXQuZmlyZShzdGF0dXMuc3RhcnRFdmVudCk7XHJcblxyXG4gIGlmIChpbmVydGlhKSB7XHJcbiAgICBzdGF0dXMudngwID0gaW50ZXJhY3Rpb24ucG9pbnRlckRlbHRhLmNsaWVudC52eDtcclxuICAgIHN0YXR1cy52eTAgPSBpbnRlcmFjdGlvbi5wb2ludGVyRGVsdGEuY2xpZW50LnZ5O1xyXG4gICAgc3RhdHVzLnYwID0gcG9pbnRlclNwZWVkO1xyXG5cclxuICAgIGNhbGNJbmVydGlhKGludGVyYWN0aW9uLCBzdGF0dXMpO1xyXG5cclxuICAgIHV0aWxzLmV4dGVuZChwYWdlLCBpbnRlcmFjdGlvbi5jdXJDb29yZHMucGFnZSk7XHJcblxyXG4gICAgcGFnZS54ICs9IHN0YXR1cy54ZTtcclxuICAgIHBhZ2UueSArPSBzdGF0dXMueWU7XHJcblxyXG4gICAgbW9kaWZpZXJzLnJlc2V0U3RhdHVzZXMoc3RhdHVzZXMpO1xyXG5cclxuICAgIG1vZGlmaWVyUmVzdWx0ID0gbW9kaWZpZXJzLnNldEFsbChtb2RpZmllckFyZyk7XHJcblxyXG4gICAgc3RhdHVzLm1vZGlmaWVkWGUgKz0gbW9kaWZpZXJSZXN1bHQuZHg7XHJcbiAgICBzdGF0dXMubW9kaWZpZWRZZSArPSBtb2RpZmllclJlc3VsdC5keTtcclxuXHJcbiAgICBzdGF0dXMuaSA9IGFuaW1hdGlvbkZyYW1lLnJlcXVlc3QoaW50ZXJhY3Rpb24uYm91bmRJbmVydGlhRnJhbWUpO1xyXG4gIH0gZWxzZSB7XHJcbiAgICBzdGF0dXMuc21vb3RoRW5kID0gdHJ1ZTtcclxuICAgIHN0YXR1cy54ZSA9IG1vZGlmaWVyUmVzdWx0LmR4O1xyXG4gICAgc3RhdHVzLnllID0gbW9kaWZpZXJSZXN1bHQuZHk7XHJcblxyXG4gICAgc3RhdHVzLnN4ID0gc3RhdHVzLnN5ID0gMDtcclxuXHJcbiAgICBzdGF0dXMuaSA9IGFuaW1hdGlvbkZyYW1lLnJlcXVlc3QoaW50ZXJhY3Rpb24uYm91bmRTbW9vdGhFbmRGcmFtZSk7XHJcbiAgfVxyXG59KTtcclxuXHJcbkludGVyYWN0aW9uLnNpZ25hbHMub24oJ3N0b3AtYWN0aXZlJywgZnVuY3Rpb24gKF9yZWYzKSB7XHJcbiAgdmFyIGludGVyYWN0aW9uID0gX3JlZjMuaW50ZXJhY3Rpb247XHJcblxyXG4gIHZhciBzdGF0dXMgPSBpbnRlcmFjdGlvbi5pbmVydGlhU3RhdHVzO1xyXG5cclxuICBpZiAoc3RhdHVzLmFjdGl2ZSkge1xyXG4gICAgYW5pbWF0aW9uRnJhbWUuY2FuY2VsKHN0YXR1cy5pKTtcclxuICAgIHN0YXR1cy5hY3RpdmUgPSBmYWxzZTtcclxuICAgIGludGVyYWN0aW9uLnNpbXVsYXRpb24gPSBudWxsO1xyXG4gIH1cclxufSk7XHJcblxyXG5mdW5jdGlvbiBjYWxjSW5lcnRpYShpbnRlcmFjdGlvbiwgc3RhdHVzKSB7XHJcbiAgdmFyIGluZXJ0aWFPcHRpb25zID0gaW50ZXJhY3Rpb24udGFyZ2V0Lm9wdGlvbnNbaW50ZXJhY3Rpb24ucHJlcGFyZWQubmFtZV0uaW5lcnRpYTtcclxuICB2YXIgbGFtYmRhID0gaW5lcnRpYU9wdGlvbnMucmVzaXN0YW5jZTtcclxuICB2YXIgaW5lcnRpYUR1ciA9IC1NYXRoLmxvZyhpbmVydGlhT3B0aW9ucy5lbmRTcGVlZCAvIHN0YXR1cy52MCkgLyBsYW1iZGE7XHJcblxyXG4gIHN0YXR1cy54MCA9IGludGVyYWN0aW9uLnByZXZFdmVudC5wYWdlWDtcclxuICBzdGF0dXMueTAgPSBpbnRlcmFjdGlvbi5wcmV2RXZlbnQucGFnZVk7XHJcbiAgc3RhdHVzLnQwID0gc3RhdHVzLnN0YXJ0RXZlbnQudGltZVN0YW1wIC8gMTAwMDtcclxuICBzdGF0dXMuc3ggPSBzdGF0dXMuc3kgPSAwO1xyXG5cclxuICBzdGF0dXMubW9kaWZpZWRYZSA9IHN0YXR1cy54ZSA9IChzdGF0dXMudngwIC0gaW5lcnRpYUR1cikgLyBsYW1iZGE7XHJcbiAgc3RhdHVzLm1vZGlmaWVkWWUgPSBzdGF0dXMueWUgPSAoc3RhdHVzLnZ5MCAtIGluZXJ0aWFEdXIpIC8gbGFtYmRhO1xyXG4gIHN0YXR1cy50ZSA9IGluZXJ0aWFEdXI7XHJcblxyXG4gIHN0YXR1cy5sYW1iZGFfdjAgPSBsYW1iZGEgLyBzdGF0dXMudjA7XHJcbiAgc3RhdHVzLm9uZV92ZV92MCA9IDEgLSBpbmVydGlhT3B0aW9ucy5lbmRTcGVlZCAvIHN0YXR1cy52MDtcclxufVxyXG5cclxuZnVuY3Rpb24gaW5lcnRpYUZyYW1lKCkge1xyXG4gIHVwZGF0ZUluZXJ0aWFDb29yZHModGhpcyk7XHJcbiAgdXRpbHMuc2V0Q29vcmREZWx0YXModGhpcy5wb2ludGVyRGVsdGEsIHRoaXMucHJldkNvb3JkcywgdGhpcy5jdXJDb29yZHMpO1xyXG5cclxuICB2YXIgc3RhdHVzID0gdGhpcy5pbmVydGlhU3RhdHVzO1xyXG4gIHZhciBvcHRpb25zID0gdGhpcy50YXJnZXQub3B0aW9uc1t0aGlzLnByZXBhcmVkLm5hbWVdLmluZXJ0aWE7XHJcbiAgdmFyIGxhbWJkYSA9IG9wdGlvbnMucmVzaXN0YW5jZTtcclxuICB2YXIgdCA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpIC8gMTAwMCAtIHN0YXR1cy50MDtcclxuXHJcbiAgaWYgKHQgPCBzdGF0dXMudGUpIHtcclxuXHJcbiAgICB2YXIgcHJvZ3Jlc3MgPSAxIC0gKE1hdGguZXhwKC1sYW1iZGEgKiB0KSAtIHN0YXR1cy5sYW1iZGFfdjApIC8gc3RhdHVzLm9uZV92ZV92MDtcclxuXHJcbiAgICBpZiAoc3RhdHVzLm1vZGlmaWVkWGUgPT09IHN0YXR1cy54ZSAmJiBzdGF0dXMubW9kaWZpZWRZZSA9PT0gc3RhdHVzLnllKSB7XHJcbiAgICAgIHN0YXR1cy5zeCA9IHN0YXR1cy54ZSAqIHByb2dyZXNzO1xyXG4gICAgICBzdGF0dXMuc3kgPSBzdGF0dXMueWUgKiBwcm9ncmVzcztcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHZhciBxdWFkUG9pbnQgPSB1dGlscy5nZXRRdWFkcmF0aWNDdXJ2ZVBvaW50KDAsIDAsIHN0YXR1cy54ZSwgc3RhdHVzLnllLCBzdGF0dXMubW9kaWZpZWRYZSwgc3RhdHVzLm1vZGlmaWVkWWUsIHByb2dyZXNzKTtcclxuXHJcbiAgICAgIHN0YXR1cy5zeCA9IHF1YWRQb2ludC54O1xyXG4gICAgICBzdGF0dXMuc3kgPSBxdWFkUG9pbnQueTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLmRvTW92ZSgpO1xyXG5cclxuICAgIHN0YXR1cy5pID0gYW5pbWF0aW9uRnJhbWUucmVxdWVzdCh0aGlzLmJvdW5kSW5lcnRpYUZyYW1lKTtcclxuICB9IGVsc2Uge1xyXG4gICAgc3RhdHVzLnN4ID0gc3RhdHVzLm1vZGlmaWVkWGU7XHJcbiAgICBzdGF0dXMuc3kgPSBzdGF0dXMubW9kaWZpZWRZZTtcclxuXHJcbiAgICB0aGlzLmRvTW92ZSgpO1xyXG4gICAgdGhpcy5lbmQoc3RhdHVzLnN0YXJ0RXZlbnQpO1xyXG4gICAgc3RhdHVzLmFjdGl2ZSA9IGZhbHNlO1xyXG4gICAgdGhpcy5zaW11bGF0aW9uID0gbnVsbDtcclxuICB9XHJcblxyXG4gIHV0aWxzLmNvcHlDb29yZHModGhpcy5wcmV2Q29vcmRzLCB0aGlzLmN1ckNvb3Jkcyk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHNtb290aEVuZEZyYW1lKCkge1xyXG4gIHVwZGF0ZUluZXJ0aWFDb29yZHModGhpcyk7XHJcblxyXG4gIHZhciBzdGF0dXMgPSB0aGlzLmluZXJ0aWFTdGF0dXM7XHJcbiAgdmFyIHQgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIHN0YXR1cy50MDtcclxuICB2YXIgZHVyYXRpb24gPSB0aGlzLnRhcmdldC5vcHRpb25zW3RoaXMucHJlcGFyZWQubmFtZV0uaW5lcnRpYS5zbW9vdGhFbmREdXJhdGlvbjtcclxuXHJcbiAgaWYgKHQgPCBkdXJhdGlvbikge1xyXG4gICAgc3RhdHVzLnN4ID0gdXRpbHMuZWFzZU91dFF1YWQodCwgMCwgc3RhdHVzLnhlLCBkdXJhdGlvbik7XHJcbiAgICBzdGF0dXMuc3kgPSB1dGlscy5lYXNlT3V0UXVhZCh0LCAwLCBzdGF0dXMueWUsIGR1cmF0aW9uKTtcclxuXHJcbiAgICB0aGlzLnBvaW50ZXJNb3ZlKHN0YXR1cy5zdGFydEV2ZW50LCBzdGF0dXMuc3RhcnRFdmVudCk7XHJcblxyXG4gICAgc3RhdHVzLmkgPSBhbmltYXRpb25GcmFtZS5yZXF1ZXN0KHRoaXMuYm91bmRTbW9vdGhFbmRGcmFtZSk7XHJcbiAgfSBlbHNlIHtcclxuICAgIHN0YXR1cy5zeCA9IHN0YXR1cy54ZTtcclxuICAgIHN0YXR1cy5zeSA9IHN0YXR1cy55ZTtcclxuXHJcbiAgICB0aGlzLnBvaW50ZXJNb3ZlKHN0YXR1cy5zdGFydEV2ZW50LCBzdGF0dXMuc3RhcnRFdmVudCk7XHJcbiAgICB0aGlzLmVuZChzdGF0dXMuc3RhcnRFdmVudCk7XHJcblxyXG4gICAgc3RhdHVzLnNtb290aEVuZCA9IHN0YXR1cy5hY3RpdmUgPSBmYWxzZTtcclxuICAgIHRoaXMuc2ltdWxhdGlvbiA9IG51bGw7XHJcbiAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiB1cGRhdGVJbmVydGlhQ29vcmRzKGludGVyYWN0aW9uKSB7XHJcbiAgdmFyIHN0YXR1cyA9IGludGVyYWN0aW9uLmluZXJ0aWFTdGF0dXM7XHJcblxyXG4gIC8vIHJldHVybiBpZiBpbmVydGlhIGlzbid0IHJ1bm5pbmdcclxuICBpZiAoIXN0YXR1cy5hY3RpdmUpIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIHZhciBwYWdlVXAgPSBzdGF0dXMudXBDb29yZHMucGFnZTtcclxuICB2YXIgY2xpZW50VXAgPSBzdGF0dXMudXBDb29yZHMuY2xpZW50O1xyXG5cclxuICB1dGlscy5zZXRDb29yZHMoaW50ZXJhY3Rpb24uY3VyQ29vcmRzLCBbe1xyXG4gICAgcGFnZVg6IHBhZ2VVcC54ICsgc3RhdHVzLnN4LFxyXG4gICAgcGFnZVk6IHBhZ2VVcC55ICsgc3RhdHVzLnN5LFxyXG4gICAgY2xpZW50WDogY2xpZW50VXAueCArIHN0YXR1cy5zeCxcclxuICAgIGNsaWVudFk6IGNsaWVudFVwLnkgKyBzdGF0dXMuc3lcclxuICB9XSk7XHJcbn1cclxuXHJcbn0se1wiLi9JbnRlcmFjdEV2ZW50XCI6MyxcIi4vSW50ZXJhY3Rpb25cIjo1LFwiLi9tb2RpZmllcnNcIjoyNCxcIi4vdXRpbHNcIjo0NCxcIi4vdXRpbHMvcmFmXCI6NTB9XSwyMTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBicm93c2VyID0gcmVxdWlyZSgnLi91dGlscy9icm93c2VyJyk7XHJcbnZhciBldmVudHMgPSByZXF1aXJlKCcuL3V0aWxzL2V2ZW50cycpO1xyXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XHJcbnZhciBzY29wZSA9IHJlcXVpcmUoJy4vc2NvcGUnKTtcclxudmFyIEludGVyYWN0YWJsZSA9IHJlcXVpcmUoJy4vSW50ZXJhY3RhYmxlJyk7XHJcbnZhciBJbnRlcmFjdGlvbiA9IHJlcXVpcmUoJy4vSW50ZXJhY3Rpb24nKTtcclxuXHJcbnZhciBnbG9iYWxFdmVudHMgPSB7fTtcclxuXHJcbi8qXFxcclxuICogaW50ZXJhY3RcclxuIFsgbWV0aG9kIF1cclxuICpcclxuICogVGhlIG1ldGhvZHMgb2YgdGhpcyB2YXJpYWJsZSBjYW4gYmUgdXNlZCB0byBzZXQgZWxlbWVudHMgYXNcclxuICogaW50ZXJhY3RhYmxlcyBhbmQgYWxzbyB0byBjaGFuZ2UgdmFyaW91cyBkZWZhdWx0IHNldHRpbmdzLlxyXG4gKlxyXG4gKiBDYWxsaW5nIGl0IGFzIGEgZnVuY3Rpb24gYW5kIHBhc3NpbmcgYW4gZWxlbWVudCBvciBhIHZhbGlkIENTUyBzZWxlY3RvclxyXG4gKiBzdHJpbmcgcmV0dXJucyBhbiBJbnRlcmFjdGFibGUgb2JqZWN0IHdoaWNoIGhhcyB2YXJpb3VzIG1ldGhvZHMgdG9cclxuICogY29uZmlndXJlIGl0LlxyXG4gKlxyXG4gLSBlbGVtZW50IChFbGVtZW50IHwgc3RyaW5nKSBUaGUgSFRNTCBvciBTVkcgRWxlbWVudCB0byBpbnRlcmFjdCB3aXRoIG9yIENTUyBzZWxlY3RvclxyXG4gPSAob2JqZWN0KSBBbiBASW50ZXJhY3RhYmxlXHJcbiAqXHJcbiA+IFVzYWdlXHJcbiB8IGludGVyYWN0KCcjZHJhZ2dhYmxlJykuZHJhZ2dhYmxlKHRydWUpO1xyXG4gfFxyXG4gfCB2YXIgcmVjdGFibGVzID0gaW50ZXJhY3QoJ3JlY3QnKTtcclxuIHwgcmVjdGFibGVzXHJcbiB8ICAgICAuZ2VzdHVyYWJsZSh0cnVlKVxyXG4gfCAgICAgLm9uKCdnZXN0dXJlbW92ZScsIGZ1bmN0aW9uIChldmVudCkge1xyXG4gfCAgICAgICAgIC8vIC4uLlxyXG4gfCAgICAgfSk7XHJcblxcKi9cclxuZnVuY3Rpb24gaW50ZXJhY3QoZWxlbWVudCwgb3B0aW9ucykge1xyXG4gIHZhciBpbnRlcmFjdGFibGUgPSBzY29wZS5pbnRlcmFjdGFibGVzLmdldChlbGVtZW50LCBvcHRpb25zKTtcclxuXHJcbiAgaWYgKCFpbnRlcmFjdGFibGUpIHtcclxuICAgIGludGVyYWN0YWJsZSA9IG5ldyBJbnRlcmFjdGFibGUoZWxlbWVudCwgb3B0aW9ucyk7XHJcbiAgICBpbnRlcmFjdGFibGUuZXZlbnRzLmdsb2JhbCA9IGdsb2JhbEV2ZW50cztcclxuICB9XHJcblxyXG4gIHJldHVybiBpbnRlcmFjdGFibGU7XHJcbn1cclxuXHJcbi8qXFxcclxuICogaW50ZXJhY3QuaXNTZXRcclxuIFsgbWV0aG9kIF1cclxuICpcclxuICogQ2hlY2sgaWYgYW4gZWxlbWVudCBoYXMgYmVlbiBzZXRcclxuIC0gZWxlbWVudCAoRWxlbWVudCkgVGhlIEVsZW1lbnQgYmVpbmcgc2VhcmNoZWQgZm9yXHJcbiA9IChib29sZWFuKSBJbmRpY2F0ZXMgaWYgdGhlIGVsZW1lbnQgb3IgQ1NTIHNlbGVjdG9yIHdhcyBwcmV2aW91c2x5IHBhc3NlZCB0byBpbnRlcmFjdFxyXG5cXCovXHJcbmludGVyYWN0LmlzU2V0ID0gZnVuY3Rpb24gKGVsZW1lbnQsIG9wdGlvbnMpIHtcclxuICByZXR1cm4gc2NvcGUuaW50ZXJhY3RhYmxlcy5pbmRleE9mRWxlbWVudChlbGVtZW50LCBvcHRpb25zICYmIG9wdGlvbnMuY29udGV4dCkgIT09IC0xO1xyXG59O1xyXG5cclxuLypcXFxyXG4gKiBpbnRlcmFjdC5vblxyXG4gWyBtZXRob2QgXVxyXG4gKlxyXG4gKiBBZGRzIGEgZ2xvYmFsIGxpc3RlbmVyIGZvciBhbiBJbnRlcmFjdEV2ZW50IG9yIGFkZHMgYSBET00gZXZlbnQgdG9cclxuICogYGRvY3VtZW50YFxyXG4gKlxyXG4gLSB0eXBlICAgICAgIChzdHJpbmcgfCBhcnJheSB8IG9iamVjdCkgVGhlIHR5cGVzIG9mIGV2ZW50cyB0byBsaXN0ZW4gZm9yXHJcbiAtIGxpc3RlbmVyICAgKGZ1bmN0aW9uKSBUaGUgZnVuY3Rpb24gZXZlbnQgKHMpXHJcbiAtIG9wdGlvbnMgICAgKG9iamVjdCB8IGJvb2xlYW4pICNvcHRpb25hbCBvcHRpb25zIG9iamVjdCBvciB1c2VDYXB0dXJlIGZsYWcgZm9yIGFkZEV2ZW50TGlzdGVuZXJcclxuID0gKG9iamVjdCkgaW50ZXJhY3RcclxuXFwqL1xyXG5pbnRlcmFjdC5vbiA9IGZ1bmN0aW9uICh0eXBlLCBsaXN0ZW5lciwgb3B0aW9ucykge1xyXG4gIGlmICh1dGlscy5pcy5zdHJpbmcodHlwZSkgJiYgdHlwZS5zZWFyY2goJyAnKSAhPT0gLTEpIHtcclxuICAgIHR5cGUgPSB0eXBlLnRyaW0oKS5zcGxpdCgvICsvKTtcclxuICB9XHJcblxyXG4gIGlmICh1dGlscy5pcy5hcnJheSh0eXBlKSkge1xyXG4gICAgZm9yICh2YXIgX2l0ZXJhdG9yID0gdHlwZSwgX2lzQXJyYXkgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvciksIF9pID0gMCwgX2l0ZXJhdG9yID0gX2lzQXJyYXkgPyBfaXRlcmF0b3IgOiBfaXRlcmF0b3JbU3ltYm9sLml0ZXJhdG9yXSgpOzspIHtcclxuICAgICAgdmFyIF9yZWY7XHJcblxyXG4gICAgICBpZiAoX2lzQXJyYXkpIHtcclxuICAgICAgICBpZiAoX2kgPj0gX2l0ZXJhdG9yLmxlbmd0aCkgYnJlYWs7XHJcbiAgICAgICAgX3JlZiA9IF9pdGVyYXRvcltfaSsrXTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBfaSA9IF9pdGVyYXRvci5uZXh0KCk7XHJcbiAgICAgICAgaWYgKF9pLmRvbmUpIGJyZWFrO1xyXG4gICAgICAgIF9yZWYgPSBfaS52YWx1ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIGV2ZW50VHlwZSA9IF9yZWY7XHJcblxyXG4gICAgICBpbnRlcmFjdC5vbihldmVudFR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gaW50ZXJhY3Q7XHJcbiAgfVxyXG5cclxuICBpZiAodXRpbHMuaXMub2JqZWN0KHR5cGUpKSB7XHJcbiAgICBmb3IgKHZhciBwcm9wIGluIHR5cGUpIHtcclxuICAgICAgaW50ZXJhY3Qub24ocHJvcCwgdHlwZVtwcm9wXSwgbGlzdGVuZXIpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBpbnRlcmFjdDtcclxuICB9XHJcblxyXG4gIC8vIGlmIGl0IGlzIGFuIEludGVyYWN0RXZlbnQgdHlwZSwgYWRkIGxpc3RlbmVyIHRvIGdsb2JhbEV2ZW50c1xyXG4gIGlmICh1dGlscy5jb250YWlucyhJbnRlcmFjdGFibGUuZXZlbnRUeXBlcywgdHlwZSkpIHtcclxuICAgIC8vIGlmIHRoaXMgdHlwZSBvZiBldmVudCB3YXMgbmV2ZXIgYm91bmRcclxuICAgIGlmICghZ2xvYmFsRXZlbnRzW3R5cGVdKSB7XHJcbiAgICAgIGdsb2JhbEV2ZW50c1t0eXBlXSA9IFtsaXN0ZW5lcl07XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBnbG9iYWxFdmVudHNbdHlwZV0ucHVzaChsaXN0ZW5lcik7XHJcbiAgICB9XHJcbiAgfVxyXG4gIC8vIElmIG5vbiBJbnRlcmFjdEV2ZW50IHR5cGUsIGFkZEV2ZW50TGlzdGVuZXIgdG8gZG9jdW1lbnRcclxuICBlbHNlIHtcclxuICAgICAgZXZlbnRzLmFkZChzY29wZS5kb2N1bWVudCwgdHlwZSwgbGlzdGVuZXIsIHsgb3B0aW9uczogb3B0aW9ucyB9KTtcclxuICAgIH1cclxuXHJcbiAgcmV0dXJuIGludGVyYWN0O1xyXG59O1xyXG5cclxuLypcXFxyXG4gKiBpbnRlcmFjdC5vZmZcclxuIFsgbWV0aG9kIF1cclxuICpcclxuICogUmVtb3ZlcyBhIGdsb2JhbCBJbnRlcmFjdEV2ZW50IGxpc3RlbmVyIG9yIERPTSBldmVudCBmcm9tIGBkb2N1bWVudGBcclxuICpcclxuIC0gdHlwZSAgICAgICAoc3RyaW5nIHwgYXJyYXkgfCBvYmplY3QpIFRoZSB0eXBlcyBvZiBldmVudHMgdGhhdCB3ZXJlIGxpc3RlbmVkIGZvclxyXG4gLSBsaXN0ZW5lciAgIChmdW5jdGlvbikgVGhlIGxpc3RlbmVyIGZ1bmN0aW9uIHRvIGJlIHJlbW92ZWRcclxuIC0gb3B0aW9ucyAgICAob2JqZWN0IHwgYm9vbGVhbikgI29wdGlvbmFsIG9wdGlvbnMgb2JqZWN0IG9yIHVzZUNhcHR1cmUgZmxhZyBmb3IgcmVtb3ZlRXZlbnRMaXN0ZW5lclxyXG4gPSAob2JqZWN0KSBpbnRlcmFjdFxyXG4gXFwqL1xyXG5pbnRlcmFjdC5vZmYgPSBmdW5jdGlvbiAodHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpIHtcclxuICBpZiAodXRpbHMuaXMuc3RyaW5nKHR5cGUpICYmIHR5cGUuc2VhcmNoKCcgJykgIT09IC0xKSB7XHJcbiAgICB0eXBlID0gdHlwZS50cmltKCkuc3BsaXQoLyArLyk7XHJcbiAgfVxyXG5cclxuICBpZiAodXRpbHMuaXMuYXJyYXkodHlwZSkpIHtcclxuICAgIGZvciAodmFyIF9pdGVyYXRvcjIgPSB0eXBlLCBfaXNBcnJheTIgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvcjIpLCBfaTIgPSAwLCBfaXRlcmF0b3IyID0gX2lzQXJyYXkyID8gX2l0ZXJhdG9yMiA6IF9pdGVyYXRvcjJbU3ltYm9sLml0ZXJhdG9yXSgpOzspIHtcclxuICAgICAgdmFyIF9yZWYyO1xyXG5cclxuICAgICAgaWYgKF9pc0FycmF5Mikge1xyXG4gICAgICAgIGlmIChfaTIgPj0gX2l0ZXJhdG9yMi5sZW5ndGgpIGJyZWFrO1xyXG4gICAgICAgIF9yZWYyID0gX2l0ZXJhdG9yMltfaTIrK107XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgX2kyID0gX2l0ZXJhdG9yMi5uZXh0KCk7XHJcbiAgICAgICAgaWYgKF9pMi5kb25lKSBicmVhaztcclxuICAgICAgICBfcmVmMiA9IF9pMi52YWx1ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIGV2ZW50VHlwZSA9IF9yZWYyO1xyXG5cclxuICAgICAgaW50ZXJhY3Qub2ZmKGV2ZW50VHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBpbnRlcmFjdDtcclxuICB9XHJcblxyXG4gIGlmICh1dGlscy5pcy5vYmplY3QodHlwZSkpIHtcclxuICAgIGZvciAodmFyIHByb3AgaW4gdHlwZSkge1xyXG4gICAgICBpbnRlcmFjdC5vZmYocHJvcCwgdHlwZVtwcm9wXSwgbGlzdGVuZXIpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBpbnRlcmFjdDtcclxuICB9XHJcblxyXG4gIGlmICghdXRpbHMuY29udGFpbnMoSW50ZXJhY3RhYmxlLmV2ZW50VHlwZXMsIHR5cGUpKSB7XHJcbiAgICBldmVudHMucmVtb3ZlKHNjb3BlLmRvY3VtZW50LCB0eXBlLCBsaXN0ZW5lciwgb3B0aW9ucyk7XHJcbiAgfSBlbHNlIHtcclxuICAgIHZhciBpbmRleCA9IHZvaWQgMDtcclxuXHJcbiAgICBpZiAodHlwZSBpbiBnbG9iYWxFdmVudHMgJiYgKGluZGV4ID0gdXRpbHMuaW5kZXhPZihnbG9iYWxFdmVudHNbdHlwZV0sIGxpc3RlbmVyKSkgIT09IC0xKSB7XHJcbiAgICAgIGdsb2JhbEV2ZW50c1t0eXBlXS5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcmV0dXJuIGludGVyYWN0O1xyXG59O1xyXG5cclxuLypcXFxyXG4gKiBpbnRlcmFjdC5kZWJ1Z1xyXG4gWyBtZXRob2QgXVxyXG4gKlxyXG4gKiBSZXR1cm5zIGFuIG9iamVjdCB3aGljaCBleHBvc2VzIGludGVybmFsIGRhdGFcclxuID0gKG9iamVjdCkgQW4gb2JqZWN0IHdpdGggcHJvcGVydGllcyB0aGF0IG91dGxpbmUgdGhlIGN1cnJlbnQgc3RhdGUgYW5kIGV4cG9zZSBpbnRlcm5hbCBmdW5jdGlvbnMgYW5kIHZhcmlhYmxlc1xyXG5cXCovXHJcbmludGVyYWN0LmRlYnVnID0gZnVuY3Rpb24gKCkge1xyXG4gIHJldHVybiBzY29wZTtcclxufTtcclxuXHJcbi8vIGV4cG9zZSB0aGUgZnVuY3Rpb25zIHVzZWQgdG8gY2FsY3VsYXRlIG11bHRpLXRvdWNoIHByb3BlcnRpZXNcclxuaW50ZXJhY3QuZ2V0UG9pbnRlckF2ZXJhZ2UgPSB1dGlscy5wb2ludGVyQXZlcmFnZTtcclxuaW50ZXJhY3QuZ2V0VG91Y2hCQm94ID0gdXRpbHMudG91Y2hCQm94O1xyXG5pbnRlcmFjdC5nZXRUb3VjaERpc3RhbmNlID0gdXRpbHMudG91Y2hEaXN0YW5jZTtcclxuaW50ZXJhY3QuZ2V0VG91Y2hBbmdsZSA9IHV0aWxzLnRvdWNoQW5nbGU7XHJcblxyXG5pbnRlcmFjdC5nZXRFbGVtZW50UmVjdCA9IHV0aWxzLmdldEVsZW1lbnRSZWN0O1xyXG5pbnRlcmFjdC5nZXRFbGVtZW50Q2xpZW50UmVjdCA9IHV0aWxzLmdldEVsZW1lbnRDbGllbnRSZWN0O1xyXG5pbnRlcmFjdC5tYXRjaGVzU2VsZWN0b3IgPSB1dGlscy5tYXRjaGVzU2VsZWN0b3I7XHJcbmludGVyYWN0LmNsb3Nlc3QgPSB1dGlscy5jbG9zZXN0O1xyXG5cclxuLypcXFxyXG4gKiBpbnRlcmFjdC5zdXBwb3J0c1RvdWNoXHJcbiBbIG1ldGhvZCBdXHJcbiAqXHJcbiA9IChib29sZWFuKSBXaGV0aGVyIG9yIG5vdCB0aGUgYnJvd3NlciBzdXBwb3J0cyB0b3VjaCBpbnB1dFxyXG5cXCovXHJcbmludGVyYWN0LnN1cHBvcnRzVG91Y2ggPSBmdW5jdGlvbiAoKSB7XHJcbiAgcmV0dXJuIGJyb3dzZXIuc3VwcG9ydHNUb3VjaDtcclxufTtcclxuXHJcbi8qXFxcclxuICogaW50ZXJhY3Quc3VwcG9ydHNQb2ludGVyRXZlbnRcclxuIFsgbWV0aG9kIF1cclxuICpcclxuID0gKGJvb2xlYW4pIFdoZXRoZXIgb3Igbm90IHRoZSBicm93c2VyIHN1cHBvcnRzIFBvaW50ZXJFdmVudHNcclxuXFwqL1xyXG5pbnRlcmFjdC5zdXBwb3J0c1BvaW50ZXJFdmVudCA9IGZ1bmN0aW9uICgpIHtcclxuICByZXR1cm4gYnJvd3Nlci5zdXBwb3J0c1BvaW50ZXJFdmVudDtcclxufTtcclxuXHJcbi8qXFxcclxuICogaW50ZXJhY3Quc3RvcFxyXG4gWyBtZXRob2QgXVxyXG4gKlxyXG4gKiBDYW5jZWxzIGFsbCBpbnRlcmFjdGlvbnMgKGVuZCBldmVudHMgYXJlIG5vdCBmaXJlZClcclxuICpcclxuIC0gZXZlbnQgKEV2ZW50KSBBbiBldmVudCBvbiB3aGljaCB0byBjYWxsIHByZXZlbnREZWZhdWx0KClcclxuID0gKG9iamVjdCkgaW50ZXJhY3RcclxuXFwqL1xyXG5pbnRlcmFjdC5zdG9wID0gZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgZm9yICh2YXIgaSA9IHNjb3BlLmludGVyYWN0aW9ucy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xyXG4gICAgc2NvcGUuaW50ZXJhY3Rpb25zW2ldLnN0b3AoZXZlbnQpO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIGludGVyYWN0O1xyXG59O1xyXG5cclxuLypcXFxyXG4gKiBpbnRlcmFjdC5wb2ludGVyTW92ZVRvbGVyYW5jZVxyXG4gWyBtZXRob2QgXVxyXG4gKiBSZXR1cm5zIG9yIHNldHMgdGhlIGRpc3RhbmNlIHRoZSBwb2ludGVyIG11c3QgYmUgbW92ZWQgYmVmb3JlIGFuIGFjdGlvblxyXG4gKiBzZXF1ZW5jZSBvY2N1cnMuIFRoaXMgYWxzbyBhZmZlY3RzIHRvbGVyYW5jZSBmb3IgdGFwIGV2ZW50cy5cclxuICpcclxuIC0gbmV3VmFsdWUgKG51bWJlcikgI29wdGlvbmFsIFRoZSBtb3ZlbWVudCBmcm9tIHRoZSBzdGFydCBwb3NpdGlvbiBtdXN0IGJlIGdyZWF0ZXIgdGhhbiB0aGlzIHZhbHVlXHJcbiA9IChudW1iZXIgfCBJbnRlcmFjdGFibGUpIFRoZSBjdXJyZW50IHNldHRpbmcgb3IgaW50ZXJhY3RcclxuXFwqL1xyXG5pbnRlcmFjdC5wb2ludGVyTW92ZVRvbGVyYW5jZSA9IGZ1bmN0aW9uIChuZXdWYWx1ZSkge1xyXG4gIGlmICh1dGlscy5pcy5udW1iZXIobmV3VmFsdWUpKSB7XHJcbiAgICBJbnRlcmFjdGlvbi5wb2ludGVyTW92ZVRvbGVyYW5jZSA9IG5ld1ZhbHVlO1xyXG5cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIEludGVyYWN0aW9uLnBvaW50ZXJNb3ZlVG9sZXJhbmNlO1xyXG59O1xyXG5cclxuaW50ZXJhY3QuYWRkRG9jdW1lbnQgPSBzY29wZS5hZGREb2N1bWVudDtcclxuaW50ZXJhY3QucmVtb3ZlRG9jdW1lbnQgPSBzY29wZS5yZW1vdmVEb2N1bWVudDtcclxuXHJcbnNjb3BlLmludGVyYWN0ID0gaW50ZXJhY3Q7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGludGVyYWN0O1xyXG5cclxufSx7XCIuL0ludGVyYWN0YWJsZVwiOjQsXCIuL0ludGVyYWN0aW9uXCI6NSxcIi4vc2NvcGVcIjozNCxcIi4vdXRpbHNcIjo0NCxcIi4vdXRpbHMvYnJvd3NlclwiOjM3LFwiLi91dGlscy9ldmVudHNcIjo0MH1dLDIyOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIEludGVyYWN0YWJsZSA9IHJlcXVpcmUoJy4vSW50ZXJhY3RhYmxlJyk7XHJcbnZhciBJbnRlcmFjdGlvbiA9IHJlcXVpcmUoJy4vSW50ZXJhY3Rpb24nKTtcclxudmFyIHNjb3BlID0gcmVxdWlyZSgnLi9zY29wZScpO1xyXG52YXIgaXMgPSByZXF1aXJlKCcuL3V0aWxzL2lzJyk7XHJcbnZhciBldmVudHMgPSByZXF1aXJlKCcuL3V0aWxzL2V2ZW50cycpO1xyXG5cclxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnLi91dGlscy9kb21VdGlscycpLFxyXG4gICAgbm9kZUNvbnRhaW5zID0gX3JlcXVpcmUubm9kZUNvbnRhaW5zLFxyXG4gICAgbWF0Y2hlc1NlbGVjdG9yID0gX3JlcXVpcmUubWF0Y2hlc1NlbGVjdG9yO1xyXG5cclxuLypcXFxyXG4gKiBJbnRlcmFjdGFibGUucHJldmVudERlZmF1bHRcclxuIFsgbWV0aG9kIF1cclxuICpcclxuICogUmV0dXJucyBvciBzZXRzIHdoZXRoZXIgdG8gcHJldmVudCB0aGUgYnJvd3NlcidzIGRlZmF1bHQgYmVoYXZpb3VyXHJcbiAqIGluIHJlc3BvbnNlIHRvIHBvaW50ZXIgZXZlbnRzLiBDYW4gYmUgc2V0IHRvOlxyXG4gKiAgLSBgJ2Fsd2F5cydgIHRvIGFsd2F5cyBwcmV2ZW50XHJcbiAqICAtIGAnbmV2ZXInYCB0byBuZXZlciBwcmV2ZW50XHJcbiAqICAtIGAnYXV0bydgIHRvIGxldCBpbnRlcmFjdC5qcyB0cnkgdG8gZGV0ZXJtaW5lIHdoYXQgd291bGQgYmUgYmVzdFxyXG4gKlxyXG4gLSBuZXdWYWx1ZSAoc3RyaW5nKSAjb3B0aW9uYWwgYHRydWVgLCBgZmFsc2VgIG9yIGAnYXV0bydgXHJcbiA9IChzdHJpbmcgfCBJbnRlcmFjdGFibGUpIFRoZSBjdXJyZW50IHNldHRpbmcgb3IgdGhpcyBJbnRlcmFjdGFibGVcclxuXFwqL1xyXG5cclxuXHJcbkludGVyYWN0YWJsZS5wcm90b3R5cGUucHJldmVudERlZmF1bHQgPSBmdW5jdGlvbiAobmV3VmFsdWUpIHtcclxuICBpZiAoL14oYWx3YXlzfG5ldmVyfGF1dG8pJC8udGVzdChuZXdWYWx1ZSkpIHtcclxuICAgIHRoaXMub3B0aW9ucy5wcmV2ZW50RGVmYXVsdCA9IG5ld1ZhbHVlO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICBpZiAoaXMuYm9vbChuZXdWYWx1ZSkpIHtcclxuICAgIHRoaXMub3B0aW9ucy5wcmV2ZW50RGVmYXVsdCA9IG5ld1ZhbHVlID8gJ2Fsd2F5cycgOiAnbmV2ZXInO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gdGhpcy5vcHRpb25zLnByZXZlbnREZWZhdWx0O1xyXG59O1xyXG5cclxuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5jaGVja0FuZFByZXZlbnREZWZhdWx0ID0gZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgdmFyIHNldHRpbmcgPSB0aGlzLm9wdGlvbnMucHJldmVudERlZmF1bHQ7XHJcblxyXG4gIGlmIChzZXR0aW5nID09PSAnbmV2ZXInKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICBpZiAoc2V0dGluZyA9PT0gJ2Fsd2F5cycpIHtcclxuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICAvLyBzZXR0aW5nID09PSAnYXV0bydcclxuXHJcbiAgLy8gZG9uJ3QgcHJldmVudERlZmF1bHQgaWYgdGhlIGJyb3dzZXIgc3VwcG9ydHMgcGFzc2l2ZUV2ZW50c1xyXG4gIC8vIENTUyB0b3VjaC1hY3Rpb24gYW5kIHVzZXItc2VsZWNjdCBzaG91bGQgYmUgdXNlZCBpbnN0ZWFkXHJcbiAgaWYgKGV2ZW50cy5zdXBwb3J0c09wdGlvbnMpIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIC8vIGRvbid0IHByZXZlbnREZWZhdWx0IG9mIHBvaW50ZXJkb3duIGV2ZW50c1xyXG4gIGlmICgvXihtb3VzZXxwb2ludGVyfHRvdWNoKSooZG93bnxzdGFydCkvaS50ZXN0KGV2ZW50LnR5cGUpKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICAvLyBkb24ndCBwcmV2ZW50RGVmYXVsdCBvbiBlZGl0YWJsZSBlbGVtZW50c1xyXG4gIGlmIChpcy5lbGVtZW50KGV2ZW50LnRhcmdldCkgJiYgbWF0Y2hlc1NlbGVjdG9yKGV2ZW50LnRhcmdldCwgJ2lucHV0LHNlbGVjdCx0ZXh0YXJlYSxbY29udGVudGVkaXRhYmxlPXRydWVdLFtjb250ZW50ZWRpdGFibGU9dHJ1ZV0gKicpKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG59O1xyXG5cclxuZnVuY3Rpb24gb25JbnRlcmFjdGlvbkV2ZW50KF9yZWYpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmLmludGVyYWN0aW9uLFxyXG4gICAgICBldmVudCA9IF9yZWYuZXZlbnQ7XHJcblxyXG4gIGlmIChpbnRlcmFjdGlvbi50YXJnZXQpIHtcclxuICAgIGludGVyYWN0aW9uLnRhcmdldC5jaGVja0FuZFByZXZlbnREZWZhdWx0KGV2ZW50KTtcclxuICB9XHJcbn1cclxuXHJcbnZhciBfYXJyID0gWydkb3duJywgJ21vdmUnLCAndXAnLCAnY2FuY2VsJ107XHJcbmZvciAodmFyIF9pID0gMDsgX2kgPCBfYXJyLmxlbmd0aDsgX2krKykge1xyXG4gIHZhciBldmVudFNpZ25hbCA9IF9hcnJbX2ldO1xyXG4gIEludGVyYWN0aW9uLnNpZ25hbHMub24oZXZlbnRTaWduYWwsIG9uSW50ZXJhY3Rpb25FdmVudCk7XHJcbn1cclxuXHJcbi8vIHByZXZlbnQgbmF0aXZlIEhUTUw1IGRyYWcgb24gaW50ZXJhY3QuanMgdGFyZ2V0IGVsZW1lbnRzXHJcbkludGVyYWN0aW9uLmRvY0V2ZW50cy5kcmFnc3RhcnQgPSBmdW5jdGlvbiBwcmV2ZW50TmF0aXZlRHJhZyhldmVudCkge1xyXG4gIGZvciAodmFyIF9pdGVyYXRvciA9IHNjb3BlLmludGVyYWN0aW9ucywgX2lzQXJyYXkgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvciksIF9pMiA9IDAsIF9pdGVyYXRvciA9IF9pc0FycmF5ID8gX2l0ZXJhdG9yIDogX2l0ZXJhdG9yW1N5bWJvbC5pdGVyYXRvcl0oKTs7KSB7XHJcbiAgICB2YXIgX3JlZjI7XHJcblxyXG4gICAgaWYgKF9pc0FycmF5KSB7XHJcbiAgICAgIGlmIChfaTIgPj0gX2l0ZXJhdG9yLmxlbmd0aCkgYnJlYWs7XHJcbiAgICAgIF9yZWYyID0gX2l0ZXJhdG9yW19pMisrXTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIF9pMiA9IF9pdGVyYXRvci5uZXh0KCk7XHJcbiAgICAgIGlmIChfaTIuZG9uZSkgYnJlYWs7XHJcbiAgICAgIF9yZWYyID0gX2kyLnZhbHVlO1xyXG4gICAgfVxyXG5cclxuICAgIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYyO1xyXG5cclxuXHJcbiAgICBpZiAoaW50ZXJhY3Rpb24uZWxlbWVudCAmJiAoaW50ZXJhY3Rpb24uZWxlbWVudCA9PT0gZXZlbnQudGFyZ2V0IHx8IG5vZGVDb250YWlucyhpbnRlcmFjdGlvbi5lbGVtZW50LCBldmVudC50YXJnZXQpKSkge1xyXG5cclxuICAgICAgaW50ZXJhY3Rpb24udGFyZ2V0LmNoZWNrQW5kUHJldmVudERlZmF1bHQoZXZlbnQpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgfVxyXG59O1xyXG5cclxufSx7XCIuL0ludGVyYWN0YWJsZVwiOjQsXCIuL0ludGVyYWN0aW9uXCI6NSxcIi4vc2NvcGVcIjozNCxcIi4vdXRpbHMvZG9tVXRpbHNcIjozOSxcIi4vdXRpbHMvZXZlbnRzXCI6NDAsXCIuL3V0aWxzL2lzXCI6NDZ9XSwyMzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBzY29wZSA9IHJlcXVpcmUoJy4vc2NvcGUnKTtcclxudmFyIGV2ZW50cyA9IHJlcXVpcmUoJy4vdXRpbHMvZXZlbnRzJyk7XHJcbnZhciBicm93c2VyID0gcmVxdWlyZSgnLi91dGlscy9icm93c2VyJyk7XHJcbnZhciBpRmluZGVyID0gcmVxdWlyZSgnLi91dGlscy9pbnRlcmFjdGlvbkZpbmRlcicpO1xyXG52YXIgcG9pbnRlckV2ZW50cyA9IHJlcXVpcmUoJy4vcG9pbnRlckV2ZW50cy9iYXNlJyk7XHJcblxyXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCcuL3V0aWxzL3dpbmRvdycpLFxyXG4gICAgd2luZG93ID0gX3JlcXVpcmUud2luZG93O1xyXG5cclxudmFyIHRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcclxuXHJcbmlmICghd2luZG93LkFycmF5LmlzQXJyYXkpIHtcclxuICB3aW5kb3cuQXJyYXkuaXNBcnJheSA9IGZ1bmN0aW9uIChvYmopIHtcclxuICAgIHJldHVybiB0b1N0cmluZy5jYWxsKG9iaikgPT09ICdbb2JqZWN0IEFycmF5XSc7XHJcbiAgfTtcclxufVxyXG5cclxuaWYgKCFTdHJpbmcucHJvdG90eXBlLnRyaW0pIHtcclxuICBTdHJpbmcucHJvdG90eXBlLnRyaW0gPSBmdW5jdGlvbiAoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5yZXBsYWNlKC9eW1xcc1xcdUZFRkZcXHhBMF0rfFtcXHNcXHVGRUZGXFx4QTBdKyQvZywgJycpO1xyXG4gIH07XHJcbn1cclxuXHJcbi8vIGh0dHA6Ly93d3cucXVpcmtzbW9kZS5vcmcvZG9tL2V2ZW50cy9jbGljay5odG1sXHJcbi8vID5FdmVudHMgbGVhZGluZyB0byBkYmxjbGlja1xyXG4vL1xyXG4vLyBJRTggZG9lc24ndCBmaXJlIGRvd24gZXZlbnQgYmVmb3JlIGRibGNsaWNrLlxyXG4vLyBUaGlzIHdvcmthcm91bmQgdHJpZXMgdG8gZmlyZSBhIHRhcCBhbmQgZG91YmxldGFwIGFmdGVyIGRibGNsaWNrXHJcbmZ1bmN0aW9uIG9uSUU4RGJsY2xpY2soZXZlbnQpIHtcclxuICB2YXIgZXZlbnRUYXJnZXQgPSBldmVudC50YXJnZXQ7XHJcbiAgdmFyIGludGVyYWN0aW9uID0gaUZpbmRlci5zZWFyY2goZXZlbnQsIGV2ZW50LnR5cGUsIGV2ZW50VGFyZ2V0KTtcclxuXHJcbiAgaWYgKCFpbnRlcmFjdGlvbikge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgaWYgKGludGVyYWN0aW9uLnByZXZUYXAgJiYgZXZlbnQuY2xpZW50WCA9PT0gaW50ZXJhY3Rpb24ucHJldlRhcC5jbGllbnRYICYmIGV2ZW50LmNsaWVudFkgPT09IGludGVyYWN0aW9uLnByZXZUYXAuY2xpZW50WSAmJiBldmVudFRhcmdldCA9PT0gaW50ZXJhY3Rpb24ucHJldlRhcC50YXJnZXQpIHtcclxuXHJcbiAgICBpbnRlcmFjdGlvbi5kb3duVGFyZ2V0c1swXSA9IGV2ZW50VGFyZ2V0O1xyXG4gICAgaW50ZXJhY3Rpb24uZG93blRpbWVzWzBdID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XHJcblxyXG4gICAgcG9pbnRlckV2ZW50cy5maXJlKHtcclxuICAgICAgaW50ZXJhY3Rpb246IGludGVyYWN0aW9uLFxyXG4gICAgICBldmVudDogZXZlbnQsXHJcbiAgICAgIGV2ZW50VGFyZ2V0OiBldmVudFRhcmdldCxcclxuICAgICAgcG9pbnRlcjogZXZlbnQsXHJcbiAgICAgIHR5cGU6ICd0YXAnXHJcbiAgICB9KTtcclxuICB9XHJcbn1cclxuXHJcbmlmIChicm93c2VyLmlzSUU4KSB7XHJcbiAgdmFyIHNlbGVjdEZpeCA9IGZ1bmN0aW9uIHNlbGVjdEZpeChldmVudCkge1xyXG4gICAgZm9yICh2YXIgX2l0ZXJhdG9yID0gc2NvcGUuaW50ZXJhY3Rpb25zLCBfaXNBcnJheSA9IEFycmF5LmlzQXJyYXkoX2l0ZXJhdG9yKSwgX2kgPSAwLCBfaXRlcmF0b3IgPSBfaXNBcnJheSA/IF9pdGVyYXRvciA6IF9pdGVyYXRvcltTeW1ib2wuaXRlcmF0b3JdKCk7Oykge1xyXG4gICAgICB2YXIgX3JlZjtcclxuXHJcbiAgICAgIGlmIChfaXNBcnJheSkge1xyXG4gICAgICAgIGlmIChfaSA+PSBfaXRlcmF0b3IubGVuZ3RoKSBicmVhaztcclxuICAgICAgICBfcmVmID0gX2l0ZXJhdG9yW19pKytdO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIF9pID0gX2l0ZXJhdG9yLm5leHQoKTtcclxuICAgICAgICBpZiAoX2kuZG9uZSkgYnJlYWs7XHJcbiAgICAgICAgX3JlZiA9IF9pLnZhbHVlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmO1xyXG5cclxuICAgICAgaWYgKGludGVyYWN0aW9uLmludGVyYWN0aW5nKCkpIHtcclxuICAgICAgICBpbnRlcmFjdGlvbi50YXJnZXQuY2hlY2tBbmRQcmV2ZW50RGVmYXVsdChldmVudCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9O1xyXG5cclxuICB2YXIgb25Eb2NJRTggPSBmdW5jdGlvbiBvbkRvY0lFOChfcmVmMiwgc2lnbmFsTmFtZSkge1xyXG4gICAgdmFyIGRvYyA9IF9yZWYyLmRvYyxcclxuICAgICAgICB3aW4gPSBfcmVmMi53aW47XHJcblxyXG4gICAgdmFyIGV2ZW50TWV0aG9kID0gc2lnbmFsTmFtZS5pbmRleE9mKCdsaXN0ZW4nKSA9PT0gMCA/IGV2ZW50cy5hZGQgOiBldmVudHMucmVtb3ZlO1xyXG5cclxuICAgIC8vIEZvciBJRSdzIGxhY2sgb2YgRXZlbnQjcHJldmVudERlZmF1bHRcclxuICAgIGV2ZW50TWV0aG9kKGRvYywgJ3NlbGVjdHN0YXJ0Jywgc2VsZWN0Rml4KTtcclxuXHJcbiAgICBpZiAocG9pbnRlckV2ZW50cykge1xyXG4gICAgICBldmVudE1ldGhvZChkb2MsICdkYmxjbGljaycsIG9uSUU4RGJsY2xpY2spO1xyXG4gICAgfVxyXG4gIH07XHJcblxyXG4gIHNjb3BlLnNpZ25hbHMub24oJ2FkZC1kb2N1bWVudCcsIG9uRG9jSUU4KTtcclxuICBzY29wZS5zaWduYWxzLm9uKCdyZW1vdmUtZG9jdW1lbnQnLCBvbkRvY0lFOCk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gbnVsbDtcclxuXHJcbn0se1wiLi9wb2ludGVyRXZlbnRzL2Jhc2VcIjozMSxcIi4vc2NvcGVcIjozNCxcIi4vdXRpbHMvYnJvd3NlclwiOjM3LFwiLi91dGlscy9ldmVudHNcIjo0MCxcIi4vdXRpbHMvaW50ZXJhY3Rpb25GaW5kZXJcIjo0NSxcIi4vdXRpbHMvd2luZG93XCI6NTJ9XSwyNDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBJbnRlcmFjdEV2ZW50ID0gcmVxdWlyZSgnLi4vSW50ZXJhY3RFdmVudCcpO1xyXG52YXIgSW50ZXJhY3Rpb24gPSByZXF1aXJlKCcuLi9JbnRlcmFjdGlvbicpO1xyXG52YXIgZXh0ZW5kID0gcmVxdWlyZSgnLi4vdXRpbHMvZXh0ZW5kJyk7XHJcblxyXG52YXIgbW9kaWZpZXJzID0ge1xyXG4gIG5hbWVzOiBbXSxcclxuXHJcbiAgc2V0T2Zmc2V0czogZnVuY3Rpb24gc2V0T2Zmc2V0cyhhcmcpIHtcclxuICAgIHZhciBpbnRlcmFjdGlvbiA9IGFyZy5pbnRlcmFjdGlvbixcclxuICAgICAgICBwYWdlID0gYXJnLnBhZ2VDb29yZHM7XHJcbiAgICB2YXIgdGFyZ2V0ID0gaW50ZXJhY3Rpb24udGFyZ2V0LFxyXG4gICAgICAgIGVsZW1lbnQgPSBpbnRlcmFjdGlvbi5lbGVtZW50LFxyXG4gICAgICAgIHN0YXJ0T2Zmc2V0ID0gaW50ZXJhY3Rpb24uc3RhcnRPZmZzZXQ7XHJcblxyXG4gICAgdmFyIHJlY3QgPSB0YXJnZXQuZ2V0UmVjdChlbGVtZW50KTtcclxuXHJcbiAgICBpZiAocmVjdCkge1xyXG4gICAgICBzdGFydE9mZnNldC5sZWZ0ID0gcGFnZS54IC0gcmVjdC5sZWZ0O1xyXG4gICAgICBzdGFydE9mZnNldC50b3AgPSBwYWdlLnkgLSByZWN0LnRvcDtcclxuXHJcbiAgICAgIHN0YXJ0T2Zmc2V0LnJpZ2h0ID0gcmVjdC5yaWdodCAtIHBhZ2UueDtcclxuICAgICAgc3RhcnRPZmZzZXQuYm90dG9tID0gcmVjdC5ib3R0b20gLSBwYWdlLnk7XHJcblxyXG4gICAgICBpZiAoISgnd2lkdGgnIGluIHJlY3QpKSB7XHJcbiAgICAgICAgcmVjdC53aWR0aCA9IHJlY3QucmlnaHQgLSByZWN0LmxlZnQ7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKCEoJ2hlaWdodCcgaW4gcmVjdCkpIHtcclxuICAgICAgICByZWN0LmhlaWdodCA9IHJlY3QuYm90dG9tIC0gcmVjdC50b3A7XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHN0YXJ0T2Zmc2V0LmxlZnQgPSBzdGFydE9mZnNldC50b3AgPSBzdGFydE9mZnNldC5yaWdodCA9IHN0YXJ0T2Zmc2V0LmJvdHRvbSA9IDA7XHJcbiAgICB9XHJcblxyXG4gICAgYXJnLnJlY3QgPSByZWN0O1xyXG4gICAgYXJnLmludGVyYWN0YWJsZSA9IHRhcmdldDtcclxuICAgIGFyZy5lbGVtZW50ID0gZWxlbWVudDtcclxuXHJcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1vZGlmaWVycy5uYW1lcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICB2YXIgbW9kaWZpZXJOYW1lID0gbW9kaWZpZXJzLm5hbWVzW2ldO1xyXG5cclxuICAgICAgYXJnLm9wdGlvbnMgPSB0YXJnZXQub3B0aW9uc1tpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lXVttb2RpZmllck5hbWVdO1xyXG5cclxuICAgICAgaWYgKCFhcmcub3B0aW9ucykge1xyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpbnRlcmFjdGlvbi5tb2RpZmllck9mZnNldHNbbW9kaWZpZXJOYW1lXSA9IG1vZGlmaWVyc1ttb2RpZmllck5hbWVdLnNldE9mZnNldChhcmcpO1xyXG4gICAgfVxyXG4gIH0sXHJcblxyXG4gIHNldEFsbDogZnVuY3Rpb24gc2V0QWxsKGFyZykge1xyXG4gICAgdmFyIGludGVyYWN0aW9uID0gYXJnLmludGVyYWN0aW9uLFxyXG4gICAgICAgIHN0YXR1c2VzID0gYXJnLnN0YXR1c2VzLFxyXG4gICAgICAgIHByZUVuZCA9IGFyZy5wcmVFbmQsXHJcbiAgICAgICAgcmVxdWlyZUVuZE9ubHkgPSBhcmcucmVxdWlyZUVuZE9ubHk7XHJcblxyXG4gICAgdmFyIGNvb3JkcyA9IGV4dGVuZCh7fSwgYXJnLnBhZ2VDb29yZHMpO1xyXG4gICAgdmFyIHJlc3VsdCA9IHtcclxuICAgICAgZHg6IDAsXHJcbiAgICAgIGR5OiAwLFxyXG4gICAgICBjaGFuZ2VkOiBmYWxzZSxcclxuICAgICAgbG9ja2VkOiBmYWxzZSxcclxuICAgICAgc2hvdWxkTW92ZTogdHJ1ZVxyXG4gICAgfTtcclxuXHJcbiAgICBmb3IgKHZhciBfaXRlcmF0b3IgPSBtb2RpZmllcnMubmFtZXMsIF9pc0FycmF5ID0gQXJyYXkuaXNBcnJheShfaXRlcmF0b3IpLCBfaSA9IDAsIF9pdGVyYXRvciA9IF9pc0FycmF5ID8gX2l0ZXJhdG9yIDogX2l0ZXJhdG9yW1N5bWJvbC5pdGVyYXRvcl0oKTs7KSB7XHJcbiAgICAgIHZhciBfcmVmO1xyXG5cclxuICAgICAgaWYgKF9pc0FycmF5KSB7XHJcbiAgICAgICAgaWYgKF9pID49IF9pdGVyYXRvci5sZW5ndGgpIGJyZWFrO1xyXG4gICAgICAgIF9yZWYgPSBfaXRlcmF0b3JbX2krK107XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgX2kgPSBfaXRlcmF0b3IubmV4dCgpO1xyXG4gICAgICAgIGlmIChfaS5kb25lKSBicmVhaztcclxuICAgICAgICBfcmVmID0gX2kudmFsdWU7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHZhciBtb2RpZmllck5hbWUgPSBfcmVmO1xyXG5cclxuICAgICAgdmFyIG1vZGlmaWVyID0gbW9kaWZpZXJzW21vZGlmaWVyTmFtZV07XHJcbiAgICAgIHZhciBvcHRpb25zID0gaW50ZXJhY3Rpb24udGFyZ2V0Lm9wdGlvbnNbaW50ZXJhY3Rpb24ucHJlcGFyZWQubmFtZV1bbW9kaWZpZXJOYW1lXTtcclxuXHJcbiAgICAgIGlmICghc2hvdWxkRG8ob3B0aW9ucywgcHJlRW5kLCByZXF1aXJlRW5kT25seSkpIHtcclxuICAgICAgICBjb250aW51ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgYXJnLnN0YXR1cyA9IGFyZy5zdGF0dXMgPSBzdGF0dXNlc1ttb2RpZmllck5hbWVdO1xyXG4gICAgICBhcmcub3B0aW9ucyA9IG9wdGlvbnM7XHJcbiAgICAgIGFyZy5vZmZzZXQgPSBhcmcuaW50ZXJhY3Rpb24ubW9kaWZpZXJPZmZzZXRzW21vZGlmaWVyTmFtZV07XHJcblxyXG4gICAgICBtb2RpZmllci5zZXQoYXJnKTtcclxuXHJcbiAgICAgIGlmIChhcmcuc3RhdHVzLmxvY2tlZCkge1xyXG4gICAgICAgIGNvb3Jkcy54ICs9IGFyZy5zdGF0dXMuZHg7XHJcbiAgICAgICAgY29vcmRzLnkgKz0gYXJnLnN0YXR1cy5keTtcclxuXHJcbiAgICAgICAgcmVzdWx0LmR4ICs9IGFyZy5zdGF0dXMuZHg7XHJcbiAgICAgICAgcmVzdWx0LmR5ICs9IGFyZy5zdGF0dXMuZHk7XHJcblxyXG4gICAgICAgIHJlc3VsdC5sb2NrZWQgPSB0cnVlO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gYSBtb3ZlIHNob3VsZCBiZSBmaXJlZCBpZjpcclxuICAgIC8vICAtIHRoZXJlIGFyZSBubyBtb2RpZmllcnMgZW5hYmxlZCxcclxuICAgIC8vICAtIG5vIG1vZGlmaWVycyBhcmUgXCJsb2NrZWRcIiBpLmUuIGhhdmUgY2hhbmdlZCB0aGUgcG9pbnRlcidzIGNvb3JkaW5hdGVzLCBvclxyXG4gICAgLy8gIC0gdGhlIGxvY2tlZCBjb29yZHMgaGF2ZSBjaGFuZ2VkIHNpbmNlIHRoZSBsYXN0IHBvaW50ZXIgbW92ZVxyXG4gICAgcmVzdWx0LnNob3VsZE1vdmUgPSAhYXJnLnN0YXR1cyB8fCAhcmVzdWx0LmxvY2tlZCB8fCBhcmcuc3RhdHVzLmNoYW5nZWQ7XHJcblxyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxuICB9LFxyXG5cclxuICByZXNldFN0YXR1c2VzOiBmdW5jdGlvbiByZXNldFN0YXR1c2VzKHN0YXR1c2VzKSB7XHJcbiAgICBmb3IgKHZhciBfaXRlcmF0b3IyID0gbW9kaWZpZXJzLm5hbWVzLCBfaXNBcnJheTIgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvcjIpLCBfaTIgPSAwLCBfaXRlcmF0b3IyID0gX2lzQXJyYXkyID8gX2l0ZXJhdG9yMiA6IF9pdGVyYXRvcjJbU3ltYm9sLml0ZXJhdG9yXSgpOzspIHtcclxuICAgICAgdmFyIF9yZWYyO1xyXG5cclxuICAgICAgaWYgKF9pc0FycmF5Mikge1xyXG4gICAgICAgIGlmIChfaTIgPj0gX2l0ZXJhdG9yMi5sZW5ndGgpIGJyZWFrO1xyXG4gICAgICAgIF9yZWYyID0gX2l0ZXJhdG9yMltfaTIrK107XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgX2kyID0gX2l0ZXJhdG9yMi5uZXh0KCk7XHJcbiAgICAgICAgaWYgKF9pMi5kb25lKSBicmVhaztcclxuICAgICAgICBfcmVmMiA9IF9pMi52YWx1ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIG1vZGlmaWVyTmFtZSA9IF9yZWYyO1xyXG5cclxuICAgICAgdmFyIHN0YXR1cyA9IHN0YXR1c2VzW21vZGlmaWVyTmFtZV0gfHwge307XHJcblxyXG4gICAgICBzdGF0dXMuZHggPSBzdGF0dXMuZHkgPSAwO1xyXG4gICAgICBzdGF0dXMubW9kaWZpZWRYID0gc3RhdHVzLm1vZGlmaWVkWSA9IE5hTjtcclxuICAgICAgc3RhdHVzLmxvY2tlZCA9IGZhbHNlO1xyXG4gICAgICBzdGF0dXMuY2hhbmdlZCA9IHRydWU7XHJcblxyXG4gICAgICBzdGF0dXNlc1ttb2RpZmllck5hbWVdID0gc3RhdHVzO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBzdGF0dXNlcztcclxuICB9LFxyXG5cclxuICBzdGFydDogZnVuY3Rpb24gc3RhcnQoX3JlZjMsIHNpZ25hbE5hbWUpIHtcclxuICAgIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYzLmludGVyYWN0aW9uO1xyXG5cclxuICAgIHZhciBhcmcgPSB7XHJcbiAgICAgIGludGVyYWN0aW9uOiBpbnRlcmFjdGlvbixcclxuICAgICAgcGFnZUNvb3JkczogKHNpZ25hbE5hbWUgPT09ICdhY3Rpb24tcmVzdW1lJyA/IGludGVyYWN0aW9uLmN1ckNvb3JkcyA6IGludGVyYWN0aW9uLnN0YXJ0Q29vcmRzKS5wYWdlLFxyXG4gICAgICBzdGFydE9mZnNldDogaW50ZXJhY3Rpb24uc3RhcnRPZmZzZXQsXHJcbiAgICAgIHN0YXR1c2VzOiBpbnRlcmFjdGlvbi5tb2RpZmllclN0YXR1c2VzLFxyXG4gICAgICBwcmVFbmQ6IGZhbHNlLFxyXG4gICAgICByZXF1aXJlRW5kT25seTogZmFsc2VcclxuICAgIH07XHJcblxyXG4gICAgbW9kaWZpZXJzLnNldE9mZnNldHMoYXJnKTtcclxuICAgIG1vZGlmaWVycy5yZXNldFN0YXR1c2VzKGFyZy5zdGF0dXNlcyk7XHJcblxyXG4gICAgYXJnLnBhZ2VDb29yZHMgPSBleHRlbmQoe30sIGludGVyYWN0aW9uLnN0YXJ0Q29vcmRzLnBhZ2UpO1xyXG4gICAgaW50ZXJhY3Rpb24ubW9kaWZpZXJSZXN1bHQgPSBtb2RpZmllcnMuc2V0QWxsKGFyZyk7XHJcbiAgfVxyXG59O1xyXG5cclxuSW50ZXJhY3Rpb24uc2lnbmFscy5vbignbmV3JywgZnVuY3Rpb24gKGludGVyYWN0aW9uKSB7XHJcbiAgaW50ZXJhY3Rpb24uc3RhcnRPZmZzZXQgPSB7IGxlZnQ6IDAsIHJpZ2h0OiAwLCB0b3A6IDAsIGJvdHRvbTogMCB9O1xyXG4gIGludGVyYWN0aW9uLm1vZGlmaWVyT2Zmc2V0cyA9IHt9O1xyXG4gIGludGVyYWN0aW9uLm1vZGlmaWVyU3RhdHVzZXMgPSBtb2RpZmllcnMucmVzZXRTdGF0dXNlcyh7fSk7XHJcbiAgaW50ZXJhY3Rpb24ubW9kaWZpZXJSZXN1bHQgPSBudWxsO1xyXG59KTtcclxuXHJcbkludGVyYWN0aW9uLnNpZ25hbHMub24oJ2FjdGlvbi1zdGFydCcsIG1vZGlmaWVycy5zdGFydCk7XHJcbkludGVyYWN0aW9uLnNpZ25hbHMub24oJ2FjdGlvbi1yZXN1bWUnLCBtb2RpZmllcnMuc3RhcnQpO1xyXG5cclxuSW50ZXJhY3Rpb24uc2lnbmFscy5vbignYmVmb3JlLWFjdGlvbi1tb3ZlJywgZnVuY3Rpb24gKF9yZWY0KSB7XHJcbiAgdmFyIGludGVyYWN0aW9uID0gX3JlZjQuaW50ZXJhY3Rpb24sXHJcbiAgICAgIHByZUVuZCA9IF9yZWY0LnByZUVuZCxcclxuICAgICAgaW50ZXJhY3RpbmdCZWZvcmVNb3ZlID0gX3JlZjQuaW50ZXJhY3RpbmdCZWZvcmVNb3ZlO1xyXG5cclxuICB2YXIgbW9kaWZpZXJSZXN1bHQgPSBtb2RpZmllcnMuc2V0QWxsKHtcclxuICAgIGludGVyYWN0aW9uOiBpbnRlcmFjdGlvbixcclxuICAgIHByZUVuZDogcHJlRW5kLFxyXG4gICAgcGFnZUNvb3JkczogaW50ZXJhY3Rpb24uY3VyQ29vcmRzLnBhZ2UsXHJcbiAgICBzdGF0dXNlczogaW50ZXJhY3Rpb24ubW9kaWZpZXJTdGF0dXNlcyxcclxuICAgIHJlcXVpcmVFbmRPbmx5OiBmYWxzZVxyXG4gIH0pO1xyXG5cclxuICAvLyBkb24ndCBmaXJlIGFuIGFjdGlvbiBtb3ZlIGlmIGEgbW9kaWZpZXIgd291bGQga2VlcCB0aGUgZXZlbnQgaW4gdGhlIHNhbWVcclxuICAvLyBjb3JkaW5hdGVzIGFzIGJlZm9yZVxyXG4gIGlmICghbW9kaWZpZXJSZXN1bHQuc2hvdWxkTW92ZSAmJiBpbnRlcmFjdGluZ0JlZm9yZU1vdmUpIHtcclxuICAgIGludGVyYWN0aW9uLl9kb250RmlyZU1vdmUgPSB0cnVlO1xyXG4gIH1cclxuXHJcbiAgaW50ZXJhY3Rpb24ubW9kaWZpZXJSZXN1bHQgPSBtb2RpZmllclJlc3VsdDtcclxufSk7XHJcblxyXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdhY3Rpb24tZW5kJywgZnVuY3Rpb24gKF9yZWY1KSB7XHJcbiAgdmFyIGludGVyYWN0aW9uID0gX3JlZjUuaW50ZXJhY3Rpb24sXHJcbiAgICAgIGV2ZW50ID0gX3JlZjUuZXZlbnQ7XHJcblxyXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbW9kaWZpZXJzLm5hbWVzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICB2YXIgb3B0aW9ucyA9IGludGVyYWN0aW9uLnRhcmdldC5vcHRpb25zW2ludGVyYWN0aW9uLnByZXBhcmVkLm5hbWVdW21vZGlmaWVycy5uYW1lc1tpXV07XHJcblxyXG4gICAgLy8gaWYgdGhlIGVuZE9ubHkgb3B0aW9uIGlzIHRydWUgZm9yIGFueSBtb2RpZmllclxyXG4gICAgaWYgKHNob3VsZERvKG9wdGlvbnMsIHRydWUsIHRydWUpKSB7XHJcbiAgICAgIC8vIGZpcmUgYSBtb3ZlIGV2ZW50IGF0IHRoZSBtb2RpZmllZCBjb29yZGluYXRlc1xyXG4gICAgICBpbnRlcmFjdGlvbi5kb01vdmUoeyBldmVudDogZXZlbnQsIHByZUVuZDogdHJ1ZSB9KTtcclxuICAgICAgYnJlYWs7XHJcbiAgICB9XHJcbiAgfVxyXG59KTtcclxuXHJcbkludGVyYWN0RXZlbnQuc2lnbmFscy5vbignc2V0LXh5JywgZnVuY3Rpb24gKGFyZykge1xyXG4gIHZhciBpRXZlbnQgPSBhcmcuaUV2ZW50LFxyXG4gICAgICBpbnRlcmFjdGlvbiA9IGFyZy5pbnRlcmFjdGlvbjtcclxuXHJcbiAgdmFyIG1vZGlmaWVyQXJnID0gZXh0ZW5kKHt9LCBhcmcpO1xyXG5cclxuICBmb3IgKHZhciBpID0gMDsgaSA8IG1vZGlmaWVycy5uYW1lcy5sZW5ndGg7IGkrKykge1xyXG4gICAgdmFyIG1vZGlmaWVyTmFtZSA9IG1vZGlmaWVycy5uYW1lc1tpXTtcclxuICAgIG1vZGlmaWVyQXJnLm9wdGlvbnMgPSBpbnRlcmFjdGlvbi50YXJnZXQub3B0aW9uc1tpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lXVttb2RpZmllck5hbWVdO1xyXG5cclxuICAgIGlmICghbW9kaWZpZXJBcmcub3B0aW9ucykge1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgbW9kaWZpZXIgPSBtb2RpZmllcnNbbW9kaWZpZXJOYW1lXTtcclxuXHJcbiAgICBtb2RpZmllckFyZy5zdGF0dXMgPSBpbnRlcmFjdGlvbi5tb2RpZmllclN0YXR1c2VzW21vZGlmaWVyTmFtZV07XHJcblxyXG4gICAgaUV2ZW50W21vZGlmaWVyTmFtZV0gPSBtb2RpZmllci5tb2RpZnlDb29yZHMobW9kaWZpZXJBcmcpO1xyXG4gIH1cclxufSk7XHJcblxyXG5mdW5jdGlvbiBzaG91bGREbyhvcHRpb25zLCBwcmVFbmQsIHJlcXVpcmVFbmRPbmx5KSB7XHJcbiAgcmV0dXJuIG9wdGlvbnMgJiYgb3B0aW9ucy5lbmFibGVkICYmIChwcmVFbmQgfHwgIW9wdGlvbnMuZW5kT25seSkgJiYgKCFyZXF1aXJlRW5kT25seSB8fCBvcHRpb25zLmVuZE9ubHkpO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IG1vZGlmaWVycztcclxuXHJcbn0se1wiLi4vSW50ZXJhY3RFdmVudFwiOjMsXCIuLi9JbnRlcmFjdGlvblwiOjUsXCIuLi91dGlscy9leHRlbmRcIjo0MX1dLDI1OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIG1vZGlmaWVycyA9IHJlcXVpcmUoJy4vaW5kZXgnKTtcclxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcclxudmFyIGRlZmF1bHRPcHRpb25zID0gcmVxdWlyZSgnLi4vZGVmYXVsdE9wdGlvbnMnKTtcclxuXHJcbnZhciByZXN0cmljdCA9IHtcclxuICBkZWZhdWx0czoge1xyXG4gICAgZW5hYmxlZDogZmFsc2UsXHJcbiAgICBlbmRPbmx5OiBmYWxzZSxcclxuICAgIHJlc3RyaWN0aW9uOiBudWxsLFxyXG4gICAgZWxlbWVudFJlY3Q6IG51bGxcclxuICB9LFxyXG5cclxuICBzZXRPZmZzZXQ6IGZ1bmN0aW9uIHNldE9mZnNldChfcmVmKSB7XHJcbiAgICB2YXIgcmVjdCA9IF9yZWYucmVjdCxcclxuICAgICAgICBzdGFydE9mZnNldCA9IF9yZWYuc3RhcnRPZmZzZXQsXHJcbiAgICAgICAgb3B0aW9ucyA9IF9yZWYub3B0aW9ucztcclxuXHJcbiAgICB2YXIgZWxlbWVudFJlY3QgPSBvcHRpb25zICYmIG9wdGlvbnMuZWxlbWVudFJlY3Q7XHJcbiAgICB2YXIgb2Zmc2V0ID0ge307XHJcblxyXG4gICAgaWYgKHJlY3QgJiYgZWxlbWVudFJlY3QpIHtcclxuICAgICAgb2Zmc2V0LmxlZnQgPSBzdGFydE9mZnNldC5sZWZ0IC0gcmVjdC53aWR0aCAqIGVsZW1lbnRSZWN0LmxlZnQ7XHJcbiAgICAgIG9mZnNldC50b3AgPSBzdGFydE9mZnNldC50b3AgLSByZWN0LmhlaWdodCAqIGVsZW1lbnRSZWN0LnRvcDtcclxuXHJcbiAgICAgIG9mZnNldC5yaWdodCA9IHN0YXJ0T2Zmc2V0LnJpZ2h0IC0gcmVjdC53aWR0aCAqICgxIC0gZWxlbWVudFJlY3QucmlnaHQpO1xyXG4gICAgICBvZmZzZXQuYm90dG9tID0gc3RhcnRPZmZzZXQuYm90dG9tIC0gcmVjdC5oZWlnaHQgKiAoMSAtIGVsZW1lbnRSZWN0LmJvdHRvbSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBvZmZzZXQubGVmdCA9IG9mZnNldC50b3AgPSBvZmZzZXQucmlnaHQgPSBvZmZzZXQuYm90dG9tID0gMDtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gb2Zmc2V0O1xyXG4gIH0sXHJcblxyXG4gIHNldDogZnVuY3Rpb24gc2V0KF9yZWYyKSB7XHJcbiAgICB2YXIgcGFnZUNvb3JkcyA9IF9yZWYyLnBhZ2VDb29yZHMsXHJcbiAgICAgICAgaW50ZXJhY3Rpb24gPSBfcmVmMi5pbnRlcmFjdGlvbixcclxuICAgICAgICBzdGF0dXMgPSBfcmVmMi5zdGF0dXMsXHJcbiAgICAgICAgb3B0aW9ucyA9IF9yZWYyLm9wdGlvbnM7XHJcblxyXG4gICAgaWYgKCFvcHRpb25zKSB7XHJcbiAgICAgIHJldHVybiBzdGF0dXM7XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIHBhZ2UgPSBzdGF0dXMudXNlU3RhdHVzWFkgPyB7IHg6IHN0YXR1cy54LCB5OiBzdGF0dXMueSB9IDogdXRpbHMuZXh0ZW5kKHt9LCBwYWdlQ29vcmRzKTtcclxuXHJcbiAgICB2YXIgcmVzdHJpY3Rpb24gPSBnZXRSZXN0cmljdGlvblJlY3Qob3B0aW9ucy5yZXN0cmljdGlvbiwgaW50ZXJhY3Rpb24sIHBhZ2UpO1xyXG5cclxuICAgIGlmICghcmVzdHJpY3Rpb24pIHtcclxuICAgICAgcmV0dXJuIHN0YXR1cztcclxuICAgIH1cclxuXHJcbiAgICBzdGF0dXMuZHggPSAwO1xyXG4gICAgc3RhdHVzLmR5ID0gMDtcclxuICAgIHN0YXR1cy5sb2NrZWQgPSBmYWxzZTtcclxuXHJcbiAgICB2YXIgcmVjdCA9IHJlc3RyaWN0aW9uO1xyXG4gICAgdmFyIG1vZGlmaWVkWCA9IHBhZ2UueDtcclxuICAgIHZhciBtb2RpZmllZFkgPSBwYWdlLnk7XHJcblxyXG4gICAgdmFyIG9mZnNldCA9IGludGVyYWN0aW9uLm1vZGlmaWVyT2Zmc2V0cy5yZXN0cmljdDtcclxuXHJcbiAgICAvLyBvYmplY3QgaXMgYXNzdW1lZCB0byBoYXZlXHJcbiAgICAvLyB4LCB5LCB3aWR0aCwgaGVpZ2h0IG9yXHJcbiAgICAvLyBsZWZ0LCB0b3AsIHJpZ2h0LCBib3R0b21cclxuICAgIGlmICgneCcgaW4gcmVzdHJpY3Rpb24gJiYgJ3knIGluIHJlc3RyaWN0aW9uKSB7XHJcbiAgICAgIG1vZGlmaWVkWCA9IE1hdGgubWF4KE1hdGgubWluKHJlY3QueCArIHJlY3Qud2lkdGggLSBvZmZzZXQucmlnaHQsIHBhZ2UueCksIHJlY3QueCArIG9mZnNldC5sZWZ0KTtcclxuICAgICAgbW9kaWZpZWRZID0gTWF0aC5tYXgoTWF0aC5taW4ocmVjdC55ICsgcmVjdC5oZWlnaHQgLSBvZmZzZXQuYm90dG9tLCBwYWdlLnkpLCByZWN0LnkgKyBvZmZzZXQudG9wKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIG1vZGlmaWVkWCA9IE1hdGgubWF4KE1hdGgubWluKHJlY3QucmlnaHQgLSBvZmZzZXQucmlnaHQsIHBhZ2UueCksIHJlY3QubGVmdCArIG9mZnNldC5sZWZ0KTtcclxuICAgICAgbW9kaWZpZWRZID0gTWF0aC5tYXgoTWF0aC5taW4ocmVjdC5ib3R0b20gLSBvZmZzZXQuYm90dG9tLCBwYWdlLnkpLCByZWN0LnRvcCArIG9mZnNldC50b3ApO1xyXG4gICAgfVxyXG5cclxuICAgIHN0YXR1cy5keCA9IG1vZGlmaWVkWCAtIHBhZ2UueDtcclxuICAgIHN0YXR1cy5keSA9IG1vZGlmaWVkWSAtIHBhZ2UueTtcclxuXHJcbiAgICBzdGF0dXMuY2hhbmdlZCA9IHN0YXR1cy5tb2RpZmllZFggIT09IG1vZGlmaWVkWCB8fCBzdGF0dXMubW9kaWZpZWRZICE9PSBtb2RpZmllZFk7XHJcbiAgICBzdGF0dXMubG9ja2VkID0gISEoc3RhdHVzLmR4IHx8IHN0YXR1cy5keSk7XHJcblxyXG4gICAgc3RhdHVzLm1vZGlmaWVkWCA9IG1vZGlmaWVkWDtcclxuICAgIHN0YXR1cy5tb2RpZmllZFkgPSBtb2RpZmllZFk7XHJcbiAgfSxcclxuXHJcbiAgbW9kaWZ5Q29vcmRzOiBmdW5jdGlvbiBtb2RpZnlDb29yZHMoX3JlZjMpIHtcclxuICAgIHZhciBwYWdlID0gX3JlZjMucGFnZSxcclxuICAgICAgICBjbGllbnQgPSBfcmVmMy5jbGllbnQsXHJcbiAgICAgICAgc3RhdHVzID0gX3JlZjMuc3RhdHVzLFxyXG4gICAgICAgIHBoYXNlID0gX3JlZjMucGhhc2UsXHJcbiAgICAgICAgb3B0aW9ucyA9IF9yZWYzLm9wdGlvbnM7XHJcblxyXG4gICAgdmFyIGVsZW1lbnRSZWN0ID0gb3B0aW9ucyAmJiBvcHRpb25zLmVsZW1lbnRSZWN0O1xyXG5cclxuICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMuZW5hYmxlZCAmJiAhKHBoYXNlID09PSAnc3RhcnQnICYmIGVsZW1lbnRSZWN0ICYmIHN0YXR1cy5sb2NrZWQpKSB7XHJcblxyXG4gICAgICBpZiAoc3RhdHVzLmxvY2tlZCkge1xyXG4gICAgICAgIHBhZ2UueCArPSBzdGF0dXMuZHg7XHJcbiAgICAgICAgcGFnZS55ICs9IHN0YXR1cy5keTtcclxuICAgICAgICBjbGllbnQueCArPSBzdGF0dXMuZHg7XHJcbiAgICAgICAgY2xpZW50LnkgKz0gc3RhdHVzLmR5O1xyXG5cclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgZHg6IHN0YXR1cy5keCxcclxuICAgICAgICAgIGR5OiBzdGF0dXMuZHlcclxuICAgICAgICB9O1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSxcclxuXHJcbiAgZ2V0UmVzdHJpY3Rpb25SZWN0OiBnZXRSZXN0cmljdGlvblJlY3RcclxufTtcclxuXHJcbmZ1bmN0aW9uIGdldFJlc3RyaWN0aW9uUmVjdCh2YWx1ZSwgaW50ZXJhY3Rpb24sIHBhZ2UpIHtcclxuICBpZiAodXRpbHMuaXMuZnVuY3Rpb24odmFsdWUpKSB7XHJcbiAgICByZXR1cm4gdXRpbHMucmVzb2x2ZVJlY3RMaWtlKHZhbHVlLCBpbnRlcmFjdGlvbi50YXJnZXQsIGludGVyYWN0aW9uLmVsZW1lbnQsIFtwYWdlLngsIHBhZ2UueSwgaW50ZXJhY3Rpb25dKTtcclxuICB9IGVsc2Uge1xyXG4gICAgcmV0dXJuIHV0aWxzLnJlc29sdmVSZWN0TGlrZSh2YWx1ZSwgaW50ZXJhY3Rpb24udGFyZ2V0LCBpbnRlcmFjdGlvbi5lbGVtZW50KTtcclxuICB9XHJcbn1cclxuXHJcbm1vZGlmaWVycy5yZXN0cmljdCA9IHJlc3RyaWN0O1xyXG5tb2RpZmllcnMubmFtZXMucHVzaCgncmVzdHJpY3QnKTtcclxuXHJcbmRlZmF1bHRPcHRpb25zLnBlckFjdGlvbi5yZXN0cmljdCA9IHJlc3RyaWN0LmRlZmF1bHRzO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSByZXN0cmljdDtcclxuXHJcbn0se1wiLi4vZGVmYXVsdE9wdGlvbnNcIjoxOCxcIi4uL3V0aWxzXCI6NDQsXCIuL2luZGV4XCI6MjR9XSwyNjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbi8vIFRoaXMgbW9kdWxlIGFkZHMgdGhlIG9wdGlvbnMucmVzaXplLnJlc3RyaWN0RWRnZXMgc2V0dGluZyB3aGljaCBzZXRzIG1pbiBhbmRcclxuLy8gbWF4IGZvciB0aGUgdG9wLCBsZWZ0LCBib3R0b20gYW5kIHJpZ2h0IGVkZ2VzIG9mIHRoZSB0YXJnZXQgYmVpbmcgcmVzaXplZC5cclxuLy9cclxuLy8gaW50ZXJhY3QodGFyZ2V0KS5yZXNpemUoe1xyXG4vLyAgIGVkZ2VzOiB7IHRvcDogdHJ1ZSwgbGVmdDogdHJ1ZSB9LFxyXG4vLyAgIHJlc3RyaWN0RWRnZXM6IHtcclxuLy8gICAgIGlubmVyOiB7IHRvcDogMjAwLCBsZWZ0OiAyMDAsIHJpZ2h0OiA0MDAsIGJvdHRvbTogNDAwIH0sXHJcbi8vICAgICBvdXRlcjogeyB0b3A6ICAgMCwgbGVmdDogICAwLCByaWdodDogNjAwLCBib3R0b206IDYwMCB9LFxyXG4vLyAgIH0sXHJcbi8vIH0pO1xyXG5cclxudmFyIG1vZGlmaWVycyA9IHJlcXVpcmUoJy4vaW5kZXgnKTtcclxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcclxudmFyIHJlY3RVdGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzL3JlY3QnKTtcclxudmFyIGRlZmF1bHRPcHRpb25zID0gcmVxdWlyZSgnLi4vZGVmYXVsdE9wdGlvbnMnKTtcclxudmFyIHJlc2l6ZSA9IHJlcXVpcmUoJy4uL2FjdGlvbnMvcmVzaXplJyk7XHJcblxyXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCcuL3Jlc3RyaWN0JyksXHJcbiAgICBnZXRSZXN0cmljdGlvblJlY3QgPSBfcmVxdWlyZS5nZXRSZXN0cmljdGlvblJlY3Q7XHJcblxyXG52YXIgbm9Jbm5lciA9IHsgdG9wOiArSW5maW5pdHksIGxlZnQ6ICtJbmZpbml0eSwgYm90dG9tOiAtSW5maW5pdHksIHJpZ2h0OiAtSW5maW5pdHkgfTtcclxudmFyIG5vT3V0ZXIgPSB7IHRvcDogLUluZmluaXR5LCBsZWZ0OiAtSW5maW5pdHksIGJvdHRvbTogK0luZmluaXR5LCByaWdodDogK0luZmluaXR5IH07XHJcblxyXG52YXIgcmVzdHJpY3RFZGdlcyA9IHtcclxuICBkZWZhdWx0czoge1xyXG4gICAgZW5hYmxlZDogZmFsc2UsXHJcbiAgICBlbmRPbmx5OiBmYWxzZSxcclxuICAgIG1pbjogbnVsbCxcclxuICAgIG1heDogbnVsbCxcclxuICAgIG9mZnNldDogbnVsbFxyXG4gIH0sXHJcblxyXG4gIHNldE9mZnNldDogZnVuY3Rpb24gc2V0T2Zmc2V0KF9yZWYpIHtcclxuICAgIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYuaW50ZXJhY3Rpb24sXHJcbiAgICAgICAgc3RhcnRPZmZzZXQgPSBfcmVmLnN0YXJ0T2Zmc2V0LFxyXG4gICAgICAgIG9wdGlvbnMgPSBfcmVmLm9wdGlvbnM7XHJcblxyXG4gICAgaWYgKCFvcHRpb25zKSB7XHJcbiAgICAgIHJldHVybiB1dGlscy5leHRlbmQoe30sIHN0YXJ0T2Zmc2V0KTtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgb2Zmc2V0ID0gZ2V0UmVzdHJpY3Rpb25SZWN0KG9wdGlvbnMub2Zmc2V0LCBpbnRlcmFjdGlvbiwgaW50ZXJhY3Rpb24uc3RhcnRDb29yZHMucGFnZSk7XHJcblxyXG4gICAgaWYgKG9mZnNldCkge1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIHRvcDogc3RhcnRPZmZzZXQudG9wICsgb2Zmc2V0LnksXHJcbiAgICAgICAgbGVmdDogc3RhcnRPZmZzZXQubGVmdCArIG9mZnNldC54LFxyXG4gICAgICAgIGJvdHRvbTogc3RhcnRPZmZzZXQuYm90dG9tICsgb2Zmc2V0LnksXHJcbiAgICAgICAgcmlnaHQ6IHN0YXJ0T2Zmc2V0LnJpZ2h0ICsgb2Zmc2V0LnhcclxuICAgICAgfTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gc3RhcnRPZmZzZXQ7XHJcbiAgfSxcclxuXHJcbiAgc2V0OiBmdW5jdGlvbiBzZXQoX3JlZjIpIHtcclxuICAgIHZhciBwYWdlQ29vcmRzID0gX3JlZjIucGFnZUNvb3JkcyxcclxuICAgICAgICBpbnRlcmFjdGlvbiA9IF9yZWYyLmludGVyYWN0aW9uLFxyXG4gICAgICAgIHN0YXR1cyA9IF9yZWYyLnN0YXR1cyxcclxuICAgICAgICBvZmZzZXQgPSBfcmVmMi5vZmZzZXQsXHJcbiAgICAgICAgb3B0aW9ucyA9IF9yZWYyLm9wdGlvbnM7XHJcblxyXG4gICAgdmFyIGVkZ2VzID0gaW50ZXJhY3Rpb24ucHJlcGFyZWQubGlua2VkRWRnZXMgfHwgaW50ZXJhY3Rpb24ucHJlcGFyZWQuZWRnZXM7XHJcblxyXG4gICAgaWYgKCFpbnRlcmFjdGlvbi5pbnRlcmFjdGluZygpIHx8ICFlZGdlcykge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIHBhZ2UgPSBzdGF0dXMudXNlU3RhdHVzWFkgPyB7IHg6IHN0YXR1cy54LCB5OiBzdGF0dXMueSB9IDogdXRpbHMuZXh0ZW5kKHt9LCBwYWdlQ29vcmRzKTtcclxuICAgIHZhciBpbm5lciA9IHJlY3RVdGlscy54eXdoVG9UbGJyKGdldFJlc3RyaWN0aW9uUmVjdChvcHRpb25zLmlubmVyLCBpbnRlcmFjdGlvbiwgcGFnZSkpIHx8IG5vSW5uZXI7XHJcbiAgICB2YXIgb3V0ZXIgPSByZWN0VXRpbHMueHl3aFRvVGxicihnZXRSZXN0cmljdGlvblJlY3Qob3B0aW9ucy5vdXRlciwgaW50ZXJhY3Rpb24sIHBhZ2UpKSB8fCBub091dGVyO1xyXG5cclxuICAgIHZhciBtb2RpZmllZFggPSBwYWdlLng7XHJcbiAgICB2YXIgbW9kaWZpZWRZID0gcGFnZS55O1xyXG5cclxuICAgIHN0YXR1cy5keCA9IDA7XHJcbiAgICBzdGF0dXMuZHkgPSAwO1xyXG4gICAgc3RhdHVzLmxvY2tlZCA9IGZhbHNlO1xyXG5cclxuICAgIGlmIChlZGdlcy50b3ApIHtcclxuICAgICAgbW9kaWZpZWRZID0gTWF0aC5taW4oTWF0aC5tYXgob3V0ZXIudG9wICsgb2Zmc2V0LnRvcCwgcGFnZS55KSwgaW5uZXIudG9wICsgb2Zmc2V0LnRvcCk7XHJcbiAgICB9IGVsc2UgaWYgKGVkZ2VzLmJvdHRvbSkge1xyXG4gICAgICBtb2RpZmllZFkgPSBNYXRoLm1heChNYXRoLm1pbihvdXRlci5ib3R0b20gLSBvZmZzZXQuYm90dG9tLCBwYWdlLnkpLCBpbm5lci5ib3R0b20gLSBvZmZzZXQuYm90dG9tKTtcclxuICAgIH1cclxuICAgIGlmIChlZGdlcy5sZWZ0KSB7XHJcbiAgICAgIG1vZGlmaWVkWCA9IE1hdGgubWluKE1hdGgubWF4KG91dGVyLmxlZnQgKyBvZmZzZXQubGVmdCwgcGFnZS54KSwgaW5uZXIubGVmdCArIG9mZnNldC5sZWZ0KTtcclxuICAgIH0gZWxzZSBpZiAoZWRnZXMucmlnaHQpIHtcclxuICAgICAgbW9kaWZpZWRYID0gTWF0aC5tYXgoTWF0aC5taW4ob3V0ZXIucmlnaHQgLSBvZmZzZXQucmlnaHQsIHBhZ2UueCksIGlubmVyLnJpZ2h0IC0gb2Zmc2V0LnJpZ2h0KTtcclxuICAgIH1cclxuXHJcbiAgICBzdGF0dXMuZHggPSBtb2RpZmllZFggLSBwYWdlLng7XHJcbiAgICBzdGF0dXMuZHkgPSBtb2RpZmllZFkgLSBwYWdlLnk7XHJcblxyXG4gICAgc3RhdHVzLmNoYW5nZWQgPSBzdGF0dXMubW9kaWZpZWRYICE9PSBtb2RpZmllZFggfHwgc3RhdHVzLm1vZGlmaWVkWSAhPT0gbW9kaWZpZWRZO1xyXG4gICAgc3RhdHVzLmxvY2tlZCA9ICEhKHN0YXR1cy5keCB8fCBzdGF0dXMuZHkpO1xyXG5cclxuICAgIHN0YXR1cy5tb2RpZmllZFggPSBtb2RpZmllZFg7XHJcbiAgICBzdGF0dXMubW9kaWZpZWRZID0gbW9kaWZpZWRZO1xyXG4gIH0sXHJcblxyXG4gIG1vZGlmeUNvb3JkczogZnVuY3Rpb24gbW9kaWZ5Q29vcmRzKF9yZWYzKSB7XHJcbiAgICB2YXIgcGFnZSA9IF9yZWYzLnBhZ2UsXHJcbiAgICAgICAgY2xpZW50ID0gX3JlZjMuY2xpZW50LFxyXG4gICAgICAgIHN0YXR1cyA9IF9yZWYzLnN0YXR1cyxcclxuICAgICAgICBwaGFzZSA9IF9yZWYzLnBoYXNlLFxyXG4gICAgICAgIG9wdGlvbnMgPSBfcmVmMy5vcHRpb25zO1xyXG5cclxuICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMuZW5hYmxlZCAmJiAhKHBoYXNlID09PSAnc3RhcnQnICYmIHN0YXR1cy5sb2NrZWQpKSB7XHJcblxyXG4gICAgICBpZiAoc3RhdHVzLmxvY2tlZCkge1xyXG4gICAgICAgIHBhZ2UueCArPSBzdGF0dXMuZHg7XHJcbiAgICAgICAgcGFnZS55ICs9IHN0YXR1cy5keTtcclxuICAgICAgICBjbGllbnQueCArPSBzdGF0dXMuZHg7XHJcbiAgICAgICAgY2xpZW50LnkgKz0gc3RhdHVzLmR5O1xyXG5cclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgZHg6IHN0YXR1cy5keCxcclxuICAgICAgICAgIGR5OiBzdGF0dXMuZHlcclxuICAgICAgICB9O1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSxcclxuXHJcbiAgbm9Jbm5lcjogbm9Jbm5lcixcclxuICBub091dGVyOiBub091dGVyLFxyXG4gIGdldFJlc3RyaWN0aW9uUmVjdDogZ2V0UmVzdHJpY3Rpb25SZWN0XHJcbn07XHJcblxyXG5tb2RpZmllcnMucmVzdHJpY3RFZGdlcyA9IHJlc3RyaWN0RWRnZXM7XHJcbm1vZGlmaWVycy5uYW1lcy5wdXNoKCdyZXN0cmljdEVkZ2VzJyk7XHJcblxyXG5kZWZhdWx0T3B0aW9ucy5wZXJBY3Rpb24ucmVzdHJpY3RFZGdlcyA9IHJlc3RyaWN0RWRnZXMuZGVmYXVsdHM7XHJcbnJlc2l6ZS5kZWZhdWx0cy5yZXN0cmljdEVkZ2VzID0gcmVzdHJpY3RFZGdlcy5kZWZhdWx0cztcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gcmVzdHJpY3RFZGdlcztcclxuXHJcbn0se1wiLi4vYWN0aW9ucy9yZXNpemVcIjoxMCxcIi4uL2RlZmF1bHRPcHRpb25zXCI6MTgsXCIuLi91dGlsc1wiOjQ0LFwiLi4vdXRpbHMvcmVjdFwiOjUxLFwiLi9pbmRleFwiOjI0LFwiLi9yZXN0cmljdFwiOjI1fV0sMjc6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xyXG4ndXNlIHN0cmljdCc7XHJcblxyXG4vLyBUaGlzIG1vZHVsZSBhZGRzIHRoZSBvcHRpb25zLnJlc2l6ZS5yZXN0cmljdFNpemUgc2V0dGluZyB3aGljaCBzZXRzIG1pbiBhbmRcclxuLy8gbWF4IHdpZHRoIGFuZCBoZWlnaHQgZm9yIHRoZSB0YXJnZXQgYmVpbmcgcmVzaXplZC5cclxuLy9cclxuLy8gaW50ZXJhY3QodGFyZ2V0KS5yZXNpemUoe1xyXG4vLyAgIGVkZ2VzOiB7IHRvcDogdHJ1ZSwgbGVmdDogdHJ1ZSB9LFxyXG4vLyAgIHJlc3RyaWN0U2l6ZToge1xyXG4vLyAgICAgbWluOiB7IHdpZHRoOiAtNjAwLCBoZWlnaHQ6IC02MDAgfSxcclxuLy8gICAgIG1heDogeyB3aWR0aDogIDYwMCwgaGVpZ2h0OiAgNjAwIH0sXHJcbi8vICAgfSxcclxuLy8gfSk7XHJcblxyXG52YXIgbW9kaWZpZXJzID0gcmVxdWlyZSgnLi9pbmRleCcpO1xyXG52YXIgcmVzdHJpY3RFZGdlcyA9IHJlcXVpcmUoJy4vcmVzdHJpY3RFZGdlcycpO1xyXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xyXG52YXIgcmVjdFV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMvcmVjdCcpO1xyXG52YXIgZGVmYXVsdE9wdGlvbnMgPSByZXF1aXJlKCcuLi9kZWZhdWx0T3B0aW9ucycpO1xyXG52YXIgcmVzaXplID0gcmVxdWlyZSgnLi4vYWN0aW9ucy9yZXNpemUnKTtcclxuXHJcbnZhciBub01pbiA9IHsgd2lkdGg6IC1JbmZpbml0eSwgaGVpZ2h0OiAtSW5maW5pdHkgfTtcclxudmFyIG5vTWF4ID0geyB3aWR0aDogK0luZmluaXR5LCBoZWlnaHQ6ICtJbmZpbml0eSB9O1xyXG5cclxudmFyIHJlc3RyaWN0U2l6ZSA9IHtcclxuICBkZWZhdWx0czoge1xyXG4gICAgZW5hYmxlZDogZmFsc2UsXHJcbiAgICBlbmRPbmx5OiBmYWxzZSxcclxuICAgIG1pbjogbnVsbCxcclxuICAgIG1heDogbnVsbFxyXG4gIH0sXHJcblxyXG4gIHNldE9mZnNldDogZnVuY3Rpb24gc2V0T2Zmc2V0KF9yZWYpIHtcclxuICAgIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYuaW50ZXJhY3Rpb247XHJcblxyXG4gICAgcmV0dXJuIGludGVyYWN0aW9uLnN0YXJ0T2Zmc2V0O1xyXG4gIH0sXHJcblxyXG4gIHNldDogZnVuY3Rpb24gc2V0KGFyZykge1xyXG4gICAgdmFyIGludGVyYWN0aW9uID0gYXJnLmludGVyYWN0aW9uLFxyXG4gICAgICAgIG9wdGlvbnMgPSBhcmcub3B0aW9ucztcclxuXHJcbiAgICB2YXIgZWRnZXMgPSBpbnRlcmFjdGlvbi5wcmVwYXJlZC5saW5rZWRFZGdlcyB8fCBpbnRlcmFjdGlvbi5wcmVwYXJlZC5lZGdlcztcclxuXHJcbiAgICBpZiAoIWludGVyYWN0aW9uLmludGVyYWN0aW5nKCkgfHwgIWVkZ2VzKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgcmVjdCA9IHJlY3RVdGlscy54eXdoVG9UbGJyKGludGVyYWN0aW9uLnJlc2l6ZVJlY3RzLmludmVydGVkKTtcclxuXHJcbiAgICB2YXIgbWluU2l6ZSA9IHJlY3RVdGlscy50bGJyVG9YeXdoKHJlc3RyaWN0RWRnZXMuZ2V0UmVzdHJpY3Rpb25SZWN0KG9wdGlvbnMubWluLCBpbnRlcmFjdGlvbikpIHx8IG5vTWluO1xyXG4gICAgdmFyIG1heFNpemUgPSByZWN0VXRpbHMudGxiclRvWHl3aChyZXN0cmljdEVkZ2VzLmdldFJlc3RyaWN0aW9uUmVjdChvcHRpb25zLm1heCwgaW50ZXJhY3Rpb24pKSB8fCBub01heDtcclxuXHJcbiAgICBhcmcub3B0aW9ucyA9IHtcclxuICAgICAgZW5hYmxlZDogb3B0aW9ucy5lbmFibGVkLFxyXG4gICAgICBlbmRPbmx5OiBvcHRpb25zLmVuZE9ubHksXHJcbiAgICAgIGlubmVyOiB1dGlscy5leHRlbmQoe30sIHJlc3RyaWN0RWRnZXMubm9Jbm5lciksXHJcbiAgICAgIG91dGVyOiB1dGlscy5leHRlbmQoe30sIHJlc3RyaWN0RWRnZXMubm9PdXRlcilcclxuICAgIH07XHJcblxyXG4gICAgaWYgKGVkZ2VzLnRvcCkge1xyXG4gICAgICBhcmcub3B0aW9ucy5pbm5lci50b3AgPSByZWN0LmJvdHRvbSAtIG1pblNpemUuaGVpZ2h0O1xyXG4gICAgICBhcmcub3B0aW9ucy5vdXRlci50b3AgPSByZWN0LmJvdHRvbSAtIG1heFNpemUuaGVpZ2h0O1xyXG4gICAgfSBlbHNlIGlmIChlZGdlcy5ib3R0b20pIHtcclxuICAgICAgYXJnLm9wdGlvbnMuaW5uZXIuYm90dG9tID0gcmVjdC50b3AgKyBtaW5TaXplLmhlaWdodDtcclxuICAgICAgYXJnLm9wdGlvbnMub3V0ZXIuYm90dG9tID0gcmVjdC50b3AgKyBtYXhTaXplLmhlaWdodDtcclxuICAgIH1cclxuICAgIGlmIChlZGdlcy5sZWZ0KSB7XHJcbiAgICAgIGFyZy5vcHRpb25zLmlubmVyLmxlZnQgPSByZWN0LnJpZ2h0IC0gbWluU2l6ZS53aWR0aDtcclxuICAgICAgYXJnLm9wdGlvbnMub3V0ZXIubGVmdCA9IHJlY3QucmlnaHQgLSBtYXhTaXplLndpZHRoO1xyXG4gICAgfSBlbHNlIGlmIChlZGdlcy5yaWdodCkge1xyXG4gICAgICBhcmcub3B0aW9ucy5pbm5lci5yaWdodCA9IHJlY3QubGVmdCArIG1pblNpemUud2lkdGg7XHJcbiAgICAgIGFyZy5vcHRpb25zLm91dGVyLnJpZ2h0ID0gcmVjdC5sZWZ0ICsgbWF4U2l6ZS53aWR0aDtcclxuICAgIH1cclxuXHJcbiAgICByZXN0cmljdEVkZ2VzLnNldChhcmcpO1xyXG4gIH0sXHJcblxyXG4gIG1vZGlmeUNvb3JkczogcmVzdHJpY3RFZGdlcy5tb2RpZnlDb29yZHNcclxufTtcclxuXHJcbm1vZGlmaWVycy5yZXN0cmljdFNpemUgPSByZXN0cmljdFNpemU7XHJcbm1vZGlmaWVycy5uYW1lcy5wdXNoKCdyZXN0cmljdFNpemUnKTtcclxuXHJcbmRlZmF1bHRPcHRpb25zLnBlckFjdGlvbi5yZXN0cmljdFNpemUgPSByZXN0cmljdFNpemUuZGVmYXVsdHM7XHJcbnJlc2l6ZS5kZWZhdWx0cy5yZXN0cmljdFNpemUgPSByZXN0cmljdFNpemUuZGVmYXVsdHM7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHJlc3RyaWN0U2l6ZTtcclxuXHJcbn0se1wiLi4vYWN0aW9ucy9yZXNpemVcIjoxMCxcIi4uL2RlZmF1bHRPcHRpb25zXCI6MTgsXCIuLi91dGlsc1wiOjQ0LFwiLi4vdXRpbHMvcmVjdFwiOjUxLFwiLi9pbmRleFwiOjI0LFwiLi9yZXN0cmljdEVkZ2VzXCI6MjZ9XSwyODpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBtb2RpZmllcnMgPSByZXF1aXJlKCcuL2luZGV4Jyk7XHJcbnZhciBpbnRlcmFjdCA9IHJlcXVpcmUoJy4uL2ludGVyYWN0Jyk7XHJcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XHJcbnZhciBkZWZhdWx0T3B0aW9ucyA9IHJlcXVpcmUoJy4uL2RlZmF1bHRPcHRpb25zJyk7XHJcblxyXG52YXIgc25hcCA9IHtcclxuICBkZWZhdWx0czoge1xyXG4gICAgZW5hYmxlZDogZmFsc2UsXHJcbiAgICBlbmRPbmx5OiBmYWxzZSxcclxuICAgIHJhbmdlOiBJbmZpbml0eSxcclxuICAgIHRhcmdldHM6IG51bGwsXHJcbiAgICBvZmZzZXRzOiBudWxsLFxyXG5cclxuICAgIHJlbGF0aXZlUG9pbnRzOiBudWxsXHJcbiAgfSxcclxuXHJcbiAgc2V0T2Zmc2V0OiBmdW5jdGlvbiBzZXRPZmZzZXQoX3JlZikge1xyXG4gICAgdmFyIGludGVyYWN0aW9uID0gX3JlZi5pbnRlcmFjdGlvbixcclxuICAgICAgICBpbnRlcmFjdGFibGUgPSBfcmVmLmludGVyYWN0YWJsZSxcclxuICAgICAgICBlbGVtZW50ID0gX3JlZi5lbGVtZW50LFxyXG4gICAgICAgIHJlY3QgPSBfcmVmLnJlY3QsXHJcbiAgICAgICAgc3RhcnRPZmZzZXQgPSBfcmVmLnN0YXJ0T2Zmc2V0LFxyXG4gICAgICAgIG9wdGlvbnMgPSBfcmVmLm9wdGlvbnM7XHJcblxyXG4gICAgdmFyIG9mZnNldHMgPSBbXTtcclxuICAgIHZhciBvcHRpb25zT3JpZ2luID0gdXRpbHMucmVjdFRvWFkodXRpbHMucmVzb2x2ZVJlY3RMaWtlKG9wdGlvbnMub3JpZ2luKSk7XHJcbiAgICB2YXIgb3JpZ2luID0gb3B0aW9uc09yaWdpbiB8fCB1dGlscy5nZXRPcmlnaW5YWShpbnRlcmFjdGFibGUsIGVsZW1lbnQsIGludGVyYWN0aW9uLnByZXBhcmVkLm5hbWUpO1xyXG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwgaW50ZXJhY3RhYmxlLm9wdGlvbnNbaW50ZXJhY3Rpb24ucHJlcGFyZWQubmFtZV0uc25hcCB8fCB7fTtcclxuXHJcbiAgICB2YXIgc25hcE9mZnNldCA9IHZvaWQgMDtcclxuXHJcbiAgICBpZiAob3B0aW9ucy5vZmZzZXQgPT09ICdzdGFydENvb3JkcycpIHtcclxuICAgICAgc25hcE9mZnNldCA9IHtcclxuICAgICAgICB4OiBpbnRlcmFjdGlvbi5zdGFydENvb3Jkcy5wYWdlLnggLSBvcmlnaW4ueCxcclxuICAgICAgICB5OiBpbnRlcmFjdGlvbi5zdGFydENvb3Jkcy5wYWdlLnkgLSBvcmlnaW4ueVxyXG4gICAgICB9O1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdmFyIG9mZnNldFJlY3QgPSB1dGlscy5yZXNvbHZlUmVjdExpa2Uob3B0aW9ucy5vZmZzZXQsIGludGVyYWN0YWJsZSwgZWxlbWVudCwgW2ludGVyYWN0aW9uXSk7XHJcblxyXG4gICAgICBzbmFwT2Zmc2V0ID0gdXRpbHMucmVjdFRvWFkob2Zmc2V0UmVjdCkgfHwgeyB4OiAwLCB5OiAwIH07XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHJlY3QgJiYgb3B0aW9ucy5yZWxhdGl2ZVBvaW50cyAmJiBvcHRpb25zLnJlbGF0aXZlUG9pbnRzLmxlbmd0aCkge1xyXG4gICAgICBmb3IgKHZhciBfaXRlcmF0b3IgPSBvcHRpb25zLnJlbGF0aXZlUG9pbnRzLCBfaXNBcnJheSA9IEFycmF5LmlzQXJyYXkoX2l0ZXJhdG9yKSwgX2kgPSAwLCBfaXRlcmF0b3IgPSBfaXNBcnJheSA/IF9pdGVyYXRvciA6IF9pdGVyYXRvcltTeW1ib2wuaXRlcmF0b3JdKCk7Oykge1xyXG4gICAgICAgIHZhciBfcmVmMjtcclxuXHJcbiAgICAgICAgaWYgKF9pc0FycmF5KSB7XHJcbiAgICAgICAgICBpZiAoX2kgPj0gX2l0ZXJhdG9yLmxlbmd0aCkgYnJlYWs7XHJcbiAgICAgICAgICBfcmVmMiA9IF9pdGVyYXRvcltfaSsrXTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgX2kgPSBfaXRlcmF0b3IubmV4dCgpO1xyXG4gICAgICAgICAgaWYgKF9pLmRvbmUpIGJyZWFrO1xyXG4gICAgICAgICAgX3JlZjIgPSBfaS52YWx1ZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBfcmVmMyA9IF9yZWYyLFxyXG4gICAgICAgICAgICByZWxhdGl2ZVggPSBfcmVmMy54LFxyXG4gICAgICAgICAgICByZWxhdGl2ZVkgPSBfcmVmMy55O1xyXG5cclxuICAgICAgICBvZmZzZXRzLnB1c2goe1xyXG4gICAgICAgICAgeDogc3RhcnRPZmZzZXQubGVmdCAtIHJlY3Qud2lkdGggKiByZWxhdGl2ZVggKyBzbmFwT2Zmc2V0LngsXHJcbiAgICAgICAgICB5OiBzdGFydE9mZnNldC50b3AgLSByZWN0LmhlaWdodCAqIHJlbGF0aXZlWSArIHNuYXBPZmZzZXQueVxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBvZmZzZXRzLnB1c2goc25hcE9mZnNldCk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIG9mZnNldHM7XHJcbiAgfSxcclxuXHJcbiAgc2V0OiBmdW5jdGlvbiBzZXQoX3JlZjQpIHtcclxuICAgIHZhciBpbnRlcmFjdGlvbiA9IF9yZWY0LmludGVyYWN0aW9uLFxyXG4gICAgICAgIHBhZ2VDb29yZHMgPSBfcmVmNC5wYWdlQ29vcmRzLFxyXG4gICAgICAgIHN0YXR1cyA9IF9yZWY0LnN0YXR1cyxcclxuICAgICAgICBvcHRpb25zID0gX3JlZjQub3B0aW9ucyxcclxuICAgICAgICBvZmZzZXRzID0gX3JlZjQub2Zmc2V0O1xyXG5cclxuICAgIHZhciB0YXJnZXRzID0gW107XHJcbiAgICB2YXIgdGFyZ2V0ID0gdm9pZCAwO1xyXG4gICAgdmFyIHBhZ2UgPSB2b2lkIDA7XHJcbiAgICB2YXIgaSA9IHZvaWQgMDtcclxuXHJcbiAgICBpZiAoc3RhdHVzLnVzZVN0YXR1c1hZKSB7XHJcbiAgICAgIHBhZ2UgPSB7IHg6IHN0YXR1cy54LCB5OiBzdGF0dXMueSB9O1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdmFyIG9yaWdpbiA9IHV0aWxzLmdldE9yaWdpblhZKGludGVyYWN0aW9uLnRhcmdldCwgaW50ZXJhY3Rpb24uZWxlbWVudCwgaW50ZXJhY3Rpb24ucHJlcGFyZWQubmFtZSk7XHJcblxyXG4gICAgICBwYWdlID0gdXRpbHMuZXh0ZW5kKHt9LCBwYWdlQ29vcmRzKTtcclxuXHJcbiAgICAgIHBhZ2UueCAtPSBvcmlnaW4ueDtcclxuICAgICAgcGFnZS55IC09IG9yaWdpbi55O1xyXG4gICAgfVxyXG5cclxuICAgIHN0YXR1cy5yZWFsWCA9IHBhZ2UueDtcclxuICAgIHN0YXR1cy5yZWFsWSA9IHBhZ2UueTtcclxuXHJcbiAgICB2YXIgbGVuID0gb3B0aW9ucy50YXJnZXRzID8gb3B0aW9ucy50YXJnZXRzLmxlbmd0aCA6IDA7XHJcblxyXG4gICAgZm9yICh2YXIgX2l0ZXJhdG9yMiA9IG9mZnNldHMsIF9pc0FycmF5MiA9IEFycmF5LmlzQXJyYXkoX2l0ZXJhdG9yMiksIF9pMiA9IDAsIF9pdGVyYXRvcjIgPSBfaXNBcnJheTIgPyBfaXRlcmF0b3IyIDogX2l0ZXJhdG9yMltTeW1ib2wuaXRlcmF0b3JdKCk7Oykge1xyXG4gICAgICB2YXIgX3JlZjU7XHJcblxyXG4gICAgICBpZiAoX2lzQXJyYXkyKSB7XHJcbiAgICAgICAgaWYgKF9pMiA+PSBfaXRlcmF0b3IyLmxlbmd0aCkgYnJlYWs7XHJcbiAgICAgICAgX3JlZjUgPSBfaXRlcmF0b3IyW19pMisrXTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBfaTIgPSBfaXRlcmF0b3IyLm5leHQoKTtcclxuICAgICAgICBpZiAoX2kyLmRvbmUpIGJyZWFrO1xyXG4gICAgICAgIF9yZWY1ID0gX2kyLnZhbHVlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB2YXIgX3JlZjYgPSBfcmVmNSxcclxuICAgICAgICAgIG9mZnNldFggPSBfcmVmNi54LFxyXG4gICAgICAgICAgb2Zmc2V0WSA9IF9yZWY2Lnk7XHJcblxyXG4gICAgICB2YXIgcmVsYXRpdmVYID0gcGFnZS54IC0gb2Zmc2V0WDtcclxuICAgICAgdmFyIHJlbGF0aXZlWSA9IHBhZ2UueSAtIG9mZnNldFk7XHJcblxyXG4gICAgICBmb3IgKHZhciBfaXRlcmF0b3IzID0gb3B0aW9ucy50YXJnZXRzLCBfaXNBcnJheTMgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvcjMpLCBfaTMgPSAwLCBfaXRlcmF0b3IzID0gX2lzQXJyYXkzID8gX2l0ZXJhdG9yMyA6IF9pdGVyYXRvcjNbU3ltYm9sLml0ZXJhdG9yXSgpOzspIHtcclxuICAgICAgICB2YXIgX3JlZjc7XHJcblxyXG4gICAgICAgIGlmIChfaXNBcnJheTMpIHtcclxuICAgICAgICAgIGlmIChfaTMgPj0gX2l0ZXJhdG9yMy5sZW5ndGgpIGJyZWFrO1xyXG4gICAgICAgICAgX3JlZjcgPSBfaXRlcmF0b3IzW19pMysrXTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgX2kzID0gX2l0ZXJhdG9yMy5uZXh0KCk7XHJcbiAgICAgICAgICBpZiAoX2kzLmRvbmUpIGJyZWFrO1xyXG4gICAgICAgICAgX3JlZjcgPSBfaTMudmFsdWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB2YXIgc25hcFRhcmdldCA9IF9yZWY3O1xyXG5cclxuICAgICAgICBpZiAodXRpbHMuaXMuZnVuY3Rpb24oc25hcFRhcmdldCkpIHtcclxuICAgICAgICAgIHRhcmdldCA9IHNuYXBUYXJnZXQocmVsYXRpdmVYLCByZWxhdGl2ZVksIGludGVyYWN0aW9uKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgdGFyZ2V0ID0gc25hcFRhcmdldDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghdGFyZ2V0KSB7XHJcbiAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRhcmdldHMucHVzaCh7XHJcbiAgICAgICAgICB4OiB1dGlscy5pcy5udW1iZXIodGFyZ2V0LngpID8gdGFyZ2V0LnggKyBvZmZzZXRYIDogcmVsYXRpdmVYLFxyXG4gICAgICAgICAgeTogdXRpbHMuaXMubnVtYmVyKHRhcmdldC55KSA/IHRhcmdldC55ICsgb2Zmc2V0WSA6IHJlbGF0aXZlWSxcclxuXHJcbiAgICAgICAgICByYW5nZTogdXRpbHMuaXMubnVtYmVyKHRhcmdldC5yYW5nZSkgPyB0YXJnZXQucmFuZ2UgOiBvcHRpb25zLnJhbmdlXHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICB2YXIgY2xvc2VzdCA9IHtcclxuICAgICAgdGFyZ2V0OiBudWxsLFxyXG4gICAgICBpblJhbmdlOiBmYWxzZSxcclxuICAgICAgZGlzdGFuY2U6IDAsXHJcbiAgICAgIHJhbmdlOiAwLFxyXG4gICAgICBkeDogMCxcclxuICAgICAgZHk6IDBcclxuICAgIH07XHJcblxyXG4gICAgZm9yIChpID0gMCwgbGVuID0gdGFyZ2V0cy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICB0YXJnZXQgPSB0YXJnZXRzW2ldO1xyXG5cclxuICAgICAgdmFyIHJhbmdlID0gdGFyZ2V0LnJhbmdlO1xyXG4gICAgICB2YXIgZHggPSB0YXJnZXQueCAtIHBhZ2UueDtcclxuICAgICAgdmFyIGR5ID0gdGFyZ2V0LnkgLSBwYWdlLnk7XHJcbiAgICAgIHZhciBkaXN0YW5jZSA9IHV0aWxzLmh5cG90KGR4LCBkeSk7XHJcbiAgICAgIHZhciBpblJhbmdlID0gZGlzdGFuY2UgPD0gcmFuZ2U7XHJcblxyXG4gICAgICAvLyBJbmZpbml0ZSB0YXJnZXRzIGNvdW50IGFzIGJlaW5nIG91dCBvZiByYW5nZVxyXG4gICAgICAvLyBjb21wYXJlZCB0byBub24gaW5maW5pdGUgb25lcyB0aGF0IGFyZSBpbiByYW5nZVxyXG4gICAgICBpZiAocmFuZ2UgPT09IEluZmluaXR5ICYmIGNsb3Nlc3QuaW5SYW5nZSAmJiBjbG9zZXN0LnJhbmdlICE9PSBJbmZpbml0eSkge1xyXG4gICAgICAgIGluUmFuZ2UgPSBmYWxzZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKCFjbG9zZXN0LnRhcmdldCB8fCAoaW5SYW5nZVxyXG4gICAgICAvLyBpcyB0aGUgY2xvc2VzdCB0YXJnZXQgaW4gcmFuZ2U/XHJcbiAgICAgID8gY2xvc2VzdC5pblJhbmdlICYmIHJhbmdlICE9PSBJbmZpbml0eVxyXG4gICAgICAvLyB0aGUgcG9pbnRlciBpcyByZWxhdGl2ZWx5IGRlZXBlciBpbiB0aGlzIHRhcmdldFxyXG4gICAgICA/IGRpc3RhbmNlIC8gcmFuZ2UgPCBjbG9zZXN0LmRpc3RhbmNlIC8gY2xvc2VzdC5yYW5nZVxyXG4gICAgICAvLyB0aGlzIHRhcmdldCBoYXMgSW5maW5pdGUgcmFuZ2UgYW5kIHRoZSBjbG9zZXN0IGRvZXNuJ3RcclxuICAgICAgOiByYW5nZSA9PT0gSW5maW5pdHkgJiYgY2xvc2VzdC5yYW5nZSAhPT0gSW5maW5pdHkgfHxcclxuICAgICAgLy8gT1IgdGhpcyB0YXJnZXQgaXMgY2xvc2VyIHRoYXQgdGhlIHByZXZpb3VzIGNsb3Nlc3RcclxuICAgICAgZGlzdGFuY2UgPCBjbG9zZXN0LmRpc3RhbmNlIDpcclxuICAgICAgLy8gVGhlIG90aGVyIGlzIG5vdCBpbiByYW5nZSBhbmQgdGhlIHBvaW50ZXIgaXMgY2xvc2VyIHRvIHRoaXMgdGFyZ2V0XHJcbiAgICAgICFjbG9zZXN0LmluUmFuZ2UgJiYgZGlzdGFuY2UgPCBjbG9zZXN0LmRpc3RhbmNlKSkge1xyXG5cclxuICAgICAgICBjbG9zZXN0LnRhcmdldCA9IHRhcmdldDtcclxuICAgICAgICBjbG9zZXN0LmRpc3RhbmNlID0gZGlzdGFuY2U7XHJcbiAgICAgICAgY2xvc2VzdC5yYW5nZSA9IHJhbmdlO1xyXG4gICAgICAgIGNsb3Nlc3QuaW5SYW5nZSA9IGluUmFuZ2U7XHJcbiAgICAgICAgY2xvc2VzdC5keCA9IGR4O1xyXG4gICAgICAgIGNsb3Nlc3QuZHkgPSBkeTtcclxuXHJcbiAgICAgICAgc3RhdHVzLnJhbmdlID0gcmFuZ2U7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICB2YXIgc25hcENoYW5nZWQgPSB2b2lkIDA7XHJcblxyXG4gICAgaWYgKGNsb3Nlc3QudGFyZ2V0KSB7XHJcbiAgICAgIHNuYXBDaGFuZ2VkID0gc3RhdHVzLm1vZGlmaWVkWCAhPT0gY2xvc2VzdC50YXJnZXQueCB8fCBzdGF0dXMubW9kaWZpZWRZICE9PSBjbG9zZXN0LnRhcmdldC55O1xyXG5cclxuICAgICAgc3RhdHVzLm1vZGlmaWVkWCA9IGNsb3Nlc3QudGFyZ2V0Lng7XHJcbiAgICAgIHN0YXR1cy5tb2RpZmllZFkgPSBjbG9zZXN0LnRhcmdldC55O1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgc25hcENoYW5nZWQgPSB0cnVlO1xyXG5cclxuICAgICAgc3RhdHVzLm1vZGlmaWVkWCA9IE5hTjtcclxuICAgICAgc3RhdHVzLm1vZGlmaWVkWSA9IE5hTjtcclxuICAgIH1cclxuXHJcbiAgICBzdGF0dXMuZHggPSBjbG9zZXN0LmR4O1xyXG4gICAgc3RhdHVzLmR5ID0gY2xvc2VzdC5keTtcclxuXHJcbiAgICBzdGF0dXMuY2hhbmdlZCA9IHNuYXBDaGFuZ2VkIHx8IGNsb3Nlc3QuaW5SYW5nZSAmJiAhc3RhdHVzLmxvY2tlZDtcclxuICAgIHN0YXR1cy5sb2NrZWQgPSBjbG9zZXN0LmluUmFuZ2U7XHJcbiAgfSxcclxuXHJcbiAgbW9kaWZ5Q29vcmRzOiBmdW5jdGlvbiBtb2RpZnlDb29yZHMoX3JlZjgpIHtcclxuICAgIHZhciBwYWdlID0gX3JlZjgucGFnZSxcclxuICAgICAgICBjbGllbnQgPSBfcmVmOC5jbGllbnQsXHJcbiAgICAgICAgc3RhdHVzID0gX3JlZjguc3RhdHVzLFxyXG4gICAgICAgIHBoYXNlID0gX3JlZjgucGhhc2UsXHJcbiAgICAgICAgb3B0aW9ucyA9IF9yZWY4Lm9wdGlvbnM7XHJcblxyXG4gICAgdmFyIHJlbGF0aXZlUG9pbnRzID0gb3B0aW9ucyAmJiBvcHRpb25zLnJlbGF0aXZlUG9pbnRzO1xyXG5cclxuICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMuZW5hYmxlZCAmJiAhKHBoYXNlID09PSAnc3RhcnQnICYmIHJlbGF0aXZlUG9pbnRzICYmIHJlbGF0aXZlUG9pbnRzLmxlbmd0aCkpIHtcclxuXHJcbiAgICAgIGlmIChzdGF0dXMubG9ja2VkKSB7XHJcbiAgICAgICAgcGFnZS54ICs9IHN0YXR1cy5keDtcclxuICAgICAgICBwYWdlLnkgKz0gc3RhdHVzLmR5O1xyXG4gICAgICAgIGNsaWVudC54ICs9IHN0YXR1cy5keDtcclxuICAgICAgICBjbGllbnQueSArPSBzdGF0dXMuZHk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgcmFuZ2U6IHN0YXR1cy5yYW5nZSxcclxuICAgICAgICBsb2NrZWQ6IHN0YXR1cy5sb2NrZWQsXHJcbiAgICAgICAgeDogc3RhdHVzLm1vZGlmaWVkWCxcclxuICAgICAgICB5OiBzdGF0dXMubW9kaWZpZWRZLFxyXG4gICAgICAgIHJlYWxYOiBzdGF0dXMucmVhbFgsXHJcbiAgICAgICAgcmVhbFk6IHN0YXR1cy5yZWFsWSxcclxuICAgICAgICBkeDogc3RhdHVzLmR4LFxyXG4gICAgICAgIGR5OiBzdGF0dXMuZHlcclxuICAgICAgfTtcclxuICAgIH1cclxuICB9XHJcbn07XHJcblxyXG5pbnRlcmFjdC5jcmVhdGVTbmFwR3JpZCA9IGZ1bmN0aW9uIChncmlkKSB7XHJcbiAgcmV0dXJuIGZ1bmN0aW9uICh4LCB5KSB7XHJcbiAgICB2YXIgbGltaXRzID0gZ3JpZC5saW1pdHMgfHwge1xyXG4gICAgICBsZWZ0OiAtSW5maW5pdHksXHJcbiAgICAgIHJpZ2h0OiBJbmZpbml0eSxcclxuICAgICAgdG9wOiAtSW5maW5pdHksXHJcbiAgICAgIGJvdHRvbTogSW5maW5pdHlcclxuICAgIH07XHJcbiAgICB2YXIgb2Zmc2V0WCA9IDA7XHJcbiAgICB2YXIgb2Zmc2V0WSA9IDA7XHJcblxyXG4gICAgaWYgKHV0aWxzLmlzLm9iamVjdChncmlkLm9mZnNldCkpIHtcclxuICAgICAgb2Zmc2V0WCA9IGdyaWQub2Zmc2V0Lng7XHJcbiAgICAgIG9mZnNldFkgPSBncmlkLm9mZnNldC55O1xyXG4gICAgfVxyXG5cclxuICAgIHZhciBncmlkeCA9IE1hdGgucm91bmQoKHggLSBvZmZzZXRYKSAvIGdyaWQueCk7XHJcbiAgICB2YXIgZ3JpZHkgPSBNYXRoLnJvdW5kKCh5IC0gb2Zmc2V0WSkgLyBncmlkLnkpO1xyXG5cclxuICAgIHZhciBuZXdYID0gTWF0aC5tYXgobGltaXRzLmxlZnQsIE1hdGgubWluKGxpbWl0cy5yaWdodCwgZ3JpZHggKiBncmlkLnggKyBvZmZzZXRYKSk7XHJcbiAgICB2YXIgbmV3WSA9IE1hdGgubWF4KGxpbWl0cy50b3AsIE1hdGgubWluKGxpbWl0cy5ib3R0b20sIGdyaWR5ICogZ3JpZC55ICsgb2Zmc2V0WSkpO1xyXG5cclxuICAgIHJldHVybiB7XHJcbiAgICAgIHg6IG5ld1gsXHJcbiAgICAgIHk6IG5ld1ksXHJcbiAgICAgIHJhbmdlOiBncmlkLnJhbmdlXHJcbiAgICB9O1xyXG4gIH07XHJcbn07XHJcblxyXG5tb2RpZmllcnMuc25hcCA9IHNuYXA7XHJcbm1vZGlmaWVycy5uYW1lcy5wdXNoKCdzbmFwJyk7XHJcblxyXG5kZWZhdWx0T3B0aW9ucy5wZXJBY3Rpb24uc25hcCA9IHNuYXAuZGVmYXVsdHM7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHNuYXA7XHJcblxyXG59LHtcIi4uL2RlZmF1bHRPcHRpb25zXCI6MTgsXCIuLi9pbnRlcmFjdFwiOjIxLFwiLi4vdXRpbHNcIjo0NCxcIi4vaW5kZXhcIjoyNH1dLDI5OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxuLy8gVGhpcyBtb2R1bGUgYWxsb3dzIHNuYXBwaW5nIG9mIHRoZSBzaXplIG9mIHRhcmdldHMgZHVyaW5nIHJlc2l6ZVxyXG4vLyBpbnRlcmFjdGlvbnMuXHJcblxyXG52YXIgbW9kaWZpZXJzID0gcmVxdWlyZSgnLi9pbmRleCcpO1xyXG52YXIgc25hcCA9IHJlcXVpcmUoJy4vc25hcCcpO1xyXG52YXIgZGVmYXVsdE9wdGlvbnMgPSByZXF1aXJlKCcuLi9kZWZhdWx0T3B0aW9ucycpO1xyXG52YXIgcmVzaXplID0gcmVxdWlyZSgnLi4vYWN0aW9ucy9yZXNpemUnKTtcclxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMvJyk7XHJcblxyXG52YXIgc25hcFNpemUgPSB7XHJcbiAgZGVmYXVsdHM6IHtcclxuICAgIGVuYWJsZWQ6IGZhbHNlLFxyXG4gICAgZW5kT25seTogZmFsc2UsXHJcbiAgICByYW5nZTogSW5maW5pdHksXHJcbiAgICB0YXJnZXRzOiBudWxsLFxyXG4gICAgb2Zmc2V0czogbnVsbFxyXG4gIH0sXHJcblxyXG4gIHNldE9mZnNldDogZnVuY3Rpb24gc2V0T2Zmc2V0KGFyZykge1xyXG4gICAgdmFyIGludGVyYWN0aW9uID0gYXJnLmludGVyYWN0aW9uLFxyXG4gICAgICAgIG9wdGlvbnMgPSBhcmcub3B0aW9ucztcclxuXHJcbiAgICB2YXIgZWRnZXMgPSBpbnRlcmFjdGlvbi5wcmVwYXJlZC5lZGdlcztcclxuXHJcbiAgICBpZiAoIWVkZ2VzKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBhcmcub3B0aW9ucyA9IHtcclxuICAgICAgcmVsYXRpdmVQb2ludHM6IFt7XHJcbiAgICAgICAgeDogZWRnZXMubGVmdCA/IDAgOiAxLFxyXG4gICAgICAgIHk6IGVkZ2VzLnRvcCA/IDAgOiAxXHJcbiAgICAgIH1dLFxyXG4gICAgICBvcmlnaW46IHsgeDogMCwgeTogMCB9LFxyXG4gICAgICBvZmZzZXQ6ICdzZWxmJyxcclxuICAgICAgcmFuZ2U6IG9wdGlvbnMucmFuZ2VcclxuICAgIH07XHJcblxyXG4gICAgdmFyIG9mZnNldHMgPSBzbmFwLnNldE9mZnNldChhcmcpO1xyXG4gICAgYXJnLm9wdGlvbnMgPSBvcHRpb25zO1xyXG5cclxuICAgIHJldHVybiBvZmZzZXRzO1xyXG4gIH0sXHJcblxyXG4gIHNldDogZnVuY3Rpb24gc2V0KGFyZykge1xyXG4gICAgdmFyIGludGVyYWN0aW9uID0gYXJnLmludGVyYWN0aW9uLFxyXG4gICAgICAgIG9wdGlvbnMgPSBhcmcub3B0aW9ucyxcclxuICAgICAgICBvZmZzZXQgPSBhcmcub2Zmc2V0LFxyXG4gICAgICAgIHBhZ2VDb29yZHMgPSBhcmcucGFnZUNvb3JkcztcclxuXHJcbiAgICB2YXIgcGFnZSA9IHV0aWxzLmV4dGVuZCh7fSwgcGFnZUNvb3Jkcyk7XHJcbiAgICB2YXIgcmVsYXRpdmVYID0gcGFnZS54IC0gb2Zmc2V0WzBdLng7XHJcbiAgICB2YXIgcmVsYXRpdmVZID0gcGFnZS55IC0gb2Zmc2V0WzBdLnk7XHJcblxyXG4gICAgYXJnLm9wdGlvbnMgPSB1dGlscy5leHRlbmQoe30sIG9wdGlvbnMpO1xyXG4gICAgYXJnLm9wdGlvbnMudGFyZ2V0cyA9IFtdO1xyXG5cclxuICAgIGZvciAodmFyIF9pdGVyYXRvciA9IG9wdGlvbnMudGFyZ2V0cywgX2lzQXJyYXkgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvciksIF9pID0gMCwgX2l0ZXJhdG9yID0gX2lzQXJyYXkgPyBfaXRlcmF0b3IgOiBfaXRlcmF0b3JbU3ltYm9sLml0ZXJhdG9yXSgpOzspIHtcclxuICAgICAgdmFyIF9yZWY7XHJcblxyXG4gICAgICBpZiAoX2lzQXJyYXkpIHtcclxuICAgICAgICBpZiAoX2kgPj0gX2l0ZXJhdG9yLmxlbmd0aCkgYnJlYWs7XHJcbiAgICAgICAgX3JlZiA9IF9pdGVyYXRvcltfaSsrXTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBfaSA9IF9pdGVyYXRvci5uZXh0KCk7XHJcbiAgICAgICAgaWYgKF9pLmRvbmUpIGJyZWFrO1xyXG4gICAgICAgIF9yZWYgPSBfaS52YWx1ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIHNuYXBUYXJnZXQgPSBfcmVmO1xyXG5cclxuICAgICAgdmFyIHRhcmdldCA9IHZvaWQgMDtcclxuXHJcbiAgICAgIGlmICh1dGlscy5pcy5mdW5jdGlvbihzbmFwVGFyZ2V0KSkge1xyXG4gICAgICAgIHRhcmdldCA9IHNuYXBUYXJnZXQocmVsYXRpdmVYLCByZWxhdGl2ZVksIGludGVyYWN0aW9uKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0YXJnZXQgPSBzbmFwVGFyZ2V0O1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoIXRhcmdldCkge1xyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoJ3dpZHRoJyBpbiB0YXJnZXQgJiYgJ2hlaWdodCcgaW4gdGFyZ2V0KSB7XHJcbiAgICAgICAgdGFyZ2V0LnggPSB0YXJnZXQud2lkdGg7XHJcbiAgICAgICAgdGFyZ2V0LnkgPSB0YXJnZXQuaGVpZ2h0O1xyXG4gICAgICB9XHJcblxyXG4gICAgICBhcmcub3B0aW9ucy50YXJnZXRzLnB1c2godGFyZ2V0KTtcclxuICAgIH1cclxuXHJcbiAgICBzbmFwLnNldChhcmcpO1xyXG4gIH0sXHJcblxyXG4gIG1vZGlmeUNvb3JkczogZnVuY3Rpb24gbW9kaWZ5Q29vcmRzKGFyZykge1xyXG4gICAgdmFyIG9wdGlvbnMgPSBhcmcub3B0aW9ucztcclxuXHJcblxyXG4gICAgYXJnLm9wdGlvbnMgPSB1dGlscy5leHRlbmQoe30sIG9wdGlvbnMpO1xyXG4gICAgYXJnLm9wdGlvbnMuZW5hYmxlZCA9IG9wdGlvbnMuZW5hYmxlZDtcclxuICAgIGFyZy5vcHRpb25zLnJlbGF0aXZlUG9pbnRzID0gW251bGxdO1xyXG5cclxuICAgIHNuYXAubW9kaWZ5Q29vcmRzKGFyZyk7XHJcbiAgfVxyXG59O1xyXG5cclxubW9kaWZpZXJzLnNuYXBTaXplID0gc25hcFNpemU7XHJcbm1vZGlmaWVycy5uYW1lcy5wdXNoKCdzbmFwU2l6ZScpO1xyXG5cclxuZGVmYXVsdE9wdGlvbnMucGVyQWN0aW9uLnNuYXBTaXplID0gc25hcFNpemUuZGVmYXVsdHM7XHJcbnJlc2l6ZS5kZWZhdWx0cy5zbmFwU2l6ZSA9IHNuYXBTaXplLmRlZmF1bHRzO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBzbmFwU2l6ZTtcclxuXHJcbn0se1wiLi4vYWN0aW9ucy9yZXNpemVcIjoxMCxcIi4uL2RlZmF1bHRPcHRpb25zXCI6MTgsXCIuLi91dGlscy9cIjo0NCxcIi4vaW5kZXhcIjoyNCxcIi4vc25hcFwiOjI4fV0sMzA6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xyXG4ndXNlIHN0cmljdCc7XHJcblxyXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxyXG5cclxudmFyIHBvaW50ZXJVdGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzL3BvaW50ZXJVdGlscycpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoKSB7XHJcbiAgZnVuY3Rpb24gUG9pbnRlckV2ZW50KHR5cGUsIHBvaW50ZXIsIGV2ZW50LCBldmVudFRhcmdldCwgaW50ZXJhY3Rpb24pIHtcclxuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBQb2ludGVyRXZlbnQpO1xyXG5cclxuICAgIHBvaW50ZXJVdGlscy5wb2ludGVyRXh0ZW5kKHRoaXMsIGV2ZW50KTtcclxuXHJcbiAgICBpZiAoZXZlbnQgIT09IHBvaW50ZXIpIHtcclxuICAgICAgcG9pbnRlclV0aWxzLnBvaW50ZXJFeHRlbmQodGhpcywgcG9pbnRlcik7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5pbnRlcmFjdGlvbiA9IGludGVyYWN0aW9uO1xyXG5cclxuICAgIHRoaXMudGltZVN0YW1wID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XHJcbiAgICB0aGlzLm9yaWdpbmFsRXZlbnQgPSBldmVudDtcclxuICAgIHRoaXMudHlwZSA9IHR5cGU7XHJcbiAgICB0aGlzLnBvaW50ZXJJZCA9IHBvaW50ZXJVdGlscy5nZXRQb2ludGVySWQocG9pbnRlcik7XHJcbiAgICB0aGlzLnBvaW50ZXJUeXBlID0gcG9pbnRlclV0aWxzLmdldFBvaW50ZXJUeXBlKHBvaW50ZXIpO1xyXG4gICAgdGhpcy50YXJnZXQgPSBldmVudFRhcmdldDtcclxuICAgIHRoaXMuY3VycmVudFRhcmdldCA9IG51bGw7XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICd0YXAnKSB7XHJcbiAgICAgIHZhciBwb2ludGVySW5kZXggPSBpbnRlcmFjdGlvbi5nZXRQb2ludGVySW5kZXgocG9pbnRlcik7XHJcbiAgICAgIHRoaXMuZHQgPSB0aGlzLnRpbWVTdGFtcCAtIGludGVyYWN0aW9uLmRvd25UaW1lc1twb2ludGVySW5kZXhdO1xyXG5cclxuICAgICAgdmFyIGludGVydmFsID0gdGhpcy50aW1lU3RhbXAgLSBpbnRlcmFjdGlvbi50YXBUaW1lO1xyXG5cclxuICAgICAgdGhpcy5kb3VibGUgPSAhIShpbnRlcmFjdGlvbi5wcmV2VGFwICYmIGludGVyYWN0aW9uLnByZXZUYXAudHlwZSAhPT0gJ2RvdWJsZXRhcCcgJiYgaW50ZXJhY3Rpb24ucHJldlRhcC50YXJnZXQgPT09IHRoaXMudGFyZ2V0ICYmIGludGVydmFsIDwgNTAwKTtcclxuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2RvdWJsZXRhcCcpIHtcclxuICAgICAgdGhpcy5kdCA9IHBvaW50ZXIudGltZVN0YW1wIC0gaW50ZXJhY3Rpb24udGFwVGltZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIFBvaW50ZXJFdmVudC5wcm90b3R5cGUuc3VidHJhY3RPcmlnaW4gPSBmdW5jdGlvbiBzdWJ0cmFjdE9yaWdpbihfcmVmKSB7XHJcbiAgICB2YXIgb3JpZ2luWCA9IF9yZWYueCxcclxuICAgICAgICBvcmlnaW5ZID0gX3JlZi55O1xyXG5cclxuICAgIHRoaXMucGFnZVggLT0gb3JpZ2luWDtcclxuICAgIHRoaXMucGFnZVkgLT0gb3JpZ2luWTtcclxuICAgIHRoaXMuY2xpZW50WCAtPSBvcmlnaW5YO1xyXG4gICAgdGhpcy5jbGllbnRZIC09IG9yaWdpblk7XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfTtcclxuXHJcbiAgUG9pbnRlckV2ZW50LnByb3RvdHlwZS5hZGRPcmlnaW4gPSBmdW5jdGlvbiBhZGRPcmlnaW4oX3JlZjIpIHtcclxuICAgIHZhciBvcmlnaW5YID0gX3JlZjIueCxcclxuICAgICAgICBvcmlnaW5ZID0gX3JlZjIueTtcclxuXHJcbiAgICB0aGlzLnBhZ2VYICs9IG9yaWdpblg7XHJcbiAgICB0aGlzLnBhZ2VZICs9IG9yaWdpblk7XHJcbiAgICB0aGlzLmNsaWVudFggKz0gb3JpZ2luWDtcclxuICAgIHRoaXMuY2xpZW50WSArPSBvcmlnaW5ZO1xyXG5cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH07XHJcblxyXG4gIFBvaW50ZXJFdmVudC5wcm90b3R5cGUucHJldmVudERlZmF1bHQgPSBmdW5jdGlvbiBwcmV2ZW50RGVmYXVsdCgpIHtcclxuICAgIHRoaXMub3JpZ2luYWxFdmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gIH07XHJcblxyXG4gIFBvaW50ZXJFdmVudC5wcm90b3R5cGUuc3RvcFByb3BhZ2F0aW9uID0gZnVuY3Rpb24gc3RvcFByb3BhZ2F0aW9uKCkge1xyXG4gICAgdGhpcy5wcm9wYWdhdGlvblN0b3BwZWQgPSB0cnVlO1xyXG4gIH07XHJcblxyXG4gIFBvaW50ZXJFdmVudC5wcm90b3R5cGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uID0gZnVuY3Rpb24gc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCkge1xyXG4gICAgdGhpcy5pbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQgPSB0aGlzLnByb3BhZ2F0aW9uU3RvcHBlZCA9IHRydWU7XHJcbiAgfTtcclxuXHJcbiAgcmV0dXJuIFBvaW50ZXJFdmVudDtcclxufSgpO1xyXG5cclxufSx7XCIuLi91dGlscy9wb2ludGVyVXRpbHNcIjo0OX1dLDMxOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIFBvaW50ZXJFdmVudCA9IHJlcXVpcmUoJy4vUG9pbnRlckV2ZW50Jyk7XHJcbnZhciBJbnRlcmFjdGlvbiA9IHJlcXVpcmUoJy4uL0ludGVyYWN0aW9uJyk7XHJcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XHJcbnZhciBicm93c2VyID0gcmVxdWlyZSgnLi4vdXRpbHMvYnJvd3NlcicpO1xyXG52YXIgZGVmYXVsdHMgPSByZXF1aXJlKCcuLi9kZWZhdWx0T3B0aW9ucycpO1xyXG52YXIgc2lnbmFscyA9IHJlcXVpcmUoJy4uL3V0aWxzL1NpZ25hbHMnKS5uZXcoKTtcclxuXHJcbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJy4uL3V0aWxzL2FycicpLFxyXG4gICAgZmlsdGVyID0gX3JlcXVpcmUuZmlsdGVyO1xyXG5cclxudmFyIHNpbXBsZVNpZ25hbHMgPSBbJ2Rvd24nLCAndXAnLCAnY2FuY2VsJ107XHJcbnZhciBzaW1wbGVFdmVudHMgPSBbJ2Rvd24nLCAndXAnLCAnY2FuY2VsJ107XHJcblxyXG52YXIgcG9pbnRlckV2ZW50cyA9IHtcclxuICBQb2ludGVyRXZlbnQ6IFBvaW50ZXJFdmVudCxcclxuICBmaXJlOiBmaXJlLFxyXG4gIGNvbGxlY3RFdmVudFRhcmdldHM6IGNvbGxlY3RFdmVudFRhcmdldHMsXHJcbiAgc2lnbmFsczogc2lnbmFscyxcclxuICBkZWZhdWx0czoge1xyXG4gICAgaG9sZER1cmF0aW9uOiA2MDAsXHJcbiAgICBpZ25vcmVGcm9tOiBudWxsLFxyXG4gICAgYWxsb3dGcm9tOiBudWxsLFxyXG4gICAgb3JpZ2luOiB7IHg6IDAsIHk6IDAgfVxyXG4gIH0sXHJcbiAgdHlwZXM6IFsnZG93bicsICdtb3ZlJywgJ3VwJywgJ2NhbmNlbCcsICd0YXAnLCAnZG91YmxldGFwJywgJ2hvbGQnXVxyXG59O1xyXG5cclxuZnVuY3Rpb24gZmlyZShhcmcpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBhcmcuaW50ZXJhY3Rpb24sXHJcbiAgICAgIHBvaW50ZXIgPSBhcmcucG9pbnRlcixcclxuICAgICAgZXZlbnQgPSBhcmcuZXZlbnQsXHJcbiAgICAgIGV2ZW50VGFyZ2V0ID0gYXJnLmV2ZW50VGFyZ2V0LFxyXG4gICAgICBfYXJnJHR5cGUgPSBhcmcudHlwZSxcclxuICAgICAgdHlwZSA9IF9hcmckdHlwZSA9PT0gdW5kZWZpbmVkID8gYXJnLnBvaW50ZXJFdmVudC50eXBlIDogX2FyZyR0eXBlLFxyXG4gICAgICBfYXJnJHRhcmdldHMgPSBhcmcudGFyZ2V0cyxcclxuICAgICAgdGFyZ2V0cyA9IF9hcmckdGFyZ2V0cyA9PT0gdW5kZWZpbmVkID8gY29sbGVjdEV2ZW50VGFyZ2V0cyhhcmcpIDogX2FyZyR0YXJnZXRzLFxyXG4gICAgICBfYXJnJHBvaW50ZXJFdmVudCA9IGFyZy5wb2ludGVyRXZlbnQsXHJcbiAgICAgIHBvaW50ZXJFdmVudCA9IF9hcmckcG9pbnRlckV2ZW50ID09PSB1bmRlZmluZWQgPyBuZXcgUG9pbnRlckV2ZW50KHR5cGUsIHBvaW50ZXIsIGV2ZW50LCBldmVudFRhcmdldCwgaW50ZXJhY3Rpb24pIDogX2FyZyRwb2ludGVyRXZlbnQ7XHJcblxyXG5cclxuICB2YXIgc2lnbmFsQXJnID0ge1xyXG4gICAgaW50ZXJhY3Rpb246IGludGVyYWN0aW9uLFxyXG4gICAgcG9pbnRlcjogcG9pbnRlcixcclxuICAgIGV2ZW50OiBldmVudCxcclxuICAgIGV2ZW50VGFyZ2V0OiBldmVudFRhcmdldCxcclxuICAgIHRhcmdldHM6IHRhcmdldHMsXHJcbiAgICB0eXBlOiB0eXBlLFxyXG4gICAgcG9pbnRlckV2ZW50OiBwb2ludGVyRXZlbnRcclxuICB9O1xyXG5cclxuICBmb3IgKHZhciBpID0gMDsgaSA8IHRhcmdldHMubGVuZ3RoOyBpKyspIHtcclxuICAgIHZhciB0YXJnZXQgPSB0YXJnZXRzW2ldO1xyXG5cclxuICAgIGZvciAodmFyIHByb3AgaW4gdGFyZ2V0LnByb3BzIHx8IHt9KSB7XHJcbiAgICAgIHBvaW50ZXJFdmVudFtwcm9wXSA9IHRhcmdldC5wcm9wc1twcm9wXTtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgb3JpZ2luID0gdXRpbHMuZ2V0T3JpZ2luWFkodGFyZ2V0LmV2ZW50YWJsZSwgdGFyZ2V0LmVsZW1lbnQpO1xyXG5cclxuICAgIHBvaW50ZXJFdmVudC5zdWJ0cmFjdE9yaWdpbihvcmlnaW4pO1xyXG4gICAgcG9pbnRlckV2ZW50LmV2ZW50YWJsZSA9IHRhcmdldC5ldmVudGFibGU7XHJcbiAgICBwb2ludGVyRXZlbnQuY3VycmVudFRhcmdldCA9IHRhcmdldC5lbGVtZW50O1xyXG5cclxuICAgIHRhcmdldC5ldmVudGFibGUuZmlyZShwb2ludGVyRXZlbnQpO1xyXG5cclxuICAgIHBvaW50ZXJFdmVudC5hZGRPcmlnaW4ob3JpZ2luKTtcclxuXHJcbiAgICBpZiAocG9pbnRlckV2ZW50LmltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZCB8fCBwb2ludGVyRXZlbnQucHJvcGFnYXRpb25TdG9wcGVkICYmIGkgKyAxIDwgdGFyZ2V0cy5sZW5ndGggJiYgdGFyZ2V0c1tpICsgMV0uZWxlbWVudCAhPT0gcG9pbnRlckV2ZW50LmN1cnJlbnRUYXJnZXQpIHtcclxuICAgICAgYnJlYWs7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBzaWduYWxzLmZpcmUoJ2ZpcmVkJywgc2lnbmFsQXJnKTtcclxuXHJcbiAgaWYgKHR5cGUgPT09ICd0YXAnKSB7XHJcbiAgICAvLyBpZiBwb2ludGVyRXZlbnQgc2hvdWxkIG1ha2UgYSBkb3VibGUgdGFwLCBjcmVhdGUgYW5kIGZpcmUgYSBkb3VibGV0YXBcclxuICAgIC8vIFBvaW50ZXJFdmVudCBhbmQgdXNlIHRoYXQgYXMgdGhlIHByZXZUYXBcclxuICAgIHZhciBwcmV2VGFwID0gcG9pbnRlckV2ZW50LmRvdWJsZSA/IGZpcmUoe1xyXG4gICAgICBpbnRlcmFjdGlvbjogaW50ZXJhY3Rpb24sIHBvaW50ZXI6IHBvaW50ZXIsIGV2ZW50OiBldmVudCwgZXZlbnRUYXJnZXQ6IGV2ZW50VGFyZ2V0LFxyXG4gICAgICB0eXBlOiAnZG91YmxldGFwJ1xyXG4gICAgfSkgOiBwb2ludGVyRXZlbnQ7XHJcblxyXG4gICAgaW50ZXJhY3Rpb24ucHJldlRhcCA9IHByZXZUYXA7XHJcbiAgICBpbnRlcmFjdGlvbi50YXBUaW1lID0gcHJldlRhcC50aW1lU3RhbXA7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gcG9pbnRlckV2ZW50O1xyXG59XHJcblxyXG5mdW5jdGlvbiBjb2xsZWN0RXZlbnRUYXJnZXRzKF9yZWYpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmLmludGVyYWN0aW9uLFxyXG4gICAgICBwb2ludGVyID0gX3JlZi5wb2ludGVyLFxyXG4gICAgICBldmVudCA9IF9yZWYuZXZlbnQsXHJcbiAgICAgIGV2ZW50VGFyZ2V0ID0gX3JlZi5ldmVudFRhcmdldCxcclxuICAgICAgdHlwZSA9IF9yZWYudHlwZTtcclxuXHJcbiAgdmFyIHBvaW50ZXJJbmRleCA9IGludGVyYWN0aW9uLmdldFBvaW50ZXJJbmRleChwb2ludGVyKTtcclxuXHJcbiAgLy8gZG8gbm90IGZpcmUgYSB0YXAgZXZlbnQgaWYgdGhlIHBvaW50ZXIgd2FzIG1vdmVkIGJlZm9yZSBiZWluZyBsaWZ0ZWRcclxuICBpZiAodHlwZSA9PT0gJ3RhcCcgJiYgKGludGVyYWN0aW9uLnBvaW50ZXJXYXNNb3ZlZFxyXG4gIC8vIG9yIGlmIHRoZSBwb2ludGVydXAgdGFyZ2V0IGlzIGRpZmZlcmVudCB0byB0aGUgcG9pbnRlcmRvd24gdGFyZ2V0XHJcbiAgfHwgIShpbnRlcmFjdGlvbi5kb3duVGFyZ2V0c1twb2ludGVySW5kZXhdICYmIGludGVyYWN0aW9uLmRvd25UYXJnZXRzW3BvaW50ZXJJbmRleF0gPT09IGV2ZW50VGFyZ2V0KSkpIHtcclxuICAgIHJldHVybiBbXTtcclxuICB9XHJcblxyXG4gIHZhciBwYXRoID0gdXRpbHMuZ2V0UGF0aChldmVudFRhcmdldCk7XHJcbiAgdmFyIHNpZ25hbEFyZyA9IHtcclxuICAgIGludGVyYWN0aW9uOiBpbnRlcmFjdGlvbixcclxuICAgIHBvaW50ZXI6IHBvaW50ZXIsXHJcbiAgICBldmVudDogZXZlbnQsXHJcbiAgICBldmVudFRhcmdldDogZXZlbnRUYXJnZXQsXHJcbiAgICB0eXBlOiB0eXBlLFxyXG4gICAgcGF0aDogcGF0aCxcclxuICAgIHRhcmdldHM6IFtdLFxyXG4gICAgZWxlbWVudDogbnVsbFxyXG4gIH07XHJcblxyXG4gIGZvciAodmFyIF9pdGVyYXRvciA9IHBhdGgsIF9pc0FycmF5ID0gQXJyYXkuaXNBcnJheShfaXRlcmF0b3IpLCBfaSA9IDAsIF9pdGVyYXRvciA9IF9pc0FycmF5ID8gX2l0ZXJhdG9yIDogX2l0ZXJhdG9yW1N5bWJvbC5pdGVyYXRvcl0oKTs7KSB7XHJcbiAgICB2YXIgX3JlZjI7XHJcblxyXG4gICAgaWYgKF9pc0FycmF5KSB7XHJcbiAgICAgIGlmIChfaSA+PSBfaXRlcmF0b3IubGVuZ3RoKSBicmVhaztcclxuICAgICAgX3JlZjIgPSBfaXRlcmF0b3JbX2krK107XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBfaSA9IF9pdGVyYXRvci5uZXh0KCk7XHJcbiAgICAgIGlmIChfaS5kb25lKSBicmVhaztcclxuICAgICAgX3JlZjIgPSBfaS52YWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgZWxlbWVudCA9IF9yZWYyO1xyXG5cclxuICAgIHNpZ25hbEFyZy5lbGVtZW50ID0gZWxlbWVudDtcclxuXHJcbiAgICBzaWduYWxzLmZpcmUoJ2NvbGxlY3QtdGFyZ2V0cycsIHNpZ25hbEFyZyk7XHJcbiAgfVxyXG5cclxuICBpZiAodHlwZSA9PT0gJ2hvbGQnKSB7XHJcbiAgICBzaWduYWxBcmcudGFyZ2V0cyA9IGZpbHRlcihzaWduYWxBcmcudGFyZ2V0cywgZnVuY3Rpb24gKHRhcmdldCkge1xyXG4gICAgICByZXR1cm4gdGFyZ2V0LmV2ZW50YWJsZS5vcHRpb25zLmhvbGREdXJhdGlvbiA9PT0gaW50ZXJhY3Rpb24uaG9sZFRpbWVyc1twb2ludGVySW5kZXhdLmR1cmF0aW9uO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gc2lnbmFsQXJnLnRhcmdldHM7XHJcbn1cclxuXHJcbkludGVyYWN0aW9uLnNpZ25hbHMub24oJ3VwZGF0ZS1wb2ludGVyLWRvd24nLCBmdW5jdGlvbiAoX3JlZjMpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmMy5pbnRlcmFjdGlvbixcclxuICAgICAgcG9pbnRlckluZGV4ID0gX3JlZjMucG9pbnRlckluZGV4O1xyXG5cclxuICBpbnRlcmFjdGlvbi5ob2xkVGltZXJzW3BvaW50ZXJJbmRleF0gPSB7IGR1cmF0aW9uOiBJbmZpbml0eSwgdGltZW91dDogbnVsbCB9O1xyXG59KTtcclxuXHJcbkludGVyYWN0aW9uLnNpZ25hbHMub24oJ3JlbW92ZS1wb2ludGVyJywgZnVuY3Rpb24gKF9yZWY0KSB7XHJcbiAgdmFyIGludGVyYWN0aW9uID0gX3JlZjQuaW50ZXJhY3Rpb24sXHJcbiAgICAgIHBvaW50ZXJJbmRleCA9IF9yZWY0LnBvaW50ZXJJbmRleDtcclxuXHJcbiAgaW50ZXJhY3Rpb24uaG9sZFRpbWVycy5zcGxpY2UocG9pbnRlckluZGV4LCAxKTtcclxufSk7XHJcblxyXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdtb3ZlJywgZnVuY3Rpb24gKF9yZWY1KSB7XHJcbiAgdmFyIGludGVyYWN0aW9uID0gX3JlZjUuaW50ZXJhY3Rpb24sXHJcbiAgICAgIHBvaW50ZXIgPSBfcmVmNS5wb2ludGVyLFxyXG4gICAgICBldmVudCA9IF9yZWY1LmV2ZW50LFxyXG4gICAgICBldmVudFRhcmdldCA9IF9yZWY1LmV2ZW50VGFyZ2V0LFxyXG4gICAgICBkdXBsaWNhdGVNb3ZlID0gX3JlZjUuZHVwbGljYXRlTW92ZTtcclxuXHJcbiAgdmFyIHBvaW50ZXJJbmRleCA9IGludGVyYWN0aW9uLmdldFBvaW50ZXJJbmRleChwb2ludGVyKTtcclxuXHJcbiAgaWYgKCFkdXBsaWNhdGVNb3ZlICYmICghaW50ZXJhY3Rpb24ucG9pbnRlcklzRG93biB8fCBpbnRlcmFjdGlvbi5wb2ludGVyV2FzTW92ZWQpKSB7XHJcbiAgICBpZiAoaW50ZXJhY3Rpb24ucG9pbnRlcklzRG93bikge1xyXG4gICAgICBjbGVhclRpbWVvdXQoaW50ZXJhY3Rpb24uaG9sZFRpbWVyc1twb2ludGVySW5kZXhdLnRpbWVvdXQpO1xyXG4gICAgfVxyXG5cclxuICAgIGZpcmUoe1xyXG4gICAgICBpbnRlcmFjdGlvbjogaW50ZXJhY3Rpb24sIHBvaW50ZXI6IHBvaW50ZXIsIGV2ZW50OiBldmVudCwgZXZlbnRUYXJnZXQ6IGV2ZW50VGFyZ2V0LFxyXG4gICAgICB0eXBlOiAnbW92ZSdcclxuICAgIH0pO1xyXG4gIH1cclxufSk7XHJcblxyXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdkb3duJywgZnVuY3Rpb24gKF9yZWY2KSB7XHJcbiAgdmFyIGludGVyYWN0aW9uID0gX3JlZjYuaW50ZXJhY3Rpb24sXHJcbiAgICAgIHBvaW50ZXIgPSBfcmVmNi5wb2ludGVyLFxyXG4gICAgICBldmVudCA9IF9yZWY2LmV2ZW50LFxyXG4gICAgICBldmVudFRhcmdldCA9IF9yZWY2LmV2ZW50VGFyZ2V0LFxyXG4gICAgICBwb2ludGVySW5kZXggPSBfcmVmNi5wb2ludGVySW5kZXg7XHJcblxyXG4gIC8vIGNvcHkgZXZlbnQgdG8gYmUgdXNlZCBpbiB0aW1lb3V0IGZvciBJRThcclxuICB2YXIgZXZlbnRDb3B5ID0gYnJvd3Nlci5pc0lFOCA/IHV0aWxzLmV4dGVuZCh7fSwgZXZlbnQpIDogZXZlbnQ7XHJcblxyXG4gIHZhciB0aW1lciA9IGludGVyYWN0aW9uLmhvbGRUaW1lcnNbcG9pbnRlckluZGV4XTtcclxuICB2YXIgcGF0aCA9IHV0aWxzLmdldFBhdGgoZXZlbnRUYXJnZXQpO1xyXG4gIHZhciBzaWduYWxBcmcgPSB7XHJcbiAgICBpbnRlcmFjdGlvbjogaW50ZXJhY3Rpb24sXHJcbiAgICBwb2ludGVyOiBwb2ludGVyLFxyXG4gICAgZXZlbnQ6IGV2ZW50LFxyXG4gICAgZXZlbnRUYXJnZXQ6IGV2ZW50VGFyZ2V0LFxyXG4gICAgdHlwZTogJ2hvbGQnLFxyXG4gICAgdGFyZ2V0czogW10sXHJcbiAgICBwYXRoOiBwYXRoLFxyXG4gICAgZWxlbWVudDogbnVsbFxyXG4gIH07XHJcblxyXG4gIGZvciAodmFyIF9pdGVyYXRvcjIgPSBwYXRoLCBfaXNBcnJheTIgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvcjIpLCBfaTIgPSAwLCBfaXRlcmF0b3IyID0gX2lzQXJyYXkyID8gX2l0ZXJhdG9yMiA6IF9pdGVyYXRvcjJbU3ltYm9sLml0ZXJhdG9yXSgpOzspIHtcclxuICAgIHZhciBfcmVmNztcclxuXHJcbiAgICBpZiAoX2lzQXJyYXkyKSB7XHJcbiAgICAgIGlmIChfaTIgPj0gX2l0ZXJhdG9yMi5sZW5ndGgpIGJyZWFrO1xyXG4gICAgICBfcmVmNyA9IF9pdGVyYXRvcjJbX2kyKytdO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgX2kyID0gX2l0ZXJhdG9yMi5uZXh0KCk7XHJcbiAgICAgIGlmIChfaTIuZG9uZSkgYnJlYWs7XHJcbiAgICAgIF9yZWY3ID0gX2kyLnZhbHVlO1xyXG4gICAgfVxyXG5cclxuICAgIHZhciBlbGVtZW50ID0gX3JlZjc7XHJcblxyXG4gICAgc2lnbmFsQXJnLmVsZW1lbnQgPSBlbGVtZW50O1xyXG5cclxuICAgIHNpZ25hbHMuZmlyZSgnY29sbGVjdC10YXJnZXRzJywgc2lnbmFsQXJnKTtcclxuICB9XHJcblxyXG4gIGlmICghc2lnbmFsQXJnLnRhcmdldHMubGVuZ3RoKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICB2YXIgbWluRHVyYXRpb24gPSBJbmZpbml0eTtcclxuXHJcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzaWduYWxBcmcudGFyZ2V0cy5sZW5ndGg7IGkrKykge1xyXG4gICAgdmFyIHRhcmdldCA9IHNpZ25hbEFyZy50YXJnZXRzW2ldO1xyXG4gICAgdmFyIGhvbGREdXJhdGlvbiA9IHRhcmdldC5ldmVudGFibGUub3B0aW9ucy5ob2xkRHVyYXRpb247XHJcblxyXG4gICAgaWYgKGhvbGREdXJhdGlvbiA8IG1pbkR1cmF0aW9uKSB7XHJcbiAgICAgIG1pbkR1cmF0aW9uID0gaG9sZER1cmF0aW9uO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgdGltZXIuZHVyYXRpb24gPSBtaW5EdXJhdGlvbjtcclxuICB0aW1lci50aW1lb3V0ID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICBmaXJlKHtcclxuICAgICAgaW50ZXJhY3Rpb246IGludGVyYWN0aW9uLFxyXG4gICAgICBldmVudFRhcmdldDogZXZlbnRUYXJnZXQsXHJcbiAgICAgIHBvaW50ZXI6IGJyb3dzZXIuaXNJRTggPyBldmVudENvcHkgOiBwb2ludGVyLFxyXG4gICAgICBldmVudDogZXZlbnRDb3B5LFxyXG4gICAgICB0eXBlOiAnaG9sZCdcclxuICAgIH0pO1xyXG4gIH0sIG1pbkR1cmF0aW9uKTtcclxufSk7XHJcblxyXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCd1cCcsIGZ1bmN0aW9uIChfcmVmOCkge1xyXG4gIHZhciBpbnRlcmFjdGlvbiA9IF9yZWY4LmludGVyYWN0aW9uLFxyXG4gICAgICBwb2ludGVyID0gX3JlZjgucG9pbnRlcixcclxuICAgICAgZXZlbnQgPSBfcmVmOC5ldmVudCxcclxuICAgICAgZXZlbnRUYXJnZXQgPSBfcmVmOC5ldmVudFRhcmdldDtcclxuXHJcbiAgaWYgKCFpbnRlcmFjdGlvbi5wb2ludGVyV2FzTW92ZWQpIHtcclxuICAgIGZpcmUoeyBpbnRlcmFjdGlvbjogaW50ZXJhY3Rpb24sIGV2ZW50VGFyZ2V0OiBldmVudFRhcmdldCwgcG9pbnRlcjogcG9pbnRlciwgZXZlbnQ6IGV2ZW50LCB0eXBlOiAndGFwJyB9KTtcclxuICB9XHJcbn0pO1xyXG5cclxuWyd1cCcsICdjYW5jZWwnXS5mb3JFYWNoKGZ1bmN0aW9uIChzaWduYWxOYW1lKSB7XHJcbiAgSW50ZXJhY3Rpb24uc2lnbmFscy5vbihzaWduYWxOYW1lLCBmdW5jdGlvbiAoX3JlZjkpIHtcclxuICAgIHZhciBpbnRlcmFjdGlvbiA9IF9yZWY5LmludGVyYWN0aW9uLFxyXG4gICAgICAgIHBvaW50ZXJJbmRleCA9IF9yZWY5LnBvaW50ZXJJbmRleDtcclxuXHJcbiAgICBpZiAoaW50ZXJhY3Rpb24uaG9sZFRpbWVyc1twb2ludGVySW5kZXhdKSB7XHJcbiAgICAgIGNsZWFyVGltZW91dChpbnRlcmFjdGlvbi5ob2xkVGltZXJzW3BvaW50ZXJJbmRleF0udGltZW91dCk7XHJcbiAgICB9XHJcbiAgfSk7XHJcbn0pO1xyXG5cclxuZnVuY3Rpb24gY3JlYXRlU2lnbmFsTGlzdGVuZXIodHlwZSkge1xyXG4gIHJldHVybiBmdW5jdGlvbiAoX3JlZjEwKSB7XHJcbiAgICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmMTAuaW50ZXJhY3Rpb24sXHJcbiAgICAgICAgcG9pbnRlciA9IF9yZWYxMC5wb2ludGVyLFxyXG4gICAgICAgIGV2ZW50ID0gX3JlZjEwLmV2ZW50LFxyXG4gICAgICAgIGV2ZW50VGFyZ2V0ID0gX3JlZjEwLmV2ZW50VGFyZ2V0O1xyXG5cclxuICAgIGZpcmUoeyBpbnRlcmFjdGlvbjogaW50ZXJhY3Rpb24sIGV2ZW50VGFyZ2V0OiBldmVudFRhcmdldCwgcG9pbnRlcjogcG9pbnRlciwgZXZlbnQ6IGV2ZW50LCB0eXBlOiB0eXBlIH0pO1xyXG4gIH07XHJcbn1cclxuXHJcbmZvciAodmFyIGkgPSAwOyBpIDwgc2ltcGxlU2lnbmFscy5sZW5ndGg7IGkrKykge1xyXG4gIEludGVyYWN0aW9uLnNpZ25hbHMub24oc2ltcGxlU2lnbmFsc1tpXSwgY3JlYXRlU2lnbmFsTGlzdGVuZXIoc2ltcGxlRXZlbnRzW2ldKSk7XHJcbn1cclxuXHJcbkludGVyYWN0aW9uLnNpZ25hbHMub24oJ25ldycsIGZ1bmN0aW9uIChpbnRlcmFjdGlvbikge1xyXG4gIGludGVyYWN0aW9uLnByZXZUYXAgPSBudWxsOyAvLyB0aGUgbW9zdCByZWNlbnQgdGFwIGV2ZW50IG9uIHRoaXMgaW50ZXJhY3Rpb25cclxuICBpbnRlcmFjdGlvbi50YXBUaW1lID0gMDsgLy8gdGltZSBvZiB0aGUgbW9zdCByZWNlbnQgdGFwIGV2ZW50XHJcbiAgaW50ZXJhY3Rpb24uaG9sZFRpbWVycyA9IFtdOyAvLyBbeyBkdXJhdGlvbiwgdGltZW91dCB9XVxyXG59KTtcclxuXHJcbmRlZmF1bHRzLnBvaW50ZXJFdmVudHMgPSBwb2ludGVyRXZlbnRzLmRlZmF1bHRzO1xyXG5tb2R1bGUuZXhwb3J0cyA9IHBvaW50ZXJFdmVudHM7XHJcblxyXG59LHtcIi4uL0ludGVyYWN0aW9uXCI6NSxcIi4uL2RlZmF1bHRPcHRpb25zXCI6MTgsXCIuLi91dGlsc1wiOjQ0LFwiLi4vdXRpbHMvU2lnbmFsc1wiOjM1LFwiLi4vdXRpbHMvYXJyXCI6MzYsXCIuLi91dGlscy9icm93c2VyXCI6MzcsXCIuL1BvaW50ZXJFdmVudFwiOjMwfV0sMzI6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xyXG4ndXNlIHN0cmljdCc7XHJcblxyXG52YXIgcG9pbnRlckV2ZW50cyA9IHJlcXVpcmUoJy4vYmFzZScpO1xyXG52YXIgSW50ZXJhY3Rpb24gPSByZXF1aXJlKCcuLi9JbnRlcmFjdGlvbicpO1xyXG5cclxucG9pbnRlckV2ZW50cy5zaWduYWxzLm9uKCduZXcnLCBvbk5ldyk7XHJcbnBvaW50ZXJFdmVudHMuc2lnbmFscy5vbignZmlyZWQnLCBvbkZpcmVkKTtcclxuXHJcbnZhciBfYXJyID0gWydtb3ZlJywgJ3VwJywgJ2NhbmNlbCcsICdlbmRhbGwnXTtcclxuZm9yICh2YXIgX2kgPSAwOyBfaSA8IF9hcnIubGVuZ3RoOyBfaSsrKSB7XHJcbiAgdmFyIHNpZ25hbCA9IF9hcnJbX2ldO1xyXG4gIEludGVyYWN0aW9uLnNpZ25hbHMub24oc2lnbmFsLCBlbmRIb2xkUmVwZWF0KTtcclxufVxyXG5cclxuZnVuY3Rpb24gb25OZXcoX3JlZikge1xyXG4gIHZhciBwb2ludGVyRXZlbnQgPSBfcmVmLnBvaW50ZXJFdmVudDtcclxuXHJcbiAgaWYgKHBvaW50ZXJFdmVudC50eXBlICE9PSAnaG9sZCcpIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIHBvaW50ZXJFdmVudC5jb3VudCA9IChwb2ludGVyRXZlbnQuY291bnQgfHwgMCkgKyAxO1xyXG59XHJcblxyXG5mdW5jdGlvbiBvbkZpcmVkKF9yZWYyKSB7XHJcbiAgdmFyIGludGVyYWN0aW9uID0gX3JlZjIuaW50ZXJhY3Rpb24sXHJcbiAgICAgIHBvaW50ZXJFdmVudCA9IF9yZWYyLnBvaW50ZXJFdmVudCxcclxuICAgICAgZXZlbnRUYXJnZXQgPSBfcmVmMi5ldmVudFRhcmdldCxcclxuICAgICAgdGFyZ2V0cyA9IF9yZWYyLnRhcmdldHM7XHJcblxyXG4gIGlmIChwb2ludGVyRXZlbnQudHlwZSAhPT0gJ2hvbGQnIHx8ICF0YXJnZXRzLmxlbmd0aCkge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgLy8gZ2V0IHRoZSByZXBlYXQgaW50ZXJ2YWwgZnJvbSB0aGUgZmlyc3QgZXZlbnRhYmxlXHJcbiAgdmFyIGludGVydmFsID0gdGFyZ2V0c1swXS5ldmVudGFibGUub3B0aW9ucy5ob2xkUmVwZWF0SW50ZXJ2YWw7XHJcblxyXG4gIC8vIGRvbid0IHJlcGVhdCBpZiB0aGUgaW50ZXJ2YWwgaXMgMCBvciBsZXNzXHJcbiAgaWYgKGludGVydmFsIDw9IDApIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIC8vIHNldCBhIHRpbWVvdXQgdG8gZmlyZSB0aGUgaG9sZHJlcGVhdCBldmVudFxyXG4gIGludGVyYWN0aW9uLmhvbGRJbnRlcnZhbEhhbmRsZSA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG4gICAgcG9pbnRlckV2ZW50cy5maXJlKHtcclxuICAgICAgaW50ZXJhY3Rpb246IGludGVyYWN0aW9uLFxyXG4gICAgICBldmVudFRhcmdldDogZXZlbnRUYXJnZXQsXHJcbiAgICAgIHR5cGU6ICdob2xkJyxcclxuICAgICAgcG9pbnRlcjogcG9pbnRlckV2ZW50LFxyXG4gICAgICBldmVudDogcG9pbnRlckV2ZW50XHJcbiAgICB9KTtcclxuICB9LCBpbnRlcnZhbCk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGVuZEhvbGRSZXBlYXQoX3JlZjMpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmMy5pbnRlcmFjdGlvbjtcclxuXHJcbiAgLy8gc2V0IHRoZSBpbnRlcmFjdGlvbidzIGhvbGRTdG9wVGltZSBwcm9wZXJ0eVxyXG4gIC8vIHRvIHN0b3AgZnVydGhlciBob2xkUmVwZWF0IGV2ZW50c1xyXG4gIGlmIChpbnRlcmFjdGlvbi5ob2xkSW50ZXJ2YWxIYW5kbGUpIHtcclxuICAgIGNsZWFySW50ZXJ2YWwoaW50ZXJhY3Rpb24uaG9sZEludGVydmFsSGFuZGxlKTtcclxuICAgIGludGVyYWN0aW9uLmhvbGRJbnRlcnZhbEhhbmRsZSA9IG51bGw7XHJcbiAgfVxyXG59XHJcblxyXG4vLyBkb24ndCByZXBlYXQgYnkgZGVmYXVsdFxyXG5wb2ludGVyRXZlbnRzLmRlZmF1bHRzLmhvbGRSZXBlYXRJbnRlcnZhbCA9IDA7XHJcbnBvaW50ZXJFdmVudHMudHlwZXMucHVzaCgnaG9sZHJlcGVhdCcpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSB7XHJcbiAgb25OZXc6IG9uTmV3LFxyXG4gIG9uRmlyZWQ6IG9uRmlyZWQsXHJcbiAgZW5kSG9sZFJlcGVhdDogZW5kSG9sZFJlcGVhdFxyXG59O1xyXG5cclxufSx7XCIuLi9JbnRlcmFjdGlvblwiOjUsXCIuL2Jhc2VcIjozMX1dLDMzOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIHBvaW50ZXJFdmVudHMgPSByZXF1aXJlKCcuL2Jhc2UnKTtcclxudmFyIEludGVyYWN0YWJsZSA9IHJlcXVpcmUoJy4uL0ludGVyYWN0YWJsZScpO1xyXG52YXIgYnJvd3NlciA9IHJlcXVpcmUoJy4uL3V0aWxzL2Jyb3dzZXInKTtcclxudmFyIGlzID0gcmVxdWlyZSgnLi4vdXRpbHMvaXMnKTtcclxudmFyIGRvbVV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMvZG9tVXRpbHMnKTtcclxudmFyIHNjb3BlID0gcmVxdWlyZSgnLi4vc2NvcGUnKTtcclxudmFyIGV4dGVuZCA9IHJlcXVpcmUoJy4uL3V0aWxzL2V4dGVuZCcpO1xyXG5cclxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnLi4vdXRpbHMvYXJyJyksXHJcbiAgICBtZXJnZSA9IF9yZXF1aXJlLm1lcmdlO1xyXG5cclxucG9pbnRlckV2ZW50cy5zaWduYWxzLm9uKCdjb2xsZWN0LXRhcmdldHMnLCBmdW5jdGlvbiAoX3JlZikge1xyXG4gIHZhciB0YXJnZXRzID0gX3JlZi50YXJnZXRzLFxyXG4gICAgICBlbGVtZW50ID0gX3JlZi5lbGVtZW50LFxyXG4gICAgICB0eXBlID0gX3JlZi50eXBlLFxyXG4gICAgICBldmVudFRhcmdldCA9IF9yZWYuZXZlbnRUYXJnZXQ7XHJcblxyXG4gIGZ1bmN0aW9uIGNvbGxlY3RTZWxlY3RvcnMoaW50ZXJhY3RhYmxlLCBzZWxlY3RvciwgY29udGV4dCkge1xyXG4gICAgdmFyIGVscyA9IGJyb3dzZXIudXNlTWF0Y2hlc1NlbGVjdG9yUG9seWZpbGwgPyBjb250ZXh0LnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpIDogdW5kZWZpbmVkO1xyXG5cclxuICAgIHZhciBldmVudGFibGUgPSBpbnRlcmFjdGFibGUuZXZlbnRzO1xyXG4gICAgdmFyIG9wdGlvbnMgPSBldmVudGFibGUub3B0aW9ucztcclxuXHJcbiAgICBpZiAoZXZlbnRhYmxlW3R5cGVdICYmIGlzLmVsZW1lbnQoZWxlbWVudCkgJiYgZG9tVXRpbHMubWF0Y2hlc1NlbGVjdG9yKGVsZW1lbnQsIHNlbGVjdG9yLCBlbHMpICYmIGludGVyYWN0YWJsZS50ZXN0SWdub3JlQWxsb3cob3B0aW9ucywgZWxlbWVudCwgZXZlbnRUYXJnZXQpKSB7XHJcblxyXG4gICAgICB0YXJnZXRzLnB1c2goe1xyXG4gICAgICAgIGVsZW1lbnQ6IGVsZW1lbnQsXHJcbiAgICAgICAgZXZlbnRhYmxlOiBldmVudGFibGUsXHJcbiAgICAgICAgcHJvcHM6IHsgaW50ZXJhY3RhYmxlOiBpbnRlcmFjdGFibGUgfVxyXG4gICAgICB9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHZhciBpbnRlcmFjdGFibGUgPSBzY29wZS5pbnRlcmFjdGFibGVzLmdldChlbGVtZW50KTtcclxuXHJcbiAgaWYgKGludGVyYWN0YWJsZSkge1xyXG4gICAgdmFyIGV2ZW50YWJsZSA9IGludGVyYWN0YWJsZS5ldmVudHM7XHJcbiAgICB2YXIgb3B0aW9ucyA9IGV2ZW50YWJsZS5vcHRpb25zO1xyXG5cclxuICAgIGlmIChldmVudGFibGVbdHlwZV0gJiYgaW50ZXJhY3RhYmxlLnRlc3RJZ25vcmVBbGxvdyhvcHRpb25zLCBlbGVtZW50LCBldmVudFRhcmdldCkpIHtcclxuICAgICAgdGFyZ2V0cy5wdXNoKHtcclxuICAgICAgICBlbGVtZW50OiBlbGVtZW50LFxyXG4gICAgICAgIGV2ZW50YWJsZTogZXZlbnRhYmxlLFxyXG4gICAgICAgIHByb3BzOiB7IGludGVyYWN0YWJsZTogaW50ZXJhY3RhYmxlIH1cclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBzY29wZS5pbnRlcmFjdGFibGVzLmZvckVhY2hTZWxlY3Rvcihjb2xsZWN0U2VsZWN0b3JzLCBlbGVtZW50KTtcclxufSk7XHJcblxyXG5JbnRlcmFjdGFibGUuc2lnbmFscy5vbignbmV3JywgZnVuY3Rpb24gKF9yZWYyKSB7XHJcbiAgdmFyIGludGVyYWN0YWJsZSA9IF9yZWYyLmludGVyYWN0YWJsZTtcclxuXHJcbiAgaW50ZXJhY3RhYmxlLmV2ZW50cy5nZXRSZWN0ID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcclxuICAgIHJldHVybiBpbnRlcmFjdGFibGUuZ2V0UmVjdChlbGVtZW50KTtcclxuICB9O1xyXG59KTtcclxuXHJcbkludGVyYWN0YWJsZS5zaWduYWxzLm9uKCdzZXQnLCBmdW5jdGlvbiAoX3JlZjMpIHtcclxuICB2YXIgaW50ZXJhY3RhYmxlID0gX3JlZjMuaW50ZXJhY3RhYmxlLFxyXG4gICAgICBvcHRpb25zID0gX3JlZjMub3B0aW9ucztcclxuXHJcbiAgZXh0ZW5kKGludGVyYWN0YWJsZS5ldmVudHMub3B0aW9ucywgcG9pbnRlckV2ZW50cy5kZWZhdWx0cyk7XHJcbiAgZXh0ZW5kKGludGVyYWN0YWJsZS5ldmVudHMub3B0aW9ucywgb3B0aW9ucyk7XHJcbn0pO1xyXG5cclxubWVyZ2UoSW50ZXJhY3RhYmxlLmV2ZW50VHlwZXMsIHBvaW50ZXJFdmVudHMudHlwZXMpO1xyXG5cclxuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5wb2ludGVyRXZlbnRzID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcclxuICBleHRlbmQodGhpcy5ldmVudHMub3B0aW9ucywgb3B0aW9ucyk7XHJcblxyXG4gIHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxudmFyIF9fYmFja0NvbXBhdE9wdGlvbiA9IEludGVyYWN0YWJsZS5wcm90b3R5cGUuX2JhY2tDb21wYXRPcHRpb247XHJcblxyXG5JbnRlcmFjdGFibGUucHJvdG90eXBlLl9iYWNrQ29tcGF0T3B0aW9uID0gZnVuY3Rpb24gKG9wdGlvbk5hbWUsIG5ld1ZhbHVlKSB7XHJcbiAgdmFyIHJldCA9IF9fYmFja0NvbXBhdE9wdGlvbi5jYWxsKHRoaXMsIG9wdGlvbk5hbWUsIG5ld1ZhbHVlKTtcclxuXHJcbiAgaWYgKHJldCA9PT0gdGhpcykge1xyXG4gICAgdGhpcy5ldmVudHMub3B0aW9uc1tvcHRpb25OYW1lXSA9IG5ld1ZhbHVlO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIHJldDtcclxufTtcclxuXHJcbkludGVyYWN0YWJsZS5zZXR0aW5nc01ldGhvZHMucHVzaCgncG9pbnRlckV2ZW50cycpO1xyXG5cclxufSx7XCIuLi9JbnRlcmFjdGFibGVcIjo0LFwiLi4vc2NvcGVcIjozNCxcIi4uL3V0aWxzL2FyclwiOjM2LFwiLi4vdXRpbHMvYnJvd3NlclwiOjM3LFwiLi4vdXRpbHMvZG9tVXRpbHNcIjozOSxcIi4uL3V0aWxzL2V4dGVuZFwiOjQxLFwiLi4vdXRpbHMvaXNcIjo0NixcIi4vYmFzZVwiOjMxfV0sMzQ6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xyXG4ndXNlIHN0cmljdCc7XHJcblxyXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XHJcbnZhciBldmVudHMgPSByZXF1aXJlKCcuL3V0aWxzL2V2ZW50cycpO1xyXG52YXIgc2lnbmFscyA9IHJlcXVpcmUoJy4vdXRpbHMvU2lnbmFscycpLm5ldygpO1xyXG5cclxudmFyIHNjb3BlID0ge1xyXG4gIHNpZ25hbHM6IHNpZ25hbHMsXHJcbiAgZXZlbnRzOiBldmVudHMsXHJcbiAgdXRpbHM6IHV0aWxzLFxyXG5cclxuICAvLyBtYWluIGRvY3VtZW50XHJcbiAgZG9jdW1lbnQ6IHJlcXVpcmUoJy4vdXRpbHMvZG9tT2JqZWN0cycpLmRvY3VtZW50LFxyXG4gIC8vIGFsbCBkb2N1bWVudHMgYmVpbmcgbGlzdGVuZWQgdG9cclxuICBkb2N1bWVudHM6IFtdLFxyXG5cclxuICBhZGREb2N1bWVudDogZnVuY3Rpb24gYWRkRG9jdW1lbnQoZG9jLCB3aW4pIHtcclxuICAgIC8vIGRvIG5vdGhpbmcgaWYgZG9jdW1lbnQgaXMgYWxyZWFkeSBrbm93blxyXG4gICAgaWYgKHV0aWxzLmNvbnRhaW5zKHNjb3BlLmRvY3VtZW50cywgZG9jKSkge1xyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgd2luID0gd2luIHx8IHNjb3BlLmdldFdpbmRvdyhkb2MpO1xyXG5cclxuICAgIHNjb3BlLmRvY3VtZW50cy5wdXNoKGRvYyk7XHJcbiAgICBldmVudHMuZG9jdW1lbnRzLnB1c2goZG9jKTtcclxuXHJcbiAgICAvLyBkb24ndCBhZGQgYW4gdW5sb2FkIGV2ZW50IGZvciB0aGUgbWFpbiBkb2N1bWVudFxyXG4gICAgLy8gc28gdGhhdCB0aGUgcGFnZSBtYXkgYmUgY2FjaGVkIGluIGJyb3dzZXIgaGlzdG9yeVxyXG4gICAgaWYgKGRvYyAhPT0gc2NvcGUuZG9jdW1lbnQpIHtcclxuICAgICAgZXZlbnRzLmFkZCh3aW4sICd1bmxvYWQnLCBzY29wZS5vbldpbmRvd1VubG9hZCk7XHJcbiAgICB9XHJcblxyXG4gICAgc2lnbmFscy5maXJlKCdhZGQtZG9jdW1lbnQnLCB7IGRvYzogZG9jLCB3aW46IHdpbiB9KTtcclxuICB9LFxyXG5cclxuICByZW1vdmVEb2N1bWVudDogZnVuY3Rpb24gcmVtb3ZlRG9jdW1lbnQoZG9jLCB3aW4pIHtcclxuICAgIHZhciBpbmRleCA9IHV0aWxzLmluZGV4T2Yoc2NvcGUuZG9jdW1lbnRzLCBkb2MpO1xyXG5cclxuICAgIHdpbiA9IHdpbiB8fCBzY29wZS5nZXRXaW5kb3coZG9jKTtcclxuXHJcbiAgICBldmVudHMucmVtb3ZlKHdpbiwgJ3VubG9hZCcsIHNjb3BlLm9uV2luZG93VW5sb2FkKTtcclxuXHJcbiAgICBzY29wZS5kb2N1bWVudHMuc3BsaWNlKGluZGV4LCAxKTtcclxuICAgIGV2ZW50cy5kb2N1bWVudHMuc3BsaWNlKGluZGV4LCAxKTtcclxuXHJcbiAgICBzaWduYWxzLmZpcmUoJ3JlbW92ZS1kb2N1bWVudCcsIHsgd2luOiB3aW4sIGRvYzogZG9jIH0pO1xyXG4gIH0sXHJcblxyXG4gIG9uV2luZG93VW5sb2FkOiBmdW5jdGlvbiBvbldpbmRvd1VubG9hZCgpIHtcclxuICAgIHNjb3BlLnJlbW92ZURvY3VtZW50KHRoaXMuZG9jdW1lbnQsIHRoaXMpO1xyXG4gIH1cclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gc2NvcGU7XHJcblxyXG59LHtcIi4vdXRpbHNcIjo0NCxcIi4vdXRpbHMvU2lnbmFsc1wiOjM1LFwiLi91dGlscy9kb21PYmplY3RzXCI6MzgsXCIuL3V0aWxzL2V2ZW50c1wiOjQwfV0sMzU6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xyXG4ndXNlIHN0cmljdCc7XHJcblxyXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxyXG5cclxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnLi9hcnInKSxcclxuICAgIGluZGV4T2YgPSBfcmVxdWlyZS5pbmRleE9mO1xyXG5cclxudmFyIFNpZ25hbHMgPSBmdW5jdGlvbiAoKSB7XHJcbiAgZnVuY3Rpb24gU2lnbmFscygpIHtcclxuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBTaWduYWxzKTtcclxuXHJcbiAgICB0aGlzLmxpc3RlbmVycyA9IHtcclxuICAgICAgLy8gc2lnbmFsTmFtZTogW2xpc3RlbmVyc10sXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgU2lnbmFscy5wcm90b3R5cGUub24gPSBmdW5jdGlvbiBvbihuYW1lLCBsaXN0ZW5lcikge1xyXG4gICAgaWYgKCF0aGlzLmxpc3RlbmVyc1tuYW1lXSkge1xyXG4gICAgICB0aGlzLmxpc3RlbmVyc1tuYW1lXSA9IFtsaXN0ZW5lcl07XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLmxpc3RlbmVyc1tuYW1lXS5wdXNoKGxpc3RlbmVyKTtcclxuICB9O1xyXG5cclxuICBTaWduYWxzLnByb3RvdHlwZS5vZmYgPSBmdW5jdGlvbiBvZmYobmFtZSwgbGlzdGVuZXIpIHtcclxuICAgIGlmICghdGhpcy5saXN0ZW5lcnNbbmFtZV0pIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHZhciBpbmRleCA9IGluZGV4T2YodGhpcy5saXN0ZW5lcnNbbmFtZV0sIGxpc3RlbmVyKTtcclxuXHJcbiAgICBpZiAoaW5kZXggIT09IC0xKSB7XHJcbiAgICAgIHRoaXMubGlzdGVuZXJzW25hbWVdLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgU2lnbmFscy5wcm90b3R5cGUuZmlyZSA9IGZ1bmN0aW9uIGZpcmUobmFtZSwgYXJnKSB7XHJcbiAgICB2YXIgdGFyZ2V0TGlzdGVuZXJzID0gdGhpcy5saXN0ZW5lcnNbbmFtZV07XHJcblxyXG4gICAgaWYgKCF0YXJnZXRMaXN0ZW5lcnMpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGFyZ2V0TGlzdGVuZXJzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgIGlmICh0YXJnZXRMaXN0ZW5lcnNbaV0oYXJnLCBuYW1lKSA9PT0gZmFsc2UpIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9O1xyXG5cclxuICByZXR1cm4gU2lnbmFscztcclxufSgpO1xyXG5cclxuU2lnbmFscy5uZXcgPSBmdW5jdGlvbiAoKSB7XHJcbiAgcmV0dXJuIG5ldyBTaWduYWxzKCk7XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IFNpZ25hbHM7XHJcblxyXG59LHtcIi4vYXJyXCI6MzZ9XSwzNjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcblwidXNlIHN0cmljdFwiO1xyXG5cclxuZnVuY3Rpb24gaW5kZXhPZihhcnJheSwgdGFyZ2V0KSB7XHJcbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGFycmF5Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICBpZiAoYXJyYXlbaV0gPT09IHRhcmdldCkge1xyXG4gICAgICByZXR1cm4gaTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHJldHVybiAtMTtcclxufVxyXG5cclxuZnVuY3Rpb24gY29udGFpbnMoYXJyYXksIHRhcmdldCkge1xyXG4gIHJldHVybiBpbmRleE9mKGFycmF5LCB0YXJnZXQpICE9PSAtMTtcclxufVxyXG5cclxuZnVuY3Rpb24gbWVyZ2UodGFyZ2V0LCBzb3VyY2UpIHtcclxuICBmb3IgKHZhciBpID0gMDsgaSA8IHNvdXJjZS5sZW5ndGg7IGkrKykge1xyXG4gICAgdGFyZ2V0LnB1c2goc291cmNlW2ldKTtcclxuICB9XHJcblxyXG4gIHJldHVybiB0YXJnZXQ7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGZpbHRlcihhcnJheSwgdGVzdCkge1xyXG4gIHZhciByZXN1bHQgPSBbXTtcclxuXHJcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykge1xyXG4gICAgaWYgKHRlc3QoYXJyYXlbaV0pKSB7XHJcbiAgICAgIHJlc3VsdC5wdXNoKGFycmF5W2ldKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0ge1xyXG4gIGluZGV4T2Y6IGluZGV4T2YsXHJcbiAgY29udGFpbnM6IGNvbnRhaW5zLFxyXG4gIG1lcmdlOiBtZXJnZSxcclxuICBmaWx0ZXI6IGZpbHRlclxyXG59O1xyXG5cclxufSx7fV0sMzc6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xyXG4ndXNlIHN0cmljdCc7XHJcblxyXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCcuL3dpbmRvdycpLFxyXG4gICAgd2luZG93ID0gX3JlcXVpcmUud2luZG93O1xyXG5cclxudmFyIGlzID0gcmVxdWlyZSgnLi9pcycpO1xyXG52YXIgZG9tT2JqZWN0cyA9IHJlcXVpcmUoJy4vZG9tT2JqZWN0cycpO1xyXG5cclxudmFyIEVsZW1lbnQgPSBkb21PYmplY3RzLkVsZW1lbnQ7XHJcbnZhciBuYXZpZ2F0b3IgPSB3aW5kb3cubmF2aWdhdG9yO1xyXG5cclxudmFyIGJyb3dzZXIgPSB7XHJcbiAgLy8gRG9lcyB0aGUgYnJvd3NlciBzdXBwb3J0IHRvdWNoIGlucHV0P1xyXG4gIHN1cHBvcnRzVG91Y2g6ICEhKCdvbnRvdWNoc3RhcnQnIGluIHdpbmRvdyB8fCBpcy5mdW5jdGlvbih3aW5kb3cuRG9jdW1lbnRUb3VjaCkgJiYgZG9tT2JqZWN0cy5kb2N1bWVudCBpbnN0YW5jZW9mIHdpbmRvdy5Eb2N1bWVudFRvdWNoKSxcclxuXHJcbiAgLy8gRG9lcyB0aGUgYnJvd3NlciBzdXBwb3J0IFBvaW50ZXJFdmVudHNcclxuICBzdXBwb3J0c1BvaW50ZXJFdmVudDogISFkb21PYmplY3RzLlBvaW50ZXJFdmVudCxcclxuXHJcbiAgaXNJRTg6ICdhdHRhY2hFdmVudCcgaW4gd2luZG93ICYmICEoJ2FkZEV2ZW50TGlzdGVuZXInIGluIHdpbmRvdyksXHJcblxyXG4gIC8vIE9wZXJhIE1vYmlsZSBtdXN0IGJlIGhhbmRsZWQgZGlmZmVyZW50bHlcclxuICBpc09wZXJhTW9iaWxlOiBuYXZpZ2F0b3IuYXBwTmFtZSA9PT0gJ09wZXJhJyAmJiBicm93c2VyLnN1cHBvcnRzVG91Y2ggJiYgbmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgnUHJlc3RvJyksXHJcblxyXG4gIC8vIHNjcm9sbGluZyBkb2Vzbid0IGNoYW5nZSB0aGUgcmVzdWx0IG9mIGdldENsaWVudFJlY3RzIG9uIGlPUyA3XHJcbiAgaXNJT1M3OiAvaVAoaG9uZXxvZHxhZCkvLnRlc3QobmF2aWdhdG9yLnBsYXRmb3JtKSAmJiAvT1MgN1teXFxkXS8udGVzdChuYXZpZ2F0b3IuYXBwVmVyc2lvbiksXHJcblxyXG4gIGlzSWU5T3JPbGRlcjogL01TSUUgKDh8OSkvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCksXHJcblxyXG4gIC8vIHByZWZpeCBtYXRjaGVzU2VsZWN0b3JcclxuICBwcmVmaXhlZE1hdGNoZXNTZWxlY3RvcjogJ21hdGNoZXMnIGluIEVsZW1lbnQucHJvdG90eXBlID8gJ21hdGNoZXMnIDogJ3dlYmtpdE1hdGNoZXNTZWxlY3RvcicgaW4gRWxlbWVudC5wcm90b3R5cGUgPyAnd2Via2l0TWF0Y2hlc1NlbGVjdG9yJyA6ICdtb3pNYXRjaGVzU2VsZWN0b3InIGluIEVsZW1lbnQucHJvdG90eXBlID8gJ21vek1hdGNoZXNTZWxlY3RvcicgOiAnb01hdGNoZXNTZWxlY3RvcicgaW4gRWxlbWVudC5wcm90b3R5cGUgPyAnb01hdGNoZXNTZWxlY3RvcicgOiAnbXNNYXRjaGVzU2VsZWN0b3InLFxyXG5cclxuICB1c2VNYXRjaGVzU2VsZWN0b3JQb2x5ZmlsbDogZmFsc2UsXHJcblxyXG4gIHBFdmVudFR5cGVzOiBkb21PYmplY3RzLlBvaW50ZXJFdmVudCA/IGRvbU9iamVjdHMuUG9pbnRlckV2ZW50ID09PSB3aW5kb3cuTVNQb2ludGVyRXZlbnQgPyB7XHJcbiAgICB1cDogJ01TUG9pbnRlclVwJyxcclxuICAgIGRvd246ICdNU1BvaW50ZXJEb3duJyxcclxuICAgIG92ZXI6ICdtb3VzZW92ZXInLFxyXG4gICAgb3V0OiAnbW91c2VvdXQnLFxyXG4gICAgbW92ZTogJ01TUG9pbnRlck1vdmUnLFxyXG4gICAgY2FuY2VsOiAnTVNQb2ludGVyQ2FuY2VsJ1xyXG4gIH0gOiB7XHJcbiAgICB1cDogJ3BvaW50ZXJ1cCcsXHJcbiAgICBkb3duOiAncG9pbnRlcmRvd24nLFxyXG4gICAgb3ZlcjogJ3BvaW50ZXJvdmVyJyxcclxuICAgIG91dDogJ3BvaW50ZXJvdXQnLFxyXG4gICAgbW92ZTogJ3BvaW50ZXJtb3ZlJyxcclxuICAgIGNhbmNlbDogJ3BvaW50ZXJjYW5jZWwnXHJcbiAgfSA6IG51bGwsXHJcblxyXG4gIC8vIGJlY2F1c2UgV2Via2l0IGFuZCBPcGVyYSBzdGlsbCB1c2UgJ21vdXNld2hlZWwnIGV2ZW50IHR5cGVcclxuICB3aGVlbEV2ZW50OiAnb25tb3VzZXdoZWVsJyBpbiBkb21PYmplY3RzLmRvY3VtZW50ID8gJ21vdXNld2hlZWwnIDogJ3doZWVsJ1xyXG5cclxufTtcclxuXHJcbmJyb3dzZXIudXNlTWF0Y2hlc1NlbGVjdG9yUG9seWZpbGwgPSAhaXMuZnVuY3Rpb24oRWxlbWVudC5wcm90b3R5cGVbYnJvd3Nlci5wcmVmaXhlZE1hdGNoZXNTZWxlY3Rvcl0pO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBicm93c2VyO1xyXG5cclxufSx7XCIuL2RvbU9iamVjdHNcIjozOCxcIi4vaXNcIjo0NixcIi4vd2luZG93XCI6NTJ9XSwzODpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBkb21PYmplY3RzID0ge307XHJcbnZhciB3aW4gPSByZXF1aXJlKCcuL3dpbmRvdycpLndpbmRvdztcclxuXHJcbmZ1bmN0aW9uIGJsYW5rKCkge31cclxuXHJcbmRvbU9iamVjdHMuZG9jdW1lbnQgPSB3aW4uZG9jdW1lbnQ7XHJcbmRvbU9iamVjdHMuRG9jdW1lbnRGcmFnbWVudCA9IHdpbi5Eb2N1bWVudEZyYWdtZW50IHx8IGJsYW5rO1xyXG5kb21PYmplY3RzLlNWR0VsZW1lbnQgPSB3aW4uU1ZHRWxlbWVudCB8fCBibGFuaztcclxuZG9tT2JqZWN0cy5TVkdTVkdFbGVtZW50ID0gd2luLlNWR1NWR0VsZW1lbnQgfHwgYmxhbms7XHJcbmRvbU9iamVjdHMuU1ZHRWxlbWVudEluc3RhbmNlID0gd2luLlNWR0VsZW1lbnRJbnN0YW5jZSB8fCBibGFuaztcclxuZG9tT2JqZWN0cy5FbGVtZW50ID0gd2luLkVsZW1lbnQgfHwgYmxhbms7XHJcbmRvbU9iamVjdHMuSFRNTEVsZW1lbnQgPSB3aW4uSFRNTEVsZW1lbnQgfHwgZG9tT2JqZWN0cy5FbGVtZW50O1xyXG5cclxuZG9tT2JqZWN0cy5FdmVudCA9IHdpbi5FdmVudDtcclxuZG9tT2JqZWN0cy5Ub3VjaCA9IHdpbi5Ub3VjaCB8fCBibGFuaztcclxuZG9tT2JqZWN0cy5Qb2ludGVyRXZlbnQgPSB3aW4uUG9pbnRlckV2ZW50IHx8IHdpbi5NU1BvaW50ZXJFdmVudDtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZG9tT2JqZWN0cztcclxuXHJcbn0se1wiLi93aW5kb3dcIjo1Mn1dLDM5OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIHdpbiA9IHJlcXVpcmUoJy4vd2luZG93Jyk7XHJcbnZhciBicm93c2VyID0gcmVxdWlyZSgnLi9icm93c2VyJyk7XHJcbnZhciBpcyA9IHJlcXVpcmUoJy4vaXMnKTtcclxudmFyIGRvbU9iamVjdHMgPSByZXF1aXJlKCcuL2RvbU9iamVjdHMnKTtcclxuXHJcbnZhciBkb21VdGlscyA9IHtcclxuICBub2RlQ29udGFpbnM6IGZ1bmN0aW9uIG5vZGVDb250YWlucyhwYXJlbnQsIGNoaWxkKSB7XHJcbiAgICB3aGlsZSAoY2hpbGQpIHtcclxuICAgICAgaWYgKGNoaWxkID09PSBwYXJlbnQpIHtcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgY2hpbGQgPSBjaGlsZC5wYXJlbnROb2RlO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBmYWxzZTtcclxuICB9LFxyXG5cclxuICBjbG9zZXN0OiBmdW5jdGlvbiBjbG9zZXN0KGVsZW1lbnQsIHNlbGVjdG9yKSB7XHJcbiAgICB3aGlsZSAoaXMuZWxlbWVudChlbGVtZW50KSkge1xyXG4gICAgICBpZiAoZG9tVXRpbHMubWF0Y2hlc1NlbGVjdG9yKGVsZW1lbnQsIHNlbGVjdG9yKSkge1xyXG4gICAgICAgIHJldHVybiBlbGVtZW50O1xyXG4gICAgICB9XHJcblxyXG4gICAgICBlbGVtZW50ID0gZG9tVXRpbHMucGFyZW50Tm9kZShlbGVtZW50KTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gbnVsbDtcclxuICB9LFxyXG5cclxuICBwYXJlbnROb2RlOiBmdW5jdGlvbiBwYXJlbnROb2RlKG5vZGUpIHtcclxuICAgIHZhciBwYXJlbnQgPSBub2RlLnBhcmVudE5vZGU7XHJcblxyXG4gICAgaWYgKGlzLmRvY0ZyYWcocGFyZW50KSkge1xyXG4gICAgICAvLyBza2lwIHBhc3QgI3NoYWRvLXJvb3QgZnJhZ21lbnRzXHJcbiAgICAgIHdoaWxlICgocGFyZW50ID0gcGFyZW50Lmhvc3QpICYmIGlzLmRvY0ZyYWcocGFyZW50KSkge1xyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gcGFyZW50O1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBwYXJlbnQ7XHJcbiAgfSxcclxuXHJcbiAgLy8gdGFrZW4gZnJvbSBodHRwOi8vdGFuYWxpbi5jb20vZW4vYmxvZy8yMDEyLzEyL21hdGNoZXMtc2VsZWN0b3ItaWU4LyBhbmQgbW9kaWZpZWRcclxuICBtYXRjaGVzU2VsZWN0b3JQb2x5ZmlsbDogYnJvd3Nlci51c2VNYXRjaGVzU2VsZWN0b3JQb2x5ZmlsbCA/IGZ1bmN0aW9uIChlbGVtZW50LCBzZWxlY3RvciwgZWxlbXMpIHtcclxuICAgIGVsZW1zID0gZWxlbXMgfHwgZWxlbWVudC5wYXJlbnROb2RlLnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpO1xyXG5cclxuICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBlbGVtcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICBpZiAoZWxlbXNbaV0gPT09IGVsZW1lbnQpIHtcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBmYWxzZTtcclxuICB9IDogbnVsbCxcclxuXHJcbiAgbWF0Y2hlc1NlbGVjdG9yOiBmdW5jdGlvbiBtYXRjaGVzU2VsZWN0b3IoZWxlbWVudCwgc2VsZWN0b3IsIG5vZGVMaXN0KSB7XHJcbiAgICBpZiAoYnJvd3Nlci51c2VNYXRjaGVzU2VsZWN0b3JQb2x5ZmlsbCkge1xyXG4gICAgICByZXR1cm4gZG9tVXRpbHMubWF0Y2hlc1NlbGVjdG9yUG9seWZpbGwoZWxlbWVudCwgc2VsZWN0b3IsIG5vZGVMaXN0KTtcclxuICAgIH1cclxuXHJcbiAgICAvLyByZW1vdmUgL2RlZXAvIGZyb20gc2VsZWN0b3JzIGlmIHNoYWRvd0RPTSBwb2x5ZmlsbCBpcyB1c2VkXHJcbiAgICBpZiAod2luLndpbmRvdyAhPT0gd2luLnJlYWxXaW5kb3cpIHtcclxuICAgICAgc2VsZWN0b3IgPSBzZWxlY3Rvci5yZXBsYWNlKC9cXC9kZWVwXFwvL2csICcgJyk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGVsZW1lbnRbYnJvd3Nlci5wcmVmaXhlZE1hdGNoZXNTZWxlY3Rvcl0oc2VsZWN0b3IpO1xyXG4gIH0sXHJcblxyXG4gIC8vIFRlc3QgZm9yIHRoZSBlbGVtZW50IHRoYXQncyBcImFib3ZlXCIgYWxsIG90aGVyIHF1YWxpZmllcnNcclxuICBpbmRleE9mRGVlcGVzdEVsZW1lbnQ6IGZ1bmN0aW9uIGluZGV4T2ZEZWVwZXN0RWxlbWVudChlbGVtZW50cykge1xyXG4gICAgdmFyIGRlZXBlc3Rab25lUGFyZW50cyA9IFtdO1xyXG4gICAgdmFyIGRyb3B6b25lUGFyZW50cyA9IFtdO1xyXG4gICAgdmFyIGRyb3B6b25lID0gdm9pZCAwO1xyXG4gICAgdmFyIGRlZXBlc3Rab25lID0gZWxlbWVudHNbMF07XHJcbiAgICB2YXIgaW5kZXggPSBkZWVwZXN0Wm9uZSA/IDAgOiAtMTtcclxuICAgIHZhciBwYXJlbnQgPSB2b2lkIDA7XHJcbiAgICB2YXIgY2hpbGQgPSB2b2lkIDA7XHJcbiAgICB2YXIgaSA9IHZvaWQgMDtcclxuICAgIHZhciBuID0gdm9pZCAwO1xyXG5cclxuICAgIGZvciAoaSA9IDE7IGkgPCBlbGVtZW50cy5sZW5ndGg7IGkrKykge1xyXG4gICAgICBkcm9wem9uZSA9IGVsZW1lbnRzW2ldO1xyXG5cclxuICAgICAgLy8gYW4gZWxlbWVudCBtaWdodCBiZWxvbmcgdG8gbXVsdGlwbGUgc2VsZWN0b3IgZHJvcHpvbmVzXHJcbiAgICAgIGlmICghZHJvcHpvbmUgfHwgZHJvcHpvbmUgPT09IGRlZXBlc3Rab25lKSB7XHJcbiAgICAgICAgY29udGludWU7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmICghZGVlcGVzdFpvbmUpIHtcclxuICAgICAgICBkZWVwZXN0Wm9uZSA9IGRyb3B6b25lO1xyXG4gICAgICAgIGluZGV4ID0gaTtcclxuICAgICAgICBjb250aW51ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gY2hlY2sgaWYgdGhlIGRlZXBlc3Qgb3IgY3VycmVudCBhcmUgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50IG9yIGRvY3VtZW50LnJvb3RFbGVtZW50XHJcbiAgICAgIC8vIC0gaWYgdGhlIGN1cnJlbnQgZHJvcHpvbmUgaXMsIGRvIG5vdGhpbmcgYW5kIGNvbnRpbnVlXHJcbiAgICAgIGlmIChkcm9wem9uZS5wYXJlbnROb2RlID09PSBkcm9wem9uZS5vd25lckRvY3VtZW50KSB7XHJcbiAgICAgICAgY29udGludWU7XHJcbiAgICAgIH1cclxuICAgICAgLy8gLSBpZiBkZWVwZXN0IGlzLCB1cGRhdGUgd2l0aCB0aGUgY3VycmVudCBkcm9wem9uZSBhbmQgY29udGludWUgdG8gbmV4dFxyXG4gICAgICBlbHNlIGlmIChkZWVwZXN0Wm9uZS5wYXJlbnROb2RlID09PSBkcm9wem9uZS5vd25lckRvY3VtZW50KSB7XHJcbiAgICAgICAgICBkZWVwZXN0Wm9uZSA9IGRyb3B6b25lO1xyXG4gICAgICAgICAgaW5kZXggPSBpO1xyXG4gICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgaWYgKCFkZWVwZXN0Wm9uZVBhcmVudHMubGVuZ3RoKSB7XHJcbiAgICAgICAgcGFyZW50ID0gZGVlcGVzdFpvbmU7XHJcbiAgICAgICAgd2hpbGUgKHBhcmVudC5wYXJlbnROb2RlICYmIHBhcmVudC5wYXJlbnROb2RlICE9PSBwYXJlbnQub3duZXJEb2N1bWVudCkge1xyXG4gICAgICAgICAgZGVlcGVzdFpvbmVQYXJlbnRzLnVuc2hpZnQocGFyZW50KTtcclxuICAgICAgICAgIHBhcmVudCA9IHBhcmVudC5wYXJlbnROb2RlO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gaWYgdGhpcyBlbGVtZW50IGlzIGFuIHN2ZyBlbGVtZW50IGFuZCB0aGUgY3VycmVudCBkZWVwZXN0IGlzXHJcbiAgICAgIC8vIGFuIEhUTUxFbGVtZW50XHJcbiAgICAgIGlmIChkZWVwZXN0Wm9uZSBpbnN0YW5jZW9mIGRvbU9iamVjdHMuSFRNTEVsZW1lbnQgJiYgZHJvcHpvbmUgaW5zdGFuY2VvZiBkb21PYmplY3RzLlNWR0VsZW1lbnQgJiYgIShkcm9wem9uZSBpbnN0YW5jZW9mIGRvbU9iamVjdHMuU1ZHU1ZHRWxlbWVudCkpIHtcclxuXHJcbiAgICAgICAgaWYgKGRyb3B6b25lID09PSBkZWVwZXN0Wm9uZS5wYXJlbnROb2RlKSB7XHJcbiAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHBhcmVudCA9IGRyb3B6b25lLm93bmVyU1ZHRWxlbWVudDtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBwYXJlbnQgPSBkcm9wem9uZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgZHJvcHpvbmVQYXJlbnRzID0gW107XHJcblxyXG4gICAgICB3aGlsZSAocGFyZW50LnBhcmVudE5vZGUgIT09IHBhcmVudC5vd25lckRvY3VtZW50KSB7XHJcbiAgICAgICAgZHJvcHpvbmVQYXJlbnRzLnVuc2hpZnQocGFyZW50KTtcclxuICAgICAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50Tm9kZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgbiA9IDA7XHJcblxyXG4gICAgICAvLyBnZXQgKHBvc2l0aW9uIG9mIGxhc3QgY29tbW9uIGFuY2VzdG9yKSArIDFcclxuICAgICAgd2hpbGUgKGRyb3B6b25lUGFyZW50c1tuXSAmJiBkcm9wem9uZVBhcmVudHNbbl0gPT09IGRlZXBlc3Rab25lUGFyZW50c1tuXSkge1xyXG4gICAgICAgIG4rKztcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIHBhcmVudHMgPSBbZHJvcHpvbmVQYXJlbnRzW24gLSAxXSwgZHJvcHpvbmVQYXJlbnRzW25dLCBkZWVwZXN0Wm9uZVBhcmVudHNbbl1dO1xyXG5cclxuICAgICAgY2hpbGQgPSBwYXJlbnRzWzBdLmxhc3RDaGlsZDtcclxuXHJcbiAgICAgIHdoaWxlIChjaGlsZCkge1xyXG4gICAgICAgIGlmIChjaGlsZCA9PT0gcGFyZW50c1sxXSkge1xyXG4gICAgICAgICAgZGVlcGVzdFpvbmUgPSBkcm9wem9uZTtcclxuICAgICAgICAgIGluZGV4ID0gaTtcclxuICAgICAgICAgIGRlZXBlc3Rab25lUGFyZW50cyA9IFtdO1xyXG5cclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoY2hpbGQgPT09IHBhcmVudHNbMl0pIHtcclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY2hpbGQgPSBjaGlsZC5wcmV2aW91c1NpYmxpbmc7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gaW5kZXg7XHJcbiAgfSxcclxuXHJcbiAgbWF0Y2hlc1VwVG86IGZ1bmN0aW9uIG1hdGNoZXNVcFRvKGVsZW1lbnQsIHNlbGVjdG9yLCBsaW1pdCkge1xyXG4gICAgd2hpbGUgKGlzLmVsZW1lbnQoZWxlbWVudCkpIHtcclxuICAgICAgaWYgKGRvbVV0aWxzLm1hdGNoZXNTZWxlY3RvcihlbGVtZW50LCBzZWxlY3RvcikpIHtcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgZWxlbWVudCA9IGRvbVV0aWxzLnBhcmVudE5vZGUoZWxlbWVudCk7XHJcblxyXG4gICAgICBpZiAoZWxlbWVudCA9PT0gbGltaXQpIHtcclxuICAgICAgICByZXR1cm4gZG9tVXRpbHMubWF0Y2hlc1NlbGVjdG9yKGVsZW1lbnQsIHNlbGVjdG9yKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBmYWxzZTtcclxuICB9LFxyXG5cclxuICBnZXRBY3R1YWxFbGVtZW50OiBmdW5jdGlvbiBnZXRBY3R1YWxFbGVtZW50KGVsZW1lbnQpIHtcclxuICAgIHJldHVybiBlbGVtZW50IGluc3RhbmNlb2YgZG9tT2JqZWN0cy5TVkdFbGVtZW50SW5zdGFuY2UgPyBlbGVtZW50LmNvcnJlc3BvbmRpbmdVc2VFbGVtZW50IDogZWxlbWVudDtcclxuICB9LFxyXG5cclxuICBnZXRTY3JvbGxYWTogZnVuY3Rpb24gZ2V0U2Nyb2xsWFkocmVsZXZhbnRXaW5kb3cpIHtcclxuICAgIHJlbGV2YW50V2luZG93ID0gcmVsZXZhbnRXaW5kb3cgfHwgd2luLndpbmRvdztcclxuICAgIHJldHVybiB7XHJcbiAgICAgIHg6IHJlbGV2YW50V2luZG93LnNjcm9sbFggfHwgcmVsZXZhbnRXaW5kb3cuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbExlZnQsXHJcbiAgICAgIHk6IHJlbGV2YW50V2luZG93LnNjcm9sbFkgfHwgcmVsZXZhbnRXaW5kb3cuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcFxyXG4gICAgfTtcclxuICB9LFxyXG5cclxuICBnZXRFbGVtZW50Q2xpZW50UmVjdDogZnVuY3Rpb24gZ2V0RWxlbWVudENsaWVudFJlY3QoZWxlbWVudCkge1xyXG4gICAgdmFyIGNsaWVudFJlY3QgPSBlbGVtZW50IGluc3RhbmNlb2YgZG9tT2JqZWN0cy5TVkdFbGVtZW50ID8gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSA6IGVsZW1lbnQuZ2V0Q2xpZW50UmVjdHMoKVswXTtcclxuXHJcbiAgICByZXR1cm4gY2xpZW50UmVjdCAmJiB7XHJcbiAgICAgIGxlZnQ6IGNsaWVudFJlY3QubGVmdCxcclxuICAgICAgcmlnaHQ6IGNsaWVudFJlY3QucmlnaHQsXHJcbiAgICAgIHRvcDogY2xpZW50UmVjdC50b3AsXHJcbiAgICAgIGJvdHRvbTogY2xpZW50UmVjdC5ib3R0b20sXHJcbiAgICAgIHdpZHRoOiBjbGllbnRSZWN0LndpZHRoIHx8IGNsaWVudFJlY3QucmlnaHQgLSBjbGllbnRSZWN0LmxlZnQsXHJcbiAgICAgIGhlaWdodDogY2xpZW50UmVjdC5oZWlnaHQgfHwgY2xpZW50UmVjdC5ib3R0b20gLSBjbGllbnRSZWN0LnRvcFxyXG4gICAgfTtcclxuICB9LFxyXG5cclxuICBnZXRFbGVtZW50UmVjdDogZnVuY3Rpb24gZ2V0RWxlbWVudFJlY3QoZWxlbWVudCkge1xyXG4gICAgdmFyIGNsaWVudFJlY3QgPSBkb21VdGlscy5nZXRFbGVtZW50Q2xpZW50UmVjdChlbGVtZW50KTtcclxuXHJcbiAgICBpZiAoIWJyb3dzZXIuaXNJT1M3ICYmIGNsaWVudFJlY3QpIHtcclxuICAgICAgdmFyIHNjcm9sbCA9IGRvbVV0aWxzLmdldFNjcm9sbFhZKHdpbi5nZXRXaW5kb3coZWxlbWVudCkpO1xyXG5cclxuICAgICAgY2xpZW50UmVjdC5sZWZ0ICs9IHNjcm9sbC54O1xyXG4gICAgICBjbGllbnRSZWN0LnJpZ2h0ICs9IHNjcm9sbC54O1xyXG4gICAgICBjbGllbnRSZWN0LnRvcCArPSBzY3JvbGwueTtcclxuICAgICAgY2xpZW50UmVjdC5ib3R0b20gKz0gc2Nyb2xsLnk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGNsaWVudFJlY3Q7XHJcbiAgfSxcclxuXHJcbiAgZ2V0UGF0aDogZnVuY3Rpb24gZ2V0UGF0aChlbGVtZW50KSB7XHJcbiAgICB2YXIgcGF0aCA9IFtdO1xyXG5cclxuICAgIHdoaWxlIChlbGVtZW50KSB7XHJcbiAgICAgIHBhdGgucHVzaChlbGVtZW50KTtcclxuICAgICAgZWxlbWVudCA9IGRvbVV0aWxzLnBhcmVudE5vZGUoZWxlbWVudCk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHBhdGg7XHJcbiAgfSxcclxuXHJcbiAgdHJ5U2VsZWN0b3I6IGZ1bmN0aW9uIHRyeVNlbGVjdG9yKHZhbHVlKSB7XHJcbiAgICBpZiAoIWlzLnN0cmluZyh2YWx1ZSkpIHtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGFuIGV4Y2VwdGlvbiB3aWxsIGJlIHJhaXNlZCBpZiBpdCBpcyBpbnZhbGlkXHJcbiAgICBkb21PYmplY3RzLmRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodmFsdWUpO1xyXG4gICAgcmV0dXJuIHRydWU7XHJcbiAgfVxyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBkb21VdGlscztcclxuXHJcbn0se1wiLi9icm93c2VyXCI6MzcsXCIuL2RvbU9iamVjdHNcIjozOCxcIi4vaXNcIjo0NixcIi4vd2luZG93XCI6NTJ9XSw0MDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBpcyA9IHJlcXVpcmUoJy4vaXMnKTtcclxudmFyIGRvbVV0aWxzID0gcmVxdWlyZSgnLi9kb21VdGlscycpO1xyXG52YXIgcEV4dGVuZCA9IHJlcXVpcmUoJy4vcG9pbnRlckV4dGVuZCcpO1xyXG5cclxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnLi93aW5kb3cnKSxcclxuICAgIHdpbmRvdyA9IF9yZXF1aXJlLndpbmRvdyxcclxuICAgIGdldFdpbmRvdyA9IF9yZXF1aXJlLmdldFdpbmRvdztcclxuXHJcbnZhciBfcmVxdWlyZTIgPSByZXF1aXJlKCcuL2FycicpLFxyXG4gICAgaW5kZXhPZiA9IF9yZXF1aXJlMi5pbmRleE9mLFxyXG4gICAgY29udGFpbnMgPSBfcmVxdWlyZTIuY29udGFpbnM7XHJcblxyXG52YXIgdXNlQXR0YWNoRXZlbnQgPSAnYXR0YWNoRXZlbnQnIGluIHdpbmRvdyAmJiAhKCdhZGRFdmVudExpc3RlbmVyJyBpbiB3aW5kb3cpO1xyXG52YXIgYWRkRXZlbnQgPSB1c2VBdHRhY2hFdmVudCA/ICdhdHRhY2hFdmVudCcgOiAnYWRkRXZlbnRMaXN0ZW5lcic7XHJcbnZhciByZW1vdmVFdmVudCA9IHVzZUF0dGFjaEV2ZW50ID8gJ2RldGFjaEV2ZW50JyA6ICdyZW1vdmVFdmVudExpc3RlbmVyJztcclxudmFyIG9uID0gdXNlQXR0YWNoRXZlbnQgPyAnb24nIDogJyc7XHJcblxyXG52YXIgZWxlbWVudHMgPSBbXTtcclxudmFyIHRhcmdldHMgPSBbXTtcclxudmFyIGF0dGFjaGVkTGlzdGVuZXJzID0gW107XHJcblxyXG4vLyB7XHJcbi8vICAgdHlwZToge1xyXG4vLyAgICAgc2VsZWN0b3JzOiBbJ3NlbGVjdG9yJywgLi4uXSxcclxuLy8gICAgIGNvbnRleHRzIDogW2RvY3VtZW50LCAuLi5dLFxyXG4vLyAgICAgbGlzdGVuZXJzOiBbW2xpc3RlbmVyLCBjYXB0dXJlLCBwYXNzaXZlXSwgLi4uXVxyXG4vLyAgIH1cclxuLy8gIH1cclxudmFyIGRlbGVnYXRlZEV2ZW50cyA9IHt9O1xyXG5cclxudmFyIGRvY3VtZW50cyA9IFtdO1xyXG5cclxudmFyIHN1cHBvcnRzT3B0aW9ucyA9ICF1c2VBdHRhY2hFdmVudCAmJiBmdW5jdGlvbiAoKSB7XHJcbiAgdmFyIHN1cHBvcnRlZCA9IGZhbHNlO1xyXG5cclxuICB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JykuYWRkRXZlbnRMaXN0ZW5lcigndGVzdCcsIG51bGwsIHtcclxuICAgIGdldCBjYXB0dXJlKCkge1xyXG4gICAgICBzdXBwb3J0ZWQgPSB0cnVlO1xyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuICByZXR1cm4gc3VwcG9ydGVkO1xyXG59KCk7XHJcblxyXG5mdW5jdGlvbiBhZGQoZWxlbWVudCwgdHlwZSwgbGlzdGVuZXIsIG9wdGlvbmFsQXJnKSB7XHJcbiAgdmFyIG9wdGlvbnMgPSBnZXRPcHRpb25zKG9wdGlvbmFsQXJnKTtcclxuICB2YXIgZWxlbWVudEluZGV4ID0gaW5kZXhPZihlbGVtZW50cywgZWxlbWVudCk7XHJcbiAgdmFyIHRhcmdldCA9IHRhcmdldHNbZWxlbWVudEluZGV4XTtcclxuXHJcbiAgaWYgKCF0YXJnZXQpIHtcclxuICAgIHRhcmdldCA9IHtcclxuICAgICAgZXZlbnRzOiB7fSxcclxuICAgICAgdHlwZUNvdW50OiAwXHJcbiAgICB9O1xyXG5cclxuICAgIGVsZW1lbnRJbmRleCA9IGVsZW1lbnRzLnB1c2goZWxlbWVudCkgLSAxO1xyXG4gICAgdGFyZ2V0cy5wdXNoKHRhcmdldCk7XHJcblxyXG4gICAgYXR0YWNoZWRMaXN0ZW5lcnMucHVzaCh1c2VBdHRhY2hFdmVudCA/IHtcclxuICAgICAgc3VwcGxpZWQ6IFtdLFxyXG4gICAgICB3cmFwcGVkOiBbXSxcclxuICAgICAgdXNlQ291bnQ6IFtdXHJcbiAgICB9IDogbnVsbCk7XHJcbiAgfVxyXG5cclxuICBpZiAoIXRhcmdldC5ldmVudHNbdHlwZV0pIHtcclxuICAgIHRhcmdldC5ldmVudHNbdHlwZV0gPSBbXTtcclxuICAgIHRhcmdldC50eXBlQ291bnQrKztcclxuICB9XHJcblxyXG4gIGlmICghY29udGFpbnModGFyZ2V0LmV2ZW50c1t0eXBlXSwgbGlzdGVuZXIpKSB7XHJcbiAgICB2YXIgcmV0ID0gdm9pZCAwO1xyXG5cclxuICAgIGlmICh1c2VBdHRhY2hFdmVudCkge1xyXG4gICAgICB2YXIgX2F0dGFjaGVkTGlzdGVuZXJzJGVsID0gYXR0YWNoZWRMaXN0ZW5lcnNbZWxlbWVudEluZGV4XSxcclxuICAgICAgICAgIHN1cHBsaWVkID0gX2F0dGFjaGVkTGlzdGVuZXJzJGVsLnN1cHBsaWVkLFxyXG4gICAgICAgICAgd3JhcHBlZCA9IF9hdHRhY2hlZExpc3RlbmVycyRlbC53cmFwcGVkLFxyXG4gICAgICAgICAgdXNlQ291bnQgPSBfYXR0YWNoZWRMaXN0ZW5lcnMkZWwudXNlQ291bnQ7XHJcblxyXG4gICAgICB2YXIgbGlzdGVuZXJJbmRleCA9IGluZGV4T2Yoc3VwcGxpZWQsIGxpc3RlbmVyKTtcclxuXHJcbiAgICAgIHZhciB3cmFwcGVkTGlzdGVuZXIgPSB3cmFwcGVkW2xpc3RlbmVySW5kZXhdIHx8IGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgIGlmICghZXZlbnQuaW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkKSB7XHJcbiAgICAgICAgICBldmVudC50YXJnZXQgPSBldmVudC5zcmNFbGVtZW50O1xyXG4gICAgICAgICAgZXZlbnQuY3VycmVudFRhcmdldCA9IGVsZW1lbnQ7XHJcblxyXG4gICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQgPSBldmVudC5wcmV2ZW50RGVmYXVsdCB8fCBwcmV2ZW50RGVmO1xyXG4gICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uID0gZXZlbnQuc3RvcFByb3BhZ2F0aW9uIHx8IHN0b3BQcm9wO1xyXG4gICAgICAgICAgZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uID0gZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uIHx8IHN0b3BJbW1Qcm9wO1xyXG5cclxuICAgICAgICAgIGlmICgvbW91c2V8Y2xpY2svLnRlc3QoZXZlbnQudHlwZSkpIHtcclxuICAgICAgICAgICAgZXZlbnQucGFnZVggPSBldmVudC5jbGllbnRYICsgZ2V0V2luZG93KGVsZW1lbnQpLmRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxMZWZ0O1xyXG4gICAgICAgICAgICBldmVudC5wYWdlWSA9IGV2ZW50LmNsaWVudFkgKyBnZXRXaW5kb3coZWxlbWVudCkuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcDtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBsaXN0ZW5lcihldmVudCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9O1xyXG5cclxuICAgICAgcmV0ID0gZWxlbWVudFthZGRFdmVudF0ob24gKyB0eXBlLCB3cmFwcGVkTGlzdGVuZXIsICEhb3B0aW9ucy5jYXB0dXJlKTtcclxuXHJcbiAgICAgIGlmIChsaXN0ZW5lckluZGV4ID09PSAtMSkge1xyXG4gICAgICAgIHN1cHBsaWVkLnB1c2gobGlzdGVuZXIpO1xyXG4gICAgICAgIHdyYXBwZWQucHVzaCh3cmFwcGVkTGlzdGVuZXIpO1xyXG4gICAgICAgIHVzZUNvdW50LnB1c2goMSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdXNlQ291bnRbbGlzdGVuZXJJbmRleF0rKztcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcmV0ID0gZWxlbWVudFthZGRFdmVudF0odHlwZSwgbGlzdGVuZXIsIHN1cHBvcnRzT3B0aW9ucyA/IG9wdGlvbnMgOiAhIW9wdGlvbnMuY2FwdHVyZSk7XHJcbiAgICB9XHJcbiAgICB0YXJnZXQuZXZlbnRzW3R5cGVdLnB1c2gobGlzdGVuZXIpO1xyXG5cclxuICAgIHJldHVybiByZXQ7XHJcbiAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiByZW1vdmUoZWxlbWVudCwgdHlwZSwgbGlzdGVuZXIsIG9wdGlvbmFsQXJnKSB7XHJcbiAgdmFyIG9wdGlvbnMgPSBnZXRPcHRpb25zKG9wdGlvbmFsQXJnKTtcclxuICB2YXIgZWxlbWVudEluZGV4ID0gaW5kZXhPZihlbGVtZW50cywgZWxlbWVudCk7XHJcbiAgdmFyIHRhcmdldCA9IHRhcmdldHNbZWxlbWVudEluZGV4XTtcclxuXHJcbiAgaWYgKCF0YXJnZXQgfHwgIXRhcmdldC5ldmVudHMpIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIHZhciB3cmFwcGVkTGlzdGVuZXIgPSBsaXN0ZW5lcjtcclxuICB2YXIgbGlzdGVuZXJzID0gdm9pZCAwO1xyXG4gIHZhciBsaXN0ZW5lckluZGV4ID0gdm9pZCAwO1xyXG5cclxuICBpZiAodXNlQXR0YWNoRXZlbnQpIHtcclxuICAgIGxpc3RlbmVycyA9IGF0dGFjaGVkTGlzdGVuZXJzW2VsZW1lbnRJbmRleF07XHJcbiAgICBsaXN0ZW5lckluZGV4ID0gaW5kZXhPZihsaXN0ZW5lcnMuc3VwcGxpZWQsIGxpc3RlbmVyKTtcclxuICAgIHdyYXBwZWRMaXN0ZW5lciA9IGxpc3RlbmVycy53cmFwcGVkW2xpc3RlbmVySW5kZXhdO1xyXG4gIH1cclxuXHJcbiAgaWYgKHR5cGUgPT09ICdhbGwnKSB7XHJcbiAgICBmb3IgKHR5cGUgaW4gdGFyZ2V0LmV2ZW50cykge1xyXG4gICAgICBpZiAodGFyZ2V0LmV2ZW50cy5oYXNPd25Qcm9wZXJ0eSh0eXBlKSkge1xyXG4gICAgICAgIHJlbW92ZShlbGVtZW50LCB0eXBlLCAnYWxsJyk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIGlmICh0YXJnZXQuZXZlbnRzW3R5cGVdKSB7XHJcbiAgICB2YXIgbGVuID0gdGFyZ2V0LmV2ZW50c1t0eXBlXS5sZW5ndGg7XHJcblxyXG4gICAgaWYgKGxpc3RlbmVyID09PSAnYWxsJykge1xyXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgcmVtb3ZlKGVsZW1lbnQsIHR5cGUsIHRhcmdldC5ldmVudHNbdHlwZV1baV0sIG9wdGlvbnMpO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybjtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBsZW47IF9pKyspIHtcclxuICAgICAgICBpZiAodGFyZ2V0LmV2ZW50c1t0eXBlXVtfaV0gPT09IGxpc3RlbmVyKSB7XHJcbiAgICAgICAgICBlbGVtZW50W3JlbW92ZUV2ZW50XShvbiArIHR5cGUsIHdyYXBwZWRMaXN0ZW5lciwgc3VwcG9ydHNPcHRpb25zID8gb3B0aW9ucyA6ICEhb3B0aW9ucy5jYXB0dXJlKTtcclxuICAgICAgICAgIHRhcmdldC5ldmVudHNbdHlwZV0uc3BsaWNlKF9pLCAxKTtcclxuXHJcbiAgICAgICAgICBpZiAodXNlQXR0YWNoRXZlbnQgJiYgbGlzdGVuZXJzKSB7XHJcbiAgICAgICAgICAgIGxpc3RlbmVycy51c2VDb3VudFtsaXN0ZW5lckluZGV4XS0tO1xyXG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzLnVzZUNvdW50W2xpc3RlbmVySW5kZXhdID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgbGlzdGVuZXJzLnN1cHBsaWVkLnNwbGljZShsaXN0ZW5lckluZGV4LCAxKTtcclxuICAgICAgICAgICAgICBsaXN0ZW5lcnMud3JhcHBlZC5zcGxpY2UobGlzdGVuZXJJbmRleCwgMSk7XHJcbiAgICAgICAgICAgICAgbGlzdGVuZXJzLnVzZUNvdW50LnNwbGljZShsaXN0ZW5lckluZGV4LCAxKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmICh0YXJnZXQuZXZlbnRzW3R5cGVdICYmIHRhcmdldC5ldmVudHNbdHlwZV0ubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgIHRhcmdldC5ldmVudHNbdHlwZV0gPSBudWxsO1xyXG4gICAgICB0YXJnZXQudHlwZUNvdW50LS07XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBpZiAoIXRhcmdldC50eXBlQ291bnQpIHtcclxuICAgIHRhcmdldHMuc3BsaWNlKGVsZW1lbnRJbmRleCwgMSk7XHJcbiAgICBlbGVtZW50cy5zcGxpY2UoZWxlbWVudEluZGV4LCAxKTtcclxuICAgIGF0dGFjaGVkTGlzdGVuZXJzLnNwbGljZShlbGVtZW50SW5kZXgsIDEpO1xyXG4gIH1cclxufVxyXG5cclxuZnVuY3Rpb24gYWRkRGVsZWdhdGUoc2VsZWN0b3IsIGNvbnRleHQsIHR5cGUsIGxpc3RlbmVyLCBvcHRpb25hbEFyZykge1xyXG4gIHZhciBvcHRpb25zID0gZ2V0T3B0aW9ucyhvcHRpb25hbEFyZyk7XHJcbiAgaWYgKCFkZWxlZ2F0ZWRFdmVudHNbdHlwZV0pIHtcclxuICAgIGRlbGVnYXRlZEV2ZW50c1t0eXBlXSA9IHtcclxuICAgICAgc2VsZWN0b3JzOiBbXSxcclxuICAgICAgY29udGV4dHM6IFtdLFxyXG4gICAgICBsaXN0ZW5lcnM6IFtdXHJcbiAgICB9O1xyXG5cclxuICAgIC8vIGFkZCBkZWxlZ2F0ZSBsaXN0ZW5lciBmdW5jdGlvbnNcclxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZG9jdW1lbnRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgIGFkZChkb2N1bWVudHNbaV0sIHR5cGUsIGRlbGVnYXRlTGlzdGVuZXIpO1xyXG4gICAgICBhZGQoZG9jdW1lbnRzW2ldLCB0eXBlLCBkZWxlZ2F0ZVVzZUNhcHR1cmUsIHRydWUpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgdmFyIGRlbGVnYXRlZCA9IGRlbGVnYXRlZEV2ZW50c1t0eXBlXTtcclxuICB2YXIgaW5kZXggPSB2b2lkIDA7XHJcblxyXG4gIGZvciAoaW5kZXggPSBkZWxlZ2F0ZWQuc2VsZWN0b3JzLmxlbmd0aCAtIDE7IGluZGV4ID49IDA7IGluZGV4LS0pIHtcclxuICAgIGlmIChkZWxlZ2F0ZWQuc2VsZWN0b3JzW2luZGV4XSA9PT0gc2VsZWN0b3IgJiYgZGVsZWdhdGVkLmNvbnRleHRzW2luZGV4XSA9PT0gY29udGV4dCkge1xyXG4gICAgICBicmVhaztcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGlmIChpbmRleCA9PT0gLTEpIHtcclxuICAgIGluZGV4ID0gZGVsZWdhdGVkLnNlbGVjdG9ycy5sZW5ndGg7XHJcblxyXG4gICAgZGVsZWdhdGVkLnNlbGVjdG9ycy5wdXNoKHNlbGVjdG9yKTtcclxuICAgIGRlbGVnYXRlZC5jb250ZXh0cy5wdXNoKGNvbnRleHQpO1xyXG4gICAgZGVsZWdhdGVkLmxpc3RlbmVycy5wdXNoKFtdKTtcclxuICB9XHJcblxyXG4gIC8vIGtlZXAgbGlzdGVuZXIgYW5kIGNhcHR1cmUgYW5kIHBhc3NpdmUgZmxhZ3NcclxuICBkZWxlZ2F0ZWQubGlzdGVuZXJzW2luZGV4XS5wdXNoKFtsaXN0ZW5lciwgISFvcHRpb25zLmNhcHR1cmUsIG9wdGlvbnMucGFzc2l2ZV0pO1xyXG59XHJcblxyXG5mdW5jdGlvbiByZW1vdmVEZWxlZ2F0ZShzZWxlY3RvciwgY29udGV4dCwgdHlwZSwgbGlzdGVuZXIsIG9wdGlvbmFsQXJnKSB7XHJcbiAgdmFyIG9wdGlvbnMgPSBnZXRPcHRpb25zKG9wdGlvbmFsQXJnKTtcclxuICB2YXIgZGVsZWdhdGVkID0gZGVsZWdhdGVkRXZlbnRzW3R5cGVdO1xyXG4gIHZhciBtYXRjaEZvdW5kID0gZmFsc2U7XHJcbiAgdmFyIGluZGV4ID0gdm9pZCAwO1xyXG5cclxuICBpZiAoIWRlbGVnYXRlZCkge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgLy8gY291bnQgZnJvbSBsYXN0IGluZGV4IG9mIGRlbGVnYXRlZCB0byAwXHJcbiAgZm9yIChpbmRleCA9IGRlbGVnYXRlZC5zZWxlY3RvcnMubGVuZ3RoIC0gMTsgaW5kZXggPj0gMDsgaW5kZXgtLSkge1xyXG4gICAgLy8gbG9vayBmb3IgbWF0Y2hpbmcgc2VsZWN0b3IgYW5kIGNvbnRleHQgTm9kZVxyXG4gICAgaWYgKGRlbGVnYXRlZC5zZWxlY3RvcnNbaW5kZXhdID09PSBzZWxlY3RvciAmJiBkZWxlZ2F0ZWQuY29udGV4dHNbaW5kZXhdID09PSBjb250ZXh0KSB7XHJcblxyXG4gICAgICB2YXIgbGlzdGVuZXJzID0gZGVsZWdhdGVkLmxpc3RlbmVyc1tpbmRleF07XHJcblxyXG4gICAgICAvLyBlYWNoIGl0ZW0gb2YgdGhlIGxpc3RlbmVycyBhcnJheSBpcyBhbiBhcnJheTogW2Z1bmN0aW9uLCBjYXB0dXJlLCBwYXNzaXZlXVxyXG4gICAgICBmb3IgKHZhciBpID0gbGlzdGVuZXJzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XHJcbiAgICAgICAgdmFyIF9saXN0ZW5lcnMkaSA9IGxpc3RlbmVyc1tpXSxcclxuICAgICAgICAgICAgZm4gPSBfbGlzdGVuZXJzJGlbMF0sXHJcbiAgICAgICAgICAgIGNhcHR1cmUgPSBfbGlzdGVuZXJzJGlbMV0sXHJcbiAgICAgICAgICAgIHBhc3NpdmUgPSBfbGlzdGVuZXJzJGlbMl07XHJcblxyXG4gICAgICAgIC8vIGNoZWNrIGlmIHRoZSBsaXN0ZW5lciBmdW5jdGlvbnMgYW5kIGNhcHR1cmUgYW5kIHBhc3NpdmUgZmxhZ3MgbWF0Y2hcclxuXHJcbiAgICAgICAgaWYgKGZuID09PSBsaXN0ZW5lciAmJiBjYXB0dXJlID09PSAhIW9wdGlvbnMuY2FwdHVyZSAmJiBwYXNzaXZlID09PSBvcHRpb25zLnBhc3NpdmUpIHtcclxuICAgICAgICAgIC8vIHJlbW92ZSB0aGUgbGlzdGVuZXIgZnJvbSB0aGUgYXJyYXkgb2YgbGlzdGVuZXJzXHJcbiAgICAgICAgICBsaXN0ZW5lcnMuc3BsaWNlKGksIDEpO1xyXG5cclxuICAgICAgICAgIC8vIGlmIGFsbCBsaXN0ZW5lcnMgZm9yIHRoaXMgaW50ZXJhY3RhYmxlIGhhdmUgYmVlbiByZW1vdmVkXHJcbiAgICAgICAgICAvLyByZW1vdmUgdGhlIGludGVyYWN0YWJsZSBmcm9tIHRoZSBkZWxlZ2F0ZWQgYXJyYXlzXHJcbiAgICAgICAgICBpZiAoIWxpc3RlbmVycy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgZGVsZWdhdGVkLnNlbGVjdG9ycy5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gICAgICAgICAgICBkZWxlZ2F0ZWQuY29udGV4dHMuc3BsaWNlKGluZGV4LCAxKTtcclxuICAgICAgICAgICAgZGVsZWdhdGVkLmxpc3RlbmVycy5zcGxpY2UoaW5kZXgsIDEpO1xyXG5cclxuICAgICAgICAgICAgLy8gcmVtb3ZlIGRlbGVnYXRlIGZ1bmN0aW9uIGZyb20gY29udGV4dFxyXG4gICAgICAgICAgICByZW1vdmUoY29udGV4dCwgdHlwZSwgZGVsZWdhdGVMaXN0ZW5lcik7XHJcbiAgICAgICAgICAgIHJlbW92ZShjb250ZXh0LCB0eXBlLCBkZWxlZ2F0ZVVzZUNhcHR1cmUsIHRydWUpO1xyXG5cclxuICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSBhcnJheXMgaWYgdGhleSBhcmUgZW1wdHlcclxuICAgICAgICAgICAgaWYgKCFkZWxlZ2F0ZWQuc2VsZWN0b3JzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgIGRlbGVnYXRlZEV2ZW50c1t0eXBlXSA9IG51bGw7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAvLyBvbmx5IHJlbW92ZSBvbmUgbGlzdGVuZXJcclxuICAgICAgICAgIG1hdGNoRm91bmQgPSB0cnVlO1xyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAobWF0Y2hGb3VuZCkge1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG59XHJcblxyXG4vLyBib3VuZCB0byB0aGUgaW50ZXJhY3RhYmxlIGNvbnRleHQgd2hlbiBhIERPTSBldmVudFxyXG4vLyBsaXN0ZW5lciBpcyBhZGRlZCB0byBhIHNlbGVjdG9yIGludGVyYWN0YWJsZVxyXG5mdW5jdGlvbiBkZWxlZ2F0ZUxpc3RlbmVyKGV2ZW50LCBvcHRpb25hbEFyZykge1xyXG4gIHZhciBvcHRpb25zID0gZ2V0T3B0aW9ucyhvcHRpb25hbEFyZyk7XHJcbiAgdmFyIGZha2VFdmVudCA9IHt9O1xyXG4gIHZhciBkZWxlZ2F0ZWQgPSBkZWxlZ2F0ZWRFdmVudHNbZXZlbnQudHlwZV07XHJcbiAgdmFyIGV2ZW50VGFyZ2V0ID0gZG9tVXRpbHMuZ2V0QWN0dWFsRWxlbWVudChldmVudC5wYXRoID8gZXZlbnQucGF0aFswXSA6IGV2ZW50LnRhcmdldCk7XHJcbiAgdmFyIGVsZW1lbnQgPSBldmVudFRhcmdldDtcclxuXHJcbiAgLy8gZHVwbGljYXRlIHRoZSBldmVudCBzbyB0aGF0IGN1cnJlbnRUYXJnZXQgY2FuIGJlIGNoYW5nZWRcclxuICBwRXh0ZW5kKGZha2VFdmVudCwgZXZlbnQpO1xyXG5cclxuICBmYWtlRXZlbnQub3JpZ2luYWxFdmVudCA9IGV2ZW50O1xyXG4gIGZha2VFdmVudC5wcmV2ZW50RGVmYXVsdCA9IHByZXZlbnRPcmlnaW5hbERlZmF1bHQ7XHJcblxyXG4gIC8vIGNsaW1iIHVwIGRvY3VtZW50IHRyZWUgbG9va2luZyBmb3Igc2VsZWN0b3IgbWF0Y2hlc1xyXG4gIHdoaWxlIChpcy5lbGVtZW50KGVsZW1lbnQpKSB7XHJcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRlbGVnYXRlZC5zZWxlY3RvcnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgdmFyIHNlbGVjdG9yID0gZGVsZWdhdGVkLnNlbGVjdG9yc1tpXTtcclxuICAgICAgdmFyIGNvbnRleHQgPSBkZWxlZ2F0ZWQuY29udGV4dHNbaV07XHJcblxyXG4gICAgICBpZiAoZG9tVXRpbHMubWF0Y2hlc1NlbGVjdG9yKGVsZW1lbnQsIHNlbGVjdG9yKSAmJiBkb21VdGlscy5ub2RlQ29udGFpbnMoY29udGV4dCwgZXZlbnRUYXJnZXQpICYmIGRvbVV0aWxzLm5vZGVDb250YWlucyhjb250ZXh0LCBlbGVtZW50KSkge1xyXG5cclxuICAgICAgICB2YXIgbGlzdGVuZXJzID0gZGVsZWdhdGVkLmxpc3RlbmVyc1tpXTtcclxuXHJcbiAgICAgICAgZmFrZUV2ZW50LmN1cnJlbnRUYXJnZXQgPSBlbGVtZW50O1xyXG5cclxuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGxpc3RlbmVycy5sZW5ndGg7IGorKykge1xyXG4gICAgICAgICAgdmFyIF9saXN0ZW5lcnMkaiA9IGxpc3RlbmVyc1tqXSxcclxuICAgICAgICAgICAgICBmbiA9IF9saXN0ZW5lcnMkalswXSxcclxuICAgICAgICAgICAgICBjYXB0dXJlID0gX2xpc3RlbmVycyRqWzFdLFxyXG4gICAgICAgICAgICAgIHBhc3NpdmUgPSBfbGlzdGVuZXJzJGpbMl07XHJcblxyXG5cclxuICAgICAgICAgIGlmIChjYXB0dXJlID09PSAhIW9wdGlvbnMuY2FwdHVyZSAmJiBwYXNzaXZlID09PSBvcHRpb25zLnBhc3NpdmUpIHtcclxuICAgICAgICAgICAgZm4oZmFrZUV2ZW50KTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBlbGVtZW50ID0gZG9tVXRpbHMucGFyZW50Tm9kZShlbGVtZW50KTtcclxuICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGRlbGVnYXRlVXNlQ2FwdHVyZShldmVudCkge1xyXG4gIHJldHVybiBkZWxlZ2F0ZUxpc3RlbmVyLmNhbGwodGhpcywgZXZlbnQsIHRydWUpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBwcmV2ZW50RGVmKCkge1xyXG4gIHRoaXMucmV0dXJuVmFsdWUgPSBmYWxzZTtcclxufVxyXG5cclxuZnVuY3Rpb24gcHJldmVudE9yaWdpbmFsRGVmYXVsdCgpIHtcclxuICB0aGlzLm9yaWdpbmFsRXZlbnQucHJldmVudERlZmF1bHQoKTtcclxufVxyXG5cclxuZnVuY3Rpb24gc3RvcFByb3AoKSB7XHJcbiAgdGhpcy5jYW5jZWxCdWJibGUgPSB0cnVlO1xyXG59XHJcblxyXG5mdW5jdGlvbiBzdG9wSW1tUHJvcCgpIHtcclxuICB0aGlzLmNhbmNlbEJ1YmJsZSA9IHRydWU7XHJcbiAgdGhpcy5pbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQgPSB0cnVlO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRPcHRpb25zKHBhcmFtKSB7XHJcbiAgcmV0dXJuIGlzLm9iamVjdChwYXJhbSkgPyBwYXJhbSA6IHsgY2FwdHVyZTogcGFyYW0gfTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSB7XHJcbiAgYWRkOiBhZGQsXHJcbiAgcmVtb3ZlOiByZW1vdmUsXHJcblxyXG4gIGFkZERlbGVnYXRlOiBhZGREZWxlZ2F0ZSxcclxuICByZW1vdmVEZWxlZ2F0ZTogcmVtb3ZlRGVsZWdhdGUsXHJcblxyXG4gIGRlbGVnYXRlTGlzdGVuZXI6IGRlbGVnYXRlTGlzdGVuZXIsXHJcbiAgZGVsZWdhdGVVc2VDYXB0dXJlOiBkZWxlZ2F0ZVVzZUNhcHR1cmUsXHJcbiAgZGVsZWdhdGVkRXZlbnRzOiBkZWxlZ2F0ZWRFdmVudHMsXHJcbiAgZG9jdW1lbnRzOiBkb2N1bWVudHMsXHJcblxyXG4gIHVzZUF0dGFjaEV2ZW50OiB1c2VBdHRhY2hFdmVudCxcclxuICBzdXBwb3J0c09wdGlvbnM6IHN1cHBvcnRzT3B0aW9ucyxcclxuXHJcbiAgX2VsZW1lbnRzOiBlbGVtZW50cyxcclxuICBfdGFyZ2V0czogdGFyZ2V0cyxcclxuICBfYXR0YWNoZWRMaXN0ZW5lcnM6IGF0dGFjaGVkTGlzdGVuZXJzXHJcbn07XHJcblxyXG59LHtcIi4vYXJyXCI6MzYsXCIuL2RvbVV0aWxzXCI6MzksXCIuL2lzXCI6NDYsXCIuL3BvaW50ZXJFeHRlbmRcIjo0OCxcIi4vd2luZG93XCI6NTJ9XSw0MTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcblwidXNlIHN0cmljdFwiO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBleHRlbmQoZGVzdCwgc291cmNlKSB7XHJcbiAgZm9yICh2YXIgcHJvcCBpbiBzb3VyY2UpIHtcclxuICAgIGRlc3RbcHJvcF0gPSBzb3VyY2VbcHJvcF07XHJcbiAgfVxyXG4gIHJldHVybiBkZXN0O1xyXG59O1xyXG5cclxufSx7fV0sNDI6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xyXG4ndXNlIHN0cmljdCc7XHJcblxyXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCcuL3JlY3QnKSxcclxuICAgIHJlc29sdmVSZWN0TGlrZSA9IF9yZXF1aXJlLnJlc29sdmVSZWN0TGlrZSxcclxuICAgIHJlY3RUb1hZID0gX3JlcXVpcmUucmVjdFRvWFk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICh0YXJnZXQsIGVsZW1lbnQsIGFjdGlvbikge1xyXG4gIHZhciBhY3Rpb25PcHRpb25zID0gdGFyZ2V0Lm9wdGlvbnNbYWN0aW9uXTtcclxuICB2YXIgYWN0aW9uT3JpZ2luID0gYWN0aW9uT3B0aW9ucyAmJiBhY3Rpb25PcHRpb25zLm9yaWdpbjtcclxuICB2YXIgb3JpZ2luID0gYWN0aW9uT3JpZ2luIHx8IHRhcmdldC5vcHRpb25zLm9yaWdpbjtcclxuXHJcbiAgdmFyIG9yaWdpblJlY3QgPSByZXNvbHZlUmVjdExpa2Uob3JpZ2luLCB0YXJnZXQsIGVsZW1lbnQsIFt0YXJnZXQgJiYgZWxlbWVudF0pO1xyXG5cclxuICByZXR1cm4gcmVjdFRvWFkob3JpZ2luUmVjdCkgfHwgeyB4OiAwLCB5OiAwIH07XHJcbn07XHJcblxyXG59LHtcIi4vcmVjdFwiOjUxfV0sNDM6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xyXG5cInVzZSBzdHJpY3RcIjtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHgsIHkpIHtcclxuICByZXR1cm4gTWF0aC5zcXJ0KHggKiB4ICsgeSAqIHkpO1xyXG59O1xyXG5cclxufSx7fV0sNDQ6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xyXG4ndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZXh0ZW5kID0gcmVxdWlyZSgnLi9leHRlbmQnKTtcclxudmFyIHdpbiA9IHJlcXVpcmUoJy4vd2luZG93Jyk7XHJcblxyXG52YXIgdXRpbHMgPSB7XHJcbiAgd2Fybk9uY2U6IGZ1bmN0aW9uIHdhcm5PbmNlKG1ldGhvZCwgbWVzc2FnZSkge1xyXG4gICAgdmFyIHdhcm5lZCA9IGZhbHNlO1xyXG5cclxuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIGlmICghd2FybmVkKSB7XHJcbiAgICAgICAgd2luLndpbmRvdy5jb25zb2xlLndhcm4obWVzc2FnZSk7XHJcbiAgICAgICAgd2FybmVkID0gdHJ1ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIG1ldGhvZC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xyXG4gICAgfTtcclxuICB9LFxyXG5cclxuICAvLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS81NjM0NTI4LzIyODA4ODhcclxuICBfZ2V0UUJlemllclZhbHVlOiBmdW5jdGlvbiBfZ2V0UUJlemllclZhbHVlKHQsIHAxLCBwMiwgcDMpIHtcclxuICAgIHZhciBpVCA9IDEgLSB0O1xyXG4gICAgcmV0dXJuIGlUICogaVQgKiBwMSArIDIgKiBpVCAqIHQgKiBwMiArIHQgKiB0ICogcDM7XHJcbiAgfSxcclxuXHJcbiAgZ2V0UXVhZHJhdGljQ3VydmVQb2ludDogZnVuY3Rpb24gZ2V0UXVhZHJhdGljQ3VydmVQb2ludChzdGFydFgsIHN0YXJ0WSwgY3BYLCBjcFksIGVuZFgsIGVuZFksIHBvc2l0aW9uKSB7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICB4OiB1dGlscy5fZ2V0UUJlemllclZhbHVlKHBvc2l0aW9uLCBzdGFydFgsIGNwWCwgZW5kWCksXHJcbiAgICAgIHk6IHV0aWxzLl9nZXRRQmV6aWVyVmFsdWUocG9zaXRpb24sIHN0YXJ0WSwgY3BZLCBlbmRZKVxyXG4gICAgfTtcclxuICB9LFxyXG5cclxuICAvLyBodHRwOi8vZ2l6bWEuY29tL2Vhc2luZy9cclxuICBlYXNlT3V0UXVhZDogZnVuY3Rpb24gZWFzZU91dFF1YWQodCwgYiwgYywgZCkge1xyXG4gICAgdCAvPSBkO1xyXG4gICAgcmV0dXJuIC1jICogdCAqICh0IC0gMikgKyBiO1xyXG4gIH0sXHJcblxyXG4gIGNvcHlBY3Rpb246IGZ1bmN0aW9uIGNvcHlBY3Rpb24oZGVzdCwgc3JjKSB7XHJcbiAgICBkZXN0Lm5hbWUgPSBzcmMubmFtZTtcclxuICAgIGRlc3QuYXhpcyA9IHNyYy5heGlzO1xyXG4gICAgZGVzdC5lZGdlcyA9IHNyYy5lZGdlcztcclxuXHJcbiAgICByZXR1cm4gZGVzdDtcclxuICB9LFxyXG5cclxuICBpczogcmVxdWlyZSgnLi9pcycpLFxyXG4gIGV4dGVuZDogZXh0ZW5kLFxyXG4gIGh5cG90OiByZXF1aXJlKCcuL2h5cG90JyksXHJcbiAgZ2V0T3JpZ2luWFk6IHJlcXVpcmUoJy4vZ2V0T3JpZ2luWFknKVxyXG59O1xyXG5cclxuZXh0ZW5kKHV0aWxzLCByZXF1aXJlKCcuL2FycicpKTtcclxuZXh0ZW5kKHV0aWxzLCByZXF1aXJlKCcuL2RvbVV0aWxzJykpO1xyXG5leHRlbmQodXRpbHMsIHJlcXVpcmUoJy4vcG9pbnRlclV0aWxzJykpO1xyXG5leHRlbmQodXRpbHMsIHJlcXVpcmUoJy4vcmVjdCcpKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gdXRpbHM7XHJcblxyXG59LHtcIi4vYXJyXCI6MzYsXCIuL2RvbVV0aWxzXCI6MzksXCIuL2V4dGVuZFwiOjQxLFwiLi9nZXRPcmlnaW5YWVwiOjQyLFwiLi9oeXBvdFwiOjQzLFwiLi9pc1wiOjQ2LFwiLi9wb2ludGVyVXRpbHNcIjo0OSxcIi4vcmVjdFwiOjUxLFwiLi93aW5kb3dcIjo1Mn1dLDQ1OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIHNjb3BlID0gcmVxdWlyZSgnLi4vc2NvcGUnKTtcclxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi9pbmRleCcpO1xyXG5cclxudmFyIGZpbmRlciA9IHtcclxuICBtZXRob2RPcmRlcjogWydzaW11bGF0aW9uUmVzdW1lJywgJ21vdXNlT3JQZW4nLCAnaGFzUG9pbnRlcicsICdpZGxlJ10sXHJcblxyXG4gIHNlYXJjaDogZnVuY3Rpb24gc2VhcmNoKHBvaW50ZXIsIGV2ZW50VHlwZSwgZXZlbnRUYXJnZXQpIHtcclxuICAgIHZhciBwb2ludGVyVHlwZSA9IHV0aWxzLmdldFBvaW50ZXJUeXBlKHBvaW50ZXIpO1xyXG4gICAgdmFyIHBvaW50ZXJJZCA9IHV0aWxzLmdldFBvaW50ZXJJZChwb2ludGVyKTtcclxuICAgIHZhciBkZXRhaWxzID0geyBwb2ludGVyOiBwb2ludGVyLCBwb2ludGVySWQ6IHBvaW50ZXJJZCwgcG9pbnRlclR5cGU6IHBvaW50ZXJUeXBlLCBldmVudFR5cGU6IGV2ZW50VHlwZSwgZXZlbnRUYXJnZXQ6IGV2ZW50VGFyZ2V0IH07XHJcblxyXG4gICAgZm9yICh2YXIgX2l0ZXJhdG9yID0gZmluZGVyLm1ldGhvZE9yZGVyLCBfaXNBcnJheSA9IEFycmF5LmlzQXJyYXkoX2l0ZXJhdG9yKSwgX2kgPSAwLCBfaXRlcmF0b3IgPSBfaXNBcnJheSA/IF9pdGVyYXRvciA6IF9pdGVyYXRvcltTeW1ib2wuaXRlcmF0b3JdKCk7Oykge1xyXG4gICAgICB2YXIgX3JlZjtcclxuXHJcbiAgICAgIGlmIChfaXNBcnJheSkge1xyXG4gICAgICAgIGlmIChfaSA+PSBfaXRlcmF0b3IubGVuZ3RoKSBicmVhaztcclxuICAgICAgICBfcmVmID0gX2l0ZXJhdG9yW19pKytdO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIF9pID0gX2l0ZXJhdG9yLm5leHQoKTtcclxuICAgICAgICBpZiAoX2kuZG9uZSkgYnJlYWs7XHJcbiAgICAgICAgX3JlZiA9IF9pLnZhbHVlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB2YXIgbWV0aG9kID0gX3JlZjtcclxuXHJcbiAgICAgIHZhciBpbnRlcmFjdGlvbiA9IGZpbmRlclttZXRob2RdKGRldGFpbHMpO1xyXG5cclxuICAgICAgaWYgKGludGVyYWN0aW9uKSB7XHJcbiAgICAgICAgcmV0dXJuIGludGVyYWN0aW9uO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSxcclxuXHJcbiAgLy8gdHJ5IHRvIHJlc3VtZSBzaW11bGF0aW9uIHdpdGggYSBuZXcgcG9pbnRlclxyXG4gIHNpbXVsYXRpb25SZXN1bWU6IGZ1bmN0aW9uIHNpbXVsYXRpb25SZXN1bWUoX3JlZjIpIHtcclxuICAgIHZhciBwb2ludGVyVHlwZSA9IF9yZWYyLnBvaW50ZXJUeXBlLFxyXG4gICAgICAgIGV2ZW50VHlwZSA9IF9yZWYyLmV2ZW50VHlwZSxcclxuICAgICAgICBldmVudFRhcmdldCA9IF9yZWYyLmV2ZW50VGFyZ2V0O1xyXG5cclxuICAgIGlmICghL2Rvd258c3RhcnQvaS50ZXN0KGV2ZW50VHlwZSkpIHtcclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgZm9yICh2YXIgX2l0ZXJhdG9yMiA9IHNjb3BlLmludGVyYWN0aW9ucywgX2lzQXJyYXkyID0gQXJyYXkuaXNBcnJheShfaXRlcmF0b3IyKSwgX2kyID0gMCwgX2l0ZXJhdG9yMiA9IF9pc0FycmF5MiA/IF9pdGVyYXRvcjIgOiBfaXRlcmF0b3IyW1N5bWJvbC5pdGVyYXRvcl0oKTs7KSB7XHJcbiAgICAgIHZhciBfcmVmMztcclxuXHJcbiAgICAgIGlmIChfaXNBcnJheTIpIHtcclxuICAgICAgICBpZiAoX2kyID49IF9pdGVyYXRvcjIubGVuZ3RoKSBicmVhaztcclxuICAgICAgICBfcmVmMyA9IF9pdGVyYXRvcjJbX2kyKytdO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIF9pMiA9IF9pdGVyYXRvcjIubmV4dCgpO1xyXG4gICAgICAgIGlmIChfaTIuZG9uZSkgYnJlYWs7XHJcbiAgICAgICAgX3JlZjMgPSBfaTIudmFsdWU7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYzO1xyXG5cclxuICAgICAgdmFyIGVsZW1lbnQgPSBldmVudFRhcmdldDtcclxuXHJcbiAgICAgIGlmIChpbnRlcmFjdGlvbi5zaW11bGF0aW9uICYmIGludGVyYWN0aW9uLnNpbXVsYXRpb24uYWxsb3dSZXN1bWUgJiYgaW50ZXJhY3Rpb24ucG9pbnRlclR5cGUgPT09IHBvaW50ZXJUeXBlKSB7XHJcbiAgICAgICAgd2hpbGUgKGVsZW1lbnQpIHtcclxuICAgICAgICAgIC8vIGlmIHRoZSBlbGVtZW50IGlzIHRoZSBpbnRlcmFjdGlvbiBlbGVtZW50XHJcbiAgICAgICAgICBpZiAoZWxlbWVudCA9PT0gaW50ZXJhY3Rpb24uZWxlbWVudCkge1xyXG4gICAgICAgICAgICByZXR1cm4gaW50ZXJhY3Rpb247XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBlbGVtZW50ID0gdXRpbHMucGFyZW50Tm9kZShlbGVtZW50KTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gbnVsbDtcclxuICB9LFxyXG5cclxuICAvLyBpZiBpdCdzIGEgbW91c2Ugb3IgcGVuIGludGVyYWN0aW9uXHJcbiAgbW91c2VPclBlbjogZnVuY3Rpb24gbW91c2VPclBlbihfcmVmNCkge1xyXG4gICAgdmFyIHBvaW50ZXJJZCA9IF9yZWY0LnBvaW50ZXJJZCxcclxuICAgICAgICBwb2ludGVyVHlwZSA9IF9yZWY0LnBvaW50ZXJUeXBlLFxyXG4gICAgICAgIGV2ZW50VHlwZSA9IF9yZWY0LmV2ZW50VHlwZTtcclxuXHJcbiAgICBpZiAocG9pbnRlclR5cGUgIT09ICdtb3VzZScgJiYgcG9pbnRlclR5cGUgIT09ICdwZW4nKSB7XHJcbiAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIHZhciBmaXJzdE5vbkFjdGl2ZSA9IHZvaWQgMDtcclxuXHJcbiAgICBmb3IgKHZhciBfaXRlcmF0b3IzID0gc2NvcGUuaW50ZXJhY3Rpb25zLCBfaXNBcnJheTMgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvcjMpLCBfaTMgPSAwLCBfaXRlcmF0b3IzID0gX2lzQXJyYXkzID8gX2l0ZXJhdG9yMyA6IF9pdGVyYXRvcjNbU3ltYm9sLml0ZXJhdG9yXSgpOzspIHtcclxuICAgICAgdmFyIF9yZWY1O1xyXG5cclxuICAgICAgaWYgKF9pc0FycmF5Mykge1xyXG4gICAgICAgIGlmIChfaTMgPj0gX2l0ZXJhdG9yMy5sZW5ndGgpIGJyZWFrO1xyXG4gICAgICAgIF9yZWY1ID0gX2l0ZXJhdG9yM1tfaTMrK107XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgX2kzID0gX2l0ZXJhdG9yMy5uZXh0KCk7XHJcbiAgICAgICAgaWYgKF9pMy5kb25lKSBicmVhaztcclxuICAgICAgICBfcmVmNSA9IF9pMy52YWx1ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIGludGVyYWN0aW9uID0gX3JlZjU7XHJcblxyXG4gICAgICBpZiAoaW50ZXJhY3Rpb24ucG9pbnRlclR5cGUgPT09IHBvaW50ZXJUeXBlKSB7XHJcbiAgICAgICAgLy8gaWYgaXQncyBhIGRvd24gZXZlbnQsIHNraXAgaW50ZXJhY3Rpb25zIHdpdGggcnVubmluZyBzaW11bGF0aW9uc1xyXG4gICAgICAgIGlmIChpbnRlcmFjdGlvbi5zaW11bGF0aW9uICYmICF1dGlscy5jb250YWlucyhpbnRlcmFjdGlvbi5wb2ludGVySWRzLCBwb2ludGVySWQpKSB7XHJcbiAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIGlmIHRoZSBpbnRlcmFjdGlvbiBpcyBhY3RpdmUsIHJldHVybiBpdCBpbW1lZGlhdGVseVxyXG4gICAgICAgIGlmIChpbnRlcmFjdGlvbi5pbnRlcmFjdGluZygpKSB7XHJcbiAgICAgICAgICByZXR1cm4gaW50ZXJhY3Rpb247XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIG90aGVyd2lzZSBzYXZlIGl0IGFuZCBsb29rIGZvciBhbm90aGVyIGFjdGl2ZSBpbnRlcmFjdGlvblxyXG4gICAgICAgIGVsc2UgaWYgKCFmaXJzdE5vbkFjdGl2ZSkge1xyXG4gICAgICAgICAgICBmaXJzdE5vbkFjdGl2ZSA9IGludGVyYWN0aW9uO1xyXG4gICAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gaWYgbm8gYWN0aXZlIG1vdXNlIGludGVyYWN0aW9uIHdhcyBmb3VuZCB1c2UgdGhlIGZpcnN0IGluYWN0aXZlIG1vdXNlXHJcbiAgICAvLyBpbnRlcmFjdGlvblxyXG4gICAgaWYgKGZpcnN0Tm9uQWN0aXZlKSB7XHJcbiAgICAgIHJldHVybiBmaXJzdE5vbkFjdGl2ZTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBmaW5kIGFueSBtb3VzZSBvciBwZW4gaW50ZXJhY3Rpb24uXHJcbiAgICAvLyBpZ25vcmUgdGhlIGludGVyYWN0aW9uIGlmIHRoZSBldmVudFR5cGUgaXMgYSAqZG93biwgYW5kIGEgc2ltdWxhdGlvblxyXG4gICAgLy8gaXMgYWN0aXZlXHJcbiAgICBmb3IgKHZhciBfaXRlcmF0b3I0ID0gc2NvcGUuaW50ZXJhY3Rpb25zLCBfaXNBcnJheTQgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvcjQpLCBfaTQgPSAwLCBfaXRlcmF0b3I0ID0gX2lzQXJyYXk0ID8gX2l0ZXJhdG9yNCA6IF9pdGVyYXRvcjRbU3ltYm9sLml0ZXJhdG9yXSgpOzspIHtcclxuICAgICAgdmFyIF9yZWY2O1xyXG5cclxuICAgICAgaWYgKF9pc0FycmF5NCkge1xyXG4gICAgICAgIGlmIChfaTQgPj0gX2l0ZXJhdG9yNC5sZW5ndGgpIGJyZWFrO1xyXG4gICAgICAgIF9yZWY2ID0gX2l0ZXJhdG9yNFtfaTQrK107XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgX2k0ID0gX2l0ZXJhdG9yNC5uZXh0KCk7XHJcbiAgICAgICAgaWYgKF9pNC5kb25lKSBicmVhaztcclxuICAgICAgICBfcmVmNiA9IF9pNC52YWx1ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIF9pbnRlcmFjdGlvbiA9IF9yZWY2O1xyXG5cclxuICAgICAgaWYgKF9pbnRlcmFjdGlvbi5wb2ludGVyVHlwZSA9PT0gcG9pbnRlclR5cGUgJiYgISgvZG93bi9pLnRlc3QoZXZlbnRUeXBlKSAmJiBfaW50ZXJhY3Rpb24uc2ltdWxhdGlvbikpIHtcclxuICAgICAgICByZXR1cm4gX2ludGVyYWN0aW9uO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIG51bGw7XHJcbiAgfSxcclxuXHJcbiAgLy8gZ2V0IGludGVyYWN0aW9uIHRoYXQgaGFzIHRoaXMgcG9pbnRlclxyXG4gIGhhc1BvaW50ZXI6IGZ1bmN0aW9uIGhhc1BvaW50ZXIoX3JlZjcpIHtcclxuICAgIHZhciBwb2ludGVySWQgPSBfcmVmNy5wb2ludGVySWQ7XHJcblxyXG4gICAgZm9yICh2YXIgX2l0ZXJhdG9yNSA9IHNjb3BlLmludGVyYWN0aW9ucywgX2lzQXJyYXk1ID0gQXJyYXkuaXNBcnJheShfaXRlcmF0b3I1KSwgX2k1ID0gMCwgX2l0ZXJhdG9yNSA9IF9pc0FycmF5NSA/IF9pdGVyYXRvcjUgOiBfaXRlcmF0b3I1W1N5bWJvbC5pdGVyYXRvcl0oKTs7KSB7XHJcbiAgICAgIHZhciBfcmVmODtcclxuXHJcbiAgICAgIGlmIChfaXNBcnJheTUpIHtcclxuICAgICAgICBpZiAoX2k1ID49IF9pdGVyYXRvcjUubGVuZ3RoKSBicmVhaztcclxuICAgICAgICBfcmVmOCA9IF9pdGVyYXRvcjVbX2k1KytdO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIF9pNSA9IF9pdGVyYXRvcjUubmV4dCgpO1xyXG4gICAgICAgIGlmIChfaTUuZG9uZSkgYnJlYWs7XHJcbiAgICAgICAgX3JlZjggPSBfaTUudmFsdWU7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHZhciBpbnRlcmFjdGlvbiA9IF9yZWY4O1xyXG5cclxuICAgICAgaWYgKHV0aWxzLmNvbnRhaW5zKGludGVyYWN0aW9uLnBvaW50ZXJJZHMsIHBvaW50ZXJJZCkpIHtcclxuICAgICAgICByZXR1cm4gaW50ZXJhY3Rpb247XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9LFxyXG5cclxuICAvLyBnZXQgZmlyc3QgaWRsZSBpbnRlcmFjdGlvbiB3aXRoIGEgbWF0Y2hpbmcgcG9pbnRlclR5cGVcclxuICBpZGxlOiBmdW5jdGlvbiBpZGxlKF9yZWY5KSB7XHJcbiAgICB2YXIgcG9pbnRlclR5cGUgPSBfcmVmOS5wb2ludGVyVHlwZTtcclxuXHJcbiAgICBmb3IgKHZhciBfaXRlcmF0b3I2ID0gc2NvcGUuaW50ZXJhY3Rpb25zLCBfaXNBcnJheTYgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvcjYpLCBfaTYgPSAwLCBfaXRlcmF0b3I2ID0gX2lzQXJyYXk2ID8gX2l0ZXJhdG9yNiA6IF9pdGVyYXRvcjZbU3ltYm9sLml0ZXJhdG9yXSgpOzspIHtcclxuICAgICAgdmFyIF9yZWYxMDtcclxuXHJcbiAgICAgIGlmIChfaXNBcnJheTYpIHtcclxuICAgICAgICBpZiAoX2k2ID49IF9pdGVyYXRvcjYubGVuZ3RoKSBicmVhaztcclxuICAgICAgICBfcmVmMTAgPSBfaXRlcmF0b3I2W19pNisrXTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBfaTYgPSBfaXRlcmF0b3I2Lm5leHQoKTtcclxuICAgICAgICBpZiAoX2k2LmRvbmUpIGJyZWFrO1xyXG4gICAgICAgIF9yZWYxMCA9IF9pNi52YWx1ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIGludGVyYWN0aW9uID0gX3JlZjEwO1xyXG5cclxuICAgICAgLy8gaWYgdGhlcmUncyBhbHJlYWR5IGEgcG9pbnRlciBoZWxkIGRvd25cclxuICAgICAgaWYgKGludGVyYWN0aW9uLnBvaW50ZXJJZHMubGVuZ3RoID09PSAxKSB7XHJcbiAgICAgICAgdmFyIHRhcmdldCA9IGludGVyYWN0aW9uLnRhcmdldDtcclxuICAgICAgICAvLyBkb24ndCBhZGQgdGhpcyBwb2ludGVyIGlmIHRoZXJlIGlzIGEgdGFyZ2V0IGludGVyYWN0YWJsZSBhbmQgaXRcclxuICAgICAgICAvLyBpc24ndCBnZXN0dXJhYmxlXHJcbiAgICAgICAgaWYgKHRhcmdldCAmJiAhdGFyZ2V0Lm9wdGlvbnMuZ2VzdHVyZS5lbmFibGVkKSB7XHJcbiAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgICAgLy8gbWF4aW11bSBvZiAyIHBvaW50ZXJzIHBlciBpbnRlcmFjdGlvblxyXG4gICAgICBlbHNlIGlmIChpbnRlcmFjdGlvbi5wb2ludGVySWRzLmxlbmd0aCA+PSAyKSB7XHJcbiAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICBpZiAoIWludGVyYWN0aW9uLmludGVyYWN0aW5nKCkgJiYgcG9pbnRlclR5cGUgPT09IGludGVyYWN0aW9uLnBvaW50ZXJUeXBlKSB7XHJcbiAgICAgICAgcmV0dXJuIGludGVyYWN0aW9uO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIG51bGw7XHJcbiAgfVxyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmaW5kZXI7XHJcblxyXG59LHtcIi4uL3Njb3BlXCI6MzQsXCIuL2luZGV4XCI6NDR9XSw0NjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBfdHlwZW9mID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09IFwic3ltYm9sXCIgPyBmdW5jdGlvbiAob2JqKSB7IHJldHVybiB0eXBlb2Ygb2JqOyB9IDogZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gb2JqICYmIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvYmouY29uc3RydWN0b3IgPT09IFN5bWJvbCAmJiBvYmogIT09IFN5bWJvbC5wcm90b3R5cGUgPyBcInN5bWJvbFwiIDogdHlwZW9mIG9iajsgfTtcclxuXHJcbnZhciB3aW4gPSByZXF1aXJlKCcuL3dpbmRvdycpO1xyXG52YXIgaXNXaW5kb3cgPSByZXF1aXJlKCcuL2lzV2luZG93Jyk7XHJcblxyXG52YXIgaXMgPSB7XHJcbiAgYXJyYXk6IGZ1bmN0aW9uIGFycmF5KCkge30sXHJcblxyXG4gIHdpbmRvdzogZnVuY3Rpb24gd2luZG93KHRoaW5nKSB7XHJcbiAgICByZXR1cm4gdGhpbmcgPT09IHdpbi53aW5kb3cgfHwgaXNXaW5kb3codGhpbmcpO1xyXG4gIH0sXHJcblxyXG4gIGRvY0ZyYWc6IGZ1bmN0aW9uIGRvY0ZyYWcodGhpbmcpIHtcclxuICAgIHJldHVybiBpcy5vYmplY3QodGhpbmcpICYmIHRoaW5nLm5vZGVUeXBlID09PSAxMTtcclxuICB9LFxyXG5cclxuICBvYmplY3Q6IGZ1bmN0aW9uIG9iamVjdCh0aGluZykge1xyXG4gICAgcmV0dXJuICEhdGhpbmcgJiYgKHR5cGVvZiB0aGluZyA9PT0gJ3VuZGVmaW5lZCcgPyAndW5kZWZpbmVkJyA6IF90eXBlb2YodGhpbmcpKSA9PT0gJ29iamVjdCc7XHJcbiAgfSxcclxuXHJcbiAgZnVuY3Rpb246IGZ1bmN0aW9uIF9mdW5jdGlvbih0aGluZykge1xyXG4gICAgcmV0dXJuIHR5cGVvZiB0aGluZyA9PT0gJ2Z1bmN0aW9uJztcclxuICB9LFxyXG5cclxuICBudW1iZXI6IGZ1bmN0aW9uIG51bWJlcih0aGluZykge1xyXG4gICAgcmV0dXJuIHR5cGVvZiB0aGluZyA9PT0gJ251bWJlcic7XHJcbiAgfSxcclxuXHJcbiAgYm9vbDogZnVuY3Rpb24gYm9vbCh0aGluZykge1xyXG4gICAgcmV0dXJuIHR5cGVvZiB0aGluZyA9PT0gJ2Jvb2xlYW4nO1xyXG4gIH0sXHJcblxyXG4gIHN0cmluZzogZnVuY3Rpb24gc3RyaW5nKHRoaW5nKSB7XHJcbiAgICByZXR1cm4gdHlwZW9mIHRoaW5nID09PSAnc3RyaW5nJztcclxuICB9LFxyXG5cclxuICBlbGVtZW50OiBmdW5jdGlvbiBlbGVtZW50KHRoaW5nKSB7XHJcbiAgICBpZiAoIXRoaW5nIHx8ICh0eXBlb2YgdGhpbmcgPT09ICd1bmRlZmluZWQnID8gJ3VuZGVmaW5lZCcgOiBfdHlwZW9mKHRoaW5nKSkgIT09ICdvYmplY3QnKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgX3dpbmRvdyA9IHdpbi5nZXRXaW5kb3codGhpbmcpIHx8IHdpbi53aW5kb3c7XHJcblxyXG4gICAgcmV0dXJuICgvb2JqZWN0fGZ1bmN0aW9uLy50ZXN0KF90eXBlb2YoX3dpbmRvdy5FbGVtZW50KSkgPyB0aGluZyBpbnN0YW5jZW9mIF93aW5kb3cuRWxlbWVudCAvL0RPTTJcclxuICAgICAgOiB0aGluZy5ub2RlVHlwZSA9PT0gMSAmJiB0eXBlb2YgdGhpbmcubm9kZU5hbWUgPT09ICdzdHJpbmcnXHJcbiAgICApO1xyXG4gIH1cclxufTtcclxuXHJcbmlzLmFycmF5ID0gZnVuY3Rpb24gKHRoaW5nKSB7XHJcbiAgcmV0dXJuIGlzLm9iamVjdCh0aGluZykgJiYgdHlwZW9mIHRoaW5nLmxlbmd0aCAhPT0gJ3VuZGVmaW5lZCcgJiYgaXMuZnVuY3Rpb24odGhpbmcuc3BsaWNlKTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gaXM7XHJcblxyXG59LHtcIi4vaXNXaW5kb3dcIjo0NyxcIi4vd2luZG93XCI6NTJ9XSw0NzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcblwidXNlIHN0cmljdFwiO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAodGhpbmcpIHtcclxuICByZXR1cm4gISEodGhpbmcgJiYgdGhpbmcuV2luZG93KSAmJiB0aGluZyBpbnN0YW5jZW9mIHRoaW5nLldpbmRvdztcclxufTtcclxuXHJcbn0se31dLDQ4OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxuZnVuY3Rpb24gcG9pbnRlckV4dGVuZChkZXN0LCBzb3VyY2UpIHtcclxuICBmb3IgKHZhciBwcm9wIGluIHNvdXJjZSkge1xyXG4gICAgdmFyIHByZWZpeGVkUHJvcFJFcyA9IG1vZHVsZS5leHBvcnRzLnByZWZpeGVkUHJvcFJFcztcclxuICAgIHZhciBkZXByZWNhdGVkID0gZmFsc2U7XHJcblxyXG4gICAgLy8gc2tpcCBkZXByZWNhdGVkIHByZWZpeGVkIHByb3BlcnRpZXNcclxuICAgIGZvciAodmFyIHZlbmRvciBpbiBwcmVmaXhlZFByb3BSRXMpIHtcclxuICAgICAgaWYgKHByb3AuaW5kZXhPZih2ZW5kb3IpID09PSAwICYmIHByZWZpeGVkUHJvcFJFc1t2ZW5kb3JdLnRlc3QocHJvcCkpIHtcclxuICAgICAgICBkZXByZWNhdGVkID0gdHJ1ZTtcclxuICAgICAgICBicmVhaztcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmICghZGVwcmVjYXRlZCAmJiB0eXBlb2Ygc291cmNlW3Byb3BdICE9PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgIGRlc3RbcHJvcF0gPSBzb3VyY2VbcHJvcF07XHJcbiAgICB9XHJcbiAgfVxyXG4gIHJldHVybiBkZXN0O1xyXG59XHJcblxyXG5wb2ludGVyRXh0ZW5kLnByZWZpeGVkUHJvcFJFcyA9IHtcclxuICB3ZWJraXQ6IC8oTW92ZW1lbnRbWFldfFJhZGl1c1tYWV18Um90YXRpb25BbmdsZXxGb3JjZSkkL1xyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBwb2ludGVyRXh0ZW5kO1xyXG5cclxufSx7fV0sNDk6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xyXG4ndXNlIHN0cmljdCc7XHJcblxyXG52YXIgaHlwb3QgPSByZXF1aXJlKCcuL2h5cG90Jyk7XHJcbnZhciBicm93c2VyID0gcmVxdWlyZSgnLi9icm93c2VyJyk7XHJcbnZhciBkb20gPSByZXF1aXJlKCcuL2RvbU9iamVjdHMnKTtcclxudmFyIGRvbVV0aWxzID0gcmVxdWlyZSgnLi9kb21VdGlscycpO1xyXG52YXIgZG9tT2JqZWN0cyA9IHJlcXVpcmUoJy4vZG9tT2JqZWN0cycpO1xyXG52YXIgaXMgPSByZXF1aXJlKCcuL2lzJyk7XHJcbnZhciBwb2ludGVyRXh0ZW5kID0gcmVxdWlyZSgnLi9wb2ludGVyRXh0ZW5kJyk7XHJcblxyXG52YXIgcG9pbnRlclV0aWxzID0ge1xyXG4gIGNvcHlDb29yZHM6IGZ1bmN0aW9uIGNvcHlDb29yZHMoZGVzdCwgc3JjKSB7XHJcbiAgICBkZXN0LnBhZ2UgPSBkZXN0LnBhZ2UgfHwge307XHJcbiAgICBkZXN0LnBhZ2UueCA9IHNyYy5wYWdlLng7XHJcbiAgICBkZXN0LnBhZ2UueSA9IHNyYy5wYWdlLnk7XHJcblxyXG4gICAgZGVzdC5jbGllbnQgPSBkZXN0LmNsaWVudCB8fCB7fTtcclxuICAgIGRlc3QuY2xpZW50LnggPSBzcmMuY2xpZW50Lng7XHJcbiAgICBkZXN0LmNsaWVudC55ID0gc3JjLmNsaWVudC55O1xyXG5cclxuICAgIGRlc3QudGltZVN0YW1wID0gc3JjLnRpbWVTdGFtcDtcclxuICB9LFxyXG5cclxuICBzZXRDb29yZERlbHRhczogZnVuY3Rpb24gc2V0Q29vcmREZWx0YXModGFyZ2V0T2JqLCBwcmV2LCBjdXIpIHtcclxuICAgIHRhcmdldE9iai5wYWdlLnggPSBjdXIucGFnZS54IC0gcHJldi5wYWdlLng7XHJcbiAgICB0YXJnZXRPYmoucGFnZS55ID0gY3VyLnBhZ2UueSAtIHByZXYucGFnZS55O1xyXG4gICAgdGFyZ2V0T2JqLmNsaWVudC54ID0gY3VyLmNsaWVudC54IC0gcHJldi5jbGllbnQueDtcclxuICAgIHRhcmdldE9iai5jbGllbnQueSA9IGN1ci5jbGllbnQueSAtIHByZXYuY2xpZW50Lnk7XHJcbiAgICB0YXJnZXRPYmoudGltZVN0YW1wID0gY3VyLnRpbWVTdGFtcCAtIHByZXYudGltZVN0YW1wO1xyXG5cclxuICAgIC8vIHNldCBwb2ludGVyIHZlbG9jaXR5XHJcbiAgICB2YXIgZHQgPSBNYXRoLm1heCh0YXJnZXRPYmoudGltZVN0YW1wIC8gMTAwMCwgMC4wMDEpO1xyXG5cclxuICAgIHRhcmdldE9iai5wYWdlLnNwZWVkID0gaHlwb3QodGFyZ2V0T2JqLnBhZ2UueCwgdGFyZ2V0T2JqLnBhZ2UueSkgLyBkdDtcclxuICAgIHRhcmdldE9iai5wYWdlLnZ4ID0gdGFyZ2V0T2JqLnBhZ2UueCAvIGR0O1xyXG4gICAgdGFyZ2V0T2JqLnBhZ2UudnkgPSB0YXJnZXRPYmoucGFnZS55IC8gZHQ7XHJcblxyXG4gICAgdGFyZ2V0T2JqLmNsaWVudC5zcGVlZCA9IGh5cG90KHRhcmdldE9iai5jbGllbnQueCwgdGFyZ2V0T2JqLnBhZ2UueSkgLyBkdDtcclxuICAgIHRhcmdldE9iai5jbGllbnQudnggPSB0YXJnZXRPYmouY2xpZW50LnggLyBkdDtcclxuICAgIHRhcmdldE9iai5jbGllbnQudnkgPSB0YXJnZXRPYmouY2xpZW50LnkgLyBkdDtcclxuICB9LFxyXG5cclxuICBpc05hdGl2ZVBvaW50ZXI6IGZ1bmN0aW9uIGlzTmF0aXZlUG9pbnRlcihwb2ludGVyKSB7XHJcbiAgICByZXR1cm4gcG9pbnRlciBpbnN0YW5jZW9mIGRvbS5FdmVudCB8fCBwb2ludGVyIGluc3RhbmNlb2YgZG9tLlRvdWNoO1xyXG4gIH0sXHJcblxyXG4gIC8vIEdldCBzcGVjaWZpZWQgWC9ZIGNvb3JkcyBmb3IgbW91c2Ugb3IgZXZlbnQudG91Y2hlc1swXVxyXG4gIGdldFhZOiBmdW5jdGlvbiBnZXRYWSh0eXBlLCBwb2ludGVyLCB4eSkge1xyXG4gICAgeHkgPSB4eSB8fCB7fTtcclxuICAgIHR5cGUgPSB0eXBlIHx8ICdwYWdlJztcclxuXHJcbiAgICB4eS54ID0gcG9pbnRlclt0eXBlICsgJ1gnXTtcclxuICAgIHh5LnkgPSBwb2ludGVyW3R5cGUgKyAnWSddO1xyXG5cclxuICAgIHJldHVybiB4eTtcclxuICB9LFxyXG5cclxuICBnZXRQYWdlWFk6IGZ1bmN0aW9uIGdldFBhZ2VYWShwb2ludGVyLCBwYWdlKSB7XHJcbiAgICBwYWdlID0gcGFnZSB8fCB7fTtcclxuXHJcbiAgICAvLyBPcGVyYSBNb2JpbGUgaGFuZGxlcyB0aGUgdmlld3BvcnQgYW5kIHNjcm9sbGluZyBvZGRseVxyXG4gICAgaWYgKGJyb3dzZXIuaXNPcGVyYU1vYmlsZSAmJiBwb2ludGVyVXRpbHMuaXNOYXRpdmVQb2ludGVyKHBvaW50ZXIpKSB7XHJcbiAgICAgIHBvaW50ZXJVdGlscy5nZXRYWSgnc2NyZWVuJywgcG9pbnRlciwgcGFnZSk7XHJcblxyXG4gICAgICBwYWdlLnggKz0gd2luZG93LnNjcm9sbFg7XHJcbiAgICAgIHBhZ2UueSArPSB3aW5kb3cuc2Nyb2xsWTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHBvaW50ZXJVdGlscy5nZXRYWSgncGFnZScsIHBvaW50ZXIsIHBhZ2UpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBwYWdlO1xyXG4gIH0sXHJcblxyXG4gIGdldENsaWVudFhZOiBmdW5jdGlvbiBnZXRDbGllbnRYWShwb2ludGVyLCBjbGllbnQpIHtcclxuICAgIGNsaWVudCA9IGNsaWVudCB8fCB7fTtcclxuXHJcbiAgICBpZiAoYnJvd3Nlci5pc09wZXJhTW9iaWxlICYmIHBvaW50ZXJVdGlscy5pc05hdGl2ZVBvaW50ZXIocG9pbnRlcikpIHtcclxuICAgICAgLy8gT3BlcmEgTW9iaWxlIGhhbmRsZXMgdGhlIHZpZXdwb3J0IGFuZCBzY3JvbGxpbmcgb2RkbHlcclxuICAgICAgcG9pbnRlclV0aWxzLmdldFhZKCdzY3JlZW4nLCBwb2ludGVyLCBjbGllbnQpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcG9pbnRlclV0aWxzLmdldFhZKCdjbGllbnQnLCBwb2ludGVyLCBjbGllbnQpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBjbGllbnQ7XHJcbiAgfSxcclxuXHJcbiAgZ2V0UG9pbnRlcklkOiBmdW5jdGlvbiBnZXRQb2ludGVySWQocG9pbnRlcikge1xyXG4gICAgcmV0dXJuIGlzLm51bWJlcihwb2ludGVyLnBvaW50ZXJJZCkgPyBwb2ludGVyLnBvaW50ZXJJZCA6IHBvaW50ZXIuaWRlbnRpZmllcjtcclxuICB9LFxyXG5cclxuICBzZXRDb29yZHM6IGZ1bmN0aW9uIHNldENvb3Jkcyh0YXJnZXRPYmosIHBvaW50ZXJzLCB0aW1lU3RhbXApIHtcclxuICAgIHZhciBwb2ludGVyID0gcG9pbnRlcnMubGVuZ3RoID4gMSA/IHBvaW50ZXJVdGlscy5wb2ludGVyQXZlcmFnZShwb2ludGVycykgOiBwb2ludGVyc1swXTtcclxuXHJcbiAgICB2YXIgdG1wWFkgPSB7fTtcclxuXHJcbiAgICBwb2ludGVyVXRpbHMuZ2V0UGFnZVhZKHBvaW50ZXIsIHRtcFhZKTtcclxuICAgIHRhcmdldE9iai5wYWdlLnggPSB0bXBYWS54O1xyXG4gICAgdGFyZ2V0T2JqLnBhZ2UueSA9IHRtcFhZLnk7XHJcblxyXG4gICAgcG9pbnRlclV0aWxzLmdldENsaWVudFhZKHBvaW50ZXIsIHRtcFhZKTtcclxuICAgIHRhcmdldE9iai5jbGllbnQueCA9IHRtcFhZLng7XHJcbiAgICB0YXJnZXRPYmouY2xpZW50LnkgPSB0bXBYWS55O1xyXG5cclxuICAgIHRhcmdldE9iai50aW1lU3RhbXAgPSBpcy5udW1iZXIodGltZVN0YW1wKSA/IHRpbWVTdGFtcCA6IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xyXG4gIH0sXHJcblxyXG4gIHBvaW50ZXJFeHRlbmQ6IHBvaW50ZXJFeHRlbmQsXHJcblxyXG4gIGdldFRvdWNoUGFpcjogZnVuY3Rpb24gZ2V0VG91Y2hQYWlyKGV2ZW50KSB7XHJcbiAgICB2YXIgdG91Y2hlcyA9IFtdO1xyXG5cclxuICAgIC8vIGFycmF5IG9mIHRvdWNoZXMgaXMgc3VwcGxpZWRcclxuICAgIGlmIChpcy5hcnJheShldmVudCkpIHtcclxuICAgICAgdG91Y2hlc1swXSA9IGV2ZW50WzBdO1xyXG4gICAgICB0b3VjaGVzWzFdID0gZXZlbnRbMV07XHJcbiAgICB9XHJcbiAgICAvLyBhbiBldmVudFxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgaWYgKGV2ZW50LnR5cGUgPT09ICd0b3VjaGVuZCcpIHtcclxuICAgICAgICAgIGlmIChldmVudC50b3VjaGVzLmxlbmd0aCA9PT0gMSkge1xyXG4gICAgICAgICAgICB0b3VjaGVzWzBdID0gZXZlbnQudG91Y2hlc1swXTtcclxuICAgICAgICAgICAgdG91Y2hlc1sxXSA9IGV2ZW50LmNoYW5nZWRUb3VjaGVzWzBdO1xyXG4gICAgICAgICAgfSBlbHNlIGlmIChldmVudC50b3VjaGVzLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgICAgICB0b3VjaGVzWzBdID0gZXZlbnQuY2hhbmdlZFRvdWNoZXNbMF07XHJcbiAgICAgICAgICAgIHRvdWNoZXNbMV0gPSBldmVudC5jaGFuZ2VkVG91Y2hlc1sxXTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgdG91Y2hlc1swXSA9IGV2ZW50LnRvdWNoZXNbMF07XHJcbiAgICAgICAgICB0b3VjaGVzWzFdID0gZXZlbnQudG91Y2hlc1sxXTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICByZXR1cm4gdG91Y2hlcztcclxuICB9LFxyXG5cclxuICBwb2ludGVyQXZlcmFnZTogZnVuY3Rpb24gcG9pbnRlckF2ZXJhZ2UocG9pbnRlcnMpIHtcclxuICAgIHZhciBhdmVyYWdlID0ge1xyXG4gICAgICBwYWdlWDogMCxcclxuICAgICAgcGFnZVk6IDAsXHJcbiAgICAgIGNsaWVudFg6IDAsXHJcbiAgICAgIGNsaWVudFk6IDAsXHJcbiAgICAgIHNjcmVlblg6IDAsXHJcbiAgICAgIHNjcmVlblk6IDBcclxuICAgIH07XHJcblxyXG4gICAgZm9yICh2YXIgX2l0ZXJhdG9yID0gcG9pbnRlcnMsIF9pc0FycmF5ID0gQXJyYXkuaXNBcnJheShfaXRlcmF0b3IpLCBfaSA9IDAsIF9pdGVyYXRvciA9IF9pc0FycmF5ID8gX2l0ZXJhdG9yIDogX2l0ZXJhdG9yW1N5bWJvbC5pdGVyYXRvcl0oKTs7KSB7XHJcbiAgICAgIHZhciBfcmVmO1xyXG5cclxuICAgICAgaWYgKF9pc0FycmF5KSB7XHJcbiAgICAgICAgaWYgKF9pID49IF9pdGVyYXRvci5sZW5ndGgpIGJyZWFrO1xyXG4gICAgICAgIF9yZWYgPSBfaXRlcmF0b3JbX2krK107XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgX2kgPSBfaXRlcmF0b3IubmV4dCgpO1xyXG4gICAgICAgIGlmIChfaS5kb25lKSBicmVhaztcclxuICAgICAgICBfcmVmID0gX2kudmFsdWU7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHZhciBwb2ludGVyID0gX3JlZjtcclxuXHJcbiAgICAgIGZvciAodmFyIF9wcm9wIGluIGF2ZXJhZ2UpIHtcclxuICAgICAgICBhdmVyYWdlW19wcm9wXSArPSBwb2ludGVyW19wcm9wXTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgZm9yICh2YXIgcHJvcCBpbiBhdmVyYWdlKSB7XHJcbiAgICAgIGF2ZXJhZ2VbcHJvcF0gLz0gcG9pbnRlcnMubGVuZ3RoO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBhdmVyYWdlO1xyXG4gIH0sXHJcblxyXG4gIHRvdWNoQkJveDogZnVuY3Rpb24gdG91Y2hCQm94KGV2ZW50KSB7XHJcbiAgICBpZiAoIWV2ZW50Lmxlbmd0aCAmJiAhKGV2ZW50LnRvdWNoZXMgJiYgZXZlbnQudG91Y2hlcy5sZW5ndGggPiAxKSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIHRvdWNoZXMgPSBwb2ludGVyVXRpbHMuZ2V0VG91Y2hQYWlyKGV2ZW50KTtcclxuICAgIHZhciBtaW5YID0gTWF0aC5taW4odG91Y2hlc1swXS5wYWdlWCwgdG91Y2hlc1sxXS5wYWdlWCk7XHJcbiAgICB2YXIgbWluWSA9IE1hdGgubWluKHRvdWNoZXNbMF0ucGFnZVksIHRvdWNoZXNbMV0ucGFnZVkpO1xyXG4gICAgdmFyIG1heFggPSBNYXRoLm1heCh0b3VjaGVzWzBdLnBhZ2VYLCB0b3VjaGVzWzFdLnBhZ2VYKTtcclxuICAgIHZhciBtYXhZID0gTWF0aC5tYXgodG91Y2hlc1swXS5wYWdlWSwgdG91Y2hlc1sxXS5wYWdlWSk7XHJcblxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgeDogbWluWCxcclxuICAgICAgeTogbWluWSxcclxuICAgICAgbGVmdDogbWluWCxcclxuICAgICAgdG9wOiBtaW5ZLFxyXG4gICAgICB3aWR0aDogbWF4WCAtIG1pblgsXHJcbiAgICAgIGhlaWdodDogbWF4WSAtIG1pbllcclxuICAgIH07XHJcbiAgfSxcclxuXHJcbiAgdG91Y2hEaXN0YW5jZTogZnVuY3Rpb24gdG91Y2hEaXN0YW5jZShldmVudCwgZGVsdGFTb3VyY2UpIHtcclxuICAgIHZhciBzb3VyY2VYID0gZGVsdGFTb3VyY2UgKyAnWCc7XHJcbiAgICB2YXIgc291cmNlWSA9IGRlbHRhU291cmNlICsgJ1knO1xyXG4gICAgdmFyIHRvdWNoZXMgPSBwb2ludGVyVXRpbHMuZ2V0VG91Y2hQYWlyKGV2ZW50KTtcclxuXHJcbiAgICB2YXIgZHggPSB0b3VjaGVzWzBdW3NvdXJjZVhdIC0gdG91Y2hlc1sxXVtzb3VyY2VYXTtcclxuICAgIHZhciBkeSA9IHRvdWNoZXNbMF1bc291cmNlWV0gLSB0b3VjaGVzWzFdW3NvdXJjZVldO1xyXG5cclxuICAgIHJldHVybiBoeXBvdChkeCwgZHkpO1xyXG4gIH0sXHJcblxyXG4gIHRvdWNoQW5nbGU6IGZ1bmN0aW9uIHRvdWNoQW5nbGUoZXZlbnQsIHByZXZBbmdsZSwgZGVsdGFTb3VyY2UpIHtcclxuICAgIHZhciBzb3VyY2VYID0gZGVsdGFTb3VyY2UgKyAnWCc7XHJcbiAgICB2YXIgc291cmNlWSA9IGRlbHRhU291cmNlICsgJ1knO1xyXG4gICAgdmFyIHRvdWNoZXMgPSBwb2ludGVyVXRpbHMuZ2V0VG91Y2hQYWlyKGV2ZW50KTtcclxuICAgIHZhciBkeCA9IHRvdWNoZXNbMV1bc291cmNlWF0gLSB0b3VjaGVzWzBdW3NvdXJjZVhdO1xyXG4gICAgdmFyIGR5ID0gdG91Y2hlc1sxXVtzb3VyY2VZXSAtIHRvdWNoZXNbMF1bc291cmNlWV07XHJcbiAgICB2YXIgYW5nbGUgPSAxODAgKiBNYXRoLmF0YW4yKGR5LCBkeCkgLyBNYXRoLlBJO1xyXG5cclxuICAgIHJldHVybiBhbmdsZTtcclxuICB9LFxyXG5cclxuICBnZXRQb2ludGVyVHlwZTogZnVuY3Rpb24gZ2V0UG9pbnRlclR5cGUocG9pbnRlcikge1xyXG4gICAgcmV0dXJuIGlzLnN0cmluZyhwb2ludGVyLnBvaW50ZXJUeXBlKSA/IHBvaW50ZXIucG9pbnRlclR5cGUgOiBpcy5udW1iZXIocG9pbnRlci5wb2ludGVyVHlwZSkgPyBbdW5kZWZpbmVkLCB1bmRlZmluZWQsICd0b3VjaCcsICdwZW4nLCAnbW91c2UnXVtwb2ludGVyLnBvaW50ZXJUeXBlXVxyXG4gICAgLy8gaWYgdGhlIFBvaW50ZXJFdmVudCBBUEkgaXNuJ3QgYXZhaWxhYmxlLCB0aGVuIHRoZSBcInBvaW50ZXJcIiBtdXN0XHJcbiAgICAvLyBiZSBlaXRoZXIgYSBNb3VzZUV2ZW50LCBUb3VjaEV2ZW50LCBvciBUb3VjaCBvYmplY3RcclxuICAgIDogL3RvdWNoLy50ZXN0KHBvaW50ZXIudHlwZSkgfHwgcG9pbnRlciBpbnN0YW5jZW9mIGRvbU9iamVjdHMuVG91Y2ggPyAndG91Y2gnIDogJ21vdXNlJztcclxuICB9LFxyXG5cclxuICAvLyBbIGV2ZW50LnRhcmdldCwgZXZlbnQuY3VycmVudFRhcmdldCBdXHJcbiAgZ2V0RXZlbnRUYXJnZXRzOiBmdW5jdGlvbiBnZXRFdmVudFRhcmdldHMoZXZlbnQpIHtcclxuICAgIHJldHVybiBbZG9tVXRpbHMuZ2V0QWN0dWFsRWxlbWVudChldmVudC5wYXRoID8gZXZlbnQucGF0aFswXSA6IGV2ZW50LnRhcmdldCksIGRvbVV0aWxzLmdldEFjdHVhbEVsZW1lbnQoZXZlbnQuY3VycmVudFRhcmdldCldO1xyXG4gIH1cclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gcG9pbnRlclV0aWxzO1xyXG5cclxufSx7XCIuL2Jyb3dzZXJcIjozNyxcIi4vZG9tT2JqZWN0c1wiOjM4LFwiLi9kb21VdGlsc1wiOjM5LFwiLi9oeXBvdFwiOjQzLFwiLi9pc1wiOjQ2LFwiLi9wb2ludGVyRXh0ZW5kXCI6NDh9XSw1MDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJy4vd2luZG93JyksXHJcbiAgICB3aW5kb3cgPSBfcmVxdWlyZS53aW5kb3c7XHJcblxyXG52YXIgdmVuZG9ycyA9IFsnbXMnLCAnbW96JywgJ3dlYmtpdCcsICdvJ107XHJcbnZhciBsYXN0VGltZSA9IDA7XHJcbnZhciByZXF1ZXN0ID0gdm9pZCAwO1xyXG52YXIgY2FuY2VsID0gdm9pZCAwO1xyXG5cclxuZm9yICh2YXIgeCA9IDA7IHggPCB2ZW5kb3JzLmxlbmd0aCAmJiAhd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZTsgeCsrKSB7XHJcbiAgcmVxdWVzdCA9IHdpbmRvd1t2ZW5kb3JzW3hdICsgJ1JlcXVlc3RBbmltYXRpb25GcmFtZSddO1xyXG4gIGNhbmNlbCA9IHdpbmRvd1t2ZW5kb3JzW3hdICsgJ0NhbmNlbEFuaW1hdGlvbkZyYW1lJ10gfHwgd2luZG93W3ZlbmRvcnNbeF0gKyAnQ2FuY2VsUmVxdWVzdEFuaW1hdGlvbkZyYW1lJ107XHJcbn1cclxuXHJcbmlmICghcmVxdWVzdCkge1xyXG4gIHJlcXVlc3QgPSBmdW5jdGlvbiByZXF1ZXN0KGNhbGxiYWNrKSB7XHJcbiAgICB2YXIgY3VyclRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcclxuICAgIHZhciB0aW1lVG9DYWxsID0gTWF0aC5tYXgoMCwgMTYgLSAoY3VyclRpbWUgLSBsYXN0VGltZSkpO1xyXG4gICAgdmFyIGlkID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgIGNhbGxiYWNrKGN1cnJUaW1lICsgdGltZVRvQ2FsbCk7XHJcbiAgICB9LCB0aW1lVG9DYWxsKTtcclxuXHJcbiAgICBsYXN0VGltZSA9IGN1cnJUaW1lICsgdGltZVRvQ2FsbDtcclxuICAgIHJldHVybiBpZDtcclxuICB9O1xyXG59XHJcblxyXG5pZiAoIWNhbmNlbCkge1xyXG4gIGNhbmNlbCA9IGZ1bmN0aW9uIGNhbmNlbChpZCkge1xyXG4gICAgY2xlYXJUaW1lb3V0KGlkKTtcclxuICB9O1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHtcclxuICByZXF1ZXN0OiByZXF1ZXN0LFxyXG4gIGNhbmNlbDogY2FuY2VsXHJcbn07XHJcblxyXG59LHtcIi4vd2luZG93XCI6NTJ9XSw1MTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBleHRlbmQgPSByZXF1aXJlKCcuL2V4dGVuZCcpO1xyXG52YXIgaXMgPSByZXF1aXJlKCcuL2lzJyk7XHJcblxyXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCcuL2RvbVV0aWxzJyksXHJcbiAgICBjbG9zZXN0ID0gX3JlcXVpcmUuY2xvc2VzdCxcclxuICAgIHBhcmVudE5vZGUgPSBfcmVxdWlyZS5wYXJlbnROb2RlLFxyXG4gICAgZ2V0RWxlbWVudFJlY3QgPSBfcmVxdWlyZS5nZXRFbGVtZW50UmVjdDtcclxuXHJcbnZhciByZWN0VXRpbHMgPSB7XHJcbiAgZ2V0U3RyaW5nT3B0aW9uUmVzdWx0OiBmdW5jdGlvbiBnZXRTdHJpbmdPcHRpb25SZXN1bHQodmFsdWUsIGludGVyYWN0YWJsZSwgZWxlbWVudCkge1xyXG4gICAgaWYgKCFpcy5zdHJpbmcodmFsdWUpKSB7XHJcbiAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh2YWx1ZSA9PT0gJ3BhcmVudCcpIHtcclxuICAgICAgdmFsdWUgPSBwYXJlbnROb2RlKGVsZW1lbnQpO1xyXG4gICAgfSBlbHNlIGlmICh2YWx1ZSA9PT0gJ3NlbGYnKSB7XHJcbiAgICAgIHZhbHVlID0gaW50ZXJhY3RhYmxlLmdldFJlY3QoZWxlbWVudCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB2YWx1ZSA9IGNsb3Nlc3QoZWxlbWVudCwgdmFsdWUpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB2YWx1ZTtcclxuICB9LFxyXG5cclxuICByZXNvbHZlUmVjdExpa2U6IGZ1bmN0aW9uIHJlc29sdmVSZWN0TGlrZSh2YWx1ZSwgaW50ZXJhY3RhYmxlLCBlbGVtZW50LCBmdW5jdGlvbkFyZ3MpIHtcclxuICAgIHZhbHVlID0gcmVjdFV0aWxzLmdldFN0cmluZ09wdGlvblJlc3VsdCh2YWx1ZSwgaW50ZXJhY3RhYmxlLCBlbGVtZW50KSB8fCB2YWx1ZTtcclxuXHJcbiAgICBpZiAoaXMuZnVuY3Rpb24odmFsdWUpKSB7XHJcbiAgICAgIHZhbHVlID0gdmFsdWUuYXBwbHkobnVsbCwgZnVuY3Rpb25BcmdzKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoaXMuZWxlbWVudCh2YWx1ZSkpIHtcclxuICAgICAgdmFsdWUgPSBnZXRFbGVtZW50UmVjdCh2YWx1ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHZhbHVlO1xyXG4gIH0sXHJcblxyXG4gIHJlY3RUb1hZOiBmdW5jdGlvbiByZWN0VG9YWShyZWN0KSB7XHJcbiAgICByZXR1cm4gcmVjdCAmJiB7XHJcbiAgICAgIHg6ICd4JyBpbiByZWN0ID8gcmVjdC54IDogcmVjdC5sZWZ0LFxyXG4gICAgICB5OiAneScgaW4gcmVjdCA/IHJlY3QueSA6IHJlY3QudG9wXHJcbiAgICB9O1xyXG4gIH0sXHJcblxyXG4gIHh5d2hUb1RsYnI6IGZ1bmN0aW9uIHh5d2hUb1RsYnIocmVjdCkge1xyXG4gICAgaWYgKHJlY3QgJiYgISgnbGVmdCcgaW4gcmVjdCAmJiAndG9wJyBpbiByZWN0KSkge1xyXG4gICAgICByZWN0ID0gZXh0ZW5kKHt9LCByZWN0KTtcclxuXHJcbiAgICAgIHJlY3QubGVmdCA9IHJlY3QueCB8fCAwO1xyXG4gICAgICByZWN0LnRvcCA9IHJlY3QueSB8fCAwO1xyXG4gICAgICByZWN0LnJpZ2h0ID0gcmVjdC5yaWdodCB8fCByZWN0LmxlZnQgKyByZWN0LndpZHRoO1xyXG4gICAgICByZWN0LmJvdHRvbSA9IHJlY3QuYm90dG9tIHx8IHJlY3QudG9wICsgcmVjdC5oZWlnaHQ7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHJlY3Q7XHJcbiAgfSxcclxuXHJcbiAgdGxiclRvWHl3aDogZnVuY3Rpb24gdGxiclRvWHl3aChyZWN0KSB7XHJcbiAgICBpZiAocmVjdCAmJiAhKCd4JyBpbiByZWN0ICYmICd5JyBpbiByZWN0KSkge1xyXG4gICAgICByZWN0ID0gZXh0ZW5kKHt9LCByZWN0KTtcclxuXHJcbiAgICAgIHJlY3QueCA9IHJlY3QubGVmdCB8fCAwO1xyXG4gICAgICByZWN0LnRvcCA9IHJlY3QudG9wIHx8IDA7XHJcbiAgICAgIHJlY3Qud2lkdGggPSByZWN0LndpZHRoIHx8IHJlY3QucmlnaHQgLSByZWN0Lng7XHJcbiAgICAgIHJlY3QuaGVpZ2h0ID0gcmVjdC5oZWlnaHQgfHwgcmVjdC5ib3R0b20gLSByZWN0Lnk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHJlY3Q7XHJcbiAgfVxyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSByZWN0VXRpbHM7XHJcblxyXG59LHtcIi4vZG9tVXRpbHNcIjozOSxcIi4vZXh0ZW5kXCI6NDEsXCIuL2lzXCI6NDZ9XSw1MjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciB3aW4gPSBtb2R1bGUuZXhwb3J0cztcclxudmFyIGlzV2luZG93ID0gcmVxdWlyZSgnLi9pc1dpbmRvdycpO1xyXG5cclxuZnVuY3Rpb24gaW5pdCh3aW5kb3cpIHtcclxuICAvLyBnZXQgd3JhcHBlZCB3aW5kb3cgaWYgdXNpbmcgU2hhZG93IERPTSBwb2x5ZmlsbFxyXG5cclxuICB3aW4ucmVhbFdpbmRvdyA9IHdpbmRvdztcclxuXHJcbiAgLy8gY3JlYXRlIGEgVGV4dE5vZGVcclxuICB2YXIgZWwgPSB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoJycpO1xyXG5cclxuICAvLyBjaGVjayBpZiBpdCdzIHdyYXBwZWQgYnkgYSBwb2x5ZmlsbFxyXG4gIGlmIChlbC5vd25lckRvY3VtZW50ICE9PSB3aW5kb3cuZG9jdW1lbnQgJiYgdHlwZW9mIHdpbmRvdy53cmFwID09PSAnZnVuY3Rpb24nICYmIHdpbmRvdy53cmFwKGVsKSA9PT0gZWwpIHtcclxuICAgIC8vIHVzZSB3cmFwcGVkIHdpbmRvd1xyXG4gICAgd2luZG93ID0gd2luZG93LndyYXAod2luZG93KTtcclxuICB9XHJcblxyXG4gIHdpbi53aW5kb3cgPSB3aW5kb3c7XHJcbn1cclxuXHJcbmlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykge1xyXG4gIHdpbi53aW5kb3cgPSB1bmRlZmluZWQ7XHJcbiAgd2luLnJlYWxXaW5kb3cgPSB1bmRlZmluZWQ7XHJcbn0gZWxzZSB7XHJcbiAgaW5pdCh3aW5kb3cpO1xyXG59XHJcblxyXG53aW4uZ2V0V2luZG93ID0gZnVuY3Rpb24gZ2V0V2luZG93KG5vZGUpIHtcclxuICBpZiAoaXNXaW5kb3cobm9kZSkpIHtcclxuICAgIHJldHVybiBub2RlO1xyXG4gIH1cclxuXHJcbiAgdmFyIHJvb3ROb2RlID0gbm9kZS5vd25lckRvY3VtZW50IHx8IG5vZGU7XHJcblxyXG4gIHJldHVybiByb290Tm9kZS5kZWZhdWx0VmlldyB8fCByb290Tm9kZS5wYXJlbnRXaW5kb3cgfHwgd2luLndpbmRvdztcclxufTtcclxuXHJcbndpbi5pbml0ID0gaW5pdDtcclxuXHJcbn0se1wiLi9pc1dpbmRvd1wiOjQ3fV19LHt9LFsxXSkoMSlcclxufSk7XHJcblxyXG5cclxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW50ZXJhY3QuanMubWFwXHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vbm9kZV9tb2R1bGVzL2ludGVyYWN0anMvZGlzdC9pbnRlcmFjdC5qc1xuLy8gbW9kdWxlIGlkID0gMTVcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///15\n"); - -/***/ }), -/* 16 */ -/***/ (function(module, exports, __webpack_require__) { - -eval("module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('div', {\n ref: \"item\",\n staticClass: \"vue-grid-item\",\n class: {\n 'vue-resizable': _vm.resizable, 'resizing': _vm.isResizing, 'vue-draggable-dragging': _vm.isDragging, 'cssTransforms': _vm.useCssTransforms, 'render-rtl': _vm.renderRtl\n },\n style: (_vm.style)\n }, [_vm._t(\"default\"), _vm._v(\" \"), (_vm.resizable) ? _c('span', {\n ref: \"handle\",\n class: _vm.resizableHandleClass\n }) : _vm._e()], 2)\n},staticRenderFns: []}\nmodule.exports.render._withStripped = true\nif (false) {\n module.hot.accept()\n if (module.hot.data) {\n require(\"vue-hot-reload-api\").rerender(\"data-v-f2ef9cd2\", module.exports)\n }\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvR3JpZEl0ZW0udnVlPzEyMDIiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsZ0JBQWdCLG1CQUFtQixhQUFhLDBCQUEwQjtBQUMxRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6IjE2LmpzIiwic291cmNlc0NvbnRlbnQiOlsibW9kdWxlLmV4cG9ydHM9e3JlbmRlcjpmdW5jdGlvbiAoKXt2YXIgX3ZtPXRoaXM7dmFyIF9oPV92bS4kY3JlYXRlRWxlbWVudDt2YXIgX2M9X3ZtLl9zZWxmLl9jfHxfaDtcbiAgcmV0dXJuIF9jKCdkaXYnLCB7XG4gICAgcmVmOiBcIml0ZW1cIixcbiAgICBzdGF0aWNDbGFzczogXCJ2dWUtZ3JpZC1pdGVtXCIsXG4gICAgY2xhc3M6IHtcbiAgICAgICd2dWUtcmVzaXphYmxlJzogX3ZtLnJlc2l6YWJsZSwgJ3Jlc2l6aW5nJzogX3ZtLmlzUmVzaXppbmcsICd2dWUtZHJhZ2dhYmxlLWRyYWdnaW5nJzogX3ZtLmlzRHJhZ2dpbmcsICdjc3NUcmFuc2Zvcm1zJzogX3ZtLnVzZUNzc1RyYW5zZm9ybXMsICdyZW5kZXItcnRsJzogX3ZtLnJlbmRlclJ0bFxuICAgIH0sXG4gICAgc3R5bGU6IChfdm0uc3R5bGUpXG4gIH0sIFtfdm0uX3QoXCJkZWZhdWx0XCIpLCBfdm0uX3YoXCIgXCIpLCAoX3ZtLnJlc2l6YWJsZSkgPyBfYygnc3BhbicsIHtcbiAgICByZWY6IFwiaGFuZGxlXCIsXG4gICAgY2xhc3M6IF92bS5yZXNpemFibGVIYW5kbGVDbGFzc1xuICB9KSA6IF92bS5fZSgpXSwgMilcbn0sc3RhdGljUmVuZGVyRm5zOiBbXX1cbm1vZHVsZS5leHBvcnRzLnJlbmRlci5fd2l0aFN0cmlwcGVkID0gdHJ1ZVxuaWYgKG1vZHVsZS5ob3QpIHtcbiAgbW9kdWxlLmhvdC5hY2NlcHQoKVxuICBpZiAobW9kdWxlLmhvdC5kYXRhKSB7XG4gICAgIHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIikucmVyZW5kZXIoXCJkYXRhLXYtZjJlZjljZDJcIiwgbW9kdWxlLmV4cG9ydHMpXG4gIH1cbn1cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi90ZW1wbGF0ZS1jb21waWxlcj97XCJpZFwiOlwiZGF0YS12LWYyZWY5Y2QyXCJ9IS4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9dGVtcGxhdGUmaW5kZXg9MCEuL3NyYy9HcmlkSXRlbS52dWVcbi8vIG1vZHVsZSBpZCA9IDE2XG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///16\n"); - -/***/ }), -/* 17 */ -/***/ (function(module, exports, __webpack_require__) { - -eval("\n/* styles */\n__webpack_require__(18)\n\nvar Component = __webpack_require__(4)(\n /* script */\n __webpack_require__(20),\n /* template */\n __webpack_require__(33),\n /* scopeId */\n null,\n /* cssModules */\n null\n)\nComponent.options.__file = \"C:\\\\projects\\\\JBAY\\\\vue-grid-layout\\\\src\\\\GridLayout.vue\"\nif (Component.esModule && Object.keys(Component.esModule).some(function (key) {return key !== \"default\" && key !== \"__esModule\"})) {console.error(\"named exports are not supported in *.vue files.\")}\nif (Component.options.functional) {console.error(\"[vue-loader] GridLayout.vue: functional components are not supported with templates, they should use render functions.\")}\n\n/* hot reload */\nif (false) {(function () {\n var hotAPI = require(\"vue-hot-reload-api\")\n hotAPI.install(require(\"vue\"), false)\n if (!hotAPI.compatible) return\n module.hot.accept()\n if (!module.hot.data) {\n hotAPI.createRecord(\"data-v-3d4bb9a4\", Component.options)\n } else {\n hotAPI.reload(\"data-v-3d4bb9a4\", Component.options)\n }\n})()}\n\nmodule.exports = Component.exports\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvR3JpZExheW91dC52dWU/OGFiMCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQ0E7QUFDQSxzQkFBNEs7O0FBRTVLO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQWdHO0FBQ2hHO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtFQUErRSxpREFBaUQsSUFBSTtBQUNwSSxtQ0FBbUM7O0FBRW5DO0FBQ0EsWUFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxDQUFDOztBQUVEIiwiZmlsZSI6IjE3LmpzIiwic291cmNlc0NvbnRlbnQiOlsiXG4vKiBzdHlsZXMgKi9cbnJlcXVpcmUoXCIhIXZ1ZS1zdHlsZS1sb2FkZXIhY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLWNvbXBpbGVyL2luZGV4P3tcXFwiaWRcXFwiOlxcXCJkYXRhLXYtM2Q0YmI5YTRcXFwiLFxcXCJzY29wZWRcXFwiOmZhbHNlLFxcXCJoYXNJbmxpbmVDb25maWdcXFwiOmZhbHNlfSEuLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3I/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL0dyaWRMYXlvdXQudnVlXCIpXG5cbnZhciBDb21wb25lbnQgPSByZXF1aXJlKFwiIS4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9jb21wb25lbnQtbm9ybWFsaXplclwiKShcbiAgLyogc2NyaXB0ICovXG4gIHJlcXVpcmUoXCIhIWJhYmVsLWxvYWRlciEuLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3I/dHlwZT1zY3JpcHQmaW5kZXg9MCEuL0dyaWRMYXlvdXQudnVlXCIpLFxuICAvKiB0ZW1wbGF0ZSAqL1xuICByZXF1aXJlKFwiISEuLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvdGVtcGxhdGUtY29tcGlsZXIvaW5kZXg/e1xcXCJpZFxcXCI6XFxcImRhdGEtdi0zZDRiYjlhNFxcXCJ9IS4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvcj90eXBlPXRlbXBsYXRlJmluZGV4PTAhLi9HcmlkTGF5b3V0LnZ1ZVwiKSxcbiAgLyogc2NvcGVJZCAqL1xuICBudWxsLFxuICAvKiBjc3NNb2R1bGVzICovXG4gIG51bGxcbilcbkNvbXBvbmVudC5vcHRpb25zLl9fZmlsZSA9IFwiQzpcXFxccHJvamVjdHNcXFxcSkJBWVxcXFx2dWUtZ3JpZC1sYXlvdXRcXFxcc3JjXFxcXEdyaWRMYXlvdXQudnVlXCJcbmlmIChDb21wb25lbnQuZXNNb2R1bGUgJiYgT2JqZWN0LmtleXMoQ29tcG9uZW50LmVzTW9kdWxlKS5zb21lKGZ1bmN0aW9uIChrZXkpIHtyZXR1cm4ga2V5ICE9PSBcImRlZmF1bHRcIiAmJiBrZXkgIT09IFwiX19lc01vZHVsZVwifSkpIHtjb25zb2xlLmVycm9yKFwibmFtZWQgZXhwb3J0cyBhcmUgbm90IHN1cHBvcnRlZCBpbiAqLnZ1ZSBmaWxlcy5cIil9XG5pZiAoQ29tcG9uZW50Lm9wdGlvbnMuZnVuY3Rpb25hbCkge2NvbnNvbGUuZXJyb3IoXCJbdnVlLWxvYWRlcl0gR3JpZExheW91dC52dWU6IGZ1bmN0aW9uYWwgY29tcG9uZW50cyBhcmUgbm90IHN1cHBvcnRlZCB3aXRoIHRlbXBsYXRlcywgdGhleSBzaG91bGQgdXNlIHJlbmRlciBmdW5jdGlvbnMuXCIpfVxuXG4vKiBob3QgcmVsb2FkICovXG5pZiAobW9kdWxlLmhvdCkgeyhmdW5jdGlvbiAoKSB7XG4gIHZhciBob3RBUEkgPSByZXF1aXJlKFwidnVlLWhvdC1yZWxvYWQtYXBpXCIpXG4gIGhvdEFQSS5pbnN0YWxsKHJlcXVpcmUoXCJ2dWVcIiksIGZhbHNlKVxuICBpZiAoIWhvdEFQSS5jb21wYXRpYmxlKSByZXR1cm5cbiAgbW9kdWxlLmhvdC5hY2NlcHQoKVxuICBpZiAoIW1vZHVsZS5ob3QuZGF0YSkge1xuICAgIGhvdEFQSS5jcmVhdGVSZWNvcmQoXCJkYXRhLXYtM2Q0YmI5YTRcIiwgQ29tcG9uZW50Lm9wdGlvbnMpXG4gIH0gZWxzZSB7XG4gICAgaG90QVBJLnJlbG9hZChcImRhdGEtdi0zZDRiYjlhNFwiLCBDb21wb25lbnQub3B0aW9ucylcbiAgfVxufSkoKX1cblxubW9kdWxlLmV4cG9ydHMgPSBDb21wb25lbnQuZXhwb3J0c1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvR3JpZExheW91dC52dWVcbi8vIG1vZHVsZSBpZCA9IDE3XG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///17\n"); - -/***/ }), -/* 18 */ -/***/ (function(module, exports, __webpack_require__) { - -eval("// style-loader: Adds some css to the DOM by adding a \\r\\n\\r\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\n// exports\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvR3JpZExheW91dC52dWU/OWEyYSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBOzs7QUFHQTtBQUNBLDZDQUE4Qyx5QkFBeUIsb0NBQW9DLEdBQUcsVUFBVSxpRkFBaUYsS0FBSyxXQUFXLFdBQVcsc2lCQUFzaUIsK0JBQStCLDBDQUEwQyxTQUFTLHNEQUFzRCw4RUFBOEUsb0JBQW9CLDREQUE0RCxnQkFBZ0IsK0NBQStDLHlFQUF5RSx3REFBd0Qsd0JBQXdCLG1EQUFtRCxhQUFhLDBCQUEwQixzQ0FBc0MscUJBQXFCLGdIQUFnSCxvRkFBb0YsMEJBQTBCLGlGQUFpRiw2QkFBNkIsa0ZBQWtGLDJCQUEyQix1RkFBdUYsMEJBQTBCLDBFQUEwRSx3Q0FBd0MscUJBQXFCLGlCQUFpQiwrQkFBK0Isb0ZBQW9GLCtCQUErQixvRkFBb0YsOEJBQThCLHFGQUFxRixvQ0FBb0Msb0ZBQW9GLG1DQUFtQyxvRkFBb0YsMEJBQTBCLG9GQUFvRixjQUFjLGdDQUFnQyx3QkFBd0IsbUVBQW1FLGlIQUFpSCxzS0FBc0ssbUJBQW1CLGFBQWEseUJBQXlCLGdDQUFnQyxvS0FBb0ssK0RBQStELGtCQUFrQixnRkFBZ0YsNkRBQTZELGtCQUFrQix5REFBeUQsd0RBQXdELDBFQUEwRSxzRUFBc0UsYUFBYSx1Q0FBdUMsNkdBQTZHLHVFQUF1RSx3RkFBd0Ysa0NBQWtDLDRDQUE0QyxnREFBZ0Qsb0NBQW9DLCtDQUErQyxrREFBa0Qsa0RBQWtELGdFQUFnRSxtRkFBbUYseUJBQXlCLG1FQUFtRSxnREFBZ0Qsb0RBQW9ELGtFQUFrRSw2R0FBNkcsRUFBRSw4RUFBOEUsc0RBQXNELDZCQUE2QixFQUFFLHlCQUF5QixFQUFFLHFCQUFxQixFQUFFLGdEQUFnRCxrREFBa0Qsa0RBQWtELGdFQUFnRSxtRkFBbUYseUJBQXlCLG1FQUFtRSxnREFBZ0Qsb0RBQW9ELGtFQUFrRSw2R0FBNkcsRUFBRSw4RUFBOEUsc0RBQXNELDZCQUE2QixFQUFFLHlCQUF5QixFQUFFLDBCQUEwQixpQkFBaUIsRUFBRSxhQUFhLHFCQUFxQixvQ0FBb0MsZ0RBQWdELHVFQUF1RSx5RUFBeUUsNENBQTRDLHFCQUFxQixFQUFFLGlCQUFpQixzQ0FBc0Msd0NBQXdDLGlCQUFpQix3Q0FBd0MsMEVBQTBFLGlCQUFpQiwwQ0FBMEMsNEVBQTRFLGlCQUFpQiwwQ0FBMEMsNEVBQTRFLGlCQUFpQixhQUFhLHVCQUF1QixnQ0FBZ0Msb0RBQW9ELDJFQUEyRSxrRUFBa0UsdUVBQXVFLHlCQUF5QixtRUFBbUUseUVBQXlFLDRDQUE0QyxxQkFBcUIsaUJBQWlCLDRDQUE0Qyx3Q0FBd0MsNEVBQTRFLGlCQUFpQiw4Q0FBOEMsMkdBQTJHLGlFQUFpRSxxQkFBcUIsaUJBQWlCLCtDQUErQywrQ0FBK0MsMkdBQTJHLGlCQUFpQixrRUFBa0Usb0ZBQW9GLGdEQUFnRCwrQ0FBK0MsK0NBQStDLCtDQUErQywrQ0FBK0MsbURBQW1ELG1EQUFtRCx5QkFBeUIsRUFBRSx1RUFBdUUseUVBQXlFLHFCQUFxQixPQUFPLG1EQUFtRCxvREFBb0QseUJBQXlCLEVBQUUscUJBQXFCLDJGQUEyRiwyREFBMkQsd0hBQXdILDZCQUE2QixTQUFTLHFCQUFxQiw0QkFBNEIsNEJBQTRCLDBJQUEwSSwrREFBK0QsK0lBQStJLHdDQUF3QywyRkFBMkYsaUJBQWlCLG9FQUFvRSx3RkFBd0YsZ0RBQWdELCtDQUErQywrQ0FBK0MsK0NBQStDLCtDQUErQyxtREFBbUQsbURBQW1ELHlCQUF5QixFQUFFLHVFQUF1RSx5RUFBeUUseUJBQXlCLE9BQU8sbURBQW1ELG9EQUFvRCx5QkFBeUIsRUFBRSxxQkFBcUIsMkRBQTJELHVIQUF1SCw2QkFBNkIsU0FBUyxxQkFBcUIsNEJBQTRCLDRCQUE0QiwrREFBK0QscURBQXFELHdDQUF3Qyw2RkFBNkYsaUJBQWlCLGNBQWMsVUFBVSw4Q0FBOEM7O0FBRXB3VyIsImZpbGUiOiIxOS5qcyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikoKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIlxcbi52dWUtZ3JpZC1sYXlvdXQge1xcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XFxuICAgIHRyYW5zaXRpb246IGhlaWdodCAyMDBtcyBlYXNlO1xcbn1cXG5cIiwgXCJcIiwge1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wiLy4vc3JjL0dyaWRMYXlvdXQudnVlPzM0NzBmMzMyXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCI7QUFhQTtJQUNBLG1CQUFBO0lBQ0EsOEJBQUE7Q0FDQVwiLFwiZmlsZVwiOlwiR3JpZExheW91dC52dWVcIixcInNvdXJjZXNDb250ZW50XCI6W1wiPHRlbXBsYXRlPlxcclxcbiAgICA8ZGl2IHJlZj1cXFwiaXRlbVxcXCIgY2xhc3M9XFxcInZ1ZS1ncmlkLWxheW91dFxcXCIgOnN0eWxlPVxcXCJtZXJnZWRTdHlsZVxcXCI+XFxyXFxuICAgICAgICA8c2xvdD48L3Nsb3Q+XFxyXFxuICAgICAgICA8Z3JpZC1pdGVtIGNsYXNzPVxcXCJ2dWUtZ3JpZC1wbGFjZWhvbGRlclxcXCJcXHJcXG4gICAgICAgICAgICAgICAgICAgdi1zaG93PVxcXCJpc0RyYWdnaW5nXFxcIlxcclxcbiAgICAgICAgICAgICAgICAgICA6eD1cXFwicGxhY2Vob2xkZXIueFxcXCJcXHJcXG4gICAgICAgICAgICAgICAgICAgOnk9XFxcInBsYWNlaG9sZGVyLnlcXFwiXFxyXFxuICAgICAgICAgICAgICAgICAgIDp3PVxcXCJwbGFjZWhvbGRlci53XFxcIlxcclxcbiAgICAgICAgICAgICAgICAgICA6aD1cXFwicGxhY2Vob2xkZXIuaFxcXCJcXHJcXG4gICAgICAgICAgICAgICAgICAgOmk9XFxcInBsYWNlaG9sZGVyLmlcXFwiPjwvZ3JpZC1pdGVtPlxcclxcbiAgICA8L2Rpdj5cXHJcXG48L3RlbXBsYXRlPlxcclxcbjxzdHlsZT5cXHJcXG4gICAgLnZ1ZS1ncmlkLWxheW91dCB7XFxyXFxuICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XFxyXFxuICAgICAgICB0cmFuc2l0aW9uOiBoZWlnaHQgMjAwbXMgZWFzZTtcXHJcXG4gICAgfVxcclxcbjwvc3R5bGU+XFxyXFxuPHNjcmlwdD5cXHJcXG4gICAgaW1wb3J0IFZ1ZSBmcm9tICd2dWUnO1xcclxcbiAgICB2YXIgZWxlbWVudFJlc2l6ZURldGVjdG9yTWFrZXIgPSByZXF1aXJlKFxcXCJlbGVtZW50LXJlc2l6ZS1kZXRlY3RvclxcXCIpO1xcclxcblxcclxcbiAgICBpbXBvcnQge2JvdHRvbSwgY29tcGFjdCwgZ2V0TGF5b3V0SXRlbSwgbW92ZUVsZW1lbnQsIHZhbGlkYXRlTGF5b3V0fSBmcm9tICcuL3V0aWxzJztcXHJcXG4gICAgLy92YXIgZXZlbnRCdXMgPSByZXF1aXJlKCcuL2V2ZW50QnVzJyk7XFxyXFxuICAgIGltcG9ydCBHcmlkSXRlbSBmcm9tICcuL0dyaWRJdGVtLnZ1ZSdcXHJcXG5cXHJcXG4gICAgZXhwb3J0IGRlZmF1bHQge1xcclxcbiAgICAgICAgbmFtZTogXFxcIkdyaWRMYXlvdXRcXFwiLFxcclxcbiAgICAgICAgcHJvdmlkZSgpIHtcXHJcXG4gICAgICAgICAgICByZXR1cm4ge1xcclxcbiAgICAgICAgICAgICAgICBldmVudEJ1czogbnVsbFxcclxcbiAgICAgICAgICAgIH1cXHJcXG4gICAgICAgIH0sXFxyXFxuICAgICAgICBjb21wb25lbnRzOiB7XFxyXFxuICAgICAgICAgICAgR3JpZEl0ZW0sXFxyXFxuICAgICAgICB9LFxcclxcbiAgICAgICAgcHJvcHM6IHtcXHJcXG4gICAgICAgICAgICAvLyBJZiB0cnVlLCB0aGUgY29udGFpbmVyIGhlaWdodCBzd2VsbHMgYW5kIGNvbnRyYWN0cyB0byBmaXQgY29udGVudHNcXHJcXG4gICAgICAgICAgICBhdXRvU2l6ZToge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBCb29sZWFuLFxcclxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiB0cnVlXFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICBjb2xOdW06IHtcXHJcXG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxcclxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiAxMlxcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgcm93SGVpZ2h0OiB7XFxyXFxuICAgICAgICAgICAgICAgIHR5cGU6IE51bWJlcixcXHJcXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogMTUwXFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICBtYXhSb3dzOiB7XFxyXFxuICAgICAgICAgICAgICAgIHR5cGU6IE51bWJlcixcXHJcXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogSW5maW5pdHlcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIG1hcmdpbjoge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBBcnJheSxcXHJcXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogZnVuY3Rpb24gKCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFsxMCwgMTBdO1xcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICBpc0RyYWdnYWJsZToge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBCb29sZWFuLFxcclxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiB0cnVlXFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICBpc1Jlc2l6YWJsZToge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBCb29sZWFuLFxcclxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiB0cnVlXFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICBpc01pcnJvcmVkOiB7XFxyXFxuICAgICAgICAgICAgICAgIHR5cGU6IEJvb2xlYW4sXFxyXFxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IGZhbHNlXFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICB1c2VDc3NUcmFuc2Zvcm1zOiB7XFxyXFxuICAgICAgICAgICAgICAgIHR5cGU6IEJvb2xlYW4sXFxyXFxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRydWVcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIHZlcnRpY2FsQ29tcGFjdDoge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBCb29sZWFuLFxcclxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiB0cnVlXFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICBsYXlvdXQ6IHtcXHJcXG4gICAgICAgICAgICAgICAgdHlwZTogQXJyYXksXFxyXFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlLFxcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICB9LFxcclxcbiAgICAgICAgZGF0YTogZnVuY3Rpb24gKCkge1xcclxcbiAgICAgICAgICAgIHJldHVybiB7XFxyXFxuICAgICAgICAgICAgICAgIHdpZHRoOiBudWxsLFxcclxcbiAgICAgICAgICAgICAgICBtZXJnZWRTdHlsZToge30sXFxyXFxuICAgICAgICAgICAgICAgIGxhc3RMYXlvdXRMZW5ndGg6IDAsXFxyXFxuICAgICAgICAgICAgICAgIGlzRHJhZ2dpbmc6IGZhbHNlLFxcclxcbiAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcjoge1xcclxcbiAgICAgICAgICAgICAgICAgICAgeDogMCxcXHJcXG4gICAgICAgICAgICAgICAgICAgIHk6IDAsXFxyXFxuICAgICAgICAgICAgICAgICAgICB3OiAwLFxcclxcbiAgICAgICAgICAgICAgICAgICAgaDogMCxcXHJcXG4gICAgICAgICAgICAgICAgICAgIGk6IC0xXFxyXFxuICAgICAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgfTtcXHJcXG4gICAgICAgIH0sXFxyXFxuICAgICAgICBjcmVhdGVkICgpIHtcXHJcXG4gICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XFxyXFxuXFxyXFxuICAgICAgICAgICAgLy8gQWNjZXNzaWJsZSByZWZlcm5jZXMgb2YgZnVuY3Rpb25zIGZvciByZW1vdmluZyBpbiBiZWZvcmVEZXN0cm95XFxyXFxuICAgICAgICAgICAgc2VsZi5yZXNpemVFdmVudEhhbmRsZXIgPSBmdW5jdGlvbihldmVudFR5cGUsIGksIHgsIHksIGgsIHcpIHtcXHJcXG4gICAgICAgICAgICAgICAgc2VsZi5yZXNpemVFdmVudChldmVudFR5cGUsIGksIHgsIHksIGgsIHcpO1xcclxcbiAgICAgICAgICAgIH07XFxyXFxuXFxyXFxuICAgICAgICAgICAgc2VsZi5kcmFnRXZlbnRIYW5kbGVyID0gZnVuY3Rpb24oZXZlbnRUeXBlLCBpLCB4LCB5LCBoLCB3KSB7XFxyXFxuICAgICAgICAgICAgICAgIHNlbGYuZHJhZ0V2ZW50KGV2ZW50VHlwZSwgaSwgeCwgeSwgaCwgdyk7XFxyXFxuICAgICAgICAgICAgfTtcXHJcXG5cXHJcXG4gICAgICAgICAgICBzZWxmLl9wcm92aWRlZC5ldmVudEJ1cyA9ICBuZXcgVnVlKCk7XFxyXFxuICAgICAgICAgICAgc2VsZi5ldmVudEJ1cyA9IHNlbGYuX3Byb3ZpZGVkLmV2ZW50QnVzO1xcclxcbiAgICAgICAgICAgIHNlbGYuZXZlbnRCdXMuJG9uKCdyZXNpemVFdmVudCcsIHNlbGYucmVzaXplRXZlbnRIYW5kbGVyKTtcXHJcXG4gICAgICAgICAgICBzZWxmLmV2ZW50QnVzLiRvbignZHJhZ0V2ZW50Jywgc2VsZi5kcmFnRXZlbnRIYW5kbGVyKTtcXHJcXG4gICAgICAgIH0sXFxyXFxuICAgICAgICBiZWZvcmVEZXN0cm95OiBmdW5jdGlvbigpe1xcclxcbiAgICAgICAgICAgIC8vUmVtb3ZlIGxpc3RlbmVyc1xcclxcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9mZigncmVzaXplRXZlbnQnLCBzZWxmLnJlc2l6ZUV2ZW50SGFuZGxlcik7XFxyXFxuICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kb2ZmKCdkcmFnRXZlbnQnLCBzZWxmLmRyYWdFdmVudEhhbmRsZXIpO1xcclxcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFxcXCJyZXNpemVcXFwiLCBzZWxmLm9uV2luZG93UmVzaXplKVxcclxcbiAgICAgICAgfSxcXHJcXG4gICAgICAgIG1vdW50ZWQ6IGZ1bmN0aW9uKCkge1xcclxcbiAgICAgICAgICAgIHRoaXMuJG5leHRUaWNrKGZ1bmN0aW9uICgpIHtcXHJcXG4gICAgICAgICAgICAgICAgdmFsaWRhdGVMYXlvdXQodGhpcy5sYXlvdXQpO1xcclxcbiAgICAgICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XFxyXFxuICAgICAgICAgICAgICAgIHRoaXMuJG5leHRUaWNrKGZ1bmN0aW9uKCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYud2lkdGggPT09IG51bGwpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLm9uV2luZG93UmVzaXplKCk7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgLy9zZWxmLndpZHRoID0gc2VsZi4kZWwub2Zmc2V0V2lkdGg7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIHNlbGYub25XaW5kb3dSZXNpemUpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgICAgICAgICAgY29tcGFjdChzZWxmLmxheW91dCwgc2VsZi52ZXJ0aWNhbENvbXBhY3QpO1xcclxcblxcclxcbiAgICAgICAgICAgICAgICAgICAgc2VsZi51cGRhdGVIZWlnaHQoKTtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuJG5leHRUaWNrKGZ1bmN0aW9uICgpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZXJkID0gZWxlbWVudFJlc2l6ZURldGVjdG9yTWFrZXIoe1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJhdGVneTogXFxcInNjcm9sbFxcXCIgLy88LSBGb3IgdWx0cmEgcGVyZm9ybWFuY2UuXFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgZXJkLmxpc3RlblRvKHNlbGYuJHJlZnMuaXRlbSwgZnVuY3Rpb24gKGVsZW1lbnQpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5vbldpbmRvd1Jlc2l6ZSgpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xcclxcbiAgICAgICAgICAgICAgICAgICAgfSk7XFxyXFxuICAgICAgICAgICAgICAgIH0pO1xcclxcbiAgICAgICAgICAgICAgICB3aW5kb3cub25sb2FkID0gZnVuY3Rpb24oKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi53aWR0aCA9PT0gbnVsbCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYub25XaW5kb3dSZXNpemUoKTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3NlbGYud2lkdGggPSBzZWxmLiRlbC5vZmZzZXRXaWR0aDtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgc2VsZi5vbldpbmRvd1Jlc2l6ZSk7XFxyXFxuICAgICAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgICAgICAgICBjb21wYWN0KHNlbGYubGF5b3V0LCBzZWxmLnZlcnRpY2FsQ29tcGFjdCk7XFxyXFxuXFxyXFxuICAgICAgICAgICAgICAgICAgICBzZWxmLnVwZGF0ZUhlaWdodCgpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgc2VsZi4kbmV4dFRpY2soZnVuY3Rpb24gKCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlcmQgPSBlbGVtZW50UmVzaXplRGV0ZWN0b3JNYWtlcih7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmF0ZWd5OiBcXFwic2Nyb2xsXFxcIiAvLzwtIEZvciB1bHRyYSBwZXJmb3JtYW5jZS5cXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBlcmQubGlzdGVuVG8oc2VsZi4kcmVmcy5pdGVtLCBmdW5jdGlvbiAoZWxlbWVudCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLm9uV2luZG93UmVzaXplKCk7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XFxyXFxuICAgICAgICAgICAgICAgICAgICB9KTtcXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgfTtcXHJcXG4gICAgICAgICAgICB9KTtcXHJcXG4gICAgICAgIH0sXFxyXFxuICAgICAgICB3YXRjaDoge1xcclxcbiAgICAgICAgICAgIHdpZHRoOiBmdW5jdGlvbiAoKSB7XFxyXFxuICAgICAgICAgICAgICAgIHRoaXMuJG5leHRUaWNrKGZ1bmN0aW9uICgpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIC8vdGhpcy4kYnJvYWRjYXN0KFxcXCJ1cGRhdGVXaWR0aFxcXCIsIHRoaXMud2lkdGgpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kZW1pdChcXFwidXBkYXRlV2lkdGhcXFwiLCB0aGlzLndpZHRoKTtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlSGVpZ2h0KCk7XFxyXFxuICAgICAgICAgICAgICAgIH0pO1xcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgbGF5b3V0OiBmdW5jdGlvbiAoKSB7XFxyXFxuICAgICAgICAgICAgICAgIHRoaXMubGF5b3V0VXBkYXRlKCk7XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICByb3dIZWlnaHQ6IGZ1bmN0aW9uKCkge1xcclxcbiAgICAgICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRlbWl0KFxcXCJzZXRSb3dIZWlnaHRcXFwiLCB0aGlzLnJvd0hlaWdodCk7XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICBpc0RyYWdnYWJsZTogZnVuY3Rpb24oKSB7XFxyXFxuICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJGVtaXQoXFxcInNldERyYWdnYWJsZVxcXCIsIHRoaXMuaXNEcmFnZ2FibGUpO1xcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgaXNSZXNpemFibGU6IGZ1bmN0aW9uKCkge1xcclxcbiAgICAgICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRlbWl0KFxcXCJzZXRSZXNpemFibGVcXFwiLCB0aGlzLmlzUmVzaXphYmxlKTtcXHJcXG4gICAgICAgICAgICB9XFxyXFxuICAgICAgICB9LFxcclxcbiAgICAgICAgbWV0aG9kczoge1xcclxcbiAgICAgICAgICAgIGxheW91dFVwZGF0ZSgpIHtcXHJcXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMubGF5b3V0ICE9PSB1bmRlZmluZWQpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmxheW91dC5sZW5ndGggIT09IHRoaXMubGFzdExheW91dExlbmd0aCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vY29uc29sZS5sb2coXFxcIiMjIyBMQVlPVVQgVVBEQVRFIVxcXCIpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubGFzdExheW91dExlbmd0aCA9IHRoaXMubGF5b3V0Lmxlbmd0aDtcXHJcXG4gICAgICAgICAgICAgICAgICAgIH1cXHJcXG4gICAgICAgICAgICAgICAgICAgIGNvbXBhY3QodGhpcy5sYXlvdXQsIHRoaXMudmVydGljYWxDb21wYWN0KTtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJGVtaXQoXFxcInVwZGF0ZVdpZHRoXFxcIiwgdGhpcy53aWR0aCk7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUhlaWdodCgpO1xcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICB1cGRhdGVIZWlnaHQ6IGZ1bmN0aW9uICgpIHtcXHJcXG4gICAgICAgICAgICAgICAgdGhpcy5tZXJnZWRTdHlsZSA9IHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIGhlaWdodDogdGhpcy5jb250YWluZXJIZWlnaHQoKVxcclxcbiAgICAgICAgICAgICAgICB9O1xcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgb25XaW5kb3dSZXNpemU6IGZ1bmN0aW9uICgpIHtcXHJcXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuJHJlZnMgIT09IG51bGwgJiYgdGhpcy4kcmVmcy5pdGVtICE9PSBudWxsICYmIHRoaXMuJHJlZnMuaXRlbSAhPT0gdW5kZWZpbmVkKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLndpZHRoID0gdGhpcy4kcmVmcy5pdGVtLm9mZnNldFdpZHRoO1xcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICBjb250YWluZXJIZWlnaHQ6IGZ1bmN0aW9uICgpIHtcXHJcXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmF1dG9TaXplKSByZXR1cm47XFxyXFxuICAgICAgICAgICAgICAgIHJldHVybiBib3R0b20odGhpcy5sYXlvdXQpICogKHRoaXMucm93SGVpZ2h0ICsgdGhpcy5tYXJnaW5bMV0pICsgdGhpcy5tYXJnaW5bMV0gKyAncHgnO1xcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgZHJhZ0V2ZW50OiBmdW5jdGlvbiAoZXZlbnROYW1lLCBpZCwgeCwgeSwgaCwgdykge1xcclxcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnROYW1lID09PSBcXFwiZHJhZ21vdmVcXFwiIHx8IGV2ZW50TmFtZSA9PT0gXFxcImRyYWdzdGFydFxcXCIpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGxhY2Vob2xkZXIuaSA9IGlkO1xcclxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbGFjZWhvbGRlci54ID0geDtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGxhY2Vob2xkZXIueSA9IHk7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsYWNlaG9sZGVyLncgPSB3O1xcclxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbGFjZWhvbGRlci5oID0gaDtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuJG5leHRUaWNrKGZ1bmN0aW9uKCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNEcmFnZ2luZyA9IHRydWU7XFxyXFxuICAgICAgICAgICAgICAgICAgICB9KTtcXHJcXG4gICAgICAgICAgICAgICAgICAgIC8vdGhpcy4kYnJvYWRjYXN0KFxcXCJ1cGRhdGVXaWR0aFxcXCIsIHRoaXMud2lkdGgpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kZW1pdChcXFwidXBkYXRlV2lkdGhcXFwiLCB0aGlzLndpZHRoKTtcXHJcXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuJG5leHRUaWNrKGZ1bmN0aW9uKCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNEcmFnZ2luZyA9IGZhbHNlO1xcclxcbiAgICAgICAgICAgICAgICAgICAgfSk7XFxyXFxuICAgICAgICAgICAgICAgIH1cXHJcXG4gICAgICAgICAgICAgICAgLy9jb25zb2xlLmxvZyhldmVudE5hbWUgKyBcXFwiIGlkPVxcXCIgKyBpZCArIFxcXCIsIHg9XFxcIiArIHggKyBcXFwiLCB5PVxcXCIgKyB5KTtcXHJcXG4gICAgICAgICAgICAgICAgdmFyIGwgPSBnZXRMYXlvdXRJdGVtKHRoaXMubGF5b3V0LCBpZCk7XFxyXFxuICAgICAgICAgICAgICAgIC8vR2V0TGF5b3V0SXRlbSBzb21ldGltZXMgcmV0dXJucyBudWxsIG9iamVjdFxcclxcbiAgICAgICAgICAgICAgICBpZiAobCA9PT0gdW5kZWZpbmVkIHx8IGwgPT09IG51bGwpe1xcclxcbiAgICAgICAgICAgICAgICAgICAgbCA9IHt4OjAsIHk6MH1cXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgICAgICBsLnggPSB4O1xcclxcbiAgICAgICAgICAgICAgICBsLnkgPSB5O1xcclxcbiAgICAgICAgICAgICAgICAvLyBNb3ZlIHRoZSBlbGVtZW50IHRvIHRoZSBkcmFnZ2VkIGxvY2F0aW9uLlxcclxcbiAgICAgICAgICAgICAgICB0aGlzLmxheW91dCA9IG1vdmVFbGVtZW50KHRoaXMubGF5b3V0LCBsLCB4LCB5LCB0cnVlKTtcXHJcXG4gICAgICAgICAgICAgICAgY29tcGFjdCh0aGlzLmxheW91dCwgdGhpcy52ZXJ0aWNhbENvbXBhY3QpO1xcclxcbiAgICAgICAgICAgICAgICAvLyBuZWVkZWQgYmVjYXVzZSB2dWUgY2FuJ3QgZGV0ZWN0IGNoYW5nZXMgb24gYXJyYXkgZWxlbWVudCBwcm9wZXJ0aWVzXFxyXFxuICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJGVtaXQoXFxcImNvbXBhY3RcXFwiKTtcXHJcXG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVIZWlnaHQoKTtcXHJcXG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50TmFtZSA9PT0gJ2RyYWdlbmQnKSB0aGlzLiRlbWl0KCdsYXlvdXQtdXBkYXRlZCcsIHRoaXMubGF5b3V0KTtcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIHJlc2l6ZUV2ZW50OiBmdW5jdGlvbiAoZXZlbnROYW1lLCBpZCwgeCwgeSwgaCwgdykge1xcclxcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnROYW1lID09PSBcXFwicmVzaXplc3RhcnRcXFwiIHx8IGV2ZW50TmFtZSA9PT0gXFxcInJlc2l6ZW1vdmVcXFwiKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsYWNlaG9sZGVyLmkgPSBpZDtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGxhY2Vob2xkZXIueCA9IHg7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsYWNlaG9sZGVyLnkgPSB5O1xcclxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbGFjZWhvbGRlci53ID0gdztcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGxhY2Vob2xkZXIuaCA9IGg7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLiRuZXh0VGljayhmdW5jdGlvbigpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzRHJhZ2dpbmcgPSB0cnVlO1xcclxcbiAgICAgICAgICAgICAgICAgICAgfSk7XFxyXFxuICAgICAgICAgICAgICAgICAgICAvL3RoaXMuJGJyb2FkY2FzdChcXFwidXBkYXRlV2lkdGhcXFwiLCB0aGlzLndpZHRoKTtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJGVtaXQoXFxcInVwZGF0ZVdpZHRoXFxcIiwgdGhpcy53aWR0aCk7XFxyXFxuXFxyXFxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLiRuZXh0VGljayhmdW5jdGlvbigpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzRHJhZ2dpbmcgPSBmYWxzZTtcXHJcXG4gICAgICAgICAgICAgICAgICAgIH0pO1xcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgICAgIHZhciBsID0gZ2V0TGF5b3V0SXRlbSh0aGlzLmxheW91dCwgaWQpO1xcclxcbiAgICAgICAgICAgICAgICAvL0dldExheW91dEl0ZW0gc29tZXRpbWVzIHJldHVybiBudWxsIG9iamVjdFxcclxcbiAgICAgICAgICAgICAgICBpZiAobCA9PT0gdW5kZWZpbmVkIHx8IGwgPT09IG51bGwpe1xcclxcbiAgICAgICAgICAgICAgICAgICAgbCA9IHtoOjAsIHc6MH1cXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgICAgICBsLmggPSBoO1xcclxcbiAgICAgICAgICAgICAgICBsLncgPSB3O1xcclxcbiAgICAgICAgICAgICAgICBjb21wYWN0KHRoaXMubGF5b3V0LCB0aGlzLnZlcnRpY2FsQ29tcGFjdCk7XFxyXFxuICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJGVtaXQoXFxcImNvbXBhY3RcXFwiKTtcXHJcXG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVIZWlnaHQoKTtcXHJcXG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50TmFtZSA9PT0gJ3Jlc2l6ZWVuZCcpIHRoaXMuJGVtaXQoJ2xheW91dC11cGRhdGVkJywgdGhpcy5sYXlvdXQpO1xcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICB9LFxcclxcbiAgICB9XFxyXFxuPC9zY3JpcHQ+XFxyXFxuXCJdLFwic291cmNlUm9vdFwiOlwid2VicGFjazovL1wifV0pO1xuXG4vLyBleHBvcnRzXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1jb21waWxlcj97XCJpZFwiOlwiZGF0YS12LTNkNGJiOWE0XCIsXCJzY29wZWRcIjpmYWxzZSxcImhhc0lubGluZUNvbmZpZ1wiOmZhbHNlfSEuL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vc3JjL0dyaWRMYXlvdXQudnVlXG4vLyBtb2R1bGUgaWQgPSAxOVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///19\n"); - -/***/ }), -/* 20 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -eval("\n\nexports.__esModule = true;\n\nvar _vue = __webpack_require__(21);\n\nvar _vue2 = _interopRequireDefault(_vue);\n\nvar _utils = __webpack_require__(0);\n\nvar _GridItem = __webpack_require__(1);\n\nvar _GridItem2 = _interopRequireDefault(_GridItem);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar elementResizeDetectorMaker = __webpack_require__(6); //\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\n//var eventBus = require('./eventBus');\nexports.default = {\n name: \"GridLayout\",\n provide: function provide() {\n return {\n eventBus: null\n };\n },\n\n components: {\n GridItem: _GridItem2.default\n },\n props: {\n // If true, the container height swells and contracts to fit contents\n autoSize: {\n type: Boolean,\n default: true\n },\n colNum: {\n type: Number,\n default: 12\n },\n rowHeight: {\n type: Number,\n default: 150\n },\n maxRows: {\n type: Number,\n default: Infinity\n },\n margin: {\n type: Array,\n default: function _default() {\n return [10, 10];\n }\n },\n isDraggable: {\n type: Boolean,\n default: true\n },\n isResizable: {\n type: Boolean,\n default: true\n },\n isMirrored: {\n type: Boolean,\n default: false\n },\n useCssTransforms: {\n type: Boolean,\n default: true\n },\n verticalCompact: {\n type: Boolean,\n default: true\n },\n layout: {\n type: Array,\n required: true\n }\n },\n data: function data() {\n return {\n width: null,\n mergedStyle: {},\n lastLayoutLength: 0,\n isDragging: false,\n placeholder: {\n x: 0,\n y: 0,\n w: 0,\n h: 0,\n i: -1\n }\n };\n },\n created: function created() {\n var self = this;\n\n // Accessible refernces of functions for removing in beforeDestroy\n self.resizeEventHandler = function (eventType, i, x, y, h, w) {\n self.resizeEvent(eventType, i, x, y, h, w);\n };\n\n self.dragEventHandler = function (eventType, i, x, y, h, w) {\n self.dragEvent(eventType, i, x, y, h, w);\n };\n\n self._provided.eventBus = new _vue2.default();\n self.eventBus = self._provided.eventBus;\n self.eventBus.$on('resizeEvent', self.resizeEventHandler);\n self.eventBus.$on('dragEvent', self.dragEventHandler);\n },\n\n beforeDestroy: function beforeDestroy() {\n //Remove listeners\n this.eventBus.$off('resizeEvent', self.resizeEventHandler);\n this.eventBus.$off('dragEvent', self.dragEventHandler);\n window.removeEventListener(\"resize\", self.onWindowResize);\n },\n mounted: function mounted() {\n this.$nextTick(function () {\n (0, _utils.validateLayout)(this.layout);\n var self = this;\n this.$nextTick(function () {\n if (self.width === null) {\n self.onWindowResize();\n //self.width = self.$el.offsetWidth;\n window.addEventListener('resize', self.onWindowResize);\n }\n (0, _utils.compact)(self.layout, self.verticalCompact);\n\n self.updateHeight();\n self.$nextTick(function () {\n var erd = elementResizeDetectorMaker({\n strategy: \"scroll\" //<- For ultra performance.\n });\n erd.listenTo(self.$refs.item, function (element) {\n self.onWindowResize();\n });\n });\n });\n window.onload = function () {\n if (self.width === null) {\n self.onWindowResize();\n //self.width = self.$el.offsetWidth;\n window.addEventListener('resize', self.onWindowResize);\n }\n (0, _utils.compact)(self.layout, self.verticalCompact);\n\n self.updateHeight();\n self.$nextTick(function () {\n var erd = elementResizeDetectorMaker({\n strategy: \"scroll\" //<- For ultra performance.\n });\n erd.listenTo(self.$refs.item, function (element) {\n self.onWindowResize();\n });\n });\n };\n });\n },\n watch: {\n width: function width() {\n this.$nextTick(function () {\n //this.$broadcast(\"updateWidth\", this.width);\n this.eventBus.$emit(\"updateWidth\", this.width);\n this.updateHeight();\n });\n },\n layout: function layout() {\n this.layoutUpdate();\n },\n rowHeight: function rowHeight() {\n this.eventBus.$emit(\"setRowHeight\", this.rowHeight);\n },\n isDraggable: function isDraggable() {\n this.eventBus.$emit(\"setDraggable\", this.isDraggable);\n },\n isResizable: function isResizable() {\n this.eventBus.$emit(\"setResizable\", this.isResizable);\n }\n },\n methods: {\n layoutUpdate: function layoutUpdate() {\n if (this.layout !== undefined) {\n if (this.layout.length !== this.lastLayoutLength) {\n //console.log(\"### LAYOUT UPDATE!\");\n this.lastLayoutLength = this.layout.length;\n }\n (0, _utils.compact)(this.layout, this.verticalCompact);\n this.eventBus.$emit(\"updateWidth\", this.width);\n this.updateHeight();\n }\n },\n\n updateHeight: function updateHeight() {\n this.mergedStyle = {\n height: this.containerHeight()\n };\n },\n onWindowResize: function onWindowResize() {\n if (this.$refs !== null && this.$refs.item !== null && this.$refs.item !== undefined) {\n this.width = this.$refs.item.offsetWidth;\n }\n },\n containerHeight: function containerHeight() {\n if (!this.autoSize) return;\n return (0, _utils.bottom)(this.layout) * (this.rowHeight + this.margin[1]) + this.margin[1] + 'px';\n },\n dragEvent: function dragEvent(eventName, id, x, y, h, w) {\n if (eventName === \"dragmove\" || eventName === \"dragstart\") {\n this.placeholder.i = id;\n this.placeholder.x = x;\n this.placeholder.y = y;\n this.placeholder.w = w;\n this.placeholder.h = h;\n this.$nextTick(function () {\n this.isDragging = true;\n });\n //this.$broadcast(\"updateWidth\", this.width);\n this.eventBus.$emit(\"updateWidth\", this.width);\n } else {\n this.$nextTick(function () {\n this.isDragging = false;\n });\n }\n //console.log(eventName + \" id=\" + id + \", x=\" + x + \", y=\" + y);\n var l = (0, _utils.getLayoutItem)(this.layout, id);\n //GetLayoutItem sometimes returns null object\n if (l === undefined || l === null) {\n l = { x: 0, y: 0 };\n }\n l.x = x;\n l.y = y;\n // Move the element to the dragged location.\n this.layout = (0, _utils.moveElement)(this.layout, l, x, y, true);\n (0, _utils.compact)(this.layout, this.verticalCompact);\n // needed because vue can't detect changes on array element properties\n this.eventBus.$emit(\"compact\");\n this.updateHeight();\n if (eventName === 'dragend') this.$emit('layout-updated', this.layout);\n },\n resizeEvent: function resizeEvent(eventName, id, x, y, h, w) {\n if (eventName === \"resizestart\" || eventName === \"resizemove\") {\n this.placeholder.i = id;\n this.placeholder.x = x;\n this.placeholder.y = y;\n this.placeholder.w = w;\n this.placeholder.h = h;\n this.$nextTick(function () {\n this.isDragging = true;\n });\n //this.$broadcast(\"updateWidth\", this.width);\n this.eventBus.$emit(\"updateWidth\", this.width);\n } else {\n this.$nextTick(function () {\n this.isDragging = false;\n });\n }\n var l = (0, _utils.getLayoutItem)(this.layout, id);\n //GetLayoutItem sometimes return null object\n if (l === undefined || l === null) {\n l = { h: 0, w: 0 };\n }\n l.h = h;\n l.w = w;\n (0, _utils.compact)(this.layout, this.verticalCompact);\n this.eventBus.$emit(\"compact\");\n this.updateHeight();\n if (eventName === 'resizeend') this.$emit('layout-updated', this.layout);\n }\n }\n};\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vR3JpZExheW91dC52dWU/MTE1NyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBbUJBOzs7O0FBR0E7O0FBSUE7Ozs7OztBQU5BOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBR0E7O1VBS0E7Z0NBQ0E7O3NCQUdBO0FBRkE7QUFHQTs7O0FBR0E7QUFGQTs7QUFJQTs7a0JBRUE7cUJBRUE7QUFIQTs7a0JBS0E7cUJBRUE7QUFIQTs7a0JBS0E7cUJBRUE7QUFIQTs7a0JBS0E7cUJBRUE7QUFIQTs7a0JBS0E7eUNBQ0E7NEJBQ0E7QUFFQTtBQUxBOztrQkFPQTtxQkFFQTtBQUhBOztrQkFLQTtxQkFFQTtBQUhBOztrQkFLQTtxQkFFQTtBQUhBOztrQkFLQTtxQkFFQTtBQUhBOztrQkFLQTtxQkFFQTtBQUhBOztrQkFLQTtzQkFHQTtBQUpBO0FBNUNBOzBCQWlEQTs7bUJBRUE7eUJBQ0E7OEJBQ0E7d0JBQ0E7O21CQUVBO21CQUNBO21CQUNBO21CQUNBO29CQUdBO0FBUEE7QUFMQTtBQWFBO2dDQUNBO21CQUVBOztBQUNBO3NFQUNBO29EQUNBO0FBRUE7O29FQUNBO2tEQUNBO0FBRUE7O2tDQUNBO3VDQUNBOzhDQUNBOzRDQUNBO0FBQ0E7OzRDQUNBO0FBQ0E7K0NBQ0E7NkNBQ0E7a0RBQ0E7QUFDQTtnQ0FDQTttQ0FDQTs0Q0FDQTt1QkFDQTt1Q0FDQTt5Q0FDQTt5QkFDQTtBQUNBOzJEQUNBO0FBQ0E7c0RBRUE7O3FCQUNBOzJDQUNBOzsyQ0FHQTtBQUZBO3FFQUdBOzZCQUNBO0FBQ0E7QUFDQTtBQUNBO3dDQUNBO3lDQUNBO3lCQUNBO0FBQ0E7MkRBQ0E7QUFDQTtzREFFQTs7cUJBQ0E7MkNBQ0E7OzJDQUdBO0FBRkE7cUVBR0E7NkJBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBOztnQ0FFQTt1Q0FDQTtBQUNBO3dEQUNBO3FCQUNBO0FBQ0E7QUFDQTtrQ0FDQTtpQkFDQTtBQUNBO3dDQUNBO3FEQUNBO0FBQ0E7NENBQ0E7cURBQ0E7QUFDQTs0Q0FDQTtxREFDQTtBQUVBO0FBcEJBOzs4Q0FzQkE7MkNBQ0E7a0VBQ0E7QUFDQTt3REFDQTtBQUNBO3NEQUNBO3dEQUNBO3FCQUNBO0FBQ0E7QUFDQTs7OENBQ0E7OzZCQUdBO0FBRkE7QUFHQTtrREFDQTtrR0FDQTs2Q0FDQTtBQUNBO0FBQ0E7b0RBQ0E7Z0NBQ0E7MEdBQ0E7QUFDQTtpRUFDQTt1RUFDQTtxQ0FDQTtxQ0FDQTtxQ0FDQTtxQ0FDQTtxQ0FDQTsyQ0FDQTtzQ0FDQTtBQUNBO0FBQ0E7d0RBQ0E7bUJBQ0E7MkNBQ0E7c0NBQ0E7QUFDQTtBQUNBO0FBQ0E7MkRBQ0E7QUFDQTsrQ0FDQTsrQkFDQTtBQUNBO2tCQUNBO2tCQUNBO0FBQ0E7d0VBQ0E7a0RBQ0E7QUFDQTtnQ0FDQTtpQkFDQTsyRUFDQTtBQUNBO3FFQUNBOzJFQUNBO3FDQUNBO3FDQUNBO3FDQUNBO3FDQUNBO3FDQUNBOzJDQUNBO3NDQUNBO0FBQ0E7QUFDQTt3REFFQTttQkFDQTsyQ0FDQTtzQ0FDQTtBQUNBO0FBQ0E7MkRBQ0E7QUFDQTsrQ0FDQTsrQkFDQTtBQUNBO2tCQUNBO2tCQUNBO2tEQUNBO2dDQUNBO2lCQUNBOzZFQUNBO0FBRUE7QUF6RkE7QUFqS0EiLCJmaWxlIjoiMjAuanMiLCJzb3VyY2VzQ29udGVudCI6WyI8dGVtcGxhdGU+XHJcbiAgICA8ZGl2IHJlZj1cIml0ZW1cIiBjbGFzcz1cInZ1ZS1ncmlkLWxheW91dFwiIDpzdHlsZT1cIm1lcmdlZFN0eWxlXCI+XHJcbiAgICAgICAgPHNsb3Q+PC9zbG90PlxyXG4gICAgICAgIDxncmlkLWl0ZW0gY2xhc3M9XCJ2dWUtZ3JpZC1wbGFjZWhvbGRlclwiXHJcbiAgICAgICAgICAgICAgICAgICB2LXNob3c9XCJpc0RyYWdnaW5nXCJcclxuICAgICAgICAgICAgICAgICAgIDp4PVwicGxhY2Vob2xkZXIueFwiXHJcbiAgICAgICAgICAgICAgICAgICA6eT1cInBsYWNlaG9sZGVyLnlcIlxyXG4gICAgICAgICAgICAgICAgICAgOnc9XCJwbGFjZWhvbGRlci53XCJcclxuICAgICAgICAgICAgICAgICAgIDpoPVwicGxhY2Vob2xkZXIuaFwiXHJcbiAgICAgICAgICAgICAgICAgICA6aT1cInBsYWNlaG9sZGVyLmlcIj48L2dyaWQtaXRlbT5cclxuICAgIDwvZGl2PlxyXG48L3RlbXBsYXRlPlxyXG48c3R5bGU+XHJcbiAgICAudnVlLWdyaWQtbGF5b3V0IHtcclxuICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XHJcbiAgICAgICAgdHJhbnNpdGlvbjogaGVpZ2h0IDIwMG1zIGVhc2U7XHJcbiAgICB9XHJcbjwvc3R5bGU+XHJcbjxzY3JpcHQ+XHJcbiAgICBpbXBvcnQgVnVlIGZyb20gJ3Z1ZSc7XHJcbiAgICB2YXIgZWxlbWVudFJlc2l6ZURldGVjdG9yTWFrZXIgPSByZXF1aXJlKFwiZWxlbWVudC1yZXNpemUtZGV0ZWN0b3JcIik7XHJcblxyXG4gICAgaW1wb3J0IHtib3R0b20sIGNvbXBhY3QsIGdldExheW91dEl0ZW0sIG1vdmVFbGVtZW50LCB2YWxpZGF0ZUxheW91dH0gZnJvbSAnLi91dGlscyc7XHJcbiAgICAvL3ZhciBldmVudEJ1cyA9IHJlcXVpcmUoJy4vZXZlbnRCdXMnKTtcclxuICAgIGltcG9ydCBHcmlkSXRlbSBmcm9tICcuL0dyaWRJdGVtLnZ1ZSdcclxuXHJcbiAgICBleHBvcnQgZGVmYXVsdCB7XHJcbiAgICAgICAgbmFtZTogXCJHcmlkTGF5b3V0XCIsXHJcbiAgICAgICAgcHJvdmlkZSgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIGV2ZW50QnVzOiBudWxsXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG4gICAgICAgIGNvbXBvbmVudHM6IHtcclxuICAgICAgICAgICAgR3JpZEl0ZW0sXHJcbiAgICAgICAgfSxcclxuICAgICAgICBwcm9wczoge1xyXG4gICAgICAgICAgICAvLyBJZiB0cnVlLCB0aGUgY29udGFpbmVyIGhlaWdodCBzd2VsbHMgYW5kIGNvbnRyYWN0cyB0byBmaXQgY29udGVudHNcclxuICAgICAgICAgICAgYXV0b1NpemU6IHtcclxuICAgICAgICAgICAgICAgIHR5cGU6IEJvb2xlYW4sXHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiB0cnVlXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGNvbE51bToge1xyXG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogMTJcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgcm93SGVpZ2h0OiB7XHJcbiAgICAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiAxNTBcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgbWF4Um93czoge1xyXG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogSW5maW5pdHlcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgbWFyZ2luOiB7XHJcbiAgICAgICAgICAgICAgICB0eXBlOiBBcnJheSxcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzEwLCAxMF07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGlzRHJhZ2dhYmxlOiB7XHJcbiAgICAgICAgICAgICAgICB0eXBlOiBCb29sZWFuLFxyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogdHJ1ZVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBpc1Jlc2l6YWJsZToge1xyXG4gICAgICAgICAgICAgICAgdHlwZTogQm9vbGVhbixcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRydWVcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgaXNNaXJyb3JlZDoge1xyXG4gICAgICAgICAgICAgICAgdHlwZTogQm9vbGVhbixcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IGZhbHNlXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHVzZUNzc1RyYW5zZm9ybXM6IHtcclxuICAgICAgICAgICAgICAgIHR5cGU6IEJvb2xlYW4sXHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiB0cnVlXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHZlcnRpY2FsQ29tcGFjdDoge1xyXG4gICAgICAgICAgICAgICAgdHlwZTogQm9vbGVhbixcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRydWVcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgbGF5b3V0OiB7XHJcbiAgICAgICAgICAgICAgICB0eXBlOiBBcnJheSxcclxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlLFxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZGF0YTogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgd2lkdGg6IG51bGwsXHJcbiAgICAgICAgICAgICAgICBtZXJnZWRTdHlsZToge30sXHJcbiAgICAgICAgICAgICAgICBsYXN0TGF5b3V0TGVuZ3RoOiAwLFxyXG4gICAgICAgICAgICAgICAgaXNEcmFnZ2luZzogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcjoge1xyXG4gICAgICAgICAgICAgICAgICAgIHg6IDAsXHJcbiAgICAgICAgICAgICAgICAgICAgeTogMCxcclxuICAgICAgICAgICAgICAgICAgICB3OiAwLFxyXG4gICAgICAgICAgICAgICAgICAgIGg6IDAsXHJcbiAgICAgICAgICAgICAgICAgICAgaTogLTFcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfSxcclxuICAgICAgICBjcmVhdGVkICgpIHtcclxuICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgICAgICAgICAgLy8gQWNjZXNzaWJsZSByZWZlcm5jZXMgb2YgZnVuY3Rpb25zIGZvciByZW1vdmluZyBpbiBiZWZvcmVEZXN0cm95XHJcbiAgICAgICAgICAgIHNlbGYucmVzaXplRXZlbnRIYW5kbGVyID0gZnVuY3Rpb24oZXZlbnRUeXBlLCBpLCB4LCB5LCBoLCB3KSB7XHJcbiAgICAgICAgICAgICAgICBzZWxmLnJlc2l6ZUV2ZW50KGV2ZW50VHlwZSwgaSwgeCwgeSwgaCwgdyk7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBzZWxmLmRyYWdFdmVudEhhbmRsZXIgPSBmdW5jdGlvbihldmVudFR5cGUsIGksIHgsIHksIGgsIHcpIHtcclxuICAgICAgICAgICAgICAgIHNlbGYuZHJhZ0V2ZW50KGV2ZW50VHlwZSwgaSwgeCwgeSwgaCwgdyk7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBzZWxmLl9wcm92aWRlZC5ldmVudEJ1cyA9ICBuZXcgVnVlKCk7XHJcbiAgICAgICAgICAgIHNlbGYuZXZlbnRCdXMgPSBzZWxmLl9wcm92aWRlZC5ldmVudEJ1cztcclxuICAgICAgICAgICAgc2VsZi5ldmVudEJ1cy4kb24oJ3Jlc2l6ZUV2ZW50Jywgc2VsZi5yZXNpemVFdmVudEhhbmRsZXIpO1xyXG4gICAgICAgICAgICBzZWxmLmV2ZW50QnVzLiRvbignZHJhZ0V2ZW50Jywgc2VsZi5kcmFnRXZlbnRIYW5kbGVyKTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIGJlZm9yZURlc3Ryb3k6IGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgICAgIC8vUmVtb3ZlIGxpc3RlbmVyc1xyXG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRvZmYoJ3Jlc2l6ZUV2ZW50Jywgc2VsZi5yZXNpemVFdmVudEhhbmRsZXIpO1xyXG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRvZmYoJ2RyYWdFdmVudCcsIHNlbGYuZHJhZ0V2ZW50SGFuZGxlcik7XHJcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFwicmVzaXplXCIsIHNlbGYub25XaW5kb3dSZXNpemUpXHJcbiAgICAgICAgfSxcclxuICAgICAgICBtb3VudGVkOiBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgdGhpcy4kbmV4dFRpY2soZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgdmFsaWRhdGVMYXlvdXQodGhpcy5sYXlvdXQpO1xyXG4gICAgICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgICAgICAgICAgdGhpcy4kbmV4dFRpY2soZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYud2lkdGggPT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5vbldpbmRvd1Jlc2l6ZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3NlbGYud2lkdGggPSBzZWxmLiRlbC5vZmZzZXRXaWR0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIHNlbGYub25XaW5kb3dSZXNpemUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBjb21wYWN0KHNlbGYubGF5b3V0LCBzZWxmLnZlcnRpY2FsQ29tcGFjdCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYudXBkYXRlSGVpZ2h0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZi4kbmV4dFRpY2soZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZXJkID0gZWxlbWVudFJlc2l6ZURldGVjdG9yTWFrZXIoe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyYXRlZ3k6IFwic2Nyb2xsXCIgLy88LSBGb3IgdWx0cmEgcGVyZm9ybWFuY2UuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlcmQubGlzdGVuVG8oc2VsZi4kcmVmcy5pdGVtLCBmdW5jdGlvbiAoZWxlbWVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5vbldpbmRvd1Jlc2l6ZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgd2luZG93Lm9ubG9hZCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLndpZHRoID09PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYub25XaW5kb3dSZXNpemUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9zZWxmLndpZHRoID0gc2VsZi4kZWwub2Zmc2V0V2lkdGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCBzZWxmLm9uV2luZG93UmVzaXplKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgY29tcGFjdChzZWxmLmxheW91dCwgc2VsZi52ZXJ0aWNhbENvbXBhY3QpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBzZWxmLnVwZGF0ZUhlaWdodCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuJG5leHRUaWNrKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVyZCA9IGVsZW1lbnRSZXNpemVEZXRlY3Rvck1ha2VyKHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmF0ZWd5OiBcInNjcm9sbFwiIC8vPC0gRm9yIHVsdHJhIHBlcmZvcm1hbmNlLlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXJkLmxpc3RlblRvKHNlbGYuJHJlZnMuaXRlbSwgZnVuY3Rpb24gKGVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYub25XaW5kb3dSZXNpemUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICB3YXRjaDoge1xyXG4gICAgICAgICAgICB3aWR0aDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy4kbmV4dFRpY2soZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vdGhpcy4kYnJvYWRjYXN0KFwidXBkYXRlV2lkdGhcIiwgdGhpcy53aWR0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kZW1pdChcInVwZGF0ZVdpZHRoXCIsIHRoaXMud2lkdGgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlSGVpZ2h0KCk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgbGF5b3V0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmxheW91dFVwZGF0ZSgpO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICByb3dIZWlnaHQ6IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kZW1pdChcInNldFJvd0hlaWdodFwiLCB0aGlzLnJvd0hlaWdodCk7XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGlzRHJhZ2dhYmxlOiBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJGVtaXQoXCJzZXREcmFnZ2FibGVcIiwgdGhpcy5pc0RyYWdnYWJsZSk7XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGlzUmVzaXphYmxlOiBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJGVtaXQoXCJzZXRSZXNpemFibGVcIiwgdGhpcy5pc1Jlc2l6YWJsZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG4gICAgICAgIG1ldGhvZHM6IHtcclxuICAgICAgICAgICAgbGF5b3V0VXBkYXRlKCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMubGF5b3V0ICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5sYXlvdXQubGVuZ3RoICE9PSB0aGlzLmxhc3RMYXlvdXRMZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9jb25zb2xlLmxvZyhcIiMjIyBMQVlPVVQgVVBEQVRFIVwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sYXN0TGF5b3V0TGVuZ3RoID0gdGhpcy5sYXlvdXQubGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBjb21wYWN0KHRoaXMubGF5b3V0LCB0aGlzLnZlcnRpY2FsQ29tcGFjdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kZW1pdChcInVwZGF0ZVdpZHRoXCIsIHRoaXMud2lkdGgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlSGVpZ2h0KCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHVwZGF0ZUhlaWdodDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5tZXJnZWRTdHlsZSA9IHtcclxuICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IHRoaXMuY29udGFpbmVySGVpZ2h0KClcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIG9uV2luZG93UmVzaXplOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy4kcmVmcyAhPT0gbnVsbCAmJiB0aGlzLiRyZWZzLml0ZW0gIT09IG51bGwgJiYgdGhpcy4kcmVmcy5pdGVtICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLndpZHRoID0gdGhpcy4kcmVmcy5pdGVtLm9mZnNldFdpZHRoO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBjb250YWluZXJIZWlnaHQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5hdXRvU2l6ZSkgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGJvdHRvbSh0aGlzLmxheW91dCkgKiAodGhpcy5yb3dIZWlnaHQgKyB0aGlzLm1hcmdpblsxXSkgKyB0aGlzLm1hcmdpblsxXSArICdweCc7XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGRyYWdFdmVudDogZnVuY3Rpb24gKGV2ZW50TmFtZSwgaWQsIHgsIHksIGgsIHcpIHtcclxuICAgICAgICAgICAgICAgIGlmIChldmVudE5hbWUgPT09IFwiZHJhZ21vdmVcIiB8fCBldmVudE5hbWUgPT09IFwiZHJhZ3N0YXJ0XCIpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsYWNlaG9sZGVyLmkgPSBpZDtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsYWNlaG9sZGVyLnggPSB4O1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGxhY2Vob2xkZXIueSA9IHk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbGFjZWhvbGRlci53ID0gdztcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsYWNlaG9sZGVyLmggPSBoO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuJG5leHRUaWNrKGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzRHJhZ2dpbmcgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vdGhpcy4kYnJvYWRjYXN0KFwidXBkYXRlV2lkdGhcIiwgdGhpcy53aWR0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kZW1pdChcInVwZGF0ZVdpZHRoXCIsIHRoaXMud2lkdGgpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLiRuZXh0VGljayhmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0RyYWdnaW5nID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKGV2ZW50TmFtZSArIFwiIGlkPVwiICsgaWQgKyBcIiwgeD1cIiArIHggKyBcIiwgeT1cIiArIHkpO1xyXG4gICAgICAgICAgICAgICAgdmFyIGwgPSBnZXRMYXlvdXRJdGVtKHRoaXMubGF5b3V0LCBpZCk7XHJcbiAgICAgICAgICAgICAgICAvL0dldExheW91dEl0ZW0gc29tZXRpbWVzIHJldHVybnMgbnVsbCBvYmplY3RcclxuICAgICAgICAgICAgICAgIGlmIChsID09PSB1bmRlZmluZWQgfHwgbCA9PT0gbnVsbCl7XHJcbiAgICAgICAgICAgICAgICAgICAgbCA9IHt4OjAsIHk6MH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGwueCA9IHg7XHJcbiAgICAgICAgICAgICAgICBsLnkgPSB5O1xyXG4gICAgICAgICAgICAgICAgLy8gTW92ZSB0aGUgZWxlbWVudCB0byB0aGUgZHJhZ2dlZCBsb2NhdGlvbi5cclxuICAgICAgICAgICAgICAgIHRoaXMubGF5b3V0ID0gbW92ZUVsZW1lbnQodGhpcy5sYXlvdXQsIGwsIHgsIHksIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgY29tcGFjdCh0aGlzLmxheW91dCwgdGhpcy52ZXJ0aWNhbENvbXBhY3QpO1xyXG4gICAgICAgICAgICAgICAgLy8gbmVlZGVkIGJlY2F1c2UgdnVlIGNhbid0IGRldGVjdCBjaGFuZ2VzIG9uIGFycmF5IGVsZW1lbnQgcHJvcGVydGllc1xyXG4gICAgICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kZW1pdChcImNvbXBhY3RcIik7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUhlaWdodCgpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50TmFtZSA9PT0gJ2RyYWdlbmQnKSB0aGlzLiRlbWl0KCdsYXlvdXQtdXBkYXRlZCcsIHRoaXMubGF5b3V0KTtcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgcmVzaXplRXZlbnQ6IGZ1bmN0aW9uIChldmVudE5hbWUsIGlkLCB4LCB5LCBoLCB3KSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnROYW1lID09PSBcInJlc2l6ZXN0YXJ0XCIgfHwgZXZlbnROYW1lID09PSBcInJlc2l6ZW1vdmVcIikge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGxhY2Vob2xkZXIuaSA9IGlkO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGxhY2Vob2xkZXIueCA9IHg7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbGFjZWhvbGRlci55ID0geTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsYWNlaG9sZGVyLncgPSB3O1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGxhY2Vob2xkZXIuaCA9IGg7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy4kbmV4dFRpY2soZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNEcmFnZ2luZyA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgLy90aGlzLiRicm9hZGNhc3QoXCJ1cGRhdGVXaWR0aFwiLCB0aGlzLndpZHRoKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRlbWl0KFwidXBkYXRlV2lkdGhcIiwgdGhpcy53aWR0aCk7XHJcblxyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLiRuZXh0VGljayhmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0RyYWdnaW5nID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB2YXIgbCA9IGdldExheW91dEl0ZW0odGhpcy5sYXlvdXQsIGlkKTtcclxuICAgICAgICAgICAgICAgIC8vR2V0TGF5b3V0SXRlbSBzb21ldGltZXMgcmV0dXJuIG51bGwgb2JqZWN0XHJcbiAgICAgICAgICAgICAgICBpZiAobCA9PT0gdW5kZWZpbmVkIHx8IGwgPT09IG51bGwpe1xyXG4gICAgICAgICAgICAgICAgICAgIGwgPSB7aDowLCB3OjB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBsLmggPSBoO1xyXG4gICAgICAgICAgICAgICAgbC53ID0gdztcclxuICAgICAgICAgICAgICAgIGNvbXBhY3QodGhpcy5sYXlvdXQsIHRoaXMudmVydGljYWxDb21wYWN0KTtcclxuICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJGVtaXQoXCJjb21wYWN0XCIpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVIZWlnaHQoKTtcclxuICAgICAgICAgICAgICAgIGlmIChldmVudE5hbWUgPT09ICdyZXNpemVlbmQnKSB0aGlzLiRlbWl0KCdsYXlvdXQtdXBkYXRlZCcsIHRoaXMubGF5b3V0KTtcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICB9LFxyXG4gICAgfVxyXG48L3NjcmlwdD5cclxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIEdyaWRMYXlvdXQudnVlPzM0NzBmMzMyIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///20\n"); - -/***/ }), -/* 21 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -eval("/* WEBPACK VAR INJECTION */(function(process, global) {/*!\n * Vue.js v2.4.2\n * (c) 2014-2017 Evan You\n * Released under the MIT License.\n */\n\n\n/* */\n\n// these helpers produces better vm code in JS engines due to their\n// explicitness and function inlining\nfunction isUndef (v) {\n return v === undefined || v === null\n}\n\nfunction isDef (v) {\n return v !== undefined && v !== null\n}\n\nfunction isTrue (v) {\n return v === true\n}\n\nfunction isFalse (v) {\n return v === false\n}\n\n/**\n * Check if value is primitive\n */\nfunction isPrimitive (value) {\n return (\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n )\n}\n\n/**\n * Quick object check - this is primarily used to tell\n * Objects from primitive values when we know the value\n * is a JSON-compliant type.\n */\nfunction isObject (obj) {\n return obj !== null && typeof obj === 'object'\n}\n\nvar _toString = Object.prototype.toString;\n\n/**\n * Strict object type check. Only returns true\n * for plain JavaScript objects.\n */\nfunction isPlainObject (obj) {\n return _toString.call(obj) === '[object Object]'\n}\n\nfunction isRegExp (v) {\n return _toString.call(v) === '[object RegExp]'\n}\n\n/**\n * Check if val is a valid array index.\n */\nfunction isValidArrayIndex (val) {\n var n = parseFloat(val);\n return n >= 0 && Math.floor(n) === n && isFinite(val)\n}\n\n/**\n * Convert a value to a string that is actually rendered.\n */\nfunction toString (val) {\n return val == null\n ? ''\n : typeof val === 'object'\n ? JSON.stringify(val, null, 2)\n : String(val)\n}\n\n/**\n * Convert a input value to a number for persistence.\n * If the conversion fails, return original string.\n */\nfunction toNumber (val) {\n var n = parseFloat(val);\n return isNaN(n) ? val : n\n}\n\n/**\n * Make a map and return a function for checking if a key\n * is in that map.\n */\nfunction makeMap (\n str,\n expectsLowerCase\n) {\n var map = Object.create(null);\n var list = str.split(',');\n for (var i = 0; i < list.length; i++) {\n map[list[i]] = true;\n }\n return expectsLowerCase\n ? function (val) { return map[val.toLowerCase()]; }\n : function (val) { return map[val]; }\n}\n\n/**\n * Check if a tag is a built-in tag.\n */\nvar isBuiltInTag = makeMap('slot,component', true);\n\n/**\n * Check if a attribute is a reserved attribute.\n */\nvar isReservedAttribute = makeMap('key,ref,slot,is');\n\n/**\n * Remove an item from an array\n */\nfunction remove (arr, item) {\n if (arr.length) {\n var index = arr.indexOf(item);\n if (index > -1) {\n return arr.splice(index, 1)\n }\n }\n}\n\n/**\n * Check whether the object has the property.\n */\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\nfunction hasOwn (obj, key) {\n return hasOwnProperty.call(obj, key)\n}\n\n/**\n * Create a cached version of a pure function.\n */\nfunction cached (fn) {\n var cache = Object.create(null);\n return (function cachedFn (str) {\n var hit = cache[str];\n return hit || (cache[str] = fn(str))\n })\n}\n\n/**\n * Camelize a hyphen-delimited string.\n */\nvar camelizeRE = /-(\\w)/g;\nvar camelize = cached(function (str) {\n return str.replace(camelizeRE, function (_, c) { return c ? c.toUpperCase() : ''; })\n});\n\n/**\n * Capitalize a string.\n */\nvar capitalize = cached(function (str) {\n return str.charAt(0).toUpperCase() + str.slice(1)\n});\n\n/**\n * Hyphenate a camelCase string.\n */\nvar hyphenateRE = /([^-])([A-Z])/g;\nvar hyphenate = cached(function (str) {\n return str\n .replace(hyphenateRE, '$1-$2')\n .replace(hyphenateRE, '$1-$2')\n .toLowerCase()\n});\n\n/**\n * Simple bind, faster than native\n */\nfunction bind (fn, ctx) {\n function boundFn (a) {\n var l = arguments.length;\n return l\n ? l > 1\n ? fn.apply(ctx, arguments)\n : fn.call(ctx, a)\n : fn.call(ctx)\n }\n // record original fn length\n boundFn._length = fn.length;\n return boundFn\n}\n\n/**\n * Convert an Array-like object to a real Array.\n */\nfunction toArray (list, start) {\n start = start || 0;\n var i = list.length - start;\n var ret = new Array(i);\n while (i--) {\n ret[i] = list[i + start];\n }\n return ret\n}\n\n/**\n * Mix properties into target object.\n */\nfunction extend (to, _from) {\n for (var key in _from) {\n to[key] = _from[key];\n }\n return to\n}\n\n/**\n * Merge an Array of Objects into a single Object.\n */\nfunction toObject (arr) {\n var res = {};\n for (var i = 0; i < arr.length; i++) {\n if (arr[i]) {\n extend(res, arr[i]);\n }\n }\n return res\n}\n\n/**\n * Perform no operation.\n * Stubbing args to make Flow happy without leaving useless transpiled code\n * with ...rest (https://flow.org/blog/2017/05/07/Strict-Function-Call-Arity/)\n */\nfunction noop (a, b, c) {}\n\n/**\n * Always return false.\n */\nvar no = function (a, b, c) { return false; };\n\n/**\n * Return same value\n */\nvar identity = function (_) { return _; };\n\n/**\n * Generate a static keys string from compiler modules.\n */\nfunction genStaticKeys (modules) {\n return modules.reduce(function (keys, m) {\n return keys.concat(m.staticKeys || [])\n }, []).join(',')\n}\n\n/**\n * Check if two values are loosely equal - that is,\n * if they are plain objects, do they have the same shape?\n */\nfunction looseEqual (a, b) {\n if (a === b) { return true }\n var isObjectA = isObject(a);\n var isObjectB = isObject(b);\n if (isObjectA && isObjectB) {\n try {\n var isArrayA = Array.isArray(a);\n var isArrayB = Array.isArray(b);\n if (isArrayA && isArrayB) {\n return a.length === b.length && a.every(function (e, i) {\n return looseEqual(e, b[i])\n })\n } else if (!isArrayA && !isArrayB) {\n var keysA = Object.keys(a);\n var keysB = Object.keys(b);\n return keysA.length === keysB.length && keysA.every(function (key) {\n return looseEqual(a[key], b[key])\n })\n } else {\n /* istanbul ignore next */\n return false\n }\n } catch (e) {\n /* istanbul ignore next */\n return false\n }\n } else if (!isObjectA && !isObjectB) {\n return String(a) === String(b)\n } else {\n return false\n }\n}\n\nfunction looseIndexOf (arr, val) {\n for (var i = 0; i < arr.length; i++) {\n if (looseEqual(arr[i], val)) { return i }\n }\n return -1\n}\n\n/**\n * Ensure a function is called only once.\n */\nfunction once (fn) {\n var called = false;\n return function () {\n if (!called) {\n called = true;\n fn.apply(this, arguments);\n }\n }\n}\n\nvar SSR_ATTR = 'data-server-rendered';\n\nvar ASSET_TYPES = [\n 'component',\n 'directive',\n 'filter'\n];\n\nvar LIFECYCLE_HOOKS = [\n 'beforeCreate',\n 'created',\n 'beforeMount',\n 'mounted',\n 'beforeUpdate',\n 'updated',\n 'beforeDestroy',\n 'destroyed',\n 'activated',\n 'deactivated'\n];\n\n/* */\n\nvar config = ({\n /**\n * Option merge strategies (used in core/util/options)\n */\n optionMergeStrategies: Object.create(null),\n\n /**\n * Whether to suppress warnings.\n */\n silent: false,\n\n /**\n * Show production mode tip message on boot?\n */\n productionTip: process.env.NODE_ENV !== 'production',\n\n /**\n * Whether to enable devtools\n */\n devtools: process.env.NODE_ENV !== 'production',\n\n /**\n * Whether to record perf\n */\n performance: false,\n\n /**\n * Error handler for watcher errors\n */\n errorHandler: null,\n\n /**\n * Warn handler for watcher warns\n */\n warnHandler: null,\n\n /**\n * Ignore certain custom elements\n */\n ignoredElements: [],\n\n /**\n * Custom user key aliases for v-on\n */\n keyCodes: Object.create(null),\n\n /**\n * Check if a tag is reserved so that it cannot be registered as a\n * component. This is platform-dependent and may be overwritten.\n */\n isReservedTag: no,\n\n /**\n * Check if an attribute is reserved so that it cannot be used as a component\n * prop. This is platform-dependent and may be overwritten.\n */\n isReservedAttr: no,\n\n /**\n * Check if a tag is an unknown element.\n * Platform-dependent.\n */\n isUnknownElement: no,\n\n /**\n * Get the namespace of an element\n */\n getTagNamespace: noop,\n\n /**\n * Parse the real tag name for the specific platform.\n */\n parsePlatformTagName: identity,\n\n /**\n * Check if an attribute must be bound using property, e.g. value\n * Platform-dependent.\n */\n mustUseProp: no,\n\n /**\n * Exposed for legacy reasons\n */\n _lifecycleHooks: LIFECYCLE_HOOKS\n});\n\n/* */\n\nvar emptyObject = Object.freeze({});\n\n/**\n * Check if a string starts with $ or _\n */\nfunction isReserved (str) {\n var c = (str + '').charCodeAt(0);\n return c === 0x24 || c === 0x5F\n}\n\n/**\n * Define a property.\n */\nfunction def (obj, key, val, enumerable) {\n Object.defineProperty(obj, key, {\n value: val,\n enumerable: !!enumerable,\n writable: true,\n configurable: true\n });\n}\n\n/**\n * Parse simple path.\n */\nvar bailRE = /[^\\w.$]/;\nfunction parsePath (path) {\n if (bailRE.test(path)) {\n return\n }\n var segments = path.split('.');\n return function (obj) {\n for (var i = 0; i < segments.length; i++) {\n if (!obj) { return }\n obj = obj[segments[i]];\n }\n return obj\n }\n}\n\n/* */\n\nvar warn = noop;\nvar tip = noop;\nvar formatComponentName = (null); // work around flow check\n\nif (process.env.NODE_ENV !== 'production') {\n var hasConsole = typeof console !== 'undefined';\n var classifyRE = /(?:^|[-_])(\\w)/g;\n var classify = function (str) { return str\n .replace(classifyRE, function (c) { return c.toUpperCase(); })\n .replace(/[-_]/g, ''); };\n\n warn = function (msg, vm) {\n var trace = vm ? generateComponentTrace(vm) : '';\n\n if (config.warnHandler) {\n config.warnHandler.call(null, msg, vm, trace);\n } else if (hasConsole && (!config.silent)) {\n console.error((\"[Vue warn]: \" + msg + trace));\n }\n };\n\n tip = function (msg, vm) {\n if (hasConsole && (!config.silent)) {\n console.warn(\"[Vue tip]: \" + msg + (\n vm ? generateComponentTrace(vm) : ''\n ));\n }\n };\n\n formatComponentName = function (vm, includeFile) {\n if (vm.$root === vm) {\n return ''\n }\n var name = typeof vm === 'string'\n ? vm\n : typeof vm === 'function' && vm.options\n ? vm.options.name\n : vm._isVue\n ? vm.$options.name || vm.$options._componentTag\n : vm.name;\n\n var file = vm._isVue && vm.$options.__file;\n if (!name && file) {\n var match = file.match(/([^/\\\\]+)\\.vue$/);\n name = match && match[1];\n }\n\n return (\n (name ? (\"<\" + (classify(name)) + \">\") : \"\") +\n (file && includeFile !== false ? (\" at \" + file) : '')\n )\n };\n\n var repeat = function (str, n) {\n var res = '';\n while (n) {\n if (n % 2 === 1) { res += str; }\n if (n > 1) { str += str; }\n n >>= 1;\n }\n return res\n };\n\n var generateComponentTrace = function (vm) {\n if (vm._isVue && vm.$parent) {\n var tree = [];\n var currentRecursiveSequence = 0;\n while (vm) {\n if (tree.length > 0) {\n var last = tree[tree.length - 1];\n if (last.constructor === vm.constructor) {\n currentRecursiveSequence++;\n vm = vm.$parent;\n continue\n } else if (currentRecursiveSequence > 0) {\n tree[tree.length - 1] = [last, currentRecursiveSequence];\n currentRecursiveSequence = 0;\n }\n }\n tree.push(vm);\n vm = vm.$parent;\n }\n return '\\n\\nfound in\\n\\n' + tree\n .map(function (vm, i) { return (\"\" + (i === 0 ? '---> ' : repeat(' ', 5 + i * 2)) + (Array.isArray(vm)\n ? ((formatComponentName(vm[0])) + \"... (\" + (vm[1]) + \" recursive calls)\")\n : formatComponentName(vm))); })\n .join('\\n')\n } else {\n return (\"\\n\\n(found in \" + (formatComponentName(vm)) + \")\")\n }\n };\n}\n\n/* */\n\nfunction handleError (err, vm, info) {\n if (config.errorHandler) {\n config.errorHandler.call(null, err, vm, info);\n } else {\n if (process.env.NODE_ENV !== 'production') {\n warn((\"Error in \" + info + \": \\\"\" + (err.toString()) + \"\\\"\"), vm);\n }\n /* istanbul ignore else */\n if (inBrowser && typeof console !== 'undefined') {\n console.error(err);\n } else {\n throw err\n }\n }\n}\n\n/* */\n/* globals MutationObserver */\n\n// can we use __proto__?\nvar hasProto = '__proto__' in {};\n\n// Browser environment sniffing\nvar inBrowser = typeof window !== 'undefined';\nvar UA = inBrowser && window.navigator.userAgent.toLowerCase();\nvar isIE = UA && /msie|trident/.test(UA);\nvar isIE9 = UA && UA.indexOf('msie 9.0') > 0;\nvar isEdge = UA && UA.indexOf('edge/') > 0;\nvar isAndroid = UA && UA.indexOf('android') > 0;\nvar isIOS = UA && /iphone|ipad|ipod|ios/.test(UA);\nvar isChrome = UA && /chrome\\/\\d+/.test(UA) && !isEdge;\n\n// Firefix has a \"watch\" function on Object.prototype...\nvar nativeWatch = ({}).watch;\n\nvar supportsPassive = false;\nif (inBrowser) {\n try {\n var opts = {};\n Object.defineProperty(opts, 'passive', ({\n get: function get () {\n /* istanbul ignore next */\n supportsPassive = true;\n }\n })); // https://github.com/facebook/flow/issues/285\n window.addEventListener('test-passive', null, opts);\n } catch (e) {}\n}\n\n// this needs to be lazy-evaled because vue may be required before\n// vue-server-renderer can set VUE_ENV\nvar _isServer;\nvar isServerRendering = function () {\n if (_isServer === undefined) {\n /* istanbul ignore if */\n if (!inBrowser && typeof global !== 'undefined') {\n // detect presence of vue-server-renderer and avoid\n // Webpack shimming the process\n _isServer = global['process'].env.VUE_ENV === 'server';\n } else {\n _isServer = false;\n }\n }\n return _isServer\n};\n\n// detect devtools\nvar devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__;\n\n/* istanbul ignore next */\nfunction isNative (Ctor) {\n return typeof Ctor === 'function' && /native code/.test(Ctor.toString())\n}\n\nvar hasSymbol =\n typeof Symbol !== 'undefined' && isNative(Symbol) &&\n typeof Reflect !== 'undefined' && isNative(Reflect.ownKeys);\n\n/**\n * Defer a task to execute it asynchronously.\n */\nvar nextTick = (function () {\n var callbacks = [];\n var pending = false;\n var timerFunc;\n\n function nextTickHandler () {\n pending = false;\n var copies = callbacks.slice(0);\n callbacks.length = 0;\n for (var i = 0; i < copies.length; i++) {\n copies[i]();\n }\n }\n\n // the nextTick behavior leverages the microtask queue, which can be accessed\n // via either native Promise.then or MutationObserver.\n // MutationObserver has wider support, however it is seriously bugged in\n // UIWebView in iOS >= 9.3.3 when triggered in touch event handlers. It\n // completely stops working after triggering a few times... so, if native\n // Promise is available, we will use it:\n /* istanbul ignore if */\n if (typeof Promise !== 'undefined' && isNative(Promise)) {\n var p = Promise.resolve();\n var logError = function (err) { console.error(err); };\n timerFunc = function () {\n p.then(nextTickHandler).catch(logError);\n // in problematic UIWebViews, Promise.then doesn't completely break, but\n // it can get stuck in a weird state where callbacks are pushed into the\n // microtask queue but the queue isn't being flushed, until the browser\n // needs to do some other work, e.g. handle a timer. Therefore we can\n // \"force\" the microtask queue to be flushed by adding an empty timer.\n if (isIOS) { setTimeout(noop); }\n };\n } else if (typeof MutationObserver !== 'undefined' && (\n isNative(MutationObserver) ||\n // PhantomJS and iOS 7.x\n MutationObserver.toString() === '[object MutationObserverConstructor]'\n )) {\n // use MutationObserver where native Promise is not available,\n // e.g. PhantomJS IE11, iOS7, Android 4.4\n var counter = 1;\n var observer = new MutationObserver(nextTickHandler);\n var textNode = document.createTextNode(String(counter));\n observer.observe(textNode, {\n characterData: true\n });\n timerFunc = function () {\n counter = (counter + 1) % 2;\n textNode.data = String(counter);\n };\n } else {\n // fallback to setTimeout\n /* istanbul ignore next */\n timerFunc = function () {\n setTimeout(nextTickHandler, 0);\n };\n }\n\n return function queueNextTick (cb, ctx) {\n var _resolve;\n callbacks.push(function () {\n if (cb) {\n try {\n cb.call(ctx);\n } catch (e) {\n handleError(e, ctx, 'nextTick');\n }\n } else if (_resolve) {\n _resolve(ctx);\n }\n });\n if (!pending) {\n pending = true;\n timerFunc();\n }\n if (!cb && typeof Promise !== 'undefined') {\n return new Promise(function (resolve, reject) {\n _resolve = resolve;\n })\n }\n }\n})();\n\nvar _Set;\n/* istanbul ignore if */\nif (typeof Set !== 'undefined' && isNative(Set)) {\n // use native Set when available.\n _Set = Set;\n} else {\n // a non-standard Set polyfill that only works with primitive keys.\n _Set = (function () {\n function Set () {\n this.set = Object.create(null);\n }\n Set.prototype.has = function has (key) {\n return this.set[key] === true\n };\n Set.prototype.add = function add (key) {\n this.set[key] = true;\n };\n Set.prototype.clear = function clear () {\n this.set = Object.create(null);\n };\n\n return Set;\n }());\n}\n\n/* */\n\n\nvar uid = 0;\n\n/**\n * A dep is an observable that can have multiple\n * directives subscribing to it.\n */\nvar Dep = function Dep () {\n this.id = uid++;\n this.subs = [];\n};\n\nDep.prototype.addSub = function addSub (sub) {\n this.subs.push(sub);\n};\n\nDep.prototype.removeSub = function removeSub (sub) {\n remove(this.subs, sub);\n};\n\nDep.prototype.depend = function depend () {\n if (Dep.target) {\n Dep.target.addDep(this);\n }\n};\n\nDep.prototype.notify = function notify () {\n // stabilize the subscriber list first\n var subs = this.subs.slice();\n for (var i = 0, l = subs.length; i < l; i++) {\n subs[i].update();\n }\n};\n\n// the current target watcher being evaluated.\n// this is globally unique because there could be only one\n// watcher being evaluated at any time.\nDep.target = null;\nvar targetStack = [];\n\nfunction pushTarget (_target) {\n if (Dep.target) { targetStack.push(Dep.target); }\n Dep.target = _target;\n}\n\nfunction popTarget () {\n Dep.target = targetStack.pop();\n}\n\n/*\n * not type checking this file because flow doesn't play well with\n * dynamically accessing methods on Array prototype\n */\n\nvar arrayProto = Array.prototype;\nvar arrayMethods = Object.create(arrayProto);[\n 'push',\n 'pop',\n 'shift',\n 'unshift',\n 'splice',\n 'sort',\n 'reverse'\n]\n.forEach(function (method) {\n // cache original method\n var original = arrayProto[method];\n def(arrayMethods, method, function mutator () {\n var args = [], len = arguments.length;\n while ( len-- ) args[ len ] = arguments[ len ];\n\n var result = original.apply(this, args);\n var ob = this.__ob__;\n var inserted;\n switch (method) {\n case 'push':\n case 'unshift':\n inserted = args;\n break\n case 'splice':\n inserted = args.slice(2);\n break\n }\n if (inserted) { ob.observeArray(inserted); }\n // notify change\n ob.dep.notify();\n return result\n });\n});\n\n/* */\n\nvar arrayKeys = Object.getOwnPropertyNames(arrayMethods);\n\n/**\n * By default, when a reactive property is set, the new value is\n * also converted to become reactive. However when passing down props,\n * we don't want to force conversion because the value may be a nested value\n * under a frozen data structure. Converting it would defeat the optimization.\n */\nvar observerState = {\n shouldConvert: true\n};\n\n/**\n * Observer class that are attached to each observed\n * object. Once attached, the observer converts target\n * object's property keys into getter/setters that\n * collect dependencies and dispatches updates.\n */\nvar Observer = function Observer (value) {\n this.value = value;\n this.dep = new Dep();\n this.vmCount = 0;\n def(value, '__ob__', this);\n if (Array.isArray(value)) {\n var augment = hasProto\n ? protoAugment\n : copyAugment;\n augment(value, arrayMethods, arrayKeys);\n this.observeArray(value);\n } else {\n this.walk(value);\n }\n};\n\n/**\n * Walk through each property and convert them into\n * getter/setters. This method should only be called when\n * value type is Object.\n */\nObserver.prototype.walk = function walk (obj) {\n var keys = Object.keys(obj);\n for (var i = 0; i < keys.length; i++) {\n defineReactive$$1(obj, keys[i], obj[keys[i]]);\n }\n};\n\n/**\n * Observe a list of Array items.\n */\nObserver.prototype.observeArray = function observeArray (items) {\n for (var i = 0, l = items.length; i < l; i++) {\n observe(items[i]);\n }\n};\n\n// helpers\n\n/**\n * Augment an target Object or Array by intercepting\n * the prototype chain using __proto__\n */\nfunction protoAugment (target, src, keys) {\n /* eslint-disable no-proto */\n target.__proto__ = src;\n /* eslint-enable no-proto */\n}\n\n/**\n * Augment an target Object or Array by defining\n * hidden properties.\n */\n/* istanbul ignore next */\nfunction copyAugment (target, src, keys) {\n for (var i = 0, l = keys.length; i < l; i++) {\n var key = keys[i];\n def(target, key, src[key]);\n }\n}\n\n/**\n * Attempt to create an observer instance for a value,\n * returns the new observer if successfully observed,\n * or the existing observer if the value already has one.\n */\nfunction observe (value, asRootData) {\n if (!isObject(value)) {\n return\n }\n var ob;\n if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {\n ob = value.__ob__;\n } else if (\n observerState.shouldConvert &&\n !isServerRendering() &&\n (Array.isArray(value) || isPlainObject(value)) &&\n Object.isExtensible(value) &&\n !value._isVue\n ) {\n ob = new Observer(value);\n }\n if (asRootData && ob) {\n ob.vmCount++;\n }\n return ob\n}\n\n/**\n * Define a reactive property on an Object.\n */\nfunction defineReactive$$1 (\n obj,\n key,\n val,\n customSetter,\n shallow\n) {\n var dep = new Dep();\n\n var property = Object.getOwnPropertyDescriptor(obj, key);\n if (property && property.configurable === false) {\n return\n }\n\n // cater for pre-defined getter/setters\n var getter = property && property.get;\n var setter = property && property.set;\n\n var childOb = !shallow && observe(val);\n Object.defineProperty(obj, key, {\n enumerable: true,\n configurable: true,\n get: function reactiveGetter () {\n var value = getter ? getter.call(obj) : val;\n if (Dep.target) {\n dep.depend();\n if (childOb) {\n childOb.dep.depend();\n }\n if (Array.isArray(value)) {\n dependArray(value);\n }\n }\n return value\n },\n set: function reactiveSetter (newVal) {\n var value = getter ? getter.call(obj) : val;\n /* eslint-disable no-self-compare */\n if (newVal === value || (newVal !== newVal && value !== value)) {\n return\n }\n /* eslint-enable no-self-compare */\n if (process.env.NODE_ENV !== 'production' && customSetter) {\n customSetter();\n }\n if (setter) {\n setter.call(obj, newVal);\n } else {\n val = newVal;\n }\n childOb = !shallow && observe(newVal);\n dep.notify();\n }\n });\n}\n\n/**\n * Set a property on an object. Adds the new property and\n * triggers change notification if the property doesn't\n * already exist.\n */\nfunction set (target, key, val) {\n if (Array.isArray(target) && isValidArrayIndex(key)) {\n target.length = Math.max(target.length, key);\n target.splice(key, 1, val);\n return val\n }\n if (hasOwn(target, key)) {\n target[key] = val;\n return val\n }\n var ob = (target).__ob__;\n if (target._isVue || (ob && ob.vmCount)) {\n process.env.NODE_ENV !== 'production' && warn(\n 'Avoid adding reactive properties to a Vue instance or its root $data ' +\n 'at runtime - declare it upfront in the data option.'\n );\n return val\n }\n if (!ob) {\n target[key] = val;\n return val\n }\n defineReactive$$1(ob.value, key, val);\n ob.dep.notify();\n return val\n}\n\n/**\n * Delete a property and trigger change if necessary.\n */\nfunction del (target, key) {\n if (Array.isArray(target) && isValidArrayIndex(key)) {\n target.splice(key, 1);\n return\n }\n var ob = (target).__ob__;\n if (target._isVue || (ob && ob.vmCount)) {\n process.env.NODE_ENV !== 'production' && warn(\n 'Avoid deleting properties on a Vue instance or its root $data ' +\n '- just set it to null.'\n );\n return\n }\n if (!hasOwn(target, key)) {\n return\n }\n delete target[key];\n if (!ob) {\n return\n }\n ob.dep.notify();\n}\n\n/**\n * Collect dependencies on array elements when the array is touched, since\n * we cannot intercept array element access like property getters.\n */\nfunction dependArray (value) {\n for (var e = (void 0), i = 0, l = value.length; i < l; i++) {\n e = value[i];\n e && e.__ob__ && e.__ob__.dep.depend();\n if (Array.isArray(e)) {\n dependArray(e);\n }\n }\n}\n\n/* */\n\n/**\n * Option overwriting strategies are functions that handle\n * how to merge a parent option value and a child option\n * value into the final value.\n */\nvar strats = config.optionMergeStrategies;\n\n/**\n * Options with restrictions\n */\nif (process.env.NODE_ENV !== 'production') {\n strats.el = strats.propsData = function (parent, child, vm, key) {\n if (!vm) {\n warn(\n \"option \\\"\" + key + \"\\\" can only be used during instance \" +\n 'creation with the `new` keyword.'\n );\n }\n return defaultStrat(parent, child)\n };\n}\n\n/**\n * Helper that recursively merges two data objects together.\n */\nfunction mergeData (to, from) {\n if (!from) { return to }\n var key, toVal, fromVal;\n var keys = Object.keys(from);\n for (var i = 0; i < keys.length; i++) {\n key = keys[i];\n toVal = to[key];\n fromVal = from[key];\n if (!hasOwn(to, key)) {\n set(to, key, fromVal);\n } else if (isPlainObject(toVal) && isPlainObject(fromVal)) {\n mergeData(toVal, fromVal);\n }\n }\n return to\n}\n\n/**\n * Data\n */\nfunction mergeDataOrFn (\n parentVal,\n childVal,\n vm\n) {\n if (!vm) {\n // in a Vue.extend merge, both should be functions\n if (!childVal) {\n return parentVal\n }\n if (!parentVal) {\n return childVal\n }\n // when parentVal & childVal are both present,\n // we need to return a function that returns the\n // merged result of both functions... no need to\n // check if parentVal is a function here because\n // it has to be a function to pass previous merges.\n return function mergedDataFn () {\n return mergeData(\n typeof childVal === 'function' ? childVal.call(this) : childVal,\n typeof parentVal === 'function' ? parentVal.call(this) : parentVal\n )\n }\n } else if (parentVal || childVal) {\n return function mergedInstanceDataFn () {\n // instance merge\n var instanceData = typeof childVal === 'function'\n ? childVal.call(vm)\n : childVal;\n var defaultData = typeof parentVal === 'function'\n ? parentVal.call(vm)\n : undefined;\n if (instanceData) {\n return mergeData(instanceData, defaultData)\n } else {\n return defaultData\n }\n }\n }\n}\n\nstrats.data = function (\n parentVal,\n childVal,\n vm\n) {\n if (!vm) {\n if (childVal && typeof childVal !== 'function') {\n process.env.NODE_ENV !== 'production' && warn(\n 'The \"data\" option should be a function ' +\n 'that returns a per-instance value in component ' +\n 'definitions.',\n vm\n );\n\n return parentVal\n }\n return mergeDataOrFn.call(this, parentVal, childVal)\n }\n\n return mergeDataOrFn(parentVal, childVal, vm)\n};\n\n/**\n * Hooks and props are merged as arrays.\n */\nfunction mergeHook (\n parentVal,\n childVal\n) {\n return childVal\n ? parentVal\n ? parentVal.concat(childVal)\n : Array.isArray(childVal)\n ? childVal\n : [childVal]\n : parentVal\n}\n\nLIFECYCLE_HOOKS.forEach(function (hook) {\n strats[hook] = mergeHook;\n});\n\n/**\n * Assets\n *\n * When a vm is present (instance creation), we need to do\n * a three-way merge between constructor options, instance\n * options and parent options.\n */\nfunction mergeAssets (parentVal, childVal) {\n var res = Object.create(parentVal || null);\n return childVal\n ? extend(res, childVal)\n : res\n}\n\nASSET_TYPES.forEach(function (type) {\n strats[type + 's'] = mergeAssets;\n});\n\n/**\n * Watchers.\n *\n * Watchers hashes should not overwrite one\n * another, so we merge them as arrays.\n */\nstrats.watch = function (parentVal, childVal) {\n // work around Firefox's Object.prototype.watch...\n if (parentVal === nativeWatch) { parentVal = undefined; }\n if (childVal === nativeWatch) { childVal = undefined; }\n /* istanbul ignore if */\n if (!childVal) { return Object.create(parentVal || null) }\n if (!parentVal) { return childVal }\n var ret = {};\n extend(ret, parentVal);\n for (var key in childVal) {\n var parent = ret[key];\n var child = childVal[key];\n if (parent && !Array.isArray(parent)) {\n parent = [parent];\n }\n ret[key] = parent\n ? parent.concat(child)\n : Array.isArray(child) ? child : [child];\n }\n return ret\n};\n\n/**\n * Other object hashes.\n */\nstrats.props =\nstrats.methods =\nstrats.inject =\nstrats.computed = function (parentVal, childVal) {\n if (!parentVal) { return childVal }\n var ret = Object.create(null);\n extend(ret, parentVal);\n if (childVal) { extend(ret, childVal); }\n return ret\n};\nstrats.provide = mergeDataOrFn;\n\n/**\n * Default strategy.\n */\nvar defaultStrat = function (parentVal, childVal) {\n return childVal === undefined\n ? parentVal\n : childVal\n};\n\n/**\n * Validate component names\n */\nfunction checkComponents (options) {\n for (var key in options.components) {\n var lower = key.toLowerCase();\n if (isBuiltInTag(lower) || config.isReservedTag(lower)) {\n warn(\n 'Do not use built-in or reserved HTML elements as component ' +\n 'id: ' + key\n );\n }\n }\n}\n\n/**\n * Ensure all props option syntax are normalized into the\n * Object-based format.\n */\nfunction normalizeProps (options) {\n var props = options.props;\n if (!props) { return }\n var res = {};\n var i, val, name;\n if (Array.isArray(props)) {\n i = props.length;\n while (i--) {\n val = props[i];\n if (typeof val === 'string') {\n name = camelize(val);\n res[name] = { type: null };\n } else if (process.env.NODE_ENV !== 'production') {\n warn('props must be strings when using array syntax.');\n }\n }\n } else if (isPlainObject(props)) {\n for (var key in props) {\n val = props[key];\n name = camelize(key);\n res[name] = isPlainObject(val)\n ? val\n : { type: val };\n }\n }\n options.props = res;\n}\n\n/**\n * Normalize all injections into Object-based format\n */\nfunction normalizeInject (options) {\n var inject = options.inject;\n if (Array.isArray(inject)) {\n var normalized = options.inject = {};\n for (var i = 0; i < inject.length; i++) {\n normalized[inject[i]] = inject[i];\n }\n }\n}\n\n/**\n * Normalize raw function directives into object format.\n */\nfunction normalizeDirectives (options) {\n var dirs = options.directives;\n if (dirs) {\n for (var key in dirs) {\n var def = dirs[key];\n if (typeof def === 'function') {\n dirs[key] = { bind: def, update: def };\n }\n }\n }\n}\n\n/**\n * Merge two option objects into a new one.\n * Core utility used in both instantiation and inheritance.\n */\nfunction mergeOptions (\n parent,\n child,\n vm\n) {\n if (process.env.NODE_ENV !== 'production') {\n checkComponents(child);\n }\n\n if (typeof child === 'function') {\n child = child.options;\n }\n\n normalizeProps(child);\n normalizeInject(child);\n normalizeDirectives(child);\n var extendsFrom = child.extends;\n if (extendsFrom) {\n parent = mergeOptions(parent, extendsFrom, vm);\n }\n if (child.mixins) {\n for (var i = 0, l = child.mixins.length; i < l; i++) {\n parent = mergeOptions(parent, child.mixins[i], vm);\n }\n }\n var options = {};\n var key;\n for (key in parent) {\n mergeField(key);\n }\n for (key in child) {\n if (!hasOwn(parent, key)) {\n mergeField(key);\n }\n }\n function mergeField (key) {\n var strat = strats[key] || defaultStrat;\n options[key] = strat(parent[key], child[key], vm, key);\n }\n return options\n}\n\n/**\n * Resolve an asset.\n * This function is used because child instances need access\n * to assets defined in its ancestor chain.\n */\nfunction resolveAsset (\n options,\n type,\n id,\n warnMissing\n) {\n /* istanbul ignore if */\n if (typeof id !== 'string') {\n return\n }\n var assets = options[type];\n // check local registration variations first\n if (hasOwn(assets, id)) { return assets[id] }\n var camelizedId = camelize(id);\n if (hasOwn(assets, camelizedId)) { return assets[camelizedId] }\n var PascalCaseId = capitalize(camelizedId);\n if (hasOwn(assets, PascalCaseId)) { return assets[PascalCaseId] }\n // fallback to prototype chain\n var res = assets[id] || assets[camelizedId] || assets[PascalCaseId];\n if (process.env.NODE_ENV !== 'production' && warnMissing && !res) {\n warn(\n 'Failed to resolve ' + type.slice(0, -1) + ': ' + id,\n options\n );\n }\n return res\n}\n\n/* */\n\nfunction validateProp (\n key,\n propOptions,\n propsData,\n vm\n) {\n var prop = propOptions[key];\n var absent = !hasOwn(propsData, key);\n var value = propsData[key];\n // handle boolean props\n if (isType(Boolean, prop.type)) {\n if (absent && !hasOwn(prop, 'default')) {\n value = false;\n } else if (!isType(String, prop.type) && (value === '' || value === hyphenate(key))) {\n value = true;\n }\n }\n // check default value\n if (value === undefined) {\n value = getPropDefaultValue(vm, prop, key);\n // since the default value is a fresh copy,\n // make sure to observe it.\n var prevShouldConvert = observerState.shouldConvert;\n observerState.shouldConvert = true;\n observe(value);\n observerState.shouldConvert = prevShouldConvert;\n }\n if (process.env.NODE_ENV !== 'production') {\n assertProp(prop, key, value, vm, absent);\n }\n return value\n}\n\n/**\n * Get the default value of a prop.\n */\nfunction getPropDefaultValue (vm, prop, key) {\n // no default, return undefined\n if (!hasOwn(prop, 'default')) {\n return undefined\n }\n var def = prop.default;\n // warn against non-factory defaults for Object & Array\n if (process.env.NODE_ENV !== 'production' && isObject(def)) {\n warn(\n 'Invalid default value for prop \"' + key + '\": ' +\n 'Props with type Object/Array must use a factory function ' +\n 'to return the default value.',\n vm\n );\n }\n // the raw prop value was also undefined from previous render,\n // return previous default value to avoid unnecessary watcher trigger\n if (vm && vm.$options.propsData &&\n vm.$options.propsData[key] === undefined &&\n vm._props[key] !== undefined\n ) {\n return vm._props[key]\n }\n // call factory function for non-Function types\n // a value is Function if its prototype is function even across different execution context\n return typeof def === 'function' && getType(prop.type) !== 'Function'\n ? def.call(vm)\n : def\n}\n\n/**\n * Assert whether a prop is valid.\n */\nfunction assertProp (\n prop,\n name,\n value,\n vm,\n absent\n) {\n if (prop.required && absent) {\n warn(\n 'Missing required prop: \"' + name + '\"',\n vm\n );\n return\n }\n if (value == null && !prop.required) {\n return\n }\n var type = prop.type;\n var valid = !type || type === true;\n var expectedTypes = [];\n if (type) {\n if (!Array.isArray(type)) {\n type = [type];\n }\n for (var i = 0; i < type.length && !valid; i++) {\n var assertedType = assertType(value, type[i]);\n expectedTypes.push(assertedType.expectedType || '');\n valid = assertedType.valid;\n }\n }\n if (!valid) {\n warn(\n 'Invalid prop: type check failed for prop \"' + name + '\".' +\n ' Expected ' + expectedTypes.map(capitalize).join(', ') +\n ', got ' + Object.prototype.toString.call(value).slice(8, -1) + '.',\n vm\n );\n return\n }\n var validator = prop.validator;\n if (validator) {\n if (!validator(value)) {\n warn(\n 'Invalid prop: custom validator check failed for prop \"' + name + '\".',\n vm\n );\n }\n }\n}\n\nvar simpleCheckRE = /^(String|Number|Boolean|Function|Symbol)$/;\n\nfunction assertType (value, type) {\n var valid;\n var expectedType = getType(type);\n if (simpleCheckRE.test(expectedType)) {\n valid = typeof value === expectedType.toLowerCase();\n } else if (expectedType === 'Object') {\n valid = isPlainObject(value);\n } else if (expectedType === 'Array') {\n valid = Array.isArray(value);\n } else {\n valid = value instanceof type;\n }\n return {\n valid: valid,\n expectedType: expectedType\n }\n}\n\n/**\n * Use function string name to check built-in types,\n * because a simple equality check will fail when running\n * across different vms / iframes.\n */\nfunction getType (fn) {\n var match = fn && fn.toString().match(/^\\s*function (\\w+)/);\n return match ? match[1] : ''\n}\n\nfunction isType (type, fn) {\n if (!Array.isArray(fn)) {\n return getType(fn) === getType(type)\n }\n for (var i = 0, len = fn.length; i < len; i++) {\n if (getType(fn[i]) === getType(type)) {\n return true\n }\n }\n /* istanbul ignore next */\n return false\n}\n\n/* */\n\nvar mark;\nvar measure;\n\nif (process.env.NODE_ENV !== 'production') {\n var perf = inBrowser && window.performance;\n /* istanbul ignore if */\n if (\n perf &&\n perf.mark &&\n perf.measure &&\n perf.clearMarks &&\n perf.clearMeasures\n ) {\n mark = function (tag) { return perf.mark(tag); };\n measure = function (name, startTag, endTag) {\n perf.measure(name, startTag, endTag);\n perf.clearMarks(startTag);\n perf.clearMarks(endTag);\n perf.clearMeasures(name);\n };\n }\n}\n\n/* not type checking this file because flow doesn't play well with Proxy */\n\nvar initProxy;\n\nif (process.env.NODE_ENV !== 'production') {\n var allowedGlobals = makeMap(\n 'Infinity,undefined,NaN,isFinite,isNaN,' +\n 'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' +\n 'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,' +\n 'require' // for Webpack/Browserify\n );\n\n var warnNonPresent = function (target, key) {\n warn(\n \"Property or method \\\"\" + key + \"\\\" is not defined on the instance but \" +\n \"referenced during render. Make sure to declare reactive data \" +\n \"properties in the data option.\",\n target\n );\n };\n\n var hasProxy =\n typeof Proxy !== 'undefined' &&\n Proxy.toString().match(/native code/);\n\n if (hasProxy) {\n var isBuiltInModifier = makeMap('stop,prevent,self,ctrl,shift,alt,meta');\n config.keyCodes = new Proxy(config.keyCodes, {\n set: function set (target, key, value) {\n if (isBuiltInModifier(key)) {\n warn((\"Avoid overwriting built-in modifier in config.keyCodes: .\" + key));\n return false\n } else {\n target[key] = value;\n return true\n }\n }\n });\n }\n\n var hasHandler = {\n has: function has (target, key) {\n var has = key in target;\n var isAllowed = allowedGlobals(key) || key.charAt(0) === '_';\n if (!has && !isAllowed) {\n warnNonPresent(target, key);\n }\n return has || !isAllowed\n }\n };\n\n var getHandler = {\n get: function get (target, key) {\n if (typeof key === 'string' && !(key in target)) {\n warnNonPresent(target, key);\n }\n return target[key]\n }\n };\n\n initProxy = function initProxy (vm) {\n if (hasProxy) {\n // determine which proxy handler to use\n var options = vm.$options;\n var handlers = options.render && options.render._withStripped\n ? getHandler\n : hasHandler;\n vm._renderProxy = new Proxy(vm, handlers);\n } else {\n vm._renderProxy = vm;\n }\n };\n}\n\n/* */\n\nvar VNode = function VNode (\n tag,\n data,\n children,\n text,\n elm,\n context,\n componentOptions,\n asyncFactory\n) {\n this.tag = tag;\n this.data = data;\n this.children = children;\n this.text = text;\n this.elm = elm;\n this.ns = undefined;\n this.context = context;\n this.functionalContext = undefined;\n this.key = data && data.key;\n this.componentOptions = componentOptions;\n this.componentInstance = undefined;\n this.parent = undefined;\n this.raw = false;\n this.isStatic = false;\n this.isRootInsert = true;\n this.isComment = false;\n this.isCloned = false;\n this.isOnce = false;\n this.asyncFactory = asyncFactory;\n this.asyncMeta = undefined;\n this.isAsyncPlaceholder = false;\n};\n\nvar prototypeAccessors = { child: {} };\n\n// DEPRECATED: alias for componentInstance for backwards compat.\n/* istanbul ignore next */\nprototypeAccessors.child.get = function () {\n return this.componentInstance\n};\n\nObject.defineProperties( VNode.prototype, prototypeAccessors );\n\nvar createEmptyVNode = function (text) {\n if ( text === void 0 ) text = '';\n\n var node = new VNode();\n node.text = text;\n node.isComment = true;\n return node\n};\n\nfunction createTextVNode (val) {\n return new VNode(undefined, undefined, undefined, String(val))\n}\n\n// optimized shallow clone\n// used for static nodes and slot nodes because they may be reused across\n// multiple renders, cloning them avoids errors when DOM manipulations rely\n// on their elm reference.\nfunction cloneVNode (vnode) {\n var cloned = new VNode(\n vnode.tag,\n vnode.data,\n vnode.children,\n vnode.text,\n vnode.elm,\n vnode.context,\n vnode.componentOptions,\n vnode.asyncFactory\n );\n cloned.ns = vnode.ns;\n cloned.isStatic = vnode.isStatic;\n cloned.key = vnode.key;\n cloned.isComment = vnode.isComment;\n cloned.isCloned = true;\n return cloned\n}\n\nfunction cloneVNodes (vnodes) {\n var len = vnodes.length;\n var res = new Array(len);\n for (var i = 0; i < len; i++) {\n res[i] = cloneVNode(vnodes[i]);\n }\n return res\n}\n\n/* */\n\nvar normalizeEvent = cached(function (name) {\n var passive = name.charAt(0) === '&';\n name = passive ? name.slice(1) : name;\n var once$$1 = name.charAt(0) === '~'; // Prefixed last, checked first\n name = once$$1 ? name.slice(1) : name;\n var capture = name.charAt(0) === '!';\n name = capture ? name.slice(1) : name;\n return {\n name: name,\n once: once$$1,\n capture: capture,\n passive: passive\n }\n});\n\nfunction createFnInvoker (fns) {\n function invoker () {\n var arguments$1 = arguments;\n\n var fns = invoker.fns;\n if (Array.isArray(fns)) {\n var cloned = fns.slice();\n for (var i = 0; i < cloned.length; i++) {\n cloned[i].apply(null, arguments$1);\n }\n } else {\n // return handler return value for single handlers\n return fns.apply(null, arguments)\n }\n }\n invoker.fns = fns;\n return invoker\n}\n\nfunction updateListeners (\n on,\n oldOn,\n add,\n remove$$1,\n vm\n) {\n var name, cur, old, event;\n for (name in on) {\n cur = on[name];\n old = oldOn[name];\n event = normalizeEvent(name);\n if (isUndef(cur)) {\n process.env.NODE_ENV !== 'production' && warn(\n \"Invalid handler for event \\\"\" + (event.name) + \"\\\": got \" + String(cur),\n vm\n );\n } else if (isUndef(old)) {\n if (isUndef(cur.fns)) {\n cur = on[name] = createFnInvoker(cur);\n }\n add(event.name, cur, event.once, event.capture, event.passive);\n } else if (cur !== old) {\n old.fns = cur;\n on[name] = old;\n }\n }\n for (name in oldOn) {\n if (isUndef(on[name])) {\n event = normalizeEvent(name);\n remove$$1(event.name, oldOn[name], event.capture);\n }\n }\n}\n\n/* */\n\nfunction mergeVNodeHook (def, hookKey, hook) {\n var invoker;\n var oldHook = def[hookKey];\n\n function wrappedHook () {\n hook.apply(this, arguments);\n // important: remove merged hook to ensure it's called only once\n // and prevent memory leak\n remove(invoker.fns, wrappedHook);\n }\n\n if (isUndef(oldHook)) {\n // no existing hook\n invoker = createFnInvoker([wrappedHook]);\n } else {\n /* istanbul ignore if */\n if (isDef(oldHook.fns) && isTrue(oldHook.merged)) {\n // already a merged invoker\n invoker = oldHook;\n invoker.fns.push(wrappedHook);\n } else {\n // existing plain hook\n invoker = createFnInvoker([oldHook, wrappedHook]);\n }\n }\n\n invoker.merged = true;\n def[hookKey] = invoker;\n}\n\n/* */\n\nfunction extractPropsFromVNodeData (\n data,\n Ctor,\n tag\n) {\n // we are only extracting raw values here.\n // validation and default values are handled in the child\n // component itself.\n var propOptions = Ctor.options.props;\n if (isUndef(propOptions)) {\n return\n }\n var res = {};\n var attrs = data.attrs;\n var props = data.props;\n if (isDef(attrs) || isDef(props)) {\n for (var key in propOptions) {\n var altKey = hyphenate(key);\n if (process.env.NODE_ENV !== 'production') {\n var keyInLowerCase = key.toLowerCase();\n if (\n key !== keyInLowerCase &&\n attrs && hasOwn(attrs, keyInLowerCase)\n ) {\n tip(\n \"Prop \\\"\" + keyInLowerCase + \"\\\" is passed to component \" +\n (formatComponentName(tag || Ctor)) + \", but the declared prop name is\" +\n \" \\\"\" + key + \"\\\". \" +\n \"Note that HTML attributes are case-insensitive and camelCased \" +\n \"props need to use their kebab-case equivalents when using in-DOM \" +\n \"templates. You should probably use \\\"\" + altKey + \"\\\" instead of \\\"\" + key + \"\\\".\"\n );\n }\n }\n checkProp(res, props, key, altKey, true) ||\n checkProp(res, attrs, key, altKey, false);\n }\n }\n return res\n}\n\nfunction checkProp (\n res,\n hash,\n key,\n altKey,\n preserve\n) {\n if (isDef(hash)) {\n if (hasOwn(hash, key)) {\n res[key] = hash[key];\n if (!preserve) {\n delete hash[key];\n }\n return true\n } else if (hasOwn(hash, altKey)) {\n res[key] = hash[altKey];\n if (!preserve) {\n delete hash[altKey];\n }\n return true\n }\n }\n return false\n}\n\n/* */\n\n// The template compiler attempts to minimize the need for normalization by\n// statically analyzing the template at compile time.\n//\n// For plain HTML markup, normalization can be completely skipped because the\n// generated render function is guaranteed to return Array. There are\n// two cases where extra normalization is needed:\n\n// 1. When the children contains components - because a functional component\n// may return an Array instead of a single root. In this case, just a simple\n// normalization is needed - if any child is an Array, we flatten the whole\n// thing with Array.prototype.concat. It is guaranteed to be only 1-level deep\n// because functional components already normalize their own children.\nfunction simpleNormalizeChildren (children) {\n for (var i = 0; i < children.length; i++) {\n if (Array.isArray(children[i])) {\n return Array.prototype.concat.apply([], children)\n }\n }\n return children\n}\n\n// 2. When the children contains constructs that always generated nested Arrays,\n// e.g.