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 31cf303c..00000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,19 +0,0 @@ -# Changelog - -## 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 9739c469..540b2231 100644 --- a/README.md +++ b/README.md @@ -1,209 +1,65 @@ -# vue-grid-layout +

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)** -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.2 (Supports Vue 2.0+) - -### **For Vue 1 use version [1.0.0](https://github.com/jbaysolutions/vue-grid-layout/tree/1.0.0)** - -
- -[**[Demo](https://jbaysolutions.github.io/vue-grid-layout/examples/01-basic.html) | [Changelog](/CHANGELOG.md)**] +## Features - #### Projects using vue-grid-layout +- [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/) *Know of others? Create a PR to let me know!* -## Features - -* Draggable widgets -* Resizable 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 - - -## 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}} - - -```` - -### 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}} - - -```` - -* 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); - }, -``` - -* 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); - }, -``` - -* 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); - }, -``` - -* Resized event: every time an item is finished being resized and changes size - -```javascript - resizedEvent: function(i, newH, newW){ - console.log("RESIZED i=" + i + ", H=" + newH + ", W=" + newW); - }, -``` - ## Contribute 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 d5472e57..00000000 --- a/dist/vue-grid-layout.js +++ /dev/null @@ -1,337 +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; - -/******/ // identity function for calling harmony imports with the correct context -/******/ __webpack_require__.i = function(value) { return value; }; - -/******/ // 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 = 38); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ function(module, exports, __webpack_require__) { - -"use strict"; -eval("/* WEBPACK VAR INJECTION */(function(process) {'use strict';\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 = \"translate(\" + left + \"px,\" + top + \"px)\";\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 = \"translate(\" + right * -1 + \"px,\" + top + \"px)\";\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__(8)))\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvdXRpbHMuanM/MmZmOCJdLCJuYW1lcyI6WyJib3R0b20iLCJjbG9uZUxheW91dCIsImNsb25lTGF5b3V0SXRlbSIsImNvbGxpZGVzIiwiY29tcGFjdCIsImNvbXBhY3RJdGVtIiwiY29ycmVjdEJvdW5kcyIsImdldExheW91dEl0ZW0iLCJnZXRGaXJzdENvbGxpc2lvbiIsImdldEFsbENvbGxpc2lvbnMiLCJnZXRTdGF0aWNzIiwibW92ZUVsZW1lbnQiLCJtb3ZlRWxlbWVudEF3YXlGcm9tQ29sbGlzaW9uIiwicGVyYyIsInNldFRyYW5zZm9ybSIsInNldFRyYW5zZm9ybVJ0bCIsInNldFRvcExlZnQiLCJzZXRUb3BSaWdodCIsInNvcnRMYXlvdXRJdGVtc0J5Um93Q29sIiwidmFsaWRhdGVMYXlvdXQiLCJhdXRvQmluZEhhbmRsZXJzIiwiY3JlYXRlTWFya3VwIiwiYWRkUHgiLCJoeXBoZW5hdGUiLCJmaW5kSXRlbUluQXJyYXkiLCJmaW5kQW5kUmVtb3ZlIiwiaXNQcm9kdWN0aW9uIiwicHJvY2VzcyIsImVudiIsIk5PREVfRU5WIiwibGF5b3V0IiwibWF4IiwiYm90dG9tWSIsImkiLCJsZW4iLCJsZW5ndGgiLCJ5IiwiaCIsIm5ld0xheW91dCIsIkFycmF5IiwibGF5b3V0SXRlbSIsIkpTT04iLCJwYXJzZSIsInN0cmluZ2lmeSIsImwxIiwibDIiLCJ4IiwidyIsInZlcnRpY2FsQ29tcGFjdCIsImNvbXBhcmVXaXRoIiwic29ydGVkIiwib3V0IiwibCIsInN0YXRpYyIsInB1c2giLCJpbmRleE9mIiwibW92ZWQiLCJib3VuZHMiLCJjb2xsaWRlc1dpdGgiLCJjb2xzIiwiaWQiLCJmaWx0ZXIiLCJpc1VzZXJBY3Rpb24iLCJtb3ZpbmdVcCIsInJldmVyc2UiLCJjb2xsaXNpb25zIiwiY29sbGlzaW9uIiwiaXRlbVRvTW92ZSIsImZha2VJdGVtIiwiTWF0aCIsInVuZGVmaW5lZCIsIm51bSIsInRvcCIsImxlZnQiLCJ3aWR0aCIsImhlaWdodCIsInRyYW5zbGF0ZSIsInRyYW5zZm9ybSIsIldlYmtpdFRyYW5zZm9ybSIsIk1velRyYW5zZm9ybSIsIm1zVHJhbnNmb3JtIiwiT1RyYW5zZm9ybSIsInBvc2l0aW9uIiwicmlnaHQiLCJjb25jYXQiLCJzb3J0IiwiYSIsImIiLCJjb250ZXh0TmFtZSIsInN1YlByb3BzIiwiaXNBcnJheSIsIkVycm9yIiwiaXRlbSIsImoiLCJlbCIsImZucyIsImZvckVhY2giLCJrZXkiLCJiaW5kIiwib2JqIiwia2V5cyIsIk9iamVjdCIsInJlc3VsdCIsInZhbCIsIklTX1VOSVRMRVNTIiwiYW5pbWF0aW9uSXRlcmF0aW9uQ291bnQiLCJib3hGbGV4IiwiYm94RmxleEdyb3VwIiwiYm94T3JkaW5hbEdyb3VwIiwiY29sdW1uQ291bnQiLCJmbGV4IiwiZmxleEdyb3ciLCJmbGV4UG9zaXRpdmUiLCJmbGV4U2hyaW5rIiwiZmxleE5lZ2F0aXZlIiwiZmxleE9yZGVyIiwiZ3JpZFJvdyIsImdyaWRDb2x1bW4iLCJmb250V2VpZ2h0IiwibGluZUNsYW1wIiwibGluZUhlaWdodCIsIm9wYWNpdHkiLCJvcmRlciIsIm9ycGhhbnMiLCJ0YWJTaXplIiwid2lkb3dzIiwiekluZGV4Iiwiem9vbSIsImZpbGxPcGFjaXR5Iiwic3RvcE9wYWNpdHkiLCJzdHJva2VEYXNob2Zmc2V0Iiwic3Ryb2tlT3BhY2l0eSIsInN0cm9rZVdpZHRoIiwibmFtZSIsInZhbHVlIiwiaHlwaGVuYXRlUkUiLCJzdHIiLCJyZXBsYWNlIiwidG9Mb3dlckNhc2UiLCJhcnJheSIsInByb3BlcnR5IiwiaW5kZXgiLCJzcGxpY2UiXSwibWFwcGluZ3MiOiI7Ozs7O1FBeUJnQkEsTSxHQUFBQSxNO1FBU0FDLFcsR0FBQUEsVztRQVNBQyxlLEdBQUFBLGU7UUFnQkFDLFEsR0FBQUEsUTtRQWtCQUMsTyxHQUFBQSxPO1FBaUNBQyxXLEdBQUFBLFc7UUFzQkFDLGEsR0FBQUEsYTtRQThCQUMsYSxHQUFBQSxhO1FBY0FDLGlCLEdBQUFBLGlC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QUErQztBQUNsREssUUFBTTNDLE9BQU4sQ0FBYyxVQUFVTSxNQUFWLEVBQWtCdUMsS0FBbEIsRUFBeUI7QUFDbkMsUUFBSXZDLE9BQU9zQyxRQUFQLE1BQXFCTixLQUF6QixFQUFnQztBQUM1QjtBQUNBSyxZQUFNRyxNQUFOLENBQWFELEtBQWIsRUFBb0IsQ0FBcEI7QUFDSDtBQUNKLEdBTEQ7QUFNSCxDIiwiZmlsZSI6IjAuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAZmxvd1xyXG5leHBvcnQgdHlwZSBMYXlvdXRJdGVtUmVxdWlyZWQgPSB7dzogbnVtYmVyLCBoOiBudW1iZXIsIHg6IG51bWJlciwgeTogbnVtYmVyLCBpOiBzdHJpbmd9O1xyXG5leHBvcnQgdHlwZSBMYXlvdXRJdGVtID0gTGF5b3V0SXRlbVJlcXVpcmVkICZcclxuICAgICAgICAgICAgICAgICAgICAgICAgIHttaW5XPzogbnVtYmVyLCBtaW5IPzogbnVtYmVyLCBtYXhXPzogbnVtYmVyLCBtYXhIPzogbnVtYmVyLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIG1vdmVkPzogYm9vbGVhbiwgc3RhdGljPzogYm9vbGVhbixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICBpc0RyYWdnYWJsZT86ID9ib29sZWFuLCBpc1Jlc2l6YWJsZT86ID9ib29sZWFufTtcclxuZXhwb3J0IHR5cGUgTGF5b3V0ID0gQXJyYXk8TGF5b3V0SXRlbT47XHJcbmV4cG9ydCB0eXBlIFBvc2l0aW9uID0ge2xlZnQ6IG51bWJlciwgdG9wOiBudW1iZXIsIHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyfTtcclxuZXhwb3J0IHR5cGUgRHJhZ0NhbGxiYWNrRGF0YSA9IHtcclxuICBub2RlOiBIVE1MRWxlbWVudCxcclxuICB4OiBudW1iZXIsIHk6IG51bWJlcixcclxuICBkZWx0YVg6IG51bWJlciwgZGVsdGFZOiBudW1iZXIsXHJcbiAgbGFzdFg6IG51bWJlciwgbGFzdFk6IG51bWJlclxyXG59O1xyXG5leHBvcnQgdHlwZSBEcmFnRXZlbnQgPSB7ZTogRXZlbnR9ICYgRHJhZ0NhbGxiYWNrRGF0YTtcclxuZXhwb3J0IHR5cGUgU2l6ZSA9IHt3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcn07XHJcbmV4cG9ydCB0eXBlIFJlc2l6ZUV2ZW50ID0ge2U6IEV2ZW50LCBub2RlOiBIVE1MRWxlbWVudCwgc2l6ZTogU2l6ZX07XHJcblxyXG5jb25zdCBpc1Byb2R1Y3Rpb24gPSBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gJ3Byb2R1Y3Rpb24nO1xyXG4vKipcclxuICogUmV0dXJuIHRoZSBib3R0b20gY29vcmRpbmF0ZSBvZiB0aGUgbGF5b3V0LlxyXG4gKlxyXG4gKiBAcGFyYW0gIHtBcnJheX0gbGF5b3V0IExheW91dCBhcnJheS5cclxuICogQHJldHVybiB7TnVtYmVyfSAgICAgICBCb3R0b20gY29vcmRpbmF0ZS5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBib3R0b20obGF5b3V0OiBMYXlvdXQpOiBudW1iZXIge1xyXG4gIGxldCBtYXggPSAwLCBib3R0b21ZO1xyXG4gIGZvciAobGV0IGkgPSAwLCBsZW4gPSBsYXlvdXQubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgIGJvdHRvbVkgPSBsYXlvdXRbaV0uIHkgKyBsYXlvdXRbaV0uaDtcclxuICAgIGlmIChib3R0b21ZID4gbWF4KSBtYXggPSBib3R0b21ZO1xyXG4gIH1cclxuICByZXR1cm4gbWF4O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gY2xvbmVMYXlvdXQobGF5b3V0OiBMYXlvdXQpOiBMYXlvdXQge1xyXG4gIGNvbnN0IG5ld0xheW91dCA9IEFycmF5KGxheW91dC5sZW5ndGgpO1xyXG4gIGZvciAobGV0IGkgPSAwLCBsZW4gPSBsYXlvdXQubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgIG5ld0xheW91dFtpXSA9IGNsb25lTGF5b3V0SXRlbShsYXlvdXRbaV0pO1xyXG4gIH1cclxuICByZXR1cm4gbmV3TGF5b3V0O1xyXG59XHJcblxyXG4vLyBGYXN0IHBhdGggdG8gY2xvbmluZywgc2luY2UgdGhpcyBpcyBtb25vbW9ycGhpY1xyXG5leHBvcnQgZnVuY3Rpb24gY2xvbmVMYXlvdXRJdGVtKGxheW91dEl0ZW06IExheW91dEl0ZW0pOiBMYXlvdXRJdGVtIHtcclxuICAvKnJldHVybiB7XHJcbiAgICB3OiBsYXlvdXRJdGVtLncsIGg6IGxheW91dEl0ZW0uaCwgeDogbGF5b3V0SXRlbS54LCB5OiBsYXlvdXRJdGVtLnksIGk6IGxheW91dEl0ZW0uaSxcclxuICAgIG1pblc6IGxheW91dEl0ZW0ubWluVywgbWF4VzogbGF5b3V0SXRlbS5tYXhXLCBtaW5IOiBsYXlvdXRJdGVtLm1pbkgsIG1heEg6IGxheW91dEl0ZW0ubWF4SCxcclxuICAgIG1vdmVkOiBCb29sZWFuKGxheW91dEl0ZW0ubW92ZWQpLCBzdGF0aWM6IEJvb2xlYW4obGF5b3V0SXRlbS5zdGF0aWMpLFxyXG4gICAgLy8gVGhlc2UgY2FuIGJlIG51bGxcclxuICAgIGlzRHJhZ2dhYmxlOiBsYXlvdXRJdGVtLmlzRHJhZ2dhYmxlLCBpc1Jlc2l6YWJsZTogbGF5b3V0SXRlbS5pc1Jlc2l6YWJsZVxyXG4gIH07Ki9cclxuICAgIHJldHVybiBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGxheW91dEl0ZW0pKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEdpdmVuIHR3byBsYXlvdXRpdGVtcywgY2hlY2sgaWYgdGhleSBjb2xsaWRlLlxyXG4gKlxyXG4gKiBAcmV0dXJuIHtCb29sZWFufSAgIFRydWUgaWYgY29sbGlkaW5nLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGNvbGxpZGVzKGwxOiBMYXlvdXRJdGVtLCBsMjogTGF5b3V0SXRlbSk6IGJvb2xlYW4ge1xyXG4gIGlmIChsMSA9PT0gbDIpIHJldHVybiBmYWxzZTsgLy8gc2FtZSBlbGVtZW50XHJcbiAgaWYgKGwxLnggKyBsMS53IDw9IGwyLngpIHJldHVybiBmYWxzZTsgLy8gbDEgaXMgbGVmdCBvZiBsMlxyXG4gIGlmIChsMS54ID49IGwyLnggKyBsMi53KSByZXR1cm4gZmFsc2U7IC8vIGwxIGlzIHJpZ2h0IG9mIGwyXHJcbiAgaWYgKGwxLnkgKyBsMS5oIDw9IGwyLnkpIHJldHVybiBmYWxzZTsgLy8gbDEgaXMgYWJvdmUgbDJcclxuICBpZiAobDEueSA+PSBsMi55ICsgbDIuaCkgcmV0dXJuIGZhbHNlOyAvLyBsMSBpcyBiZWxvdyBsMlxyXG4gIHJldHVybiB0cnVlOyAvLyBib3hlcyBvdmVybGFwXHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHaXZlbiBhIGxheW91dCwgY29tcGFjdCBpdC4gVGhpcyBpbnZvbHZlcyBnb2luZyBkb3duIGVhY2ggeSBjb29yZGluYXRlIGFuZCByZW1vdmluZyBnYXBzXHJcbiAqIGJldHdlZW4gaXRlbXMuXHJcbiAqXHJcbiAqIEBwYXJhbSAge0FycmF5fSBsYXlvdXQgTGF5b3V0LlxyXG4gKiBAcGFyYW0gIHtCb29sZWFufSB2ZXJ0aWNhbENvbXBhY3QgV2hldGhlciBvciBub3QgdG8gY29tcGFjdCB0aGUgbGF5b3V0XHJcbiAqICAgdmVydGljYWxseS5cclxuICogQHJldHVybiB7QXJyYXl9ICAgICAgIENvbXBhY3RlZCBMYXlvdXQuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gY29tcGFjdChsYXlvdXQ6IExheW91dCwgdmVydGljYWxDb21wYWN0OiBCb29sZWFuKTogTGF5b3V0IHtcclxuICAgIC8vIFN0YXRpY3MgZ28gaW4gdGhlIGNvbXBhcmVXaXRoIGFycmF5IHJpZ2h0IGF3YXkgc28gaXRlbXMgZmxvdyBhcm91bmQgdGhlbS5cclxuICBjb25zdCBjb21wYXJlV2l0aCA9IGdldFN0YXRpY3MobGF5b3V0KTtcclxuICAvLyBXZSBnbyB0aHJvdWdoIHRoZSBpdGVtcyBieSByb3cgYW5kIGNvbHVtbi5cclxuICBjb25zdCBzb3J0ZWQgPSBzb3J0TGF5b3V0SXRlbXNCeVJvd0NvbChsYXlvdXQpO1xyXG4gIC8vIEhvbGRpbmcgZm9yIG5ldyBpdGVtcy5cclxuICBjb25zdCBvdXQgPSBBcnJheShsYXlvdXQubGVuZ3RoKTtcclxuXHJcbiAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IHNvcnRlZC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgbGV0IGwgPSBzb3J0ZWRbaV07XHJcblxyXG4gICAgLy8gRG9uJ3QgbW92ZSBzdGF0aWMgZWxlbWVudHNcclxuICAgIGlmICghbC5zdGF0aWMpIHtcclxuICAgICAgbCA9IGNvbXBhY3RJdGVtKGNvbXBhcmVXaXRoLCBsLCB2ZXJ0aWNhbENvbXBhY3QpO1xyXG5cclxuICAgICAgLy8gQWRkIHRvIGNvbXBhcmlzb24gYXJyYXkuIFdlIG9ubHkgY29sbGlkZSB3aXRoIGl0ZW1zIGJlZm9yZSB0aGlzIG9uZS5cclxuICAgICAgLy8gU3RhdGljcyBhcmUgYWxyZWFkeSBpbiB0aGlzIGFycmF5LlxyXG4gICAgICBjb21wYXJlV2l0aC5wdXNoKGwpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIEFkZCB0byBvdXRwdXQgYXJyYXkgdG8gbWFrZSBzdXJlIHRoZXkgc3RpbGwgY29tZSBvdXQgaW4gdGhlIHJpZ2h0IG9yZGVyLlxyXG4gICAgb3V0W2xheW91dC5pbmRleE9mKGwpXSA9IGw7XHJcblxyXG4gICAgLy8gQ2xlYXIgbW92ZWQgZmxhZywgaWYgaXQgZXhpc3RzLlxyXG4gICAgbC5tb3ZlZCA9IGZhbHNlO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIG91dDtcclxufVxyXG5cclxuLyoqXHJcbiAqIENvbXBhY3QgYW4gaXRlbSBpbiB0aGUgbGF5b3V0LlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGNvbXBhY3RJdGVtKGNvbXBhcmVXaXRoOiBMYXlvdXQsIGw6IExheW91dEl0ZW0sIHZlcnRpY2FsQ29tcGFjdDogYm9vbGVhbik6IExheW91dEl0ZW0ge1xyXG4gIGlmICh2ZXJ0aWNhbENvbXBhY3QpIHtcclxuICAgIC8vIE1vdmUgdGhlIGVsZW1lbnQgdXAgYXMgZmFyIGFzIGl0IGNhbiBnbyB3aXRob3V0IGNvbGxpZGluZy5cclxuICAgIHdoaWxlIChsLnkgPiAwICYmICFnZXRGaXJzdENvbGxpc2lvbihjb21wYXJlV2l0aCwgbCkpIHtcclxuICAgICAgbC55LS07XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLyBNb3ZlIGl0IGRvd24sIGFuZCBrZWVwIG1vdmluZyBpdCBkb3duIGlmIGl0J3MgY29sbGlkaW5nLlxyXG4gIGxldCBjb2xsaWRlcztcclxuICB3aGlsZSgoY29sbGlkZXMgPSBnZXRGaXJzdENvbGxpc2lvbihjb21wYXJlV2l0aCwgbCkpKSB7XHJcbiAgICBsLnkgPSBjb2xsaWRlcy55ICsgY29sbGlkZXMuaDtcclxuICB9XHJcbiAgcmV0dXJuIGw7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHaXZlbiBhIGxheW91dCwgbWFrZSBzdXJlIGFsbCBlbGVtZW50cyBmaXQgd2l0aGluIGl0cyBib3VuZHMuXHJcbiAqXHJcbiAqIEBwYXJhbSAge0FycmF5fSBsYXlvdXQgTGF5b3V0IGFycmF5LlxyXG4gKiBAcGFyYW0gIHtOdW1iZXJ9IGJvdW5kcyBOdW1iZXIgb2YgY29sdW1ucy5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBjb3JyZWN0Qm91bmRzKGxheW91dDogTGF5b3V0LCBib3VuZHM6IHtjb2xzOiBudW1iZXJ9KTogTGF5b3V0IHtcclxuICBjb25zdCBjb2xsaWRlc1dpdGggPSBnZXRTdGF0aWNzKGxheW91dCk7XHJcbiAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGxheW91dC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgY29uc3QgbCA9IGxheW91dFtpXTtcclxuICAgIC8vIE92ZXJmbG93cyByaWdodFxyXG4gICAgaWYgKGwueCArIGwudyA+IGJvdW5kcy5jb2xzKSBsLnggPSBib3VuZHMuY29scyAtIGwudztcclxuICAgIC8vIE92ZXJmbG93cyBsZWZ0XHJcbiAgICBpZiAobC54IDwgMCkge1xyXG4gICAgICBsLnggPSAwO1xyXG4gICAgICBsLncgPSBib3VuZHMuY29scztcclxuICAgIH1cclxuICAgIGlmICghbC5zdGF0aWMpIGNvbGxpZGVzV2l0aC5wdXNoKGwpO1xyXG4gICAgZWxzZSB7XHJcbiAgICAgIC8vIElmIHRoaXMgaXMgc3RhdGljIGFuZCBjb2xsaWRlcyB3aXRoIG90aGVyIHN0YXRpY3MsIHdlIG11c3QgbW92ZSBpdCBkb3duLlxyXG4gICAgICAvLyBXZSBoYXZlIHRvIGRvIHNvbWV0aGluZyBuaWNlciB0aGFuIGp1c3QgbGV0dGluZyB0aGVtIG92ZXJsYXAuXHJcbiAgICAgIHdoaWxlKGdldEZpcnN0Q29sbGlzaW9uKGNvbGxpZGVzV2l0aCwgbCkpIHtcclxuICAgICAgICBsLnkrKztcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuICByZXR1cm4gbGF5b3V0O1xyXG59XHJcblxyXG4vKipcclxuICogR2V0IGEgbGF5b3V0IGl0ZW0gYnkgSUQuIFVzZWQgc28gd2UgY2FuIG92ZXJyaWRlIGxhdGVyIG9uIGlmIG5lY2Vzc2FyeS5cclxuICpcclxuICogQHBhcmFtICB7QXJyYXl9ICBsYXlvdXQgTGF5b3V0IGFycmF5LlxyXG4gKiBAcGFyYW0gIHtTdHJpbmd9IGlkICAgICBJRFxyXG4gKiBAcmV0dXJuIHtMYXlvdXRJdGVtfSAgICBJdGVtIGF0IElELlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGdldExheW91dEl0ZW0obGF5b3V0OiBMYXlvdXQsIGlkOiBzdHJpbmcpOiA/TGF5b3V0SXRlbSB7XHJcbiAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGxheW91dC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgaWYgKGxheW91dFtpXS5pID09PSBpZCkgcmV0dXJuIGxheW91dFtpXTtcclxuICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRoZSBmaXJzdCBpdGVtIHRoaXMgbGF5b3V0IGNvbGxpZGVzIHdpdGguXHJcbiAqIEl0IGRvZXNuJ3QgYXBwZWFyIHRvIG1hdHRlciB3aGljaCBvcmRlciB3ZSBhcHByb2FjaCB0aGlzIGZyb20sIGFsdGhvdWdoXHJcbiAqIHBlcmhhcHMgdGhhdCBpcyB0aGUgd3JvbmcgdGhpbmcgdG8gZG8uXHJcbiAqXHJcbiAqIEBwYXJhbSAge09iamVjdH0gbGF5b3V0SXRlbSBMYXlvdXQgaXRlbS5cclxuICogQHJldHVybiB7T2JqZWN0fHVuZGVmaW5lZH0gIEEgY29sbGlkaW5nIGxheW91dCBpdGVtLCBvciB1bmRlZmluZWQuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rmlyc3RDb2xsaXNpb24obGF5b3V0OiBMYXlvdXQsIGxheW91dEl0ZW06IExheW91dEl0ZW0pOiA/TGF5b3V0SXRlbSB7XHJcbiAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGxheW91dC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgaWYgKGNvbGxpZGVzKGxheW91dFtpXSwgbGF5b3V0SXRlbSkpIHJldHVybiBsYXlvdXRbaV07XHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZ2V0QWxsQ29sbGlzaW9ucyhsYXlvdXQ6IExheW91dCwgbGF5b3V0SXRlbTogTGF5b3V0SXRlbSk6IEFycmF5PExheW91dEl0ZW0+IHtcclxuICByZXR1cm4gbGF5b3V0LmZpbHRlcigobCkgPT4gY29sbGlkZXMobCwgbGF5b3V0SXRlbSkpO1xyXG59XHJcblxyXG4vKipcclxuICogR2V0IGFsbCBzdGF0aWMgZWxlbWVudHMuXHJcbiAqIEBwYXJhbSAge0FycmF5fSBsYXlvdXQgQXJyYXkgb2YgbGF5b3V0IG9iamVjdHMuXHJcbiAqIEByZXR1cm4ge0FycmF5fSAgICAgICAgQXJyYXkgb2Ygc3RhdGljIGxheW91dCBpdGVtcy4uXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZ2V0U3RhdGljcyhsYXlvdXQ6IExheW91dCk6IEFycmF5PExheW91dEl0ZW0+IHtcclxuICAgIC8vcmV0dXJuIFtdO1xyXG4gICAgcmV0dXJuIGxheW91dC5maWx0ZXIoKGwpID0+IGwuc3RhdGljKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIE1vdmUgYW4gZWxlbWVudC4gUmVzcG9uc2libGUgZm9yIGRvaW5nIGNhc2NhZGluZyBtb3ZlbWVudHMgb2Ygb3RoZXIgZWxlbWVudHMuXHJcbiAqXHJcbiAqIEBwYXJhbSAge0FycmF5fSAgICAgIGxheW91dCBGdWxsIGxheW91dCB0byBtb2RpZnkuXHJcbiAqIEBwYXJhbSAge0xheW91dEl0ZW19IGwgICAgICBlbGVtZW50IHRvIG1vdmUuXHJcbiAqIEBwYXJhbSAge051bWJlcn0gICAgIFt4XSAgICBYIHBvc2l0aW9uIGluIGdyaWQgdW5pdHMuXHJcbiAqIEBwYXJhbSAge051bWJlcn0gICAgIFt5XSAgICBZIHBvc2l0aW9uIGluIGdyaWQgdW5pdHMuXHJcbiAqIEBwYXJhbSAge0Jvb2xlYW59ICAgIFtpc1VzZXJBY3Rpb25dIElmIHRydWUsIGRlc2lnbmF0ZXMgdGhhdCB0aGUgaXRlbSB3ZSdyZSBtb3ZpbmcgaXNcclxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVpbmcgZHJhZ2dlZC9yZXNpemVkIGJ5IHRoIGV1c2VyLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIG1vdmVFbGVtZW50KGxheW91dDogTGF5b3V0LCBsOiBMYXlvdXRJdGVtLCB4OiBOdW1iZXIsIHk6IE51bWJlciwgaXNVc2VyQWN0aW9uOiBCb29sZWFuKTogTGF5b3V0IHtcclxuICBpZiAobC5zdGF0aWMpIHJldHVybiBsYXlvdXQ7XHJcblxyXG4gIC8vIFNob3J0LWNpcmN1aXQgaWYgbm90aGluZyB0byBkby5cclxuICAvL2lmIChsLnkgPT09IHkgJiYgbC54ID09PSB4KSByZXR1cm4gbGF5b3V0O1xyXG5cclxuICBjb25zdCBtb3ZpbmdVcCA9IHkgJiYgbC55ID4geTtcclxuICAvLyBUaGlzIGlzIHF1aXRlIGEgYml0IGZhc3RlciB0aGFuIGV4dGVuZGluZyB0aGUgb2JqZWN0XHJcbiAgaWYgKHR5cGVvZiB4ID09PSAnbnVtYmVyJykgbC54ID0geDtcclxuICBpZiAodHlwZW9mIHkgPT09ICdudW1iZXInKSBsLnkgPSB5O1xyXG4gIGwubW92ZWQgPSB0cnVlO1xyXG5cclxuICAvLyBJZiB0aGlzIGNvbGxpZGVzIHdpdGggYW55dGhpbmcsIG1vdmUgaXQuXHJcbiAgLy8gV2hlbiBkb2luZyB0aGlzIGNvbXBhcmlzb24sIHdlIGhhdmUgdG8gc29ydCB0aGUgaXRlbXMgd2UgY29tcGFyZSB3aXRoXHJcbiAgLy8gdG8gZW5zdXJlLCBpbiB0aGUgY2FzZSBvZiBtdWx0aXBsZSBjb2xsaXNpb25zLCB0aGF0IHdlJ3JlIGdldHRpbmcgdGhlXHJcbiAgLy8gbmVhcmVzdCBjb2xsaXNpb24uXHJcbiAgbGV0IHNvcnRlZCA9IHNvcnRMYXlvdXRJdGVtc0J5Um93Q29sKGxheW91dCk7XHJcbiAgaWYgKG1vdmluZ1VwKSBzb3J0ZWQgPSBzb3J0ZWQucmV2ZXJzZSgpO1xyXG4gIGNvbnN0IGNvbGxpc2lvbnMgPSBnZXRBbGxDb2xsaXNpb25zKHNvcnRlZCwgbCk7XHJcblxyXG4gIC8vIE1vdmUgZWFjaCBpdGVtIHRoYXQgY29sbGlkZXMgYXdheSBmcm9tIHRoaXMgZWxlbWVudC5cclxuICBmb3IgKGxldCBpID0gMCwgbGVuID0gY29sbGlzaW9ucy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgY29uc3QgY29sbGlzaW9uID0gY29sbGlzaW9uc1tpXTtcclxuICAgIC8vIGNvbnNvbGUubG9nKCdyZXNvbHZpbmcgY29sbGlzaW9uIGJldHdlZW4nLCBsLmksICdhdCcsIGwueSwgJ2FuZCcsIGNvbGxpc2lvbi5pLCAnYXQnLCBjb2xsaXNpb24ueSk7XHJcblxyXG4gICAgLy8gU2hvcnQgY2lyY3VpdCBzbyB3ZSBjYW4ndCBpbmZpbml0ZSBsb29wXHJcbiAgICBpZiAoY29sbGlzaW9uLm1vdmVkKSBjb250aW51ZTtcclxuXHJcbiAgICAvLyBUaGlzIG1ha2VzIGl0IGZlZWwgYSBiaXQgbW9yZSBwcmVjaXNlIGJ5IHdhaXRpbmcgdG8gc3dhcCBmb3IganVzdCBhIGJpdCB3aGVuIG1vdmluZyB1cC5cclxuICAgIGlmIChsLnkgPiBjb2xsaXNpb24ueSAmJiBsLnkgLSBjb2xsaXNpb24ueSA+IGNvbGxpc2lvbi5oIC8gNCkgY29udGludWU7XHJcblxyXG4gICAgLy8gRG9uJ3QgbW92ZSBzdGF0aWMgaXRlbXMgLSB3ZSBoYXZlIHRvIG1vdmUgKnRoaXMqIGVsZW1lbnQgYXdheVxyXG4gICAgaWYgKGNvbGxpc2lvbi5zdGF0aWMpIHtcclxuICAgICAgbGF5b3V0ID0gbW92ZUVsZW1lbnRBd2F5RnJvbUNvbGxpc2lvbihsYXlvdXQsIGNvbGxpc2lvbiwgbCwgaXNVc2VyQWN0aW9uKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGxheW91dCA9IG1vdmVFbGVtZW50QXdheUZyb21Db2xsaXNpb24obGF5b3V0LCBsLCBjb2xsaXNpb24sIGlzVXNlckFjdGlvbik7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZXR1cm4gbGF5b3V0O1xyXG59XHJcblxyXG4vKipcclxuICogVGhpcyBpcyB3aGVyZSB0aGUgbWFnaWMgbmVlZHMgdG8gaGFwcGVuIC0gZ2l2ZW4gYSBjb2xsaXNpb24sIG1vdmUgYW4gZWxlbWVudCBhd2F5IGZyb20gdGhlIGNvbGxpc2lvbi5cclxuICogV2UgYXR0ZW1wdCB0byBtb3ZlIGl0IHVwIGlmIHRoZXJlJ3Mgcm9vbSwgb3RoZXJ3aXNlIGl0IGdvZXMgYmVsb3cuXHJcbiAqXHJcbiAqIEBwYXJhbSAge0FycmF5fSBsYXlvdXQgICAgICAgICAgICBGdWxsIGxheW91dCB0byBtb2RpZnkuXHJcbiAqIEBwYXJhbSAge0xheW91dEl0ZW19IGNvbGxpZGVzV2l0aCBMYXlvdXQgaXRlbSB3ZSdyZSBjb2xsaWRpbmcgd2l0aC5cclxuICogQHBhcmFtICB7TGF5b3V0SXRlbX0gaXRlbVRvTW92ZSAgIExheW91dCBpdGVtIHdlJ3JlIG1vdmluZy5cclxuICogQHBhcmFtICB7Qm9vbGVhbn0gW2lzVXNlckFjdGlvbl0gIElmIHRydWUsIGRlc2lnbmF0ZXMgdGhhdCB0aGUgaXRlbSB3ZSdyZSBtb3ZpbmcgaXMgYmVpbmcgZHJhZ2dlZC9yZXNpemVkXHJcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieSB0aGUgdXNlci5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBtb3ZlRWxlbWVudEF3YXlGcm9tQ29sbGlzaW9uKGxheW91dDogTGF5b3V0LCBjb2xsaWRlc1dpdGg6IExheW91dEl0ZW0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW1Ub01vdmU6IExheW91dEl0ZW0sIGlzVXNlckFjdGlvbjogP2Jvb2xlYW4pOiBMYXlvdXQge1xyXG5cclxuICAvLyBJZiB0aGVyZSBpcyBlbm91Z2ggc3BhY2UgYWJvdmUgdGhlIGNvbGxpc2lvbiB0byBwdXQgdGhpcyBlbGVtZW50LCBtb3ZlIGl0IHRoZXJlLlxyXG4gIC8vIFdlIG9ubHkgZG8gdGhpcyBvbiB0aGUgbWFpbiBjb2xsaXNpb24gYXMgdGhpcyBjYW4gZ2V0IGZ1bmt5IGluIGNhc2NhZGVzIGFuZCBjYXVzZVxyXG4gIC8vIHVud2FudGVkIHN3YXBwaW5nIGJlaGF2aW9yLlxyXG4gIGlmIChpc1VzZXJBY3Rpb24pIHtcclxuICAgIC8vIE1ha2UgYSBtb2NrIGl0ZW0gc28gd2UgZG9uJ3QgbW9kaWZ5IHRoZSBpdGVtIGhlcmUsIG9ubHkgbW9kaWZ5IGluIG1vdmVFbGVtZW50LlxyXG4gICAgY29uc3QgZmFrZUl0ZW06IExheW91dEl0ZW0gPSB7XHJcbiAgICAgIHg6IGl0ZW1Ub01vdmUueCxcclxuICAgICAgeTogaXRlbVRvTW92ZS55LFxyXG4gICAgICB3OiBpdGVtVG9Nb3ZlLncsXHJcbiAgICAgIGg6IGl0ZW1Ub01vdmUuaCxcclxuICAgICAgaTogJy0xJ1xyXG4gICAgfTtcclxuICAgIGZha2VJdGVtLnkgPSBNYXRoLm1heChjb2xsaWRlc1dpdGgueSAtIGl0ZW1Ub01vdmUuaCwgMCk7XHJcbiAgICBpZiAoIWdldEZpcnN0Q29sbGlzaW9uKGxheW91dCwgZmFrZUl0ZW0pKSB7XHJcbiAgICAgIHJldHVybiBtb3ZlRWxlbWVudChsYXlvdXQsIGl0ZW1Ub01vdmUsIHVuZGVmaW5lZCwgZmFrZUl0ZW0ueSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLyBQcmV2aW91c2x5IHRoaXMgd2FzIG9wdGltaXplZCB0byBtb3ZlIGJlbG93IHRoZSBjb2xsaXNpb24gZGlyZWN0bHksIGJ1dCB0aGlzIGNhbiBjYXVzZSBwcm9ibGVtc1xyXG4gIC8vIHdpdGggY2FzY2FkaW5nIG1vdmVzLCBhcyBhbiBpdGVtIG1heSBhY3R1YWxseSBsZWFwZmxvZyBhIGNvbGxpc2lvbiBhbmQgY2F1c2UgYSByZXZlcnNhbCBpbiBvcmRlci5cclxuICByZXR1cm4gbW92ZUVsZW1lbnQobGF5b3V0LCBpdGVtVG9Nb3ZlLCB1bmRlZmluZWQsIGl0ZW1Ub01vdmUueSArIDEpO1xyXG59XHJcblxyXG4vKipcclxuICogSGVscGVyIHRvIGNvbnZlcnQgYSBudW1iZXIgdG8gYSBwZXJjZW50YWdlIHN0cmluZy5cclxuICpcclxuICogQHBhcmFtICB7TnVtYmVyfSBudW0gQW55IG51bWJlclxyXG4gKiBAcmV0dXJuIHtTdHJpbmd9ICAgICBUaGF0IG51bWJlciBhcyBhIHBlcmNlbnRhZ2UuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gcGVyYyhudW06IG51bWJlcik6IHN0cmluZyB7XHJcbiAgcmV0dXJuIG51bSAqIDEwMCArICclJztcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHNldFRyYW5zZm9ybSh0b3AsIGxlZnQsIHdpZHRoLCBoZWlnaHQpOiBPYmplY3Qge1xyXG4gIC8vIFJlcGxhY2UgdW5pdGxlc3MgaXRlbXMgd2l0aCBweFxyXG4gIGNvbnN0IHRyYW5zbGF0ZSA9IFwidHJhbnNsYXRlKFwiICsgbGVmdCArIFwicHgsXCIgKyB0b3AgKyBcInB4KVwiO1xyXG4gIHJldHVybiB7XHJcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZSxcclxuICAgIFdlYmtpdFRyYW5zZm9ybTogdHJhbnNsYXRlLFxyXG4gICAgTW96VHJhbnNmb3JtOiB0cmFuc2xhdGUsXHJcbiAgICBtc1RyYW5zZm9ybTogdHJhbnNsYXRlLFxyXG4gICAgT1RyYW5zZm9ybTogdHJhbnNsYXRlLFxyXG4gICAgd2lkdGg6IHdpZHRoICsgXCJweFwiLFxyXG4gICAgaGVpZ2h0OiBoZWlnaHQgKyBcInB4XCIsXHJcbiAgICBwb3NpdGlvbjogJ2Fic29sdXRlJ1xyXG4gIH07XHJcbn1cclxuLyoqXHJcbiAqIEp1c3QgbGlrZSB0aGUgc2V0VHJhbnNmb3JtIG1ldGhvZCwgYnV0IGluc3RlYWQgaXQgd2lsbCByZXR1cm4gYSBuZWdhdGl2ZSB2YWx1ZSBvZiByaWdodC5cclxuICpcclxuICogQHBhcmFtIHRvcFxyXG4gKiBAcGFyYW0gcmlnaHRcclxuICogQHBhcmFtIHdpZHRoXHJcbiAqIEBwYXJhbSBoZWlnaHRcclxuICogQHJldHVybnMge3t0cmFuc2Zvcm06IHN0cmluZywgV2Via2l0VHJhbnNmb3JtOiBzdHJpbmcsIE1velRyYW5zZm9ybTogc3RyaW5nLCBtc1RyYW5zZm9ybTogc3RyaW5nLCBPVHJhbnNmb3JtOiBzdHJpbmcsIHdpZHRoOiBzdHJpbmcsIGhlaWdodDogc3RyaW5nLCBwb3NpdGlvbjogc3RyaW5nfX1cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBzZXRUcmFuc2Zvcm1SdGwodG9wLCByaWdodCwgd2lkdGgsIGhlaWdodCk6IE9iamVjdCB7XHJcbiAgICAvLyBSZXBsYWNlIHVuaXRsZXNzIGl0ZW1zIHdpdGggcHhcclxuICAgIGNvbnN0IHRyYW5zbGF0ZSA9IFwidHJhbnNsYXRlKFwiICsgcmlnaHQgKiAtMSArIFwicHgsXCIgKyB0b3AgKyBcInB4KVwiO1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZSxcclxuICAgICAgICBXZWJraXRUcmFuc2Zvcm06IHRyYW5zbGF0ZSxcclxuICAgICAgICBNb3pUcmFuc2Zvcm06IHRyYW5zbGF0ZSxcclxuICAgICAgICBtc1RyYW5zZm9ybTogdHJhbnNsYXRlLFxyXG4gICAgICAgIE9UcmFuc2Zvcm06IHRyYW5zbGF0ZSxcclxuICAgICAgICB3aWR0aDogd2lkdGggKyBcInB4XCIsXHJcbiAgICAgICAgaGVpZ2h0OiBoZWlnaHQgKyBcInB4XCIsXHJcbiAgICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZSdcclxuICAgIH07XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBzZXRUb3BMZWZ0KHRvcCwgbGVmdCwgd2lkdGgsIGhlaWdodCk6IE9iamVjdCB7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIHRvcDogdG9wICsgXCJweFwiLFxyXG4gICAgICAgIGxlZnQ6IGxlZnQgKyBcInB4XCIsXHJcbiAgICAgICAgd2lkdGg6IHdpZHRoICsgXCJweFwiLFxyXG4gICAgICAgIGhlaWdodDogaGVpZ2h0ICsgXCJweFwiLFxyXG4gICAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnXHJcbiAgICB9O1xyXG59XHJcbi8qKlxyXG4gKiBKdXN0IGxpa2UgdGhlIHNldFRvcExlZnQgbWV0aG9kLCBidXQgaW5zdGVhZCwgaXQgd2lsbCByZXR1cm4gYSByaWdodCBwcm9wZXJ0eSBpbnN0ZWFkIG9mIGxlZnQuXHJcbiAqXHJcbiAqIEBwYXJhbSB0b3BcclxuICogQHBhcmFtIHJpZ2h0XHJcbiAqIEBwYXJhbSB3aWR0aFxyXG4gKiBAcGFyYW0gaGVpZ2h0XHJcbiAqIEByZXR1cm5zIHt7dG9wOiBzdHJpbmcsIHJpZ2h0OiBzdHJpbmcsIHdpZHRoOiBzdHJpbmcsIGhlaWdodDogc3RyaW5nLCBwb3NpdGlvbjogc3RyaW5nfX1cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBzZXRUb3BSaWdodCh0b3AsIHJpZ2h0LCB3aWR0aCwgaGVpZ2h0KTogT2JqZWN0IHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgdG9wOiB0b3AgKyBcInB4XCIsXHJcbiAgICAgICAgcmlnaHQ6IHJpZ2h0KyBcInB4XCIsXHJcbiAgICAgICAgd2lkdGg6IHdpZHRoICsgXCJweFwiLFxyXG4gICAgICAgIGhlaWdodDogaGVpZ2h0ICsgXCJweFwiLFxyXG4gICAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnXHJcbiAgICB9O1xyXG59XHJcblxyXG5cclxuLyoqXHJcbiAqIEdldCBsYXlvdXQgaXRlbXMgc29ydGVkIGZyb20gdG9wIGxlZnQgdG8gcmlnaHQgYW5kIGRvd24uXHJcbiAqXHJcbiAqIEByZXR1cm4ge0FycmF5fSBBcnJheSBvZiBsYXlvdXQgb2JqZWN0cy5cclxuICogQHJldHVybiB7QXJyYXl9ICAgICAgICBMYXlvdXQsIHNvcnRlZCBzdGF0aWMgaXRlbXMgZmlyc3QuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gc29ydExheW91dEl0ZW1zQnlSb3dDb2wobGF5b3V0OiBMYXlvdXQpOiBMYXlvdXQge1xyXG4gIHJldHVybiBbXS5jb25jYXQobGF5b3V0KS5zb3J0KGZ1bmN0aW9uKGEsIGIpIHtcclxuICAgIGlmIChhLnkgPiBiLnkgfHwgKGEueSA9PT0gYi55ICYmIGEueCA+IGIueCkpIHtcclxuICAgICAgcmV0dXJuIDE7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gLTE7XHJcbiAgfSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZW5lcmF0ZSBhIGxheW91dCB1c2luZyB0aGUgaW5pdGlhbExheW91dCBhbmQgY2hpbGRyZW4gYXMgYSB0ZW1wbGF0ZS5cclxuICogTWlzc2luZyBlbnRyaWVzIHdpbGwgYmUgYWRkZWQsIGV4dHJhbmVvdXMgb25lcyB3aWxsIGJlIHRydW5jYXRlZC5cclxuICpcclxuICogQHBhcmFtICB7QXJyYXl9ICBpbml0aWFsTGF5b3V0IExheW91dCBwYXNzZWQgaW4gdGhyb3VnaCBwcm9wcy5cclxuICogQHBhcmFtICB7U3RyaW5nfSBicmVha3BvaW50ICAgIEN1cnJlbnQgcmVzcG9uc2l2ZSBicmVha3BvaW50LlxyXG4gKiBAcGFyYW0gIHtCb29sZWFufSB2ZXJ0aWNhbENvbXBhY3QgV2hldGhlciBvciBub3QgdG8gY29tcGFjdCB0aGUgbGF5b3V0IHZlcnRpY2FsbHkuXHJcbiAqIEByZXR1cm4ge0FycmF5fSAgICAgICAgICAgICAgICBXb3JraW5nIGxheW91dC5cclxuICovXHJcbi8qXHJcbmV4cG9ydCBmdW5jdGlvbiBzeW5jaHJvbml6ZUxheW91dFdpdGhDaGlsZHJlbihpbml0aWFsTGF5b3V0OiBMYXlvdXQsIGNoaWxkcmVuOiBBcnJheTxSZWFjdC5FbGVtZW50PnxSZWFjdC5FbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sczogbnVtYmVyLCB2ZXJ0aWNhbENvbXBhY3Q6IGJvb2xlYW4pOiBMYXlvdXQge1xyXG4gIC8vIGVuc3VyZSAnY2hpbGRyZW4nIGlzIGFsd2F5cyBhbiBhcnJheVxyXG4gIGlmICghQXJyYXkuaXNBcnJheShjaGlsZHJlbikpIHtcclxuICAgIGNoaWxkcmVuID0gW2NoaWxkcmVuXTtcclxuICB9XHJcbiAgaW5pdGlhbExheW91dCA9IGluaXRpYWxMYXlvdXQgfHwgW107XHJcblxyXG4gIC8vIEdlbmVyYXRlIG9uZSBsYXlvdXQgaXRlbSBwZXIgY2hpbGQuXHJcbiAgbGV0IGxheW91dDogTGF5b3V0ID0gW107XHJcbiAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGNoaWxkcmVuLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICBsZXQgbmV3SXRlbTtcclxuICAgIGNvbnN0IGNoaWxkID0gY2hpbGRyZW5baV07XHJcblxyXG4gICAgLy8gRG9uJ3Qgb3ZlcndyaXRlIGlmIGl0IGFscmVhZHkgZXhpc3RzLlxyXG4gICAgY29uc3QgZXhpc3RzID0gZ2V0TGF5b3V0SXRlbShpbml0aWFsTGF5b3V0LCBjaGlsZC5rZXkgfHwgXCIxXCIgLyEqIEZJWE1FIHNhdGlzZmllcyBGbG93ICohLyk7XHJcbiAgICBpZiAoZXhpc3RzKSB7XHJcbiAgICAgIG5ld0l0ZW0gPSBleGlzdHM7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb25zdCBnID0gY2hpbGQucHJvcHMuX2dyaWQ7XHJcblxyXG4gICAgICAvLyBIZXksIHRoaXMgaXRlbSBoYXMgYSBfZ3JpZCBwcm9wZXJ0eSwgdXNlIGl0LlxyXG4gICAgICBpZiAoZykge1xyXG4gICAgICAgIGlmICghaXNQcm9kdWN0aW9uKSB7XHJcbiAgICAgICAgICB2YWxpZGF0ZUxheW91dChbZ10sICdSZWFjdEdyaWRMYXlvdXQuY2hpbGRyZW4nKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gVmFsaWRhdGVkOyBhZGQgaXQgdG8gdGhlIGxheW91dC4gQm90dG9tICd5JyBwb3NzaWJsZSBpcyB0aGUgYm90dG9tIG9mIHRoZSBsYXlvdXQuXHJcbiAgICAgICAgLy8gVGhpcyBhbGxvd3MgeW91IHRvIGRvIG5pY2Ugc3R1ZmYgbGlrZSBzcGVjaWZ5IHt5OiBJbmZpbml0eX1cclxuICAgICAgICBpZiAodmVydGljYWxDb21wYWN0KSB7XHJcbiAgICAgICAgICBuZXdJdGVtID0gY2xvbmVMYXlvdXRJdGVtKHsuLi5nLCB5OiBNYXRoLm1pbihib3R0b20obGF5b3V0KSwgZy55KSwgaTogY2hpbGQua2V5fSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIG5ld0l0ZW0gPSBjbG9uZUxheW91dEl0ZW0oey4uLmcsIHk6IGcueSwgaTogY2hpbGQua2V5fSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIC8vIE5vdGhpbmcgcHJvdmlkZWQ6IGVuc3VyZSB0aGlzIGlzIGFkZGVkIHRvIHRoZSBib3R0b21cclxuICAgICAgZWxzZSB7XHJcbiAgICAgICAgbmV3SXRlbSA9IGNsb25lTGF5b3V0SXRlbSh7dzogMSwgaDogMSwgeDogMCwgeTogYm90dG9tKGxheW91dCksIGk6IGNoaWxkLmtleSB8fCBcIjFcIn0pO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBsYXlvdXRbaV0gPSBuZXdJdGVtO1xyXG4gIH1cclxuXHJcbiAgLy8gQ29ycmVjdCB0aGUgbGF5b3V0LlxyXG4gIGxheW91dCA9IGNvcnJlY3RCb3VuZHMobGF5b3V0LCB7Y29sczogY29sc30pO1xyXG4gIGxheW91dCA9IGNvbXBhY3QobGF5b3V0LCB2ZXJ0aWNhbENvbXBhY3QpO1xyXG5cclxuICByZXR1cm4gbGF5b3V0O1xyXG59XHJcbiovXHJcblxyXG4vKipcclxuICogVmFsaWRhdGUgYSBsYXlvdXQuIFRocm93cyBlcnJvcnMuXHJcbiAqXHJcbiAqIEBwYXJhbSAge0FycmF5fSAgbGF5b3V0ICAgICAgICBBcnJheSBvZiBsYXlvdXQgaXRlbXMuXHJcbiAqIEBwYXJhbSAge1N0cmluZ30gW2NvbnRleHROYW1lXSBDb250ZXh0IG5hbWUgZm9yIGVycm9ycy5cclxuICogQHRocm93ICB7RXJyb3J9ICAgICAgICAgICAgICAgIFZhbGlkYXRpb24gZXJyb3IuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVMYXlvdXQobGF5b3V0OiBMYXlvdXQsIGNvbnRleHROYW1lOiBzdHJpbmcpOiB2b2lkIHtcclxuICBjb250ZXh0TmFtZSA9IGNvbnRleHROYW1lIHx8IFwiTGF5b3V0XCI7XHJcbiAgY29uc3Qgc3ViUHJvcHMgPSBbJ3gnLCAneScsICd3JywgJ2gnXTtcclxuICBpZiAoIUFycmF5LmlzQXJyYXkobGF5b3V0KSkgdGhyb3cgbmV3IEVycm9yKGNvbnRleHROYW1lICsgXCIgbXVzdCBiZSBhbiBhcnJheSFcIik7XHJcbiAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGxheW91dC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgY29uc3QgaXRlbSA9IGxheW91dFtpXTtcclxuICAgIGZvciAobGV0IGogPSAwOyBqIDwgc3ViUHJvcHMubGVuZ3RoOyBqKyspIHtcclxuICAgICAgaWYgKHR5cGVvZiBpdGVtW3N1YlByb3BzW2pdXSAhPT0gJ251bWJlcicpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Z1ZUdyaWRMYXlvdXQ6ICcgKyBjb250ZXh0TmFtZSArICdbJyArIGkgKyAnXS4nICsgc3ViUHJvcHNbal0gKyAnIG11c3QgYmUgYSBudW1iZXIhJyk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIGlmIChpdGVtLmkgJiYgdHlwZW9mIGl0ZW0uaSAhPT0gJ3N0cmluZycpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdWdWVHcmlkTGF5b3V0OiAnICsgY29udGV4dE5hbWUgKyAnWycgKyBpICsgJ10uaSBtdXN0IGJlIGEgc3RyaW5nIScpO1xyXG4gICAgfVxyXG4gICAgaWYgKGl0ZW0uc3RhdGljICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIGl0ZW0uc3RhdGljICE9PSAnYm9vbGVhbicpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdWdWVHcmlkTGF5b3V0OiAnICsgY29udGV4dE5hbWUgKyAnWycgKyBpICsgJ10uc3RhdGljIG11c3QgYmUgYSBib29sZWFuIScpO1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG5cclxuLy8gRmxvdyBjYW4ndCByZWFsbHkgZmlndXJlIHRoaXMgb3V0LCBzbyB3ZSBqdXN0IHVzZSBPYmplY3RcclxuZXhwb3J0IGZ1bmN0aW9uIGF1dG9CaW5kSGFuZGxlcnMoZWw6IE9iamVjdCwgZm5zOiBBcnJheTxzdHJpbmc+KTogdm9pZCB7XHJcbiAgZm5zLmZvckVhY2goKGtleSkgPT4gZWxba2V5XSA9IGVsW2tleV0uYmluZChlbCkpO1xyXG59XHJcblxyXG5cclxuXHJcbi8qKlxyXG4gKiBDb252ZXJ0IGEgSlMgb2JqZWN0IHRvIENTUyBzdHJpbmcuIFNpbWlsYXIgdG8gUmVhY3QncyBvdXRwdXQgb2YgQ1NTLlxyXG4gKiBAcGFyYW0gb2JqXHJcbiAqIEByZXR1cm5zIHtzdHJpbmd9XHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlTWFya3VwKG9iaikge1xyXG4gICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhvYmopO1xyXG4gICAgaWYgKCFrZXlzLmxlbmd0aCkgcmV0dXJuICcnO1xyXG4gICAgdmFyIGksIGxlbiA9IGtleXMubGVuZ3RoO1xyXG4gICAgdmFyIHJlc3VsdCA9ICcnO1xyXG5cclxuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgIHZhciBrZXkgPSBrZXlzW2ldO1xyXG4gICAgICAgIHZhciB2YWwgPSBvYmpba2V5XTtcclxuICAgICAgICByZXN1bHQgKz0gaHlwaGVuYXRlKGtleSkgKyAnOicgKyBhZGRQeChrZXksIHZhbCkgKyAnOyc7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxuXHJcbi8qIFRoZSBmb2xsb3dpbmcgbGlzdCBpcyBkZWZpbmVkIGluIFJlYWN0J3MgY29yZSAqL1xyXG5leHBvcnQgdmFyIElTX1VOSVRMRVNTID0ge1xyXG4gICAgYW5pbWF0aW9uSXRlcmF0aW9uQ291bnQ6IHRydWUsXHJcbiAgICBib3hGbGV4OiB0cnVlLFxyXG4gICAgYm94RmxleEdyb3VwOiB0cnVlLFxyXG4gICAgYm94T3JkaW5hbEdyb3VwOiB0cnVlLFxyXG4gICAgY29sdW1uQ291bnQ6IHRydWUsXHJcbiAgICBmbGV4OiB0cnVlLFxyXG4gICAgZmxleEdyb3c6IHRydWUsXHJcbiAgICBmbGV4UG9zaXRpdmU6IHRydWUsXHJcbiAgICBmbGV4U2hyaW5rOiB0cnVlLFxyXG4gICAgZmxleE5lZ2F0aXZlOiB0cnVlLFxyXG4gICAgZmxleE9yZGVyOiB0cnVlLFxyXG4gICAgZ3JpZFJvdzogdHJ1ZSxcclxuICAgIGdyaWRDb2x1bW46IHRydWUsXHJcbiAgICBmb250V2VpZ2h0OiB0cnVlLFxyXG4gICAgbGluZUNsYW1wOiB0cnVlLFxyXG4gICAgbGluZUhlaWdodDogdHJ1ZSxcclxuICAgIG9wYWNpdHk6IHRydWUsXHJcbiAgICBvcmRlcjogdHJ1ZSxcclxuICAgIG9ycGhhbnM6IHRydWUsXHJcbiAgICB0YWJTaXplOiB0cnVlLFxyXG4gICAgd2lkb3dzOiB0cnVlLFxyXG4gICAgekluZGV4OiB0cnVlLFxyXG4gICAgem9vbTogdHJ1ZSxcclxuXHJcbiAgICAvLyBTVkctcmVsYXRlZCBwcm9wZXJ0aWVzXHJcbiAgICBmaWxsT3BhY2l0eTogdHJ1ZSxcclxuICAgIHN0b3BPcGFjaXR5OiB0cnVlLFxyXG4gICAgc3Ryb2tlRGFzaG9mZnNldDogdHJ1ZSxcclxuICAgIHN0cm9rZU9wYWNpdHk6IHRydWUsXHJcbiAgICBzdHJva2VXaWR0aDogdHJ1ZVxyXG59O1xyXG5cclxuXHJcbi8qKlxyXG4gKiBXaWxsIGFkZCBweCB0byB0aGUgZW5kIG9mIHN0eWxlIHZhbHVlcyB3aGljaCBhcmUgTnVtYmVycy5cclxuICogQHBhcmFtIG5hbWVcclxuICogQHBhcmFtIHZhbHVlXHJcbiAqIEByZXR1cm5zIHsqfVxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGFkZFB4KG5hbWUsIHZhbHVlKSB7XHJcbiAgICBpZih0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInICYmICFJU19VTklUTEVTU1sgbmFtZSBdKSB7XHJcbiAgICAgICAgcmV0dXJuIHZhbHVlICsgJ3B4JztcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xyXG4gICAgfVxyXG59XHJcblxyXG5cclxuLyoqXHJcbiAqIEh5cGhlbmF0ZSBhIGNhbWVsQ2FzZSBzdHJpbmcuXHJcbiAqXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcclxuICogQHJldHVybiB7U3RyaW5nfVxyXG4gKi9cclxuXHJcbmV4cG9ydCB2YXIgaHlwaGVuYXRlUkUgPSAvKFthLXpcXGRdKShbQS1aXSkvZztcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBoeXBoZW5hdGUoc3RyKSB7XHJcbiAgICByZXR1cm4gc3RyLnJlcGxhY2UoaHlwaGVuYXRlUkUsICckMS0kMicpLnRvTG93ZXJDYXNlKCk7XHJcbn1cclxuXHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZmluZEl0ZW1JbkFycmF5KGFycmF5LCBwcm9wZXJ0eSwgdmFsdWUpIHtcclxuICAgIGZvciAodmFyIGk9MDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKVxyXG4gICAgICAgIGlmIChhcnJheVtpXVtwcm9wZXJ0eV0gPT0gdmFsdWUpXHJcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG5cclxuICAgIHJldHVybiBmYWxzZTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGZpbmRBbmRSZW1vdmUoYXJyYXksIHByb3BlcnR5LCB2YWx1ZSkge1xyXG4gICAgYXJyYXkuZm9yRWFjaChmdW5jdGlvbiAocmVzdWx0LCBpbmRleCkge1xyXG4gICAgICAgIGlmIChyZXN1bHRbcHJvcGVydHldID09PSB2YWx1ZSkge1xyXG4gICAgICAgICAgICAvL1JlbW92ZSBmcm9tIGFycmF5XHJcbiAgICAgICAgICAgIGFycmF5LnNwbGljZShpbmRleCwgMSk7XHJcbiAgICAgICAgfVxyXG4gICAgfSk7XHJcbn1cclxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc3JjL3V0aWxzLmpzIl0sInNvdXJjZVJvb3QiOiIifQ=="); - -/***/ }, -/* 1 */ -/***/ function(module, exports, __webpack_require__) { - -eval("var __vue_exports__, __vue_options__\nvar __vue_styles__ = {}\n\n/* styles */\n__webpack_require__(35)\n\n/* script */\n__vue_exports__ = __webpack_require__(11)\n\n/* template */\nvar __vue_template__ = __webpack_require__(32)\n__vue_options__ = __vue_exports__ = __vue_exports__ || {}\nif (\n typeof __vue_exports__.default === \"object\" ||\n typeof __vue_exports__.default === \"function\"\n) {\nif (Object.keys(__vue_exports__).some(function (key) { return key !== \"default\" && key !== \"__esModule\" })) {console.error(\"named exports are not supported in *.vue files.\")}\n__vue_options__ = __vue_exports__ = __vue_exports__.default\n}\nif (typeof __vue_options__ === \"function\") {\n __vue_options__ = __vue_options__.options\n}\n__vue_options__.__file = \"C:\\\\projects\\\\JBAY\\\\vue-grid-layout\\\\src\\\\GridItem.vue\"\n__vue_options__.render = __vue_template__.render\n__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\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-e800ab18\", __vue_options__)\n } else {\n hotAPI.reload(\"data-v-e800ab18\", __vue_options__)\n }\n})()}\nif (__vue_options__.functional) {console.error(\"[vue-loader] GridItem.vue: functional components are not supported and should be defined in plain js files using render functions.\")}\n\nmodule.exports = __vue_exports__\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvR3JpZEl0ZW0udnVlPzhkZmUiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzREFBc0QsbURBQW1ELElBQUk7QUFDN0c7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFlBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsQ0FBQztBQUNELGlDQUFpQzs7QUFFakMiLCJmaWxlIjoiMS5qcyIsInNvdXJjZXNDb250ZW50IjpbInZhciBfX3Z1ZV9leHBvcnRzX18sIF9fdnVlX29wdGlvbnNfX1xudmFyIF9fdnVlX3N0eWxlc19fID0ge31cblxuLyogc3R5bGVzICovXG5yZXF1aXJlKFwiISF2dWUtc3R5bGUtbG9hZGVyIWNzcy1sb2FkZXI/c291cmNlTWFwIXZ1ZS1sb2FkZXIvbGliL3N0eWxlLXJld3JpdGVyP2lkPWRhdGEtdi1lODAwYWIxOCF2dWUtbG9hZGVyL2xpYi9zZWxlY3Rvcj90eXBlPXN0eWxlcyZpbmRleD0wIS4vR3JpZEl0ZW0udnVlXCIpXG5cbi8qIHNjcmlwdCAqL1xuX192dWVfZXhwb3J0c19fID0gcmVxdWlyZShcIiEhYmFiZWwtbG9hZGVyIXZ1ZS1sb2FkZXIvbGliL3NlbGVjdG9yP3R5cGU9c2NyaXB0JmluZGV4PTAhLi9HcmlkSXRlbS52dWVcIilcblxuLyogdGVtcGxhdGUgKi9cbnZhciBfX3Z1ZV90ZW1wbGF0ZV9fID0gcmVxdWlyZShcIiEhdnVlLWxvYWRlci9saWIvdGVtcGxhdGUtY29tcGlsZXI/aWQ9ZGF0YS12LWU4MDBhYjE4IXZ1ZS1sb2FkZXIvbGliL3NlbGVjdG9yP3R5cGU9dGVtcGxhdGUmaW5kZXg9MCEuL0dyaWRJdGVtLnZ1ZVwiKVxuX192dWVfb3B0aW9uc19fID0gX192dWVfZXhwb3J0c19fID0gX192dWVfZXhwb3J0c19fIHx8IHt9XG5pZiAoXG4gIHR5cGVvZiBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdCA9PT0gXCJvYmplY3RcIiB8fFxuICB0eXBlb2YgX192dWVfZXhwb3J0c19fLmRlZmF1bHQgPT09IFwiZnVuY3Rpb25cIlxuKSB7XG5pZiAoT2JqZWN0LmtleXMoX192dWVfZXhwb3J0c19fKS5zb21lKGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIGtleSAhPT0gXCJkZWZhdWx0XCIgJiYga2V5ICE9PSBcIl9fZXNNb2R1bGVcIiB9KSkge2NvbnNvbGUuZXJyb3IoXCJuYW1lZCBleHBvcnRzIGFyZSBub3Qgc3VwcG9ydGVkIGluICoudnVlIGZpbGVzLlwiKX1cbl9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX2V4cG9ydHNfXyA9IF9fdnVlX2V4cG9ydHNfXy5kZWZhdWx0XG59XG5pZiAodHlwZW9mIF9fdnVlX29wdGlvbnNfXyA9PT0gXCJmdW5jdGlvblwiKSB7XG4gIF9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX29wdGlvbnNfXy5vcHRpb25zXG59XG5fX3Z1ZV9vcHRpb25zX18uX19maWxlID0gXCJDOlxcXFxwcm9qZWN0c1xcXFxKQkFZXFxcXHZ1ZS1ncmlkLWxheW91dFxcXFxzcmNcXFxcR3JpZEl0ZW0udnVlXCJcbl9fdnVlX29wdGlvbnNfXy5yZW5kZXIgPSBfX3Z1ZV90ZW1wbGF0ZV9fLnJlbmRlclxuX192dWVfb3B0aW9uc19fLnN0YXRpY1JlbmRlckZucyA9IF9fdnVlX3RlbXBsYXRlX18uc3RhdGljUmVuZGVyRm5zXG5cbi8qIGhvdCByZWxvYWQgKi9cbmlmIChtb2R1bGUuaG90KSB7KGZ1bmN0aW9uICgpIHtcbiAgdmFyIGhvdEFQSSA9IHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIilcbiAgaG90QVBJLmluc3RhbGwocmVxdWlyZShcInZ1ZVwiKSwgZmFsc2UpXG4gIGlmICghaG90QVBJLmNvbXBhdGlibGUpIHJldHVyblxuICBtb2R1bGUuaG90LmFjY2VwdCgpXG4gIGlmICghbW9kdWxlLmhvdC5kYXRhKSB7XG4gICAgaG90QVBJLmNyZWF0ZVJlY29yZChcImRhdGEtdi1lODAwYWIxOFwiLCBfX3Z1ZV9vcHRpb25zX18pXG4gIH0gZWxzZSB7XG4gICAgaG90QVBJLnJlbG9hZChcImRhdGEtdi1lODAwYWIxOFwiLCBfX3Z1ZV9vcHRpb25zX18pXG4gIH1cbn0pKCl9XG5pZiAoX192dWVfb3B0aW9uc19fLmZ1bmN0aW9uYWwpIHtjb25zb2xlLmVycm9yKFwiW3Z1ZS1sb2FkZXJdIEdyaWRJdGVtLnZ1ZTogZnVuY3Rpb25hbCBjb21wb25lbnRzIGFyZSBub3Qgc3VwcG9ydGVkIGFuZCBzaG91bGQgYmUgZGVmaW5lZCBpbiBwbGFpbiBqcyBmaWxlcyB1c2luZyByZW5kZXIgZnVuY3Rpb25zLlwiKX1cblxubW9kdWxlLmV4cG9ydHMgPSBfX3Z1ZV9leHBvcnRzX19cblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vc3JjL0dyaWRJdGVtLnZ1ZVxuLy8gbW9kdWxlIGlkID0gMVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwic291cmNlUm9vdCI6IiJ9"); - -/***/ }, -/* 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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9+L2Nzcy1sb2FkZXIvbGliL2Nzcy1iYXNlLmpzP2RhMDQiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLGlCQUFpQjtBQUNqQztBQUNBO0FBQ0Esd0NBQXdDLGdCQUFnQjtBQUN4RCxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLGlCQUFpQjtBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksb0JBQW9CO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiIyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLypcclxuXHRNSVQgTGljZW5zZSBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocFxyXG5cdEF1dGhvciBUb2JpYXMgS29wcGVycyBAc29rcmFcclxuKi9cclxuLy8gY3NzIGJhc2UgY29kZSwgaW5qZWN0ZWQgYnkgdGhlIGNzcy1sb2FkZXJcclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbigpIHtcclxuXHR2YXIgbGlzdCA9IFtdO1xyXG5cclxuXHQvLyByZXR1cm4gdGhlIGxpc3Qgb2YgbW9kdWxlcyBhcyBjc3Mgc3RyaW5nXHJcblx0bGlzdC50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xyXG5cdFx0dmFyIHJlc3VsdCA9IFtdO1xyXG5cdFx0Zm9yKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcclxuXHRcdFx0dmFyIGl0ZW0gPSB0aGlzW2ldO1xyXG5cdFx0XHRpZihpdGVtWzJdKSB7XHJcblx0XHRcdFx0cmVzdWx0LnB1c2goXCJAbWVkaWEgXCIgKyBpdGVtWzJdICsgXCJ7XCIgKyBpdGVtWzFdICsgXCJ9XCIpO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdHJlc3VsdC5wdXNoKGl0ZW1bMV0pO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gcmVzdWx0LmpvaW4oXCJcIik7XHJcblx0fTtcclxuXHJcblx0Ly8gaW1wb3J0IGEgbGlzdCBvZiBtb2R1bGVzIGludG8gdGhlIGxpc3RcclxuXHRsaXN0LmkgPSBmdW5jdGlvbihtb2R1bGVzLCBtZWRpYVF1ZXJ5KSB7XHJcblx0XHRpZih0eXBlb2YgbW9kdWxlcyA9PT0gXCJzdHJpbmdcIilcclxuXHRcdFx0bW9kdWxlcyA9IFtbbnVsbCwgbW9kdWxlcywgXCJcIl1dO1xyXG5cdFx0dmFyIGFscmVhZHlJbXBvcnRlZE1vZHVsZXMgPSB7fTtcclxuXHRcdGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XHJcblx0XHRcdHZhciBpZCA9IHRoaXNbaV1bMF07XHJcblx0XHRcdGlmKHR5cGVvZiBpZCA9PT0gXCJudW1iZXJcIilcclxuXHRcdFx0XHRhbHJlYWR5SW1wb3J0ZWRNb2R1bGVzW2lkXSA9IHRydWU7XHJcblx0XHR9XHJcblx0XHRmb3IoaSA9IDA7IGkgPCBtb2R1bGVzLmxlbmd0aDsgaSsrKSB7XHJcblx0XHRcdHZhciBpdGVtID0gbW9kdWxlc1tpXTtcclxuXHRcdFx0Ly8gc2tpcCBhbHJlYWR5IGltcG9ydGVkIG1vZHVsZVxyXG5cdFx0XHQvLyB0aGlzIGltcGxlbWVudGF0aW9uIGlzIG5vdCAxMDAlIHBlcmZlY3QgZm9yIHdlaXJkIG1lZGlhIHF1ZXJ5IGNvbWJpbmF0aW9uc1xyXG5cdFx0XHQvLyAgd2hlbiBhIG1vZHVsZSBpcyBpbXBvcnRlZCBtdWx0aXBsZSB0aW1lcyB3aXRoIGRpZmZlcmVudCBtZWRpYSBxdWVyaWVzLlxyXG5cdFx0XHQvLyAgSSBob3BlIHRoaXMgd2lsbCBuZXZlciBvY2N1ciAoSGV5IHRoaXMgd2F5IHdlIGhhdmUgc21hbGxlciBidW5kbGVzKVxyXG5cdFx0XHRpZih0eXBlb2YgaXRlbVswXSAhPT0gXCJudW1iZXJcIiB8fCAhYWxyZWFkeUltcG9ydGVkTW9kdWxlc1tpdGVtWzBdXSkge1xyXG5cdFx0XHRcdGlmKG1lZGlhUXVlcnkgJiYgIWl0ZW1bMl0pIHtcclxuXHRcdFx0XHRcdGl0ZW1bMl0gPSBtZWRpYVF1ZXJ5O1xyXG5cdFx0XHRcdH0gZWxzZSBpZihtZWRpYVF1ZXJ5KSB7XHJcblx0XHRcdFx0XHRpdGVtWzJdID0gXCIoXCIgKyBpdGVtWzJdICsgXCIpIGFuZCAoXCIgKyBtZWRpYVF1ZXJ5ICsgXCIpXCI7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGxpc3QucHVzaChpdGVtKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH07XHJcblx0cmV0dXJuIGxpc3Q7XHJcbn07XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jc3MtbG9hZGVyL2xpYi9jc3MtYmFzZS5qc1xuLy8gbW9kdWxlIGlkID0gMlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwic291cmNlUm9vdCI6IiJ9"); - -/***/ }, -/* 3 */ -/***/ function(module, exports) { - -eval("/*\n\tMIT License http://www.opensource.org/licenses/mit-license.php\n\tAuthor Tobias Koppers @sokra\n*/\nvar stylesInDom = {},\n\tmemoize = function(fn) {\n\t\tvar memo;\n\t\treturn function () {\n\t\t\tif (typeof memo === \"undefined\") memo = fn.apply(this, arguments);\n\t\t\treturn memo;\n\t\t};\n\t},\n\tisOldIE = memoize(function() {\n\t\treturn /msie [6-9]\\b/.test(window.navigator.userAgent.toLowerCase());\n\t}),\n\tgetHeadElement = memoize(function () {\n\t\treturn document.head || document.getElementsByTagName(\"head\")[0];\n\t}),\n\tsingletonElement = null,\n\tsingletonCounter = 0,\n\tstyleElementsInsertedAtTop = [];\n\nmodule.exports = function(list, options) {\n\tif(typeof DEBUG !== \"undefined\" && DEBUG) {\n\t\tif(typeof document !== \"object\") throw new Error(\"The style-loader cannot be used in a non-browser environment\");\n\t}\n\n\toptions = options || {};\n\t// Force single-tag solution on IE6-9, which has a hard limit on the # of \\r\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\n// exports\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvR3JpZExheW91dC52dWU/MWE1ZiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBOzs7QUFHQTtBQUNBLDZDQUE4Qyx5QkFBeUIsb0NBQW9DLEdBQUcsVUFBVSxpRkFBaUYsS0FBSyxXQUFXLFdBQVcsc2lCQUFzaUIsK0JBQStCLDBDQUEwQyxTQUFTLHNHQUFzRyxvQkFBb0IsNERBQTRELGdCQUFnQiw2Q0FBNkMseUVBQXlFLDBEQUEwRCxzQ0FBc0MscUJBQXFCLGdIQUFnSCxvRkFBb0YsMEJBQTBCLGlGQUFpRiw2QkFBNkIsa0ZBQWtGLDJCQUEyQix1RkFBdUYsMEJBQTBCLDBFQUEwRSx3Q0FBd0MscUJBQXFCLGlCQUFpQiwrQkFBK0Isb0ZBQW9GLCtCQUErQixvRkFBb0Ysb0NBQW9DLG9GQUFvRixtQ0FBbUMsb0ZBQW9GLDBCQUEwQixvRkFBb0YsY0FBYyxnQ0FBZ0Msd0JBQXdCLG1FQUFtRSxpSEFBaUgscUtBQXFLLG1CQUFtQixhQUFhLHlCQUF5QixnQ0FBZ0Msb0tBQW9LLCtEQUErRCxrQkFBa0IsZ0ZBQWdGLDZEQUE2RCxrQkFBa0IseUVBQXlFLGlFQUFpRSxhQUFhLHVDQUF1Qyx3R0FBd0csa0VBQWtFLHdGQUF3RixrQ0FBa0MsNENBQTRDLGdEQUFnRCxvQ0FBb0MsK0NBQStDLGtEQUFrRCxrREFBa0QsZ0VBQWdFLG1GQUFtRix5QkFBeUIsbUVBQW1FLGdEQUFnRCxvREFBb0Qsa0VBQWtFLDZHQUE2RyxFQUFFLDhFQUE4RSxzREFBc0QsNkJBQTZCLEVBQUUseUJBQXlCLEVBQUUscUJBQXFCLEVBQUUsZ0RBQWdELGtEQUFrRCxrREFBa0QsZ0VBQWdFLG1GQUFtRix5QkFBeUIsbUVBQW1FLGdEQUFnRCxvREFBb0Qsa0VBQWtFLDZHQUE2RyxFQUFFLDhFQUE4RSxzREFBc0QsNkJBQTZCLEVBQUUseUJBQXlCLEVBQUUsMEJBQTBCLGlCQUFpQixFQUFFLGFBQWEscUJBQXFCLG9DQUFvQyxnREFBZ0QsdUVBQXVFLG9FQUFvRSw0Q0FBNEMscUJBQXFCLEVBQUUsaUJBQWlCLHNDQUFzQyx3Q0FBd0MsaUJBQWlCLHdDQUF3QyxxRUFBcUUsaUJBQWlCLDBDQUEwQyx1RUFBdUUsaUJBQWlCLDBDQUEwQyx1RUFBdUUsaUJBQWlCLGFBQWEsdUJBQXVCLGdDQUFnQyxvR0FBb0csOERBQThELG1FQUFtRSxtRUFBbUUsMkVBQTJFLG9FQUFvRSw0Q0FBNEMscUJBQXFCLGlCQUFpQiw0Q0FBNEMsd0NBQXdDLDRFQUE0RSxpQkFBaUIsOENBQThDLDBFQUEwRSxpRUFBaUUscUJBQXFCLGlCQUFpQiwrQ0FBK0MsK0NBQStDLDJHQUEyRyxpQkFBaUIsa0VBQWtFLGtGQUFrRiwrQ0FBK0MsZ0RBQWdELCtDQUErQywrQ0FBK0MsK0NBQStDLCtDQUErQyx1RUFBdUUsb0VBQW9FLHFCQUFxQixPQUFPLGdEQUFnRCxxQkFBcUIsMkZBQTJGLDJEQUEyRCw0QkFBNEIsNEJBQTRCLDBJQUEwSSwrREFBK0QsMElBQTBJLHdDQUF3QyxpQkFBaUIsb0VBQW9FLHNGQUFzRiwrQ0FBK0MsZ0RBQWdELCtDQUErQywrQ0FBK0MsK0NBQStDLCtDQUErQyx1RUFBdUUsb0VBQW9FLHlCQUF5QixPQUFPLGdEQUFnRCxxQkFBcUIsMkRBQTJELDRCQUE0Qiw0QkFBNEIsK0RBQStELGdEQUFnRCx3Q0FBd0MsaUJBQWlCLGNBQWMsVUFBVSwwQ0FBMEM7O0FBRW45VCIsImZpbGUiOiIxOC5qcyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2xpYi9jc3MtYmFzZS5qc1wiKSgpO1xuLy8gaW1wb3J0c1xuXG5cbi8vIG1vZHVsZVxuZXhwb3J0cy5wdXNoKFttb2R1bGUuaWQsIFwiXFxuLnZ1ZS1ncmlkLWxheW91dCB7XFxuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcXG4gICAgdHJhbnNpdGlvbjogaGVpZ2h0IDIwMG1zIGVhc2U7XFxufVxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi9zcmMvR3JpZExheW91dC52dWU/MmVjYzJjMjRcIl0sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIjtBQWFBO0lBQ0EsbUJBQUE7SUFDQSw4QkFBQTtDQUNBXCIsXCJmaWxlXCI6XCJHcmlkTGF5b3V0LnZ1ZVwiLFwic291cmNlc0NvbnRlbnRcIjpbXCI8dGVtcGxhdGU+XFxyXFxuICAgIDxkaXYgcmVmPVxcXCJpdGVtXFxcIiBjbGFzcz1cXFwidnVlLWdyaWQtbGF5b3V0XFxcIiA6c3R5bGU9XFxcIm1lcmdlZFN0eWxlXFxcIj5cXHJcXG4gICAgICAgIDxzbG90Pjwvc2xvdD5cXHJcXG4gICAgICAgIDxncmlkLWl0ZW0gY2xhc3M9XFxcInZ1ZS1ncmlkLXBsYWNlaG9sZGVyXFxcIlxcclxcbiAgICAgICAgICAgICAgICAgICB2LXNob3c9XFxcImlzRHJhZ2dpbmdcXFwiXFxyXFxuICAgICAgICAgICAgICAgICAgIDp4PVxcXCJwbGFjZWhvbGRlci54XFxcIlxcclxcbiAgICAgICAgICAgICAgICAgICA6eT1cXFwicGxhY2Vob2xkZXIueVxcXCJcXHJcXG4gICAgICAgICAgICAgICAgICAgOnc9XFxcInBsYWNlaG9sZGVyLndcXFwiXFxyXFxuICAgICAgICAgICAgICAgICAgIDpoPVxcXCJwbGFjZWhvbGRlci5oXFxcIlxcclxcbiAgICAgICAgICAgICAgICAgICA6aT1cXFwicGxhY2Vob2xkZXIuaVxcXCI+PC9ncmlkLWl0ZW0+XFxyXFxuICAgIDwvZGl2PlxcclxcbjwvdGVtcGxhdGU+XFxyXFxuPHN0eWxlPlxcclxcbiAgICAudnVlLWdyaWQtbGF5b3V0IHtcXHJcXG4gICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcXHJcXG4gICAgICAgIHRyYW5zaXRpb246IGhlaWdodCAyMDBtcyBlYXNlO1xcclxcbiAgICB9XFxyXFxuPC9zdHlsZT5cXHJcXG48c2NyaXB0PlxcclxcbiAgICB2YXIgZWxlbWVudFJlc2l6ZURldGVjdG9yTWFrZXIgPSByZXF1aXJlKFxcXCJlbGVtZW50LXJlc2l6ZS1kZXRlY3RvclxcXCIpO1xcclxcblxcclxcbiAgICBpbXBvcnQge2JvdHRvbSwgY29tcGFjdCwgZ2V0TGF5b3V0SXRlbSwgbW92ZUVsZW1lbnQsIHZhbGlkYXRlTGF5b3V0fSBmcm9tICcuL3V0aWxzJztcXHJcXG4gICAgdmFyIGV2ZW50QnVzID0gcmVxdWlyZSgnLi9ldmVudEJ1cycpO1xcclxcbiAgICBpbXBvcnQgR3JpZEl0ZW0gZnJvbSAnLi9HcmlkSXRlbS52dWUnXFxyXFxuXFxyXFxuICAgIGV4cG9ydCBkZWZhdWx0IHtcXHJcXG4gICAgICAgIG5hbWU6IFxcXCJHcmlkTGF5b3V0XFxcIixcXHJcXG4gICAgICAgIGNvbXBvbmVudHM6IHtcXHJcXG4gICAgICAgICAgICBHcmlkSXRlbSxcXHJcXG4gICAgICAgIH0sXFxyXFxuICAgICAgICBwcm9wczoge1xcclxcbiAgICAgICAgICAgIC8vIElmIHRydWUsIHRoZSBjb250YWluZXIgaGVpZ2h0IHN3ZWxscyBhbmQgY29udHJhY3RzIHRvIGZpdCBjb250ZW50c1xcclxcbiAgICAgICAgICAgIGF1dG9TaXplOiB7XFxyXFxuICAgICAgICAgICAgICAgIHR5cGU6IEJvb2xlYW4sXFxyXFxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRydWVcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIGNvbE51bToge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXFxyXFxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IDEyXFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICByb3dIZWlnaHQ6IHtcXHJcXG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxcclxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiAxNTBcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIG1heFJvd3M6IHtcXHJcXG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxcclxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiBJbmZpbml0eVxcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgbWFyZ2luOiB7XFxyXFxuICAgICAgICAgICAgICAgIHR5cGU6IEFycmF5LFxcclxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiBmdW5jdGlvbiAoKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzEwLCAxMF07XFxyXFxuICAgICAgICAgICAgICAgIH1cXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIGlzRHJhZ2dhYmxlOiB7XFxyXFxuICAgICAgICAgICAgICAgIHR5cGU6IEJvb2xlYW4sXFxyXFxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRydWVcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIGlzUmVzaXphYmxlOiB7XFxyXFxuICAgICAgICAgICAgICAgIHR5cGU6IEJvb2xlYW4sXFxyXFxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRydWVcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIHVzZUNzc1RyYW5zZm9ybXM6IHtcXHJcXG4gICAgICAgICAgICAgICAgdHlwZTogQm9vbGVhbixcXHJcXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogdHJ1ZVxcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgdmVydGljYWxDb21wYWN0OiB7XFxyXFxuICAgICAgICAgICAgICAgIHR5cGU6IEJvb2xlYW4sXFxyXFxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRydWVcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIGxheW91dDoge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBBcnJheSxcXHJcXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWUsXFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgIH0sXFxyXFxuICAgICAgICBkYXRhOiBmdW5jdGlvbiAoKSB7XFxyXFxuICAgICAgICAgICAgcmV0dXJuIHtcXHJcXG4gICAgICAgICAgICAgICAgd2lkdGg6IG51bGwsXFxyXFxuICAgICAgICAgICAgICAgIG1lcmdlZFN0eWxlOiB7fSxcXHJcXG4gICAgICAgICAgICAgICAgbGFzdExheW91dExlbmd0aDogMCxcXHJcXG4gICAgICAgICAgICAgICAgaXNEcmFnZ2luZzogZmFsc2UsXFxyXFxuICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyOiB7XFxyXFxuICAgICAgICAgICAgICAgICAgICB4OiAwLFxcclxcbiAgICAgICAgICAgICAgICAgICAgeTogMCxcXHJcXG4gICAgICAgICAgICAgICAgICAgIHc6IDAsXFxyXFxuICAgICAgICAgICAgICAgICAgICBoOiAwLFxcclxcbiAgICAgICAgICAgICAgICAgICAgaTogMFxcclxcbiAgICAgICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIH07XFxyXFxuICAgICAgICB9LFxcclxcbiAgICAgICAgY3JlYXRlZCAoKSB7XFxyXFxuICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xcclxcblxcclxcbiAgICAgICAgICAgIC8vIEFjY2Vzc2libGUgcmVmZXJuY2VzIG9mIGZ1bmN0aW9ucyBmb3IgcmVtb3ZpbmcgaW4gYmVmb3JlRGVzdHJveVxcclxcbiAgICAgICAgICAgIHNlbGYucmVzaXplRXZlbnRIYW5kbGVyID0gZnVuY3Rpb24oZXZlbnRUeXBlLCBpLCB4LCB5LCBoLCB3KSB7XFxyXFxuICAgICAgICAgICAgICAgIHNlbGYucmVzaXplRXZlbnQoZXZlbnRUeXBlLCBpLCB4LCB5LCBoLCB3KTtcXHJcXG4gICAgICAgICAgICB9O1xcclxcblxcclxcbiAgICAgICAgICAgIHNlbGYuZHJhZ0V2ZW50SGFuZGxlciA9IGZ1bmN0aW9uKGV2ZW50VHlwZSwgaSwgeCwgeSwgaCwgdykge1xcclxcbiAgICAgICAgICAgICAgICBzZWxmLmRyYWdFdmVudChldmVudFR5cGUsIGksIHgsIHksIGgsIHcpO1xcclxcbiAgICAgICAgICAgIH07XFxyXFxuXFxyXFxuICAgICAgICAgICAgZXZlbnRCdXMuJG9uKCdyZXNpemVFdmVudCcsIHNlbGYucmVzaXplRXZlbnRIYW5kbGVyKTtcXHJcXG4gICAgICAgICAgICBldmVudEJ1cy4kb24oJ2RyYWdFdmVudCcsIHNlbGYuZHJhZ0V2ZW50SGFuZGxlcik7XFxyXFxuICAgICAgICB9LFxcclxcbiAgICAgICAgYmVmb3JlRGVzdHJveTogZnVuY3Rpb24oKXtcXHJcXG4gICAgICAgICAgICAvL1JlbW92ZSBsaXN0ZW5lcnNcXHJcXG4gICAgICAgICAgICBldmVudEJ1cy4kb2ZmKCdyZXNpemVFdmVudCcsIHNlbGYucmVzaXplRXZlbnRIYW5kbGVyKTtcXHJcXG4gICAgICAgICAgICBldmVudEJ1cy4kb2ZmKCdkcmFnRXZlbnQnLCBzZWxmLmRyYWdFdmVudEhhbmRsZXIpO1xcclxcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFxcXCJyZXNpemVcXFwiLCBzZWxmLm9uV2luZG93UmVzaXplKVxcclxcbiAgICAgICAgfSxcXHJcXG4gICAgICAgIG1vdW50ZWQ6IGZ1bmN0aW9uKCkge1xcclxcbiAgICAgICAgICAgIHRoaXMuJG5leHRUaWNrKGZ1bmN0aW9uICgpIHtcXHJcXG4gICAgICAgICAgICAgICAgdmFsaWRhdGVMYXlvdXQodGhpcy5sYXlvdXQpO1xcclxcbiAgICAgICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XFxyXFxuICAgICAgICAgICAgICAgIHRoaXMuJG5leHRUaWNrKGZ1bmN0aW9uKCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYud2lkdGggPT09IG51bGwpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLm9uV2luZG93UmVzaXplKCk7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgLy9zZWxmLndpZHRoID0gc2VsZi4kZWwub2Zmc2V0V2lkdGg7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIHNlbGYub25XaW5kb3dSZXNpemUpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgICAgICAgICAgY29tcGFjdChzZWxmLmxheW91dCwgc2VsZi52ZXJ0aWNhbENvbXBhY3QpO1xcclxcblxcclxcbiAgICAgICAgICAgICAgICAgICAgc2VsZi51cGRhdGVIZWlnaHQoKTtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuJG5leHRUaWNrKGZ1bmN0aW9uICgpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZXJkID0gZWxlbWVudFJlc2l6ZURldGVjdG9yTWFrZXIoe1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJhdGVneTogXFxcInNjcm9sbFxcXCIgLy88LSBGb3IgdWx0cmEgcGVyZm9ybWFuY2UuXFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgZXJkLmxpc3RlblRvKHNlbGYuJHJlZnMuaXRlbSwgZnVuY3Rpb24gKGVsZW1lbnQpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5vbldpbmRvd1Jlc2l6ZSgpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xcclxcbiAgICAgICAgICAgICAgICAgICAgfSk7XFxyXFxuICAgICAgICAgICAgICAgIH0pO1xcclxcbiAgICAgICAgICAgICAgICB3aW5kb3cub25sb2FkID0gZnVuY3Rpb24oKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi53aWR0aCA9PT0gbnVsbCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYub25XaW5kb3dSZXNpemUoKTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3NlbGYud2lkdGggPSBzZWxmLiRlbC5vZmZzZXRXaWR0aDtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgc2VsZi5vbldpbmRvd1Jlc2l6ZSk7XFxyXFxuICAgICAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgICAgICAgICBjb21wYWN0KHNlbGYubGF5b3V0LCBzZWxmLnZlcnRpY2FsQ29tcGFjdCk7XFxyXFxuXFxyXFxuICAgICAgICAgICAgICAgICAgICBzZWxmLnVwZGF0ZUhlaWdodCgpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgc2VsZi4kbmV4dFRpY2soZnVuY3Rpb24gKCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlcmQgPSBlbGVtZW50UmVzaXplRGV0ZWN0b3JNYWtlcih7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmF0ZWd5OiBcXFwic2Nyb2xsXFxcIiAvLzwtIEZvciB1bHRyYSBwZXJmb3JtYW5jZS5cXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBlcmQubGlzdGVuVG8oc2VsZi4kcmVmcy5pdGVtLCBmdW5jdGlvbiAoZWxlbWVudCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLm9uV2luZG93UmVzaXplKCk7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XFxyXFxuICAgICAgICAgICAgICAgICAgICB9KTtcXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgfTtcXHJcXG4gICAgICAgICAgICB9KTtcXHJcXG4gICAgICAgIH0sXFxyXFxuICAgICAgICB3YXRjaDoge1xcclxcbiAgICAgICAgICAgIHdpZHRoOiBmdW5jdGlvbiAoKSB7XFxyXFxuICAgICAgICAgICAgICAgIHRoaXMuJG5leHRUaWNrKGZ1bmN0aW9uICgpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIC8vdGhpcy4kYnJvYWRjYXN0KFxcXCJ1cGRhdGVXaWR0aFxcXCIsIHRoaXMud2lkdGgpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgZXZlbnRCdXMuJGVtaXQoXFxcInVwZGF0ZVdpZHRoXFxcIiwgdGhpcy53aWR0aCk7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUhlaWdodCgpO1xcclxcbiAgICAgICAgICAgICAgICB9KTtcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIGxheW91dDogZnVuY3Rpb24gKCkge1xcclxcbiAgICAgICAgICAgICAgICB0aGlzLmxheW91dFVwZGF0ZSgpO1xcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgcm93SGVpZ2h0OiBmdW5jdGlvbigpIHtcXHJcXG4gICAgICAgICAgICAgICAgZXZlbnRCdXMuJGVtaXQoXFxcInNldFJvd0hlaWdodFxcXCIsIHRoaXMucm93SGVpZ2h0KTtcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIGlzRHJhZ2dhYmxlOiBmdW5jdGlvbigpIHtcXHJcXG4gICAgICAgICAgICAgICAgZXZlbnRCdXMuJGVtaXQoXFxcInNldERyYWdnYWJsZVxcXCIsIHRoaXMuaXNEcmFnZ2FibGUpO1xcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgaXNSZXNpemFibGU6IGZ1bmN0aW9uKCkge1xcclxcbiAgICAgICAgICAgICAgICBldmVudEJ1cy4kZW1pdChcXFwic2V0UmVzaXphYmxlXFxcIiwgdGhpcy5pc1Jlc2l6YWJsZSk7XFxyXFxuICAgICAgICAgICAgfVxcclxcbiAgICAgICAgfSxcXHJcXG4gICAgICAgIG1ldGhvZHM6IHtcXHJcXG4gICAgICAgICAgICBsYXlvdXRVcGRhdGUoKSB7XFxyXFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmxheW91dCAhPT0gdW5kZWZpbmVkICYmIHRoaXMubGF5b3V0Lmxlbmd0aCAhPT0gdGhpcy5sYXN0TGF5b3V0TGVuZ3RoKSB7XFxyXFxuLy8gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxcXCIjIyMgTEFZT1VUIFVQREFURSFcXFwiKTtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubGFzdExheW91dExlbmd0aCA9IHRoaXMubGF5b3V0Lmxlbmd0aDtcXHJcXG4gICAgICAgICAgICAgICAgICAgIGNvbXBhY3QodGhpcy5sYXlvdXQsIHRoaXMudmVydGljYWxDb21wYWN0KTtcXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgICAgIC8vdGhpcy4kYnJvYWRjYXN0KFxcXCJ1cGRhdGVXaWR0aFxcXCIsIHRoaXMud2lkdGgpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgZXZlbnRCdXMuJGVtaXQoXFxcInVwZGF0ZVdpZHRoXFxcIiwgdGhpcy53aWR0aCk7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUhlaWdodCgpO1xcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICB1cGRhdGVIZWlnaHQ6IGZ1bmN0aW9uICgpIHtcXHJcXG4gICAgICAgICAgICAgICAgdGhpcy5tZXJnZWRTdHlsZSA9IHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIGhlaWdodDogdGhpcy5jb250YWluZXJIZWlnaHQoKVxcclxcbiAgICAgICAgICAgICAgICB9O1xcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgb25XaW5kb3dSZXNpemU6IGZ1bmN0aW9uICgpIHtcXHJcXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuJHJlZnMgIT09IG51bGwgJiYgdGhpcy4kcmVmcy5pdGVtICE9PSBudWxsKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLndpZHRoID0gdGhpcy4kcmVmcy5pdGVtLm9mZnNldFdpZHRoO1xcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICBjb250YWluZXJIZWlnaHQ6IGZ1bmN0aW9uICgpIHtcXHJcXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmF1dG9TaXplKSByZXR1cm47XFxyXFxuICAgICAgICAgICAgICAgIHJldHVybiBib3R0b20odGhpcy5sYXlvdXQpICogKHRoaXMucm93SGVpZ2h0ICsgdGhpcy5tYXJnaW5bMV0pICsgdGhpcy5tYXJnaW5bMV0gKyAncHgnO1xcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgZHJhZ0V2ZW50OiBmdW5jdGlvbiAoZXZlbnROYW1lLCBpZCwgeCwgeSwgaCwgdykge1xcclxcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnROYW1lID09IFxcXCJkcmFnbW92ZVxcXCIgfHwgZXZlbnROYW1lID09IFxcXCJkcmFnc3RhcnRcXFwiKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmlzRHJhZ2dpbmcgPSB0cnVlO1xcclxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbGFjZWhvbGRlci5pID0gaWQ7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsYWNlaG9sZGVyLnggPSB4O1xcclxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbGFjZWhvbGRlci55ID0geTtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGxhY2Vob2xkZXIudyA9IHc7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsYWNlaG9sZGVyLmggPSBoO1xcclxcbiAgICAgICAgICAgICAgICAgICAgLy90aGlzLiRicm9hZGNhc3QoXFxcInVwZGF0ZVdpZHRoXFxcIiwgdGhpcy53aWR0aCk7XFxyXFxuICAgICAgICAgICAgICAgICAgICBldmVudEJ1cy4kZW1pdChcXFwidXBkYXRlV2lkdGhcXFwiLCB0aGlzLndpZHRoKTtcXHJcXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaXNEcmFnZ2luZyA9IGZhbHNlO1xcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgICAgIC8vY29uc29sZS5sb2coZXZlbnROYW1lICsgXFxcIiBpZD1cXFwiICsgaWQgKyBcXFwiLCB4PVxcXCIgKyB4ICsgXFxcIiwgeT1cXFwiICsgeSk7XFxyXFxuICAgICAgICAgICAgICAgIHZhciBsID0gZ2V0TGF5b3V0SXRlbSh0aGlzLmxheW91dCwgaWQpO1xcclxcbiAgICAgICAgICAgICAgICBsLnggPSB4O1xcclxcbiAgICAgICAgICAgICAgICBsLnkgPSB5O1xcclxcbiAgICAgICAgICAgICAgICAvLyBNb3ZlIHRoZSBlbGVtZW50IHRvIHRoZSBkcmFnZ2VkIGxvY2F0aW9uLlxcclxcbiAgICAgICAgICAgICAgICB0aGlzLmxheW91dCA9IG1vdmVFbGVtZW50KHRoaXMubGF5b3V0LCBsLCB4LCB5LCB0cnVlKTtcXHJcXG4gICAgICAgICAgICAgICAgY29tcGFjdCh0aGlzLmxheW91dCwgdGhpcy52ZXJ0aWNhbENvbXBhY3QpO1xcclxcbiAgICAgICAgICAgICAgICAvLyBuZWVkZWQgYmVjYXVzZSB2dWUgY2FuJ3QgZGV0ZWN0IGNoYW5nZXMgb24gYXJyYXkgZWxlbWVudCBwcm9wZXJ0aWVzXFxyXFxuICAgICAgICAgICAgICAgIGV2ZW50QnVzLiRlbWl0KFxcXCJjb21wYWN0XFxcIik7XFxyXFxuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlSGVpZ2h0KCk7XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICByZXNpemVFdmVudDogZnVuY3Rpb24gKGV2ZW50TmFtZSwgaWQsIHgsIHksIGgsIHcpIHtcXHJcXG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50TmFtZSA9PSBcXFwicmVzaXplc3RhcnRcXFwiIHx8IGV2ZW50TmFtZSA9PSBcXFwicmVzaXplbW92ZVxcXCIpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaXNEcmFnZ2luZyA9IHRydWU7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsYWNlaG9sZGVyLmkgPSBpZDtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGxhY2Vob2xkZXIueCA9IHg7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsYWNlaG9sZGVyLnkgPSB5O1xcclxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbGFjZWhvbGRlci53ID0gdztcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGxhY2Vob2xkZXIuaCA9IGg7XFxyXFxuICAgICAgICAgICAgICAgICAgICAvL3RoaXMuJGJyb2FkY2FzdChcXFwidXBkYXRlV2lkdGhcXFwiLCB0aGlzLndpZHRoKTtcXHJcXG4gICAgICAgICAgICAgICAgICAgIGV2ZW50QnVzLiRlbWl0KFxcXCJ1cGRhdGVXaWR0aFxcXCIsIHRoaXMud2lkdGgpO1xcclxcblxcclxcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xcclxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0RyYWdnaW5nID0gZmFsc2U7XFxyXFxuICAgICAgICAgICAgICAgIH1cXHJcXG4gICAgICAgICAgICAgICAgdmFyIGwgPSBnZXRMYXlvdXRJdGVtKHRoaXMubGF5b3V0LCBpZCk7XFxyXFxuICAgICAgICAgICAgICAgIGwuaCA9IGg7XFxyXFxuICAgICAgICAgICAgICAgIGwudyA9IHc7XFxyXFxuICAgICAgICAgICAgICAgIGNvbXBhY3QodGhpcy5sYXlvdXQsIHRoaXMudmVydGljYWxDb21wYWN0KTtcXHJcXG4gICAgICAgICAgICAgICAgZXZlbnRCdXMuJGVtaXQoXFxcImNvbXBhY3RcXFwiKTtcXHJcXG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVIZWlnaHQoKTtcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgfSxcXHJcXG4gICAgfVxcclxcbjwvc2NyaXB0PlwiXSxcInNvdXJjZVJvb3RcIjpcIndlYnBhY2s6Ly9cIn1dKTtcblxuLy8gZXhwb3J0c1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2Nzcy1sb2FkZXI/c291cmNlTWFwIS4vfi92dWUtbG9hZGVyL2xpYi9zdHlsZS1yZXdyaXRlci5qcz9pZD1kYXRhLXYtNjZkNmQ4Y2IhLi9+L3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9zcmMvR3JpZExheW91dC52dWVcbi8vIG1vZHVsZSBpZCA9IDE4XG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0="); - -/***/ }, -/* 19 */ -/***/ function(module, exports, __webpack_require__) { - -eval("exports = module.exports = __webpack_require__(2)();\n// imports\n\n\n// module\nexports.push([module.i, \"\\n.vue-grid-layout {\\n position: relative;\\n transition: height 200ms ease;\\n}\\n\", \"\", {\"version\":3,\"sources\":[\"/./src/ResponsiveGridLayout.vue?bf6e6790\"],\"names\":[],\"mappings\":\";AAMA;IACA,mBAAA;IACA,8BAAA;CACA\",\"file\":\"ResponsiveGridLayout.vue\",\"sourcesContent\":[\"\\r\\n\\r\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\n// exports\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvUmVzcG9uc2l2ZUdyaWRMYXlvdXQudnVlPzg3NmIiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTs7O0FBR0E7QUFDQSw2Q0FBOEMseUJBQXlCLG9DQUFvQyxHQUFHLFVBQVUsMkZBQTJGLEtBQUssV0FBVyxXQUFXLDJPQUEyTywrQkFBK0IsMENBQTBDLFNBQVMsc0dBQXNHLG9CQUFvQiw0RkFBNEYsZ0JBQWdCLGdCQUFnQix3R0FBd0csMEJBQTBCLHlFQUF5RSxvRUFBb0Usc0NBQXNDLHFCQUFxQiwyQkFBMkIsb0ZBQW9GLDBCQUEwQixvSEFBb0gsNkJBQTZCLGtGQUFrRiwyQkFBMkIsdUZBQXVGLDhFQUE4RSwwRUFBMEUsaUJBQWlCLEVBQUUsaUJBQWlCLCtCQUErQixvRkFBb0YsK0JBQStCLG9GQUFvRixvQ0FBb0Msb0ZBQW9GLG1DQUFtQyxvRkFBb0Ysa0xBQWtMLHlIQUF5SCwyQkFBMkIsWUFBWSxRQUFRLG9DQUFvQyxvQ0FBb0MsOEdBQThHLFFBQVEsNkNBQTZDLGlCQUFpQiwwRkFBMEYsOEdBQThHLFFBQVEsc0NBQXNDLGlCQUFpQix1REFBdUQsK0JBQStCLHdCQUF3QiwwR0FBMEcsMkRBQTJELGFBQWEsdUNBQXVDLDBIQUEwSCx3QkFBd0IsNENBQTRDLGdEQUFnRCxvREFBb0Qsb0NBQW9DLGdEQUFnRCw4Q0FBOEMsNERBQTRELCtFQUErRSxtRUFBbUUsNENBQTRDLG1EQUFtRCxnREFBZ0Qsa0VBQWtFLDZHQUE2RyxFQUFFLDZFQUE2RSxzREFBc0Qsa0VBQWtFLG1FQUFtRSxrRkFBa0YsK0JBQStCLEVBQUUseUJBQXlCLEVBQUUscUJBQXFCLGlCQUFpQixFQUFFLGFBQWEscUJBQXFCLG1DQUFtQywyQ0FBMkMsd0RBQXdELHFCQUFxQixPQUFPLHdDQUF3QyxxQkFBcUIsK0NBQStDLG9GQUFvRix3Q0FBd0MsZ0VBQWdFLDBEQUEwRCx5QkFBeUIsRUFBRSw0Q0FBNEMsbUVBQW1FLHFCQUFxQixFQUFFLGlCQUFpQixxQ0FBcUMsb0dBQW9HLG1FQUFtRSxtRUFBbUUsMERBQTBELHVFQUF1RSx3Q0FBd0MsZ0VBQWdFLDBEQUEwRCx5QkFBeUIsRUFBRSxnREFBZ0QsMkJBQTJCLEVBQUUscUJBQXFCLGlCQUFpQixhQUFhLHVCQUF1Qiw0Q0FBNEMsMEVBQTBFLGlFQUFpRSxxQkFBcUIsaUJBQWlCLDJDQUEyQyx3Q0FBd0MsNEVBQTRFLGlCQUFpQiw4Q0FBOEMsK0NBQStDLDJHQUEyRyxpQkFBaUIsMkRBQTJELG9DQUFvQywyRkFBMkYsMkRBQTJELDBJQUEwSSwrREFBK0QsMEpBQTBKLDREQUE0RCxtREFBbUQscUJBQXFCLEVBQUUsNENBQTRDLGlCQUFpQiw2REFBNkQsb0NBQW9DLHlFQUF5RSw0QkFBNEIsc0JBQXNCLCtEQUErRCwrSEFBK0gsZ0VBQWdFLDREQUE0RCxtREFBbUQscUJBQXFCLEVBQUUsNENBQTRDLGlCQUFpQixjQUFjLHdCQUF3QixhQUFhLFdBQVcsMENBQTBDOztBQUVoelEiLCJmaWxlIjoiMTkuanMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikoKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIlxcbi52dWUtZ3JpZC1sYXlvdXQge1xcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XFxuICAgIHRyYW5zaXRpb246IGhlaWdodCAyMDBtcyBlYXNlO1xcbn1cXG5cIiwgXCJcIiwge1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wiLy4vc3JjL1Jlc3BvbnNpdmVHcmlkTGF5b3V0LnZ1ZT9iZjZlNjc5MFwiXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiO0FBTUE7SUFDQSxtQkFBQTtJQUNBLDhCQUFBO0NBQ0FcIixcImZpbGVcIjpcIlJlc3BvbnNpdmVHcmlkTGF5b3V0LnZ1ZVwiLFwic291cmNlc0NvbnRlbnRcIjpbXCI8dGVtcGxhdGU+XFxyXFxuICAgIDxkaXYgcmVmPVxcXCJpdGVtXFxcIiBjbGFzcz1cXFwidnVlLWdyaWQtbGF5b3V0XFxcIiA6c3R5bGU9XFxcIm1lcmdlZFN0eWxlXFxcIj5cXHJcXG4gICAgICAgIDxzbG90Pjwvc2xvdD5cXHJcXG4gICAgPC9kaXY+XFxyXFxuPC90ZW1wbGF0ZT5cXHJcXG48c3R5bGU+XFxyXFxuICAgIC52dWUtZ3JpZC1sYXlvdXQge1xcclxcbiAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xcclxcbiAgICAgICAgdHJhbnNpdGlvbjogaGVpZ2h0IDIwMG1zIGVhc2U7XFxyXFxuICAgIH1cXHJcXG48L3N0eWxlPlxcclxcbjxzY3JpcHQ+XFxyXFxuICAgIHZhciBlbGVtZW50UmVzaXplRGV0ZWN0b3JNYWtlciA9IHJlcXVpcmUoXFxcImVsZW1lbnQtcmVzaXplLWRldGVjdG9yXFxcIik7XFxyXFxuXFxyXFxuICAgIGltcG9ydCB7Ym90dG9tLCBjb21wYWN0LCBnZXRMYXlvdXRJdGVtLCBtb3ZlRWxlbWVudCwgdmFsaWRhdGVMYXlvdXQsIGZpbmRJdGVtSW5BcnJheSwgZmluZEFuZFJlbW92ZX0gZnJvbSAnLi91dGlscyc7XFxyXFxuICAgIGltcG9ydCB7Z2V0QnJlYWtwb2ludEZyb21XaWR0aCwgZ2V0Q29sc0Zyb21CcmVha3BvaW50LCBmaW5kT3JHZW5lcmF0ZVJlc3BvbnNpdmVMYXlvdXQsIGdlbmVyYXRlUmVzcG9uc2l2ZUxheW91dH0gZnJvbSAnLi9yZXNwb25zaXZlVXRpbHMnO1xcclxcbiAgICBpbXBvcnQgR3JpZEl0ZW0gZnJvbSAnLi9HcmlkSXRlbS52dWUnXFxyXFxuXFxyXFxuICAgIGV4cG9ydCBkZWZhdWx0IHtcXHJcXG4gICAgICAgIG5hbWU6IFxcXCJSZXNwb25zaXZlR3JpZExheW91dFxcXCIsXFxyXFxuICAgICAgICBjb21wb25lbnRzOiB7XFxyXFxuICAgICAgICAgICAgR3JpZEl0ZW0sXFxyXFxuICAgICAgICB9LFxcclxcbiAgICAgICAgcHJvcHM6IHtcXHJcXG4gICAgICAgICAgICBhdXRvU2l6ZToge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBCb29sZWFuLFxcclxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiB0cnVlXFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICBjb2xOdW06IHtcXHJcXG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxcclxcbiAgICAgICAgICAgICAgICByZXF1aXJlZDogZmFsc2UsXFxyXFxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IDBcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIHJvd0hlaWdodDoge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXFxyXFxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IDE1MFxcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgbWF4Um93czoge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXFxyXFxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IEluZmluaXR5XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICAvLyBNYXJnaW4gYmV0d2VlbiBpdGVtcyBbeCwgeV0gaW4gcHhcXHJcXG4gICAgICAgICAgICBtYXJnaW46IHtcXHJcXG4gICAgICAgICAgICAgICAgdHlwZTogQXJyYXksXFxyXFxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIFsxMCwgMTBdOyB9XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICBpc0RyYWdnYWJsZToge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBCb29sZWFuLFxcclxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiB0cnVlXFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICBpc1Jlc2l6YWJsZToge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBCb29sZWFuLFxcclxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiB0cnVlXFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICB1c2VDc3NUcmFuc2Zvcm1zOiB7XFxyXFxuICAgICAgICAgICAgICAgIHR5cGU6IEJvb2xlYW4sXFxyXFxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRydWVcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIHZlcnRpY2FsQ29tcGFjdDoge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBCb29sZWFuLFxcclxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiB0cnVlXFxyXFxuICAgICAgICAgICAgfSxcXHJcXG5cXHJcXG4gICAgICAgICAgICAvLyBPcHRpb25hbCwgYnV0IGlmIHlvdSBhcmUgbWFuYWdpbmcgd2lkdGggeW91cnNlbGYgeW91IG1heSB3YW50IHRvIHNldCB0aGUgYnJlYWtwb2ludFxcclxcbiAgICAgICAgICAgIC8vIHlvdXJzZWxmIGFzIHdlbGwuXFxyXFxuLypcXHJcXG4gICAgICAgICAgICBicmVha3BvaW50OiB7XFxyXFxuICAgICAgICAgICAgICAgIHR5cGU6IFN0cmluZyxcXHJcXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IGZhbHNlLFxcclxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiBcXFwibGdcXFwiXFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4qL1xcclxcbiAgICAgICAgICAgIC8vIHtuYW1lOiBweFZhbH0sIGUuZy4ge2xnOiAxMjAwLCBtZDogOTk2LCBzbTogNzY4LCB4czogNDgwfVxcclxcbi8qXFxyXFxuICAgICAgICAgICAgYnJlYWtwb2ludHM6IHtcXHJcXG4gICAgICAgICAgICAgICAgdHlwZTogT2JqZWN0LFxcclxcbiAgICAgICAgICAgICAgICByZXF1aXJlZDogZmFsc2UsXFxyXFxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IGZ1bmN0aW9uKCkge3JldHVybiB7bGc6IDEyMDAsIG1kOiA5OTYsIHNtOiA3NjgsIHhzOiA0ODAsIHh4czogMH19XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG5cXHJcXG4gICAgICAgICAgICAvLyAjIG9mIGNvbHMuIFRoaXMgaXMgYSBicmVha3BvaW50IC0+IGNvbHMgbWFwXFxyXFxuICAgICAgICAgICAgY29sczoge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBPYmplY3QsXFxyXFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcXHJcXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogZnVuY3Rpb24oKSB7cmV0dXJuIHtsZzogMTIsIG1kOiAxMCwgc206IDYsIHhzOiA0LCB4eHM6IDJ9fVxcclxcbiAgICAgICAgICAgIH0sXFxyXFxuKi9cXHJcXG5cXHJcXG4gICAgICAgICAgICBsYXlvdXQ6IFtdLFxcclxcblxcclxcbiAgICAgICAgfSxcXHJcXG4gICAgICAgIGRhdGE6IGZ1bmN0aW9uKCkge1xcclxcbiAgICAgICAgICAgIHJldHVybiB7XFxyXFxuICAgICAgICAgICAgICAgIG9yaWdpbmFsQ29sczogbnVsbCxcXHJcXG4gICAgICAgICAgICAgICAgd2lkdGg6IG51bGwsXFxyXFxuICAgICAgICAgICAgICAgIG1lcmdlZFN0eWxlOiB7fSxcXHJcXG4gICAgICAgICAgICAgICAgbGFzdExheW91dExlbmd0aDogMCxcXHJcXG4gICAgICAgICAgICB9O1xcclxcbiAgICAgICAgfSxcXHJcXG4gICAgICAgIGJlZm9yZURlc3Ryb3k6IGZ1bmN0aW9uKCl7XFxyXFxuICAgICAgICAgICAgLy9SZW1vdmUgbGlzdGVuZXJzXFxyXFxuICAgICAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXFxcInJlc2l6ZVxcXCIsIHNlbGYub25XaW5kb3dSZXNpemUpXFxyXFxuICAgICAgICB9LFxcclxcbiAgICAgICAgbW91bnRlZCgpIHtcXHJcXG4gICAgICAgICAgICB0aGlzLiRuZXh0VGljayhmdW5jdGlvbiAoKSB7XFxyXFxuICAgICAgICAgICAgICAgIHZhbGlkYXRlTGF5b3V0KHRoaXMubGF5b3V0KTtcXHJcXG4gICAgICAgICAgICAgICAgdGhpcy5vcmlnaW5hbENvbHMgPSB0aGlzLmNvbE51bTtcXHJcXG4gICAgICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xcclxcbiAgICAgICAgICAgICAgICB3aW5kb3cub25sb2FkID0gZnVuY3Rpb24oKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICBzZWxmLm9uV2luZG93UmVzaXplKCk7XFxyXFxuICAgICAgICAgICAgICAgICAgICAvL3NlbGYud2lkdGggPSBzZWxmLiRlbC5vZmZzZXRXaWR0aDtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCBzZWxmLm9uV2luZG93UmVzaXplKTtcXHJcXG4gICAgICAgICAgICAgICAgICAgIGNvbXBhY3Qoc2VsZi5sYXlvdXQsIHNlbGYudmVydGljYWxDb21wYWN0KTtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHNlbGYudXBkYXRlSGVpZ2h0KCk7XFxyXFxuICAgICAgICAgICAgICAgICAgICBzZWxmLiRuZXh0VGljayhmdW5jdGlvbigpIHtcXHJcXG4vLyAgICAgICAgICAgICAgICAgICAgc2VsZi5vbldpbmRvd1Jlc2l6ZSgpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlcmQgPSBlbGVtZW50UmVzaXplRGV0ZWN0b3JNYWtlcih7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmF0ZWd5OiBcXFwic2Nyb2xsXFxcIiAvLzwtIEZvciB1bHRyYSBwZXJmb3JtYW5jZS5cXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBlcmQubGlzdGVuVG8oc2VsZi4kcmVmcy5pdGVtLCBmdW5jdGlvbihlbGVtZW50KSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYub25XaW5kb3dSZXNpemUoKTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLyp2YXIgd2lkdGggPSBlbGVtZW50Lm9mZnNldFdpZHRoO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhlaWdodCA9IGVsZW1lbnQub2Zmc2V0SGVpZ2h0O1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXFxcIlNpemU6IFxcXCIgKyB3aWR0aCArIFxcXCJ4XFxcIiArIGhlaWdodCk7Ki9cXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcXHJcXG4gICAgICAgICAgICAgICAgICAgIH0pO1xcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgfSk7XFxyXFxuICAgICAgICB9LFxcclxcbiAgICAgICAgd2F0Y2g6IHtcXHJcXG4gICAgICAgICAgICB3aWR0aDogZnVuY3Rpb24oKSB7XFxyXFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLndpZHRoID4gNzY4KSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbE51bSA9IHRoaXMub3JpZ2luYWxDb2xzO1xcclxcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xcclxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb2xOdW0gPSAyO1xcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgICAgIHRoaXMuJG5leHRUaWNrKGZ1bmN0aW9uKCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgLy90aGlzLiRicm9hZGNhc3QoXFxcInVwZGF0ZVdpZHRoXFxcIiwgdGhpcy53aWR0aCwgdGhpcy5jb2xOdW0pO1xcclxcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xcclxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy4kY2hpbGRyZW4uZm9yRWFjaChmdW5jdGlvbihjaGlsZCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLnVwZGF0ZVdpZHRoKHNlbGYud2lkdGgpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgfSk7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUhlaWdodCgpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgY29tcGFjdCh0aGlzLmxheW91dCwgdGhpcy52ZXJ0aWNhbENvbXBhY3QpO1xcclxcbiAgICAgICAgICAgICAgICB9KTtcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIGxheW91dDogZnVuY3Rpb24oKSB7XFxyXFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmxheW91dCAhPT0gdW5kZWZpbmVkICYmIHRoaXMubGF5b3V0Lmxlbmd0aCAhPT0gdGhpcy5sYXN0TGF5b3V0TGVuZ3RoKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmxhc3RMYXlvdXRMZW5ndGggPSB0aGlzLmxheW91dC5sZW5ndGg7XFxyXFxuICAgICAgICAgICAgICAgICAgICBjb21wYWN0KHRoaXMubGF5b3V0LCB0aGlzLnZlcnRpY2FsQ29tcGFjdCk7XFxyXFxuXFxyXFxuICAgICAgICAgICAgICAgICAgICAvL3RoaXMuJG5leHRUaWNrKGZ1bmN0aW9uICgpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIC8vdGhpcy4kYnJvYWRjYXN0KFxcXCJ1cGRhdGVXaWR0aFxcXCIsIHRoaXMud2lkdGgpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xcclxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy4kY2hpbGRyZW4uZm9yRWFjaChmdW5jdGlvbihjaGlsZCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLnVwZGF0ZVdpZHRoKHNlbGYud2lkdGgpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgfSk7XFxyXFxuXFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUhlaWdodCgpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgLy99KTtcXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgIH1cXHJcXG4gICAgICAgIH0sXFxyXFxuICAgICAgICBtZXRob2RzOiB7XFxyXFxuICAgICAgICAgICAgb25XaW5kb3dSZXNpemU6IGZ1bmN0aW9uKCkge1xcclxcbiAgICAgICAgICAgICAgICBpZiAodGhpcy4kcmVmcyAhPT0gbnVsbCAmJiB0aGlzLiRyZWZzLml0ZW0gIT09IG51bGwpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMud2lkdGggPSB0aGlzLiRyZWZzLml0ZW0ub2Zmc2V0V2lkdGg7XFxyXFxuICAgICAgICAgICAgICAgIH1cXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIHVwZGF0ZUhlaWdodDogZnVuY3Rpb24oKSB7XFxyXFxuICAgICAgICAgICAgICAgIHRoaXMubWVyZ2VkU3R5bGUgPSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IHRoaXMuY29udGFpbmVySGVpZ2h0KClcXHJcXG4gICAgICAgICAgICAgICAgfTtcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIGNvbnRhaW5lckhlaWdodDogZnVuY3Rpb24oKSB7XFxyXFxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5hdXRvU2l6ZSkgcmV0dXJuO1xcclxcbiAgICAgICAgICAgICAgICByZXR1cm4gYm90dG9tKHRoaXMubGF5b3V0KSAqICh0aGlzLnJvd0hlaWdodCArIHRoaXMubWFyZ2luWzFdKSArIHRoaXMubWFyZ2luWzFdICsgJ3B4JztcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIGRyYWdFdmVudDogZnVuY3Rpb24oZXZlbnROYW1lLCBpZCwgeCwgeSkge1xcclxcbiAgICAgICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XFxyXFxuLy8gICAgICAgICAgICAgICAgY29uc29sZS5sb2coZXZlbnROYW1lICsgXFxcIiBpZD1cXFwiICsgaWQgKyBcXFwiLCB4PVxcXCIgKyB4ICsgXFxcIiwgeT1cXFwiICsgeSk7XFxyXFxuICAgICAgICAgICAgICAgIHZhciBsID0gZ2V0TGF5b3V0SXRlbSh0aGlzLmxheW91dCwgaWQpO1xcclxcbiAgICAgICAgICAgICAgICAvLyBNb3ZlIHRoZSBlbGVtZW50IHRvIHRoZSBkcmFnZ2VkIGxvY2F0aW9uLlxcclxcbiAgICAgICAgICAgICAgICB0aGlzLmxheW91dCA9IG1vdmVFbGVtZW50KHRoaXMubGF5b3V0LCBsLCB4LCB5LCB0cnVlKTtcXHJcXG4gICAgICAgICAgICAgICAgY29tcGFjdCh0aGlzLmxheW91dCwgdGhpcy52ZXJ0aWNhbENvbXBhY3QpO1xcclxcbiAgICAgICAgICAgICAgICAvLyBuZWVkZWQgYmVjYXVzZSB2dWUgY2FuJ3QgZGV0ZWN0IGNoYW5nZXMgb24gYXJyYXkgZWxlbWVudCBwcm9wZXJ0aWVzXFxyXFxuICAgICAgICAgICAgICAgIC8vdGhpcy4kYnJvYWRjYXN0KFxcXCJjb21wYWN0XFxcIiwgdGhpcy5sYXlvdXQpO1xcclxcbiAgICAgICAgICAgICAgICB0aGlzLiRjaGlsZHJlbi5mb3JFYWNoKGZ1bmN0aW9uKGNoaWxkKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICBjaGlsZC5jb21wYWN0KHNlbGYubGF5b3V0KTtcXHJcXG4gICAgICAgICAgICAgICAgfSk7XFxyXFxuXFxyXFxuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlSGVpZ2h0KCk7XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICByZXNpemVFdmVudDogZnVuY3Rpb24oZXZlbnROYW1lLCBpZCwgaCwgdykge1xcclxcbiAgICAgICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XFxyXFxuICAgICAgICAgICAgICAgIC8qaWYgKGV2ZW50TmFtZSA9PT0gXFxcImRyYWdcXFwiICYmIGggPCAtNDAgJiYgdyA8IC00MCkge1xcclxcbiAgICAgICAgICAgICAgICAgcmV0dXJuO1xcclxcbiAgICAgICAgICAgICAgICAgfSovXFxyXFxuLy8gICAgICAgICAgICAgICAgY29uc29sZS5sb2coZXZlbnROYW1lICsgXFxcIiBpZD1cXFwiICsgaWQpO1xcclxcbiAgICAgICAgICAgICAgICAvLyBNb3ZlIHRoZSBlbGVtZW50IHRvIHRoZSBkcmFnZ2VkIGxvY2F0aW9uLlxcclxcbiAgICAgICAgICAgICAgICBjb21wYWN0KHRoaXMubGF5b3V0LCB0aGlzLnZlcnRpY2FsQ29tcGFjdCk7XFxyXFxuICAgICAgICAgICAgICAgIC8vdGhpcy4kYnJvYWRjYXN0KFxcXCJjb21wYWN0XFxcIiwgdGhpcy5sYXlvdXQpO1xcclxcbiAgICAgICAgICAgICAgICB0aGlzLiRjaGlsZHJlbi5mb3JFYWNoKGZ1bmN0aW9uKGNoaWxkKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICBjaGlsZC5jb21wYWN0KHNlbGYubGF5b3V0KTtcXHJcXG4gICAgICAgICAgICAgICAgfSk7XFxyXFxuXFxyXFxuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlSGVpZ2h0KCk7XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgIH0sXFxyXFxuICAgICAgICAvKmV2ZW50czoge1xcclxcbiAgICAgICAgfSovXFxyXFxuICAgIH1cXHJcXG48L3NjcmlwdD5cIl0sXCJzb3VyY2VSb290XCI6XCJ3ZWJwYWNrOi8vXCJ9XSk7XG5cbi8vIGV4cG9ydHNcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL34vdnVlLWxvYWRlci9saWIvc3R5bGUtcmV3cml0ZXIuanM/aWQ9ZGF0YS12LTZkMGQyZmRmIS4vfi92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vc3JjL1Jlc3BvbnNpdmVHcmlkTGF5b3V0LnZ1ZVxuLy8gbW9kdWxlIGlkID0gMTlcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sInNvdXJjZVJvb3QiOiIifQ=="); - -/***/ }, -/* 20 */ -/***/ function(module, exports, __webpack_require__) { - -eval("exports = module.exports = __webpack_require__(2)();\n// imports\n\n\n// module\nexports.push([module.i, \"\\n.vue-grid-item {\\n transition: all 200ms ease;\\n transition-property: left, top, right;\\n /* add right for rtl */\\n}\\n.vue-grid-item.cssTransforms {\\n transition-property: transform;\\n}\\n.vue-grid-item.resizing {\\n opacity: 0.6;\\n z-index: 3;\\n}\\n.vue-grid-item.vue-draggable-dragging {\\n /*transition:none;*/\\n z-index: 3;\\n}\\n.vue-grid-item.vue-grid-placeholder {\\n background: red;\\n opacity: 0.2;\\n transition-duration: 100ms;\\n z-index: 2;\\n -webkit-user-select: none;\\n -moz-user-select: none;\\n -ms-user-select: none;\\n -o-user-select: none;\\n user-select: none;\\n}\\n.vue-grid-item > .vue-resizable-handle {\\n position: absolute;\\n width: 20px;\\n height: 20px;\\n bottom: 0;\\n right: 0;\\n background: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pg08IS0tIEdlbmVyYXRvcjogQWRvYmUgRmlyZXdvcmtzIENTNiwgRXhwb3J0IFNWRyBFeHRlbnNpb24gYnkgQWFyb24gQmVhbGwgKGh0dHA6Ly9maXJld29ya3MuYWJlYWxsLmNvbSkgLiBWZXJzaW9uOiAwLjYuMSAgLS0+DTwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DTxzdmcgaWQ9IlVudGl0bGVkLVBhZ2UlMjAxIiB2aWV3Qm94PSIwIDAgNiA2IiBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjojZmZmZmZmMDAiIHZlcnNpb249IjEuMSINCXhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbDpzcGFjZT0icHJlc2VydmUiDQl4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjZweCIgaGVpZ2h0PSI2cHgiDT4NCTxnIG9wYWNpdHk9IjAuMzAyIj4NCQk8cGF0aCBkPSJNIDYgNiBMIDAgNiBMIDAgNC4yIEwgNCA0LjIgTCA0LjIgNC4yIEwgNC4yIDAgTCA2IDAgTCA2IDYgTCA2IDYgWiIgZmlsbD0iIzAwMDAwMCIvPg0JPC9nPg08L3N2Zz4=');\\n background-position: bottom right;\\n padding: 0 3px 3px 0;\\n background-repeat: no-repeat;\\n background-origin: content-box;\\n box-sizing: border-box;\\n cursor: se-resize;\\n}\\n.vue-grid-item > .vue-rtl-resizable-handle {\\n bottom: 0;\\n left: 0;\\n background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAuMDAwMDAwMDAwMDAwMDAyIiBoZWlnaHQ9IjEwLjAwMDAwMDAwMDAwMDAwMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KIDwhLS0gQ3JlYXRlZCB3aXRoIE1ldGhvZCBEcmF3IC0gaHR0cDovL2dpdGh1Yi5jb20vZHVvcGl4ZWwvTWV0aG9kLURyYXcvIC0tPgogPGc+CiAgPHRpdGxlPmJhY2tncm91bmQ8L3RpdGxlPgogIDxyZWN0IGZpbGw9Im5vbmUiIGlkPSJjYW52YXNfYmFja2dyb3VuZCIgaGVpZ2h0PSIxMiIgd2lkdGg9IjEyIiB5PSItMSIgeD0iLTEiLz4KICA8ZyBkaXNwbGF5PSJub25lIiBvdmVyZmxvdz0idmlzaWJsZSIgeT0iMCIgeD0iMCIgaGVpZ2h0PSIxMDAlIiB3aWR0aD0iMTAwJSIgaWQ9ImNhbnZhc0dyaWQiPgogICA8cmVjdCBmaWxsPSJ1cmwoI2dyaWRwYXR0ZXJuKSIgc3Ryb2tlLXdpZHRoPSIwIiB5PSIwIiB4PSIwIiBoZWlnaHQ9IjEwMCUiIHdpZHRoPSIxMDAlIi8+CiAgPC9nPgogPC9nPgogPGc+CiAgPHRpdGxlPkxheWVyIDE8L3RpdGxlPgogIDxsaW5lIGNhbnZhcz0iI2ZmZmZmZiIgY2FudmFzLW9wYWNpdHk9IjEiIHN0cm9rZS1saW5lY2FwPSJ1bmRlZmluZWQiIHN0cm9rZS1saW5lam9pbj0idW5kZWZpbmVkIiBpZD0ic3ZnXzEiIHkyPSItNzAuMTc4NDA3IiB4Mj0iMTI0LjQ2NDE3NSIgeTE9Ii0zOC4zOTI3MzciIHgxPSIxNDQuODIxMjg5IiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlPSIjMDAwIiBmaWxsPSJub25lIi8+CiAgPGxpbmUgc3Ryb2tlPSIjNjY2NjY2IiBzdHJva2UtbGluZWNhcD0idW5kZWZpbmVkIiBzdHJva2UtbGluZWpvaW49InVuZGVmaW5lZCIgaWQ9InN2Z181IiB5Mj0iOS4xMDY5NTciIHgyPSIwLjk0NzI0NyIgeTE9Ii0wLjAxODEyOCIgeDE9IjAuOTQ3MjQ3IiBzdHJva2Utd2lkdGg9IjIiIGZpbGw9Im5vbmUiLz4KICA8bGluZSBzdHJva2UtbGluZWNhcD0idW5kZWZpbmVkIiBzdHJva2UtbGluZWpvaW49InVuZGVmaW5lZCIgaWQ9InN2Z183IiB5Mj0iOSIgeDI9IjEwLjA3MzUyOSIgeTE9IjkiIHgxPSItMC42NTU2NCIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2U9IiM2NjY2NjYiIGZpbGw9Im5vbmUiLz4KIDwvZz4KPC9zdmc+);\\n background-position: bottom left;\\n padding-left: 3px;\\n background-repeat: no-repeat;\\n background-origin: content-box;\\n cursor: sw-resize;\\n right: auto;\\n}\\n\", \"\", {\"version\":3,\"sources\":[\"/./src/GridItem.vue?e2a14cb2\"],\"names\":[],\"mappings\":\";AAWA;IACA,2BAAA;IACA,sCAAA;IACA,uBAAA;CACA;AACA;IACA,+BAAA;CACA;AACA;IACA,aAAA;IACA,WAAA;CACA;AAEA;IACA,oBAAA;IACA,WAAA;CACA;AAEA;IACA,gBAAA;IACA,aAAA;IACA,2BAAA;IACA,WAAA;IACA,0BAAA;IACA,uBAAA;IACA,sBAAA;IACA,qBAAA;IACA,kBAAA;CACA;AAEA;IACA,mBAAA;IACA,YAAA;IACA,aAAA;IACA,UAAA;IACA,SAAA;IACA,s3BAAA;IACA,kCAAA;IACA,qBAAA;IACA,6BAAA;IACA,+BAAA;IACA,uBAAA;IACA,kBAAA;CACA;AAEA;IACA,UAAA;IACA,QAAA;IACA,g+CAAA;IACA,iCAAA;IACA,kBAAA;IACA,6BAAA;IACA,+BAAA;IACA,kBAAA;IACA,YAAA;CACA\",\"file\":\"GridItem.vue\",\"sourcesContent\":[\"\\r\\n\\r\\n\\r\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\n// exports\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvR3JpZEl0ZW0udnVlP2VlYzIiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTs7O0FBR0E7QUFDQSwyQ0FBNEMsaUNBQWlDLDRDQUE0QyxnQ0FBZ0MsZ0NBQWdDLHFDQUFxQyxHQUFHLDJCQUEyQixtQkFBbUIsaUJBQWlCLEdBQUcseUNBQXlDLHdCQUF3QixtQkFBbUIsR0FBRyx1Q0FBdUMsc0JBQXNCLG1CQUFtQixpQ0FBaUMsaUJBQWlCLGdDQUFnQyw2QkFBNkIsNEJBQTRCLDJCQUEyQix3QkFBd0IsR0FBRywwQ0FBMEMseUJBQXlCLGtCQUFrQixtQkFBbUIsZ0JBQWdCLGVBQWUsMENBQTBDLGsxQkFBazFCLHdDQUF3QywyQkFBMkIsbUNBQW1DLHFDQUFxQyw2QkFBNkIsd0JBQXdCLEdBQUcsOENBQThDLGdCQUFnQixjQUFjLHlDQUF5Qyw2N0NBQTY3Qyx1Q0FBdUMsd0JBQXdCLG1DQUFtQyxxQ0FBcUMsd0JBQXdCLGtCQUFrQixHQUFHLFVBQVUsK0VBQStFLEtBQUssV0FBVyxXQUFXLFdBQVcsS0FBSyxLQUFLLFdBQVcsS0FBSyxLQUFLLFVBQVUsVUFBVSxLQUFLLEtBQUssV0FBVyxVQUFVLEtBQUssS0FBSyxXQUFXLFVBQVUsV0FBVyxVQUFVLFdBQVcsV0FBVyxXQUFXLFdBQVcsV0FBVyxLQUFLLEtBQUssV0FBVyxVQUFVLFVBQVUsVUFBVSxVQUFVLFlBQVksV0FBVyxXQUFXLFdBQVcsV0FBVyxXQUFXLFdBQVcsS0FBSyxLQUFLLFVBQVUsVUFBVSxZQUFZLFdBQVcsV0FBVyxXQUFXLFdBQVcsV0FBVyxVQUFVLHFKQUFxSixvSUFBb0ksc09BQXNPLHVDQUF1QyxrREFBa0QsNENBQTRDLHNDQUFzQywyQ0FBMkMsU0FBUyxpQ0FBaUMseUJBQXlCLHVCQUF1QixTQUFTLG1EQUFtRCw4QkFBOEIseUJBQXlCLFNBQVMsaURBQWlELDRCQUE0Qix5QkFBeUIsdUNBQXVDLHVCQUF1QixzQ0FBc0MsbUNBQW1DLGtDQUFr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QUFxQixvR0FBb0csaUJBQWlCLHFEQUFxRCx5REFBeUQseUVBQXlFLG1DQUFtQyxxUkFBcVIsZ2JBQWdiLHFCQUFxQixPQUFPLG1DQUFtQyxvUkFBb1IsZ2JBQWdiLHFCQUFxQix1Q0FBdUMsaUJBQWlCLDJIQUEySCxPQUFPLDhFQUE4RSxPQUFPLCtFQUErRSxPQUFPLGlLQUFpSyx5REFBeUQscWFBQXFhLG1HQUFtRyx1R0FBdUcsd0VBQXdFLGdDQUFnQyxNQUFNLGlCQUFpQixzRkFBc0YsMEdBQTBHLDBGQUEwRixvQ0FBb0MsaUJBQWlCLHNJQUFzSSxPQUFPLHFEQUFxRCxPQUFPLG9EQUFvRCxPQUFPLDhFQUE4RSx5REFBeUQsOFBBQThQLHNHQUFzRyx1R0FBdUcsd0VBQXdFLDRCQUE0QixNQUFNLGlCQUFpQix1REFBdUQsZ0RBQWdELGtFQUFrRSwyQ0FBMkMscUJBQXFCLGlCQUFpQixzQ0FBc0MsdUNBQXVDLGlCQUFpQixhQUFhLFVBQVUsOENBQThDOztBQUUvOS9CIiwiZmlsZSI6IjIwLmpzIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvbGliL2Nzcy1iYXNlLmpzXCIpKCk7XG4vLyBpbXBvcnRzXG5cblxuLy8gbW9kdWxlXG5leHBvcnRzLnB1c2goW21vZHVsZS5pZCwgXCJcXG4udnVlLWdyaWQtaXRlbSB7XFxuICAgIHRyYW5zaXRpb246IGFsbCAyMDBtcyBlYXNlO1xcbiAgICB0cmFuc2l0aW9uLXByb3BlcnR5OiBsZWZ0LCB0b3AsIHJpZ2h0O1xcbiAgICAvKiBhZGQgcmlnaHQgZm9yIHJ0bCAqL1xcbn1cXG4udnVlLWdyaWQtaXRlbS5jc3NUcmFuc2Zvcm1zIHtcXG4gICAgdHJhbnNpdGlvbi1wcm9wZXJ0eTogdHJhbnNmb3JtO1xcbn1cXG4udnVlLWdyaWQtaXRlbS5yZXNpemluZyB7XFxuICAgIG9wYWNpdHk6IDAuNjtcXG4gICAgei1pbmRleDogMztcXG59XFxuLnZ1ZS1ncmlkLWl0ZW0udnVlLWRyYWdnYWJsZS1kcmFnZ2luZyB7XFxuICAgIC8qdHJhbnNpdGlvbjpub25lOyovXFxuICAgIHotaW5kZXg6IDM7XFxufVxcbi52dWUtZ3JpZC1pdGVtLnZ1ZS1ncmlkLXBsYWNlaG9sZGVyIHtcXG4gICAgYmFja2dyb3VuZDogcmVkO1xcbiAgICBvcGFjaXR5OiAwLjI7XFxuICAgIHRyYW5zaXRpb24tZHVyYXRpb246IDEwMG1zO1xcbiAgICB6LWluZGV4OiAyO1xcbiAgICAtd2Via2l0LXVzZXItc2VsZWN0OiBub25lO1xcbiAgICAtbW96LXVzZXItc2VsZWN0OiBub25lO1xcbiAgICAtbXMtdXNlci1zZWxlY3Q6IG5vbmU7XFxuICAgIC1vLXVzZXItc2VsZWN0OiBub25lO1xcbiAgICB1c2VyLXNlbGVjdDogbm9uZTtcXG59XFxuLnZ1ZS1ncmlkLWl0ZW0gPiAudnVlLXJlc2l6YWJsZS1oYW5kbGUge1xcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XFxuICAgIHdpZHRoOiAyMHB4O1xcbiAgICBoZWlnaHQ6IDIwcHg7XFxuICAgIGJvdHRvbTogMDtcXG4gICAgcmlnaHQ6IDA7XFxuICAgIGJhY2tncm91bmQ6IHVybCgnZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxQRDk0Yld3Z2RtVnljMmx2YmowaU1TNHdJaUJ6ZEdGdVpHRnNiMjVsUFNKdWJ5SS9QZzA4SVMwdElFZGxibVZ5WVhSdmNqb2dRV1J2WW1VZ1JtbHlaWGR2Y210eklFTlROaXdnUlhod2IzSjBJRk5XUnlCRmVIUmxibk5wYjI0Z1lua2dRV0Z5YjI0Z1FtVmhiR3dnS0doMGRIQTZMeTltYVhKbGQyOXlhM011WVdKbFlXeHNMbU52YlNrZ0xpQldaWEp6YVc5dU9pQXdMall1TVNBZ0xTMCtEVHdoUkU5RFZGbFFSU0J6ZG1jZ1VGVkNURWxESUNJdEx5OVhNME12TDBSVVJDQlRWa2NnTVM0eEx5OUZUaUlnSW1oMGRIQTZMeTkzZDNjdWR6TXViM0puTDBkeVlYQm9hV056TDFOV1J5OHhMakV2UkZSRUwzTjJaekV4TG1SMFpDSStEVHh6ZG1jZ2FXUTlJbFZ1ZEdsMGJHVmtMVkJoWjJVbE1qQXhJaUIyYVdWM1FtOTRQU0l3SURBZ05pQTJJaUJ6ZEhsc1pUMGlZbUZqYTJkeWIzVnVaQzFqYjJ4dmNqb2pabVptWm1abU1EQWlJSFpsY25OcGIyNDlJakV1TVNJTkNYaHRiRzV6UFNKb2RIUndPaTh2ZDNkM0xuY3pMbTl5Wnk4eU1EQXdMM04yWnlJZ2VHMXNibk02ZUd4cGJtczlJbWgwZEhBNkx5OTNkM2N1ZHpNdWIzSm5MekU1T1RrdmVHeHBibXNpSUhodGJEcHpjR0ZqWlQwaWNISmxjMlZ5ZG1VaURRbDRQU0l3Y0hnaUlIazlJakJ3ZUNJZ2QybGtkR2c5SWpad2VDSWdhR1ZwWjJoMFBTSTJjSGdpRFQ0TkNUeG5JRzl3WVdOcGRIazlJakF1TXpBeUlqNE5DUWs4Y0dGMGFDQmtQU0pOSURZZ05pQk1JREFnTmlCTUlEQWdOQzR5SUV3Z05DQTBMaklnVENBMExqSWdOQzR5SUV3Z05DNHlJREFnVENBMklEQWdUQ0EySURZZ1RDQTJJRFlnV2lJZ1ptbHNiRDBpSXpBd01EQXdNQ0l2UGcwSlBDOW5QZzA4TDNOMlp6ND0nKTtcXG4gICAgYmFja2dyb3VuZC1wb3NpdGlvbjogYm90dG9tIHJpZ2h0O1xcbiAgICBwYWRkaW5nOiAwIDNweCAzcHggMDtcXG4gICAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDtcXG4gICAgYmFja2dyb3VuZC1vcmlnaW46IGNvbnRlbnQtYm94O1xcbiAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xcbiAgICBjdXJzb3I6IHNlLXJlc2l6ZTtcXG59XFxuLnZ1ZS1ncmlkLWl0ZW0gPiAudnVlLXJ0bC1yZXNpemFibGUtaGFuZGxlIHtcXG4gICAgYm90dG9tOiAwO1xcbiAgICBsZWZ0OiAwO1xcbiAgICBiYWNrZ3JvdW5kOiB1cmwoZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxQSE4yWnlCM2FXUjBhRDBpTVRBdU1EQXdNREF3TURBd01EQXdNREF5SWlCb1pXbG5hSFE5SWpFd0xqQXdNREF3TURBd01EQXdNREF3TWlJZ2VHMXNibk05SW1oMGRIQTZMeTkzZDNjdWR6TXViM0puTHpJd01EQXZjM1puSWo0S0lEd2hMUzBnUTNKbFlYUmxaQ0IzYVhSb0lFMWxkR2h2WkNCRWNtRjNJQzBnYUhSMGNEb3ZMMmRwZEdoMVlpNWpiMjB2WkhWdmNHbDRaV3d2VFdWMGFHOWtMVVJ5WVhjdklDMHRQZ29nUEdjK0NpQWdQSFJwZEd4bFBtSmhZMnRuY205MWJtUThMM1JwZEd4bFBnb2dJRHh5WldOMElHWnBiR3c5SW01dmJtVWlJR2xrUFNKallXNTJZWE5mWW1GamEyZHliM1Z1WkNJZ2FHVnBaMmgwUFNJeE1pSWdkMmxrZEdnOUlqRXlJaUI1UFNJdE1TSWdlRDBpTFRFaUx6NEtJQ0E4WnlCa2FYTndiR0Y1UFNKdWIyNWxJaUJ2ZG1WeVpteHZkejBpZG1semFXSnNaU0lnZVQwaU1DSWdlRDBpTUNJZ2FHVnBaMmgwUFNJeE1EQWxJaUIzYVdSMGFEMGlNVEF3SlNJZ2FXUTlJbU5oYm5aaGMwZHlhV1FpUGdvZ0lDQThjbVZqZENCbWFXeHNQU0oxY213b0kyZHlhV1J3WVhSMFpYSnVLU0lnYzNSeWIydGxMWGRwWkhSb1BTSXdJaUI1UFNJd0lpQjRQU0l3SWlCb1pXbG5hSFE5SWpFd01DVWlJSGRwWkhSb1BTSXhNREFsSWk4K0NpQWdQQzluUGdvZ1BDOW5QZ29nUEdjK0NpQWdQSFJwZEd4bFBreGhlV1Z5SURFOEwzUnBkR3hsUGdvZ0lEeHNhVzVsSUdOaGJuWmhjejBpSTJabVptWm1aaUlnWTJGdWRtRnpMVzl3WVdOcGRIazlJakVpSUhOMGNtOXJaUzFzYVc1bFkyRndQU0oxYm1SbFptbHVaV1FpSUhOMGNtOXJaUzFzYVc1bGFtOXBiajBpZFc1a1pXWnBibVZrSWlCcFpEMGljM1puWHpFaUlIa3lQU0l0TnpBdU1UYzROREEzSWlCNE1qMGlNVEkwTGpRMk5ERTNOU0lnZVRFOUlpMHpPQzR6T1RJM016Y2lJSGd4UFNJeE5EUXVPREl4TWpnNUlpQnpkSEp2YTJVdGQybGtkR2c5SWpFdU5TSWdjM1J5YjJ0bFBTSWpNREF3SWlCbWFXeHNQU0p1YjI1bElpOCtDaUFnUEd4cGJtVWdjM1J5YjJ0bFBTSWpOalkyTmpZMklpQnpkSEp2YTJVdGJHbHVaV05oY0QwaWRXNWtaV1pwYm1Wa0lpQnpkSEp2YTJVdGJHbHVaV3B2YVc0OUluVnVaR1ZtYVc1bFpDSWdhV1E5SW5OMloxODFJaUI1TWowaU9TNHhNRFk1TlRjaUlIZ3lQU0l3TGprME56STBOeUlnZVRFOUlpMHdMakF4T0RFeU9DSWdlREU5SWpBdU9UUTNNalEzSWlCemRISnZhMlV0ZDJsa2RHZzlJaklpSUdacGJHdzlJbTV2Ym1VaUx6NEtJQ0E4YkdsdVpTQnpkSEp2YTJVdGJHbHVaV05oY0QwaWRXNWtaV1pwYm1Wa0lpQnpkSEp2YTJVdGJHbHVaV3B2YVc0OUluVnVaR1ZtYVc1bFpDSWdhV1E5SW5OMloxODNJaUI1TWowaU9TSWdlREk5SWpFd0xqQTNNelV5T1NJZ2VURTlJamtpSUhneFBTSXRNQzQyTlRVMk5DSWdjM1J5YjJ0bExYZHBaSFJvUFNJeUlpQnpkSEp2YTJVOUlpTTJOalkyTmpZaUlHWnBiR3c5SW01dmJtVWlMejRLSUR3dlp6NEtQQzl6ZG1jKyk7XFxuICAgIGJhY2tncm91bmQtcG9zaXRpb246IGJvdHRvbSBsZWZ0O1xcbiAgICBwYWRkaW5nLWxlZnQ6IDNweDtcXG4gICAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDtcXG4gICAgYmFja2dyb3VuZC1vcmlnaW46IGNvbnRlbnQtYm94O1xcbiAgICBjdXJzb3I6IHN3LXJlc2l6ZTtcXG4gICAgcmlnaHQ6IGF1dG87XFxufVxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi9zcmMvR3JpZEl0ZW0udnVlP2UyYTE0Y2IyXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCI7QUFXQTtJQUNBLDJCQUFBO0lBQ0Esc0NBQUE7SUFDQSx1QkFBQTtDQUNBO0FBQ0E7SUFDQSwrQkFBQTtDQUNBO0FBQ0E7SUFDQSxhQUFBO0lBQ0EsV0FBQTtDQUNBO0FBRUE7SUFDQSxvQkFBQTtJQUNBLFdBQUE7Q0FDQTtBQUVBO0lBQ0EsZ0JBQUE7SUFDQSxhQUFBO0lBQ0EsMkJBQUE7SUFDQSxXQUFBO0lBQ0EsMEJBQUE7SUFDQSx1QkFBQTtJQUNBLHNCQUFBO0lBQ0EscUJBQUE7SUFDQSxrQkFBQTtDQUNBO0FBRUE7SUFDQSxtQkFBQTtJQUNBLFlBQUE7SUFDQSxhQUFBO0lBQ0EsVUFBQTtJQUNBLFNBQUE7SUFDQSxzM0JBQUE7SUFDQSxrQ0FBQTtJQUNBLHFCQUFBO0lBQ0EsNkJBQUE7SUFDQSwrQkFBQTtJQUNBLHVCQUFBO0lBQ0Esa0JBQUE7Q0FDQTtBQUVBO0lBQ0EsVUFBQTtJQUNBLFFBQUE7SUFDQSxnK0NBQUE7SUFDQSxpQ0FBQTtJQUNBLGtCQUFBO0lBQ0EsNkJBQUE7SUFDQSwrQkFBQTtJQUNBLGtCQUFBO0lBQ0EsWUFBQTtDQUNBXCIsXCJmaWxlXCI6XCJHcmlkSXRlbS52dWVcIixcInNvdXJjZXNDb250ZW50XCI6W1wiPHRlbXBsYXRlPlxcclxcbiAgICA8ZGl2IHJlZj1cXFwiaXRlbVxcXCJcXHJcXG4gICAgICAgICAgICAgY2xhc3M9XFxcInZ1ZS1ncmlkLWl0ZW1cXFwiXFxyXFxuICAgICAgICAgICAgIDpjbGFzcz1cXFwieyAndnVlLXJlc2l6YWJsZScgOiBpc1Jlc2l6YWJsZSwgJ3Jlc2l6aW5nJyA6IGlzUmVzaXppbmcsICd2dWUtZHJhZ2dhYmxlLWRyYWdnaW5nJyA6IGlzRHJhZ2dpbmcsICdjc3NUcmFuc2Zvcm1zJyA6IHVzZUNzc1RyYW5zZm9ybXMgfVxcXCJcXHJcXG4gICAgICAgICAgICAgOnN0eWxlPVxcXCJzdHlsZVxcXCJcXHJcXG4gICAgICAgID5cXHJcXG4gICAgICAgIDxzbG90Pjwvc2xvdD5cXHJcXG4gICAgICAgIDxzcGFuIHYtaWY9XFxcImlzUmVzaXphYmxlXFxcIiByZWY9XFxcImhhbmRsZVxcXCIgOmNsYXNzPVxcXCJyZXNpemFibGVIYW5kbGVDbGFzc1xcXCI+PC9zcGFuPlxcclxcbiAgICA8L2Rpdj5cXHJcXG48L3RlbXBsYXRlPlxcclxcbjxzdHlsZT5cXHJcXG4gICAgLnZ1ZS1ncmlkLWl0ZW0ge1xcclxcbiAgICAgICAgdHJhbnNpdGlvbjogYWxsIDIwMG1zIGVhc2U7XFxyXFxuICAgICAgICB0cmFuc2l0aW9uLXByb3BlcnR5OiBsZWZ0LCB0b3AsIHJpZ2h0O1xcclxcbiAgICAgICAgLyogYWRkIHJpZ2h0IGZvciBydGwgKi9cXHJcXG4gICAgfVxcclxcbiAgICAudnVlLWdyaWQtaXRlbS5jc3NUcmFuc2Zvcm1zIHtcXHJcXG4gICAgICAgIHRyYW5zaXRpb24tcHJvcGVydHk6IHRyYW5zZm9ybTtcXHJcXG4gICAgfVxcclxcbiAgICAudnVlLWdyaWQtaXRlbS5yZXNpemluZyB7XFxyXFxuICAgICAgICBvcGFjaXR5OiAwLjY7XFxyXFxuICAgICAgICB6LWluZGV4OiAzO1xcclxcbiAgICB9XFxyXFxuXFxyXFxuICAgIC52dWUtZ3JpZC1pdGVtLnZ1ZS1kcmFnZ2FibGUtZHJhZ2dpbmcge1xcclxcbiAgICAgICAgLyp0cmFuc2l0aW9uOm5vbmU7Ki9cXHJcXG4gICAgICAgIHotaW5kZXg6IDM7XFxyXFxuICAgIH1cXHJcXG5cXHJcXG4gICAgLnZ1ZS1ncmlkLWl0ZW0udnVlLWdyaWQtcGxhY2Vob2xkZXIge1xcclxcbiAgICAgICAgYmFja2dyb3VuZDogcmVkO1xcclxcbiAgICAgICAgb3BhY2l0eTogMC4yO1xcclxcbiAgICAgICAgdHJhbnNpdGlvbi1kdXJhdGlvbjogMTAwbXM7XFxyXFxuICAgICAgICB6LWluZGV4OiAyO1xcclxcbiAgICAgICAgLXdlYmtpdC11c2VyLXNlbGVjdDogbm9uZTtcXHJcXG4gICAgICAgIC1tb3otdXNlci1zZWxlY3Q6IG5vbmU7XFxyXFxuICAgICAgICAtbXMtdXNlci1zZWxlY3Q6IG5vbmU7XFxyXFxuICAgICAgICAtby11c2VyLXNlbGVjdDogbm9uZTtcXHJcXG4gICAgICAgIHVzZXItc2VsZWN0OiBub25lO1xcclxcbiAgICB9XFxyXFxuXFxyXFxuICAgIC52dWUtZ3JpZC1pdGVtID4gLnZ1ZS1yZXNpemFibGUtaGFuZGxlIHtcXHJcXG4gICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXHJcXG4gICAgICAgIHdpZHRoOiAyMHB4O1xcclxcbiAgICAgICAgaGVpZ2h0OiAyMHB4O1xcclxcbiAgICAgICAgYm90dG9tOiAwO1xcclxcbiAgICAgICAgcmlnaHQ6IDA7XFxyXFxuICAgICAgICBiYWNrZ3JvdW5kOiB1cmwoJ2RhdGE6aW1hZ2Uvc3ZnK3htbDtiYXNlNjQsUEQ5NGJXd2dkbVZ5YzJsdmJqMGlNUzR3SWlCemRHRnVaR0ZzYjI1bFBTSnVieUkvUGcwOElTMHRJRWRsYm1WeVlYUnZjam9nUVdSdlltVWdSbWx5WlhkdmNtdHpJRU5UTml3Z1JYaHdiM0owSUZOV1J5QkZlSFJsYm5OcGIyNGdZbmtnUVdGeWIyNGdRbVZoYkd3Z0tHaDBkSEE2THk5bWFYSmxkMjl5YTNNdVlXSmxZV3hzTG1OdmJTa2dMaUJXWlhKemFXOXVPaUF3TGpZdU1TQWdMUzArRFR3aFJFOURWRmxRUlNCemRtY2dVRlZDVEVsRElDSXRMeTlYTTBNdkwwUlVSQ0JUVmtjZ01TNHhMeTlGVGlJZ0ltaDBkSEE2THk5M2QzY3Vkek11YjNKbkwwZHlZWEJvYVdOekwxTldSeTh4TGpFdlJGUkVMM04yWnpFeExtUjBaQ0krRFR4emRtY2dhV1E5SWxWdWRHbDBiR1ZrTFZCaFoyVWxNakF4SWlCMmFXVjNRbTk0UFNJd0lEQWdOaUEySWlCemRIbHNaVDBpWW1GamEyZHliM1Z1WkMxamIyeHZjam9qWm1abVptWm1NREFpSUhabGNuTnBiMjQ5SWpFdU1TSU5DWGh0Ykc1elBTSm9kSFJ3T2k4dmQzZDNMbmN6TG05eVp5OHlNREF3TDNOMlp5SWdlRzFzYm5NNmVHeHBibXM5SW1oMGRIQTZMeTkzZDNjdWR6TXViM0puTHpFNU9Ua3ZlR3hwYm1zaUlIaHRiRHB6Y0dGalpUMGljSEpsYzJWeWRtVWlEUWw0UFNJd2NIZ2lJSGs5SWpCd2VDSWdkMmxrZEdnOUlqWndlQ0lnYUdWcFoyaDBQU0kyY0hnaURUNE5DVHhuSUc5d1lXTnBkSGs5SWpBdU16QXlJajROQ1FrOGNHRjBhQ0JrUFNKTklEWWdOaUJNSURBZ05pQk1JREFnTkM0eUlFd2dOQ0EwTGpJZ1RDQTBMaklnTkM0eUlFd2dOQzR5SURBZ1RDQTJJREFnVENBMklEWWdUQ0EySURZZ1dpSWdabWxzYkQwaUl6QXdNREF3TUNJdlBnMEpQQzluUGcwOEwzTjJaejQ9Jyk7XFxyXFxuICAgICAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiBib3R0b20gcmlnaHQ7XFxyXFxuICAgICAgICBwYWRkaW5nOiAwIDNweCAzcHggMDtcXHJcXG4gICAgICAgIGJhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7XFxyXFxuICAgICAgICBiYWNrZ3JvdW5kLW9yaWdpbjogY29udGVudC1ib3g7XFxyXFxuICAgICAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xcclxcbiAgICAgICAgY3Vyc29yOiBzZS1yZXNpemU7XFxyXFxuICAgIH1cXHJcXG5cXHJcXG4gICAgLnZ1ZS1ncmlkLWl0ZW0gPiAudnVlLXJ0bC1yZXNpemFibGUtaGFuZGxlIHtcXHJcXG4gICAgICAgIGJvdHRvbTogMDtcXHJcXG4gICAgICAgIGxlZnQ6IDA7XFxyXFxuICAgICAgICBiYWNrZ3JvdW5kOiB1cmwoZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxQSE4yWnlCM2FXUjBhRDBpTVRBdU1EQXdNREF3TURBd01EQXdNREF5SWlCb1pXbG5hSFE5SWpFd0xqQXdNREF3TURBd01EQXdNREF3TWlJZ2VHMXNibk05SW1oMGRIQTZMeTkzZDNjdWR6TXViM0puTHpJd01EQXZjM1puSWo0S0lEd2hMUzBnUTNKbFlYUmxaQ0IzYVhSb0lFMWxkR2h2WkNCRWNtRjNJQzBnYUhSMGNEb3ZMMmRwZEdoMVlpNWpiMjB2WkhWdmNHbDRaV3d2VFdWMGFHOWtMVVJ5WVhjdklDMHRQZ29nUEdjK0NpQWdQSFJwZEd4bFBtSmhZMnRuY205MWJtUThMM1JwZEd4bFBnb2dJRHh5WldOMElHWnBiR3c5SW01dmJtVWlJR2xrUFNKallXNTJZWE5mWW1GamEyZHliM1Z1WkNJZ2FHVnBaMmgwUFNJeE1pSWdkMmxrZEdnOUlqRXlJaUI1UFNJdE1TSWdlRDBpTFRFaUx6NEtJQ0E4WnlCa2FYTndiR0Y1UFNKdWIyNWxJaUJ2ZG1WeVpteHZkejBpZG1semFXSnNaU0lnZVQwaU1DSWdlRDBpTUNJZ2FHVnBaMmgwUFNJeE1EQWxJaUIzYVdSMGFEMGlNVEF3SlNJZ2FXUTlJbU5oYm5aaGMwZHlhV1FpUGdvZ0lDQThjbVZqZENCbWFXeHNQU0oxY213b0kyZHlhV1J3WVhSMFpYSnVLU0lnYzNSeWIydGxMWGRwWkhSb1BTSXdJaUI1UFNJd0lpQjRQU0l3SWlCb1pXbG5hSFE5SWpFd01DVWlJSGRwWkhSb1BTSXhNREFsSWk4K0NpQWdQQzluUGdvZ1BDOW5QZ29nUEdjK0NpQWdQSFJwZEd4bFBreGhlV1Z5SURFOEwzUnBkR3hsUGdvZ0lEeHNhVzVsSUdOaGJuWmhjejBpSTJabVptWm1aaUlnWTJGdWRtRnpMVzl3WVdOcGRIazlJakVpSUhOMGNtOXJaUzFzYVc1bFkyRndQU0oxYm1SbFptbHVaV1FpSUhOMGNtOXJaUzFzYVc1bGFtOXBiajBpZFc1a1pXWnBibVZrSWlCcFpEMGljM1puWHpFaUlIa3lQU0l0TnpBdU1UYzROREEzSWlCNE1qMGlNVEkwTGpRMk5ERTNOU0lnZVRFOUlpMHpPQzR6T1RJM016Y2lJSGd4UFNJeE5EUXVPREl4TWpnNUlpQnpkSEp2YTJVdGQybGtkR2c5SWpFdU5TSWdjM1J5YjJ0bFBTSWpNREF3SWlCbWFXeHNQU0p1YjI1bElpOCtDaUFnUEd4cGJtVWdjM1J5YjJ0bFBTSWpOalkyTmpZMklpQnpkSEp2YTJVdGJHbHVaV05oY0QwaWRXNWtaV1pwYm1Wa0lpQnpkSEp2YTJVdGJHbHVaV3B2YVc0OUluVnVaR1ZtYVc1bFpDSWdhV1E5SW5OMloxODFJaUI1TWowaU9TNHhNRFk1TlRjaUlIZ3lQU0l3TGprME56STBOeUlnZVRFOUlpMHdMakF4T0RFeU9DSWdlREU5SWpBdU9UUTNNalEzSWlCemRISnZhMlV0ZDJsa2RHZzlJaklpSUdacGJHdzlJbTV2Ym1VaUx6NEtJQ0E4YkdsdVpTQnpkSEp2YTJVdGJHbHVaV05oY0QwaWRXNWtaV1pwYm1Wa0lpQnpkSEp2YTJVdGJHbHVaV3B2YVc0OUluVnVaR1ZtYVc1bFpDSWdhV1E5SW5OMloxODNJaUI1TWowaU9TSWdlREk5SWpFd0xqQTNNelV5T1NJZ2VURTlJamtpSUhneFBTSXRNQzQyTlRVMk5DSWdjM1J5YjJ0bExYZHBaSFJvUFNJeUlpQnpkSEp2YTJVOUlpTTJOalkyTmpZaUlHWnBiR3c5SW01dmJtVWlMejRLSUR3dlp6NEtQQzl6ZG1jKyk7XFxyXFxuICAgICAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiBib3R0b20gbGVmdDtcXHJcXG4gICAgICAgIHBhZGRpbmctbGVmdDogM3B4O1xcclxcbiAgICAgICAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDtcXHJcXG4gICAgICAgIGJhY2tncm91bmQtb3JpZ2luOiBjb250ZW50LWJveDtcXHJcXG4gICAgICAgIGN1cnNvcjogc3ctcmVzaXplO1xcclxcbiAgICAgICAgcmlnaHQ6IGF1dG87XFxyXFxuICAgIH1cXHJcXG48L3N0eWxlPlxcclxcbjxzY3JpcHQ+XFxyXFxuICAgIGltcG9ydCB7c2V0VG9wTGVmdCwgc2V0VG9wUmlnaHQsIHNldFRyYW5zZm9ybVJ0bCwgc2V0VHJhbnNmb3JtLCBjcmVhdGVNYXJrdXAsIGdldExheW91dEl0ZW19IGZyb20gJy4vdXRpbHMnO1xcclxcbiAgICBpbXBvcnQge2dldENvbnRyb2xQb3NpdGlvbiwgb2Zmc2V0WFlGcm9tUGFyZW50T2YsIGNyZWF0ZUNvcmVEYXRhfSBmcm9tICcuL2RyYWdnYWJsZVV0aWxzJztcXHJcXG4gICAgdmFyIGV2ZW50QnVzID0gcmVxdWlyZSgnLi9ldmVudEJ1cycpO1xcclxcblxcclxcbiAgICB2YXIgaW50ZXJhY3QgPSByZXF1aXJlKFxcXCJpbnRlcmFjdC5qc1xcXCIpO1xcclxcblxcclxcbiAgICBleHBvcnQgZGVmYXVsdCB7XFxyXFxuICAgICAgICBuYW1lOiBcXFwiR3JpZEl0ZW1cXFwiLFxcclxcbiAgICAgICAgcHJvcHM6IHtcXHJcXG4gICAgICAgICAgICAvKmNvbHM6IHtcXHJcXG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxcclxcbiAgICAgICAgICAgICAgICByZXF1aXJlZDogdHJ1ZVxcclxcbiAgICAgICAgICAgIH0sKi9cXHJcXG4gICAgICAgICAgICAvKmNvbnRhaW5lcldpZHRoOiB7XFxyXFxuICAgICAgICAgICAgICAgIHR5cGU6IE51bWJlcixcXHJcXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcXHJcXG5cXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIHJvd0hlaWdodDoge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXFxyXFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlXFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICBtYXJnaW46IHtcXHJcXG4gICAgICAgICAgICAgICAgdHlwZTogQXJyYXksXFxyXFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlXFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICBtYXhSb3dzOiB7XFxyXFxuICAgICAgICAgICAgICAgIHR5cGU6IE51bWJlcixcXHJcXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcXHJcXG4gICAgICAgICAgICB9LCovXFxyXFxuICAgICAgICAgICAgaXNEcmFnZ2FibGU6IHtcXHJcXG4gICAgICAgICAgICAgICAgdHlwZTogQm9vbGVhbixcXHJcXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IGZhbHNlLFxcclxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiBudWxsXFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICBpc1Jlc2l6YWJsZToge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBCb29sZWFuLFxcclxcbiAgICAgICAgICAgICAgICByZXF1aXJlZDogZmFsc2UsXFxyXFxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IG51bGxcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIC8qdXNlQ3NzVHJhbnNmb3Jtczoge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBCb29sZWFuLFxcclxcbiAgICAgICAgICAgICAgICByZXF1aXJlZDogdHJ1ZVxcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgc3RhdGljOiB7XFxyXFxuICAgICAgICAgICAgICAgIHR5cGU6IEJvb2xlYW4sXFxyXFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcXHJcXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogZmFsc2VcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgICovXFxyXFxuICAgICAgICAgICAgbWluSDoge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXFxyXFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcXHJcXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogMVxcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgbWluVzoge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXFxyXFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcXHJcXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogMVxcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgbWF4SDoge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXFxyXFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcXHJcXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogSW5maW5pdHlcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIG1heFc6IHtcXHJcXG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxcclxcbiAgICAgICAgICAgICAgICByZXF1aXJlZDogZmFsc2UsXFxyXFxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IEluZmluaXR5XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICB4OiB7XFxyXFxuICAgICAgICAgICAgICAgIHR5cGU6IE51bWJlcixcXHJcXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIHk6IHtcXHJcXG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxcclxcbiAgICAgICAgICAgICAgICByZXF1aXJlZDogdHJ1ZVxcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgdzoge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXFxyXFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlXFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICBoOiB7XFxyXFxuICAgICAgICAgICAgICAgIHR5cGU6IE51bWJlcixcXHJcXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIGk6IHtcXHJcXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcXHJcXG4gICAgICAgICAgICB9XFxyXFxuICAgICAgICB9LFxcclxcbiAgICAgICAgZGF0YTogZnVuY3Rpb24oKSB7XFxyXFxuICAgICAgICAgICAgcmV0dXJuIHtcXHJcXG4gICAgICAgICAgICAgICAgY29sczogMSxcXHJcXG4gICAgICAgICAgICAgICAgY29udGFpbmVyV2lkdGg6IDEwMCxcXHJcXG4gICAgICAgICAgICAgICAgcm93SGVpZ2h0OiAzMCxcXHJcXG4gICAgICAgICAgICAgICAgbWFyZ2luOiBbMTAsIDEwXSxcXHJcXG4gICAgICAgICAgICAgICAgbWF4Um93czogSW5maW5pdHksXFxyXFxuLy8gICAgICAgICAgICAgICAgaXNEcmFnZ2FibGU6IG51bGwsXFxyXFxuLy8gICAgICAgICAgICAgICAgaXNSZXNpemFibGU6IG51bGwsXFxyXFxuICAgICAgICAgICAgICAgIHVzZUNzc1RyYW5zZm9ybXM6IHRydWUsXFxyXFxuXFxyXFxuICAgICAgICAgICAgICAgIGlzRHJhZ2dpbmc6IGZhbHNlLFxcclxcbiAgICAgICAgICAgICAgICBkcmFnZ2luZzogbnVsbCxcXHJcXG4gICAgICAgICAgICAgICAgaXNSZXNpemluZzogZmFsc2UsXFxyXFxuICAgICAgICAgICAgICAgIHJlc2l6aW5nOiBudWxsLFxcclxcbiAgICAgICAgICAgICAgICBsYXN0WDogTmFOLFxcclxcbiAgICAgICAgICAgICAgICBsYXN0WTogTmFOLFxcclxcbiAgICAgICAgICAgICAgICBsYXN0VzogTmFOLFxcclxcbiAgICAgICAgICAgICAgICBsYXN0SDogTmFOLFxcclxcbiAgICAgICAgICAgICAgICBzdHlsZToge30sXFxyXFxuICAgICAgICAgICAgICAgIHJ0bDogZmFsc2UsXFxyXFxuXFxyXFxuICAgICAgICAgICAgICAgIGRyYWdFdmVudFNldDogZmFsc2UsXFxyXFxuICAgICAgICAgICAgICAgIHJlc2l6ZUV2ZW50U2V0OiBmYWxzZSxcXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgcHJldmlvdXNXOiBudWxsLFxcclxcbiAgICAgICAgICAgICAgICBwcmV2aW91c0g6IG51bGwsXFxyXFxuICAgICAgICAgICAgICAgIHByZXZpb3VzWDogbnVsbCxcXHJcXG4gICAgICAgICAgICAgICAgcHJldmlvdXNZOiBudWxsLFxcclxcbiAgICAgICAgICAgIH1cXHJcXG4gICAgICAgIH0sXFxyXFxuICAgICAgICBjcmVhdGVkICgpIHtcXHJcXG4gICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XFxyXFxuXFxyXFxuICAgICAgICAgICAgLy8gQWNjZXNzaWJsZSByZWZlcm5jZXMgb2YgZnVuY3Rpb25zIGZvciByZW1vdmluZyBpbiBiZWZvcmVEZXN0cm95XFxyXFxuICAgICAgICAgICAgc2VsZi51cGRhdGVXaWR0aEhhbmRsZXIgPSBmdW5jdGlvbih3aWR0aCkge1xcclxcbiAgICAgICAgICAgICAgICBzZWxmLnVwZGF0ZVdpZHRoKHdpZHRoKTtcXHJcXG4gICAgICAgICAgICB9O1xcclxcblxcclxcbiAgICAgICAgICAgIHNlbGYuY29tcGFjdEhhbmRsZXIgPSBmdW5jdGlvbihsYXlvdXQpIHtcXHJcXG4gICAgICAgICAgICAgICAgc2VsZi5jb21wYWN0KGxheW91dCk7XFxyXFxuICAgICAgICAgICAgfTtcXHJcXG5cXHJcXG4gICAgICAgICAgICBzZWxmLnNldERyYWdnYWJsZUhhbmRsZXIgPSBmdW5jdGlvbihpc0RyYWdnYWJsZSkge1xcclxcbiAgICAgICAgICAgICAgICBzZWxmLmlzRHJhZ2dhYmxlID0gaXNEcmFnZ2FibGU7XFxyXFxuICAgICAgICAgICAgfTtcXHJcXG5cXHJcXG4gICAgICAgICAgICBzZWxmLnNldFJlc2l6YWJsZUhhbmRsZXIgPSBmdW5jdGlvbihpc1Jlc2l6YWJsZSkge1xcclxcbiAgICAgICAgICAgICAgICBzZWxmLmlzUmVzaXphYmxlID0gaXNSZXNpemFibGU7XFxyXFxuICAgICAgICAgICAgfTtcXHJcXG5cXHJcXG4gICAgICAgICAgICBzZWxmLnNldFJvd0hlaWdodEhhbmRsZXIgPSBmdW5jdGlvbihyb3dIZWlnaHQpIHtcXHJcXG4gICAgICAgICAgICAgICAgc2VsZi5yb3dIZWlnaHQgPSByb3dIZWlnaHQ7XFxyXFxuICAgICAgICAgICAgfTtcXHJcXG5cXHJcXG4gICAgICAgICAgICBzZWxmLmRpcmVjdGlvbmNoYW5nZUhhbmRsZXIgPSAoZGlyZWN0aW9uKSA9PiB7XFxyXFxuICAgICAgICAgICAgICAgIHZhciBkaXJlY3Rpb24gPSAoZG9jdW1lbnQuZGlyICE9IHVuZGVmaW5lZCkgP1xcclxcbiAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnQuZGlyIDpcXHJcXG4gICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKFxcXCJodG1sXFxcIilbMF0uZ2V0QXR0cmlidXRlKFxcXCJkaXJcXFwiKTtcXHJcXG4gICAgICAgICAgICAgICAgdGhpcy5ydGwgPSAoZGlyZWN0aW9uID09IFxcXCJydGxcXFwiKTtcXHJcXG4gICAgICAgICAgICAgICAgdGhpcy5jb21wYWN0KCk7XFxyXFxuICAgICAgICAgICAgfTtcXHJcXG5cXHJcXG4gICAgICAgICAgICBldmVudEJ1cy4kb24oJ3VwZGF0ZVdpZHRoJywgc2VsZi51cGRhdGVXaWR0aEhhbmRsZXIpO1xcclxcbiAgICAgICAgICAgIGV2ZW50QnVzLiRvbignY29tcGFjdCcsIHNlbGYuY29tcGFjdEhhbmRsZXIpO1xcclxcbiAgICAgICAgICAgIGV2ZW50QnVzLiRvbignc2V0RHJhZ2dhYmxlJywgc2VsZi5zZXREcmFnZ2FibGVIYW5kbGVyKTtcXHJcXG4gICAgICAgICAgICBldmVudEJ1cy4kb24oJ3NldFJlc2l6YWJsZScsIHNlbGYuc2V0UmVzaXphYmxlSGFuZGxlcik7XFxyXFxuICAgICAgICAgICAgZXZlbnRCdXMuJG9uKCdzZXRSb3dIZWlnaHQnLCBzZWxmLnNldFJvd0hlaWdodEhhbmRsZXIpO1xcclxcbiAgICAgICAgICAgIGV2ZW50QnVzLiRvbignZGlyZWN0aW9uY2hhbmdlJywgc2VsZi5kaXJlY3Rpb25jaGFuZ2VIYW5kbGVyKTtcXHJcXG5cXHJcXG4gICAgICAgICAgICAvKmV2ZW50QnVzLiRvbignc2V0Q29sTnVtJywgZnVuY3Rpb24oY29sTnVtKSB7XFxyXFxuICAgICAgICAgICAgICAgIHNlbGYuY29scyA9IGNvbE51bTtcXHJcXG4gICAgICAgICAgICB9KTsqL1xcclxcbiAgICAgICAgICAgIHZhciBkaXJlY3Rpb24gPSAoZG9jdW1lbnQuZGlyICE9dW5kZWZpbmVkKSA/XFxyXFxuICAgICAgICAgICAgICAgIGRvY3VtZW50LmRpciA6XFxyXFxuICAgICAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKFxcXCJodG1sXFxcIilbMF0uZ2V0QXR0cmlidXRlKFxcXCJkaXJcXFwiKTtcXHJcXG4gICAgICAgICAgICB0aGlzLnJ0bCA9IChkaXJlY3Rpb24gPT0gXFxcInJ0bFxcXCIpO1xcclxcbiAgICAgICAgfSxcXHJcXG4gICAgICAgIGJlZm9yZURlc3Ryb3k6IGZ1bmN0aW9uKCl7XFxyXFxuICAgICAgICAgICAgLy9SZW1vdmUgbGlzdGVuZXJzXFxyXFxuICAgICAgICAgICAgZXZlbnRCdXMuJG9mZigndXBkYXRlV2lkdGgnLCBzZWxmLnVwZGF0ZVdpZHRoSGFuZGxlcik7XFxyXFxuICAgICAgICAgICAgZXZlbnRCdXMuJG9mZignY29tcGFjdCcsIHNlbGYuY29tcGFjdEhhbmRsZXIpO1xcclxcbiAgICAgICAgICAgIGV2ZW50QnVzLiRvZmYoJ3NldERyYWdnYWJsZScsIHNlbGYuc2V0RHJhZ2dhYmxlSGFuZGxlcik7XFxyXFxuICAgICAgICAgICAgZXZlbnRCdXMuJG9mZignc2V0UmVzaXphYmxlJywgc2VsZi5zZXRSZXNpemFibGVIYW5kbGVyKTtcXHJcXG4gICAgICAgICAgICBldmVudEJ1cy4kb2ZmKCdzZXRSb3dIZWlnaHQnLCBzZWxmLnNldFJvd0hlaWdodEhhbmRsZXIpO1xcclxcbiAgICAgICAgICAgIGV2ZW50QnVzLiRvZmYoJ2RpcmVjdGlvbmNoYW5nZScsIHNlbGYuZGlyZWN0aW9uY2hhbmdlSGFuZGxlcik7XFxyXFxuICAgICAgICB9LFxcclxcbiAgICAgICAgbW91bnRlZDogZnVuY3Rpb24oKSB7XFxyXFxuICAgICAgICAgICAgdGhpcy5jb2xzID0gdGhpcy4kcGFyZW50LmNvbE51bTtcXHJcXG4gICAgICAgICAgICB0aGlzLnJvd0hlaWdodCA9IHRoaXMuJHBhcmVudC5yb3dIZWlnaHQ7XFxyXFxuICAgICAgICAgICAgdGhpcy5jb250YWluZXJXaWR0aCA9IHRoaXMuJHBhcmVudC53aWR0aCAhPT0gbnVsbCA/IHRoaXMuJHBhcmVudC53aWR0aCA6IDEwMDtcXHJcXG4gICAgICAgICAgICB0aGlzLm1hcmdpbiA9IHRoaXMuJHBhcmVudC5tYXJnaW4gIT09IHVuZGVmaW5lZCA/IHRoaXMuJHBhcmVudC5tYXJnaW4gOiBbMTAsIDEwXTtcXHJcXG4gICAgICAgICAgICB0aGlzLm1heFJvd3MgPSB0aGlzLiRwYXJlbnQubWF4Um93cztcXHJcXG4gICAgICAgICAgICB0aGlzLmlzRHJhZ2dhYmxlID0gdGhpcy4kcGFyZW50LmlzRHJhZ2dhYmxlO1xcclxcbiAgICAgICAgICAgIHRoaXMuaXNSZXNpemFibGUgPSB0aGlzLiRwYXJlbnQuaXNSZXNpemFibGU7XFxyXFxuICAgICAgICAgICAgdGhpcy51c2VDc3NUcmFuc2Zvcm1zID0gdGhpcy4kcGFyZW50LnVzZUNzc1RyYW5zZm9ybXM7XFxyXFxuICAgICAgICAgICAgdGhpcy5jcmVhdGVTdHlsZSgpO1xcclxcbiAgICAgICAgfSxcXHJcXG4gICAgICAgIHdhdGNoOiB7XFxyXFxuICAgICAgICAgICAgaXNEcmFnZ2FibGU6IGZ1bmN0aW9uKCkge1xcclxcbiAgICAgICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XFxyXFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmludGVyYWN0T2JqID09IG51bGwpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaW50ZXJhY3RPYmogPSBpbnRlcmFjdCh0aGlzLiRyZWZzLml0ZW0sIHtpZ25vcmVGcm9tOiBcXFwiYSwgYnV0dG9uXFxcIn0pO1xcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzRHJhZ2dhYmxlKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmludGVyYWN0T2JqLmRyYWdnYWJsZSh7fSk7XFxyXFxuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuZHJhZ0V2ZW50U2V0KSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kcmFnRXZlbnRTZXQgPSB0cnVlO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaW50ZXJhY3RPYmoub24oJ2RyYWdzdGFydCBkcmFnbW92ZSBkcmFnZW5kJywgZnVuY3Rpb24gKGV2ZW50KSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuaGFuZGxlRHJhZyhldmVudCk7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XFxyXFxuICAgICAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmludGVyYWN0T2JqLmRyYWdnYWJsZSh7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuYWJsZWQ6ZmFsc2VcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgaXNSZXNpemFibGU6IGZ1bmN0aW9uKCkge1xcclxcbiAgICAgICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XFxyXFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmludGVyYWN0T2JqID09IG51bGwpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaW50ZXJhY3RPYmogPSBpbnRlcmFjdCh0aGlzLiRyZWZzLml0ZW0sIHtpZ25vcmVGcm9tOiBcXFwiYSwgYnV0dG9uXFxcIn0pO1xcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzUmVzaXphYmxlKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmludGVyYWN0T2JqXFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgLnJlc2l6YWJsZSh7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZXNlcnZlQXNwZWN0UmF0aW86IGZhbHNlLFxcclxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlZGdlczoge2xlZnQ6IGZhbHNlLCByaWdodDogdHJ1ZSwgYm90dG9tOiB0cnVlLCB0b3A6IGZhbHNlfVxcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xcclxcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLnJlc2l6ZUV2ZW50U2V0KSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZXNpemVFdmVudFNldCA9IHRydWU7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnRlcmFjdE9ialxcclxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAub24oJ3Jlc2l6ZXN0YXJ0IHJlc2l6ZW1vdmUgcmVzaXplZW5kJywgZnVuY3Rpb24gKGV2ZW50KSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmhhbmRsZVJlc2l6ZShldmVudCk7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xcclxcbiAgICAgICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xcclxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnRlcmFjdE9iai5yZXNpemFibGUoe1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIGVuYWJsZWQ6ZmFsc2VcXHJcXG4gICAgICAgICAgICAgICAgICAgIH0pO1xcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICByb3dIZWlnaHQ6IGZ1bmN0aW9uKCkge1xcclxcbiAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVN0eWxlKCk7XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICBjb2xzOiBmdW5jdGlvbigpIHtcXHJcXG4gICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVTdHlsZSgpO1xcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgY29udGFpbmVyV2lkdGg6IGZ1bmN0aW9uKCkge1xcclxcbiAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVN0eWxlKCk7XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICB4OiBmdW5jdGlvbigpIHtcXHJcXG4gICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVTdHlsZSgpO1xcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgeTogZnVuY3Rpb24oKSB7XFxyXFxuICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRlU3R5bGUoKTtcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIGg6IGZ1bmN0aW9uKCkge1xcclxcbiAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVN0eWxlKCk7XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICB3OiBmdW5jdGlvbigpIHtcXHJcXG4gICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVTdHlsZSgpO1xcclxcbiAgICAgICAgICAgIH1cXHJcXG4gICAgICAgIH0sXFxyXFxuICAgICAgICBjb21wdXRlZDoge1xcclxcbiAgICAgICAgICAgIHJlc2l6YWJsZUhhbmRsZUNsYXNzKCkge1xcclxcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5ydGwpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAndnVlLXJlc2l6YWJsZS1oYW5kbGUgdnVlLXJ0bC1yZXNpemFibGUtaGFuZGxlJztcXHJcXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAndnVlLXJlc2l6YWJsZS1oYW5kbGUnO1xcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgfVxcclxcbiAgICAgICAgfSxcXHJcXG4gICAgICAgIG1ldGhvZHM6IHtcXHJcXG4gICAgICAgICAgICBjcmVhdGVTdHlsZTogZnVuY3Rpb24oKSB7XFxyXFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnggKyB0aGlzLncgPiB0aGlzLmNvbHMpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMueCA9IDA7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLncgPSB0aGlzLmNvbHM7XFxyXFxuICAgICAgICAgICAgICAgIH1cXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgdmFyIHBvcyA9IHRoaXMuY2FsY1Bvc2l0aW9uKHRoaXMueCwgdGhpcy55LCB0aGlzLncsIHRoaXMuaCk7XFxyXFxuXFxyXFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzRHJhZ2dpbmcpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHBvcy50b3AgPSB0aGlzLmRyYWdnaW5nLnRvcDtcXHJcXG4vLyAgICAgICAgICAgICAgICAgICAgQWRkIHJ0bCBzdXBwb3J0XFxyXFxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5ydGwpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBwb3MucmlnaHQgPSB0aGlzLmRyYWdnaW5nLmxlZnQ7XFxyXFxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBvcy5sZWZ0ID0gdGhpcy5kcmFnZ2luZy5sZWZ0O1xcclxcbiAgICAgICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzUmVzaXppbmcpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHBvcy53aWR0aCA9IHRoaXMucmVzaXppbmcud2lkdGg7XFxyXFxuICAgICAgICAgICAgICAgICAgICBwb3MuaGVpZ2h0ID0gdGhpcy5yZXNpemluZy5oZWlnaHQ7XFxyXFxuICAgICAgICAgICAgICAgIH1cXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgbGV0IHN0eWxlO1xcclxcbiAgICAgICAgICAgICAgICAvLyBDU1MgVHJhbnNmb3JtcyBzdXBwb3J0IChkZWZhdWx0KVxcclxcbiAgICAgICAgICAgICAgICBpZiAodGhpcy51c2VDc3NUcmFuc2Zvcm1zKSB7XFxyXFxuLy8gICAgICAgICAgICAgICAgICAgIEFkZCBydGwgc3VwcG9ydFxcclxcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucnRsKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGUgPSBzZXRUcmFuc2Zvcm1SdGwocG9zLnRvcCwgcG9zLnJpZ2h0LCBwb3Mud2lkdGgsIHBvcy5oZWlnaHQpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZSA9IHNldFRyYW5zZm9ybShwb3MudG9wLCBwb3MubGVmdCwgcG9zLndpZHRoLCBwb3MuaGVpZ2h0KTtcXHJcXG4gICAgICAgICAgICAgICAgICAgIH1cXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgICAgICAvLyB0b3AsbGVmdCAoc2xvdylcXHJcXG4gICAgICAgICAgICAgICAgZWxzZSB7XFxyXFxuLy8gICAgICAgICAgICAgICAgICAgIEFkZCBydGwgc3VwcG9ydFxcclxcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucnRsKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGUgPSBzZXRUb3BSaWdodChwb3MudG9wLCBwb3MucmlnaHQsIHBvcy53aWR0aCwgcG9zLmhlaWdodCk7XFxyXFxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlID0gc2V0VG9wTGVmdChwb3MudG9wLCBwb3MubGVmdCwgcG9zLndpZHRoLCBwb3MuaGVpZ2h0KTtcXHJcXG4gICAgICAgICAgICAgICAgICAgIH1cXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgICAgICB0aGlzLnN0eWxlID0gc3R5bGU7XFxyXFxuXFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICBoYW5kbGVSZXNpemU6IGZ1bmN0aW9uKGV2ZW50KSB7XFxyXFxuICAgICAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9uID0gZ2V0Q29udHJvbFBvc2l0aW9uKGV2ZW50KTtcXHJcXG4gICAgICAgICAgICAgICAgLy8gR2V0IHRoZSBjdXJyZW50IGRyYWcgcG9pbnQgZnJvbSB0aGUgZXZlbnQuIFRoaXMgaXMgdXNlZCBhcyB0aGUgb2Zmc2V0LlxcclxcbiAgICAgICAgICAgICAgICBpZiAocG9zaXRpb24gPT0gbnVsbCkgcmV0dXJuOyAvLyBub3QgcG9zc2libGUgYnV0IHNhdGlzZmllcyBmbG93XFxyXFxuICAgICAgICAgICAgICAgIGNvbnN0IHt4LCB5fSA9IHBvc2l0aW9uO1xcclxcblxcclxcbiAgICAgICAgICAgICAgICBjb25zdCBuZXdTaXplID0ge3dpZHRoOiAwLCBoZWlnaHQ6IDB9O1xcclxcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKGV2ZW50LnR5cGUpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXFxcInJlc2l6ZXN0YXJ0XFxcIjpcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnByZXZpb3VzVyA9IHRoaXMudztcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnByZXZpb3VzSCA9IHRoaXMuaDtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgcG9zID0gdGhpcy5jYWxjUG9zaXRpb24odGhpcy54LCB0aGlzLnksIHRoaXMudywgdGhpcy5oKTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdTaXplLndpZHRoID0gcG9zLndpZHRoO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1NpemUuaGVpZ2h0ID0gcG9zLmhlaWdodDtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc2l6aW5nID0gbmV3U2l6ZTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzUmVzaXppbmcgPSB0cnVlO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xcclxcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcXFwicmVzaXplbW92ZVxcXCI6XFxyXFxuLy8gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcXFwiIyMjIHJlc2l6ZSA9PiBcXFwiICsgZXZlbnQudHlwZSArIFxcXCIsIGxhc3RXPVxcXCIgKyB0aGlzLmxhc3RXICsgXFxcIiwgbGFzdEg9XFxcIiArIHRoaXMubGFzdEgpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvcmVFdmVudCA9IGNyZWF0ZUNvcmVEYXRhKHRoaXMubGFzdFcsIHRoaXMubGFzdEgsIHgsIHkpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnJ0bCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdTaXplLndpZHRoID0gdGhpcy5yZXNpemluZy53aWR0aCAtIGNvcmVFdmVudC5kZWx0YVg7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3U2l6ZS53aWR0aCA9IHRoaXMucmVzaXppbmcud2lkdGggKyBjb3JlRXZlbnQuZGVsdGFYO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdTaXplLmhlaWdodCA9IHRoaXMucmVzaXppbmcuaGVpZ2h0ICsgY29yZUV2ZW50LmRlbHRhWTtcXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICAvLy9jb25zb2xlLmxvZyhcXFwiIyMjIHJlc2l6ZSA9PiBcXFwiICsgZXZlbnQudHlwZSArIFxcXCIsIGRlbHRhWD1cXFwiICsgY29yZUV2ZW50LmRlbHRhWCArIFxcXCIsIGRlbHRhWT1cXFwiICsgY29yZUV2ZW50LmRlbHRhWSk7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZXNpemluZyA9IG5ld1NpemU7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XFxyXFxuICAgICAgICAgICAgICAgICAgICBjYXNlIFxcXCJyZXNpemVlbmRcXFwiOlxcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vY29uc29sZS5sb2coXFxcIiMjIyByZXNpemUgZW5kID0+IHg9XFxcIiArdGhpcy54ICsgXFxcIiB5PVxcXCIgKyB0aGlzLnkgKyBcXFwiIHc9XFxcIiArIHRoaXMudyArIFxcXCIgaD1cXFwiICsgdGhpcy5oKTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgcG9zID0gdGhpcy5jYWxjUG9zaXRpb24odGhpcy54LCB0aGlzLnksIHRoaXMudywgdGhpcy5oKTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdTaXplLndpZHRoID0gcG9zLndpZHRoO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1NpemUuaGVpZ2h0ID0gcG9zLmhlaWdodDtcXHJcXG4vLyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxcXCIjIyMgcmVzaXplIGVuZCA9PiBcXFwiICsgSlNPTi5zdHJpbmdpZnkobmV3U2l6ZSkpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVzaXppbmcgPSBudWxsO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNSZXNpemluZyA9IGZhbHNlO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuXFxyXFxuICAgICAgICAgICAgICAgIC8vIEdldCBuZXcgV0hcXHJcXG4gICAgICAgICAgICAgICAgdmFyIHBvcyA9IHRoaXMuY2FsY1dIKG5ld1NpemUuaGVpZ2h0LCBuZXdTaXplLndpZHRoKTtcXHJcXG4gICAgICAgICAgICAgICAgaWYgKHBvcy53IDwgdGhpcy5taW5XKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICBwb3MudyA9IHRoaXMubWluVztcXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgICAgICBpZiAocG9zLncgPiB0aGlzLm1heFcpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHBvcy53ID0gdGhpcy5tYXhXO1xcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgICAgIGlmIChwb3MuaCA8IHRoaXMubWluSCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgcG9zLmggPSB0aGlzLm1pbkg7XFxyXFxuICAgICAgICAgICAgICAgIH1cXHJcXG4gICAgICAgICAgICAgICAgaWYgKHBvcy5oID4gdGhpcy5tYXhIKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICBwb3MuaCA9IHRoaXMubWF4SDtcXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcblxcclxcbiAgICAgICAgICAgICAgICBpZiAocG9zLmggPCAxKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICBwb3MuaCA9IDE7XFxyXFxuICAgICAgICAgICAgICAgIH1cXHJcXG4gICAgICAgICAgICAgICAgaWYgKHBvcy53IDwgMSkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgcG9zLncgPSAxO1xcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuXFxyXFxuICAgICAgICAgICAgICAgIHRoaXMubGFzdFcgPSB4O1xcclxcbiAgICAgICAgICAgICAgICB0aGlzLmxhc3RIID0geTtcXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMudyAhPT0gcG9zLncgfHwgdGhpcy5oICE9PSBwb3MuaCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy4kZW1pdChcXFwicmVzaXplXFxcIiwgdGhpcy5pLCBwb3MuaCwgcG9zLncpO1xcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgICAgIGlmIChldmVudC50eXBlID09PSBcXFwicmVzaXplZW5kXFxcIiAmJiAodGhpcy5wcmV2aW91c1cgIT09IHRoaXMudyB8fCB0aGlzLnByZXZpb3VzSCAhPT0gdGhpcy5oKSkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy4kZW1pdChcXFwicmVzaXplZFxcXCIsIHRoaXMuaSwgcG9zLmgsIHBvcy53KTtcXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgICAgICBldmVudEJ1cy4kZW1pdChcXFwicmVzaXplRXZlbnRcXFwiLCBldmVudC50eXBlLCB0aGlzLmksIHRoaXMueCwgdGhpcy55LCBwb3MuaCwgcG9zLncpO1xcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgaGFuZGxlRHJhZyhldmVudCkge1xcclxcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5pc1Jlc2l6aW5nKSByZXR1cm47XFxyXFxuXFxyXFxuICAgICAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9uID0gZ2V0Q29udHJvbFBvc2l0aW9uKGV2ZW50KTtcXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgLy8gR2V0IHRoZSBjdXJyZW50IGRyYWcgcG9pbnQgZnJvbSB0aGUgZXZlbnQuIFRoaXMgaXMgdXNlZCBhcyB0aGUgb2Zmc2V0LlxcclxcbiAgICAgICAgICAgICAgICBpZiAocG9zaXRpb24gPT0gbnVsbCkgcmV0dXJuOyAvLyBub3QgcG9zc2libGUgYnV0IHNhdGlzZmllcyBmbG93XFxyXFxuICAgICAgICAgICAgICAgIGNvbnN0IHt4LCB5fSA9IHBvc2l0aW9uO1xcclxcblxcclxcbiAgICAgICAgICAgICAgICB2YXIgc2hvdWxkVXBkYXRlID0gZmFsc2U7XFxyXFxuICAgICAgICAgICAgICAgIGNvbnN0IG5ld1Bvc2l0aW9uID0ge3RvcDogMCwgbGVmdDogMH07XFxyXFxuICAgICAgICAgICAgICAgIHN3aXRjaCAoZXZlbnQudHlwZSkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcXFwiZHJhZ3N0YXJ0XFxcIjpcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnByZXZpb3VzWCA9IHRoaXMueDtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnByZXZpb3VzWSA9IHRoaXMueTtcXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGFyZW50UmVjdCA9IGV2ZW50LnRhcmdldC5vZmZzZXRQYXJlbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNsaWVudFJlY3QgPSBldmVudC50YXJnZXQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucnRsKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1Bvc2l0aW9uLmxlZnQgPSAoY2xpZW50UmVjdC5yaWdodCAtIHBhcmVudFJlY3QucmlnaHQpICogLTE7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3UG9zaXRpb24ubGVmdCA9IGNsaWVudFJlY3QubGVmdCAtIHBhcmVudFJlY3QubGVmdDtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3UG9zaXRpb24udG9wID0gY2xpZW50UmVjdC50b3AgLSBwYXJlbnRSZWN0LnRvcDtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRyYWdnaW5nID0gbmV3UG9zaXRpb247XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0RyYWdnaW5nID0gdHJ1ZTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcXHJcXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXFxcImRyYWdlbmRcXFwiOlxcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5pc0RyYWdnaW5nKSByZXR1cm47XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50UmVjdCA9IGV2ZW50LnRhcmdldC5vZmZzZXRQYXJlbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgY2xpZW50UmVjdCA9IGV2ZW50LnRhcmdldC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcXHJcXG4vLyAgICAgICAgICAgICAgICAgICAgICAgIEFkZCBydGwgc3VwcG9ydFxcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnJ0bCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdQb3NpdGlvbi5sZWZ0ID0gKGNsaWVudFJlY3QucmlnaHQgLSBwYXJlbnRSZWN0LnJpZ2h0KSAqIC0xO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1Bvc2l0aW9uLmxlZnQgPSBjbGllbnRSZWN0LmxlZnQgLSBwYXJlbnRSZWN0LmxlZnQ7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1Bvc2l0aW9uLnRvcCA9IGNsaWVudFJlY3QudG9wIC0gcGFyZW50UmVjdC50b3A7XFxyXFxuLy8gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcXFwiIyMjIGRyYWcgZW5kID0+IFxcXCIgKyBKU09OLnN0cmluZ2lmeShuZXdQb3NpdGlvbikpO1xcclxcbi8vICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXFxcIiMjIyBEUk9QOiBcXFwiICsgSlNPTi5zdHJpbmdpZnkobmV3UG9zaXRpb24pKTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRyYWdnaW5nID0gbnVsbDtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzRHJhZ2dpbmcgPSBmYWxzZTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBzaG91bGRVcGRhdGUgPSB0cnVlO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xcclxcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcXFwiZHJhZ21vdmVcXFwiOlxcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvcmVFdmVudCA9IGNyZWF0ZUNvcmVEYXRhKHRoaXMubGFzdFgsIHRoaXMubGFzdFksIHgsIHkpO1xcclxcbi8vICAgICAgICAgICAgICAgICAgICAgICAgQWRkIHJ0bCBzdXBwb3J0XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucnRsKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1Bvc2l0aW9uLmxlZnQgPSB0aGlzLmRyYWdnaW5nLmxlZnQgLSBjb3JlRXZlbnQuZGVsdGFYO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1Bvc2l0aW9uLmxlZnQgPSB0aGlzLmRyYWdnaW5nLmxlZnQgKyBjb3JlRXZlbnQuZGVsdGFYO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdQb3NpdGlvbi50b3AgPSB0aGlzLmRyYWdnaW5nLnRvcCArIGNvcmVFdmVudC5kZWx0YVk7XFxyXFxuLy8gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcXFwiIyMjIGRyYWcgPT4gXFxcIiArIGV2ZW50LnR5cGUgKyBcXFwiLCB4PVxcXCIgKyB4ICsgXFxcIiwgeT1cXFwiICsgeSk7XFxyXFxuLy8gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcXFwiIyMjIGRyYWcgPT4gXFxcIiArIGV2ZW50LnR5cGUgKyBcXFwiLCBkZWx0YVg9XFxcIiArIGNvcmVFdmVudC5kZWx0YVggKyBcXFwiLCBkZWx0YVk9XFxcIiArIGNvcmVFdmVudC5kZWx0YVkpO1xcclxcbi8vICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXFxcIiMjIyBkcmFnIGVuZCA9PiBcXFwiICsgSlNPTi5zdHJpbmdpZnkobmV3UG9zaXRpb24pKTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRyYWdnaW5nID0gbmV3UG9zaXRpb247XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XFxyXFxuICAgICAgICAgICAgICAgIH1cXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgLy8gR2V0IG5ldyBYWVxcclxcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5ydGwpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHZhciBwb3MgPSB0aGlzLmNhbGNYWShuZXdQb3NpdGlvbi50b3AsIG5ld1Bvc2l0aW9uLmxlZnQpO1xcclxcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xcclxcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBvcyA9IHRoaXMuY2FsY1hZKG5ld1Bvc2l0aW9uLnRvcCwgbmV3UG9zaXRpb24ubGVmdCk7XFxyXFxuICAgICAgICAgICAgICAgIH1cXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgdGhpcy5sYXN0WCA9IHg7XFxyXFxuICAgICAgICAgICAgICAgIHRoaXMubGFzdFkgPSB5O1xcclxcblxcclxcbiAgICAgICAgICAgICAgICBpZiAodGhpcy54ICE9PSBwb3MueCB8fCB0aGlzLnkgIT09IHBvcy55KSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbWl0KFxcXCJtb3ZlXFxcIiwgdGhpcy5pLCBwb3MueCwgcG9zLnkpO1xcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgICAgIGlmIChldmVudC50eXBlID09PSBcXFwiZHJhZ2VuZFxcXCIgJiYgKHRoaXMucHJldmlvdXNYICE9PSB0aGlzLnggfHwgdGhpcy5wcmV2aW91c1kgIT09IHRoaXMueSkpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuJGVtaXQoXFxcIm1vdmVkXFxcIiwgdGhpcy5pLCBwb3MueCwgcG9zLnkpO1xcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgICAgIGV2ZW50QnVzLiRlbWl0KFxcXCJkcmFnRXZlbnRcXFwiLCBldmVudC50eXBlLCB0aGlzLmksIHBvcy54LCBwb3MueSwgdGhpcy5oLCB0aGlzLncpO1xcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgY2FsY1Bvc2l0aW9uOiBmdW5jdGlvbih4LCB5LCB3LCBoKSB7XFxyXFxuICAgICAgICAgICAgICAgIGNvbnN0IGNvbFdpZHRoID0gdGhpcy5jYWxjQ29sV2lkdGgoKTtcXHJcXG4gICAgICAgICAgICAgICAgLy8gYWRkIHJ0bCBzdXBwb3J0XFxyXFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnJ0bCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgdmFyIG91dCA9IHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICByaWdodDogTWF0aC5yb3VuZChjb2xXaWR0aCAqIHggKyAoeCArIDEpICogdGhpcy5tYXJnaW5bMF0pLFxcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvcDogTWF0aC5yb3VuZCh0aGlzLnJvd0hlaWdodCAqIHkgKyAoeSArIDEpICogdGhpcy5tYXJnaW5bMV0pLFxcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIDAgKiBJbmZpbml0eSA9PT0gTmFOLCB3aGljaCBjYXVzZXMgcHJvYmxlbXMgd2l0aCByZXNpemUgY29uc3RyaWFudHM7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gRml4IHRoaXMgaWYgaXQgb2NjdXJzLlxcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5vdGUgd2UgZG8gaXQgaGVyZSByYXRoZXIgdGhhbiBsYXRlciBiZWNhdXNlIE1hdGgucm91bmQoSW5maW5pdHkpIGNhdXNlcyBkZW9wdFxcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoOiB3ID09PSBJbmZpbml0eSA/IHcgOiBNYXRoLnJvdW5kKGNvbFdpZHRoICogdyArIE1hdGgubWF4KDAsIHcgLSAxKSAqIHRoaXMubWFyZ2luWzBdKSxcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IGggPT09IEluZmluaXR5ID8gaCA6IE1hdGgucm91bmQodGhpcy5yb3dIZWlnaHQgKiBoICsgTWF0aC5tYXgoMCwgaCAtIDEpICogdGhpcy5tYXJnaW5bMV0pXFxyXFxuICAgICAgICAgICAgICAgICAgICB9O1xcclxcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xcclxcbiAgICAgICAgICAgICAgICAgICAgdmFyIG91dCA9IHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBsZWZ0OiBNYXRoLnJvdW5kKGNvbFdpZHRoICogeCArICh4ICsgMSkgKiB0aGlzLm1hcmdpblswXSksXFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgdG9wOiBNYXRoLnJvdW5kKHRoaXMucm93SGVpZ2h0ICogeSArICh5ICsgMSkgKiB0aGlzLm1hcmdpblsxXSksXFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gMCAqIEluZmluaXR5ID09PSBOYU4sIHdoaWNoIGNhdXNlcyBwcm9ibGVtcyB3aXRoIHJlc2l6ZSBjb25zdHJpYW50cztcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBGaXggdGhpcyBpZiBpdCBvY2N1cnMuXFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gTm90ZSB3ZSBkbyBpdCBoZXJlIHJhdGhlciB0aGFuIGxhdGVyIGJlY2F1c2UgTWF0aC5yb3VuZChJbmZpbml0eSkgY2F1c2VzIGRlb3B0XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHcgPT09IEluZmluaXR5ID8gdyA6IE1hdGgucm91bmQoY29sV2lkdGggKiB3ICsgTWF0aC5tYXgoMCwgdyAtIDEpICogdGhpcy5tYXJnaW5bMF0pLFxcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodDogaCA9PT0gSW5maW5pdHkgPyBoIDogTWF0aC5yb3VuZCh0aGlzLnJvd0hlaWdodCAqIGggKyBNYXRoLm1heCgwLCBoIC0gMSkgKiB0aGlzLm1hcmdpblsxXSlcXHJcXG4gICAgICAgICAgICAgICAgICAgIH07XFxyXFxuICAgICAgICAgICAgICAgIH1cXHJcXG5cXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgcmV0dXJuIG91dDtcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIC8qKlxcclxcbiAgICAgICAgICAgICAqIFRyYW5zbGF0ZSB4IGFuZCB5IGNvb3JkaW5hdGVzIGZyb20gcGl4ZWxzIHRvIGdyaWQgdW5pdHMuXFxyXFxuICAgICAgICAgICAgICogQHBhcmFtICB7TnVtYmVyfSB0b3AgIFRvcCBwb3NpdGlvbiAocmVsYXRpdmUgdG8gcGFyZW50KSBpbiBwaXhlbHMuXFxyXFxuICAgICAgICAgICAgICogQHBhcmFtICB7TnVtYmVyfSBsZWZ0IExlZnQgcG9zaXRpb24gKHJlbGF0aXZlIHRvIHBhcmVudCkgaW4gcGl4ZWxzLlxcclxcbiAgICAgICAgICAgICAqIEByZXR1cm4ge09iamVjdH0geCBhbmQgeSBpbiBncmlkIHVuaXRzLlxcclxcbiAgICAgICAgICAgICAqL1xcclxcbiAgICAgICAgICAgIC8vIFRPRE8gY2hlY2sgaWYgdGhpcyBmdW5jdGlvbiBuZWVkcyBjaGFuZ2UgaW4gb3JkZXIgdG8gc3VwcG9ydCBydGwuXFxyXFxuICAgICAgICAgICAgY2FsY1hZKHRvcCwgbGVmdCkge1xcclxcbiAgICAgICAgICAgICAgICBjb25zdCBjb2xXaWR0aCA9IHRoaXMuY2FsY0NvbFdpZHRoKCk7XFxyXFxuXFxyXFxuICAgICAgICAgICAgICAgIC8vIGxlZnQgPSBjb2xXaWR0aCAqIHggKyBtYXJnaW4gKiAoeCArIDEpXFxyXFxuICAgICAgICAgICAgICAgIC8vIGwgPSBjeCArIG0oeCsxKVxcclxcbiAgICAgICAgICAgICAgICAvLyBsID0gY3ggKyBteCArIG1cXHJcXG4gICAgICAgICAgICAgICAgLy8gbCAtIG0gPSBjeCArIG14XFxyXFxuICAgICAgICAgICAgICAgIC8vIGwgLSBtID0geChjICsgbSlcXHJcXG4gICAgICAgICAgICAgICAgLy8gKGwgLSBtKSAvIChjICsgbSkgPSB4XFxyXFxuICAgICAgICAgICAgICAgIC8vIHggPSAobGVmdCAtIG1hcmdpbikgLyAoY29sZFdpZHRoICsgbWFyZ2luKVxcclxcbiAgICAgICAgICAgICAgICBsZXQgeCA9IE1hdGgucm91bmQoKGxlZnQgLSB0aGlzLm1hcmdpblswXSkgLyAoY29sV2lkdGggKyB0aGlzLm1hcmdpblswXSkpO1xcclxcbiAgICAgICAgICAgICAgICBsZXQgeSA9IE1hdGgucm91bmQoKHRvcCAtIHRoaXMubWFyZ2luWzFdKSAvICh0aGlzLnJvd0hlaWdodCArIHRoaXMubWFyZ2luWzFdKSk7XFxyXFxuXFxyXFxuICAgICAgICAgICAgICAgIC8vIENhcHBpbmdcXHJcXG4gICAgICAgICAgICAgICAgeCA9IE1hdGgubWF4KE1hdGgubWluKHgsIHRoaXMuY29scyAtIHRoaXMudyksIDApO1xcclxcbiAgICAgICAgICAgICAgICB5ID0gTWF0aC5tYXgoTWF0aC5taW4oeSwgdGhpcy5tYXhSb3dzIC0gdGhpcy5oKSwgMCk7XFxyXFxuXFxyXFxuICAgICAgICAgICAgICAgIHJldHVybiB7eCwgeX07XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICAvLyBIZWxwZXIgZm9yIGdlbmVyYXRpbmcgY29sdW1uIHdpZHRoXFxyXFxuICAgICAgICAgICAgY2FsY0NvbFdpZHRoKCkge1xcclxcbiAgICAgICAgICAgICAgICB2YXIgY29sV2lkdGggPSAodGhpcy5jb250YWluZXJXaWR0aCAtICh0aGlzLm1hcmdpblswXSAqICh0aGlzLmNvbHMgKyAxKSkpIC8gdGhpcy5jb2xzO1xcclxcbi8vICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxcXCIjIyMgQ09MUz1cXFwiICsgdGhpcy5jb2xzICsgXFxcIiBDT0wgV0lEVEg9XFxcIiArIGNvbFdpZHRoKTtcXHJcXG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbFdpZHRoO1xcclxcbiAgICAgICAgICAgIH0sXFxyXFxuXFxyXFxuICAgICAgICAgICAgLyoqXFxyXFxuICAgICAgICAgICAgICogR2l2ZW4gYSBoZWlnaHQgYW5kIHdpZHRoIGluIHBpeGVsIHZhbHVlcywgY2FsY3VsYXRlIGdyaWQgdW5pdHMuXFxyXFxuICAgICAgICAgICAgICogQHBhcmFtICB7TnVtYmVyfSBoZWlnaHQgSGVpZ2h0IGluIHBpeGVscy5cXHJcXG4gICAgICAgICAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9IHdpZHRoICBXaWR0aCBpbiBwaXhlbHMuXFxyXFxuICAgICAgICAgICAgICogQHJldHVybiB7T2JqZWN0fSB3LCBoIGFzIGdyaWQgdW5pdHMuXFxyXFxuICAgICAgICAgICAgICovXFxyXFxuICAgICAgICAgICAgY2FsY1dIKGhlaWdodCwgd2lkdGgpIHtcXHJcXG4gICAgICAgICAgICAgICAgY29uc3QgY29sV2lkdGggPSB0aGlzLmNhbGNDb2xXaWR0aCgpO1xcclxcblxcclxcbiAgICAgICAgICAgICAgICAvLyB3aWR0aCA9IGNvbFdpZHRoICogdyAtIChtYXJnaW4gKiAodyAtIDEpKVxcclxcbiAgICAgICAgICAgICAgICAvLyAuLi5cXHJcXG4gICAgICAgICAgICAgICAgLy8gdyA9ICh3aWR0aCArIG1hcmdpbikgLyAoY29sV2lkdGggKyBtYXJnaW4pXFxyXFxuICAgICAgICAgICAgICAgIGxldCB3ID0gTWF0aC5yb3VuZCgod2lkdGggKyB0aGlzLm1hcmdpblswXSkgLyAoY29sV2lkdGggKyB0aGlzLm1hcmdpblswXSkpO1xcclxcbiAgICAgICAgICAgICAgICBsZXQgaCA9IE1hdGgucm91bmQoKGhlaWdodCArIHRoaXMubWFyZ2luWzFdKSAvICh0aGlzLnJvd0hlaWdodCArIHRoaXMubWFyZ2luWzFdKSk7XFxyXFxuXFxyXFxuICAgICAgICAgICAgICAgIC8vIENhcHBpbmdcXHJcXG4gICAgICAgICAgICAgICAgdyA9IE1hdGgubWF4KE1hdGgubWluKHcsIHRoaXMuY29scyAtIHRoaXMueCksIDApO1xcclxcbiAgICAgICAgICAgICAgICBoID0gTWF0aC5tYXgoTWF0aC5taW4oaCwgdGhpcy5tYXhSb3dzIC0gdGhpcy55KSwgMCk7XFxyXFxuICAgICAgICAgICAgICAgIHJldHVybiB7dywgaH07XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICB1cGRhdGVXaWR0aDogZnVuY3Rpb24od2lkdGgsIGNvbE51bSkge1xcclxcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnRhaW5lcldpZHRoID0gd2lkdGg7XFxyXFxuICAgICAgICAgICAgICAgIGlmIChjb2xOdW0gIT09IHVuZGVmaW5lZCAmJiBjb2xOdW0gIT09IG51bGwpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29scyA9IGNvbE51bTtcXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgY29tcGFjdDogZnVuY3Rpb24oKSB7XFxyXFxuICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRlU3R5bGUoKTtcXHJcXG4gICAgICAgICAgICB9XFxyXFxuICAgICAgICB9LFxcclxcbiAgICB9XFxyXFxuPC9zY3JpcHQ+XFxyXFxuXCJdLFwic291cmNlUm9vdFwiOlwid2VicGFjazovL1wifV0pO1xuXG4vLyBleHBvcnRzXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi9+L3Z1ZS1sb2FkZXIvbGliL3N0eWxlLXJld3JpdGVyLmpzP2lkPWRhdGEtdi1lODAwYWIxOCEuL34vdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL3NyYy9HcmlkSXRlbS52dWVcbi8vIG1vZHVsZSBpZCA9IDIwXG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0="); - -/***/ }, -/* 21 */ -/***/ function(module, exports, __webpack_require__) { - -"use strict"; -eval("/**\n * Resize detection strategy that injects objects to elements in order to detect resize events.\n * Heavily inspired by: http://www.backalleycoder.com/2013/03/18/cross-browser-event-based-element-resize-detection/\n */\n\n\"use strict\";\n\nvar browserDetector = __webpack_require__(5);\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\n if(!reporter) {\n throw new Error(\"Missing required dependency: reporter.\");\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 if(!getObject(element)) {\n throw new Error(\"Element is not detectable by this strategy.\");\n }\n\n function listenerProxy() {\n listener(element);\n }\n\n if(browserDetector.isIE(8)) {\n //IE 8 does not support object, but supports the resize event directly on elements.\n getState(element).object = {\n proxy: listenerProxy\n };\n element.attachEvent(\"onresize\", listenerProxy);\n } else {\n var object = getObject(element);\n object.contentDocument.defaultView.addEventListener(\"resize\", listenerProxy);\n }\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 var debug = options.debug;\n\n function injectObject(element, callback) {\n var OBJECT_STYLE = \"display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none; padding: 0; margin: 0; opacity: 0; z-index: -1000; pointer-events: none;\";\n\n //The target element needs to be positioned (everything except static) so the absolute positioned object will be positioned relative to the target element.\n\n // Position altering may be performed directly or on object load, depending on if style resolution is possible directly or not.\n var positionCheckPerformed = false;\n\n // The element may not yet be attached to the DOM, and therefore the style object may be empty in some browsers.\n // Since the style object is a reference, it will be updated as soon as the element is attached to the DOM.\n var style = window.getComputedStyle(element);\n var width = element.offsetWidth;\n var height = element.offsetHeight;\n\n getState(element).startSize = {\n width: width,\n height: height\n };\n\n function mutateDom() {\n function alterPositionStyles() {\n if(style.position === \"static\") {\n element.style.position = \"relative\";\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 onObjectLoad() {\n // The object has been loaded, which means that the element now is guaranteed to be attached to the DOM.\n if (!positionCheckPerformed) {\n alterPositionStyles();\n }\n\n /*jshint validthis: true */\n\n function getDocument(element, callback) {\n //Opera 12 seem to call the object.onload before the actual document has been created.\n //So if it is not present, poll it with an timeout until it is present.\n //TODO: Could maybe be handled better with object.onreadystatechange or similar.\n if(!element.contentDocument) {\n setTimeout(function checkForObjectDocument() {\n getDocument(element, callback);\n }, 100);\n\n return;\n }\n\n callback(element.contentDocument);\n }\n\n //Mutating the object element here seems to fire another load event.\n //Mutating the inner document of the object element is fine though.\n var objectElement = this;\n\n //Create the style element to be added to the object.\n getDocument(objectElement, function onObjectDocumentReady(objectDocument) {\n //Notify that the element is ready to be listened to.\n callback(element);\n });\n }\n\n // The element may be detached from the DOM, and some browsers does not support style resolving of detached elements.\n // The alterPositionStyles needs to be delayed until we know the element has been attached to the DOM (which we are sure of when the onObjectLoad has been fired), if style resolution is not possible.\n if (style.position !== \"\") {\n alterPositionStyles(style);\n positionCheckPerformed = true;\n }\n\n //Add an object element as a child to the target element that will be listened to for resize events.\n var object = document.createElement(\"object\");\n object.style.cssText = OBJECT_STYLE;\n object.tabIndex = -1;\n object.type = \"text/html\";\n object.onload = onObjectLoad;\n\n //Safari: This must occur before adding the object to the DOM.\n //IE: Does not like that this happens before, even if it is also added after.\n if(!browserDetector.isIE()) {\n object.data = \"about:blank\";\n }\n\n element.appendChild(object);\n getState(element).object = object;\n\n //IE: This must occur after adding the object to the DOM.\n if(browserDetector.isIE()) {\n object.data = \"about:blank\";\n }\n }\n\n if(batchProcessor) {\n batchProcessor.add(mutateDom);\n } else {\n mutateDom();\n }\n }\n\n if(browserDetector.isIE(8)) {\n //IE 8 does not support objects properly. Luckily they do support the resize event.\n //So do not inject the object and notify that the element is already ready to be listened to.\n //The event handler for the resize event is attached in the utils.addListener instead.\n callback(element);\n } else {\n injectObject(element, callback);\n }\n }\n\n /**\n * Returns the child object of the target element.\n * @private\n * @param {element} element The target element.\n * @returns The object element of the target.\n */\n function getObject(element) {\n return getState(element).object;\n }\n\n function uninstall(element) {\n if(browserDetector.isIE(8)) {\n element.detachEvent(\"onresize\", getState(element).object.proxy);\n } else {\n element.removeChild(getObject(element));\n }\n delete getState(element).object;\n }\n\n return {\n makeDetectable: makeDetectable,\n addListener: addListener,\n uninstall: uninstall\n };\n};\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9+L2VsZW1lbnQtcmVzaXplLWRldGVjdG9yL3NyYy9kZXRlY3Rpb24tc3RyYXRlZ3kvb2JqZWN0LmpzPzllNDgiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsU0FBUztBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsUUFBUTtBQUN2QixlQUFlLFNBQVM7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLCtDQUErQyxvQkFBb0IsUUFBUSxTQUFTLGFBQWEsY0FBYyxjQUFjLFlBQVksV0FBVyxZQUFZLGdCQUFnQixzQkFBc0I7O0FBRXRNOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2Qjs7QUFFN0I7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiMjEuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFJlc2l6ZSBkZXRlY3Rpb24gc3RyYXRlZ3kgdGhhdCBpbmplY3RzIG9iamVjdHMgdG8gZWxlbWVudHMgaW4gb3JkZXIgdG8gZGV0ZWN0IHJlc2l6ZSBldmVudHMuXG4gKiBIZWF2aWx5IGluc3BpcmVkIGJ5OiBodHRwOi8vd3d3LmJhY2thbGxleWNvZGVyLmNvbS8yMDEzLzAzLzE4L2Nyb3NzLWJyb3dzZXItZXZlbnQtYmFzZWQtZWxlbWVudC1yZXNpemUtZGV0ZWN0aW9uL1xuICovXG5cblwidXNlIHN0cmljdFwiO1xuXG52YXIgYnJvd3NlckRldGVjdG9yID0gcmVxdWlyZShcIi4uL2Jyb3dzZXItZGV0ZWN0b3JcIik7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24ob3B0aW9ucykge1xuICAgIG9wdGlvbnMgICAgICAgICAgICAgPSBvcHRpb25zIHx8IHt9O1xuICAgIHZhciByZXBvcnRlciAgICAgICAgPSBvcHRpb25zLnJlcG9ydGVyO1xuICAgIHZhciBiYXRjaFByb2Nlc3NvciAgPSBvcHRpb25zLmJhdGNoUHJvY2Vzc29yO1xuICAgIHZhciBnZXRTdGF0ZSAgICAgICAgPSBvcHRpb25zLnN0YXRlSGFuZGxlci5nZXRTdGF0ZTtcblxuICAgIGlmKCFyZXBvcnRlcikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIHJlcXVpcmVkIGRlcGVuZGVuY3k6IHJlcG9ydGVyLlwiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBZGRzIGEgcmVzaXplIGV2ZW50IGxpc3RlbmVyIHRvIHRoZSBlbGVtZW50LlxuICAgICAqIEBwdWJsaWNcbiAgICAgKiBAcGFyYW0ge2VsZW1lbnR9IGVsZW1lbnQgVGhlIGVsZW1lbnQgdGhhdCBzaG91bGQgaGF2ZSB0aGUgbGlzdGVuZXIgYWRkZWQuXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gbGlzdGVuZXIgVGhlIGxpc3RlbmVyIGNhbGxiYWNrIHRvIGJlIGNhbGxlZCBmb3IgZWFjaCByZXNpemUgZXZlbnQgb2YgdGhlIGVsZW1lbnQuIFRoZSBlbGVtZW50IHdpbGwgYmUgZ2l2ZW4gYXMgYSBwYXJhbWV0ZXIgdG8gdGhlIGxpc3RlbmVyIGNhbGxiYWNrLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGFkZExpc3RlbmVyKGVsZW1lbnQsIGxpc3RlbmVyKSB7XG4gICAgICAgIGlmKCFnZXRPYmplY3QoZWxlbWVudCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkVsZW1lbnQgaXMgbm90IGRldGVjdGFibGUgYnkgdGhpcyBzdHJhdGVneS5cIik7XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBsaXN0ZW5lclByb3h5KCkge1xuICAgICAgICAgICAgbGlzdGVuZXIoZWxlbWVudCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZihicm93c2VyRGV0ZWN0b3IuaXNJRSg4KSkge1xuICAgICAgICAgICAgLy9JRSA4IGRvZXMgbm90IHN1cHBvcnQgb2JqZWN0LCBidXQgc3VwcG9ydHMgdGhlIHJlc2l6ZSBldmVudCBkaXJlY3RseSBvbiBlbGVtZW50cy5cbiAgICAgICAgICAgIGdldFN0YXRlKGVsZW1lbnQpLm9iamVjdCA9IHtcbiAgICAgICAgICAgICAgICBwcm94eTogbGlzdGVuZXJQcm94eVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGVsZW1lbnQuYXR0YWNoRXZlbnQoXCJvbnJlc2l6ZVwiLCBsaXN0ZW5lclByb3h5KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhciBvYmplY3QgPSBnZXRPYmplY3QoZWxlbWVudCk7XG4gICAgICAgICAgICBvYmplY3QuY29udGVudERvY3VtZW50LmRlZmF1bHRWaWV3LmFkZEV2ZW50TGlzdGVuZXIoXCJyZXNpemVcIiwgbGlzdGVuZXJQcm94eSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNYWtlcyBhbiBlbGVtZW50IGRldGVjdGFibGUgYW5kIHJlYWR5IHRvIGJlIGxpc3RlbmVkIGZvciByZXNpemUgZXZlbnRzLiBXaWxsIGNhbGwgdGhlIGNhbGxiYWNrIHdoZW4gdGhlIGVsZW1lbnQgaXMgcmVhZHkgdG8gYmUgbGlzdGVuZWQgZm9yIHJlc2l6ZSBjaGFuZ2VzLlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtvYmplY3R9IG9wdGlvbnMgT3B0aW9uYWwgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtIHtlbGVtZW50fSBlbGVtZW50IFRoZSBlbGVtZW50IHRvIG1ha2UgZGV0ZWN0YWJsZVxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBiZSBjYWxsZWQgd2hlbiB0aGUgZWxlbWVudCBpcyByZWFkeSB0byBiZSBsaXN0ZW5lZCBmb3IgcmVzaXplIGNoYW5nZXMuIFdpbGwgYmUgY2FsbGVkIHdpdGggdGhlIGVsZW1lbnQgYXMgZmlyc3QgcGFyYW1ldGVyLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1ha2VEZXRlY3RhYmxlKG9wdGlvbnMsIGVsZW1lbnQsIGNhbGxiYWNrKSB7XG4gICAgICAgIGlmICghY2FsbGJhY2spIHtcbiAgICAgICAgICAgIGNhbGxiYWNrID0gZWxlbWVudDtcbiAgICAgICAgICAgIGVsZW1lbnQgPSBvcHRpb25zO1xuICAgICAgICAgICAgb3B0aW9ucyA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgICAgICAgdmFyIGRlYnVnID0gb3B0aW9ucy5kZWJ1ZztcblxuICAgICAgICBmdW5jdGlvbiBpbmplY3RPYmplY3QoZWxlbWVudCwgY2FsbGJhY2spIHtcbiAgICAgICAgICAgIHZhciBPQkpFQ1RfU1RZTEUgPSBcImRpc3BsYXk6IGJsb2NrOyBwb3NpdGlvbjogYWJzb2x1dGU7IHRvcDogMDsgbGVmdDogMDsgd2lkdGg6IDEwMCU7IGhlaWdodDogMTAwJTsgYm9yZGVyOiBub25lOyBwYWRkaW5nOiAwOyBtYXJnaW46IDA7IG9wYWNpdHk6IDA7IHotaW5kZXg6IC0xMDAwOyBwb2ludGVyLWV2ZW50czogbm9uZTtcIjtcblxuICAgICAgICAgICAgLy9UaGUgdGFyZ2V0IGVsZW1lbnQgbmVlZHMgdG8gYmUgcG9zaXRpb25lZCAoZXZlcnl0aGluZyBleGNlcHQgc3RhdGljKSBzbyB0aGUgYWJzb2x1dGUgcG9zaXRpb25lZCBvYmplY3Qgd2lsbCBiZSBwb3NpdGlvbmVkIHJlbGF0aXZlIHRvIHRoZSB0YXJnZXQgZWxlbWVudC5cblxuICAgICAgICAgICAgLy8gUG9zaXRpb24gYWx0ZXJpbmcgbWF5IGJlIHBlcmZvcm1lZCBkaXJlY3RseSBvciBvbiBvYmplY3QgbG9hZCwgZGVwZW5kaW5nIG9uIGlmIHN0eWxlIHJlc29sdXRpb24gaXMgcG9zc2libGUgZGlyZWN0bHkgb3Igbm90LlxuICAgICAgICAgICAgdmFyIHBvc2l0aW9uQ2hlY2tQZXJmb3JtZWQgPSBmYWxzZTtcblxuICAgICAgICAgICAgLy8gVGhlIGVsZW1lbnQgbWF5IG5vdCB5ZXQgYmUgYXR0YWNoZWQgdG8gdGhlIERPTSwgYW5kIHRoZXJlZm9yZSB0aGUgc3R5bGUgb2JqZWN0IG1heSBiZSBlbXB0eSBpbiBzb21lIGJyb3dzZXJzLlxuICAgICAgICAgICAgLy8gU2luY2UgdGhlIHN0eWxlIG9iamVjdCBpcyBhIHJlZmVyZW5jZSwgaXQgd2lsbCBiZSB1cGRhdGVkIGFzIHNvb24gYXMgdGhlIGVsZW1lbnQgaXMgYXR0YWNoZWQgdG8gdGhlIERPTS5cbiAgICAgICAgICAgIHZhciBzdHlsZSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpO1xuICAgICAgICAgICAgdmFyIHdpZHRoID0gZWxlbWVudC5vZmZzZXRXaWR0aDtcbiAgICAgICAgICAgIHZhciBoZWlnaHQgPSBlbGVtZW50Lm9mZnNldEhlaWdodDtcblxuICAgICAgICAgICAgZ2V0U3RhdGUoZWxlbWVudCkuc3RhcnRTaXplID0ge1xuICAgICAgICAgICAgICAgIHdpZHRoOiB3aWR0aCxcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IGhlaWdodFxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgZnVuY3Rpb24gbXV0YXRlRG9tKCkge1xuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGFsdGVyUG9zaXRpb25TdHlsZXMoKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmKHN0eWxlLnBvc2l0aW9uID09PSBcInN0YXRpY1wiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnN0eWxlLnBvc2l0aW9uID0gXCJyZWxhdGl2ZVwiO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVtb3ZlUmVsYXRpdmVTdHlsZXMgPSBmdW5jdGlvbihyZXBvcnRlciwgZWxlbWVudCwgc3R5bGUsIHByb3BlcnR5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gZ2V0TnVtZXJpY2FsVmFsdWUodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlLnJlcGxhY2UoL1teLVxcZFxcLl0vZywgXCJcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHZhbHVlID0gc3R5bGVbcHJvcGVydHldO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYodmFsdWUgIT09IFwiYXV0b1wiICYmIGdldE51bWVyaWNhbFZhbHVlKHZhbHVlKSAhPT0gXCIwXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0ZXIud2FybihcIkFuIGVsZW1lbnQgdGhhdCBpcyBwb3NpdGlvbmVkIHN0YXRpYyBoYXMgc3R5bGUuXCIgKyBwcm9wZXJ0eSArIFwiPVwiICsgdmFsdWUgKyBcIiB3aGljaCBpcyBpZ25vcmVkIGR1ZSB0byB0aGUgc3RhdGljIHBvc2l0aW9uaW5nLiBUaGUgZWxlbWVudCB3aWxsIG5lZWQgdG8gYmUgcG9zaXRpb25lZCByZWxhdGl2ZSwgc28gdGhlIHN0eWxlLlwiICsgcHJvcGVydHkgKyBcIiB3aWxsIGJlIHNldCB0byAwLiBFbGVtZW50OiBcIiwgZWxlbWVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuc3R5bGVbcHJvcGVydHldID0gMDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAvL0NoZWNrIHNvIHRoYXQgdGhlcmUgYXJlIG5vIGFjY2lkZW50YWwgc3R5bGVzIHRoYXQgd2lsbCBtYWtlIHRoZSBlbGVtZW50IHN0eWxlZCBkaWZmZXJlbnRseSBub3cgdGhhdCBpcyBpcyByZWxhdGl2ZS5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vSWYgdGhlcmUgYXJlIGFueSwgc2V0IHRoZW0gdG8gMCAodGhpcyBzaG91bGQgYmUgb2theSB3aXRoIHRoZSB1c2VyIHNpbmNlIHRoZSBzdHlsZSBwcm9wZXJ0aWVzIGRpZCBub3RoaW5nIGJlZm9yZSBbc2luY2UgdGhlIGVsZW1lbnQgd2FzIHBvc2l0aW9uZWQgc3RhdGljXSBhbnl3YXkpLlxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlUmVsYXRpdmVTdHlsZXMocmVwb3J0ZXIsIGVsZW1lbnQsIHN0eWxlLCBcInRvcFwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZVJlbGF0aXZlU3R5bGVzKHJlcG9ydGVyLCBlbGVtZW50LCBzdHlsZSwgXCJyaWdodFwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZVJlbGF0aXZlU3R5bGVzKHJlcG9ydGVyLCBlbGVtZW50LCBzdHlsZSwgXCJib3R0b21cIik7XG4gICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVSZWxhdGl2ZVN0eWxlcyhyZXBvcnRlciwgZWxlbWVudCwgc3R5bGUsIFwibGVmdFwiKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIG9uT2JqZWN0TG9hZCgpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gVGhlIG9iamVjdCBoYXMgYmVlbiBsb2FkZWQsIHdoaWNoIG1lYW5zIHRoYXQgdGhlIGVsZW1lbnQgbm93IGlzIGd1YXJhbnRlZWQgdG8gYmUgYXR0YWNoZWQgdG8gdGhlIERPTS5cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFwb3NpdGlvbkNoZWNrUGVyZm9ybWVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhbHRlclBvc2l0aW9uU3R5bGVzKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvKmpzaGludCB2YWxpZHRoaXM6IHRydWUgKi9cblxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBnZXREb2N1bWVudChlbGVtZW50LCBjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy9PcGVyYSAxMiBzZWVtIHRvIGNhbGwgdGhlIG9iamVjdC5vbmxvYWQgYmVmb3JlIHRoZSBhY3R1YWwgZG9jdW1lbnQgaGFzIGJlZW4gY3JlYXRlZC5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vU28gaWYgaXQgaXMgbm90IHByZXNlbnQsIHBvbGwgaXQgd2l0aCBhbiB0aW1lb3V0IHVudGlsIGl0IGlzIHByZXNlbnQuXG4gICAgICAgICAgICAgICAgICAgICAgICAvL1RPRE86IENvdWxkIG1heWJlIGJlIGhhbmRsZWQgYmV0dGVyIHdpdGggb2JqZWN0Lm9ucmVhZHlzdGF0ZWNoYW5nZSBvciBzaW1pbGFyLlxuICAgICAgICAgICAgICAgICAgICAgICAgaWYoIWVsZW1lbnQuY29udGVudERvY3VtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiBjaGVja0Zvck9iamVjdERvY3VtZW50KCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXREb2N1bWVudChlbGVtZW50LCBjYWxsYmFjayk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgMTAwKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2soZWxlbWVudC5jb250ZW50RG9jdW1lbnQpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgLy9NdXRhdGluZyB0aGUgb2JqZWN0IGVsZW1lbnQgaGVyZSBzZWVtcyB0byBmaXJlIGFub3RoZXIgbG9hZCBldmVudC5cbiAgICAgICAgICAgICAgICAgICAgLy9NdXRhdGluZyB0aGUgaW5uZXIgZG9jdW1lbnQgb2YgdGhlIG9iamVjdCBlbGVtZW50IGlzIGZpbmUgdGhvdWdoLlxuICAgICAgICAgICAgICAgICAgICB2YXIgb2JqZWN0RWxlbWVudCA9IHRoaXM7XG5cbiAgICAgICAgICAgICAgICAgICAgLy9DcmVhdGUgdGhlIHN0eWxlIGVsZW1lbnQgdG8gYmUgYWRkZWQgdG8gdGhlIG9iamVjdC5cbiAgICAgICAgICAgICAgICAgICAgZ2V0RG9jdW1lbnQob2JqZWN0RWxlbWVudCwgZnVuY3Rpb24gb25PYmplY3REb2N1bWVudFJlYWR5KG9iamVjdERvY3VtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvL05vdGlmeSB0aGF0IHRoZSBlbGVtZW50IGlzIHJlYWR5IHRvIGJlIGxpc3RlbmVkIHRvLlxuICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2soZWxlbWVudCk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIFRoZSBlbGVtZW50IG1heSBiZSBkZXRhY2hlZCBmcm9tIHRoZSBET00sIGFuZCBzb21lIGJyb3dzZXJzIGRvZXMgbm90IHN1cHBvcnQgc3R5bGUgcmVzb2x2aW5nIG9mIGRldGFjaGVkIGVsZW1lbnRzLlxuICAgICAgICAgICAgICAgIC8vIFRoZSBhbHRlclBvc2l0aW9uU3R5bGVzIG5lZWRzIHRvIGJlIGRlbGF5ZWQgdW50aWwgd2Uga25vdyB0aGUgZWxlbWVudCBoYXMgYmVlbiBhdHRhY2hlZCB0byB0aGUgRE9NICh3aGljaCB3ZSBhcmUgc3VyZSBvZiB3aGVuIHRoZSBvbk9iamVjdExvYWQgaGFzIGJlZW4gZmlyZWQpLCBpZiBzdHlsZSByZXNvbHV0aW9uIGlzIG5vdCBwb3NzaWJsZS5cbiAgICAgICAgICAgICAgICBpZiAoc3R5bGUucG9zaXRpb24gIT09IFwiXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgYWx0ZXJQb3NpdGlvblN0eWxlcyhzdHlsZSk7XG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uQ2hlY2tQZXJmb3JtZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vQWRkIGFuIG9iamVjdCBlbGVtZW50IGFzIGEgY2hpbGQgdG8gdGhlIHRhcmdldCBlbGVtZW50IHRoYXQgd2lsbCBiZSBsaXN0ZW5lZCB0byBmb3IgcmVzaXplIGV2ZW50cy5cbiAgICAgICAgICAgICAgICB2YXIgb2JqZWN0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcIm9iamVjdFwiKTtcbiAgICAgICAgICAgICAgICBvYmplY3Quc3R5bGUuY3NzVGV4dCA9IE9CSkVDVF9TVFlMRTtcbiAgICAgICAgICAgICAgICBvYmplY3QudGFiSW5kZXggPSAtMTtcbiAgICAgICAgICAgICAgICBvYmplY3QudHlwZSA9IFwidGV4dC9odG1sXCI7XG4gICAgICAgICAgICAgICAgb2JqZWN0Lm9ubG9hZCA9IG9uT2JqZWN0TG9hZDtcblxuICAgICAgICAgICAgICAgIC8vU2FmYXJpOiBUaGlzIG11c3Qgb2NjdXIgYmVmb3JlIGFkZGluZyB0aGUgb2JqZWN0IHRvIHRoZSBET00uXG4gICAgICAgICAgICAgICAgLy9JRTogRG9lcyBub3QgbGlrZSB0aGF0IHRoaXMgaGFwcGVucyBiZWZvcmUsIGV2ZW4gaWYgaXQgaXMgYWxzbyBhZGRlZCBhZnRlci5cbiAgICAgICAgICAgICAgICBpZighYnJvd3NlckRldGVjdG9yLmlzSUUoKSkge1xuICAgICAgICAgICAgICAgICAgICBvYmplY3QuZGF0YSA9IFwiYWJvdXQ6YmxhbmtcIjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBlbGVtZW50LmFwcGVuZENoaWxkKG9iamVjdCk7XG4gICAgICAgICAgICAgICAgZ2V0U3RhdGUoZWxlbWVudCkub2JqZWN0ID0gb2JqZWN0O1xuXG4gICAgICAgICAgICAgICAgLy9JRTogVGhpcyBtdXN0IG9jY3VyIGFmdGVyIGFkZGluZyB0aGUgb2JqZWN0IHRvIHRoZSBET00uXG4gICAgICAgICAgICAgICAgaWYoYnJvd3NlckRldGVjdG9yLmlzSUUoKSkge1xuICAgICAgICAgICAgICAgICAgICBvYmplY3QuZGF0YSA9IFwiYWJvdXQ6YmxhbmtcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmKGJhdGNoUHJvY2Vzc29yKSB7XG4gICAgICAgICAgICAgICAgYmF0Y2hQcm9jZXNzb3IuYWRkKG11dGF0ZURvbSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG11dGF0ZURvbSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYoYnJvd3NlckRldGVjdG9yLmlzSUUoOCkpIHtcbiAgICAgICAgICAgIC8vSUUgOCBkb2VzIG5vdCBzdXBwb3J0IG9iamVjdHMgcHJvcGVybHkuIEx1Y2tpbHkgdGhleSBkbyBzdXBwb3J0IHRoZSByZXNpemUgZXZlbnQuXG4gICAgICAgICAgICAvL1NvIGRvIG5vdCBpbmplY3QgdGhlIG9iamVjdCBhbmQgbm90aWZ5IHRoYXQgdGhlIGVsZW1lbnQgaXMgYWxyZWFkeSByZWFkeSB0byBiZSBsaXN0ZW5lZCB0by5cbiAgICAgICAgICAgIC8vVGhlIGV2ZW50IGhhbmRsZXIgZm9yIHRoZSByZXNpemUgZXZlbnQgaXMgYXR0YWNoZWQgaW4gdGhlIHV0aWxzLmFkZExpc3RlbmVyIGluc3RlYWQuXG4gICAgICAgICAgICBjYWxsYmFjayhlbGVtZW50KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGluamVjdE9iamVjdChlbGVtZW50LCBjYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBjaGlsZCBvYmplY3Qgb2YgdGhlIHRhcmdldCBlbGVtZW50LlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtlbGVtZW50fSBlbGVtZW50IFRoZSB0YXJnZXQgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyBUaGUgb2JqZWN0IGVsZW1lbnQgb2YgdGhlIHRhcmdldC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRPYmplY3QoZWxlbWVudCkge1xuICAgICAgICByZXR1cm4gZ2V0U3RhdGUoZWxlbWVudCkub2JqZWN0O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHVuaW5zdGFsbChlbGVtZW50KSB7XG4gICAgICAgIGlmKGJyb3dzZXJEZXRlY3Rvci5pc0lFKDgpKSB7XG4gICAgICAgICAgICBlbGVtZW50LmRldGFjaEV2ZW50KFwib25yZXNpemVcIiwgZ2V0U3RhdGUoZWxlbWVudCkub2JqZWN0LnByb3h5KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGVsZW1lbnQucmVtb3ZlQ2hpbGQoZ2V0T2JqZWN0KGVsZW1lbnQpKTtcbiAgICAgICAgfVxuICAgICAgICBkZWxldGUgZ2V0U3RhdGUoZWxlbWVudCkub2JqZWN0O1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICAgIG1ha2VEZXRlY3RhYmxlOiBtYWtlRGV0ZWN0YWJsZSxcbiAgICAgICAgYWRkTGlzdGVuZXI6IGFkZExpc3RlbmVyLFxuICAgICAgICB1bmluc3RhbGw6IHVuaW5zdGFsbFxuICAgIH07XG59O1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2VsZW1lbnQtcmVzaXplLWRldGVjdG9yL3NyYy9kZXRlY3Rpb24tc3RyYXRlZ3kvb2JqZWN0LmpzXG4vLyBtb2R1bGUgaWQgPSAyMVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwic291cmNlUm9vdCI6IiJ9"); - -/***/ }, -/* 22 */ -/***/ function(module, exports, __webpack_require__) { - -"use strict"; -eval("/**\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 = __webpack_require__(6).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 // 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 var styleId = \"erd_scroll_detection_scrollbar_style\";\n var detectionContainerClass = \"erd_scroll_detection_container\";\n injectScrollStyle(styleId, detectionContainerClass);\n\n function getScrollbarSizes() {\n var width = 500;\n var height = 500;\n\n var child = document.createElement(\"div\");\n child.style.cssText = \"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 = \"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(styleId, containerClass) {\n function injectStyle(style, method) {\n method = method || function (element) {\n document.head.appendChild(element);\n };\n\n var styleElement = document.createElement(\"style\");\n styleElement.innerHTML = style;\n styleElement.id = styleId;\n method(styleElement);\n return styleElement;\n }\n\n if (!document.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 { display: none; }\\n\\n\";\n style += \".\" + containerAnimationActiveClass + \" { -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 return element === element.ownerDocument.body || element.ownerDocument.body.contains(element);\n }\n return !isInDocument(element);\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 return getComputedStyle(container).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 = 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 = \"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.position = \"relative\";\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 = \"position: absolute; flex: none; overflow: hidden; z-index: -1; visibility: hidden; width: 100%; height: 100%; left: 0px; top: 0px;\";\n var containerStyle = \"position: absolute; flex: none; overflow: hidden; z-index: -1; visibility: hidden; \" + getLeftTopBottomRightCssText(-(1 + scrollbarWidth), -(1 + scrollbarHeight), -scrollbarHeight, -scrollbarWidth);\n var expandStyle = \"position: absolute; flex: none; overflow: scroll; z-index: -1; visibility: hidden; width: 100%; height: 100%;\";\n var shrinkStyle = \"position: absolute; flex: none; overflow: scroll; z-index: -1; visibility: hidden; width: 100%; height: 100%;\";\n var expandChildStyle = \"position: absolute; left: 0; top: 0;\";\n var shrinkChildStyle = \"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 getState(element).onExpand && getState(element).onExpand();\n }\n\n function onShrinkScroll() {\n getState(element).onShrink && getState(element).onShrink();\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.width = expandWidth + \"px\";\n expandChild.style.height = expandHeight + \"px\";\n }\n\n function updateDetectorElements(done) {\n var width = element.offsetWidth;\n var height = element.offsetHeight;\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 (!getState(element)) {\n debug(\"Aborting because element has been uninstalled\");\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 if (!getState(element)) {\n debug(\"Aborting because element has been uninstalled\");\n return;\n }\n\n positionScrollbars(element, width, height);\n });\n\n if (done) {\n batchProcessor.add(2, function () {\n if (!getState(element)) {\n debug(\"Aborting because element has been uninstalled\");\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 the 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 var width = element.offsetWidth;\n var height = element.offsetHeight;\n\n if (width !== element.lastWidth || height !== element.lastHeight) {\n debug(\"Element size changed.\");\n updateDetectorElements(notifyListenersIfNeeded);\n } else {\n debug(\"Element size has not changed (\" + width + \"x\" + height + \").\");\n }\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 };\n};\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9+L2VsZW1lbnQtcmVzaXplLWRldGVjdG9yL3NyYy9kZXRlY3Rpb24tc3RyYXRlZ3kvc2Nyb2xsLmpzP2Y5YzEiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0Esa0RBQWtELDBCQUEwQiw0QkFBNEIsb0JBQW9CLFdBQVcsWUFBWTs7QUFFbko7QUFDQSxzREFBc0Qsd0JBQXdCLDBCQUEwQixrQkFBa0Isa0JBQWtCLHlCQUF5QiwyQkFBMkIsb0JBQW9CLFdBQVcsWUFBWTs7QUFFM087O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0VBQXdFLGVBQWUsRUFBRTtBQUN6Riw4REFBOEQsa0NBQWtDLDBCQUEwQix5REFBeUQsaURBQWlELEVBQUU7QUFDdE8sMkVBQTJFLEtBQUssWUFBWSxFQUFFLE1BQU0sWUFBWSxFQUFFLE9BQU8sWUFBWSxFQUFFLEVBQUU7QUFDekksMkVBQTJFLEtBQUssWUFBWSxFQUFFLE1BQU0sWUFBWSxFQUFFLE9BQU8sWUFBWSxFQUFFLEVBQUU7QUFDekk7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVB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Q0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6IjIyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBSZXNpemUgZGV0ZWN0aW9uIHN0cmF0ZWd5IHRoYXQgaW5qZWN0cyBkaXZzIHRvIGVsZW1lbnRzIGluIG9yZGVyIHRvIGRldGVjdCByZXNpemUgZXZlbnRzIG9uIHNjcm9sbCBldmVudHMuXG4gKiBIZWF2aWx5IGluc3BpcmVkIGJ5OiBodHRwczovL2dpdGh1Yi5jb20vbWFyY2ovY3NzLWVsZW1lbnQtcXVlcmllcy9ibG9iL21hc3Rlci9zcmMvUmVzaXplU2Vuc29yLmpzXG4gKi9cblxuXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBmb3JFYWNoID0gcmVxdWlyZShcIi4uL2NvbGxlY3Rpb24tdXRpbHNcIikuZm9yRWFjaDtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgb3B0aW9ucyAgICAgICAgICAgICA9IG9wdGlvbnMgfHwge307XG4gICAgdmFyIHJlcG9ydGVyICAgICAgICA9IG9wdGlvbnMucmVwb3J0ZXI7XG4gICAgdmFyIGJhdGNoUHJvY2Vzc29yICA9IG9wdGlvbnMuYmF0Y2hQcm9jZXNzb3I7XG4gICAgdmFyIGdldFN0YXRlICAgICAgICA9IG9wdGlvbnMuc3RhdGVIYW5kbGVyLmdldFN0YXRlO1xuICAgIHZhciBoYXNTdGF0ZSAgICAgICAgPSBvcHRpb25zLnN0YXRlSGFuZGxlci5oYXNTdGF0ZTtcbiAgICB2YXIgaWRIYW5kbGVyICAgICAgID0gb3B0aW9ucy5pZEhhbmRsZXI7XG5cbiAgICBpZiAoIWJhdGNoUHJvY2Vzc29yKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgcmVxdWlyZWQgZGVwZW5kZW5jeTogYmF0Y2hQcm9jZXNzb3JcIik7XG4gICAgfVxuXG4gICAgaWYgKCFyZXBvcnRlcikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIHJlcXVpcmVkIGRlcGVuZGVuY3k6IHJlcG9ydGVyLlwiKTtcbiAgICB9XG5cbiAgICAvL1RPRE86IENvdWxkIHRoaXMgcGVyaGFwcyBiZSBkb25lIGF0IGluc3RhbGxhdGlvbiB0aW1lP1xuICAgIHZhciBzY3JvbGxiYXJTaXplcyA9IGdldFNjcm9sbGJhclNpemVzKCk7XG5cbiAgICAvLyBJbmplY3QgdGhlIHNjcm9sbGJhciBzdHlsaW5nIHRoYXQgcHJldmVudHMgdGhlbSBmcm9tIGFwcGVhcmluZyBzb21ldGltZXMgaW4gQ2hyb21lLlxuICAgIC8vIFRoZSBpbmplY3RlZCBjb250YWluZXIgbmVlZHMgdG8gaGF2ZSBhIGNsYXNzLCBzbyB0aGF0IGl0IG1heSBiZSBzdHlsZWQgd2l0aCBDU1MgKHBzZXVkbyBlbGVtZW50cykuXG4gICAgdmFyIHN0eWxlSWQgPSBcImVyZF9zY3JvbGxfZGV0ZWN0aW9uX3Njcm9sbGJhcl9zdHlsZVwiO1xuICAgIHZhciBkZXRlY3Rpb25Db250YWluZXJDbGFzcyA9IFwiZXJkX3Njcm9sbF9kZXRlY3Rpb25fY29udGFpbmVyXCI7XG4gICAgaW5qZWN0U2Nyb2xsU3R5bGUoc3R5bGVJZCwgZGV0ZWN0aW9uQ29udGFpbmVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gZ2V0U2Nyb2xsYmFyU2l6ZXMoKSB7XG4gICAgICAgIHZhciB3aWR0aCA9IDUwMDtcbiAgICAgICAgdmFyIGhlaWdodCA9IDUwMDtcblxuICAgICAgICB2YXIgY2hpbGQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgICAgICBjaGlsZC5zdHlsZS5jc3NUZXh0ID0gXCJwb3NpdGlvbjogYWJzb2x1dGU7IHdpZHRoOiBcIiArIHdpZHRoKjIgKyBcInB4OyBoZWlnaHQ6IFwiICsgaGVpZ2h0KjIgKyBcInB4OyB2aXNpYmlsaXR5OiBoaWRkZW47IG1hcmdpbjogMDsgcGFkZGluZzogMDtcIjtcblxuICAgICAgICB2YXIgY29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICAgICAgY29udGFpbmVyLnN0eWxlLmNzc1RleHQgPSBcInBvc2l0aW9uOiBhYnNvbHV0ZTsgd2lkdGg6IFwiICsgd2lkdGggKyBcInB4OyBoZWlnaHQ6IFwiICsgaGVpZ2h0ICsgXCJweDsgb3ZlcmZsb3c6IHNjcm9sbDsgdmlzaWJpbGl0eTogbm9uZTsgdG9wOiBcIiArIC13aWR0aCozICsgXCJweDsgbGVmdDogXCIgKyAtaGVpZ2h0KjMgKyBcInB4OyB2aXNpYmlsaXR5OiBoaWRkZW47IG1hcmdpbjogMDsgcGFkZGluZzogMDtcIjtcblxuICAgICAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQoY2hpbGQpO1xuXG4gICAgICAgIGRvY3VtZW50LmJvZHkuaW5zZXJ0QmVmb3JlKGNvbnRhaW5lciwgZG9jdW1lbnQuYm9keS5maXJzdENoaWxkKTtcblxuICAgICAgICB2YXIgd2lkdGhTaXplID0gd2lkdGggLSBjb250YWluZXIuY2xpZW50V2lkdGg7XG4gICAgICAgIHZhciBoZWlnaHRTaXplID0gaGVpZ2h0IC0gY29udGFpbmVyLmNsaWVudEhlaWdodDtcblxuICAgICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGNvbnRhaW5lcik7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHdpZHRoOiB3aWR0aFNpemUsXG4gICAgICAgICAgICBoZWlnaHQ6IGhlaWdodFNpemVcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpbmplY3RTY3JvbGxTdHlsZShzdHlsZUlkLCBjb250YWluZXJDbGFzcykge1xuICAgICAgICBmdW5jdGlvbiBpbmplY3RTdHlsZShzdHlsZSwgbWV0aG9kKSB7XG4gICAgICAgICAgICBtZXRob2QgPSBtZXRob2QgfHwgZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKGVsZW1lbnQpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdmFyIHN0eWxlRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzdHlsZVwiKTtcbiAgICAgICAgICAgIHN0eWxlRWxlbWVudC5pbm5lckhUTUwgPSBzdHlsZTtcbiAgICAgICAgICAgIHN0eWxlRWxlbWVudC5pZCA9IHN0eWxlSWQ7XG4gICAgICAgICAgICBtZXRob2Qoc3R5bGVFbGVtZW50KTtcbiAgICAgICAgICAgIHJldHVybiBzdHlsZUVsZW1lbnQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHN0eWxlSWQpKSB7XG4gICAgICAgICAgICB2YXIgY29udGFpbmVyQW5pbWF0aW9uQ2xhc3MgPSBjb250YWluZXJDbGFzcyArIFwiX2FuaW1hdGlvblwiO1xuICAgICAgICAgICAgdmFyIGNvbnRhaW5lckFuaW1hdGlvbkFjdGl2ZUNsYXNzID0gY29udGFpbmVyQ2xhc3MgKyBcIl9hbmltYXRpb25fYWN0aXZlXCI7XG4gICAgICAgICAgICB2YXIgc3R5bGUgPSBcIi8qIENyZWF0ZWQgYnkgdGhlIGVsZW1lbnQtcmVzaXplLWRldGVjdG9yIGxpYnJhcnkuICovXFxuXCI7XG4gICAgICAgICAgICBzdHlsZSArPSBcIi5cIiArIGNvbnRhaW5lckNsYXNzICsgXCIgPiBkaXY6Oi13ZWJraXQtc2Nyb2xsYmFyIHsgZGlzcGxheTogbm9uZTsgfVxcblxcblwiO1xuICAgICAgICAgICAgc3R5bGUgKz0gXCIuXCIgKyBjb250YWluZXJBbmltYXRpb25BY3RpdmVDbGFzcyArIFwiIHsgLXdlYmtpdC1hbmltYXRpb24tZHVyYXRpb246IDAuMXM7IGFuaW1hdGlvbi1kdXJhdGlvbjogMC4xczsgLXdlYmtpdC1hbmltYXRpb24tbmFtZTogXCIgKyBjb250YWluZXJBbmltYXRpb25DbGFzcyArIFwiOyBhbmltYXRpb24tbmFtZTogXCIgKyBjb250YWluZXJBbmltYXRpb25DbGFzcyArIFwiOyB9XFxuXCI7XG4gICAgICAgICAgICBzdHlsZSArPSBcIkAtd2Via2l0LWtleWZyYW1lcyBcIiArIGNvbnRhaW5lckFuaW1hdGlvbkNsYXNzICsgIFwiIHsgMCUgeyBvcGFjaXR5OiAxOyB9IDUwJSB7IG9wYWNpdHk6IDA7IH0gMTAwJSB7IG9wYWNpdHk6IDE7IH0gfVxcblwiO1xuICAgICAgICAgICAgc3R5bGUgKz0gXCJAa2V5ZnJhbWVzIFwiICsgY29udGFpbmVyQW5pbWF0aW9uQ2xhc3MgKyAgICAgICAgICBcIiB7IDAlIHsgb3BhY2l0eTogMTsgfSA1MCUgeyBvcGFjaXR5OiAwOyB9IDEwMCUgeyBvcGFjaXR5OiAxOyB9IH1cIjtcbiAgICAgICAgICAgIGluamVjdFN0eWxlKHN0eWxlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFkZEFuaW1hdGlvbkNsYXNzKGVsZW1lbnQpIHtcbiAgICAgICAgZWxlbWVudC5jbGFzc05hbWUgKz0gXCIgXCIgKyBkZXRlY3Rpb25Db250YWluZXJDbGFzcyArIFwiX2FuaW1hdGlvbl9hY3RpdmVcIjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhZGRFdmVudChlbCwgbmFtZSwgY2IpIHtcbiAgICAgICAgaWYgKGVsLmFkZEV2ZW50TGlzdGVuZXIpIHtcbiAgICAgICAgICAgIGVsLmFkZEV2ZW50TGlzdGVuZXIobmFtZSwgY2IpO1xuICAgICAgICB9IGVsc2UgaWYoZWwuYXR0YWNoRXZlbnQpIHtcbiAgICAgICAgICAgIGVsLmF0dGFjaEV2ZW50KFwib25cIiArIG5hbWUsIGNiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiByZXBvcnRlci5lcnJvcihcIltzY3JvbGxdIERvbid0IGtub3cgaG93IHRvIGFkZCBldmVudCBsaXN0ZW5lcnMuXCIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmVtb3ZlRXZlbnQoZWwsIG5hbWUsIGNiKSB7XG4gICAgICAgIGlmIChlbC5yZW1vdmVFdmVudExpc3RlbmVyKSB7XG4gICAgICAgICAgICBlbC5yZW1vdmVFdmVudExpc3RlbmVyKG5hbWUsIGNiKTtcbiAgICAgICAgfSBlbHNlIGlmKGVsLmRldGFjaEV2ZW50KSB7XG4gICAgICAgICAgICBlbC5kZXRhY2hFdmVudChcIm9uXCIgKyBuYW1lLCBjYik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gcmVwb3J0ZXIuZXJyb3IoXCJbc2Nyb2xsXSBEb24ndCBrbm93IGhvdyB0byByZW1vdmUgZXZlbnQgbGlzdGVuZXJzLlwiKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldEV4cGFuZEVsZW1lbnQoZWxlbWVudCkge1xuICAgICAgICByZXR1cm4gZ2V0U3RhdGUoZWxlbWVudCkuY29udGFpbmVyLmNoaWxkTm9kZXNbMF0uY2hpbGROb2Rlc1swXS5jaGlsZE5vZGVzWzBdO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldFNocmlua0VsZW1lbnQoZWxlbWVudCkge1xuICAgICAgICByZXR1cm4gZ2V0U3RhdGUoZWxlbWVudCkuY29udGFpbmVyLmNoaWxkTm9kZXNbMF0uY2hpbGROb2Rlc1swXS5jaGlsZE5vZGVzWzFdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZHMgYSByZXNpemUgZXZlbnQgbGlzdGVuZXIgdG8gdGhlIGVsZW1lbnQuXG4gICAgICogQHB1YmxpY1xuICAgICAqIEBwYXJhbSB7ZWxlbWVudH0gZWxlbWVudCBUaGUgZWxlbWVudCB0aGF0IHNob3VsZCBoYXZlIHRoZSBsaXN0ZW5lciBhZGRlZC5cbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBsaXN0ZW5lciBUaGUgbGlzdGVuZXIgY2FsbGJhY2sgdG8gYmUgY2FsbGVkIGZvciBlYWNoIHJlc2l6ZSBldmVudCBvZiB0aGUgZWxlbWVudC4gVGhlIGVsZW1lbnQgd2lsbCBiZSBnaXZlbiBhcyBhIHBhcmFtZXRlciB0byB0aGUgbGlzdGVuZXIgY2FsbGJhY2suXG4gICAgICovXG4gICAgZnVuY3Rpb24gYWRkTGlzdGVuZXIoZWxlbWVudCwgbGlzdGVuZXIpIHtcbiAgICAgICAgdmFyIGxpc3RlbmVycyA9IGdldFN0YXRlKGVsZW1lbnQpLmxpc3RlbmVycztcblxuICAgICAgICBpZiAoIWxpc3RlbmVycy5wdXNoKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgYWRkIGxpc3RlbmVyIHRvIGFuIGVsZW1lbnQgdGhhdCBpcyBub3QgZGV0ZWN0YWJsZS5cIik7XG4gICAgICAgIH1cblxuICAgICAgICBnZXRTdGF0ZShlbGVtZW50KS5saXN0ZW5lcnMucHVzaChsaXN0ZW5lcik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTWFrZXMgYW4gZWxlbWVudCBkZXRlY3RhYmxlIGFuZCByZWFkeSB0byBiZSBsaXN0ZW5lZCBmb3IgcmVzaXplIGV2ZW50cy4gV2lsbCBjYWxsIHRoZSBjYWxsYmFjayB3aGVuIHRoZSBlbGVtZW50IGlzIHJlYWR5IHRvIGJlIGxpc3RlbmVkIGZvciByZXNpemUgY2hhbmdlcy5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBvcHRpb25zIE9wdGlvbmFsIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7ZWxlbWVudH0gZWxlbWVudCBUaGUgZWxlbWVudCB0byBtYWtlIGRldGVjdGFibGVcbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGVsZW1lbnQgaXMgcmVhZHkgdG8gYmUgbGlzdGVuZWQgZm9yIHJlc2l6ZSBjaGFuZ2VzLiBXaWxsIGJlIGNhbGxlZCB3aXRoIHRoZSBlbGVtZW50IGFzIGZpcnN0IHBhcmFtZXRlci5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYWtlRGV0ZWN0YWJsZShvcHRpb25zLCBlbGVtZW50LCBjYWxsYmFjaykge1xuICAgICAgICBpZiAoIWNhbGxiYWNrKSB7XG4gICAgICAgICAgICBjYWxsYmFjayA9IGVsZW1lbnQ7XG4gICAgICAgICAgICBlbGVtZW50ID0gb3B0aW9ucztcbiAgICAgICAgICAgIG9wdGlvbnMgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgICAgICAgZnVuY3Rpb24gZGVidWcoKSB7XG4gICAgICAgICAgICBpZiAob3B0aW9ucy5kZWJ1Zykge1xuICAgICAgICAgICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgICBhcmdzLnVuc2hpZnQoaWRIYW5kbGVyLmdldChlbGVtZW50KSwgXCJTY3JvbGw6IFwiKTtcbiAgICAgICAgICAgICAgICBpZiAocmVwb3J0ZXIubG9nLmFwcGx5KSB7XG4gICAgICAgICAgICAgICAgICAgIHJlcG9ydGVyLmxvZy5hcHBseShudWxsLCBhcmdzKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydGVyLmxvZyhhcmdzW2ldKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGlzRGV0YWNoZWQoZWxlbWVudCkge1xuICAgICAgICAgICAgZnVuY3Rpb24gaXNJbkRvY3VtZW50KGVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZWxlbWVudCA9PT0gZWxlbWVudC5vd25lckRvY3VtZW50LmJvZHkgfHwgZWxlbWVudC5vd25lckRvY3VtZW50LmJvZHkuY29udGFpbnMoZWxlbWVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gIWlzSW5Eb2N1bWVudChlbGVtZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGlzVW5yZW5kZXJlZChlbGVtZW50KSB7XG4gICAgICAgICAgICAvLyBDaGVjayB0aGUgYWJzb2x1dGUgcG9zaXRpb25lZCBjb250YWluZXIgc2luY2UgdGhlIHRvcCBsZXZlbCBjb250YWluZXIgaXMgZGlzcGxheTogaW5saW5lLlxuICAgICAgICAgICAgdmFyIGNvbnRhaW5lciA9IGdldFN0YXRlKGVsZW1lbnQpLmNvbnRhaW5lci5jaGlsZE5vZGVzWzBdO1xuICAgICAgICAgICAgcmV0dXJuIGdldENvbXB1dGVkU3R5bGUoY29udGFpbmVyKS53aWR0aC5pbmRleE9mKFwicHhcIikgPT09IC0xOyAvL0NhbiBvbmx5IGNvbXB1dGUgcGl4ZWwgdmFsdWUgd2hlbiByZW5kZXJlZC5cbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGdldFN0eWxlKCkge1xuICAgICAgICAgICAgLy8gU29tZSBicm93c2VycyBvbmx5IGZvcmNlIGxheW91dHMgd2hlbiBhY3R1YWxseSByZWFkaW5nIHRoZSBzdHlsZSBwcm9wZXJ0aWVzIG9mIHRoZSBzdHlsZSBvYmplY3QsIHNvIG1ha2Ugc3VyZSB0aGF0IHRoZXkgYXJlIGFsbCByZWFkIGhlcmUsXG4gICAgICAgICAgICAvLyBzbyB0aGF0IHRoZSB1c2VyIG9mIHRoZSBmdW5jdGlvbiBjYW4gYmUgc3VyZSB0aGF0IGl0IHdpbGwgcGVyZm9ybSB0aGUgbGF5b3V0IGhlcmUsIGluc3RlYWQgb2YgbGF0ZXIgKGltcG9ydGFudCBmb3IgYmF0Y2hpbmcpLlxuICAgICAgICAgICAgdmFyIGVsZW1lbnRTdHlsZSAgICAgICAgICAgID0gZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KTtcbiAgICAgICAgICAgIHZhciBzdHlsZSAgICAgICAgICAgICAgICAgICA9IHt9O1xuICAgICAgICAgICAgc3R5bGUucG9zaXRpb24gICAgICAgICAgICAgID0gZWxlbWVudFN0eWxlLnBvc2l0aW9uO1xuICAgICAgICAgICAgc3R5bGUud2lkdGggICAgICAgICAgICAgICAgID0gZWxlbWVudC5vZmZzZXRXaWR0aDtcbiAgICAgICAgICAgIHN0eWxlLmhlaWdodCAgICAgICAgICAgICAgICA9IGVsZW1lbnQub2Zmc2V0SGVpZ2h0O1xuICAgICAgICAgICAgc3R5bGUudG9wICAgICAgICAgICAgICAgICAgID0gZWxlbWVudFN0eWxlLnRvcDtcbiAgICAgICAgICAgIHN0eWxlLnJpZ2h0ICAgICAgICAgICAgICAgICA9IGVsZW1lbnRTdHlsZS5yaWdodDtcbiAgICAgICAgICAgIHN0eWxlLmJvdHRvbSAgICAgICAgICAgICAgICA9IGVsZW1lbnRTdHlsZS5ib3R0b207XG4gICAgICAgICAgICBzdHlsZS5sZWZ0ICAgICAgICAgICAgICAgICAgPSBlbGVtZW50U3R5bGUubGVmdDtcbiAgICAgICAgICAgIHN0eWxlLndpZHRoQ1NTICAgICAgICAgICAgICA9IGVsZW1lbnRTdHlsZS53aWR0aDtcbiAgICAgICAgICAgIHN0eWxlLmhlaWdodENTUyAgICAgICAgICAgICA9IGVsZW1lbnRTdHlsZS5oZWlnaHQ7XG4gICAgICAgICAgICByZXR1cm4gc3R5bGU7XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBzdG9yZVN0YXJ0U2l6ZSgpIHtcbiAgICAgICAgICAgIHZhciBzdHlsZSA9IGdldFN0eWxlKCk7XG4gICAgICAgICAgICBnZXRTdGF0ZShlbGVtZW50KS5zdGFydFNpemUgPSB7XG4gICAgICAgICAgICAgICAgd2lkdGg6IHN0eWxlLndpZHRoLFxuICAgICAgICAgICAgICAgIGhlaWdodDogc3R5bGUuaGVpZ2h0XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgZGVidWcoXCJFbGVtZW50IHN0YXJ0IHNpemVcIiwgZ2V0U3RhdGUoZWxlbWVudCkuc3RhcnRTaXplKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGluaXRMaXN0ZW5lcnMoKSB7XG4gICAgICAgICAgICBnZXRTdGF0ZShlbGVtZW50KS5saXN0ZW5lcnMgPSBbXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIHN0b3JlU3R5bGUoKSB7XG4gICAgICAgICAgICBkZWJ1ZyhcInN0b3JlU3R5bGUgaW52b2tlZC5cIik7XG4gICAgICAgICAgICBpZiAoIWdldFN0YXRlKGVsZW1lbnQpKSB7XG4gICAgICAgICAgICAgICAgZGVidWcoXCJBYm9ydGluZyBiZWNhdXNlIGVsZW1lbnQgaGFzIGJlZW4gdW5pbnN0YWxsZWRcIik7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgc3R5bGUgPSBnZXRTdHlsZSgpO1xuICAgICAgICAgICAgZ2V0U3RhdGUoZWxlbWVudCkuc3R5bGUgPSBzdHlsZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIHN0b3JlQ3VycmVudFNpemUoZWxlbWVudCwgd2lkdGgsIGhlaWdodCkge1xuICAgICAgICAgICAgZ2V0U3RhdGUoZWxlbWVudCkubGFzdFdpZHRoID0gd2lkdGg7XG4gICAgICAgICAgICBnZXRTdGF0ZShlbGVtZW50KS5sYXN0SGVpZ2h0ICA9IGhlaWdodDtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGdldEV4cGFuZENoaWxkRWxlbWVudChlbGVtZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gZ2V0RXhwYW5kRWxlbWVudChlbGVtZW50KS5jaGlsZE5vZGVzWzBdO1xuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gZ2V0V2lkdGhPZmZzZXQoKSB7XG4gICAgICAgICAgICByZXR1cm4gMiAqIHNjcm9sbGJhclNpemVzLndpZHRoICsgMTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGdldEhlaWdodE9mZnNldCgpIHtcbiAgICAgICAgICAgIHJldHVybiAyICogc2Nyb2xsYmFyU2l6ZXMuaGVpZ2h0ICsgMTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGdldEV4cGFuZFdpZHRoKHdpZHRoKSB7XG4gICAgICAgICAgICByZXR1cm4gd2lkdGggKyAxMCArIGdldFdpZHRoT2Zmc2V0KCk7XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBnZXRFeHBhbmRIZWlnaHQoaGVpZ2h0KSB7XG4gICAgICAgICAgICByZXR1cm4gaGVpZ2h0ICsgMTAgKyBnZXRIZWlnaHRPZmZzZXQoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGdldFNocmlua1dpZHRoKHdpZHRoKSB7XG4gICAgICAgICAgICByZXR1cm4gd2lkdGggKiAyICsgZ2V0V2lkdGhPZmZzZXQoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGdldFNocmlua0hlaWdodChoZWlnaHQpIHtcbiAgICAgICAgICAgIHJldHVybiBoZWlnaHQgKiAyICsgZ2V0SGVpZ2h0T2Zmc2V0KCk7XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBwb3NpdGlvblNjcm9sbGJhcnMoZWxlbWVudCwgd2lkdGgsIGhlaWdodCkge1xuICAgICAgICAgICAgdmFyIGV4cGFuZCAgICAgICAgICA9IGdldEV4cGFuZEVsZW1lbnQoZWxlbWVudCk7XG4gICAgICAgICAgICB2YXIgc2hyaW5rICAgICAgICAgID0gZ2V0U2hyaW5rRWxlbWVudChlbGVtZW50KTtcbiAgICAgICAgICAgIHZhciBleHBhbmRXaWR0aCAgICAgPSBnZXRFeHBhbmRXaWR0aCh3aWR0aCk7XG4gICAgICAgICAgICB2YXIgZXhwYW5kSGVpZ2h0ICAgID0gZ2V0RXhwYW5kSGVpZ2h0KGhlaWdodCk7XG4gICAgICAgICAgICB2YXIgc2hyaW5rV2lkdGggICAgID0gZ2V0U2hyaW5rV2lkdGgod2lkdGgpO1xuICAgICAgICAgICAgdmFyIHNocmlua0hlaWdodCAgICA9IGdldFNocmlua0hlaWdodChoZWlnaHQpO1xuICAgICAgICAgICAgZXhwYW5kLnNjcm9sbExlZnQgICA9IGV4cGFuZFdpZHRoO1xuICAgICAgICAgICAgZXhwYW5kLnNjcm9sbFRvcCAgICA9IGV4cGFuZEhlaWdodDtcbiAgICAgICAgICAgIHNocmluay5zY3JvbGxMZWZ0ICAgPSBzaHJpbmtXaWR0aDtcbiAgICAgICAgICAgIHNocmluay5zY3JvbGxUb3AgICAgPSBzaHJpbmtIZWlnaHQ7XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBpbmplY3RDb250YWluZXJFbGVtZW50KCkge1xuICAgICAgICAgICAgdmFyIGNvbnRhaW5lciA9IGdldFN0YXRlKGVsZW1lbnQpLmNvbnRhaW5lcjtcblxuICAgICAgICAgICAgaWYgKCFjb250YWluZXIpIHtcbiAgICAgICAgICAgICAgICBjb250YWluZXIgICAgICAgICAgICAgICAgICAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgICAgICAgICAgICAgIGNvbnRhaW5lci5jbGFzc05hbWUgICAgICAgICA9IGRldGVjdGlvbkNvbnRhaW5lckNsYXNzO1xuICAgICAgICAgICAgICAgIGNvbnRhaW5lci5zdHlsZS5jc3NUZXh0ICAgICA9IFwidmlzaWJpbGl0eTogaGlkZGVuOyBkaXNwbGF5OiBpbmxpbmU7IHdpZHRoOiAwcHg7IGhlaWdodDogMHB4OyB6LWluZGV4OiAtMTsgb3ZlcmZsb3c6IGhpZGRlbjsgbWFyZ2luOiAwOyBwYWRkaW5nOiAwO1wiO1xuICAgICAgICAgICAgICAgIGdldFN0YXRlKGVsZW1lbnQpLmNvbnRhaW5lciA9IGNvbnRhaW5lcjtcbiAgICAgICAgICAgICAgICBhZGRBbmltYXRpb25DbGFzcyhjb250YWluZXIpO1xuICAgICAgICAgICAgICAgIGVsZW1lbnQuYXBwZW5kQ2hpbGQoY29udGFpbmVyKTtcblxuICAgICAgICAgICAgICAgIHZhciBvbkFuaW1hdGlvblN0YXJ0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBnZXRTdGF0ZShlbGVtZW50KS5vblJlbmRlcmVkICYmIGdldFN0YXRlKGVsZW1lbnQpLm9uUmVuZGVyZWQoKTtcbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgYWRkRXZlbnQoY29udGFpbmVyLCBcImFuaW1hdGlvbnN0YXJ0XCIsIG9uQW5pbWF0aW9uU3RhcnQpO1xuXG4gICAgICAgICAgICAgICAgLy8gU3RvcmUgdGhlIGV2ZW50IGhhbmRsZXIgaGVyZSBzbyB0aGF0IHRoZXkgbWF5IGJlIHJlbW92ZWQgd2hlbiB1bmluc3RhbGwgaXMgY2FsbGVkLlxuICAgICAgICAgICAgICAgIC8vIFNlZSB1bmluc3RhbGwgZnVuY3Rpb24gZm9yIGFuIGV4cGxhbmF0aW9uIHdoeSBpdCBpcyBuZWVkZWQuXG4gICAgICAgICAgICAgICAgZ2V0U3RhdGUoZWxlbWVudCkub25BbmltYXRpb25TdGFydCA9IG9uQW5pbWF0aW9uU3RhcnQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBjb250YWluZXI7XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBpbmplY3RTY3JvbGxFbGVtZW50cygpIHtcbiAgICAgICAgICAgIGZ1bmN0aW9uIGFsdGVyUG9zaXRpb25TdHlsZXMoKSB7XG4gICAgICAgICAgICAgICAgdmFyIHN0eWxlID0gZ2V0U3RhdGUoZWxlbWVudCkuc3R5bGU7XG5cbiAgICAgICAgICAgICAgICBpZihzdHlsZS5wb3NpdGlvbiA9PT0gXCJzdGF0aWNcIikge1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnN0eWxlLnBvc2l0aW9uID0gXCJyZWxhdGl2ZVwiO1xuXG4gICAgICAgICAgICAgICAgICAgIHZhciByZW1vdmVSZWxhdGl2ZVN0eWxlcyA9IGZ1bmN0aW9uKHJlcG9ydGVyLCBlbGVtZW50LCBzdHlsZSwgcHJvcGVydHkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGdldE51bWVyaWNhbFZhbHVlKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlLnJlcGxhY2UoL1teLVxcZFxcLl0vZywgXCJcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2YWx1ZSA9IHN0eWxlW3Byb3BlcnR5XTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYodmFsdWUgIT09IFwiYXV0b1wiICYmIGdldE51bWVyaWNhbFZhbHVlKHZhbHVlKSAhPT0gXCIwXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRlci53YXJuKFwiQW4gZWxlbWVudCB0aGF0IGlzIHBvc2l0aW9uZWQgc3RhdGljIGhhcyBzdHlsZS5cIiArIHByb3BlcnR5ICsgXCI9XCIgKyB2YWx1ZSArIFwiIHdoaWNoIGlzIGlnbm9yZWQgZHVlIHRvIHRoZSBzdGF0aWMgcG9zaXRpb25pbmcuIFRoZSBlbGVtZW50IHdpbGwgbmVlZCB0byBiZSBwb3NpdGlvbmVkIHJlbGF0aXZlLCBzbyB0aGUgc3R5bGUuXCIgKyBwcm9wZXJ0eSArIFwiIHdpbGwgYmUgc2V0IHRvIDAuIEVsZW1lbnQ6IFwiLCBlbGVtZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnN0eWxlW3Byb3BlcnR5XSA9IDA7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAgICAgLy9DaGVjayBzbyB0aGF0IHRoZXJlIGFyZSBubyBhY2NpZGVudGFsIHN0eWxlcyB0aGF0IHdpbGwgbWFrZSB0aGUgZWxlbWVudCBzdHlsZWQgZGlmZmVyZW50bHkgbm93IHRoYXQgaXMgaXMgcmVsYXRpdmUuXG4gICAgICAgICAgICAgICAgICAgIC8vSWYgdGhlcmUgYXJlIGFueSwgc2V0IHRoZW0gdG8gMCAodGhpcyBzaG91bGQgYmUgb2theSB3aXRoIHRoZSB1c2VyIHNpbmNlIHRoZSBzdHlsZSBwcm9wZXJ0aWVzIGRpZCBub3RoaW5nIGJlZm9yZSBbc2luY2UgdGhlIGVsZW1lbnQgd2FzIHBvc2l0aW9uZWQgc3RhdGljXSBhbnl3YXkpLlxuICAgICAgICAgICAgICAgICAgICByZW1vdmVSZWxhdGl2ZVN0eWxlcyhyZXBvcnRlciwgZWxlbWVudCwgc3R5bGUsIFwidG9wXCIpO1xuICAgICAgICAgICAgICAgICAgICByZW1vdmVSZWxhdGl2ZVN0eWxlcyhyZXBvcnRlciwgZWxlbWVudCwgc3R5bGUsIFwicmlnaHRcIik7XG4gICAgICAgICAgICAgICAgICAgIHJlbW92ZVJlbGF0aXZlU3R5bGVzKHJlcG9ydGVyLCBlbGVtZW50LCBzdHlsZSwgXCJib3R0b21cIik7XG4gICAgICAgICAgICAgICAgICAgIHJlbW92ZVJlbGF0aXZlU3R5bGVzKHJlcG9ydGVyLCBlbGVtZW50LCBzdHlsZSwgXCJsZWZ0XCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZnVuY3Rpb24gZ2V0TGVmdFRvcEJvdHRvbVJpZ2h0Q3NzVGV4dChsZWZ0LCB0b3AsIGJvdHRvbSwgcmlnaHQpIHtcbiAgICAgICAgICAgICAgICBsZWZ0ID0gKCFsZWZ0ID8gXCIwXCIgOiAobGVmdCArIFwicHhcIikpO1xuICAgICAgICAgICAgICAgIHRvcCA9ICghdG9wID8gXCIwXCIgOiAodG9wICsgXCJweFwiKSk7XG4gICAgICAgICAgICAgICAgYm90dG9tID0gKCFib3R0b20gPyBcIjBcIiA6IChib3R0b20gKyBcInB4XCIpKTtcbiAgICAgICAgICAgICAgICByaWdodCA9ICghcmlnaHQgPyBcIjBcIiA6IChyaWdodCArIFwicHhcIikpO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIFwibGVmdDogXCIgKyBsZWZ0ICsgXCI7IHRvcDogXCIgKyB0b3AgKyBcIjsgcmlnaHQ6IFwiICsgcmlnaHQgKyBcIjsgYm90dG9tOiBcIiArIGJvdHRvbSArIFwiO1wiO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBkZWJ1ZyhcIkluamVjdGluZyBlbGVtZW50c1wiKTtcblxuICAgICAgICAgICAgaWYgKCFnZXRTdGF0ZShlbGVtZW50KSkge1xuICAgICAgICAgICAgICAgIGRlYnVnKFwiQWJvcnRpbmcgYmVjYXVzZSBlbGVtZW50IGhhcyBiZWVuIHVuaW5zdGFsbGVkXCIpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgYWx0ZXJQb3NpdGlvblN0eWxlcygpO1xuXG4gICAgICAgICAgICB2YXIgcm9vdENvbnRhaW5lciA9IGdldFN0YXRlKGVsZW1lbnQpLmNvbnRhaW5lcjtcblxuICAgICAgICAgICAgaWYgKCFyb290Q29udGFpbmVyKSB7XG4gICAgICAgICAgICAgICAgcm9vdENvbnRhaW5lciA9IGluamVjdENvbnRhaW5lckVsZW1lbnQoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gRHVlIHRvIHRoaXMgV2ViS2l0IGJ1ZyBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9ODA4MDggKGN1cnJlbnRseSBmaXhlZCBpbiBCbGluaywgYnV0IHN0aWxsIHByZXNlbnQgaW4gV2ViS2l0IGJyb3dzZXJzIHN1Y2ggYXMgU2FmYXJpKSxcbiAgICAgICAgICAgIC8vIHdlIG5lZWQgdG8gaW5qZWN0IHR3byBjb250YWluZXJzLCBvbmUgdGhhdCBpcyB3aWR0aC9oZWlnaHQgMTAwJSBhbmQgYW5vdGhlciB0aGF0IGlzIGxlZnQvdG9wIC0xcHggc28gdGhhdCB0aGUgZmluYWwgY29udGFpbmVyIGFsd2F5cyBpcyAxeDEgcGl4ZWxzIGJpZ2dlciB0aGFuXG4gICAgICAgICAgICAvLyB0aGUgdGFyZ2V0ZWQgZWxlbWVudC5cbiAgICAgICAgICAgIC8vIFdoZW4gdGhlIGJ1ZyBpcyByZXNvbHZlZCwgXCJjb250YWluZXJDb250YWluZXJcIiBtYXkgYmUgcmVtb3ZlZC5cblxuICAgICAgICAgICAgLy8gVGhlIG91dGVyIGNvbnRhaW5lciBjYW4gb2NjYXNpb25hbGx5IGJlIGxlc3Mgd2lkZSB0aGFuIHRoZSB0YXJnZXRlZCB3aGVuIGluc2lkZSBpbmxpbmUgZWxlbWVudHMgZWxlbWVudCBpbiBXZWJLaXQgKHNlZSBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTUyOTgwKS5cbiAgICAgICAgICAgIC8vIFRoaXMgc2hvdWxkIGJlIG5vIHByb2JsZW0gc2luY2UgdGhlIGlubmVyIGNvbnRhaW5lciBlaXRoZXIgd2F5IG1ha2VzIHN1cmUgdGhlIGluamVjdGVkIHNjcm9sbCBlbGVtZW50cyBhcmUgYXQgbGVhc3QgMXgxIHB4LlxuXG4gICAgICAgICAgICB2YXIgc2Nyb2xsYmFyV2lkdGggICAgICAgICAgPSBzY3JvbGxiYXJTaXplcy53aWR0aDtcbiAgICAgICAgICAgIHZhciBzY3JvbGxiYXJIZWlnaHQgICAgICAgICA9IHNjcm9sbGJhclNpemVzLmhlaWdodDtcbiAgICAgICAgICAgIHZhciBjb250YWluZXJDb250YWluZXJTdHlsZSA9IFwicG9zaXRpb246IGFic29sdXRlOyBmbGV4OiBub25lOyBvdmVyZmxvdzogaGlkZGVuOyB6LWluZGV4OiAtMTsgdmlzaWJpbGl0eTogaGlkZGVuOyB3aWR0aDogMTAwJTsgaGVpZ2h0OiAxMDAlOyBsZWZ0OiAwcHg7IHRvcDogMHB4O1wiO1xuICAgICAgICAgICAgdmFyIGNvbnRhaW5lclN0eWxlICAgICAgICAgID0gXCJwb3NpdGlvbjogYWJzb2x1dGU7IGZsZXg6IG5vbmU7IG92ZXJmbG93OiBoaWRkZW47IHotaW5kZXg6IC0xOyB2aXNpYmlsaXR5OiBoaWRkZW47IFwiICsgZ2V0TGVmdFRvcEJvdHRvbVJpZ2h0Q3NzVGV4dCgtKDEgKyBzY3JvbGxiYXJXaWR0aCksIC0oMSArIHNjcm9sbGJhckhlaWdodCksIC1zY3JvbGxiYXJIZWlnaHQsIC1zY3JvbGxiYXJXaWR0aCk7XG4gICAgICAgICAgICB2YXIgZXhwYW5kU3R5bGUgICAgICAgICAgICAgPSBcInBvc2l0aW9uOiBhYnNvbHV0ZTsgZmxleDogbm9uZTsgb3ZlcmZsb3c6IHNjcm9sbDsgei1pbmRleDogLTE7IHZpc2liaWxpdHk6IGhpZGRlbjsgd2lkdGg6IDEwMCU7IGhlaWdodDogMTAwJTtcIjtcbiAgICAgICAgICAgIHZhciBzaHJpbmtTdHlsZSAgICAgICAgICAgICA9IFwicG9zaXRpb246IGFic29sdXRlOyBmbGV4OiBub25lOyBvdmVyZmxvdzogc2Nyb2xsOyB6LWluZGV4OiAtMTsgdmlzaWJpbGl0eTogaGlkZGVuOyB3aWR0aDogMTAwJTsgaGVpZ2h0OiAxMDAlO1wiO1xuICAgICAgICAgICAgdmFyIGV4cGFuZENoaWxkU3R5bGUgICAgICAgID0gXCJwb3NpdGlvbjogYWJzb2x1dGU7IGxlZnQ6IDA7IHRvcDogMDtcIjtcbiAgICAgICAgICAgIHZhciBzaHJpbmtDaGlsZFN0eWxlICAgICAgICA9IFwicG9zaXRpb246IGFic29sdXRlOyB3aWR0aDogMjAwJTsgaGVpZ2h0OiAyMDAlO1wiO1xuXG4gICAgICAgICAgICB2YXIgY29udGFpbmVyQ29udGFpbmVyICAgICAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgICAgICAgICAgdmFyIGNvbnRhaW5lciAgICAgICAgICAgICAgID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICAgICAgICAgIHZhciBleHBhbmQgICAgICAgICAgICAgICAgICA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgICAgICAgICB2YXIgZXhwYW5kQ2hpbGQgICAgICAgICAgICAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgICAgICAgICAgdmFyIHNocmluayAgICAgICAgICAgICAgICAgID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICAgICAgICAgIHZhciBzaHJpbmtDaGlsZCAgICAgICAgICAgICA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG5cbiAgICAgICAgICAgIC8vIFNvbWUgYnJvd3NlcnMgY2hva2Ugb24gdGhlIHJlc2l6ZSBzeXN0ZW0gYmVpbmcgcnRsLCBzbyBmb3JjZSBpdCB0byBsdHIuIGh0dHBzOi8vZ2l0aHViLmNvbS93bnIvZWxlbWVudC1yZXNpemUtZGV0ZWN0b3IvaXNzdWVzLzU2XG4gICAgICAgICAgICAvLyBIb3dldmVyLCBkaXIgc2hvdWxkIG5vdCBiZSBzZXQgb24gdGhlIHRvcCBsZXZlbCBjb250YWluZXIgYXMgaXQgYWx0ZXJzIHRoZSBkaW1lbnNpb25zIG9mIHRoZSB0YXJnZXQgZWxlbWVudCBpbiBzb21lIGJyb3dzZXJzLlxuICAgICAgICAgICAgY29udGFpbmVyQ29udGFpbmVyLmRpciAgICAgICAgICAgICAgPSBcImx0clwiO1xuXG4gICAgICAgICAgICBjb250YWluZXJDb250YWluZXIuc3R5bGUuY3NzVGV4dCAgICA9IGNvbnRhaW5lckNvbnRhaW5lclN0eWxlO1xuICAgICAgICAgICAgY29udGFpbmVyQ29udGFpbmVyLmNsYXNzTmFtZSAgICAgICAgPSBkZXRlY3Rpb25Db250YWluZXJDbGFzcztcbiAgICAgICAgICAgIGNvbnRhaW5lci5jbGFzc05hbWUgICAgICAgICAgICAgICAgID0gZGV0ZWN0aW9uQ29udGFpbmVyQ2xhc3M7XG4gICAgICAgICAgICBjb250YWluZXIuc3R5bGUuY3NzVGV4dCAgICAgICAgICAgICA9IGNvbnRhaW5lclN0eWxlO1xuICAgICAgICAgICAgZXhwYW5kLnN0eWxlLmNzc1RleHQgICAgICAgICAgICAgICAgPSBleHBhbmRTdHlsZTtcbiAgICAgICAgICAgIGV4cGFuZENoaWxkLnN0eWxlLmNzc1RleHQgICAgICAgICAgID0gZXhwYW5kQ2hpbGRTdHlsZTtcbiAgICAgICAgICAgIHNocmluay5zdHlsZS5jc3NUZXh0ICAgICAgICAgICAgICAgID0gc2hyaW5rU3R5bGU7XG4gICAgICAgICAgICBzaHJpbmtDaGlsZC5zdHlsZS5jc3NUZXh0ICAgICAgICAgICA9IHNocmlua0NoaWxkU3R5bGU7XG5cbiAgICAgICAgICAgIGV4cGFuZC5hcHBlbmRDaGlsZChleHBhbmRDaGlsZCk7XG4gICAgICAgICAgICBzaHJpbmsuYXBwZW5kQ2hpbGQoc2hyaW5rQ2hpbGQpO1xuICAgICAgICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKGV4cGFuZCk7XG4gICAgICAgICAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQoc2hyaW5rKTtcbiAgICAgICAgICAgIGNvbnRhaW5lckNvbnRhaW5lci5hcHBlbmRDaGlsZChjb250YWluZXIpO1xuICAgICAgICAgICAgcm9vdENvbnRhaW5lci5hcHBlbmRDaGlsZChjb250YWluZXJDb250YWluZXIpO1xuXG4gICAgICAgICAgICBmdW5jdGlvbiBvbkV4cGFuZFNjcm9sbCgpIHtcbiAgICAgICAgICAgICAgICBnZXRTdGF0ZShlbGVtZW50KS5vbkV4cGFuZCAmJiBnZXRTdGF0ZShlbGVtZW50KS5vbkV4cGFuZCgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmdW5jdGlvbiBvblNocmlua1Njcm9sbCgpIHtcbiAgICAgICAgICAgICAgICBnZXRTdGF0ZShlbGVtZW50KS5vblNocmluayAmJiBnZXRTdGF0ZShlbGVtZW50KS5vblNocmluaygpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBhZGRFdmVudChleHBhbmQsIFwic2Nyb2xsXCIsIG9uRXhwYW5kU2Nyb2xsKTtcbiAgICAgICAgICAgIGFkZEV2ZW50KHNocmluaywgXCJzY3JvbGxcIiwgb25TaHJpbmtTY3JvbGwpO1xuXG4gICAgICAgICAgICAvLyBTdG9yZSB0aGUgZXZlbnQgaGFuZGxlcnMgaGVyZSBzbyB0aGF0IHRoZXkgbWF5IGJlIHJlbW92ZWQgd2hlbiB1bmluc3RhbGwgaXMgY2FsbGVkLlxuICAgICAgICAgICAgLy8gU2VlIHVuaW5zdGFsbCBmdW5jdGlvbiBmb3IgYW4gZXhwbGFuYXRpb24gd2h5IGl0IGlzIG5lZWRlZC5cbiAgICAgICAgICAgIGdldFN0YXRlKGVsZW1lbnQpLm9uRXhwYW5kU2Nyb2xsID0gb25FeHBhbmRTY3JvbGw7XG4gICAgICAgICAgICBnZXRTdGF0ZShlbGVtZW50KS5vblNocmlua1Njcm9sbCA9IG9uU2hyaW5rU2Nyb2xsO1xuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gcmVnaXN0ZXJMaXN0ZW5lcnNBbmRQb3NpdGlvbkVsZW1lbnRzKCkge1xuICAgICAgICAgICAgZnVuY3Rpb24gdXBkYXRlQ2hpbGRTaXplcyhlbGVtZW50LCB3aWR0aCwgaGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgdmFyIGV4cGFuZENoaWxkICAgICAgICAgICAgID0gZ2V0RXhwYW5kQ2hpbGRFbGVtZW50KGVsZW1lbnQpO1xuICAgICAgICAgICAgICAgIHZhciBleHBhbmRXaWR0aCAgICAgICAgICAgICA9IGdldEV4cGFuZFdpZHRoKHdpZHRoKTtcbiAgICAgICAgICAgICAgICB2YXIgZXhwYW5kSGVpZ2h0ICAgICAgICAgICAgPSBnZXRFeHBhbmRIZWlnaHQoaGVpZ2h0KTtcbiAgICAgICAgICAgICAgICBleHBhbmRDaGlsZC5zdHlsZS53aWR0aCAgICAgPSBleHBhbmRXaWR0aCArIFwicHhcIjtcbiAgICAgICAgICAgICAgICBleHBhbmRDaGlsZC5zdHlsZS5oZWlnaHQgICAgPSBleHBhbmRIZWlnaHQgKyBcInB4XCI7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZ1bmN0aW9uIHVwZGF0ZURldGVjdG9yRWxlbWVudHMoZG9uZSkge1xuICAgICAgICAgICAgICAgIHZhciB3aWR0aCAgICAgICAgICAgPSBlbGVtZW50Lm9mZnNldFdpZHRoO1xuICAgICAgICAgICAgICAgIHZhciBoZWlnaHQgICAgICAgICAgPSBlbGVtZW50Lm9mZnNldEhlaWdodDtcblxuICAgICAgICAgICAgICAgIGRlYnVnKFwiU3RvcmluZyBjdXJyZW50IHNpemVcIiwgd2lkdGgsIGhlaWdodCk7XG5cbiAgICAgICAgICAgICAgICAvLyBTdG9yZSB0aGUgc2l6ZSBvZiB0aGUgZWxlbWVudCBzeW5jIGhlcmUsIHNvIHRoYXQgbXVsdGlwbGUgc2Nyb2xsIGV2ZW50cyBtYXkgYmUgaWdub3JlZCBpbiB0aGUgZXZlbnQgbGlzdGVuZXJzLlxuICAgICAgICAgICAgICAgIC8vIE90aGVyd2lzZSB0aGUgaWYtY2hlY2sgaW4gaGFuZGxlU2Nyb2xsIGlzIHVzZWxlc3MuXG4gICAgICAgICAgICAgICAgc3RvcmVDdXJyZW50U2l6ZShlbGVtZW50LCB3aWR0aCwgaGVpZ2h0KTtcblxuICAgICAgICAgICAgICAgIC8vIFNpbmNlIHdlIGRlbGF5IHRoZSBwcm9jZXNzaW5nIG9mIHRoZSBiYXRjaCwgdGhlcmUgaXMgYSByaXNrIHRoYXQgdW5pbnN0YWxsIGhhcyBiZWVuIGNhbGxlZCBiZWZvcmUgdGhlIGJhdGNoIGdldHMgdG8gZXhlY3V0ZS5cbiAgICAgICAgICAgICAgICAvLyBTaW5jZSB0aGVyZSBpcyBubyB3YXkgdG8gY2FuY2VsIHRoZSBmbiBleGVjdXRpb25zLCB3ZSBuZWVkIHRvIGFkZCBhbiB1bmluc3RhbGwgZ3VhcmQgdG8gYWxsIGZucyBvZiB0aGUgYmF0Y2guXG5cbiAgICAgICAgICAgICAgICBiYXRjaFByb2Nlc3Nvci5hZGQoMCwgZnVuY3Rpb24gcGVyZm9ybVVwZGF0ZUNoaWxkU2l6ZXMoKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghZ2V0U3RhdGUoZWxlbWVudCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlYnVnKFwiQWJvcnRpbmcgYmVjYXVzZSBlbGVtZW50IGhhcyBiZWVuIHVuaW5zdGFsbGVkXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuZGVidWcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB3ID0gZWxlbWVudC5vZmZzZXRXaWR0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBoID0gZWxlbWVudC5vZmZzZXRIZWlnaHQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh3ICE9PSB3aWR0aCB8fCBoICE9PSBoZWlnaHQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRlci53YXJuKGlkSGFuZGxlci5nZXQoZWxlbWVudCksIFwiU2Nyb2xsOiBTaXplIGNoYW5nZWQgYmVmb3JlIHVwZGF0aW5nIGRldGVjdG9yIGVsZW1lbnRzLlwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHVwZGF0ZUNoaWxkU2l6ZXMoZWxlbWVudCwgd2lkdGgsIGhlaWdodCk7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICBiYXRjaFByb2Nlc3Nvci5hZGQoMSwgZnVuY3Rpb24gdXBkYXRlU2Nyb2xsYmFycygpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFnZXRTdGF0ZShlbGVtZW50KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVidWcoXCJBYm9ydGluZyBiZWNhdXNlIGVsZW1lbnQgaGFzIGJlZW4gdW5pbnN0YWxsZWRcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBwb3NpdGlvblNjcm9sbGJhcnMoZWxlbWVudCwgd2lkdGgsIGhlaWdodCk7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICBpZiAoZG9uZSkge1xuICAgICAgICAgICAgICAgICAgICBiYXRjaFByb2Nlc3Nvci5hZGQoMiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFnZXRTdGF0ZShlbGVtZW50KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlYnVnKFwiQWJvcnRpbmcgYmVjYXVzZSBlbGVtZW50IGhhcyBiZWVuIHVuaW5zdGFsbGVkXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZ1bmN0aW9uIGFyZUVsZW1lbnRzSW5qZWN0ZWQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuICEhZ2V0U3RhdGUoZWxlbWVudCkuY29udGFpbmVyO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmdW5jdGlvbiBub3RpZnlMaXN0ZW5lcnNJZk5lZWRlZCgpIHtcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBpc0ZpcnN0Tm90aWZ5KCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZ2V0U3RhdGUoZWxlbWVudCkubGFzdE5vdGlmaWVkV2lkdGggPT09IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBkZWJ1ZyhcIm5vdGlmeUxpc3RlbmVyc0lmTmVlZGVkIGludm9rZWRcIik7XG5cbiAgICAgICAgICAgICAgICB2YXIgc3RhdGUgPSBnZXRTdGF0ZShlbGVtZW50KTtcblxuICAgICAgICAgICAgICAgIC8vIERvbid0IG5vdGlmeSB0aGUgaWYgdGhlIGN1cnJlbnQgc2l6ZSBpcyB0aGUgc3RhcnQgc2l6ZSwgYW5kIHRoaXMgaXMgdGhlIGZpcnN0IG5vdGlmaWNhdGlvbi5cbiAgICAgICAgICAgICAgICBpZiAoaXNGaXJzdE5vdGlmeSgpICYmIHN0YXRlLmxhc3RXaWR0aCA9PT0gc3RhdGUuc3RhcnRTaXplLndpZHRoICYmIHN0YXRlLmxhc3RIZWlnaHQgPT09IHN0YXRlLnN0YXJ0U2l6ZS5oZWlnaHQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRlYnVnKFwiTm90IG5vdGlmeWluZzogU2l6ZSBpcyB0aGUgc2FtZSBhcyB0aGUgc3RhcnQgc2l6ZSwgYW5kIHRoZXJlIGhhcyBiZWVuIG5vIG5vdGlmaWNhdGlvbiB5ZXQuXCIpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIERvbid0IG5vdGlmeSBpZiB0aGUgc2l6ZSBhbHJlYWR5IGhhcyBiZWVuIG5vdGlmaWVkLlxuICAgICAgICAgICAgICAgIGlmIChzdGF0ZS5sYXN0V2lkdGggPT09IHN0YXRlLmxhc3ROb3RpZmllZFdpZHRoICYmIHN0YXRlLmxhc3RIZWlnaHQgPT09IHN0YXRlLmxhc3ROb3RpZmllZEhlaWdodCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGVidWcoXCJOb3Qgbm90aWZ5aW5nOiBTaXplIGFscmVhZHkgbm90aWZpZWRcIik7XG4gICAgICAgICAgICAgICAgfVxuXG5cbiAgICAgICAgICAgICAgICBkZWJ1ZyhcIkN1cnJlbnQgc2l6ZSBub3Qgbm90aWZpZWQsIG5vdGlmeWluZy4uLlwiKTtcbiAgICAgICAgICAgICAgICBzdGF0ZS5sYXN0Tm90aWZpZWRXaWR0aCA9IHN0YXRlLmxhc3RXaWR0aDtcbiAgICAgICAgICAgICAgICBzdGF0ZS5sYXN0Tm90aWZpZWRIZWlnaHQgPSBzdGF0ZS5sYXN0SGVpZ2h0O1xuICAgICAgICAgICAgICAgIGZvckVhY2goZ2V0U3RhdGUoZWxlbWVudCkubGlzdGVuZXJzLCBmdW5jdGlvbiAobGlzdGVuZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXIoZWxlbWVudCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZ1bmN0aW9uIGhhbmRsZVJlbmRlcigpIHtcbiAgICAgICAgICAgICAgICBkZWJ1ZyhcInN0YXJ0YW5pbWF0aW9uIHRyaWdnZXJlZC5cIik7XG5cbiAgICAgICAgICAgICAgICBpZiAoaXNVbnJlbmRlcmVkKGVsZW1lbnQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlYnVnKFwiSWdub3Jpbmcgc2luY2UgZWxlbWVudCBpcyBzdGlsbCB1bnJlbmRlcmVkLi4uXCIpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZGVidWcoXCJFbGVtZW50IHJlbmRlcmVkLlwiKTtcbiAgICAgICAgICAgICAgICB2YXIgZXhwYW5kID0gZ2V0RXhwYW5kRWxlbWVudChlbGVtZW50KTtcbiAgICAgICAgICAgICAgICB2YXIgc2hyaW5rID0gZ2V0U2hyaW5rRWxlbWVudChlbGVtZW50KTtcbiAgICAgICAgICAgICAgICBpZiAoZXhwYW5kLnNjcm9sbExlZnQgPT09IDAgfHwgZXhwYW5kLnNjcm9sbFRvcCA9PT0gMCB8fCBzaHJpbmsuc2Nyb2xsTGVmdCA9PT0gMCB8fCBzaHJpbmsuc2Nyb2xsVG9wID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlYnVnKFwiU2Nyb2xsYmFycyBvdXQgb2Ygc3luYy4gVXBkYXRpbmcgZGV0ZWN0b3IgZWxlbWVudHMuLi5cIik7XG4gICAgICAgICAgICAgICAgICAgIHVwZGF0ZURldGVjdG9yRWxlbWVudHMobm90aWZ5TGlzdGVuZXJzSWZOZWVkZWQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZnVuY3Rpb24gaGFuZGxlU2Nyb2xsKCkge1xuICAgICAgICAgICAgICAgIGRlYnVnKFwiU2Nyb2xsIGRldGVjdGVkLlwiKTtcblxuICAgICAgICAgICAgICAgIGlmIChpc1VucmVuZGVyZWQoZWxlbWVudCkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gRWxlbWVudCBpcyBzdGlsbCB1bnJlbmRlcmVkLiBTa2lwIHRoaXMgc2Nyb2xsIGV2ZW50LlxuICAgICAgICAgICAgICAgICAgICBkZWJ1ZyhcIlNjcm9sbCBldmVudCBmaXJlZCB3aGlsZSB1bnJlbmRlcmVkLiBJZ25vcmluZy4uLlwiKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHZhciB3aWR0aCA9IGVsZW1lbnQub2Zmc2V0V2lkdGg7XG4gICAgICAgICAgICAgICAgdmFyIGhlaWdodCA9IGVsZW1lbnQub2Zmc2V0SGVpZ2h0O1xuXG4gICAgICAgICAgICAgICAgaWYgKHdpZHRoICE9PSBlbGVtZW50Lmxhc3RXaWR0aCB8fCBoZWlnaHQgIT09IGVsZW1lbnQubGFzdEhlaWdodCkge1xuICAgICAgICAgICAgICAgICAgICBkZWJ1ZyhcIkVsZW1lbnQgc2l6ZSBjaGFuZ2VkLlwiKTtcbiAgICAgICAgICAgICAgICAgICAgdXBkYXRlRGV0ZWN0b3JFbGVtZW50cyhub3RpZnlMaXN0ZW5lcnNJZk5lZWRlZCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZGVidWcoXCJFbGVtZW50IHNpemUgaGFzIG5vdCBjaGFuZ2VkIChcIiArIHdpZHRoICsgXCJ4XCIgKyBoZWlnaHQgKyBcIikuXCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZGVidWcoXCJyZWdpc3Rlckxpc3RlbmVyc0FuZFBvc2l0aW9uRWxlbWVudHMgaW52b2tlZC5cIik7XG5cbiAgICAgICAgICAgIGlmICghZ2V0U3RhdGUoZWxlbWVudCkpIHtcbiAgICAgICAgICAgICAgICBkZWJ1ZyhcIkFib3J0aW5nIGJlY2F1c2UgZWxlbWVudCBoYXMgYmVlbiB1bmluc3RhbGxlZFwiKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGdldFN0YXRlKGVsZW1lbnQpLm9uUmVuZGVyZWQgPSBoYW5kbGVSZW5kZXI7XG4gICAgICAgICAgICBnZXRTdGF0ZShlbGVtZW50KS5vbkV4cGFuZCA9IGhhbmRsZVNjcm9sbDtcbiAgICAgICAgICAgIGdldFN0YXRlKGVsZW1lbnQpLm9uU2hyaW5rID0gaGFuZGxlU2Nyb2xsO1xuXG4gICAgICAgICAgICB2YXIgc3R5bGUgPSBnZXRTdGF0ZShlbGVtZW50KS5zdHlsZTtcbiAgICAgICAgICAgIHVwZGF0ZUNoaWxkU2l6ZXMoZWxlbWVudCwgc3R5bGUud2lkdGgsIHN0eWxlLmhlaWdodCk7XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBmaW5hbGl6ZURvbU11dGF0aW9uKCkge1xuICAgICAgICAgICAgZGVidWcoXCJmaW5hbGl6ZURvbU11dGF0aW9uIGludm9rZWQuXCIpO1xuXG4gICAgICAgICAgICBpZiAoIWdldFN0YXRlKGVsZW1lbnQpKSB7XG4gICAgICAgICAgICAgICAgZGVidWcoXCJBYm9ydGluZyBiZWNhdXNlIGVsZW1lbnQgaGFzIGJlZW4gdW5pbnN0YWxsZWRcIik7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgc3R5bGUgPSBnZXRTdGF0ZShlbGVtZW50KS5zdHlsZTtcbiAgICAgICAgICAgIHN0b3JlQ3VycmVudFNpemUoZWxlbWVudCwgc3R5bGUud2lkdGgsIHN0eWxlLmhlaWdodCk7XG4gICAgICAgICAgICBwb3NpdGlvblNjcm9sbGJhcnMoZWxlbWVudCwgc3R5bGUud2lkdGgsIHN0eWxlLmhlaWdodCk7XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiByZWFkeSgpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGVsZW1lbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gaW5zdGFsbCgpIHtcbiAgICAgICAgICAgIGRlYnVnKFwiSW5zdGFsbGluZy4uLlwiKTtcbiAgICAgICAgICAgIGluaXRMaXN0ZW5lcnMoKTtcbiAgICAgICAgICAgIHN0b3JlU3RhcnRTaXplKCk7XG5cbiAgICAgICAgICAgIGJhdGNoUHJvY2Vzc29yLmFkZCgwLCBzdG9yZVN0eWxlKTtcbiAgICAgICAgICAgIGJhdGNoUHJvY2Vzc29yLmFkZCgxLCBpbmplY3RTY3JvbGxFbGVtZW50cyk7XG4gICAgICAgICAgICBiYXRjaFByb2Nlc3Nvci5hZGQoMiwgcmVnaXN0ZXJMaXN0ZW5lcnNBbmRQb3NpdGlvbkVsZW1lbnRzKTtcbiAgICAgICAgICAgIGJhdGNoUHJvY2Vzc29yLmFkZCgzLCBmaW5hbGl6ZURvbU11dGF0aW9uKTtcbiAgICAgICAgICAgIGJhdGNoUHJvY2Vzc29yLmFkZCg0LCByZWFkeSk7XG4gICAgICAgIH1cblxuICAgICAgICBkZWJ1ZyhcIk1ha2luZyBkZXRlY3RhYmxlLi4uXCIpO1xuXG4gICAgICAgIGlmIChpc0RldGFjaGVkKGVsZW1lbnQpKSB7XG4gICAgICAgICAgICBkZWJ1ZyhcIkVsZW1lbnQgaXMgZGV0YWNoZWRcIik7XG5cbiAgICAgICAgICAgIGluamVjdENvbnRhaW5lckVsZW1lbnQoKTtcblxuICAgICAgICAgICAgZGVidWcoXCJXYWl0aW5nIHVudGlsIGVsZW1lbnQgaXMgYXR0YWNoZWQuLi5cIik7XG5cbiAgICAgICAgICAgIGdldFN0YXRlKGVsZW1lbnQpLm9uUmVuZGVyZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgZGVidWcoXCJFbGVtZW50IGlzIG5vdyBhdHRhY2hlZFwiKTtcbiAgICAgICAgICAgICAgICBpbnN0YWxsKCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaW5zdGFsbCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdW5pbnN0YWxsKGVsZW1lbnQpIHtcbiAgICAgICAgdmFyIHN0YXRlID0gZ2V0U3RhdGUoZWxlbWVudCk7XG5cbiAgICAgICAgaWYgKCFzdGF0ZSkge1xuICAgICAgICAgICAgLy8gVW5pbnN0YWxsIGhhcyBiZWVuIGNhbGxlZCBvbiBhIG5vbi1lcmQgZWxlbWVudC5cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFVuaW5zdGFsbCBtYXkgaGF2ZSBiZWVuIGNhbGxlZCBpbiB0aGUgZm9sbG93aW5nIHNjZW5hcmlvczpcbiAgICAgICAgLy8gKDEpIFJpZ2h0IGJldHdlZW4gdGhlIHN5bmMgY29kZSBhbmQgYXN5bmMgYmF0Y2ggKGhlcmUgc3RhdGUuYnVzeSA9IHRydWUsIGJ1dCBub3RoaW5nIGhhdmUgYmVlbiByZWdpc3RlcmVkIG9yIGluamVjdGVkKS5cbiAgICAgICAgLy8gKDIpIEluIHRoZSByZWFkeSBjYWxsYmFjayBvZiB0aGUgbGFzdCBsZXZlbCBvZiB0aGUgYmF0Y2ggYnkgYW5vdGhlciBlbGVtZW50IChoZXJlLCBzdGF0ZS5idXN5ID0gdHJ1ZSwgYnV0IGFsbCB0aGUgc3R1ZmYgaGFzIGJlZW4gaW5qZWN0ZWQpLlxuICAgICAgICAvLyAoMykgQWZ0ZXIgdGhlIGluc3RhbGxhdGlvbiBwcm9jZXNzIChoZXJlLCBzdGF0ZS5idXN5ID0gZmFsc2UgYW5kIGFsbCB0aGUgc3R1ZmYgaGFzIGJlZW4gaW5qZWN0ZWQpLlxuICAgICAgICAvLyBTbyB0byBiZSBvbiB0aGUgc2FmZSBzaWRlLCBsZXQncyBjaGVjayBmb3IgZWFjaCB0aGluZyBiZWZvcmUgcmVtb3ZpbmcuXG5cbiAgICAgICAgLy8gV2UgbmVlZCB0byByZW1vdmUgdGhlIGV2ZW50IGxpc3RlbmVycywgYmVjYXVzZSBvdGhlcndpc2UgdGhlIGV2ZW50IG1pZ2h0IGZpcmUgb24gYW4gdW5pbnN0YWxsIGVsZW1lbnQgd2hpY2ggcmVzdWx0cyBpbiBhbiBlcnJvciB3aGVuIHRyeWluZyB0byBnZXQgdGhlIHN0YXRlIG9mIHRoZSBlbGVtZW50LlxuICAgICAgICBzdGF0ZS5vbkV4cGFuZFNjcm9sbCAmJiByZW1vdmVFdmVudChnZXRFeHBhbmRFbGVtZW50KGVsZW1lbnQpLCBcInNjcm9sbFwiLCBzdGF0ZS5vbkV4cGFuZFNjcm9sbCk7XG4gICAgICAgIHN0YXRlLm9uU2hyaW5rU2Nyb2xsICYmIHJlbW92ZUV2ZW50KGdldFNocmlua0VsZW1lbnQoZWxlbWVudCksIFwic2Nyb2xsXCIsIHN0YXRlLm9uU2hyaW5rU2Nyb2xsKTtcbiAgICAgICAgc3RhdGUub25BbmltYXRpb25TdGFydCAmJiByZW1vdmVFdmVudChzdGF0ZS5jb250YWluZXIsIFwiYW5pbWF0aW9uc3RhcnRcIiwgc3RhdGUub25BbmltYXRpb25TdGFydCk7XG5cbiAgICAgICAgc3RhdGUuY29udGFpbmVyICYmIGVsZW1lbnQucmVtb3ZlQ2hpbGQoc3RhdGUuY29udGFpbmVyKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBtYWtlRGV0ZWN0YWJsZTogbWFrZURldGVjdGFibGUsXG4gICAgICAgIGFkZExpc3RlbmVyOiBhZGRMaXN0ZW5lcixcbiAgICAgICAgdW5pbnN0YWxsOiB1bmluc3RhbGxcbiAgICB9O1xufTtcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9lbGVtZW50LXJlc2l6ZS1kZXRlY3Rvci9zcmMvZGV0ZWN0aW9uLXN0cmF0ZWd5L3Njcm9sbC5qc1xuLy8gbW9kdWxlIGlkID0gMjJcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sInNvdXJjZVJvb3QiOiIifQ=="); - -/***/ }, -/* 23 */ -/***/ function(module, exports) { - -"use strict"; -eval("\"use strict\";\n\nmodule.exports = function(options) {\n var getState = options.stateHandler.getState;\n\n /**\n * Tells if the element has been made detectable and ready to be listened for resize events.\n * @public\n * @param {element} The element to check.\n * @returns {boolean} True or false depending on if the element is detectable or not.\n */\n function isDetectable(element) {\n var state = getState(element);\n return state && !!state.isDetectable;\n }\n\n /**\n * Marks the element that it has been made detectable and ready to be listened for resize events.\n * @public\n * @param {element} The element to mark.\n */\n function markAsDetectable(element) {\n getState(element).isDetectable = true;\n }\n\n /**\n * Tells if the element is busy or not.\n * @public\n * @param {element} The element to check.\n * @returns {boolean} True or false depending on if the element is busy or not.\n */\n function isBusy(element) {\n return !!getState(element).busy;\n }\n\n /**\n * Marks the object is busy and should not be made detectable.\n * @public\n * @param {element} element The element to mark.\n * @param {boolean} busy If the element is busy or not.\n */\n function markBusy(element, busy) {\n getState(element).busy = !!busy;\n }\n\n return {\n isDetectable: isDetectable,\n markAsDetectable: markAsDetectable,\n isBusy: isBusy,\n markBusy: markBusy\n };\n};\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9+L2VsZW1lbnQtcmVzaXplLWRldGVjdG9yL3NyYy9lbGVtZW50LXV0aWxzLmpzPzI2NmQiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixlQUFlLFFBQVE7QUFDdkI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiMjMuanMiLCJzb3VyY2VzQ29udGVudCI6WyJcInVzZSBzdHJpY3RcIjtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgdmFyIGdldFN0YXRlID0gb3B0aW9ucy5zdGF0ZUhhbmRsZXIuZ2V0U3RhdGU7XG5cbiAgICAvKipcbiAgICAgKiBUZWxscyBpZiB0aGUgZWxlbWVudCBoYXMgYmVlbiBtYWRlIGRldGVjdGFibGUgYW5kIHJlYWR5IHRvIGJlIGxpc3RlbmVkIGZvciByZXNpemUgZXZlbnRzLlxuICAgICAqIEBwdWJsaWNcbiAgICAgKiBAcGFyYW0ge2VsZW1lbnR9IFRoZSBlbGVtZW50IHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIG9yIGZhbHNlIGRlcGVuZGluZyBvbiBpZiB0aGUgZWxlbWVudCBpcyBkZXRlY3RhYmxlIG9yIG5vdC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0RldGVjdGFibGUoZWxlbWVudCkge1xuICAgICAgICB2YXIgc3RhdGUgPSBnZXRTdGF0ZShlbGVtZW50KTtcbiAgICAgICAgcmV0dXJuIHN0YXRlICYmICEhc3RhdGUuaXNEZXRlY3RhYmxlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE1hcmtzIHRoZSBlbGVtZW50IHRoYXQgaXQgaGFzIGJlZW4gbWFkZSBkZXRlY3RhYmxlIGFuZCByZWFkeSB0byBiZSBsaXN0ZW5lZCBmb3IgcmVzaXplIGV2ZW50cy5cbiAgICAgKiBAcHVibGljXG4gICAgICogQHBhcmFtIHtlbGVtZW50fSBUaGUgZWxlbWVudCB0byBtYXJrLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1hcmtBc0RldGVjdGFibGUoZWxlbWVudCkge1xuICAgICAgICBnZXRTdGF0ZShlbGVtZW50KS5pc0RldGVjdGFibGUgPSB0cnVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRlbGxzIGlmIHRoZSBlbGVtZW50IGlzIGJ1c3kgb3Igbm90LlxuICAgICAqIEBwdWJsaWNcbiAgICAgKiBAcGFyYW0ge2VsZW1lbnR9IFRoZSBlbGVtZW50IHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIG9yIGZhbHNlIGRlcGVuZGluZyBvbiBpZiB0aGUgZWxlbWVudCBpcyBidXN5IG9yIG5vdC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0J1c3koZWxlbWVudCkge1xuICAgICAgICByZXR1cm4gISFnZXRTdGF0ZShlbGVtZW50KS5idXN5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE1hcmtzIHRoZSBvYmplY3QgaXMgYnVzeSBhbmQgc2hvdWxkIG5vdCBiZSBtYWRlIGRldGVjdGFibGUuXG4gICAgICogQHB1YmxpY1xuICAgICAqIEBwYXJhbSB7ZWxlbWVudH0gZWxlbWVudCBUaGUgZWxlbWVudCB0byBtYXJrLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gYnVzeSBJZiB0aGUgZWxlbWVudCBpcyBidXN5IG9yIG5vdC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXJrQnVzeShlbGVtZW50LCBidXN5KSB7XG4gICAgICAgIGdldFN0YXRlKGVsZW1lbnQpLmJ1c3kgPSAhIWJ1c3k7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgaXNEZXRlY3RhYmxlOiBpc0RldGVjdGFibGUsXG4gICAgICAgIG1hcmtBc0RldGVjdGFibGU6IG1hcmtBc0RldGVjdGFibGUsXG4gICAgICAgIGlzQnVzeTogaXNCdXN5LFxuICAgICAgICBtYXJrQnVzeTogbWFya0J1c3lcbiAgICB9O1xufTtcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9lbGVtZW50LXJlc2l6ZS1kZXRlY3Rvci9zcmMvZWxlbWVudC11dGlscy5qc1xuLy8gbW9kdWxlIGlkID0gMjNcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sInNvdXJjZVJvb3QiOiIifQ=="); - -/***/ }, -/* 24 */ -/***/ function(module, exports) { - -"use strict"; -eval("\"use strict\";\n\nmodule.exports = function() {\n var idCount = 1;\n\n /**\n * Generates a new unique id in the context.\n * @public\n * @returns {number} A unique id in the context.\n */\n function generate() {\n return idCount++;\n }\n\n return {\n generate: generate\n };\n};\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9+L2VsZW1lbnQtcmVzaXplLWRldGVjdG9yL3NyYy9pZC1nZW5lcmF0b3IuanM/OWE1NCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixPQUFPO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6IjI0LmpzIiwic291cmNlc0NvbnRlbnQiOlsiXCJ1c2Ugc3RyaWN0XCI7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGlkQ291bnQgPSAxO1xuXG4gICAgLyoqXG4gICAgICogR2VuZXJhdGVzIGEgbmV3IHVuaXF1ZSBpZCBpbiB0aGUgY29udGV4dC5cbiAgICAgKiBAcHVibGljXG4gICAgICogQHJldHVybnMge251bWJlcn0gQSB1bmlxdWUgaWQgaW4gdGhlIGNvbnRleHQuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2VuZXJhdGUoKSB7XG4gICAgICAgIHJldHVybiBpZENvdW50Kys7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgZ2VuZXJhdGU6IGdlbmVyYXRlXG4gICAgfTtcbn07XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vZWxlbWVudC1yZXNpemUtZGV0ZWN0b3Ivc3JjL2lkLWdlbmVyYXRvci5qc1xuLy8gbW9kdWxlIGlkID0gMjRcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sInNvdXJjZVJvb3QiOiIifQ=="); - -/***/ }, -/* 25 */ -/***/ function(module, exports) { - -"use strict"; -eval("\"use strict\";\n\nmodule.exports = function(options) {\n var idGenerator = options.idGenerator;\n var getState = options.stateHandler.getState;\n\n /**\n * Gets the resize detector id of the element.\n * @public\n * @param {element} element The target element to get the id of.\n * @returns {string|number|null} The id of the element. Null if it has no id.\n */\n function getId(element) {\n var state = getState(element);\n\n if (state && state.id !== undefined) {\n return state.id;\n }\n\n return null;\n }\n\n /**\n * Sets the resize detector id of the element. Requires the element to have a resize detector state initialized.\n * @public\n * @param {element} element The target element to set the id of.\n * @returns {string|number|null} The id of the element.\n */\n function setId(element) {\n var state = getState(element);\n\n if (!state) {\n throw new Error(\"setId required the element to have a resize detection state.\");\n }\n\n var id = idGenerator.generate();\n\n state.id = id;\n\n return id;\n }\n\n return {\n get: getId,\n set: setId\n };\n};\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9+L2VsZW1lbnQtcmVzaXplLWRldGVjdG9yL3NyYy9pZC1oYW5kbGVyLmpzPzIzYTgiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsbUJBQW1CO0FBQ3BDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsaUJBQWlCLG1CQUFtQjtBQUNwQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiIyNS5qcyIsInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICB2YXIgaWRHZW5lcmF0b3IgICAgID0gb3B0aW9ucy5pZEdlbmVyYXRvcjtcbiAgICB2YXIgZ2V0U3RhdGUgICAgICAgID0gb3B0aW9ucy5zdGF0ZUhhbmRsZXIuZ2V0U3RhdGU7XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSByZXNpemUgZGV0ZWN0b3IgaWQgb2YgdGhlIGVsZW1lbnQuXG4gICAgICogQHB1YmxpY1xuICAgICAqIEBwYXJhbSB7ZWxlbWVudH0gZWxlbWVudCBUaGUgdGFyZ2V0IGVsZW1lbnQgdG8gZ2V0IHRoZSBpZCBvZi5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bWJlcnxudWxsfSBUaGUgaWQgb2YgdGhlIGVsZW1lbnQuIE51bGwgaWYgaXQgaGFzIG5vIGlkLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldElkKGVsZW1lbnQpIHtcbiAgICAgICAgdmFyIHN0YXRlID0gZ2V0U3RhdGUoZWxlbWVudCk7XG5cbiAgICAgICAgaWYgKHN0YXRlICYmIHN0YXRlLmlkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBzdGF0ZS5pZDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIHJlc2l6ZSBkZXRlY3RvciBpZCBvZiB0aGUgZWxlbWVudC4gUmVxdWlyZXMgdGhlIGVsZW1lbnQgdG8gaGF2ZSBhIHJlc2l6ZSBkZXRlY3RvciBzdGF0ZSBpbml0aWFsaXplZC5cbiAgICAgKiBAcHVibGljXG4gICAgICogQHBhcmFtIHtlbGVtZW50fSBlbGVtZW50IFRoZSB0YXJnZXQgZWxlbWVudCB0byBzZXQgdGhlIGlkIG9mLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVtYmVyfG51bGx9IFRoZSBpZCBvZiB0aGUgZWxlbWVudC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzZXRJZChlbGVtZW50KSB7XG4gICAgICAgIHZhciBzdGF0ZSA9IGdldFN0YXRlKGVsZW1lbnQpO1xuXG4gICAgICAgIGlmICghc3RhdGUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInNldElkIHJlcXVpcmVkIHRoZSBlbGVtZW50IHRvIGhhdmUgYSByZXNpemUgZGV0ZWN0aW9uIHN0YXRlLlwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBpZCA9IGlkR2VuZXJhdG9yLmdlbmVyYXRlKCk7XG5cbiAgICAgICAgc3RhdGUuaWQgPSBpZDtcblxuICAgICAgICByZXR1cm4gaWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgZ2V0OiBnZXRJZCxcbiAgICAgICAgc2V0OiBzZXRJZFxuICAgIH07XG59O1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2VsZW1lbnQtcmVzaXplLWRldGVjdG9yL3NyYy9pZC1oYW5kbGVyLmpzXG4vLyBtb2R1bGUgaWQgPSAyNVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwic291cmNlUm9vdCI6IiJ9"); - -/***/ }, -/* 26 */ -/***/ function(module, exports) { - -"use strict"; -eval("\"use strict\";\n\nmodule.exports = function(idHandler) {\n var eventListeners = {};\n\n /**\n * Gets all listeners for the given element.\n * @public\n * @param {element} element The element to get all listeners for.\n * @returns All listeners for the given element.\n */\n function getListeners(element) {\n var id = idHandler.get(element);\n\n if (id === undefined) {\n return [];\n }\n\n return eventListeners[id] || [];\n }\n\n /**\n * Stores the given listener for the given element. Will not actually add the listener to the element.\n * @public\n * @param {element} element The element that should have the listener added.\n * @param {function} listener The callback that the element has added.\n */\n function addListener(element, listener) {\n var id = idHandler.get(element);\n\n if(!eventListeners[id]) {\n eventListeners[id] = [];\n }\n\n eventListeners[id].push(listener);\n }\n\n function removeListener(element, listener) {\n var listeners = getListeners(element);\n for (var i = 0, len = listeners.length; i < len; ++i) {\n if (listeners[i] === listener) {\n listeners.splice(i, 1);\n break;\n }\n }\n }\n\n function removeAllListeners(element) {\n var listeners = getListeners(element);\n if (!listeners) { return; }\n listeners.length = 0;\n }\n\n return {\n get: getListeners,\n add: addListener,\n removeListener: removeListener,\n removeAllListeners: removeAllListeners\n };\n};\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9+L2VsZW1lbnQtcmVzaXplLWRldGVjdG9yL3NyYy9saXN0ZW5lci1oYW5kbGVyLmpzP2FlMTQiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsU0FBUztBQUN4QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLCtDQUErQyxTQUFTO0FBQ3hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsdUJBQXVCLFFBQVE7QUFDL0I7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiIyNi5qcyIsInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGlkSGFuZGxlcikge1xuICAgIHZhciBldmVudExpc3RlbmVycyA9IHt9O1xuXG4gICAgLyoqXG4gICAgICogR2V0cyBhbGwgbGlzdGVuZXJzIGZvciB0aGUgZ2l2ZW4gZWxlbWVudC5cbiAgICAgKiBAcHVibGljXG4gICAgICogQHBhcmFtIHtlbGVtZW50fSBlbGVtZW50IFRoZSBlbGVtZW50IHRvIGdldCBhbGwgbGlzdGVuZXJzIGZvci5cbiAgICAgKiBAcmV0dXJucyBBbGwgbGlzdGVuZXJzIGZvciB0aGUgZ2l2ZW4gZWxlbWVudC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRMaXN0ZW5lcnMoZWxlbWVudCkge1xuICAgICAgICB2YXIgaWQgPSBpZEhhbmRsZXIuZ2V0KGVsZW1lbnQpO1xuXG4gICAgICAgIGlmIChpZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZXZlbnRMaXN0ZW5lcnNbaWRdIHx8IFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN0b3JlcyB0aGUgZ2l2ZW4gbGlzdGVuZXIgZm9yIHRoZSBnaXZlbiBlbGVtZW50LiBXaWxsIG5vdCBhY3R1YWxseSBhZGQgdGhlIGxpc3RlbmVyIHRvIHRoZSBlbGVtZW50LlxuICAgICAqIEBwdWJsaWNcbiAgICAgKiBAcGFyYW0ge2VsZW1lbnR9IGVsZW1lbnQgVGhlIGVsZW1lbnQgdGhhdCBzaG91bGQgaGF2ZSB0aGUgbGlzdGVuZXIgYWRkZWQuXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gbGlzdGVuZXIgVGhlIGNhbGxiYWNrIHRoYXQgdGhlIGVsZW1lbnQgaGFzIGFkZGVkLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGFkZExpc3RlbmVyKGVsZW1lbnQsIGxpc3RlbmVyKSB7XG4gICAgICAgIHZhciBpZCA9IGlkSGFuZGxlci5nZXQoZWxlbWVudCk7XG5cbiAgICAgICAgaWYoIWV2ZW50TGlzdGVuZXJzW2lkXSkge1xuICAgICAgICAgICAgZXZlbnRMaXN0ZW5lcnNbaWRdID0gW107XG4gICAgICAgIH1cblxuICAgICAgICBldmVudExpc3RlbmVyc1tpZF0ucHVzaChsaXN0ZW5lcik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmVtb3ZlTGlzdGVuZXIoZWxlbWVudCwgbGlzdGVuZXIpIHtcbiAgICAgICAgdmFyIGxpc3RlbmVycyA9IGdldExpc3RlbmVycyhlbGVtZW50KTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGxpc3RlbmVycy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgICAgICAgICAgaWYgKGxpc3RlbmVyc1tpXSA9PT0gbGlzdGVuZXIpIHtcbiAgICAgICAgICAgICAgbGlzdGVuZXJzLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiByZW1vdmVBbGxMaXN0ZW5lcnMoZWxlbWVudCkge1xuICAgICAgdmFyIGxpc3RlbmVycyA9IGdldExpc3RlbmVycyhlbGVtZW50KTtcbiAgICAgIGlmICghbGlzdGVuZXJzKSB7IHJldHVybjsgfVxuICAgICAgbGlzdGVuZXJzLmxlbmd0aCA9IDA7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgZ2V0OiBnZXRMaXN0ZW5lcnMsXG4gICAgICAgIGFkZDogYWRkTGlzdGVuZXIsXG4gICAgICAgIHJlbW92ZUxpc3RlbmVyOiByZW1vdmVMaXN0ZW5lcixcbiAgICAgICAgcmVtb3ZlQWxsTGlzdGVuZXJzOiByZW1vdmVBbGxMaXN0ZW5lcnNcbiAgICB9O1xufTtcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9lbGVtZW50LXJlc2l6ZS1kZXRlY3Rvci9zcmMvbGlzdGVuZXItaGFuZGxlci5qc1xuLy8gbW9kdWxlIGlkID0gMjZcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sInNvdXJjZVJvb3QiOiIifQ=="); - -/***/ }, -/* 27 */ -/***/ function(module, exports) { - -"use strict"; -eval("\"use strict\";\n\n/* global console: false */\n\n/**\n * Reporter that handles the reporting of logs, warnings and errors.\n * @public\n * @param {boolean} quiet Tells if the reporter should be quiet or not.\n */\nmodule.exports = function(quiet) {\n function noop() {\n //Does nothing.\n }\n\n var reporter = {\n log: noop,\n warn: noop,\n error: noop\n };\n\n if(!quiet && window.console) {\n var attachFunction = function(reporter, name) {\n //The proxy is needed to be able to call the method with the console context,\n //since we cannot use bind.\n reporter[name] = function reporterProxy() {\n var f = console[name];\n if (f.apply) { //IE9 does not support console.log.apply :)\n f.apply(console, arguments);\n } else {\n for (var i = 0; i < arguments.length; i++) {\n f(arguments[i]);\n }\n }\n };\n };\n\n attachFunction(reporter, \"log\");\n attachFunction(reporter, \"warn\");\n attachFunction(reporter, \"error\");\n }\n\n return reporter;\n};\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9+L2VsZW1lbnQtcmVzaXplLWRldGVjdG9yL3NyYy9yZXBvcnRlci5qcz9mMzk4Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsUUFBUTtBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOEJBQThCO0FBQzlCO0FBQ0EsaUJBQWlCO0FBQ2pCLG1DQUFtQyxzQkFBc0I7QUFDekQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBIiwiZmlsZSI6IjI3LmpzIiwic291cmNlc0NvbnRlbnQiOlsiXCJ1c2Ugc3RyaWN0XCI7XG5cbi8qIGdsb2JhbCBjb25zb2xlOiBmYWxzZSAqL1xuXG4vKipcbiAqIFJlcG9ydGVyIHRoYXQgaGFuZGxlcyB0aGUgcmVwb3J0aW5nIG9mIGxvZ3MsIHdhcm5pbmdzIGFuZCBlcnJvcnMuXG4gKiBAcHVibGljXG4gKiBAcGFyYW0ge2Jvb2xlYW59IHF1aWV0IFRlbGxzIGlmIHRoZSByZXBvcnRlciBzaG91bGQgYmUgcXVpZXQgb3Igbm90LlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKHF1aWV0KSB7XG4gICAgZnVuY3Rpb24gbm9vcCgpIHtcbiAgICAgICAgLy9Eb2VzIG5vdGhpbmcuXG4gICAgfVxuXG4gICAgdmFyIHJlcG9ydGVyID0ge1xuICAgICAgICBsb2c6IG5vb3AsXG4gICAgICAgIHdhcm46IG5vb3AsXG4gICAgICAgIGVycm9yOiBub29wXG4gICAgfTtcblxuICAgIGlmKCFxdWlldCAmJiB3aW5kb3cuY29uc29sZSkge1xuICAgICAgICB2YXIgYXR0YWNoRnVuY3Rpb24gPSBmdW5jdGlvbihyZXBvcnRlciwgbmFtZSkge1xuICAgICAgICAgICAgLy9UaGUgcHJveHkgaXMgbmVlZGVkIHRvIGJlIGFibGUgdG8gY2FsbCB0aGUgbWV0aG9kIHdpdGggdGhlIGNvbnNvbGUgY29udGV4dCxcbiAgICAgICAgICAgIC8vc2luY2Ugd2UgY2Fubm90IHVzZSBiaW5kLlxuICAgICAgICAgICAgcmVwb3J0ZXJbbmFtZV0gPSBmdW5jdGlvbiByZXBvcnRlclByb3h5KCkge1xuICAgICAgICAgICAgICAgIHZhciBmID0gY29uc29sZVtuYW1lXTtcbiAgICAgICAgICAgICAgICBpZiAoZi5hcHBseSkgeyAvL0lFOSBkb2VzIG5vdCBzdXBwb3J0IGNvbnNvbGUubG9nLmFwcGx5IDopXG4gICAgICAgICAgICAgICAgICAgIGYuYXBwbHkoY29uc29sZSwgYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgZihhcmd1bWVudHNbaV0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfTtcblxuICAgICAgICBhdHRhY2hGdW5jdGlvbihyZXBvcnRlciwgXCJsb2dcIik7XG4gICAgICAgIGF0dGFjaEZ1bmN0aW9uKHJlcG9ydGVyLCBcIndhcm5cIik7XG4gICAgICAgIGF0dGFjaEZ1bmN0aW9uKHJlcG9ydGVyLCBcImVycm9yXCIpO1xuICAgIH1cblxuICAgIHJldHVybiByZXBvcnRlcjtcbn07XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2VsZW1lbnQtcmVzaXplLWRldGVjdG9yL3NyYy9yZXBvcnRlci5qc1xuLy8gbW9kdWxlIGlkID0gMjdcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sInNvdXJjZVJvb3QiOiIifQ=="); - -/***/ }, -/* 28 */ -/***/ function(module, exports) { - -"use strict"; -eval("\"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\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9+L2VsZW1lbnQtcmVzaXplLWRldGVjdG9yL3NyYy9zdGF0ZS1oYW5kbGVyLmpzPzMwZDEiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6IjI4LmpzIiwic291cmNlc0NvbnRlbnQiOlsiXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBwcm9wID0gXCJfZXJkXCI7XG5cbmZ1bmN0aW9uIGluaXRTdGF0ZShlbGVtZW50KSB7XG4gICAgZWxlbWVudFtwcm9wXSA9IHt9O1xuICAgIHJldHVybiBnZXRTdGF0ZShlbGVtZW50KTtcbn1cblxuZnVuY3Rpb24gZ2V0U3RhdGUoZWxlbWVudCkge1xuICAgIHJldHVybiBlbGVtZW50W3Byb3BdO1xufVxuXG5mdW5jdGlvbiBjbGVhblN0YXRlKGVsZW1lbnQpIHtcbiAgICBkZWxldGUgZWxlbWVudFtwcm9wXTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgaW5pdFN0YXRlOiBpbml0U3RhdGUsXG4gICAgZ2V0U3RhdGU6IGdldFN0YXRlLFxuICAgIGNsZWFuU3RhdGU6IGNsZWFuU3RhdGVcbn07XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vZWxlbWVudC1yZXNpemUtZGV0ZWN0b3Ivc3JjL3N0YXRlLWhhbmRsZXIuanNcbi8vIG1vZHVsZSBpZCA9IDI4XG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0="); - -/***/ }, -/* 29 */ -/***/ function(module, exports, __webpack_require__) { - -eval("/**\n * interact.js v1.2.8\n *\n * Copyright (c) 2012-2015 Taye Adeyemi \n * Open source under the MIT License.\n * https://raw.github.com/taye/interact.js/master/LICENSE\n */\n(function (realWindow) {\n 'use strict';\n\n // return early if there's no window to work with (eg. Node.js)\n if (!realWindow) { return; }\n\n var // get wrapped window if using Shadow DOM polyfill\n window = (function () {\n // create a TextNode\n var el = realWindow.document.createTextNode('');\n\n // check if it's wrapped by a polyfill\n if (el.ownerDocument !== realWindow.document\n && typeof realWindow.wrap === 'function'\n && realWindow.wrap(el) === el) {\n // return wrapped window\n return realWindow.wrap(realWindow);\n }\n\n // no Shadow DOM polyfil or native implementation\n return realWindow;\n }()),\n\n document = window.document,\n DocumentFragment = window.DocumentFragment || blank,\n SVGElement = window.SVGElement || blank,\n SVGSVGElement = window.SVGSVGElement || blank,\n SVGElementInstance = window.SVGElementInstance || blank,\n HTMLElement = window.HTMLElement || window.Element,\n\n PointerEvent = (window.PointerEvent || window.MSPointerEvent),\n pEventTypes,\n\n hypot = Math.hypot || function (x, y) { return Math.sqrt(x * x + y * y); },\n\n tmpXY = {}, // reduce object creation in getXY()\n\n documents = [], // all documents being listened to\n\n interactables = [], // all set interactables\n interactions = [], // all interactions\n\n dynamicDrop = false,\n\n // {\n // type: {\n // selectors: ['selector', ...],\n // contexts : [document, ...],\n // listeners: [[listener, useCapture], ...]\n // }\n // }\n delegatedEvents = {},\n\n defaultOptions = {\n base: {\n accept : null,\n actionChecker : null,\n styleCursor : true,\n preventDefault: 'auto',\n origin : { x: 0, y: 0 },\n deltaSource : 'page',\n allowFrom : null,\n ignoreFrom : null,\n _context : document,\n dropChecker : null\n },\n\n drag: {\n enabled: false,\n manualStart: true,\n max: Infinity,\n maxPerElement: 1,\n\n snap: null,\n restrict: null,\n inertia: null,\n autoScroll: null,\n\n axis: 'xy'\n },\n\n drop: {\n enabled: false,\n accept: null,\n overlap: 'pointer'\n },\n\n resize: {\n enabled: false,\n manualStart: false,\n max: Infinity,\n maxPerElement: 1,\n\n snap: null,\n restrict: null,\n inertia: null,\n autoScroll: null,\n\n square: false,\n preserveAspectRatio: false,\n axis: 'xy',\n\n // use default margin\n margin: NaN,\n\n // object with props left, right, top, bottom which are\n // true/false values to resize when the pointer is over that edge,\n // CSS selectors to match the handles for each direction\n // or the Elements for each handle\n edges: null,\n\n // a value of 'none' will limit the resize rect to a minimum of 0x0\n // 'negate' will alow the rect to have negative width/height\n // 'reposition' will keep the width/height positive by swapping\n // the top and bottom edges and/or swapping the left and right edges\n invert: 'none'\n },\n\n gesture: {\n manualStart: false,\n enabled: false,\n max: Infinity,\n maxPerElement: 1,\n\n restrict: null\n },\n\n perAction: {\n manualStart: false,\n max: Infinity,\n maxPerElement: 1,\n\n snap: {\n enabled : false,\n endOnly : false,\n range : Infinity,\n targets : null,\n offsets : null,\n\n relativePoints: null\n },\n\n restrict: {\n enabled: false,\n endOnly: false\n },\n\n autoScroll: {\n enabled : false,\n container : null, // the item that is scrolled (Window or HTMLElement)\n margin : 60,\n speed : 300 // the scroll speed in pixels per second\n },\n\n inertia: {\n enabled : false,\n resistance : 10, // the lambda in exponential decay\n minSpeed : 100, // target speed must be above this for inertia to start\n endSpeed : 10, // the speed at which inertia is slow enough to stop\n allowResume : true, // allow resuming an action in inertia phase\n zeroResumeDelta : true, // if an action is resumed after launch, set dx/dy to 0\n smoothEndDuration: 300 // animate to snap/restrict endOnly if there's no inertia\n }\n },\n\n _holdDuration: 600\n },\n\n // Things related to autoScroll\n autoScroll = {\n interaction: null,\n i: null, // the handle returned by window.setInterval\n x: 0, y: 0, // Direction each pulse is to scroll in\n\n // scroll the window by the values in scroll.x/y\n scroll: function () {\n var options = autoScroll.interaction.target.options[autoScroll.interaction.prepared.name].autoScroll,\n container = options.container || getWindow(autoScroll.interaction.element),\n now = new Date().getTime(),\n // change in time in seconds\n dtx = (now - autoScroll.prevTimeX) / 1000,\n dty = (now - autoScroll.prevTimeY) / 1000,\n vx, vy, sx, sy;\n\n // displacement\n if (options.velocity) {\n vx = options.velocity.x;\n vy = options.velocity.y;\n }\n else {\n vx = vy = options.speed\n }\n \n sx = vx * dtx;\n sy = vy * dty;\n\n if (sx >= 1 || sy >= 1) {\n if (isWindow(container)) {\n container.scrollBy(autoScroll.x * sx, autoScroll.y * sy);\n }\n else if (container) {\n container.scrollLeft += autoScroll.x * sx;\n container.scrollTop += autoScroll.y * sy;\n }\n\n if (sx >=1) autoScroll.prevTimeX = now;\n if (sy >= 1) autoScroll.prevTimeY = now;\n }\n\n if (autoScroll.isScrolling) {\n cancelFrame(autoScroll.i);\n autoScroll.i = reqFrame(autoScroll.scroll);\n }\n },\n\n isScrolling: false,\n prevTimeX: 0,\n prevTimeY: 0,\n\n start: function (interaction) {\n autoScroll.isScrolling = true;\n cancelFrame(autoScroll.i);\n\n autoScroll.interaction = interaction;\n autoScroll.prevTimeX = new Date().getTime();\n autoScroll.prevTimeY = new Date().getTime();\n autoScroll.i = reqFrame(autoScroll.scroll);\n },\n\n stop: function () {\n autoScroll.isScrolling = false;\n cancelFrame(autoScroll.i);\n }\n },\n\n // Does the browser support touch input?\n supportsTouch = (('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch),\n\n // Does the browser support PointerEvents\n // Avoid PointerEvent bugs introduced in Chrome 55\n supportsPointerEvent = PointerEvent && !/Chrome/.test(navigator.userAgent),\n\n // Less Precision with touch input\n margin = supportsTouch || supportsPointerEvent? 20: 10,\n\n pointerMoveTolerance = 1,\n\n // for ignoring browser's simulated mouse events\n prevTouchTime = 0,\n\n // Allow this many interactions to happen simultaneously\n maxInteractions = Infinity,\n\n // Check if is IE9 or older\n actionCursors = (document.all && !window.atob) ? {\n drag : 'move',\n resizex : 'e-resize',\n resizey : 's-resize',\n resizexy: 'se-resize',\n\n resizetop : 'n-resize',\n resizeleft : 'w-resize',\n resizebottom : 's-resize',\n resizeright : 'e-resize',\n resizetopleft : 'se-resize',\n resizebottomright: 'se-resize',\n resizetopright : 'ne-resize',\n resizebottomleft : 'ne-resize',\n\n gesture : ''\n } : {\n drag : 'move',\n resizex : 'ew-resize',\n resizey : 'ns-resize',\n resizexy: 'nwse-resize',\n\n resizetop : 'ns-resize',\n resizeleft : 'ew-resize',\n resizebottom : 'ns-resize',\n resizeright : 'ew-resize',\n resizetopleft : 'nwse-resize',\n resizebottomright: 'nwse-resize',\n resizetopright : 'nesw-resize',\n resizebottomleft : 'nesw-resize',\n\n gesture : ''\n },\n\n actionIsEnabled = {\n drag : true,\n resize : true,\n gesture: true\n },\n\n // because Webkit and Opera still use 'mousewheel' event type\n wheelEvent = 'onmousewheel' in document? 'mousewheel': 'wheel',\n\n eventTypes = [\n 'dragstart',\n 'dragmove',\n 'draginertiastart',\n 'dragend',\n 'dragenter',\n 'dragleave',\n 'dropactivate',\n 'dropdeactivate',\n 'dropmove',\n 'drop',\n 'resizestart',\n 'resizemove',\n 'resizeinertiastart',\n 'resizeend',\n 'gesturestart',\n 'gesturemove',\n 'gestureinertiastart',\n 'gestureend',\n\n 'down',\n 'move',\n 'up',\n 'cancel',\n 'tap',\n 'doubletap',\n 'hold'\n ],\n\n globalEvents = {},\n\n // Opera Mobile must be handled differently\n isOperaMobile = navigator.appName == 'Opera' &&\n supportsTouch &&\n navigator.userAgent.match('Presto'),\n\n // scrolling doesn't change the result of getClientRects on iOS 7\n isIOS7 = (/iP(hone|od|ad)/.test(navigator.platform)\n && /OS 7[^\\d]/.test(navigator.appVersion)),\n\n // prefix matchesSelector\n prefixedMatchesSelector = 'matches' in Element.prototype?\n 'matches': 'webkitMatchesSelector' in Element.prototype?\n 'webkitMatchesSelector': 'mozMatchesSelector' in Element.prototype?\n 'mozMatchesSelector': 'oMatchesSelector' in Element.prototype?\n 'oMatchesSelector': 'msMatchesSelector',\n\n // will be polyfill function if browser is IE8\n ie8MatchesSelector,\n\n // native requestAnimationFrame or polyfill\n reqFrame = realWindow.requestAnimationFrame,\n cancelFrame = realWindow.cancelAnimationFrame,\n\n // Events wrapper\n events = (function () {\n var useAttachEvent = ('attachEvent' in window) && !('addEventListener' in window),\n addEvent = useAttachEvent? 'attachEvent': 'addEventListener',\n removeEvent = useAttachEvent? 'detachEvent': 'removeEventListener',\n on = useAttachEvent? 'on': '',\n\n elements = [],\n targets = [],\n attachedListeners = [];\n\n function add (element, type, listener, useCapture) {\n var elementIndex = indexOf(elements, element),\n target = targets[elementIndex];\n\n if (!target) {\n target = {\n events: {},\n typeCount: 0\n };\n\n elementIndex = elements.push(element) - 1;\n targets.push(target);\n\n attachedListeners.push((useAttachEvent ? {\n supplied: [],\n wrapped : [],\n useCount: []\n } : null));\n }\n\n if (!target.events[type]) {\n target.events[type] = [];\n target.typeCount++;\n }\n\n if (!contains(target.events[type], listener)) {\n var ret;\n\n if (useAttachEvent) {\n var listeners = attachedListeners[elementIndex],\n listenerIndex = indexOf(listeners.supplied, listener);\n\n var wrapped = listeners.wrapped[listenerIndex] || function (event) {\n if (!event.immediatePropagationStopped) {\n event.target = event.srcElement;\n event.currentTarget = element;\n\n event.preventDefault = event.preventDefault || preventDef;\n event.stopPropagation = event.stopPropagation || stopProp;\n event.stopImmediatePropagation = event.stopImmediatePropagation || stopImmProp;\n\n if (/mouse|click/.test(event.type)) {\n event.pageX = event.clientX + getWindow(element).document.documentElement.scrollLeft;\n event.pageY = event.clientY + getWindow(element).document.documentElement.scrollTop;\n }\n\n listener(event);\n }\n };\n\n ret = element[addEvent](on + type, wrapped, Boolean(useCapture));\n\n if (listenerIndex === -1) {\n listeners.supplied.push(listener);\n listeners.wrapped.push(wrapped);\n listeners.useCount.push(1);\n }\n else {\n listeners.useCount[listenerIndex]++;\n }\n }\n else {\n ret = element[addEvent](type, listener, useCapture || false);\n }\n target.events[type].push(listener);\n\n return ret;\n }\n }\n\n function remove (element, type, listener, useCapture) {\n var i,\n elementIndex = indexOf(elements, element),\n target = targets[elementIndex],\n listeners,\n listenerIndex,\n wrapped = listener;\n\n if (!target || !target.events) {\n return;\n }\n\n if (useAttachEvent) {\n listeners = attachedListeners[elementIndex];\n listenerIndex = indexOf(listeners.supplied, listener);\n wrapped = listeners.wrapped[listenerIndex];\n }\n\n if (type === 'all') {\n for (type in target.events) {\n if (target.events.hasOwnProperty(type)) {\n remove(element, type, 'all');\n }\n }\n return;\n }\n\n if (target.events[type]) {\n var len = target.events[type].length;\n\n if (listener === 'all') {\n for (i = 0; i < len; i++) {\n remove(element, type, target.events[type][i], Boolean(useCapture));\n }\n return;\n } else {\n for (i = 0; i < len; i++) {\n if (target.events[type][i] === listener) {\n element[removeEvent](on + type, wrapped, useCapture || false);\n target.events[type].splice(i, 1);\n\n if (useAttachEvent && listeners) {\n listeners.useCount[listenerIndex]--;\n if (listeners.useCount[listenerIndex] === 0) {\n listeners.supplied.splice(listenerIndex, 1);\n listeners.wrapped.splice(listenerIndex, 1);\n listeners.useCount.splice(listenerIndex, 1);\n }\n }\n\n break;\n }\n }\n }\n\n if (target.events[type] && target.events[type].length === 0) {\n target.events[type] = null;\n target.typeCount--;\n }\n }\n\n if (!target.typeCount) {\n targets.splice(elementIndex, 1);\n elements.splice(elementIndex, 1);\n attachedListeners.splice(elementIndex, 1);\n }\n }\n\n function preventDef () {\n this.returnValue = false;\n }\n\n function stopProp () {\n this.cancelBubble = true;\n }\n\n function stopImmProp () {\n this.cancelBubble = true;\n this.immediatePropagationStopped = true;\n }\n\n return {\n add: add,\n remove: remove,\n useAttachEvent: useAttachEvent,\n\n _elements: elements,\n _targets: targets,\n _attachedListeners: attachedListeners\n };\n }());\n\n function blank () {}\n\n function isElement (o) {\n if (!o || (typeof o !== 'object')) { return false; }\n\n var _window = getWindow(o) || window;\n\n return (/object|function/.test(typeof _window.Element)\n ? o instanceof _window.Element //DOM2\n : o.nodeType === 1 && typeof o.nodeName === \"string\");\n }\n function isWindow (thing) { return thing === window || !!(thing && thing.Window) && (thing instanceof thing.Window); }\n function isDocFrag (thing) { return !!thing && thing instanceof DocumentFragment; }\n function isArray (thing) {\n return isObject(thing)\n && (typeof thing.length !== undefined)\n && isFunction(thing.splice);\n }\n function isObject (thing) { return !!thing && (typeof thing === 'object'); }\n function isFunction (thing) { return typeof thing === 'function'; }\n function isNumber (thing) { return typeof thing === 'number' ; }\n function isBool (thing) { return typeof thing === 'boolean' ; }\n function isString (thing) { return typeof thing === 'string' ; }\n\n function trySelector (value) {\n if (!isString(value)) { return false; }\n\n // an exception will be raised if it is invalid\n document.querySelector(value);\n return true;\n }\n\n function extend (dest, source) {\n for (var prop in source) {\n dest[prop] = source[prop];\n }\n return dest;\n }\n\n var prefixedPropREs = {\n webkit: /(Movement[XY]|Radius[XY]|RotationAngle|Force)$/\n };\n\n function pointerExtend (dest, source) {\n for (var prop in source) {\n var deprecated = false;\n\n // skip deprecated prefixed properties\n for (var vendor in prefixedPropREs) {\n if (prop.indexOf(vendor) === 0 && prefixedPropREs[vendor].test(prop)) {\n deprecated = true;\n break;\n }\n }\n\n if (!deprecated) {\n dest[prop] = source[prop];\n }\n }\n return dest;\n }\n\n function copyCoords (dest, src) {\n dest.page = dest.page || {};\n dest.page.x = src.page.x;\n dest.page.y = src.page.y;\n\n dest.client = dest.client || {};\n dest.client.x = src.client.x;\n dest.client.y = src.client.y;\n\n dest.timeStamp = src.timeStamp;\n }\n\n function setEventXY (targetObj, pointers, interaction) {\n var pointer = (pointers.length > 1\n ? pointerAverage(pointers)\n : pointers[0]);\n\n getPageXY(pointer, tmpXY, interaction);\n targetObj.page.x = tmpXY.x;\n targetObj.page.y = tmpXY.y;\n\n getClientXY(pointer, tmpXY, interaction);\n targetObj.client.x = tmpXY.x;\n targetObj.client.y = tmpXY.y;\n\n targetObj.timeStamp = new Date().getTime();\n }\n\n function setEventDeltas (targetObj, prev, cur) {\n targetObj.page.x = cur.page.x - prev.page.x;\n targetObj.page.y = cur.page.y - prev.page.y;\n targetObj.client.x = cur.client.x - prev.client.x;\n targetObj.client.y = cur.client.y - prev.client.y;\n targetObj.timeStamp = new Date().getTime() - prev.timeStamp;\n\n // set pointer velocity\n var dt = Math.max(targetObj.timeStamp / 1000, 0.001);\n targetObj.page.speed = hypot(targetObj.page.x, targetObj.page.y) / dt;\n targetObj.page.vx = targetObj.page.x / dt;\n targetObj.page.vy = targetObj.page.y / dt;\n\n targetObj.client.speed = hypot(targetObj.client.x, targetObj.page.y) / dt;\n targetObj.client.vx = targetObj.client.x / dt;\n targetObj.client.vy = targetObj.client.y / dt;\n }\n\n function isNativePointer (pointer) {\n return (pointer instanceof window.Event\n || (supportsTouch && window.Touch && pointer instanceof window.Touch));\n }\n\n // Get specified X/Y coords for mouse or event.touches[0]\n function getXY (type, pointer, xy) {\n xy = xy || {};\n type = type || 'page';\n\n xy.x = pointer[type + 'X'];\n xy.y = pointer[type + 'Y'];\n\n return xy;\n }\n\n function getPageXY (pointer, page) {\n page = page || {};\n\n // Opera Mobile handles the viewport and scrolling oddly\n if (isOperaMobile && isNativePointer(pointer)) {\n getXY('screen', pointer, page);\n\n page.x += window.scrollX;\n page.y += window.scrollY;\n }\n else {\n getXY('page', pointer, page);\n }\n\n return page;\n }\n\n function getClientXY (pointer, client) {\n client = client || {};\n\n if (isOperaMobile && isNativePointer(pointer)) {\n // Opera Mobile handles the viewport and scrolling oddly\n getXY('screen', pointer, client);\n }\n else {\n getXY('client', pointer, client);\n }\n\n return client;\n }\n\n function getScrollXY (win) {\n win = win || window;\n return {\n x: win.scrollX || win.document.documentElement.scrollLeft,\n y: win.scrollY || win.document.documentElement.scrollTop\n };\n }\n\n function getPointerId (pointer) {\n return isNumber(pointer.pointerId)? pointer.pointerId : pointer.identifier;\n }\n\n function getActualElement (element) {\n return (element instanceof SVGElementInstance\n ? element.correspondingUseElement\n : element);\n }\n\n function getWindow (node) {\n if (isWindow(node)) {\n return node;\n }\n\n var rootNode = (node.ownerDocument || node);\n\n return rootNode.defaultView || rootNode.parentWindow || window;\n }\n\n function getElementClientRect (element) {\n var clientRect = (element instanceof SVGElement\n ? element.getBoundingClientRect()\n : element.getClientRects()[0]);\n\n return clientRect && {\n left : clientRect.left,\n right : clientRect.right,\n top : clientRect.top,\n bottom: clientRect.bottom,\n width : clientRect.width || clientRect.right - clientRect.left,\n height: clientRect.height || clientRect.bottom - clientRect.top\n };\n }\n\n function getElementRect (element) {\n var clientRect = getElementClientRect(element);\n\n if (!isIOS7 && clientRect) {\n var scroll = getScrollXY(getWindow(element));\n\n clientRect.left += scroll.x;\n clientRect.right += scroll.x;\n clientRect.top += scroll.y;\n clientRect.bottom += scroll.y;\n }\n\n return clientRect;\n }\n\n function getTouchPair (event) {\n var touches = [];\n\n // array of touches is supplied\n if (isArray(event)) {\n touches[0] = event[0];\n touches[1] = event[1];\n }\n // an event\n else {\n if (event.type === 'touchend') {\n if (event.touches.length === 1) {\n touches[0] = event.touches[0];\n touches[1] = event.changedTouches[0];\n }\n else if (event.touches.length === 0) {\n touches[0] = event.changedTouches[0];\n touches[1] = event.changedTouches[1];\n }\n }\n else {\n touches[0] = event.touches[0];\n touches[1] = event.touches[1];\n }\n }\n\n return touches;\n }\n\n function pointerAverage (pointers) {\n var average = {\n pageX : 0,\n pageY : 0,\n clientX: 0,\n clientY: 0,\n screenX: 0,\n screenY: 0\n };\n var prop;\n\n for (var i = 0; i < pointers.length; i++) {\n for (prop in average) {\n average[prop] += pointers[i][prop];\n }\n }\n for (prop in average) {\n average[prop] /= pointers.length;\n }\n\n return average;\n }\n\n function touchBBox (event) {\n if (!event.length && !(event.touches && event.touches.length > 1)) {\n return;\n }\n\n var touches = getTouchPair(event),\n minX = Math.min(touches[0].pageX, touches[1].pageX),\n minY = Math.min(touches[0].pageY, touches[1].pageY),\n maxX = Math.max(touches[0].pageX, touches[1].pageX),\n maxY = Math.max(touches[0].pageY, touches[1].pageY);\n\n return {\n x: minX,\n y: minY,\n left: minX,\n top: minY,\n width: maxX - minX,\n height: maxY - minY\n };\n }\n\n function touchDistance (event, deltaSource) {\n deltaSource = deltaSource || defaultOptions.deltaSource;\n\n var sourceX = deltaSource + 'X',\n sourceY = deltaSource + 'Y',\n touches = getTouchPair(event);\n\n\n var dx = touches[0][sourceX] - touches[1][sourceX],\n dy = touches[0][sourceY] - touches[1][sourceY];\n\n return hypot(dx, dy);\n }\n\n function touchAngle (event, prevAngle, deltaSource) {\n deltaSource = deltaSource || defaultOptions.deltaSource;\n\n var sourceX = deltaSource + 'X',\n sourceY = deltaSource + 'Y',\n touches = getTouchPair(event),\n dx = touches[0][sourceX] - touches[1][sourceX],\n dy = touches[0][sourceY] - touches[1][sourceY],\n angle = 180 * Math.atan(dy / dx) / Math.PI;\n\n if (isNumber(prevAngle)) {\n var dr = angle - prevAngle,\n drClamped = dr % 360;\n\n if (drClamped > 315) {\n angle -= 360 + (angle / 360)|0 * 360;\n }\n else if (drClamped > 135) {\n angle -= 180 + (angle / 360)|0 * 360;\n }\n else if (drClamped < -315) {\n angle += 360 + (angle / 360)|0 * 360;\n }\n else if (drClamped < -135) {\n angle += 180 + (angle / 360)|0 * 360;\n }\n }\n\n return angle;\n }\n\n function getOriginXY (interactable, element) {\n var origin = interactable\n ? interactable.options.origin\n : defaultOptions.origin;\n\n if (origin === 'parent') {\n origin = parentElement(element);\n }\n else if (origin === 'self') {\n origin = interactable.getRect(element);\n }\n else if (trySelector(origin)) {\n origin = closest(element, origin) || { x: 0, y: 0 };\n }\n\n if (isFunction(origin)) {\n origin = origin(interactable && element);\n }\n\n if (isElement(origin)) {\n origin = getElementRect(origin);\n }\n\n origin.x = ('x' in origin)? origin.x : origin.left;\n origin.y = ('y' in origin)? origin.y : origin.top;\n\n return origin;\n }\n\n // http://stackoverflow.com/a/5634528/2280888\n function _getQBezierValue(t, p1, p2, p3) {\n var iT = 1 - t;\n return iT * iT * p1 + 2 * iT * t * p2 + t * t * p3;\n }\n\n function getQuadraticCurvePoint(startX, startY, cpX, cpY, endX, endY, position) {\n return {\n x: _getQBezierValue(position, startX, cpX, endX),\n y: _getQBezierValue(position, startY, cpY, endY)\n };\n }\n\n // http://gizma.com/easing/\n function easeOutQuad (t, b, c, d) {\n t /= d;\n return -c * t*(t-2) + b;\n }\n\n function nodeContains (parent, child) {\n while (child) {\n if (child === parent) {\n return true;\n }\n\n child = child.parentNode;\n }\n\n return false;\n }\n\n function closest (child, selector) {\n var parent = parentElement(child);\n\n while (isElement(parent)) {\n if (matchesSelector(parent, selector)) { return parent; }\n\n parent = parentElement(parent);\n }\n\n return null;\n }\n\n function parentElement (node) {\n var parent = node.parentNode;\n\n if (isDocFrag(parent)) {\n // skip past #shado-root fragments\n while ((parent = parent.host) && isDocFrag(parent)) {}\n\n return parent;\n }\n\n return parent;\n }\n\n function inContext (interactable, element) {\n return interactable._context === element.ownerDocument\n || nodeContains(interactable._context, element);\n }\n\n function testIgnore (interactable, interactableElement, element) {\n var ignoreFrom = interactable.options.ignoreFrom;\n\n if (!ignoreFrom || !isElement(element)) { return false; }\n\n if (isString(ignoreFrom)) {\n return matchesUpTo(element, ignoreFrom, interactableElement);\n }\n else if (isElement(ignoreFrom)) {\n return nodeContains(ignoreFrom, element);\n }\n\n return false;\n }\n\n function testAllow (interactable, interactableElement, element) {\n var allowFrom = interactable.options.allowFrom;\n\n if (!allowFrom) { return true; }\n\n if (!isElement(element)) { return false; }\n\n if (isString(allowFrom)) {\n return matchesUpTo(element, allowFrom, interactableElement);\n }\n else if (isElement(allowFrom)) {\n return nodeContains(allowFrom, element);\n }\n\n return false;\n }\n\n function checkAxis (axis, interactable) {\n if (!interactable) { return false; }\n\n var thisAxis = interactable.options.drag.axis;\n\n return (axis === 'xy' || thisAxis === 'xy' || thisAxis === axis);\n }\n\n function checkSnap (interactable, action) {\n var options = interactable.options;\n\n if (/^resize/.test(action)) {\n action = 'resize';\n }\n\n return options[action].snap && options[action].snap.enabled;\n }\n\n function checkRestrict (interactable, action) {\n var options = interactable.options;\n\n if (/^resize/.test(action)) {\n action = 'resize';\n }\n\n return options[action].restrict && options[action].restrict.enabled;\n }\n\n function checkAutoScroll (interactable, action) {\n var options = interactable.options;\n\n if (/^resize/.test(action)) {\n action = 'resize';\n }\n\n return options[action].autoScroll && options[action].autoScroll.enabled;\n }\n\n function withinInteractionLimit (interactable, element, action) {\n var options = interactable.options,\n maxActions = options[action.name].max,\n maxPerElement = options[action.name].maxPerElement,\n activeInteractions = 0,\n targetCount = 0,\n targetElementCount = 0;\n\n for (var i = 0, len = interactions.length; i < len; i++) {\n var interaction = interactions[i],\n otherAction = interaction.prepared.name,\n active = interaction.interacting();\n\n if (!active) { continue; }\n\n activeInteractions++;\n\n if (activeInteractions >= maxInteractions) {\n return false;\n }\n\n if (interaction.target !== interactable) { continue; }\n\n targetCount += (otherAction === action.name)|0;\n\n if (targetCount >= maxActions) {\n return false;\n }\n\n if (interaction.element === element) {\n targetElementCount++;\n\n if (otherAction !== action.name || targetElementCount >= maxPerElement) {\n return false;\n }\n }\n }\n\n return maxInteractions > 0;\n }\n\n // Test for the element that's \"above\" all other qualifiers\n function indexOfDeepestElement (elements) {\n var dropzone,\n deepestZone = elements[0],\n index = deepestZone? 0: -1,\n parent,\n deepestZoneParents = [],\n dropzoneParents = [],\n child,\n i,\n n;\n\n for (i = 1; i < elements.length; i++) {\n dropzone = elements[i];\n\n // an element might belong to multiple selector dropzones\n if (!dropzone || dropzone === deepestZone) {\n continue;\n }\n\n if (!deepestZone) {\n deepestZone = dropzone;\n index = i;\n continue;\n }\n\n // check if the deepest or current are document.documentElement or document.rootElement\n // - if the current dropzone is, do nothing and continue\n if (dropzone.parentNode === dropzone.ownerDocument) {\n continue;\n }\n // - if deepest is, update with the current dropzone and continue to next\n else if (deepestZone.parentNode === dropzone.ownerDocument) {\n deepestZone = dropzone;\n index = i;\n continue;\n }\n\n if (!deepestZoneParents.length) {\n parent = deepestZone;\n while (parent.parentNode && parent.parentNode !== parent.ownerDocument) {\n deepestZoneParents.unshift(parent);\n parent = parent.parentNode;\n }\n }\n\n // if this element is an svg element and the current deepest is\n // an HTMLElement\n if (deepestZone instanceof HTMLElement\n && dropzone instanceof SVGElement\n && !(dropzone instanceof SVGSVGElement)) {\n\n if (dropzone === deepestZone.parentNode) {\n continue;\n }\n\n parent = dropzone.ownerSVGElement;\n }\n else {\n parent = dropzone;\n }\n\n dropzoneParents = [];\n\n while (parent.parentNode !== parent.ownerDocument) {\n dropzoneParents.unshift(parent);\n parent = parent.parentNode;\n }\n\n n = 0;\n\n // get (position of last common ancestor) + 1\n while (dropzoneParents[n] && dropzoneParents[n] === deepestZoneParents[n]) {\n n++;\n }\n\n var parents = [\n dropzoneParents[n - 1],\n dropzoneParents[n],\n deepestZoneParents[n]\n ];\n\n child = parents[0].lastChild;\n\n while (child) {\n if (child === parents[1]) {\n deepestZone = dropzone;\n index = i;\n deepestZoneParents = [];\n\n break;\n }\n else if (child === parents[2]) {\n break;\n }\n\n child = child.previousSibling;\n }\n }\n\n return index;\n }\n\n function Interaction () {\n this.target = null; // current interactable being interacted with\n this.element = null; // the target element of the interactable\n this.dropTarget = null; // the dropzone a drag target might be dropped into\n this.dropElement = null; // the element at the time of checking\n this.prevDropTarget = null; // the dropzone that was recently dragged away from\n this.prevDropElement = null; // the element at the time of checking\n\n this.prepared = { // action that's ready to be fired on next move event\n name : null,\n axis : null,\n edges: null\n };\n\n this.matches = []; // all selectors that are matched by target element\n this.matchElements = []; // corresponding elements\n\n this.inertiaStatus = {\n active : false,\n smoothEnd : false,\n ending : false,\n\n startEvent: null,\n upCoords: {},\n\n xe: 0, ye: 0,\n sx: 0, sy: 0,\n\n t0: 0,\n vx0: 0, vys: 0,\n duration: 0,\n\n resumeDx: 0,\n resumeDy: 0,\n\n lambda_v0: 0,\n one_ve_v0: 0,\n i : null\n };\n\n if (isFunction(Function.prototype.bind)) {\n this.boundInertiaFrame = this.inertiaFrame.bind(this);\n this.boundSmoothEndFrame = this.smoothEndFrame.bind(this);\n }\n else {\n var that = this;\n\n this.boundInertiaFrame = function () { return that.inertiaFrame(); };\n this.boundSmoothEndFrame = function () { return that.smoothEndFrame(); };\n }\n\n this.activeDrops = {\n dropzones: [], // the dropzones that are mentioned below\n elements : [], // elements of dropzones that accept the target draggable\n rects : [] // the rects of the elements mentioned above\n };\n\n // keep track of added pointers\n this.pointers = [];\n this.pointerIds = [];\n this.downTargets = [];\n this.downTimes = [];\n this.holdTimers = [];\n\n // Previous native pointer move event coordinates\n this.prevCoords = {\n page : { x: 0, y: 0 },\n client : { x: 0, y: 0 },\n timeStamp: 0\n };\n // current native pointer move event coordinates\n this.curCoords = {\n page : { x: 0, y: 0 },\n client : { x: 0, y: 0 },\n timeStamp: 0\n };\n\n // Starting InteractEvent pointer coordinates\n this.startCoords = {\n page : { x: 0, y: 0 },\n client : { x: 0, y: 0 },\n timeStamp: 0\n };\n\n // Change in coordinates and time of the pointer\n this.pointerDelta = {\n page : { x: 0, y: 0, vx: 0, vy: 0, speed: 0 },\n client : { x: 0, y: 0, vx: 0, vy: 0, speed: 0 },\n timeStamp: 0\n };\n\n this.downEvent = null; // pointerdown/mousedown/touchstart event\n this.downPointer = {};\n\n this._eventTarget = null;\n this._curEventTarget = null;\n\n this.prevEvent = null; // previous action event\n this.tapTime = 0; // time of the most recent tap event\n this.prevTap = null;\n\n this.startOffset = { left: 0, right: 0, top: 0, bottom: 0 };\n this.restrictOffset = { left: 0, right: 0, top: 0, bottom: 0 };\n this.snapOffsets = [];\n\n this.gesture = {\n start: { x: 0, y: 0 },\n\n startDistance: 0, // distance between two touches of touchStart\n prevDistance : 0,\n distance : 0,\n\n scale: 1, // gesture.distance / gesture.startDistance\n\n startAngle: 0, // angle of line joining two touches\n prevAngle : 0 // angle of the previous gesture event\n };\n\n this.snapStatus = {\n x : 0, y : 0,\n dx : 0, dy : 0,\n realX : 0, realY : 0,\n snappedX: 0, snappedY: 0,\n targets : [],\n locked : false,\n changed : false\n };\n\n this.restrictStatus = {\n dx : 0, dy : 0,\n restrictedX: 0, restrictedY: 0,\n snap : null,\n restricted : false,\n changed : false\n };\n\n this.restrictStatus.snap = this.snapStatus;\n\n this.pointerIsDown = false;\n this.pointerWasMoved = false;\n this.gesturing = false;\n this.dragging = false;\n this.resizing = false;\n this.resizeAxes = 'xy';\n\n this.mouse = false;\n\n interactions.push(this);\n }\n\n Interaction.prototype = {\n getPageXY : function (pointer, xy) { return getPageXY(pointer, xy, this); },\n getClientXY: function (pointer, xy) { return getClientXY(pointer, xy, this); },\n setEventXY : function (target, ptr) { return setEventXY(target, ptr, this); },\n\n pointerOver: function (pointer, event, eventTarget) {\n if (this.prepared.name || !this.mouse) { return; }\n\n var curMatches = [],\n curMatchElements = [],\n prevTargetElement = this.element;\n\n this.addPointer(pointer);\n\n if (this.target\n && (testIgnore(this.target, this.element, eventTarget)\n || !testAllow(this.target, this.element, eventTarget))) {\n // if the eventTarget should be ignored or shouldn't be allowed\n // clear the previous target\n this.target = null;\n this.element = null;\n this.matches = [];\n this.matchElements = [];\n }\n\n var elementInteractable = interactables.get(eventTarget),\n elementAction = (elementInteractable\n && !testIgnore(elementInteractable, eventTarget, eventTarget)\n && testAllow(elementInteractable, eventTarget, eventTarget)\n && validateAction(\n elementInteractable.getAction(pointer, event, this, eventTarget),\n elementInteractable));\n\n if (elementAction && !withinInteractionLimit(elementInteractable, eventTarget, elementAction)) {\n elementAction = null;\n }\n\n function pushCurMatches (interactable, selector) {\n if (interactable\n && inContext(interactable, eventTarget)\n && !testIgnore(interactable, eventTarget, eventTarget)\n && testAllow(interactable, eventTarget, eventTarget)\n && matchesSelector(eventTarget, selector)) {\n\n curMatches.push(interactable);\n curMatchElements.push(eventTarget);\n }\n }\n\n if (elementAction) {\n this.target = elementInteractable;\n this.element = eventTarget;\n this.matches = [];\n this.matchElements = [];\n }\n else {\n interactables.forEachSelector(pushCurMatches);\n\n if (this.validateSelector(pointer, event, curMatches, curMatchElements)) {\n this.matches = curMatches;\n this.matchElements = curMatchElements;\n\n this.pointerHover(pointer, event, this.matches, this.matchElements);\n events.add(eventTarget,\n supportsPointerEvent? pEventTypes.move : 'mousemove',\n listeners.pointerHover);\n }\n else if (this.target) {\n if (nodeContains(prevTargetElement, eventTarget)) {\n this.pointerHover(pointer, event, this.matches, this.matchElements);\n events.add(this.element,\n supportsPointerEvent? pEventTypes.move : 'mousemove',\n listeners.pointerHover);\n }\n else {\n this.target = null;\n this.element = null;\n this.matches = [];\n this.matchElements = [];\n }\n }\n }\n },\n\n // Check what action would be performed on pointerMove target if a mouse\n // button were pressed and change the cursor accordingly\n pointerHover: function (pointer, event, eventTarget, curEventTarget, matches, matchElements) {\n var target = this.target;\n\n if (!this.prepared.name && this.mouse) {\n\n var action;\n\n // update pointer coords for defaultActionChecker to use\n this.setEventXY(this.curCoords, [pointer]);\n\n if (matches) {\n action = this.validateSelector(pointer, event, matches, matchElements);\n }\n else if (target) {\n action = validateAction(target.getAction(this.pointers[0], event, this, this.element), this.target);\n }\n\n if (target && target.options.styleCursor) {\n if (action) {\n target._doc.documentElement.style.cursor = getActionCursor(action);\n }\n else {\n target._doc.documentElement.style.cursor = '';\n }\n }\n }\n else if (this.prepared.name) {\n this.checkAndPreventDefault(event, target, this.element);\n }\n },\n\n pointerOut: function (pointer, event, eventTarget) {\n if (this.prepared.name) { return; }\n\n // Remove temporary event listeners for selector Interactables\n if (!interactables.get(eventTarget)) {\n events.remove(eventTarget,\n supportsPointerEvent? pEventTypes.move : 'mousemove',\n listeners.pointerHover);\n }\n\n if (this.target && this.target.options.styleCursor && !this.interacting()) {\n this.target._doc.documentElement.style.cursor = '';\n }\n },\n\n selectorDown: function (pointer, event, eventTarget, curEventTarget) {\n var that = this,\n // copy event to be used in timeout for IE8\n eventCopy = events.useAttachEvent? extend({}, event) : event,\n element = eventTarget,\n pointerIndex = this.addPointer(pointer),\n action;\n\n this.holdTimers[pointerIndex] = setTimeout(function () {\n that.pointerHold(events.useAttachEvent? eventCopy : pointer, eventCopy, eventTarget, curEventTarget);\n }, defaultOptions._holdDuration);\n\n this.pointerIsDown = true;\n\n // Check if the down event hits the current inertia target\n if (this.inertiaStatus.active && this.target.selector) {\n // climb up the DOM tree from the event target\n while (isElement(element)) {\n\n // if this element is the current inertia target element\n if (element === this.element\n // and the prospective action is the same as the ongoing one\n && validateAction(this.target.getAction(pointer, event, this, this.element), this.target).name === this.prepared.name) {\n\n // stop inertia so that the next move will be a normal one\n cancelFrame(this.inertiaStatus.i);\n this.inertiaStatus.active = false;\n\n this.collectEventTargets(pointer, event, eventTarget, 'down');\n return;\n }\n element = parentElement(element);\n }\n }\n\n // do nothing if interacting\n if (this.interacting()) {\n this.collectEventTargets(pointer, event, eventTarget, 'down');\n return;\n }\n\n function pushMatches (interactable, selector, context) {\n var elements = ie8MatchesSelector\n ? context.querySelectorAll(selector)\n : undefined;\n\n if (inContext(interactable, element)\n && !testIgnore(interactable, element, eventTarget)\n && testAllow(interactable, element, eventTarget)\n && matchesSelector(element, selector, elements)) {\n\n that.matches.push(interactable);\n that.matchElements.push(element);\n }\n }\n\n // update pointer coords for defaultActionChecker to use\n this.setEventXY(this.curCoords, [pointer]);\n this.downEvent = event;\n\n while (isElement(element) && !action) {\n this.matches = [];\n this.matchElements = [];\n\n interactables.forEachSelector(pushMatches);\n\n action = this.validateSelector(pointer, event, this.matches, this.matchElements);\n element = parentElement(element);\n }\n\n if (action) {\n this.prepared.name = action.name;\n this.prepared.axis = action.axis;\n this.prepared.edges = action.edges;\n\n this.collectEventTargets(pointer, event, eventTarget, 'down');\n\n return this.pointerDown(pointer, event, eventTarget, curEventTarget, action);\n }\n else {\n // do these now since pointerDown isn't being called from here\n this.downTimes[pointerIndex] = new Date().getTime();\n this.downTargets[pointerIndex] = eventTarget;\n pointerExtend(this.downPointer, pointer);\n\n copyCoords(this.prevCoords, this.curCoords);\n this.pointerWasMoved = false;\n }\n\n this.collectEventTargets(pointer, event, eventTarget, 'down');\n },\n\n // Determine action to be performed on next pointerMove and add appropriate\n // style and event Listeners\n pointerDown: function (pointer, event, eventTarget, curEventTarget, forceAction) {\n if (!forceAction && !this.inertiaStatus.active && this.pointerWasMoved && this.prepared.name) {\n this.checkAndPreventDefault(event, this.target, this.element);\n\n return;\n }\n\n this.pointerIsDown = true;\n this.downEvent = event;\n\n var pointerIndex = this.addPointer(pointer),\n action;\n\n // If it is the second touch of a multi-touch gesture, keep the\n // target the same and get a new action if a target was set by the\n // first touch\n if (this.pointerIds.length > 1 && this.target._element === this.element) {\n var newAction = validateAction(forceAction || this.target.getAction(pointer, event, this, this.element), this.target);\n\n if (withinInteractionLimit(this.target, this.element, newAction)) {\n action = newAction;\n }\n\n this.prepared.name = null;\n }\n // Otherwise, set the target if there is no action prepared\n else if (!this.prepared.name) {\n var interactable = interactables.get(curEventTarget);\n\n if (interactable\n && !testIgnore(interactable, curEventTarget, eventTarget)\n && testAllow(interactable, curEventTarget, eventTarget)\n && (action = validateAction(forceAction || interactable.getAction(pointer, event, this, curEventTarget), interactable, eventTarget))\n && withinInteractionLimit(interactable, curEventTarget, action)) {\n this.target = interactable;\n this.element = curEventTarget;\n }\n }\n\n var target = this.target,\n options = target && target.options;\n\n if (target && (forceAction || !this.prepared.name)) {\n action = action || validateAction(forceAction || target.getAction(pointer, event, this, curEventTarget), target, this.element);\n\n this.setEventXY(this.startCoords, this.pointers);\n\n if (!action) { return; }\n\n if (options.styleCursor) {\n target._doc.documentElement.style.cursor = getActionCursor(action);\n }\n\n this.resizeAxes = action.name === 'resize'? action.axis : null;\n\n if (action === 'gesture' && this.pointerIds.length < 2) {\n action = null;\n }\n\n this.prepared.name = action.name;\n this.prepared.axis = action.axis;\n this.prepared.edges = action.edges;\n\n this.snapStatus.snappedX = this.snapStatus.snappedY =\n this.restrictStatus.restrictedX = this.restrictStatus.restrictedY = NaN;\n\n this.downTimes[pointerIndex] = new Date().getTime();\n this.downTargets[pointerIndex] = eventTarget;\n pointerExtend(this.downPointer, pointer);\n\n copyCoords(this.prevCoords, this.startCoords);\n this.pointerWasMoved = false;\n\n this.checkAndPreventDefault(event, target, this.element);\n }\n // if inertia is active try to resume action\n else if (this.inertiaStatus.active\n && curEventTarget === this.element\n && validateAction(target.getAction(pointer, event, this, this.element), target).name === this.prepared.name) {\n\n cancelFrame(this.inertiaStatus.i);\n this.inertiaStatus.active = false;\n\n this.checkAndPreventDefault(event, target, this.element);\n }\n },\n\n setModifications: function (coords, preEnd) {\n var target = this.target,\n shouldMove = true,\n shouldSnap = checkSnap(target, this.prepared.name) && (!target.options[this.prepared.name].snap.endOnly || preEnd),\n shouldRestrict = checkRestrict(target, this.prepared.name) && (!target.options[this.prepared.name].restrict.endOnly || preEnd);\n\n if (shouldSnap ) { this.setSnapping (coords); } else { this.snapStatus .locked = false; }\n if (shouldRestrict) { this.setRestriction(coords); } else { this.restrictStatus.restricted = false; }\n\n if (shouldSnap && this.snapStatus.locked && !this.snapStatus.changed) {\n shouldMove = shouldRestrict && this.restrictStatus.restricted && this.restrictStatus.changed;\n }\n else if (shouldRestrict && this.restrictStatus.restricted && !this.restrictStatus.changed) {\n shouldMove = false;\n }\n\n return shouldMove;\n },\n\n setStartOffsets: function (action, interactable, element) {\n var rect = interactable.getRect(element),\n origin = getOriginXY(interactable, element),\n snap = interactable.options[this.prepared.name].snap,\n restrict = interactable.options[this.prepared.name].restrict,\n width, height;\n\n if (rect) {\n this.startOffset.left = this.startCoords.page.x - rect.left;\n this.startOffset.top = this.startCoords.page.y - rect.top;\n\n this.startOffset.right = rect.right - this.startCoords.page.x;\n this.startOffset.bottom = rect.bottom - this.startCoords.page.y;\n\n if ('width' in rect) { width = rect.width; }\n else { width = rect.right - rect.left; }\n if ('height' in rect) { height = rect.height; }\n else { height = rect.bottom - rect.top; }\n }\n else {\n this.startOffset.left = this.startOffset.top = this.startOffset.right = this.startOffset.bottom = 0;\n }\n\n this.snapOffsets.splice(0);\n\n var snapOffset = snap && snap.offset === 'startCoords'\n ? {\n x: this.startCoords.page.x - origin.x,\n y: this.startCoords.page.y - origin.y\n }\n : snap && snap.offset || { x: 0, y: 0 };\n\n if (rect && snap && snap.relativePoints && snap.relativePoints.length) {\n for (var i = 0; i < snap.relativePoints.length; i++) {\n this.snapOffsets.push({\n x: this.startOffset.left - (width * snap.relativePoints[i].x) + snapOffset.x,\n y: this.startOffset.top - (height * snap.relativePoints[i].y) + snapOffset.y\n });\n }\n }\n else {\n this.snapOffsets.push(snapOffset);\n }\n\n if (rect && restrict.elementRect) {\n this.restrictOffset.left = this.startOffset.left - (width * restrict.elementRect.left);\n this.restrictOffset.top = this.startOffset.top - (height * restrict.elementRect.top);\n\n this.restrictOffset.right = this.startOffset.right - (width * (1 - restrict.elementRect.right));\n this.restrictOffset.bottom = this.startOffset.bottom - (height * (1 - restrict.elementRect.bottom));\n }\n else {\n this.restrictOffset.left = this.restrictOffset.top = this.restrictOffset.right = this.restrictOffset.bottom = 0;\n }\n },\n\n /*\\\n * Interaction.start\n [ method ]\n *\n * Start an action with the given Interactable and Element as tartgets. The\n * action must be enabled for the target Interactable and an appropriate number\n * of pointers must be held down – 1 for drag/resize, 2 for gesture.\n *\n * Use it with `interactable.able({ manualStart: false })` to always\n * [start actions manually](https://github.com/taye/interact.js/issues/114)\n *\n - action (object) The action to be performed - drag, resize, etc.\n - interactable (Interactable) The Interactable to target\n - element (Element) The DOM Element to target\n = (object) interact\n **\n | interact(target)\n | .draggable({\n | // disable the default drag start by down->move\n | manualStart: true\n | })\n | // start dragging after the user holds the pointer down\n | .on('hold', function (event) {\n | var interaction = event.interaction;\n |\n | if (!interaction.interacting()) {\n | interaction.start({ name: 'drag' },\n | event.interactable,\n | event.currentTarget);\n | }\n | });\n \\*/\n start: function (action, interactable, element) {\n if (this.interacting()\n || !this.pointerIsDown\n || this.pointerIds.length < (action.name === 'gesture'? 2 : 1)) {\n return;\n }\n\n // if this interaction had been removed after stopping\n // add it back\n if (indexOf(interactions, this) === -1) {\n interactions.push(this);\n }\n\n // set the startCoords if there was no prepared action\n if (!this.prepared.name) {\n this.setEventXY(this.startCoords, this.pointers);\n }\n\n this.prepared.name = action.name;\n this.prepared.axis = action.axis;\n this.prepared.edges = action.edges;\n this.target = interactable;\n this.element = element;\n\n this.setStartOffsets(action.name, interactable, element);\n this.setModifications(this.startCoords.page);\n\n this.prevEvent = this[this.prepared.name + 'Start'](this.downEvent);\n },\n\n pointerMove: function (pointer, event, eventTarget, curEventTarget, preEnd) {\n if (this.inertiaStatus.active) {\n var pageUp = this.inertiaStatus.upCoords.page;\n var clientUp = this.inertiaStatus.upCoords.client;\n\n var inertiaPosition = {\n pageX : pageUp.x + this.inertiaStatus.sx,\n pageY : pageUp.y + this.inertiaStatus.sy,\n clientX: clientUp.x + this.inertiaStatus.sx,\n clientY: clientUp.y + this.inertiaStatus.sy\n };\n\n this.setEventXY(this.curCoords, [inertiaPosition]);\n }\n else {\n this.recordPointer(pointer);\n this.setEventXY(this.curCoords, this.pointers);\n }\n\n var duplicateMove = (this.curCoords.page.x === this.prevCoords.page.x\n && this.curCoords.page.y === this.prevCoords.page.y\n && this.curCoords.client.x === this.prevCoords.client.x\n && this.curCoords.client.y === this.prevCoords.client.y);\n\n var dx, dy,\n pointerIndex = this.mouse? 0 : indexOf(this.pointerIds, getPointerId(pointer));\n\n // register movement greater than pointerMoveTolerance\n if (this.pointerIsDown && !this.pointerWasMoved) {\n dx = this.curCoords.client.x - this.startCoords.client.x;\n dy = this.curCoords.client.y - this.startCoords.client.y;\n\n this.pointerWasMoved = hypot(dx, dy) > pointerMoveTolerance;\n }\n\n if (!duplicateMove && (!this.pointerIsDown || this.pointerWasMoved)) {\n if (this.pointerIsDown) {\n clearTimeout(this.holdTimers[pointerIndex]);\n }\n\n this.collectEventTargets(pointer, event, eventTarget, 'move');\n }\n\n if (!this.pointerIsDown) { return; }\n\n if (duplicateMove && this.pointerWasMoved && !preEnd) {\n this.checkAndPreventDefault(event, this.target, this.element);\n return;\n }\n\n // set pointer coordinate, time changes and speeds\n setEventDeltas(this.pointerDelta, this.prevCoords, this.curCoords);\n\n if (!this.prepared.name) { return; }\n\n if (this.pointerWasMoved\n // ignore movement while inertia is active\n && (!this.inertiaStatus.active || (pointer instanceof InteractEvent && /inertiastart/.test(pointer.type)))) {\n\n // if just starting an action, calculate the pointer speed now\n if (!this.interacting()) {\n setEventDeltas(this.pointerDelta, this.prevCoords, this.curCoords);\n\n // check if a drag is in the correct axis\n if (this.prepared.name === 'drag') {\n var absX = Math.abs(dx),\n absY = Math.abs(dy),\n targetAxis = this.target.options.drag.axis,\n axis = (absX > absY ? 'x' : absX < absY ? 'y' : 'xy');\n\n // if the movement isn't in the axis of the interactable\n if (axis !== 'xy' && targetAxis !== 'xy' && targetAxis !== axis) {\n // cancel the prepared action\n this.prepared.name = null;\n\n // then try to get a drag from another ineractable\n\n var element = eventTarget;\n\n // check element interactables\n while (isElement(element)) {\n var elementInteractable = interactables.get(element);\n\n if (elementInteractable\n && elementInteractable !== this.target\n && !elementInteractable.options.drag.manualStart\n && elementInteractable.getAction(this.downPointer, this.downEvent, this, element).name === 'drag'\n && checkAxis(axis, elementInteractable)) {\n\n this.prepared.name = 'drag';\n this.target = elementInteractable;\n this.element = element;\n break;\n }\n\n element = parentElement(element);\n }\n\n // if there's no drag from element interactables,\n // check the selector interactables\n if (!this.prepared.name) {\n var thisInteraction = this;\n\n var getDraggable = function (interactable, selector, context) {\n var elements = ie8MatchesSelector\n ? context.querySelectorAll(selector)\n : undefined;\n\n if (interactable === thisInteraction.target) { return; }\n\n if (inContext(interactable, eventTarget)\n && !interactable.options.drag.manualStart\n && !testIgnore(interactable, element, eventTarget)\n && testAllow(interactable, element, eventTarget)\n && matchesSelector(element, selector, elements)\n && interactable.getAction(thisInteraction.downPointer, thisInteraction.downEvent, thisInteraction, element).name === 'drag'\n && checkAxis(axis, interactable)\n && withinInteractionLimit(interactable, element, 'drag')) {\n\n return interactable;\n }\n };\n\n element = eventTarget;\n\n while (isElement(element)) {\n var selectorInteractable = interactables.forEachSelector(getDraggable);\n\n if (selectorInteractable) {\n this.prepared.name = 'drag';\n this.target = selectorInteractable;\n this.element = element;\n break;\n }\n\n element = parentElement(element);\n }\n }\n }\n }\n }\n\n var starting = !!this.prepared.name && !this.interacting();\n\n if (starting\n && (this.target.options[this.prepared.name].manualStart\n || !withinInteractionLimit(this.target, this.element, this.prepared))) {\n this.stop(event);\n return;\n }\n\n if (this.prepared.name && this.target) {\n if (starting) {\n this.start(this.prepared, this.target, this.element);\n }\n\n var shouldMove = this.setModifications(this.curCoords.page, preEnd);\n\n // move if snapping or restriction doesn't prevent it\n if (shouldMove || starting) {\n this.prevEvent = this[this.prepared.name + 'Move'](event);\n }\n\n this.checkAndPreventDefault(event, this.target, this.element);\n }\n }\n\n copyCoords(this.prevCoords, this.curCoords);\n\n if (this.dragging || this.resizing) {\n this.autoScrollMove(pointer);\n }\n },\n\n dragStart: function (event) {\n var dragEvent = new InteractEvent(this, event, 'drag', 'start', this.element);\n\n this.dragging = true;\n this.target.fire(dragEvent);\n\n // reset active dropzones\n this.activeDrops.dropzones = [];\n this.activeDrops.elements = [];\n this.activeDrops.rects = [];\n\n if (!this.dynamicDrop) {\n this.setActiveDrops(this.element);\n }\n\n var dropEvents = this.getDropEvents(event, dragEvent);\n\n if (dropEvents.activate) {\n this.fireActiveDrops(dropEvents.activate);\n }\n\n return dragEvent;\n },\n\n dragMove: function (event) {\n var target = this.target,\n dragEvent = new InteractEvent(this, event, 'drag', 'move', this.element),\n draggableElement = this.element,\n drop = this.getDrop(dragEvent, event, draggableElement);\n\n this.dropTarget = drop.dropzone;\n this.dropElement = drop.element;\n\n var dropEvents = this.getDropEvents(event, dragEvent);\n\n target.fire(dragEvent);\n\n if (dropEvents.leave) { this.prevDropTarget.fire(dropEvents.leave); }\n if (dropEvents.enter) { this.dropTarget.fire(dropEvents.enter); }\n if (dropEvents.move ) { this.dropTarget.fire(dropEvents.move ); }\n\n this.prevDropTarget = this.dropTarget;\n this.prevDropElement = this.dropElement;\n\n return dragEvent;\n },\n\n resizeStart: function (event) {\n var resizeEvent = new InteractEvent(this, event, 'resize', 'start', this.element);\n\n if (this.prepared.edges) {\n var startRect = this.target.getRect(this.element);\n\n /*\n * When using the `resizable.square` or `resizable.preserveAspectRatio` options, resizing from one edge\n * will affect another. E.g. with `resizable.square`, resizing to make the right edge larger will make\n * the bottom edge larger by the same amount. We call these 'linked' edges. Any linked edges will depend\n * on the active edges and the edge being interacted with.\n */\n if (this.target.options.resize.square || this.target.options.resize.preserveAspectRatio) {\n var linkedEdges = extend({}, this.prepared.edges);\n\n linkedEdges.top = linkedEdges.top || (linkedEdges.left && !linkedEdges.bottom);\n linkedEdges.left = linkedEdges.left || (linkedEdges.top && !linkedEdges.right );\n linkedEdges.bottom = linkedEdges.bottom || (linkedEdges.right && !linkedEdges.top );\n linkedEdges.right = linkedEdges.right || (linkedEdges.bottom && !linkedEdges.left );\n\n this.prepared._linkedEdges = linkedEdges;\n }\n else {\n this.prepared._linkedEdges = null;\n }\n\n // if using `resizable.preserveAspectRatio` option, record aspect ratio at the start of the resize\n if (this.target.options.resize.preserveAspectRatio) {\n this.resizeStartAspectRatio = startRect.width / startRect.height;\n }\n\n this.resizeRects = {\n start : startRect,\n current : extend({}, startRect),\n restricted: extend({}, startRect),\n previous : extend({}, startRect),\n delta : {\n left: 0, right : 0, width : 0,\n top : 0, bottom: 0, height: 0\n }\n };\n\n resizeEvent.rect = this.resizeRects.restricted;\n resizeEvent.deltaRect = this.resizeRects.delta;\n }\n\n this.target.fire(resizeEvent);\n\n this.resizing = true;\n\n return resizeEvent;\n },\n\n resizeMove: function (event) {\n var resizeEvent = new InteractEvent(this, event, 'resize', 'move', this.element);\n\n var edges = this.prepared.edges,\n invert = this.target.options.resize.invert,\n invertible = invert === 'reposition' || invert === 'negate';\n\n if (edges) {\n var dx = resizeEvent.dx,\n dy = resizeEvent.dy,\n\n start = this.resizeRects.start,\n current = this.resizeRects.current,\n restricted = this.resizeRects.restricted,\n delta = this.resizeRects.delta,\n previous = extend(this.resizeRects.previous, restricted),\n\n originalEdges = edges;\n\n // `resize.preserveAspectRatio` takes precedence over `resize.square`\n if (this.target.options.resize.preserveAspectRatio) {\n var resizeStartAspectRatio = this.resizeStartAspectRatio;\n\n edges = this.prepared._linkedEdges;\n\n if ((originalEdges.left && originalEdges.bottom)\n || (originalEdges.right && originalEdges.top)) {\n dy = -dx / resizeStartAspectRatio;\n }\n else if (originalEdges.left || originalEdges.right) { dy = dx / resizeStartAspectRatio; }\n else if (originalEdges.top || originalEdges.bottom) { dx = dy * resizeStartAspectRatio; }\n }\n else if (this.target.options.resize.square) {\n edges = this.prepared._linkedEdges;\n\n if ((originalEdges.left && originalEdges.bottom)\n || (originalEdges.right && originalEdges.top)) {\n dy = -dx;\n }\n else if (originalEdges.left || originalEdges.right) { dy = dx; }\n else if (originalEdges.top || originalEdges.bottom) { dx = dy; }\n }\n\n // update the 'current' rect without modifications\n if (edges.top ) { current.top += dy; }\n if (edges.bottom) { current.bottom += dy; }\n if (edges.left ) { current.left += dx; }\n if (edges.right ) { current.right += dx; }\n\n if (invertible) {\n // if invertible, copy the current rect\n extend(restricted, current);\n\n if (invert === 'reposition') {\n // swap edge values if necessary to keep width/height positive\n var swap;\n\n if (restricted.top > restricted.bottom) {\n swap = restricted.top;\n\n restricted.top = restricted.bottom;\n restricted.bottom = swap;\n }\n if (restricted.left > restricted.right) {\n swap = restricted.left;\n\n restricted.left = restricted.right;\n restricted.right = swap;\n }\n }\n }\n else {\n // if not invertible, restrict to minimum of 0x0 rect\n restricted.top = Math.min(current.top, start.bottom);\n restricted.bottom = Math.max(current.bottom, start.top);\n restricted.left = Math.min(current.left, start.right);\n restricted.right = Math.max(current.right, start.left);\n }\n\n restricted.width = restricted.right - restricted.left;\n restricted.height = restricted.bottom - restricted.top ;\n\n for (var edge in restricted) {\n delta[edge] = restricted[edge] - previous[edge];\n }\n\n resizeEvent.edges = this.prepared.edges;\n resizeEvent.rect = restricted;\n resizeEvent.deltaRect = delta;\n }\n\n this.target.fire(resizeEvent);\n\n return resizeEvent;\n },\n\n gestureStart: function (event) {\n var gestureEvent = new InteractEvent(this, event, 'gesture', 'start', this.element);\n\n gestureEvent.ds = 0;\n\n this.gesture.startDistance = this.gesture.prevDistance = gestureEvent.distance;\n this.gesture.startAngle = this.gesture.prevAngle = gestureEvent.angle;\n this.gesture.scale = 1;\n\n this.gesturing = true;\n\n this.target.fire(gestureEvent);\n\n return gestureEvent;\n },\n\n gestureMove: function (event) {\n if (!this.pointerIds.length) {\n return this.prevEvent;\n }\n\n var gestureEvent;\n\n gestureEvent = new InteractEvent(this, event, 'gesture', 'move', this.element);\n gestureEvent.ds = gestureEvent.scale - this.gesture.scale;\n\n this.target.fire(gestureEvent);\n\n this.gesture.prevAngle = gestureEvent.angle;\n this.gesture.prevDistance = gestureEvent.distance;\n\n if (gestureEvent.scale !== Infinity &&\n gestureEvent.scale !== null &&\n gestureEvent.scale !== undefined &&\n !isNaN(gestureEvent.scale)) {\n\n this.gesture.scale = gestureEvent.scale;\n }\n\n return gestureEvent;\n },\n\n pointerHold: function (pointer, event, eventTarget) {\n this.collectEventTargets(pointer, event, eventTarget, 'hold');\n },\n\n pointerUp: function (pointer, event, eventTarget, curEventTarget) {\n var pointerIndex = this.mouse? 0 : indexOf(this.pointerIds, getPointerId(pointer));\n\n clearTimeout(this.holdTimers[pointerIndex]);\n\n this.collectEventTargets(pointer, event, eventTarget, 'up' );\n this.collectEventTargets(pointer, event, eventTarget, 'tap');\n\n this.pointerEnd(pointer, event, eventTarget, curEventTarget);\n\n this.removePointer(pointer);\n },\n\n pointerCancel: function (pointer, event, eventTarget, curEventTarget) {\n var pointerIndex = this.mouse? 0 : indexOf(this.pointerIds, getPointerId(pointer));\n\n clearTimeout(this.holdTimers[pointerIndex]);\n\n this.collectEventTargets(pointer, event, eventTarget, 'cancel');\n this.pointerEnd(pointer, event, eventTarget, curEventTarget);\n\n this.removePointer(pointer);\n },\n\n // http://www.quirksmode.org/dom/events/click.html\n // >Events leading to dblclick\n //\n // IE8 doesn't fire down event before dblclick.\n // This workaround tries to fire a tap and doubletap after dblclick\n ie8Dblclick: function (pointer, event, eventTarget) {\n if (this.prevTap\n && event.clientX === this.prevTap.clientX\n && event.clientY === this.prevTap.clientY\n && eventTarget === this.prevTap.target) {\n\n this.downTargets[0] = eventTarget;\n this.downTimes[0] = new Date().getTime();\n this.collectEventTargets(pointer, event, eventTarget, 'tap');\n }\n },\n\n // End interact move events and stop auto-scroll unless inertia is enabled\n pointerEnd: function (pointer, event, eventTarget, curEventTarget) {\n var endEvent,\n target = this.target,\n options = target && target.options,\n inertiaOptions = options && this.prepared.name && options[this.prepared.name].inertia,\n inertiaStatus = this.inertiaStatus;\n\n if (this.interacting()) {\n\n if (inertiaStatus.active && !inertiaStatus.ending) { return; }\n\n var pointerSpeed,\n now = new Date().getTime(),\n inertiaPossible = false,\n inertia = false,\n smoothEnd = false,\n endSnap = checkSnap(target, this.prepared.name) && options[this.prepared.name].snap.endOnly,\n endRestrict = checkRestrict(target, this.prepared.name) && options[this.prepared.name].restrict.endOnly,\n dx = 0,\n dy = 0,\n startEvent;\n\n if (this.dragging) {\n if (options.drag.axis === 'x' ) { pointerSpeed = Math.abs(this.pointerDelta.client.vx); }\n else if (options.drag.axis === 'y' ) { pointerSpeed = Math.abs(this.pointerDelta.client.vy); }\n else /*options.drag.axis === 'xy'*/{ pointerSpeed = this.pointerDelta.client.speed; }\n }\n else {\n pointerSpeed = this.pointerDelta.client.speed;\n }\n\n // check if inertia should be started\n inertiaPossible = (inertiaOptions && inertiaOptions.enabled\n && this.prepared.name !== 'gesture'\n && event !== inertiaStatus.startEvent);\n\n inertia = (inertiaPossible\n && (now - this.curCoords.timeStamp) < 50\n && pointerSpeed > inertiaOptions.minSpeed\n && pointerSpeed > inertiaOptions.endSpeed);\n\n if (inertiaPossible && !inertia && (endSnap || endRestrict)) {\n\n var snapRestrict = {};\n\n snapRestrict.snap = snapRestrict.restrict = snapRestrict;\n\n if (endSnap) {\n this.setSnapping(this.curCoords.page, snapRestrict);\n if (snapRestrict.locked) {\n dx += snapRestrict.dx;\n dy += snapRestrict.dy;\n }\n }\n\n if (endRestrict) {\n this.setRestriction(this.curCoords.page, snapRestrict);\n if (snapRestrict.restricted) {\n dx += snapRestrict.dx;\n dy += snapRestrict.dy;\n }\n }\n\n if (dx || dy) {\n smoothEnd = true;\n }\n }\n\n if (inertia || smoothEnd) {\n copyCoords(inertiaStatus.upCoords, this.curCoords);\n\n this.pointers[0] = inertiaStatus.startEvent = startEvent =\n new InteractEvent(this, event, this.prepared.name, 'inertiastart', this.element);\n\n inertiaStatus.t0 = now;\n\n target.fire(inertiaStatus.startEvent);\n\n if (inertia) {\n inertiaStatus.vx0 = this.pointerDelta.client.vx;\n inertiaStatus.vy0 = this.pointerDelta.client.vy;\n inertiaStatus.v0 = pointerSpeed;\n\n this.calcInertia(inertiaStatus);\n\n var page = extend({}, this.curCoords.page),\n origin = getOriginXY(target, this.element),\n statusObject;\n\n page.x = page.x + inertiaStatus.xe - origin.x;\n page.y = page.y + inertiaStatus.ye - origin.y;\n\n statusObject = {\n useStatusXY: true,\n x: page.x,\n y: page.y,\n dx: 0,\n dy: 0,\n snap: null\n };\n\n statusObject.snap = statusObject;\n\n dx = dy = 0;\n\n if (endSnap) {\n var snap = this.setSnapping(this.curCoords.page, statusObject);\n\n if (snap.locked) {\n dx += snap.dx;\n dy += snap.dy;\n }\n }\n\n if (endRestrict) {\n var restrict = this.setRestriction(this.curCoords.page, statusObject);\n\n if (restrict.restricted) {\n dx += restrict.dx;\n dy += restrict.dy;\n }\n }\n\n inertiaStatus.modifiedXe += dx;\n inertiaStatus.modifiedYe += dy;\n\n inertiaStatus.i = reqFrame(this.boundInertiaFrame);\n }\n else {\n inertiaStatus.smoothEnd = true;\n inertiaStatus.xe = dx;\n inertiaStatus.ye = dy;\n\n inertiaStatus.sx = inertiaStatus.sy = 0;\n\n inertiaStatus.i = reqFrame(this.boundSmoothEndFrame);\n }\n\n inertiaStatus.active = true;\n return;\n }\n\n if (endSnap || endRestrict) {\n // fire a move event at the snapped coordinates\n this.pointerMove(pointer, event, eventTarget, curEventTarget, true);\n }\n }\n\n if (this.dragging) {\n endEvent = new InteractEvent(this, event, 'drag', 'end', this.element);\n\n var draggableElement = this.element,\n drop = this.getDrop(endEvent, event, draggableElement);\n\n this.dropTarget = drop.dropzone;\n this.dropElement = drop.element;\n\n var dropEvents = this.getDropEvents(event, endEvent);\n\n if (dropEvents.leave) { this.prevDropTarget.fire(dropEvents.leave); }\n if (dropEvents.enter) { this.dropTarget.fire(dropEvents.enter); }\n if (dropEvents.drop ) { this.dropTarget.fire(dropEvents.drop ); }\n if (dropEvents.deactivate) {\n this.fireActiveDrops(dropEvents.deactivate);\n }\n\n target.fire(endEvent);\n }\n else if (this.resizing) {\n endEvent = new InteractEvent(this, event, 'resize', 'end', this.element);\n target.fire(endEvent);\n }\n else if (this.gesturing) {\n endEvent = new InteractEvent(this, event, 'gesture', 'end', this.element);\n target.fire(endEvent);\n }\n\n this.stop(event);\n },\n\n collectDrops: function (element) {\n var drops = [],\n elements = [],\n i;\n\n element = element || this.element;\n\n // collect all dropzones and their elements which qualify for a drop\n for (i = 0; i < interactables.length; i++) {\n if (!interactables[i].options.drop.enabled) { continue; }\n\n var current = interactables[i],\n accept = current.options.drop.accept;\n\n // test the draggable element against the dropzone's accept setting\n if ((isElement(accept) && accept !== element)\n || (isString(accept)\n && !matchesSelector(element, accept))) {\n\n continue;\n }\n\n // query for new elements if necessary\n var dropElements = current.selector? current._context.querySelectorAll(current.selector) : [current._element];\n\n for (var j = 0, len = dropElements.length; j < len; j++) {\n var currentElement = dropElements[j];\n\n if (currentElement === element) {\n continue;\n }\n\n drops.push(current);\n elements.push(currentElement);\n }\n }\n\n return {\n dropzones: drops,\n elements: elements\n };\n },\n\n fireActiveDrops: function (event) {\n var i,\n current,\n currentElement,\n prevElement;\n\n // loop through all active dropzones and trigger event\n for (i = 0; i < this.activeDrops.dropzones.length; i++) {\n current = this.activeDrops.dropzones[i];\n currentElement = this.activeDrops.elements [i];\n\n // prevent trigger of duplicate events on same element\n if (currentElement !== prevElement) {\n // set current element as event target\n event.target = currentElement;\n current.fire(event);\n }\n prevElement = currentElement;\n }\n },\n\n // Collect a new set of possible drops and save them in activeDrops.\n // setActiveDrops should always be called when a drag has just started or a\n // drag event happens while dynamicDrop is true\n setActiveDrops: function (dragElement) {\n // get dropzones and their elements that could receive the draggable\n var possibleDrops = this.collectDrops(dragElement, true);\n\n this.activeDrops.dropzones = possibleDrops.dropzones;\n this.activeDrops.elements = possibleDrops.elements;\n this.activeDrops.rects = [];\n\n for (var i = 0; i < this.activeDrops.dropzones.length; i++) {\n this.activeDrops.rects[i] = this.activeDrops.dropzones[i].getRect(this.activeDrops.elements[i]);\n }\n },\n\n getDrop: function (dragEvent, event, dragElement) {\n var validDrops = [];\n\n if (dynamicDrop) {\n this.setActiveDrops(dragElement);\n }\n\n // collect all dropzones and their elements which qualify for a drop\n for (var j = 0; j < this.activeDrops.dropzones.length; j++) {\n var current = this.activeDrops.dropzones[j],\n currentElement = this.activeDrops.elements [j],\n rect = this.activeDrops.rects [j];\n\n validDrops.push(current.dropCheck(dragEvent, event, this.target, dragElement, currentElement, rect)\n ? currentElement\n : null);\n }\n\n // get the most appropriate dropzone based on DOM depth and order\n var dropIndex = indexOfDeepestElement(validDrops),\n dropzone = this.activeDrops.dropzones[dropIndex] || null,\n element = this.activeDrops.elements [dropIndex] || null;\n\n return {\n dropzone: dropzone,\n element: element\n };\n },\n\n getDropEvents: function (pointerEvent, dragEvent) {\n var dropEvents = {\n enter : null,\n leave : null,\n activate : null,\n deactivate: null,\n move : null,\n drop : null\n };\n\n if (this.dropElement !== this.prevDropElement) {\n // if there was a prevDropTarget, create a dragleave event\n if (this.prevDropTarget) {\n dropEvents.leave = {\n target : this.prevDropElement,\n dropzone : this.prevDropTarget,\n relatedTarget: dragEvent.target,\n draggable : dragEvent.interactable,\n dragEvent : dragEvent,\n interaction : this,\n timeStamp : dragEvent.timeStamp,\n type : 'dragleave'\n };\n\n dragEvent.dragLeave = this.prevDropElement;\n dragEvent.prevDropzone = this.prevDropTarget;\n }\n // if the dropTarget is not null, create a dragenter event\n if (this.dropTarget) {\n dropEvents.enter = {\n target : this.dropElement,\n dropzone : this.dropTarget,\n relatedTarget: dragEvent.target,\n draggable : dragEvent.interactable,\n dragEvent : dragEvent,\n interaction : this,\n timeStamp : dragEvent.timeStamp,\n type : 'dragenter'\n };\n\n dragEvent.dragEnter = this.dropElement;\n dragEvent.dropzone = this.dropTarget;\n }\n }\n\n if (dragEvent.type === 'dragend' && this.dropTarget) {\n dropEvents.drop = {\n target : this.dropElement,\n dropzone : this.dropTarget,\n relatedTarget: dragEvent.target,\n draggable : dragEvent.interactable,\n dragEvent : dragEvent,\n interaction : this,\n timeStamp : dragEvent.timeStamp,\n type : 'drop'\n };\n\n dragEvent.dropzone = this.dropTarget;\n }\n if (dragEvent.type === 'dragstart') {\n dropEvents.activate = {\n target : null,\n dropzone : null,\n relatedTarget: dragEvent.target,\n draggable : dragEvent.interactable,\n dragEvent : dragEvent,\n interaction : this,\n timeStamp : dragEvent.timeStamp,\n type : 'dropactivate'\n };\n }\n if (dragEvent.type === 'dragend') {\n dropEvents.deactivate = {\n target : null,\n dropzone : null,\n relatedTarget: dragEvent.target,\n draggable : dragEvent.interactable,\n dragEvent : dragEvent,\n interaction : this,\n timeStamp : dragEvent.timeStamp,\n type : 'dropdeactivate'\n };\n }\n if (dragEvent.type === 'dragmove' && this.dropTarget) {\n dropEvents.move = {\n target : this.dropElement,\n dropzone : this.dropTarget,\n relatedTarget: dragEvent.target,\n draggable : dragEvent.interactable,\n dragEvent : dragEvent,\n interaction : this,\n dragmove : dragEvent,\n timeStamp : dragEvent.timeStamp,\n type : 'dropmove'\n };\n dragEvent.dropzone = this.dropTarget;\n }\n\n return dropEvents;\n },\n\n currentAction: function () {\n return (this.dragging && 'drag') || (this.resizing && 'resize') || (this.gesturing && 'gesture') || null;\n },\n\n interacting: function () {\n return this.dragging || this.resizing || this.gesturing;\n },\n\n clearTargets: function () {\n this.target = this.element = null;\n\n this.dropTarget = this.dropElement = this.prevDropTarget = this.prevDropElement = null;\n },\n\n stop: function (event) {\n if (this.interacting()) {\n autoScroll.stop();\n this.matches = [];\n this.matchElements = [];\n\n var target = this.target;\n\n if (target.options.styleCursor) {\n target._doc.documentElement.style.cursor = '';\n }\n\n // prevent Default only if were previously interacting\n if (event && isFunction(event.preventDefault)) {\n this.checkAndPreventDefault(event, target, this.element);\n }\n\n if (this.dragging) {\n this.activeDrops.dropzones = this.activeDrops.elements = this.activeDrops.rects = null;\n }\n }\n\n this.clearTargets();\n\n this.pointerIsDown = this.snapStatus.locked = this.dragging = this.resizing = this.gesturing = false;\n this.prepared.name = this.prevEvent = null;\n this.inertiaStatus.resumeDx = this.inertiaStatus.resumeDy = 0;\n\n // remove pointers if their ID isn't in this.pointerIds\n for (var i = 0; i < this.pointers.length; i++) {\n if (indexOf(this.pointerIds, getPointerId(this.pointers[i])) === -1) {\n this.pointers.splice(i, 1);\n }\n }\n },\n\n inertiaFrame: function () {\n var inertiaStatus = this.inertiaStatus,\n options = this.target.options[this.prepared.name].inertia,\n lambda = options.resistance,\n t = new Date().getTime() / 1000 - inertiaStatus.t0;\n\n if (t < inertiaStatus.te) {\n\n var progress = 1 - (Math.exp(-lambda * t) - inertiaStatus.lambda_v0) / inertiaStatus.one_ve_v0;\n\n if (inertiaStatus.modifiedXe === inertiaStatus.xe && inertiaStatus.modifiedYe === inertiaStatus.ye) {\n inertiaStatus.sx = inertiaStatus.xe * progress;\n inertiaStatus.sy = inertiaStatus.ye * progress;\n }\n else {\n var quadPoint = getQuadraticCurvePoint(\n 0, 0,\n inertiaStatus.xe, inertiaStatus.ye,\n inertiaStatus.modifiedXe, inertiaStatus.modifiedYe,\n progress);\n\n inertiaStatus.sx = quadPoint.x;\n inertiaStatus.sy = quadPoint.y;\n }\n\n this.pointerMove(inertiaStatus.startEvent, inertiaStatus.startEvent);\n\n inertiaStatus.i = reqFrame(this.boundInertiaFrame);\n }\n else {\n inertiaStatus.ending = true;\n\n inertiaStatus.sx = inertiaStatus.modifiedXe;\n inertiaStatus.sy = inertiaStatus.modifiedYe;\n\n this.pointerMove(inertiaStatus.startEvent, inertiaStatus.startEvent);\n this.pointerEnd(inertiaStatus.startEvent, inertiaStatus.startEvent);\n\n inertiaStatus.active = inertiaStatus.ending = false;\n }\n },\n\n smoothEndFrame: function () {\n var inertiaStatus = this.inertiaStatus,\n t = new Date().getTime() - inertiaStatus.t0,\n duration = this.target.options[this.prepared.name].inertia.smoothEndDuration;\n\n if (t < duration) {\n inertiaStatus.sx = easeOutQuad(t, 0, inertiaStatus.xe, duration);\n inertiaStatus.sy = easeOutQuad(t, 0, inertiaStatus.ye, duration);\n\n this.pointerMove(inertiaStatus.startEvent, inertiaStatus.startEvent);\n\n inertiaStatus.i = reqFrame(this.boundSmoothEndFrame);\n }\n else {\n inertiaStatus.ending = true;\n\n inertiaStatus.sx = inertiaStatus.xe;\n inertiaStatus.sy = inertiaStatus.ye;\n\n this.pointerMove(inertiaStatus.startEvent, inertiaStatus.startEvent);\n this.pointerEnd(inertiaStatus.startEvent, inertiaStatus.startEvent);\n\n inertiaStatus.smoothEnd =\n inertiaStatus.active = inertiaStatus.ending = false;\n }\n },\n\n addPointer: function (pointer) {\n var id = getPointerId(pointer),\n index = this.mouse? 0 : indexOf(this.pointerIds, id);\n\n if (index === -1) {\n index = this.pointerIds.length;\n }\n\n this.pointerIds[index] = id;\n this.pointers[index] = pointer;\n\n return index;\n },\n\n removePointer: function (pointer) {\n var id = getPointerId(pointer),\n index = this.mouse? 0 : indexOf(this.pointerIds, id);\n\n if (index === -1) { return; }\n\n this.pointers .splice(index, 1);\n this.pointerIds .splice(index, 1);\n this.downTargets.splice(index, 1);\n this.downTimes .splice(index, 1);\n this.holdTimers .splice(index, 1);\n },\n\n recordPointer: function (pointer) {\n var index = this.mouse? 0: indexOf(this.pointerIds, getPointerId(pointer));\n\n if (index === -1) { return; }\n\n this.pointers[index] = pointer;\n },\n\n collectEventTargets: function (pointer, event, eventTarget, eventType) {\n var pointerIndex = this.mouse? 0 : indexOf(this.pointerIds, getPointerId(pointer));\n\n // do not fire a tap event if the pointer was moved before being lifted\n if (eventType === 'tap' && (this.pointerWasMoved\n // or if the pointerup target is different to the pointerdown target\n || !(this.downTargets[pointerIndex] && this.downTargets[pointerIndex] === eventTarget))) {\n return;\n }\n\n var targets = [],\n elements = [],\n element = eventTarget;\n\n function collectSelectors (interactable, selector, context) {\n var els = ie8MatchesSelector\n ? context.querySelectorAll(selector)\n : undefined;\n\n if (interactable._iEvents[eventType]\n && isElement(element)\n && inContext(interactable, element)\n && !testIgnore(interactable, element, eventTarget)\n && testAllow(interactable, element, eventTarget)\n && matchesSelector(element, selector, els)) {\n\n targets.push(interactable);\n elements.push(element);\n }\n }\n\n while (element) {\n if (interact.isSet(element) && interact(element)._iEvents[eventType]) {\n targets.push(interact(element));\n elements.push(element);\n }\n\n interactables.forEachSelector(collectSelectors);\n\n element = parentElement(element);\n }\n\n // create the tap event even if there are no listeners so that\n // doubletap can still be created and fired\n if (targets.length || eventType === 'tap') {\n this.firePointers(pointer, event, eventTarget, targets, elements, eventType);\n }\n },\n\n firePointers: function (pointer, event, eventTarget, targets, elements, eventType) {\n var pointerIndex = this.mouse? 0 : indexOf(this.pointerIds, getPointerId(pointer)),\n pointerEvent = {},\n i,\n // for tap events\n interval, createNewDoubleTap;\n\n // if it's a doubletap then the event properties would have been\n // copied from the tap event and provided as the pointer argument\n if (eventType === 'doubletap') {\n pointerEvent = pointer;\n }\n else {\n pointerExtend(pointerEvent, event);\n if (event !== pointer) {\n pointerExtend(pointerEvent, pointer);\n }\n\n pointerEvent.preventDefault = preventOriginalDefault;\n pointerEvent.stopPropagation = InteractEvent.prototype.stopPropagation;\n pointerEvent.stopImmediatePropagation = InteractEvent.prototype.stopImmediatePropagation;\n pointerEvent.interaction = this;\n\n pointerEvent.timeStamp = new Date().getTime();\n pointerEvent.originalEvent = event;\n pointerEvent.originalPointer = pointer;\n pointerEvent.type = eventType;\n pointerEvent.pointerId = getPointerId(pointer);\n pointerEvent.pointerType = this.mouse? 'mouse' : !supportsPointerEvent? 'touch'\n : isString(pointer.pointerType)\n ? pointer.pointerType\n : [,,'touch', 'pen', 'mouse'][pointer.pointerType];\n }\n\n if (eventType === 'tap') {\n pointerEvent.dt = pointerEvent.timeStamp - this.downTimes[pointerIndex];\n\n interval = pointerEvent.timeStamp - this.tapTime;\n createNewDoubleTap = !!(this.prevTap && this.prevTap.type !== 'doubletap'\n && this.prevTap.target === pointerEvent.target\n && interval < 500);\n\n pointerEvent.double = createNewDoubleTap;\n\n this.tapTime = pointerEvent.timeStamp;\n }\n\n for (i = 0; i < targets.length; i++) {\n pointerEvent.currentTarget = elements[i];\n pointerEvent.interactable = targets[i];\n targets[i].fire(pointerEvent);\n\n if (pointerEvent.immediatePropagationStopped\n ||(pointerEvent.propagationStopped && elements[i + 1] !== pointerEvent.currentTarget)) {\n break;\n }\n }\n\n if (createNewDoubleTap) {\n var doubleTap = {};\n\n extend(doubleTap, pointerEvent);\n\n doubleTap.dt = interval;\n doubleTap.type = 'doubletap';\n\n this.collectEventTargets(doubleTap, event, eventTarget, 'doubletap');\n\n this.prevTap = doubleTap;\n }\n else if (eventType === 'tap') {\n this.prevTap = pointerEvent;\n }\n },\n\n validateSelector: function (pointer, event, matches, matchElements) {\n for (var i = 0, len = matches.length; i < len; i++) {\n var match = matches[i],\n matchElement = matchElements[i],\n action = validateAction(match.getAction(pointer, event, this, matchElement), match);\n\n if (action && withinInteractionLimit(match, matchElement, action)) {\n this.target = match;\n this.element = matchElement;\n\n return action;\n }\n }\n },\n\n setSnapping: function (pageCoords, status) {\n var snap = this.target.options[this.prepared.name].snap,\n targets = [],\n target,\n page,\n i;\n\n status = status || this.snapStatus;\n\n if (status.useStatusXY) {\n page = { x: status.x, y: status.y };\n }\n else {\n var origin = getOriginXY(this.target, this.element);\n\n page = extend({}, pageCoords);\n\n page.x -= origin.x;\n page.y -= origin.y;\n }\n\n status.realX = page.x;\n status.realY = page.y;\n\n page.x = page.x - this.inertiaStatus.resumeDx;\n page.y = page.y - this.inertiaStatus.resumeDy;\n\n var len = snap.targets? snap.targets.length : 0;\n\n for (var relIndex = 0; relIndex < this.snapOffsets.length; relIndex++) {\n var relative = {\n x: page.x - this.snapOffsets[relIndex].x,\n y: page.y - this.snapOffsets[relIndex].y\n };\n\n for (i = 0; i < len; i++) {\n if (isFunction(snap.targets[i])) {\n target = snap.targets[i](relative.x, relative.y, this);\n }\n else {\n target = snap.targets[i];\n }\n\n if (!target) { continue; }\n\n targets.push({\n x: isNumber(target.x) ? (target.x + this.snapOffsets[relIndex].x) : relative.x,\n y: isNumber(target.y) ? (target.y + this.snapOffsets[relIndex].y) : relative.y,\n\n range: isNumber(target.range)? target.range: snap.range\n });\n }\n }\n\n var closest = {\n target: null,\n inRange: false,\n distance: 0,\n range: 0,\n dx: 0,\n dy: 0\n };\n\n for (i = 0, len = targets.length; i < len; i++) {\n target = targets[i];\n\n var range = target.range,\n dx = target.x - page.x,\n dy = target.y - page.y,\n distance = hypot(dx, dy),\n inRange = distance <= range;\n\n // Infinite targets count as being out of range\n // compared to non infinite ones that are in range\n if (range === Infinity && closest.inRange && closest.range !== Infinity) {\n inRange = false;\n }\n\n if (!closest.target || (inRange\n // is the closest target in range?\n ? (closest.inRange && range !== Infinity\n // the pointer is relatively deeper in this target\n ? distance / range < closest.distance / closest.range\n // this target has Infinite range and the closest doesn't\n : (range === Infinity && closest.range !== Infinity)\n // OR this target is closer that the previous closest\n || distance < closest.distance)\n // The other is not in range and the pointer is closer to this target\n : (!closest.inRange && distance < closest.distance))) {\n\n if (range === Infinity) {\n inRange = true;\n }\n\n closest.target = target;\n closest.distance = distance;\n closest.range = range;\n closest.inRange = inRange;\n closest.dx = dx;\n closest.dy = dy;\n\n status.range = range;\n }\n }\n\n var snapChanged;\n\n if (closest.target) {\n snapChanged = (status.snappedX !== closest.target.x || status.snappedY !== closest.target.y);\n\n status.snappedX = closest.target.x;\n status.snappedY = closest.target.y;\n }\n else {\n snapChanged = true;\n\n status.snappedX = NaN;\n status.snappedY = NaN;\n }\n\n status.dx = closest.dx;\n status.dy = closest.dy;\n\n status.changed = (snapChanged || (closest.inRange && !status.locked));\n status.locked = closest.inRange;\n\n return status;\n },\n\n setRestriction: function (pageCoords, status) {\n var target = this.target,\n restrict = target && target.options[this.prepared.name].restrict,\n restriction = restrict && restrict.restriction,\n page;\n\n if (!restriction) {\n return status;\n }\n\n status = status || this.restrictStatus;\n\n page = status.useStatusXY\n ? page = { x: status.x, y: status.y }\n : page = extend({}, pageCoords);\n\n if (status.snap && status.snap.locked) {\n page.x += status.snap.dx || 0;\n page.y += status.snap.dy || 0;\n }\n\n page.x -= this.inertiaStatus.resumeDx;\n page.y -= this.inertiaStatus.resumeDy;\n\n status.dx = 0;\n status.dy = 0;\n status.restricted = false;\n\n var rect, restrictedX, restrictedY;\n\n if (isString(restriction)) {\n if (restriction === 'parent') {\n restriction = parentElement(this.element);\n }\n else if (restriction === 'self') {\n restriction = target.getRect(this.element);\n }\n else {\n restriction = closest(this.element, restriction);\n }\n\n if (!restriction) { return status; }\n }\n\n if (isFunction(restriction)) {\n restriction = restriction(page.x, page.y, this.element);\n }\n\n if (isElement(restriction)) {\n restriction = getElementRect(restriction);\n }\n\n rect = restriction;\n\n if (!restriction) {\n restrictedX = page.x;\n restrictedY = page.y;\n }\n // object is assumed to have\n // x, y, width, height or\n // left, top, right, bottom\n else if ('x' in restriction && 'y' in restriction) {\n restrictedX = Math.max(Math.min(rect.x + rect.width - this.restrictOffset.right , page.x), rect.x + this.restrictOffset.left);\n restrictedY = Math.max(Math.min(rect.y + rect.height - this.restrictOffset.bottom, page.y), rect.y + this.restrictOffset.top );\n }\n else {\n restrictedX = Math.max(Math.min(rect.right - this.restrictOffset.right , page.x), rect.left + this.restrictOffset.left);\n restrictedY = Math.max(Math.min(rect.bottom - this.restrictOffset.bottom, page.y), rect.top + this.restrictOffset.top );\n }\n\n status.dx = restrictedX - page.x;\n status.dy = restrictedY - page.y;\n\n status.changed = status.restrictedX !== restrictedX || status.restrictedY !== restrictedY;\n status.restricted = !!(status.dx || status.dy);\n\n status.restrictedX = restrictedX;\n status.restrictedY = restrictedY;\n\n return status;\n },\n\n checkAndPreventDefault: function (event, interactable, element) {\n if (!(interactable = interactable || this.target)) { return; }\n\n var options = interactable.options,\n prevent = options.preventDefault;\n\n if (prevent === 'auto' && element && !/^(input|select|textarea)$/i.test(event.target.nodeName)) {\n // do not preventDefault on pointerdown if the prepared action is a drag\n // and dragging can only start from a certain direction - this allows\n // a touch to pan the viewport if a drag isn't in the right direction\n if (/down|start/i.test(event.type)\n && this.prepared.name === 'drag' && options.drag.axis !== 'xy') {\n\n return;\n }\n\n // with manualStart, only preventDefault while interacting\n if (options[this.prepared.name] && options[this.prepared.name].manualStart\n && !this.interacting()) {\n return;\n }\n\n event.preventDefault();\n return;\n }\n\n if (prevent === 'always') {\n event.preventDefault();\n return;\n }\n },\n\n calcInertia: function (status) {\n var inertiaOptions = this.target.options[this.prepared.name].inertia,\n lambda = inertiaOptions.resistance,\n inertiaDur = -Math.log(inertiaOptions.endSpeed / status.v0) / lambda;\n\n status.x0 = this.prevEvent.pageX;\n status.y0 = this.prevEvent.pageY;\n status.t0 = status.startEvent.timeStamp / 1000;\n status.sx = status.sy = 0;\n\n status.modifiedXe = status.xe = (status.vx0 - inertiaDur) / lambda;\n status.modifiedYe = status.ye = (status.vy0 - inertiaDur) / lambda;\n status.te = inertiaDur;\n\n status.lambda_v0 = lambda / status.v0;\n status.one_ve_v0 = 1 - inertiaOptions.endSpeed / status.v0;\n },\n\n autoScrollMove: function (pointer) {\n if (!(this.interacting()\n && checkAutoScroll(this.target, this.prepared.name))) {\n return;\n }\n\n if (this.inertiaStatus.active) {\n autoScroll.x = autoScroll.y = 0;\n return;\n }\n\n var top,\n right,\n bottom,\n left,\n options = this.target.options[this.prepared.name].autoScroll,\n container = options.container || getWindow(this.element);\n\n if (isWindow(container)) {\n left = pointer.clientX < autoScroll.margin;\n top = pointer.clientY < autoScroll.margin;\n right = pointer.clientX > container.innerWidth - autoScroll.margin;\n bottom = pointer.clientY > container.innerHeight - autoScroll.margin;\n }\n else {\n var rect = getElementClientRect(container);\n\n left = pointer.clientX < rect.left + autoScroll.margin;\n top = pointer.clientY < rect.top + autoScroll.margin;\n right = pointer.clientX > rect.right - autoScroll.margin;\n bottom = pointer.clientY > rect.bottom - autoScroll.margin;\n }\n\n autoScroll.x = (right ? 1: left? -1: 0);\n autoScroll.y = (bottom? 1: top? -1: 0);\n\n if (!autoScroll.isScrolling) {\n // set the autoScroll properties to those of the target\n autoScroll.margin = options.margin;\n autoScroll.speed = options.speed;\n\n autoScroll.start(this);\n }\n },\n\n _updateEventTargets: function (target, currentTarget) {\n this._eventTarget = target;\n this._curEventTarget = currentTarget;\n }\n\n };\n\n function getInteractionFromPointer (pointer, eventType, eventTarget) {\n var i = 0, len = interactions.length,\n mouseEvent = (/mouse/i.test(pointer.pointerType || eventType)\n // MSPointerEvent.MSPOINTER_TYPE_MOUSE\n || pointer.pointerType === 4),\n interaction;\n\n var id = getPointerId(pointer);\n\n // try to resume inertia with a new pointer\n if (/down|start/i.test(eventType)) {\n for (i = 0; i < len; i++) {\n interaction = interactions[i];\n\n var element = eventTarget;\n\n if (interaction.inertiaStatus.active && interaction.target.options[interaction.prepared.name].inertia.allowResume\n && (interaction.mouse === mouseEvent)) {\n while (element) {\n // if the element is the interaction element\n if (element === interaction.element) {\n return interaction;\n }\n element = parentElement(element);\n }\n }\n }\n }\n\n // if it's a mouse interaction\n if (mouseEvent || !(supportsTouch || supportsPointerEvent)) {\n\n // find a mouse interaction that's not in inertia phase\n for (i = 0; i < len; i++) {\n if (interactions[i].mouse && !interactions[i].inertiaStatus.active) {\n return interactions[i];\n }\n }\n\n // find any interaction specifically for mouse.\n // if the eventType is a mousedown, and inertia is active\n // ignore the interaction\n for (i = 0; i < len; i++) {\n if (interactions[i].mouse && !(/down/.test(eventType) && interactions[i].inertiaStatus.active)) {\n return interaction;\n }\n }\n\n // create a new interaction for mouse\n interaction = new Interaction();\n interaction.mouse = true;\n\n return interaction;\n }\n\n // get interaction that has this pointer\n for (i = 0; i < len; i++) {\n if (contains(interactions[i].pointerIds, id)) {\n return interactions[i];\n }\n }\n\n // at this stage, a pointerUp should not return an interaction\n if (/up|end|out/i.test(eventType)) {\n return null;\n }\n\n // get first idle interaction\n for (i = 0; i < len; i++) {\n interaction = interactions[i];\n\n if ((!interaction.prepared.name || (interaction.target.options.gesture.enabled))\n && !interaction.interacting()\n && !(!mouseEvent && interaction.mouse)) {\n\n return interaction;\n }\n }\n\n return new Interaction();\n }\n\n function doOnInteractions (method) {\n return (function (event) {\n var interaction,\n eventTarget = getActualElement(event.path\n ? event.path[0]\n : event.target),\n curEventTarget = getActualElement(event.currentTarget),\n i;\n\n if (supportsTouch && /touch/.test(event.type)) {\n prevTouchTime = new Date().getTime();\n\n for (i = 0; i < event.changedTouches.length; i++) {\n var pointer = event.changedTouches[i];\n\n interaction = getInteractionFromPointer(pointer, event.type, eventTarget);\n\n if (!interaction) { continue; }\n\n interaction._updateEventTargets(eventTarget, curEventTarget);\n\n interaction[method](pointer, event, eventTarget, curEventTarget);\n }\n }\n else {\n if (!supportsPointerEvent && /mouse/.test(event.type)) {\n // ignore mouse events while touch interactions are active\n for (i = 0; i < interactions.length; i++) {\n if (!interactions[i].mouse && interactions[i].pointerIsDown) {\n return;\n }\n }\n\n // try to ignore mouse events that are simulated by the browser\n // after a touch event\n if (new Date().getTime() - prevTouchTime < 500) {\n return;\n }\n }\n\n interaction = getInteractionFromPointer(event, event.type, eventTarget);\n\n if (!interaction) { return; }\n\n interaction._updateEventTargets(eventTarget, curEventTarget);\n\n interaction[method](event, event, eventTarget, curEventTarget);\n }\n });\n }\n\n function InteractEvent (interaction, event, action, phase, element, related) {\n var client,\n page,\n target = interaction.target,\n snapStatus = interaction.snapStatus,\n restrictStatus = interaction.restrictStatus,\n pointers = interaction.pointers,\n deltaSource = (target && target.options || defaultOptions).deltaSource,\n sourceX = deltaSource + 'X',\n sourceY = deltaSource + 'Y',\n options = target? target.options: defaultOptions,\n origin = getOriginXY(target, element),\n starting = phase === 'start',\n ending = phase === 'end',\n coords = starting? interaction.startCoords : interaction.curCoords;\n\n element = element || interaction.element;\n\n page = extend({}, coords.page);\n client = extend({}, coords.client);\n\n page.x -= origin.x;\n page.y -= origin.y;\n\n client.x -= origin.x;\n client.y -= origin.y;\n\n var relativePoints = options[action].snap && options[action].snap.relativePoints ;\n\n if (checkSnap(target, action) && !(starting && relativePoints && relativePoints.length)) {\n this.snap = {\n range : snapStatus.range,\n locked : snapStatus.locked,\n x : snapStatus.snappedX,\n y : snapStatus.snappedY,\n realX : snapStatus.realX,\n realY : snapStatus.realY,\n dx : snapStatus.dx,\n dy : snapStatus.dy\n };\n\n if (snapStatus.locked) {\n page.x += snapStatus.dx;\n page.y += snapStatus.dy;\n client.x += snapStatus.dx;\n client.y += snapStatus.dy;\n }\n }\n\n if (checkRestrict(target, action) && !(starting && options[action].restrict.elementRect) && restrictStatus.restricted) {\n page.x += restrictStatus.dx;\n page.y += restrictStatus.dy;\n client.x += restrictStatus.dx;\n client.y += restrictStatus.dy;\n\n this.restrict = {\n dx: restrictStatus.dx,\n dy: restrictStatus.dy\n };\n }\n\n this.pageX = page.x;\n this.pageY = page.y;\n this.clientX = client.x;\n this.clientY = client.y;\n\n this.x0 = interaction.startCoords.page.x - origin.x;\n this.y0 = interaction.startCoords.page.y - origin.y;\n this.clientX0 = interaction.startCoords.client.x - origin.x;\n this.clientY0 = interaction.startCoords.client.y - origin.y;\n this.ctrlKey = event.ctrlKey;\n this.altKey = event.altKey;\n this.shiftKey = event.shiftKey;\n this.metaKey = event.metaKey;\n this.button = event.button;\n this.buttons = event.buttons;\n this.target = element;\n this.t0 = interaction.downTimes[0];\n this.type = action + (phase || '');\n\n this.interaction = interaction;\n this.interactable = target;\n\n var inertiaStatus = interaction.inertiaStatus;\n\n if (inertiaStatus.active) {\n this.detail = 'inertia';\n }\n\n if (related) {\n this.relatedTarget = related;\n }\n\n // end event dx, dy is difference between start and end points\n if (ending) {\n if (deltaSource === 'client') {\n this.dx = client.x - interaction.startCoords.client.x;\n this.dy = client.y - interaction.startCoords.client.y;\n }\n else {\n this.dx = page.x - interaction.startCoords.page.x;\n this.dy = page.y - interaction.startCoords.page.y;\n }\n }\n else if (starting) {\n this.dx = 0;\n this.dy = 0;\n }\n // copy properties from previousmove if starting inertia\n else if (phase === 'inertiastart') {\n this.dx = interaction.prevEvent.dx;\n this.dy = interaction.prevEvent.dy;\n }\n else {\n if (deltaSource === 'client') {\n this.dx = client.x - interaction.prevEvent.clientX;\n this.dy = client.y - interaction.prevEvent.clientY;\n }\n else {\n this.dx = page.x - interaction.prevEvent.pageX;\n this.dy = page.y - interaction.prevEvent.pageY;\n }\n }\n if (interaction.prevEvent && interaction.prevEvent.detail === 'inertia'\n && !inertiaStatus.active\n && options[action].inertia && options[action].inertia.zeroResumeDelta) {\n\n inertiaStatus.resumeDx += this.dx;\n inertiaStatus.resumeDy += this.dy;\n\n this.dx = this.dy = 0;\n }\n\n if (action === 'resize' && interaction.resizeAxes) {\n if (options.resize.square) {\n if (interaction.resizeAxes === 'y') {\n this.dx = this.dy;\n }\n else {\n this.dy = this.dx;\n }\n this.axes = 'xy';\n }\n else {\n this.axes = interaction.resizeAxes;\n\n if (interaction.resizeAxes === 'x') {\n this.dy = 0;\n }\n else if (interaction.resizeAxes === 'y') {\n this.dx = 0;\n }\n }\n }\n else if (action === 'gesture') {\n this.touches = [pointers[0], pointers[1]];\n\n if (starting) {\n this.distance = touchDistance(pointers, deltaSource);\n this.box = touchBBox(pointers);\n this.scale = 1;\n this.ds = 0;\n this.angle = touchAngle(pointers, undefined, deltaSource);\n this.da = 0;\n }\n else if (ending || event instanceof InteractEvent) {\n this.distance = interaction.prevEvent.distance;\n this.box = interaction.prevEvent.box;\n this.scale = interaction.prevEvent.scale;\n this.ds = this.scale - 1;\n this.angle = interaction.prevEvent.angle;\n this.da = this.angle - interaction.gesture.startAngle;\n }\n else {\n this.distance = touchDistance(pointers, deltaSource);\n this.box = touchBBox(pointers);\n this.scale = this.distance / interaction.gesture.startDistance;\n this.angle = touchAngle(pointers, interaction.gesture.prevAngle, deltaSource);\n\n this.ds = this.scale - interaction.gesture.prevScale;\n this.da = this.angle - interaction.gesture.prevAngle;\n }\n }\n\n if (starting) {\n this.timeStamp = interaction.downTimes[0];\n this.dt = 0;\n this.duration = 0;\n this.speed = 0;\n this.velocityX = 0;\n this.velocityY = 0;\n }\n else if (phase === 'inertiastart') {\n this.timeStamp = interaction.prevEvent.timeStamp;\n this.dt = interaction.prevEvent.dt;\n this.duration = interaction.prevEvent.duration;\n this.speed = interaction.prevEvent.speed;\n this.velocityX = interaction.prevEvent.velocityX;\n this.velocityY = interaction.prevEvent.velocityY;\n }\n else {\n this.timeStamp = new Date().getTime();\n this.dt = this.timeStamp - interaction.prevEvent.timeStamp;\n this.duration = this.timeStamp - interaction.downTimes[0];\n\n if (event instanceof InteractEvent) {\n var dx = this[sourceX] - interaction.prevEvent[sourceX],\n dy = this[sourceY] - interaction.prevEvent[sourceY],\n dt = this.dt / 1000;\n\n this.speed = hypot(dx, dy) / dt;\n this.velocityX = dx / dt;\n this.velocityY = dy / dt;\n }\n // if normal move or end event, use previous user event coords\n else {\n // speed and velocity in pixels per second\n this.speed = interaction.pointerDelta[deltaSource].speed;\n this.velocityX = interaction.pointerDelta[deltaSource].vx;\n this.velocityY = interaction.pointerDelta[deltaSource].vy;\n }\n }\n\n if ((ending || phase === 'inertiastart')\n && interaction.prevEvent.speed > 600 && this.timeStamp - interaction.prevEvent.timeStamp < 150) {\n\n var angle = 180 * Math.atan2(interaction.prevEvent.velocityY, interaction.prevEvent.velocityX) / Math.PI,\n overlap = 22.5;\n\n if (angle < 0) {\n angle += 360;\n }\n\n var left = 135 - overlap <= angle && angle < 225 + overlap,\n up = 225 - overlap <= angle && angle < 315 + overlap,\n\n right = !left && (315 - overlap <= angle || angle < 45 + overlap),\n down = !up && 45 - overlap <= angle && angle < 135 + overlap;\n\n this.swipe = {\n up : up,\n down : down,\n left : left,\n right: right,\n angle: angle,\n speed: interaction.prevEvent.speed,\n velocity: {\n x: interaction.prevEvent.velocityX,\n y: interaction.prevEvent.velocityY\n }\n };\n }\n }\n\n InteractEvent.prototype = {\n preventDefault: blank,\n stopImmediatePropagation: function () {\n this.immediatePropagationStopped = this.propagationStopped = true;\n },\n stopPropagation: function () {\n this.propagationStopped = true;\n }\n };\n\n function preventOriginalDefault () {\n this.originalEvent.preventDefault();\n }\n\n function getActionCursor (action) {\n var cursor = '';\n\n if (action.name === 'drag') {\n cursor = actionCursors.drag;\n }\n if (action.name === 'resize') {\n if (action.axis) {\n cursor = actionCursors[action.name + action.axis];\n }\n else if (action.edges) {\n var cursorKey = 'resize',\n edgeNames = ['top', 'bottom', 'left', 'right'];\n\n for (var i = 0; i < 4; i++) {\n if (action.edges[edgeNames[i]]) {\n cursorKey += edgeNames[i];\n }\n }\n\n cursor = actionCursors[cursorKey];\n }\n }\n\n return cursor;\n }\n\n function checkResizeEdge (name, value, page, element, interactableElement, rect, margin) {\n // false, '', undefined, null\n if (!value) { return false; }\n\n // true value, use pointer coords and element rect\n if (value === true) {\n // if dimensions are negative, \"switch\" edges\n var width = isNumber(rect.width)? rect.width : rect.right - rect.left,\n height = isNumber(rect.height)? rect.height : rect.bottom - rect.top;\n\n if (width < 0) {\n if (name === 'left' ) { name = 'right'; }\n else if (name === 'right') { name = 'left' ; }\n }\n if (height < 0) {\n if (name === 'top' ) { name = 'bottom'; }\n else if (name === 'bottom') { name = 'top' ; }\n }\n\n if (name === 'left' ) { return page.x < ((width >= 0? rect.left: rect.right ) + margin); }\n if (name === 'top' ) { return page.y < ((height >= 0? rect.top : rect.bottom) + margin); }\n\n if (name === 'right' ) { return page.x > ((width >= 0? rect.right : rect.left) - margin); }\n if (name === 'bottom') { return page.y > ((height >= 0? rect.bottom: rect.top ) - margin); }\n }\n\n // the remaining checks require an element\n if (!isElement(element)) { return false; }\n\n return isElement(value)\n // the value is an element to use as a resize handle\n ? value === element\n // otherwise check if element matches value as selector\n : matchesUpTo(element, value, interactableElement);\n }\n\n function defaultActionChecker (pointer, interaction, element) {\n var rect = this.getRect(element),\n shouldResize = false,\n action = null,\n resizeAxes = null,\n resizeEdges,\n page = extend({}, interaction.curCoords.page),\n options = this.options;\n\n if (!rect) { return null; }\n\n if (actionIsEnabled.resize && options.resize.enabled) {\n var resizeOptions = options.resize;\n\n resizeEdges = {\n left: false, right: false, top: false, bottom: false\n };\n\n // if using resize.edges\n if (isObject(resizeOptions.edges)) {\n for (var edge in resizeEdges) {\n resizeEdges[edge] = checkResizeEdge(edge,\n resizeOptions.edges[edge],\n page,\n interaction._eventTarget,\n element,\n rect,\n resizeOptions.margin || margin);\n }\n\n resizeEdges.left = resizeEdges.left && !resizeEdges.right;\n resizeEdges.top = resizeEdges.top && !resizeEdges.bottom;\n\n shouldResize = resizeEdges.left || resizeEdges.right || resizeEdges.top || resizeEdges.bottom;\n }\n else {\n var right = options.resize.axis !== 'y' && page.x > (rect.right - margin),\n bottom = options.resize.axis !== 'x' && page.y > (rect.bottom - margin);\n\n shouldResize = right || bottom;\n resizeAxes = (right? 'x' : '') + (bottom? 'y' : '');\n }\n }\n\n action = shouldResize\n ? 'resize'\n : actionIsEnabled.drag && options.drag.enabled\n ? 'drag'\n : null;\n\n if (actionIsEnabled.gesture\n && interaction.pointerIds.length >=2\n && !(interaction.dragging || interaction.resizing)) {\n action = 'gesture';\n }\n\n if (action) {\n return {\n name: action,\n axis: resizeAxes,\n edges: resizeEdges\n };\n }\n\n return null;\n }\n\n // Check if action is enabled globally and the current target supports it\n // If so, return the validated action. Otherwise, return null\n function validateAction (action, interactable) {\n if (!isObject(action)) { return null; }\n\n var actionName = action.name,\n options = interactable.options;\n\n if (( (actionName === 'resize' && options.resize.enabled )\n || (actionName === 'drag' && options.drag.enabled )\n || (actionName === 'gesture' && options.gesture.enabled))\n && actionIsEnabled[actionName]) {\n\n if (actionName === 'resize' || actionName === 'resizeyx') {\n actionName = 'resizexy';\n }\n\n return action;\n }\n return null;\n }\n\n var listeners = {},\n interactionListeners = [\n 'dragStart', 'dragMove', 'resizeStart', 'resizeMove', 'gestureStart', 'gestureMove',\n 'pointerOver', 'pointerOut', 'pointerHover', 'selectorDown',\n 'pointerDown', 'pointerMove', 'pointerUp', 'pointerCancel', 'pointerEnd',\n 'addPointer', 'removePointer', 'recordPointer', 'autoScrollMove'\n ];\n\n for (var i = 0, len = interactionListeners.length; i < len; i++) {\n var name = interactionListeners[i];\n\n listeners[name] = doOnInteractions(name);\n }\n\n // bound to the interactable context when a DOM event\n // listener is added to a selector interactable\n function delegateListener (event, useCapture) {\n var fakeEvent = {},\n delegated = delegatedEvents[event.type],\n eventTarget = getActualElement(event.path\n ? event.path[0]\n : event.target),\n element = eventTarget;\n\n useCapture = useCapture? true: false;\n\n // duplicate the event so that currentTarget can be changed\n for (var prop in event) {\n fakeEvent[prop] = event[prop];\n }\n\n fakeEvent.originalEvent = event;\n fakeEvent.preventDefault = preventOriginalDefault;\n\n // climb up document tree looking for selector matches\n while (isElement(element)) {\n for (var i = 0; i < delegated.selectors.length; i++) {\n var selector = delegated.selectors[i],\n context = delegated.contexts[i];\n\n if (matchesSelector(element, selector)\n && nodeContains(context, eventTarget)\n && nodeContains(context, element)) {\n\n var listeners = delegated.listeners[i];\n\n fakeEvent.currentTarget = element;\n\n for (var j = 0; j < listeners.length; j++) {\n if (listeners[j][1] === useCapture) {\n listeners[j][0](fakeEvent);\n }\n }\n }\n }\n\n element = parentElement(element);\n }\n }\n\n function delegateUseCapture (event) {\n return delegateListener.call(this, event, true);\n }\n\n interactables.indexOfElement = function indexOfElement (element, context) {\n context = context || document;\n\n for (var i = 0; i < this.length; i++) {\n var interactable = this[i];\n\n if ((interactable.selector === element\n && (interactable._context === context))\n || (!interactable.selector && interactable._element === element)) {\n\n return i;\n }\n }\n return -1;\n };\n\n interactables.get = function interactableGet (element, options) {\n return this[this.indexOfElement(element, options && options.context)];\n };\n\n interactables.forEachSelector = function (callback) {\n for (var i = 0; i < this.length; i++) {\n var interactable = this[i];\n\n if (!interactable.selector) {\n continue;\n }\n\n var ret = callback(interactable, interactable.selector, interactable._context, i, this);\n\n if (ret !== undefined) {\n return ret;\n }\n }\n };\n\n /*\\\n * interact\n [ method ]\n *\n * The methods of this variable can be used to set elements as\n * interactables and also to change various default settings.\n *\n * Calling it as a function and passing an element or a valid CSS selector\n * string returns an Interactable object which has various methods to\n * configure it.\n *\n - element (Element | string) The HTML or SVG Element to interact with or CSS selector\n = (object) An @Interactable\n *\n > Usage\n | interact(document.getElementById('draggable')).draggable(true);\n |\n | var rectables = interact('rect');\n | rectables\n | .gesturable(true)\n | .on('gesturemove', function (event) {\n | // something cool...\n | })\n | .autoScroll(true);\n \\*/\n function interact (element, options) {\n return interactables.get(element, options) || new Interactable(element, options);\n }\n\n /*\\\n * Interactable\n [ property ]\n **\n * Object type returned by @interact\n \\*/\n function Interactable (element, options) {\n this._element = element;\n this._iEvents = this._iEvents || {};\n\n var _window;\n\n if (trySelector(element)) {\n this.selector = element;\n\n var context = options && options.context;\n\n _window = context? getWindow(context) : window;\n\n if (context && (_window.Node\n ? context instanceof _window.Node\n : (isElement(context) || context === _window.document))) {\n\n this._context = context;\n }\n }\n else {\n _window = getWindow(element);\n\n if (isElement(element, _window)) {\n\n if (supportsPointerEvent) {\n events.add(this._element, pEventTypes.down, listeners.pointerDown );\n events.add(this._element, pEventTypes.move, listeners.pointerHover);\n }\n else {\n events.add(this._element, 'mousedown' , listeners.pointerDown );\n events.add(this._element, 'mousemove' , listeners.pointerHover);\n events.add(this._element, 'touchstart', listeners.pointerDown );\n events.add(this._element, 'touchmove' , listeners.pointerHover);\n }\n }\n }\n\n this._doc = _window.document;\n\n if (!contains(documents, this._doc)) {\n listenToDocument(this._doc);\n }\n\n interactables.push(this);\n\n this.set(options);\n }\n\n Interactable.prototype = {\n setOnEvents: function (action, phases) {\n if (action === 'drop') {\n if (isFunction(phases.ondrop) ) { this.ondrop = phases.ondrop ; }\n if (isFunction(phases.ondropactivate) ) { this.ondropactivate = phases.ondropactivate ; }\n if (isFunction(phases.ondropdeactivate)) { this.ondropdeactivate = phases.ondropdeactivate; }\n if (isFunction(phases.ondragenter) ) { this.ondragenter = phases.ondragenter ; }\n if (isFunction(phases.ondragleave) ) { this.ondragleave = phases.ondragleave ; }\n if (isFunction(phases.ondropmove) ) { this.ondropmove = phases.ondropmove ; }\n }\n else {\n action = 'on' + action;\n\n if (isFunction(phases.onstart) ) { this[action + 'start' ] = phases.onstart ; }\n if (isFunction(phases.onmove) ) { this[action + 'move' ] = phases.onmove ; }\n if (isFunction(phases.onend) ) { this[action + 'end' ] = phases.onend ; }\n if (isFunction(phases.oninertiastart)) { this[action + 'inertiastart' ] = phases.oninertiastart ; }\n }\n\n return this;\n },\n\n /*\\\n * Interactable.draggable\n [ method ]\n *\n * Gets or sets whether drag actions can be performed on the\n * Interactable\n *\n = (boolean) Indicates if this can be the target of drag events\n | var isDraggable = interact('ul li').draggable();\n * or\n - options (boolean | object) #optional true/false or An object with event listeners to be fired on drag events (object makes the Interactable draggable)\n = (object) This Interactable\n | interact(element).draggable({\n | onstart: function (event) {},\n | onmove : function (event) {},\n | onend : function (event) {},\n |\n | // the axis in which the first movement must be\n | // for the drag sequence to start\n | // 'xy' by default - any direction\n | axis: 'x' || 'y' || 'xy',\n |\n | // max number of drags that can happen concurrently\n | // with elements of this Interactable. Infinity by default\n | max: Infinity,\n |\n | // max number of drags that can target the same element+Interactable\n | // 1 by default\n | maxPerElement: 2\n | });\n \\*/\n draggable: function (options) {\n if (isObject(options)) {\n this.options.drag.enabled = options.enabled === false? false: true;\n this.setPerAction('drag', options);\n this.setOnEvents('drag', options);\n\n if (/^x$|^y$|^xy$/.test(options.axis)) {\n this.options.drag.axis = options.axis;\n }\n else if (options.axis === null) {\n delete this.options.drag.axis;\n }\n\n return this;\n }\n\n if (isBool(options)) {\n this.options.drag.enabled = options;\n\n return this;\n }\n\n return this.options.drag;\n },\n\n setPerAction: function (action, options) {\n // for all the default per-action options\n for (var option in options) {\n // if this option exists for this action\n if (option in defaultOptions[action]) {\n // if the option in the options arg is an object value\n if (isObject(options[option])) {\n // duplicate the object\n this.options[action][option] = extend(this.options[action][option] || {}, options[option]);\n\n if (isObject(defaultOptions.perAction[option]) && 'enabled' in defaultOptions.perAction[option]) {\n this.options[action][option].enabled = options[option].enabled === false? false : true;\n }\n }\n else if (isBool(options[option]) && isObject(defaultOptions.perAction[option])) {\n this.options[action][option].enabled = options[option];\n }\n else if (options[option] !== undefined) {\n // or if it's not undefined, do a plain assignment\n this.options[action][option] = options[option];\n }\n }\n }\n },\n\n /*\\\n * Interactable.dropzone\n [ method ]\n *\n * Returns or sets whether elements can be dropped onto this\n * Interactable to trigger drop events\n *\n * Dropzones can receive the following events:\n * - `dropactivate` and `dropdeactivate` when an acceptable drag starts and ends\n * - `dragenter` and `dragleave` when a draggable enters and leaves the dropzone\n * - `dragmove` when a draggable that has entered the dropzone is moved\n * - `drop` when a draggable is dropped into this dropzone\n *\n * Use the `accept` option to allow only elements that match the given CSS selector or element.\n *\n * Use the `overlap` option to set how drops are checked for. The allowed values are:\n * - `'pointer'`, the pointer must be over the dropzone (default)\n * - `'center'`, the draggable element's center must be over the dropzone\n * - a number from 0-1 which is the `(intersection area) / (draggable area)`.\n * e.g. `0.5` for drop to happen when half of the area of the\n * draggable is over the dropzone\n *\n - options (boolean | object | null) #optional The new value to be set.\n | interact('.drop').dropzone({\n | accept: '.can-drop' || document.getElementById('single-drop'),\n | overlap: 'pointer' || 'center' || zeroToOne\n | }\n = (boolean | object) The current setting or this Interactable\n \\*/\n dropzone: function (options) {\n if (isObject(options)) {\n this.options.drop.enabled = options.enabled === false? false: true;\n this.setOnEvents('drop', options);\n\n if (/^(pointer|center)$/.test(options.overlap)) {\n this.options.drop.overlap = options.overlap;\n }\n else if (isNumber(options.overlap)) {\n this.options.drop.overlap = Math.max(Math.min(1, options.overlap), 0);\n }\n if ('accept' in options) {\n this.options.drop.accept = options.accept;\n }\n if ('checker' in options) {\n this.options.drop.checker = options.checker;\n }\n\n return this;\n }\n\n if (isBool(options)) {\n this.options.drop.enabled = options;\n\n return this;\n }\n\n return this.options.drop;\n },\n\n dropCheck: function (dragEvent, event, draggable, draggableElement, dropElement, rect) {\n var dropped = false;\n\n // if the dropzone has no rect (eg. display: none)\n // call the custom dropChecker or just return false\n if (!(rect = rect || this.getRect(dropElement))) {\n return (this.options.drop.checker\n ? this.options.drop.checker(dragEvent, event, dropped, this, dropElement, draggable, draggableElement)\n : false);\n }\n\n var dropOverlap = this.options.drop.overlap;\n\n if (dropOverlap === 'pointer') {\n var page = getPageXY(dragEvent),\n origin = getOriginXY(draggable, draggableElement),\n horizontal,\n vertical;\n\n page.x += origin.x;\n page.y += origin.y;\n\n horizontal = (page.x > rect.left) && (page.x < rect.right);\n vertical = (page.y > rect.top ) && (page.y < rect.bottom);\n\n dropped = horizontal && vertical;\n }\n\n var dragRect = draggable.getRect(draggableElement);\n\n if (dropOverlap === 'center') {\n var cx = dragRect.left + dragRect.width / 2,\n cy = dragRect.top + dragRect.height / 2;\n\n dropped = cx >= rect.left && cx <= rect.right && cy >= rect.top && cy <= rect.bottom;\n }\n\n if (isNumber(dropOverlap)) {\n var overlapArea = (Math.max(0, Math.min(rect.right , dragRect.right ) - Math.max(rect.left, dragRect.left))\n * Math.max(0, Math.min(rect.bottom, dragRect.bottom) - Math.max(rect.top , dragRect.top ))),\n overlapRatio = overlapArea / (dragRect.width * dragRect.height);\n\n dropped = overlapRatio >= dropOverlap;\n }\n\n if (this.options.drop.checker) {\n dropped = this.options.drop.checker(dragEvent, event, dropped, this, dropElement, draggable, draggableElement);\n }\n\n return dropped;\n },\n\n /*\\\n * Interactable.dropChecker\n [ method ]\n *\n * DEPRECATED. Use interactable.dropzone({ checker: function... }) instead.\n *\n * Gets or sets the function used to check if a dragged element is\n * over this Interactable.\n *\n - checker (function) #optional The function that will be called when checking for a drop\n = (Function | Interactable) The checker function or this Interactable\n *\n * The checker function takes the following arguments:\n *\n - dragEvent (InteractEvent) The related dragmove or dragend event\n - event (TouchEvent | PointerEvent | MouseEvent) The user move/up/end Event related to the dragEvent\n - dropped (boolean) The value from the default drop checker\n - dropzone (Interactable) The dropzone interactable\n - dropElement (Element) The dropzone element\n - draggable (Interactable) The Interactable being dragged\n - draggableElement (Element) The actual element that's being dragged\n *\n > Usage:\n | interact(target)\n | .dropChecker(function(dragEvent, // related dragmove or dragend event\n | event, // TouchEvent/PointerEvent/MouseEvent\n | dropped, // bool result of the default checker\n | dropzone, // dropzone Interactable\n | dropElement, // dropzone elemnt\n | draggable, // draggable Interactable\n | draggableElement) {// draggable element\n |\n | return dropped && event.target.hasAttribute('allow-drop');\n | }\n \\*/\n dropChecker: function (checker) {\n if (isFunction(checker)) {\n this.options.drop.checker = checker;\n\n return this;\n }\n if (checker === null) {\n delete this.options.getRect;\n\n return this;\n }\n\n return this.options.drop.checker;\n },\n\n /*\\\n * Interactable.accept\n [ method ]\n *\n * Deprecated. add an `accept` property to the options object passed to\n * @Interactable.dropzone instead.\n *\n * Gets or sets the Element or CSS selector match that this\n * Interactable accepts if it is a dropzone.\n *\n - newValue (Element | string | null) #optional\n * If it is an Element, then only that element can be dropped into this dropzone.\n * If it is a string, the element being dragged must match it as a selector.\n * If it is null, the accept options is cleared - it accepts any element.\n *\n = (string | Element | null | Interactable) The current accept option if given `undefined` or this Interactable\n \\*/\n accept: function (newValue) {\n if (isElement(newValue)) {\n this.options.drop.accept = newValue;\n\n return this;\n }\n\n // test if it is a valid CSS selector\n if (trySelector(newValue)) {\n this.options.drop.accept = newValue;\n\n return this;\n }\n\n if (newValue === null) {\n delete this.options.drop.accept;\n\n return this;\n }\n\n return this.options.drop.accept;\n },\n\n /*\\\n * Interactable.resizable\n [ method ]\n *\n * Gets or sets whether resize actions can be performed on the\n * Interactable\n *\n = (boolean) Indicates if this can be the target of resize elements\n | var isResizeable = interact('input[type=text]').resizable();\n * or\n - options (boolean | object) #optional true/false or An object with event listeners to be fired on resize events (object makes the Interactable resizable)\n = (object) This Interactable\n | interact(element).resizable({\n | onstart: function (event) {},\n | onmove : function (event) {},\n | onend : function (event) {},\n |\n | edges: {\n | top : true, // Use pointer coords to check for resize.\n | left : false, // Disable resizing from left edge.\n | bottom: '.resize-s',// Resize if pointer target matches selector\n | right : handleEl // Resize if pointer target is the given Element\n | },\n |\n | // Width and height can be adjusted independently. When `true`, width and\n | // height are adjusted at a 1:1 ratio.\n | square: false,\n |\n | // Width and height can be adjusted independently. When `true`, width and\n | // height maintain the aspect ratio they had when resizing started.\n | preserveAspectRatio: false,\n |\n | // a value of 'none' will limit the resize rect to a minimum of 0x0\n | // 'negate' will allow the rect to have negative width/height\n | // 'reposition' will keep the width/height positive by swapping\n | // the top and bottom edges and/or swapping the left and right edges\n | invert: 'none' || 'negate' || 'reposition'\n |\n | // limit multiple resizes.\n | // See the explanation in the @Interactable.draggable example\n | max: Infinity,\n | maxPerElement: 1,\n | });\n \\*/\n resizable: function (options) {\n if (isObject(options)) {\n this.options.resize.enabled = options.enabled === false? false: true;\n this.setPerAction('resize', options);\n this.setOnEvents('resize', options);\n\n if (/^x$|^y$|^xy$/.test(options.axis)) {\n this.options.resize.axis = options.axis;\n }\n else if (options.axis === null) {\n this.options.resize.axis = defaultOptions.resize.axis;\n }\n\n if (isBool(options.preserveAspectRatio)) {\n this.options.resize.preserveAspectRatio = options.preserveAspectRatio;\n }\n else if (isBool(options.square)) {\n this.options.resize.square = options.square;\n }\n\n return this;\n }\n if (isBool(options)) {\n this.options.resize.enabled = options;\n\n return this;\n }\n return this.options.resize;\n },\n\n /*\\\n * Interactable.squareResize\n [ method ]\n *\n * Deprecated. Add a `square: true || false` property to @Interactable.resizable instead\n *\n * Gets or sets whether resizing is forced 1:1 aspect\n *\n = (boolean) Current setting\n *\n * or\n *\n - newValue (boolean) #optional\n = (object) this Interactable\n \\*/\n squareResize: function (newValue) {\n if (isBool(newValue)) {\n this.options.resize.square = newValue;\n\n return this;\n }\n\n if (newValue === null) {\n delete this.options.resize.square;\n\n return this;\n }\n\n return this.options.resize.square;\n },\n\n /*\\\n * Interactable.gesturable\n [ method ]\n *\n * Gets or sets whether multitouch gestures can be performed on the\n * Interactable's element\n *\n = (boolean) Indicates if this can be the target of gesture events\n | var isGestureable = interact(element).gesturable();\n * or\n - options (boolean | object) #optional true/false or An object with event listeners to be fired on gesture events (makes the Interactable gesturable)\n = (object) this Interactable\n | interact(element).gesturable({\n | onstart: function (event) {},\n | onmove : function (event) {},\n | onend : function (event) {},\n |\n | // limit multiple gestures.\n | // See the explanation in @Interactable.draggable example\n | max: Infinity,\n | maxPerElement: 1,\n | });\n \\*/\n gesturable: function (options) {\n if (isObject(options)) {\n this.options.gesture.enabled = options.enabled === false? false: true;\n this.setPerAction('gesture', options);\n this.setOnEvents('gesture', options);\n\n return this;\n }\n\n if (isBool(options)) {\n this.options.gesture.enabled = options;\n\n return this;\n }\n\n return this.options.gesture;\n },\n\n /*\\\n * Interactable.autoScroll\n [ method ]\n **\n * Deprecated. Add an `autoscroll` property to the options object\n * passed to @Interactable.draggable or @Interactable.resizable instead.\n *\n * Returns or sets whether dragging and resizing near the edges of the\n * window/container trigger autoScroll for this Interactable\n *\n = (object) Object with autoScroll properties\n *\n * or\n *\n - options (object | boolean) #optional\n * options can be:\n * - an object with margin, distance and interval properties,\n * - true or false to enable or disable autoScroll or\n = (Interactable) this Interactable\n \\*/\n autoScroll: function (options) {\n if (isObject(options)) {\n options = extend({ actions: ['drag', 'resize']}, options);\n }\n else if (isBool(options)) {\n options = { actions: ['drag', 'resize'], enabled: options };\n }\n\n return this.setOptions('autoScroll', options);\n },\n\n /*\\\n * Interactable.snap\n [ method ]\n **\n * Deprecated. Add a `snap` property to the options object passed\n * to @Interactable.draggable or @Interactable.resizable instead.\n *\n * Returns or sets if and how action coordinates are snapped. By\n * default, snapping is relative to the pointer coordinates. You can\n * change this by setting the\n * [`elementOrigin`](https://github.com/taye/interact.js/pull/72).\n **\n = (boolean | object) `false` if snap is disabled; object with snap properties if snap is enabled\n **\n * or\n **\n - options (object | boolean | null) #optional\n = (Interactable) this Interactable\n > Usage\n | interact(document.querySelector('#thing')).snap({\n | targets: [\n | // snap to this specific point\n | {\n | x: 100,\n | y: 100,\n | range: 25\n | },\n | // give this function the x and y page coords and snap to the object returned\n | function (x, y) {\n | return {\n | x: x,\n | y: (75 + 50 * Math.sin(x * 0.04)),\n | range: 40\n | };\n | },\n | // create a function that snaps to a grid\n | interact.createSnapGrid({\n | x: 50,\n | y: 50,\n | range: 10, // optional\n | offset: { x: 5, y: 10 } // optional\n | })\n | ],\n | // do not snap during normal movement.\n | // Instead, trigger only one snapped move event\n | // immediately before the end event.\n | endOnly: true,\n |\n | relativePoints: [\n | { x: 0, y: 0 }, // snap relative to the top left of the element\n | { x: 1, y: 1 }, // and also to the bottom right\n | ], \n |\n | // offset the snap target coordinates\n | // can be an object with x/y or 'startCoords'\n | offset: { x: 50, y: 50 }\n | }\n | });\n \\*/\n snap: function (options) {\n var ret = this.setOptions('snap', options);\n\n if (ret === this) { return this; }\n\n return ret.drag;\n },\n\n setOptions: function (option, options) {\n var actions = options && isArray(options.actions)\n ? options.actions\n : ['drag'];\n\n var i;\n\n if (isObject(options) || isBool(options)) {\n for (i = 0; i < actions.length; i++) {\n var action = /resize/.test(actions[i])? 'resize' : actions[i];\n\n if (!isObject(this.options[action])) { continue; }\n\n var thisOption = this.options[action][option];\n\n if (isObject(options)) {\n extend(thisOption, options);\n thisOption.enabled = options.enabled === false? false: true;\n\n if (option === 'snap') {\n if (thisOption.mode === 'grid') {\n thisOption.targets = [\n interact.createSnapGrid(extend({\n offset: thisOption.gridOffset || { x: 0, y: 0 }\n }, thisOption.grid || {}))\n ];\n }\n else if (thisOption.mode === 'anchor') {\n thisOption.targets = thisOption.anchors;\n }\n else if (thisOption.mode === 'path') {\n thisOption.targets = thisOption.paths;\n }\n\n if ('elementOrigin' in options) {\n thisOption.relativePoints = [options.elementOrigin];\n }\n }\n }\n else if (isBool(options)) {\n thisOption.enabled = options;\n }\n }\n\n return this;\n }\n\n var ret = {},\n allActions = ['drag', 'resize', 'gesture'];\n\n for (i = 0; i < allActions.length; i++) {\n if (option in defaultOptions[allActions[i]]) {\n ret[allActions[i]] = this.options[allActions[i]][option];\n }\n }\n\n return ret;\n },\n\n\n /*\\\n * Interactable.inertia\n [ method ]\n **\n * Deprecated. Add an `inertia` property to the options object passed\n * to @Interactable.draggable or @Interactable.resizable instead.\n *\n * Returns or sets if and how events continue to run after the pointer is released\n **\n = (boolean | object) `false` if inertia is disabled; `object` with inertia properties if inertia is enabled\n **\n * or\n **\n - options (object | boolean | null) #optional\n = (Interactable) this Interactable\n > Usage\n | // enable and use default settings\n | interact(element).inertia(true);\n |\n | // enable and use custom settings\n | interact(element).inertia({\n | // value greater than 0\n | // high values slow the object down more quickly\n | resistance : 16,\n |\n | // the minimum launch speed (pixels per second) that results in inertia start\n | minSpeed : 200,\n |\n | // inertia will stop when the object slows down to this speed\n | endSpeed : 20,\n |\n | // boolean; should actions be resumed when the pointer goes down during inertia\n | allowResume : true,\n |\n | // boolean; should the jump when resuming from inertia be ignored in event.dx/dy\n | zeroResumeDelta: false,\n |\n | // if snap/restrict are set to be endOnly and inertia is enabled, releasing\n | // the pointer without triggering inertia will animate from the release\n | // point to the snaped/restricted point in the given amount of time (ms)\n | smoothEndDuration: 300,\n |\n | // an array of action types that can have inertia (no gesture)\n | actions : ['drag', 'resize']\n | });\n |\n | // reset custom settings and use all defaults\n | interact(element).inertia(null);\n \\*/\n inertia: function (options) {\n var ret = this.setOptions('inertia', options);\n\n if (ret === this) { return this; }\n\n return ret.drag;\n },\n\n getAction: function (pointer, event, interaction, element) {\n var action = this.defaultActionChecker(pointer, interaction, element);\n\n if (this.options.actionChecker) {\n return this.options.actionChecker(pointer, event, action, this, element, interaction);\n }\n\n return action;\n },\n\n defaultActionChecker: defaultActionChecker,\n\n /*\\\n * Interactable.actionChecker\n [ method ]\n *\n * Gets or sets the function used to check action to be performed on\n * pointerDown\n *\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.\n = (Function | Interactable) The checker function or this Interactable\n *\n | interact('.resize-drag')\n | .resizable(true)\n | .draggable(true)\n | .actionChecker(function (pointer, event, action, interactable, element, interaction) {\n |\n | if (interact.matchesSelector(event.target, '.drag-handle') {\n | // force drag with handle target\n | action.name = drag;\n | }\n | else {\n | // resize from the top and right edges\n | action.name = 'resize';\n | action.edges = { top: true, right: true };\n | }\n |\n | return action;\n | });\n \\*/\n actionChecker: function (checker) {\n if (isFunction(checker)) {\n this.options.actionChecker = checker;\n\n return this;\n }\n\n if (checker === null) {\n delete this.options.actionChecker;\n\n return this;\n }\n\n return this.options.actionChecker;\n },\n\n /*\\\n * Interactable.getRect\n [ method ]\n *\n * The default function to get an Interactables bounding rect. Can be\n * overridden using @Interactable.rectChecker.\n *\n - element (Element) #optional The element to measure.\n = (object) The object's bounding rectangle.\n o {\n o top : 0,\n o left : 0,\n o bottom: 0,\n o right : 0,\n o width : 0,\n o height: 0\n o }\n \\*/\n getRect: function rectCheck (element) {\n element = element || this._element;\n\n if (this.selector && !(isElement(element))) {\n element = this._context.querySelector(this.selector);\n }\n\n return getElementRect(element);\n },\n\n /*\\\n * Interactable.rectChecker\n [ method ]\n *\n * Returns or sets the function used to calculate the interactable's\n * element's rectangle\n *\n - checker (function) #optional A function which returns this Interactable's bounding rectangle. See @Interactable.getRect\n = (function | object) The checker function or this Interactable\n \\*/\n rectChecker: function (checker) {\n if (isFunction(checker)) {\n this.getRect = checker;\n\n return this;\n }\n\n if (checker === null) {\n delete this.options.getRect;\n\n return this;\n }\n\n return this.getRect;\n },\n\n /*\\\n * Interactable.styleCursor\n [ method ]\n *\n * Returns or sets whether the action that would be performed when the\n * mouse on the element are checked on `mousemove` so that the cursor\n * may be styled appropriately\n *\n - newValue (boolean) #optional\n = (boolean | Interactable) The current setting or this Interactable\n \\*/\n styleCursor: function (newValue) {\n if (isBool(newValue)) {\n this.options.styleCursor = newValue;\n\n return this;\n }\n\n if (newValue === null) {\n delete this.options.styleCursor;\n\n return this;\n }\n\n return this.options.styleCursor;\n },\n\n /*\\\n * Interactable.preventDefault\n [ method ]\n *\n * Returns or sets whether to prevent the browser's default behaviour\n * in response to pointer events. Can be set to:\n * - `'always'` to always prevent\n * - `'never'` to never prevent\n * - `'auto'` to let interact.js try to determine what would be best\n *\n - newValue (string) #optional `true`, `false` or `'auto'`\n = (string | Interactable) The current setting or this Interactable\n \\*/\n preventDefault: function (newValue) {\n if (/^(always|never|auto)$/.test(newValue)) {\n this.options.preventDefault = newValue;\n return this;\n }\n\n if (isBool(newValue)) {\n this.options.preventDefault = newValue? 'always' : 'never';\n return this;\n }\n\n return this.options.preventDefault;\n },\n\n /*\\\n * Interactable.origin\n [ method ]\n *\n * Gets or sets the origin of the Interactable's element. The x and y\n * of the origin will be subtracted from action event coordinates.\n *\n - origin (object | string) #optional An object eg. { x: 0, y: 0 } or string 'parent', 'self' or any CSS selector\n * OR\n - origin (Element) #optional An HTML or SVG Element whose rect will be used\n **\n = (object) The current origin or this Interactable\n \\*/\n origin: function (newValue) {\n if (trySelector(newValue)) {\n this.options.origin = newValue;\n return this;\n }\n else if (isObject(newValue)) {\n this.options.origin = newValue;\n return this;\n }\n\n return this.options.origin;\n },\n\n /*\\\n * Interactable.deltaSource\n [ method ]\n *\n * Returns or sets the mouse coordinate types used to calculate the\n * movement of the pointer.\n *\n - newValue (string) #optional Use 'client' if you will be scrolling while interacting; Use 'page' if you want autoScroll to work\n = (string | object) The current deltaSource or this Interactable\n \\*/\n deltaSource: function (newValue) {\n if (newValue === 'page' || newValue === 'client') {\n this.options.deltaSource = newValue;\n\n return this;\n }\n\n return this.options.deltaSource;\n },\n\n /*\\\n * Interactable.restrict\n [ method ]\n **\n * Deprecated. Add a `restrict` property to the options object passed to\n * @Interactable.draggable, @Interactable.resizable or @Interactable.gesturable instead.\n *\n * Returns or sets the rectangles within which actions on this\n * interactable (after snap calculations) are restricted. By default,\n * restricting is relative to the pointer coordinates. You can change\n * this by setting the\n * [`elementRect`](https://github.com/taye/interact.js/pull/72).\n **\n - options (object) #optional an object with keys drag, resize, and/or gesture whose values are rects, Elements, CSS selectors, or 'parent' or 'self'\n = (object) The current restrictions object or this Interactable\n **\n | interact(element).restrict({\n | // the rect will be `interact.getElementRect(element.parentNode)`\n | drag: element.parentNode,\n |\n | // x and y are relative to the the interactable's origin\n | resize: { x: 100, y: 100, width: 200, height: 200 }\n | })\n |\n | interact('.draggable').restrict({\n | // the rect will be the selected element's parent\n | drag: 'parent',\n |\n | // do not restrict during normal movement.\n | // Instead, trigger only one restricted move event\n | // immediately before the end event.\n | endOnly: true,\n |\n | // https://github.com/taye/interact.js/pull/72#issue-41813493\n | elementRect: { top: 0, left: 0, bottom: 1, right: 1 }\n | });\n \\*/\n restrict: function (options) {\n if (!isObject(options)) {\n return this.setOptions('restrict', options);\n }\n\n var actions = ['drag', 'resize', 'gesture'],\n ret;\n\n for (var i = 0; i < actions.length; i++) {\n var action = actions[i];\n\n if (action in options) {\n var perAction = extend({\n actions: [action],\n restriction: options[action]\n }, options);\n\n ret = this.setOptions('restrict', perAction);\n }\n }\n\n return ret;\n },\n\n /*\\\n * Interactable.context\n [ method ]\n *\n * Gets the selector context Node of the Interactable. The default is `window.document`.\n *\n = (Node) The context Node of this Interactable\n **\n \\*/\n context: function () {\n return this._context;\n },\n\n _context: document,\n\n /*\\\n * Interactable.ignoreFrom\n [ method ]\n *\n * If the target of the `mousedown`, `pointerdown` or `touchstart`\n * event or any of it's parents match the given CSS selector or\n * Element, no drag/resize/gesture is started.\n *\n - newValue (string | Element | null) #optional a CSS selector string, an Element or `null` to not ignore any elements\n = (string | Element | object) The current ignoreFrom value or this Interactable\n **\n | interact(element, { ignoreFrom: document.getElementById('no-action') });\n | // or\n | interact(element).ignoreFrom('input, textarea, a');\n \\*/\n ignoreFrom: function (newValue) {\n if (trySelector(newValue)) { // CSS selector to match event.target\n this.options.ignoreFrom = newValue;\n return this;\n }\n\n if (isElement(newValue)) { // specific element\n this.options.ignoreFrom = newValue;\n return this;\n }\n\n return this.options.ignoreFrom;\n },\n\n /*\\\n * Interactable.allowFrom\n [ method ]\n *\n * A drag/resize/gesture is started only If the target of the\n * `mousedown`, `pointerdown` or `touchstart` event or any of it's\n * parents match the given CSS selector or Element.\n *\n - newValue (string | Element | null) #optional a CSS selector string, an Element or `null` to allow from any element\n = (string | Element | object) The current allowFrom value or this Interactable\n **\n | interact(element, { allowFrom: document.getElementById('drag-handle') });\n | // or\n | interact(element).allowFrom('.handle');\n \\*/\n allowFrom: function (newValue) {\n if (trySelector(newValue)) { // CSS selector to match event.target\n this.options.allowFrom = newValue;\n return this;\n }\n\n if (isElement(newValue)) { // specific element\n this.options.allowFrom = newValue;\n return this;\n }\n\n return this.options.allowFrom;\n },\n\n /*\\\n * Interactable.element\n [ method ]\n *\n * If this is not a selector Interactable, it returns the element this\n * interactable represents\n *\n = (Element) HTML / SVG Element\n \\*/\n element: function () {\n return this._element;\n },\n\n /*\\\n * Interactable.fire\n [ method ]\n *\n * Calls listeners for the given InteractEvent type bound globally\n * and directly to this Interactable\n *\n - iEvent (InteractEvent) The InteractEvent object to be fired on this Interactable\n = (Interactable) this Interactable\n \\*/\n fire: function (iEvent) {\n if (!(iEvent && iEvent.type) || !contains(eventTypes, iEvent.type)) {\n return this;\n }\n\n var listeners,\n i,\n len,\n onEvent = 'on' + iEvent.type,\n funcName = '';\n\n // Interactable#on() listeners\n if (iEvent.type in this._iEvents) {\n listeners = this._iEvents[iEvent.type];\n\n for (i = 0, len = listeners.length; i < len && !iEvent.immediatePropagationStopped; i++) {\n funcName = listeners[i].name;\n listeners[i](iEvent);\n }\n }\n\n // interactable.onevent listener\n if (isFunction(this[onEvent])) {\n funcName = this[onEvent].name;\n this[onEvent](iEvent);\n }\n\n // interact.on() listeners\n if (iEvent.type in globalEvents && (listeners = globalEvents[iEvent.type])) {\n\n for (i = 0, len = listeners.length; i < len && !iEvent.immediatePropagationStopped; i++) {\n funcName = listeners[i].name;\n listeners[i](iEvent);\n }\n }\n\n return this;\n },\n\n /*\\\n * Interactable.on\n [ method ]\n *\n * Binds a listener for an InteractEvent or DOM event.\n *\n - eventType (string | array | object) The types of events to listen for\n - listener (function) The function to be called on the given event(s)\n - useCapture (boolean) #optional useCapture flag for addEventListener\n = (object) This Interactable\n \\*/\n on: function (eventType, listener, useCapture) {\n var i;\n\n if (isString(eventType) && eventType.search(' ') !== -1) {\n eventType = eventType.trim().split(/ +/);\n }\n\n if (isArray(eventType)) {\n for (i = 0; i < eventType.length; i++) {\n this.on(eventType[i], listener, useCapture);\n }\n\n return this;\n }\n\n if (isObject(eventType)) {\n for (var prop in eventType) {\n this.on(prop, eventType[prop], listener);\n }\n\n return this;\n }\n\n if (eventType === 'wheel') {\n eventType = wheelEvent;\n }\n\n // convert to boolean\n useCapture = useCapture? true: false;\n\n if (contains(eventTypes, eventType)) {\n // if this type of event was never bound to this Interactable\n if (!(eventType in this._iEvents)) {\n this._iEvents[eventType] = [listener];\n }\n else {\n this._iEvents[eventType].push(listener);\n }\n }\n // delegated event for selector\n else if (this.selector) {\n if (!delegatedEvents[eventType]) {\n delegatedEvents[eventType] = {\n selectors: [],\n contexts : [],\n listeners: []\n };\n\n // add delegate listener functions\n for (i = 0; i < documents.length; i++) {\n events.add(documents[i], eventType, delegateListener);\n events.add(documents[i], eventType, delegateUseCapture, true);\n }\n }\n\n var delegated = delegatedEvents[eventType],\n index;\n\n for (index = delegated.selectors.length - 1; index >= 0; index--) {\n if (delegated.selectors[index] === this.selector\n && delegated.contexts[index] === this._context) {\n break;\n }\n }\n\n if (index === -1) {\n index = delegated.selectors.length;\n\n delegated.selectors.push(this.selector);\n delegated.contexts .push(this._context);\n delegated.listeners.push([]);\n }\n\n // keep listener and useCapture flag\n delegated.listeners[index].push([listener, useCapture]);\n }\n else {\n events.add(this._element, eventType, listener, useCapture);\n }\n\n return this;\n },\n\n /*\\\n * Interactable.off\n [ method ]\n *\n * Removes an InteractEvent or DOM event listener\n *\n - eventType (string | array | object) The types of events that were listened for\n - listener (function) The listener function to be removed\n - useCapture (boolean) #optional useCapture flag for removeEventListener\n = (object) This Interactable\n \\*/\n off: function (eventType, listener, useCapture) {\n var i;\n\n if (isString(eventType) && eventType.search(' ') !== -1) {\n eventType = eventType.trim().split(/ +/);\n }\n\n if (isArray(eventType)) {\n for (i = 0; i < eventType.length; i++) {\n this.off(eventType[i], listener, useCapture);\n }\n\n return this;\n }\n\n if (isObject(eventType)) {\n for (var prop in eventType) {\n this.off(prop, eventType[prop], listener);\n }\n\n return this;\n }\n\n var eventList,\n index = -1;\n\n // convert to boolean\n useCapture = useCapture? true: false;\n\n if (eventType === 'wheel') {\n eventType = wheelEvent;\n }\n\n // if it is an action event type\n if (contains(eventTypes, eventType)) {\n eventList = this._iEvents[eventType];\n\n if (eventList && (index = indexOf(eventList, listener)) !== -1) {\n this._iEvents[eventType].splice(index, 1);\n }\n }\n // delegated event\n else if (this.selector) {\n var delegated = delegatedEvents[eventType],\n matchFound = false;\n\n if (!delegated) { return this; }\n\n // count from last index of delegated to 0\n for (index = delegated.selectors.length - 1; index >= 0; index--) {\n // look for matching selector and context Node\n if (delegated.selectors[index] === this.selector\n && delegated.contexts[index] === this._context) {\n\n var listeners = delegated.listeners[index];\n\n // each item of the listeners array is an array: [function, useCaptureFlag]\n for (i = listeners.length - 1; i >= 0; i--) {\n var fn = listeners[i][0],\n useCap = listeners[i][1];\n\n // check if the listener functions and useCapture flags match\n if (fn === listener && useCap === useCapture) {\n // remove the listener from the array of listeners\n listeners.splice(i, 1);\n\n // if all listeners for this interactable have been removed\n // remove the interactable from the delegated arrays\n if (!listeners.length) {\n delegated.selectors.splice(index, 1);\n delegated.contexts .splice(index, 1);\n delegated.listeners.splice(index, 1);\n\n // remove delegate function from context\n events.remove(this._context, eventType, delegateListener);\n events.remove(this._context, eventType, delegateUseCapture, true);\n\n // remove the arrays if they are empty\n if (!delegated.selectors.length) {\n delegatedEvents[eventType] = null;\n }\n }\n\n // only remove one listener\n matchFound = true;\n break;\n }\n }\n\n if (matchFound) { break; }\n }\n }\n }\n // remove listener from this Interatable's element\n else {\n events.remove(this._element, eventType, listener, useCapture);\n }\n\n return this;\n },\n\n /*\\\n * Interactable.set\n [ method ]\n *\n * Reset the options of this Interactable\n - options (object) The new settings to apply\n = (object) This Interactable\n \\*/\n set: function (options) {\n if (!isObject(options)) {\n options = {};\n }\n\n this.options = extend({}, defaultOptions.base);\n\n var i,\n actions = ['drag', 'drop', 'resize', 'gesture'],\n methods = ['draggable', 'dropzone', 'resizable', 'gesturable'],\n perActions = extend(extend({}, defaultOptions.perAction), options[action] || {});\n\n for (i = 0; i < actions.length; i++) {\n var action = actions[i];\n\n this.options[action] = extend({}, defaultOptions[action]);\n\n this.setPerAction(action, perActions);\n\n this[methods[i]](options[action]);\n }\n\n var settings = [\n 'accept', 'actionChecker', 'allowFrom', 'deltaSource',\n 'dropChecker', 'ignoreFrom', 'origin', 'preventDefault',\n 'rectChecker', 'styleCursor'\n ];\n\n for (i = 0, len = settings.length; i < len; i++) {\n var setting = settings[i];\n\n this.options[setting] = defaultOptions.base[setting];\n\n if (setting in options) {\n this[setting](options[setting]);\n }\n }\n\n return this;\n },\n\n /*\\\n * Interactable.unset\n [ method ]\n *\n * Remove this interactable from the list of interactables and remove\n * it's drag, drop, resize and gesture capabilities\n *\n = (object) @interact\n \\*/\n unset: function () {\n events.remove(this._element, 'all');\n\n if (!isString(this.selector)) {\n events.remove(this, 'all');\n if (this.options.styleCursor) {\n this._element.style.cursor = '';\n }\n }\n else {\n // remove delegated events\n for (var type in delegatedEvents) {\n var delegated = delegatedEvents[type];\n\n for (var i = 0; i < delegated.selectors.length; i++) {\n if (delegated.selectors[i] === this.selector\n && delegated.contexts[i] === this._context) {\n\n delegated.selectors.splice(i, 1);\n delegated.contexts .splice(i, 1);\n delegated.listeners.splice(i, 1);\n\n // remove the arrays if they are empty\n if (!delegated.selectors.length) {\n delegatedEvents[type] = null;\n }\n }\n\n events.remove(this._context, type, delegateListener);\n events.remove(this._context, type, delegateUseCapture, true);\n\n break;\n }\n }\n }\n\n this.dropzone(false);\n\n interactables.splice(indexOf(interactables, this), 1);\n\n return interact;\n }\n };\n\n function warnOnce (method, message) {\n var warned = false;\n\n return function () {\n if (!warned) {\n window.console.warn(message);\n warned = true;\n }\n\n return method.apply(this, arguments);\n };\n }\n\n Interactable.prototype.snap = warnOnce(Interactable.prototype.snap,\n 'Interactable#snap is deprecated. See the new documentation for snapping at http://interactjs.io/docs/snapping');\n Interactable.prototype.restrict = warnOnce(Interactable.prototype.restrict,\n 'Interactable#restrict is deprecated. See the new documentation for resticting at http://interactjs.io/docs/restriction');\n Interactable.prototype.inertia = warnOnce(Interactable.prototype.inertia,\n 'Interactable#inertia is deprecated. See the new documentation for inertia at http://interactjs.io/docs/inertia');\n Interactable.prototype.autoScroll = warnOnce(Interactable.prototype.autoScroll,\n 'Interactable#autoScroll is deprecated. See the new documentation for autoScroll at http://interactjs.io/docs/#autoscroll');\n Interactable.prototype.squareResize = warnOnce(Interactable.prototype.squareResize,\n 'Interactable#squareResize is deprecated. See http://interactjs.io/docs/#resize-square');\n\n Interactable.prototype.accept = warnOnce(Interactable.prototype.accept,\n 'Interactable#accept is deprecated. use Interactable#dropzone({ accept: target }) instead');\n Interactable.prototype.dropChecker = warnOnce(Interactable.prototype.dropChecker,\n 'Interactable#dropChecker is deprecated. use Interactable#dropzone({ dropChecker: checkerFunction }) instead');\n Interactable.prototype.context = warnOnce(Interactable.prototype.context,\n 'Interactable#context as a method is deprecated. It will soon be a DOM Node instead');\n\n /*\\\n * interact.isSet\n [ method ]\n *\n * Check if an element has been set\n - element (Element) The Element being searched for\n = (boolean) Indicates if the element or CSS selector was previously passed to interact\n \\*/\n interact.isSet = function(element, options) {\n return interactables.indexOfElement(element, options && options.context) !== -1;\n };\n\n /*\\\n * interact.on\n [ method ]\n *\n * Adds a global listener for an InteractEvent or adds a DOM event to\n * `document`\n *\n - type (string | array | object) The types of events to listen for\n - listener (function) The function to be called on the given event(s)\n - useCapture (boolean) #optional useCapture flag for addEventListener\n = (object) interact\n \\*/\n interact.on = function (type, listener, useCapture) {\n if (isString(type) && type.search(' ') !== -1) {\n type = type.trim().split(/ +/);\n }\n\n if (isArray(type)) {\n for (var i = 0; i < type.length; i++) {\n interact.on(type[i], listener, useCapture);\n }\n\n return interact;\n }\n\n if (isObject(type)) {\n for (var prop in type) {\n interact.on(prop, type[prop], listener);\n }\n\n return interact;\n }\n\n // if it is an InteractEvent type, add listener to globalEvents\n if (contains(eventTypes, type)) {\n // if this type of event was never bound\n if (!globalEvents[type]) {\n globalEvents[type] = [listener];\n }\n else {\n globalEvents[type].push(listener);\n }\n }\n // If non InteractEvent type, addEventListener to document\n else {\n events.add(document, type, listener, useCapture);\n }\n\n return interact;\n };\n\n /*\\\n * interact.off\n [ method ]\n *\n * Removes a global InteractEvent listener or DOM event from `document`\n *\n - type (string | array | object) The types of events that were listened for\n - listener (function) The listener function to be removed\n - useCapture (boolean) #optional useCapture flag for removeEventListener\n = (object) interact\n \\*/\n interact.off = function (type, listener, useCapture) {\n if (isString(type) && type.search(' ') !== -1) {\n type = type.trim().split(/ +/);\n }\n\n if (isArray(type)) {\n for (var i = 0; i < type.length; i++) {\n interact.off(type[i], listener, useCapture);\n }\n\n return interact;\n }\n\n if (isObject(type)) {\n for (var prop in type) {\n interact.off(prop, type[prop], listener);\n }\n\n return interact;\n }\n\n if (!contains(eventTypes, type)) {\n events.remove(document, type, listener, useCapture);\n }\n else {\n var index;\n\n if (type in globalEvents\n && (index = indexOf(globalEvents[type], listener)) !== -1) {\n globalEvents[type].splice(index, 1);\n }\n }\n\n return interact;\n };\n\n /*\\\n * interact.enableDragging\n [ method ]\n *\n * Deprecated.\n *\n * Returns or sets whether dragging is enabled for any Interactables\n *\n - newValue (boolean) #optional `true` to allow the action; `false` to disable action for all Interactables\n = (boolean | object) The current setting or interact\n \\*/\n interact.enableDragging = warnOnce(function (newValue) {\n if (newValue !== null && newValue !== undefined) {\n actionIsEnabled.drag = newValue;\n\n return interact;\n }\n return actionIsEnabled.drag;\n }, 'interact.enableDragging is deprecated and will soon be removed.');\n\n /*\\\n * interact.enableResizing\n [ method ]\n *\n * Deprecated.\n *\n * Returns or sets whether resizing is enabled for any Interactables\n *\n - newValue (boolean) #optional `true` to allow the action; `false` to disable action for all Interactables\n = (boolean | object) The current setting or interact\n \\*/\n interact.enableResizing = warnOnce(function (newValue) {\n if (newValue !== null && newValue !== undefined) {\n actionIsEnabled.resize = newValue;\n\n return interact;\n }\n return actionIsEnabled.resize;\n }, 'interact.enableResizing is deprecated and will soon be removed.');\n\n /*\\\n * interact.enableGesturing\n [ method ]\n *\n * Deprecated.\n *\n * Returns or sets whether gesturing is enabled for any Interactables\n *\n - newValue (boolean) #optional `true` to allow the action; `false` to disable action for all Interactables\n = (boolean | object) The current setting or interact\n \\*/\n interact.enableGesturing = warnOnce(function (newValue) {\n if (newValue !== null && newValue !== undefined) {\n actionIsEnabled.gesture = newValue;\n\n return interact;\n }\n return actionIsEnabled.gesture;\n }, 'interact.enableGesturing is deprecated and will soon be removed.');\n\n interact.eventTypes = eventTypes;\n\n /*\\\n * interact.debug\n [ method ]\n *\n * Returns debugging data\n = (object) An object with properties that outline the current state and expose internal functions and variables\n \\*/\n interact.debug = function () {\n var interaction = interactions[0] || new Interaction();\n\n return {\n interactions : interactions,\n target : interaction.target,\n dragging : interaction.dragging,\n resizing : interaction.resizing,\n gesturing : interaction.gesturing,\n prepared : interaction.prepared,\n matches : interaction.matches,\n matchElements : interaction.matchElements,\n\n prevCoords : interaction.prevCoords,\n startCoords : interaction.startCoords,\n\n pointerIds : interaction.pointerIds,\n pointers : interaction.pointers,\n addPointer : listeners.addPointer,\n removePointer : listeners.removePointer,\n recordPointer : listeners.recordPointer,\n\n snap : interaction.snapStatus,\n restrict : interaction.restrictStatus,\n inertia : interaction.inertiaStatus,\n\n downTime : interaction.downTimes[0],\n downEvent : interaction.downEvent,\n downPointer : interaction.downPointer,\n prevEvent : interaction.prevEvent,\n\n Interactable : Interactable,\n interactables : interactables,\n pointerIsDown : interaction.pointerIsDown,\n defaultOptions : defaultOptions,\n defaultActionChecker : defaultActionChecker,\n\n actionCursors : actionCursors,\n dragMove : listeners.dragMove,\n resizeMove : listeners.resizeMove,\n gestureMove : listeners.gestureMove,\n pointerUp : listeners.pointerUp,\n pointerDown : listeners.pointerDown,\n pointerMove : listeners.pointerMove,\n pointerHover : listeners.pointerHover,\n\n eventTypes : eventTypes,\n\n events : events,\n globalEvents : globalEvents,\n delegatedEvents : delegatedEvents,\n\n prefixedPropREs : prefixedPropREs\n };\n };\n\n // expose the functions used to calculate multi-touch properties\n interact.getPointerAverage = pointerAverage;\n interact.getTouchBBox = touchBBox;\n interact.getTouchDistance = touchDistance;\n interact.getTouchAngle = touchAngle;\n\n interact.getElementRect = getElementRect;\n interact.getElementClientRect = getElementClientRect;\n interact.matchesSelector = matchesSelector;\n interact.closest = closest;\n\n /*\\\n * interact.margin\n [ method ]\n *\n * Deprecated. Use `interact(target).resizable({ margin: number });` instead.\n * Returns or sets the margin for autocheck resizing used in\n * @Interactable.getAction. That is the distance from the bottom and right\n * edges of an element clicking in which will start resizing\n *\n - newValue (number) #optional\n = (number | interact) The current margin value or interact\n \\*/\n interact.margin = warnOnce(function (newvalue) {\n if (isNumber(newvalue)) {\n margin = newvalue;\n\n return interact;\n }\n return margin;\n },\n 'interact.margin is deprecated. Use interact(target).resizable({ margin: number }); instead.') ;\n\n /*\\\n * interact.supportsTouch\n [ method ]\n *\n = (boolean) Whether or not the browser supports touch input\n \\*/\n interact.supportsTouch = function () {\n return supportsTouch;\n };\n\n /*\\\n * interact.supportsPointerEvent\n [ method ]\n *\n = (boolean) Whether or not the browser supports PointerEvents\n \\*/\n interact.supportsPointerEvent = function () {\n return supportsPointerEvent;\n };\n\n /*\\\n * interact.stop\n [ method ]\n *\n * Cancels all interactions (end events are not fired)\n *\n - event (Event) An event on which to call preventDefault()\n = (object) interact\n \\*/\n interact.stop = function (event) {\n for (var i = interactions.length - 1; i >= 0; i--) {\n interactions[i].stop(event);\n }\n\n return interact;\n };\n\n /*\\\n * interact.dynamicDrop\n [ method ]\n *\n * Returns or sets whether the dimensions of dropzone elements are\n * calculated on every dragmove or only on dragstart for the default\n * dropChecker\n *\n - newValue (boolean) #optional True to check on each move. False to check only before start\n = (boolean | interact) The current setting or interact\n \\*/\n interact.dynamicDrop = function (newValue) {\n if (isBool(newValue)) {\n //if (dragging && dynamicDrop !== newValue && !newValue) {\n //calcRects(dropzones);\n //}\n\n dynamicDrop = newValue;\n\n return interact;\n }\n return dynamicDrop;\n };\n\n /*\\\n * interact.pointerMoveTolerance\n [ method ]\n * Returns or sets the distance the pointer must be moved before an action\n * sequence occurs. This also affects tolerance for tap events.\n *\n - newValue (number) #optional The movement from the start position must be greater than this value\n = (number | Interactable) The current setting or interact\n \\*/\n interact.pointerMoveTolerance = function (newValue) {\n if (isNumber(newValue)) {\n pointerMoveTolerance = newValue;\n\n return this;\n }\n\n return pointerMoveTolerance;\n };\n\n /*\\\n * interact.maxInteractions\n [ method ]\n **\n * Returns or sets the maximum number of concurrent interactions allowed.\n * By default only 1 interaction is allowed at a time (for backwards\n * compatibility). To allow multiple interactions on the same Interactables\n * and elements, you need to enable it in the draggable, resizable and\n * gesturable `'max'` and `'maxPerElement'` options.\n **\n - newValue (number) #optional Any number. newValue <= 0 means no interactions.\n \\*/\n interact.maxInteractions = function (newValue) {\n if (isNumber(newValue)) {\n maxInteractions = newValue;\n\n return this;\n }\n\n return maxInteractions;\n };\n\n interact.createSnapGrid = function (grid) {\n return function (x, y) {\n var offsetX = 0,\n offsetY = 0;\n\n if (isObject(grid.offset)) {\n offsetX = grid.offset.x;\n offsetY = grid.offset.y;\n }\n\n var gridx = Math.round((x - offsetX) / grid.x),\n gridy = Math.round((y - offsetY) / grid.y),\n\n newX = gridx * grid.x + offsetX,\n newY = gridy * grid.y + offsetY;\n\n return {\n x: newX,\n y: newY,\n range: grid.range\n };\n };\n };\n\n function endAllInteractions (event) {\n for (var i = 0; i < interactions.length; i++) {\n interactions[i].pointerEnd(event, event);\n }\n }\n\n function listenToDocument (doc) {\n if (contains(documents, doc)) { return; }\n\n var win = doc.defaultView || doc.parentWindow;\n\n // add delegate event listener\n for (var eventType in delegatedEvents) {\n events.add(doc, eventType, delegateListener);\n events.add(doc, eventType, delegateUseCapture, true);\n }\n\n if (supportsPointerEvent) {\n if (PointerEvent === win.MSPointerEvent) {\n pEventTypes = {\n up: 'MSPointerUp', down: 'MSPointerDown', over: 'mouseover',\n out: 'mouseout', move: 'MSPointerMove', cancel: 'MSPointerCancel' };\n }\n else {\n pEventTypes = {\n up: 'pointerup', down: 'pointerdown', over: 'pointerover',\n out: 'pointerout', move: 'pointermove', cancel: 'pointercancel' };\n }\n\n events.add(doc, pEventTypes.down , listeners.selectorDown );\n events.add(doc, pEventTypes.move , listeners.pointerMove );\n events.add(doc, pEventTypes.over , listeners.pointerOver );\n events.add(doc, pEventTypes.out , listeners.pointerOut );\n events.add(doc, pEventTypes.up , listeners.pointerUp );\n events.add(doc, pEventTypes.cancel, listeners.pointerCancel);\n\n // autoscroll\n events.add(doc, pEventTypes.move, listeners.autoScrollMove);\n }\n else {\n events.add(doc, 'mousedown', listeners.selectorDown);\n events.add(doc, 'mousemove', listeners.pointerMove );\n events.add(doc, 'mouseup' , listeners.pointerUp );\n events.add(doc, 'mouseover', listeners.pointerOver );\n events.add(doc, 'mouseout' , listeners.pointerOut );\n\n events.add(doc, 'touchstart' , listeners.selectorDown );\n events.add(doc, 'touchmove' , listeners.pointerMove );\n events.add(doc, 'touchend' , listeners.pointerUp );\n events.add(doc, 'touchcancel', listeners.pointerCancel);\n\n // autoscroll\n events.add(doc, 'mousemove', listeners.autoScrollMove);\n events.add(doc, 'touchmove', listeners.autoScrollMove);\n }\n\n events.add(win, 'blur', endAllInteractions);\n\n try {\n if (win.frameElement) {\n var parentDoc = win.frameElement.ownerDocument,\n parentWindow = parentDoc.defaultView;\n\n events.add(parentDoc , 'mouseup' , listeners.pointerEnd);\n events.add(parentDoc , 'touchend' , listeners.pointerEnd);\n events.add(parentDoc , 'touchcancel' , listeners.pointerEnd);\n events.add(parentDoc , 'pointerup' , listeners.pointerEnd);\n events.add(parentDoc , 'MSPointerUp' , listeners.pointerEnd);\n events.add(parentWindow, 'blur' , endAllInteractions );\n }\n }\n catch (error) {\n interact.windowParentError = error;\n }\n\n // prevent native HTML5 drag on interact.js target elements\n events.add(doc, 'dragstart', function (event) {\n for (var i = 0; i < interactions.length; i++) {\n var interaction = interactions[i];\n\n if (interaction.element\n && (interaction.element === event.target\n || nodeContains(interaction.element, event.target))) {\n\n interaction.checkAndPreventDefault(event, interaction.target, interaction.element);\n return;\n }\n }\n });\n\n if (events.useAttachEvent) {\n // For IE's lack of Event#preventDefault\n events.add(doc, 'selectstart', function (event) {\n var interaction = interactions[0];\n\n if (interaction.currentAction()) {\n interaction.checkAndPreventDefault(event);\n }\n });\n\n // For IE's bad dblclick event sequence\n events.add(doc, 'dblclick', doOnInteractions('ie8Dblclick'));\n }\n\n documents.push(doc);\n }\n\n listenToDocument(document);\n\n function indexOf (array, target) {\n for (var i = 0, len = array.length; i < len; i++) {\n if (array[i] === target) {\n return i;\n }\n }\n\n return -1;\n }\n\n function contains (array, target) {\n return indexOf(array, target) !== -1;\n }\n\n function matchesSelector (element, selector, nodeList) {\n if (ie8MatchesSelector) {\n return ie8MatchesSelector(element, selector, nodeList);\n }\n\n // remove /deep/ from selectors if shadowDOM polyfill is used\n if (window !== realWindow) {\n selector = selector.replace(/\\/deep\\//g, ' ');\n }\n\n return element[prefixedMatchesSelector](selector);\n }\n\n function matchesUpTo (element, selector, limit) {\n while (isElement(element)) {\n if (matchesSelector(element, selector)) {\n return true;\n }\n\n element = parentElement(element);\n\n if (element === limit) {\n return matchesSelector(element, selector);\n }\n }\n\n return false;\n }\n\n // For IE8's lack of an Element#matchesSelector\n // taken from http://tanalin.com/en/blog/2012/12/matches-selector-ie8/ and modified\n if (!(prefixedMatchesSelector in Element.prototype) || !isFunction(Element.prototype[prefixedMatchesSelector])) {\n ie8MatchesSelector = function (element, selector, elems) {\n elems = elems || element.parentNode.querySelectorAll(selector);\n\n for (var i = 0, len = elems.length; i < len; i++) {\n if (elems[i] === element) {\n return true;\n }\n }\n\n return false;\n };\n }\n\n // requestAnimationFrame polyfill\n (function() {\n var lastTime = 0,\n vendors = ['ms', 'moz', 'webkit', 'o'];\n\n for(var x = 0; x < vendors.length && !realWindow.requestAnimationFrame; ++x) {\n reqFrame = realWindow[vendors[x]+'RequestAnimationFrame'];\n cancelFrame = realWindow[vendors[x]+'CancelAnimationFrame'] || realWindow[vendors[x]+'CancelRequestAnimationFrame'];\n }\n\n if (!reqFrame) {\n reqFrame = function(callback) {\n var currTime = new Date().getTime(),\n timeToCall = Math.max(0, 16 - (currTime - lastTime)),\n id = setTimeout(function() { callback(currTime + timeToCall); },\n timeToCall);\n lastTime = currTime + timeToCall;\n return id;\n };\n }\n\n if (!cancelFrame) {\n cancelFrame = function(id) {\n clearTimeout(id);\n };\n }\n }());\n\n /* global exports: true, module, define */\n\n // http://documentcloud.github.io/underscore/docs/underscore.html#section-11\n if (true) {\n if (typeof module !== 'undefined' && module.exports) {\n exports = module.exports = interact;\n }\n exports.interact = interact;\n }\n // AMD\n else if (typeof define === 'function' && define.amd) {\n define('interact', function() {\n return interact;\n });\n }\n else {\n realWindow.interact = interact;\n }\n\n} (typeof window === 'undefined'? undefined : window));\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9+L2ludGVyYWN0LmpzL2ludGVyYWN0LmpzPzNjMjMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0Esc0JBQXNCLFFBQVE7O0FBRTlCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxTQUFTOztBQUVUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLCtDQUErQyxpQ0FBaUMsRUFBRTs7QUFFbEYsa0JBQWtCOztBQUVsQjs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCOztBQUU1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUMsYUFBYTtBQUM5QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsYUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7O0FBRWI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxhQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0EsU0FBUzs7QUFFVDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7O0FBRVQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHlCQUF5Qjs7QUFFekI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esa0NBQWtDO0FBQ2xDO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxtQ0FBbUMsU0FBUztBQUM1QztBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckIsbUNBQW1DLFNBQVM7QUFDNUM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7O0FBRVQ7O0FBRUE7QUFDQSw0Q0FBNEMsY0FBYzs7QUFFMUQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQkFBK0IseUZBQXlGO0FBQ3hILGdDQUFnQyxxREFBcUQ7QUFDckY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQywrQ0FBK0M7QUFDaEYsaUNBQWlDLG9DQUFvQztBQUNyRSxpQ0FBaUMsb0NBQW9DO0FBQ3JFLGlDQUFpQyxvQ0FBb0M7QUFDckUsaUNBQWlDLG9DQUFvQzs7QUFFckU7QUFDQSwrQkFBK0IsY0FBYzs7QUFFN0M7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHVCQUF1QixxQkFBcUI7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0RBQWtEO0FBQ2xEOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLG9EQUFvRCxlQUFlOztBQUVuRTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztB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QTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLDZDQUE2Qyx1Q0FBdUMsRUFBRTtBQUN0Riw2Q0FBNkMsdUNBQXVDLEVBQUU7QUFDdEYsNkNBQTZDLHVDQUF1QyxFQUFFOztBQUV0RjtBQUNBLG9EQUFvRCxRQUFROztBQUU1RDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTOztBQUVUO0FBQ0EscUNBQXFDLFFBQVE7O0FBRTdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxTQUFTOztBQUVUO0FBQ0E7QUFDQTtBQUNBLDREQUE0RDtBQUM1RDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGFBQWE7O0FBRWI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztB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RCw2REFBNkQsVUFBVTs7QUFFdkU7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsMERBQTBELFNBQVM7QUFDbkU7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsdUJBQXVCLHVDQUF1QztBQUM5RDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTOztBQUVUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsMkJBQTJCLHVDQUF1QztBQUNsRTtBQUNBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDJCQUEyQix1Q0FBdUM7QUFDbEU7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxTQUFTOztBQUVUO0FBQ0E7QUFDQSxTQUFTOztBQUVUO0FBQ0E7QUFDQSxTQUFTOztBQUVUO0FBQ0E7O0FBRUE7QUFDQSxTQUFTOztBQUVUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDJCQUEyQiwwQkFBMEI7QUFDckQ7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTOztBQUVUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7O0FBRVQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBO0FBQ0E7O0FBRUEsK0JBQStCLFFBQVE7O0FBRXZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTOztBQUVUO0FBQ0E7O0FBRUEsK0JBQStCLFFBQVE7O0FBRXZDO0FBQ0EsU0FBUzs7QUFFVDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBO0FBQ0EsaUNBQWlDO0FBQ2pDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUEsdUJBQXVCLG9CQUFvQjtBQUMzQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7O0FBRVQ7QUFDQSxpREFBaUQsU0FBUztBQUMxRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7O0FBRVQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0Esd0JBQXdCO0FBQ3hCO0FBQ0E7QUFDQTs7QUFFQSxnQ0FBZ0M7O0FBRWhDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUEsa0NBQWtDLG9DQUFvQztBQUN0RTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSwyQkFBMkIsU0FBUztBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsa0NBQWtDLFVBQVU7O0FBRTVDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsNkNBQTZDLFNBQVM7QUFDdEQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxTQUFTOztBQUVUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsOEJBQThCO0FBQzlCLHNDQUFzQzs7QUFFdEM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsbUNBQW1DLGVBQWU7QUFDbEQ7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxTQUFTOztBQUVUO0FBQ0EsZ0VBQWdFLFFBQVE7O0FBRXhFO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTOztBQUVUO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLHVCQUF1QixTQUFTO0FBQ2hDOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsdUJBQXVCLFNBQVM7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLFNBQVM7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxtQkFBbUIsU0FBUztBQUM1QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLG1CQUFtQixTQUFTO0FBQzVCOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsMkJBQTJCLGlDQUFpQztBQUM1RDs7QUFFQTs7QUFFQSx1Q0FBdUMsVUFBVTs7QUFFakQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0JBQStCLHlCQUF5QjtBQUN4RDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsbUNBQW1DLFFBQVE7O0FBRTNDOztBQUVBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLDBCQUEwQjtBQUMxQiwwQkFBMEI7O0FBRTFCO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNB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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxTQUFTOztBQUVUO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFNBQVM7O0FBRVQ7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrREFBa0QsdUJBQXVCO0FBQ3pFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0RBQW9EO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxTQUFTOztBQUVUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxTQUFTOztBQUVUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkNBQTJDO0FBQzNDLDJDQUEyQztBQUMzQywyQ0FBMkM7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7O0FBRVQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJDQUEyQztBQUMzQywyQ0FBMkM7QUFDM0MsMkNBQTJDO0FBQzNDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtDQUFrQyw2QkFBNkI7QUFDL0Q7QUFDQTtBQUNBLDJCQUEyQjtBQUMzQjs7QUFFQTtBQUNBLFNBQVM7O0FBRVQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMERBQTBEO0FBQzFEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsY0FBYztBQUM5QyxvQkFBb0I7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsYUFBYTtBQUNqQyxvQkFBb0IsYUFBYTtBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QjtBQUN4QjtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7O0FBRUEsK0JBQStCLGFBQWE7O0FBRTVDO0FBQ0EsU0FBUzs7QUFFVDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLDJCQUEyQixvQkFBb0I7QUFDL0M7O0FBRUEsMERBQTBELFVBQVU7O0FBRXBFOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBFQUEwRTtBQUMxRSxxQ0FBcUMsdUJBQXVCO0FBQzVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsd0JBQXdCO0FBQ3hCOztBQUVBLHVCQUF1Qix1QkFBdUI7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxTQUFTOzs7QUFHVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2REFBNkQ7QUFDN0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCO0FBQzFCO0FBQ0E7QUFDQSwwQkFBMEI7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSwrQkFBK0IsYUFBYTs7QUFFNUM7QUFDQSxTQUFTOztBQUVUO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsU0FBUzs7QUFFVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtCQUErQjtBQUMvQjtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxTQUFTOztBQUVUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLFNBQVM7O0FBRVQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLFNBQVM7O0FBRVQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7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O0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0RBQStEO0FBQy9EO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0RBQStEO0FBQy9EO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9EQUFvRCxpQkFBaUIsRUFBRTtBQUN2RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsb0VBQW9FLGlCQUFpQixFQUFFOztBQUV2RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkNBQTZDLFFBQVE7QUFDckQ7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSx1QkFBdUIseUJBQXlCO0FBQ2hEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHVDQUF1QyxRQUFROztBQUUvQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSwyQkFBMkIseUJBQXlCO0FBQ3BEOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7O0FBRVQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsYUFBYTs7QUFFYjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLDJDQUEyQyxTQUFTO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsK0NBQStDLFNBQVM7QUFDeEQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHNCQUFzQix5REFBeUQ7QUFDL0U7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0RBQWdELGlDQUFpQyxFQUFFO0FBQ25GO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxDQUFDIiwiZmlsZSI6IjI5LmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBpbnRlcmFjdC5qcyB2MS4yLjhcbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTItMjAxNSBUYXllIEFkZXllbWkgPGRldkB0YXllLm1lPlxuICogT3BlbiBzb3VyY2UgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuICogaHR0cHM6Ly9yYXcuZ2l0aHViLmNvbS90YXllL2ludGVyYWN0LmpzL21hc3Rlci9MSUNFTlNFXG4gKi9cbihmdW5jdGlvbiAocmVhbFdpbmRvdykge1xuICAgICd1c2Ugc3RyaWN0JztcblxuICAgIC8vIHJldHVybiBlYXJseSBpZiB0aGVyZSdzIG5vIHdpbmRvdyB0byB3b3JrIHdpdGggKGVnLiBOb2RlLmpzKVxuICAgIGlmICghcmVhbFdpbmRvdykgeyByZXR1cm47IH1cblxuICAgIHZhciAvLyBnZXQgd3JhcHBlZCB3aW5kb3cgaWYgdXNpbmcgU2hhZG93IERPTSBwb2x5ZmlsbFxuICAgICAgICB3aW5kb3cgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgLy8gY3JlYXRlIGEgVGV4dE5vZGVcbiAgICAgICAgICAgIHZhciBlbCA9IHJlYWxXaW5kb3cuZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoJycpO1xuXG4gICAgICAgICAgICAvLyBjaGVjayBpZiBpdCdzIHdyYXBwZWQgYnkgYSBwb2x5ZmlsbFxuICAgICAgICAgICAgaWYgKGVsLm93bmVyRG9jdW1lbnQgIT09IHJlYWxXaW5kb3cuZG9jdW1lbnRcbiAgICAgICAgICAgICAgICAmJiB0eXBlb2YgcmVhbFdpbmRvdy53cmFwID09PSAnZnVuY3Rpb24nXG4gICAgICAgICAgICAgICAgJiYgcmVhbFdpbmRvdy53cmFwKGVsKSA9PT0gZWwpIHtcbiAgICAgICAgICAgICAgICAvLyByZXR1cm4gd3JhcHBlZCB3aW5kb3dcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVhbFdpbmRvdy53cmFwKHJlYWxXaW5kb3cpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBubyBTaGFkb3cgRE9NIHBvbHlmaWwgb3IgbmF0aXZlIGltcGxlbWVudGF0aW9uXG4gICAgICAgICAgICByZXR1cm4gcmVhbFdpbmRvdztcbiAgICAgICAgfSgpKSxcblxuICAgICAgICBkb2N1bWVudCAgICAgICAgICAgPSB3aW5kb3cuZG9jdW1lbnQsXG4gICAgICAgIERvY3VtZW50RnJhZ21lbnQgICA9IHdpbmRvdy5Eb2N1bWVudEZyYWdtZW50ICAgfHwgYmxhbmssXG4gICAgICAgIFNWR0VsZW1lbnQgICAgICAgICA9IHdpbmRvdy5TVkdFbGVtZW50ICAgICAgICAgfHwgYmxhbmssXG4gICAgICAgIFNWR1NWR0VsZW1lbnQgICAgICA9IHdpbmRvdy5TVkdTVkdFbGVtZW50ICAgICAgfHwgYmxhbmssXG4gICAgICAgIFNWR0VsZW1lbnRJbnN0YW5jZSA9IHdpbmRvdy5TVkdFbGVtZW50SW5zdGFuY2UgfHwgYmxhbmssXG4gICAgICAgIEhUTUxFbGVtZW50ICAgICAgICA9IHdpbmRvdy5IVE1MRWxlbWVudCAgICAgICAgfHwgd2luZG93LkVsZW1lbnQsXG5cbiAgICAgICAgUG9pbnRlckV2ZW50ID0gKHdpbmRvdy5Qb2ludGVyRXZlbnQgfHwgd2luZG93Lk1TUG9pbnRlckV2ZW50KSxcbiAgICAgICAgcEV2ZW50VHlwZXMsXG5cbiAgICAgICAgaHlwb3QgPSBNYXRoLmh5cG90IHx8IGZ1bmN0aW9uICh4LCB5KSB7IHJldHVybiBNYXRoLnNxcnQoeCAqIHggKyB5ICogeSk7IH0sXG5cbiAgICAgICAgdG1wWFkgPSB7fSwgICAgIC8vIHJlZHVjZSBvYmplY3QgY3JlYXRpb24gaW4gZ2V0WFkoKVxuXG4gICAgICAgIGRvY3VtZW50cyAgICAgICA9IFtdLCAgIC8vIGFsbCBkb2N1bWVudHMgYmVpbmcgbGlzdGVuZWQgdG9cblxuICAgICAgICBpbnRlcmFjdGFibGVzICAgPSBbXSwgICAvLyBhbGwgc2V0IGludGVyYWN0YWJsZXNcbiAgICAgICAgaW50ZXJhY3Rpb25zICAgID0gW10sICAgLy8gYWxsIGludGVyYWN0aW9uc1xuXG4gICAgICAgIGR5bmFtaWNEcm9wICAgICA9IGZhbHNlLFxuXG4gICAgICAgIC8vIHtcbiAgICAgICAgLy8gICAgICB0eXBlOiB7XG4gICAgICAgIC8vICAgICAgICAgIHNlbGVjdG9yczogWydzZWxlY3RvcicsIC4uLl0sXG4gICAgICAgIC8vICAgICAgICAgIGNvbnRleHRzIDogW2RvY3VtZW50LCAuLi5dLFxuICAgICAgICAvLyAgICAgICAgICBsaXN0ZW5lcnM6IFtbbGlzdGVuZXIsIHVzZUNhcHR1cmVdLCAuLi5dXG4gICAgICAgIC8vICAgICAgfVxuICAgICAgICAvLyAgfVxuICAgICAgICBkZWxlZ2F0ZWRFdmVudHMgPSB7fSxcblxuICAgICAgICBkZWZhdWx0T3B0aW9ucyA9IHtcbiAgICAgICAgICAgIGJhc2U6IHtcbiAgICAgICAgICAgICAgICBhY2NlcHQgICAgICAgIDogbnVsbCxcbiAgICAgICAgICAgICAgICBhY3Rpb25DaGVja2VyIDogbnVsbCxcbiAgICAgICAgICAgICAgICBzdHlsZUN1cnNvciAgIDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBwcmV2ZW50RGVmYXVsdDogJ2F1dG8nLFxuICAgICAgICAgICAgICAgIG9yaWdpbiAgICAgICAgOiB7IHg6IDAsIHk6IDAgfSxcbiAgICAgICAgICAgICAgICBkZWx0YVNvdXJjZSAgIDogJ3BhZ2UnLFxuICAgICAgICAgICAgICAgIGFsbG93RnJvbSAgICAgOiBudWxsLFxuICAgICAgICAgICAgICAgIGlnbm9yZUZyb20gICAgOiBudWxsLFxuICAgICAgICAgICAgICAgIF9jb250ZXh0ICAgICAgOiBkb2N1bWVudCxcbiAgICAgICAgICAgICAgICBkcm9wQ2hlY2tlciAgIDogbnVsbFxuICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgZHJhZzoge1xuICAgICAgICAgICAgICAgIGVuYWJsZWQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgIG1hbnVhbFN0YXJ0OiB0cnVlLFxuICAgICAgICAgICAgICAgIG1heDogSW5maW5pdHksXG4gICAgICAgICAgICAgICAgbWF4UGVyRWxlbWVudDogMSxcblxuICAgICAgICAgICAgICAgIHNuYXA6IG51bGwsXG4gICAgICAgICAgICAgICAgcmVzdHJpY3Q6IG51bGwsXG4gICAgICAgICAgICAgICAgaW5lcnRpYTogbnVsbCxcbiAgICAgICAgICAgICAgICBhdXRvU2Nyb2xsOiBudWxsLFxuXG4gICAgICAgICAgICAgICAgYXhpczogJ3h5J1xuICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgZHJvcDoge1xuICAgICAgICAgICAgICAgIGVuYWJsZWQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGFjY2VwdDogbnVsbCxcbiAgICAgICAgICAgICAgICBvdmVybGFwOiAncG9pbnRlcidcbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIHJlc2l6ZToge1xuICAgICAgICAgICAgICAgIGVuYWJsZWQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgIG1hbnVhbFN0YXJ0OiBmYWxzZSxcbiAgICAgICAgICAgICAgICBtYXg6IEluZmluaXR5LFxuICAgICAgICAgICAgICAgIG1heFBlckVsZW1lbnQ6IDEsXG5cbiAgICAgICAgICAgICAgICBzbmFwOiBudWxsLFxuICAgICAgICAgICAgICAgIHJlc3RyaWN0OiBudWxsLFxuICAgICAgICAgICAgICAgIGluZXJ0aWE6IG51bGwsXG4gICAgICAgICAgICAgICAgYXV0b1Njcm9sbDogbnVsbCxcblxuICAgICAgICAgICAgICAgIHNxdWFyZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgcHJlc2VydmVBc3BlY3RSYXRpbzogZmFsc2UsXG4gICAgICAgICAgICAgICAgYXhpczogJ3h5JyxcblxuICAgICAgICAgICAgICAgIC8vIHVzZSBkZWZhdWx0IG1hcmdpblxuICAgICAgICAgICAgICAgIG1hcmdpbjogTmFOLFxuXG4gICAgICAgICAgICAgICAgLy8gb2JqZWN0IHdpdGggcHJvcHMgbGVmdCwgcmlnaHQsIHRvcCwgYm90dG9tIHdoaWNoIGFyZVxuICAgICAgICAgICAgICAgIC8vIHRydWUvZmFsc2UgdmFsdWVzIHRvIHJlc2l6ZSB3aGVuIHRoZSBwb2ludGVyIGlzIG92ZXIgdGhhdCBlZGdlLFxuICAgICAgICAgICAgICAgIC8vIENTUyBzZWxlY3RvcnMgdG8gbWF0Y2ggdGhlIGhhbmRsZXMgZm9yIGVhY2ggZGlyZWN0aW9uXG4gICAgICAgICAgICAgICAgLy8gb3IgdGhlIEVsZW1lbnRzIGZvciBlYWNoIGhhbmRsZVxuICAgICAgICAgICAgICAgIGVkZ2VzOiBudWxsLFxuXG4gICAgICAgICAgICAgICAgLy8gYSB2YWx1ZSBvZiAnbm9uZScgd2lsbCBsaW1pdCB0aGUgcmVzaXplIHJlY3QgdG8gYSBtaW5pbXVtIG9mIDB4MFxuICAgICAgICAgICAgICAgIC8vICduZWdhdGUnIHdpbGwgYWxvdyB0aGUgcmVjdCB0byBoYXZlIG5lZ2F0aXZlIHdpZHRoL2hlaWdodFxuICAgICAgICAgICAgICAgIC8vICdyZXBvc2l0aW9uJyB3aWxsIGtlZXAgdGhlIHdpZHRoL2hlaWdodCBwb3NpdGl2ZSBieSBzd2FwcGluZ1xuICAgICAgICAgICAgICAgIC8vIHRoZSB0b3AgYW5kIGJvdHRvbSBlZGdlcyBhbmQvb3Igc3dhcHBpbmcgdGhlIGxlZnQgYW5kIHJpZ2h0IGVkZ2VzXG4gICAgICAgICAgICAgICAgaW52ZXJ0OiAnbm9uZSdcbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIGdlc3R1cmU6IHtcbiAgICAgICAgICAgICAgICBtYW51YWxTdGFydDogZmFsc2UsXG4gICAgICAgICAgICAgICAgZW5hYmxlZDogZmFsc2UsXG4gICAgICAgICAgICAgICAgbWF4OiBJbmZpbml0eSxcbiAgICAgICAgICAgICAgICBtYXhQZXJFbGVtZW50OiAxLFxuXG4gICAgICAgICAgICAgICAgcmVzdHJpY3Q6IG51bGxcbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIHBlckFjdGlvbjoge1xuICAgICAgICAgICAgICAgIG1hbnVhbFN0YXJ0OiBmYWxzZSxcbiAgICAgICAgICAgICAgICBtYXg6IEluZmluaXR5LFxuICAgICAgICAgICAgICAgIG1heFBlckVsZW1lbnQ6IDEsXG5cbiAgICAgICAgICAgICAgICBzbmFwOiB7XG4gICAgICAgICAgICAgICAgICAgIGVuYWJsZWQgICAgIDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIGVuZE9ubHkgICAgIDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIHJhbmdlICAgICAgIDogSW5maW5pdHksXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldHMgICAgIDogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgb2Zmc2V0cyAgICAgOiBudWxsLFxuXG4gICAgICAgICAgICAgICAgICAgIHJlbGF0aXZlUG9pbnRzOiBudWxsXG4gICAgICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgICAgIHJlc3RyaWN0OiB7XG4gICAgICAgICAgICAgICAgICAgIGVuYWJsZWQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBlbmRPbmx5OiBmYWxzZVxuICAgICAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgICAgICBhdXRvU2Nyb2xsOiB7XG4gICAgICAgICAgICAgICAgICAgIGVuYWJsZWQgICAgIDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIGNvbnRhaW5lciAgIDogbnVsbCwgICAgIC8vIHRoZSBpdGVtIHRoYXQgaXMgc2Nyb2xsZWQgKFdpbmRvdyBvciBIVE1MRWxlbWVudClcbiAgICAgICAgICAgICAgICAgICAgbWFyZ2luICAgICAgOiA2MCxcbiAgICAgICAgICAgICAgICAgICAgc3BlZWQgICAgICAgOiAzMDAgICAgICAgLy8gdGhlIHNjcm9sbCBzcGVlZCBpbiBwaXhlbHMgcGVyIHNlY29uZFxuICAgICAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgICAgICBpbmVydGlhOiB7XG4gICAgICAgICAgICAgICAgICAgIGVuYWJsZWQgICAgICAgICAgOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgcmVzaXN0YW5jZSAgICAgICA6IDEwLCAgICAvLyB0aGUgbGFtYmRhIGluIGV4cG9uZW50aWFsIGRlY2F5XG4gICAgICAgICAgICAgICAgICAgIG1pblNwZWVkICAgICAgICAgOiAxMDAsICAgLy8gdGFyZ2V0IHNwZWVkIG11c3QgYmUgYWJvdmUgdGhpcyBmb3IgaW5lcnRpYSB0byBzdGFydFxuICAgICAgICAgICAgICAgICAgICBlbmRTcGVlZCAgICAgICAgIDogMTAsICAgIC8vIHRoZSBzcGVlZCBhdCB3aGljaCBpbmVydGlhIGlzIHNsb3cgZW5vdWdoIHRvIHN0b3BcbiAgICAgICAgICAgICAgICAgICAgYWxsb3dSZXN1bWUgICAgICA6IHRydWUsICAvLyBhbGxvdyByZXN1bWluZyBhbiBhY3Rpb24gaW4gaW5lcnRpYSBwaGFzZVxuICAgICAgICAgICAgICAgICAgICB6ZXJvUmVzdW1lRGVsdGEgIDogdHJ1ZSwgIC8vIGlmIGFuIGFjdGlvbiBpcyByZXN1bWVkIGFmdGVyIGxhdW5jaCwgc2V0IGR4L2R5IHRvIDBcbiAgICAgICAgICAgICAgICAgICAgc21vb3RoRW5kRHVyYXRpb246IDMwMCAgICAvLyBhbmltYXRlIHRvIHNuYXAvcmVzdHJpY3QgZW5kT25seSBpZiB0aGVyZSdzIG5vIGluZXJ0aWFcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICBfaG9sZER1cmF0aW9uOiA2MDBcbiAgICAgICAgfSxcblxuICAgICAgICAvLyBUaGluZ3MgcmVsYXRlZCB0byBhdXRvU2Nyb2xsXG4gICAgICAgIGF1dG9TY3JvbGwgPSB7XG4gICAgICAgICAgICBpbnRlcmFjdGlvbjogbnVsbCxcbiAgICAgICAgICAgIGk6IG51bGwsICAgIC8vIHRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgd2luZG93LnNldEludGVydmFsXG4gICAgICAgICAgICB4OiAwLCB5OiAwLCAvLyBEaXJlY3Rpb24gZWFjaCBwdWxzZSBpcyB0byBzY3JvbGwgaW5cblxuICAgICAgICAgICAgLy8gc2Nyb2xsIHRoZSB3aW5kb3cgYnkgdGhlIHZhbHVlcyBpbiBzY3JvbGwueC95XG4gICAgICAgICAgICBzY3JvbGw6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgb3B0aW9ucyA9IGF1dG9TY3JvbGwuaW50ZXJhY3Rpb24udGFyZ2V0Lm9wdGlvbnNbYXV0b1Njcm9sbC5pbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lXS5hdXRvU2Nyb2xsLFxuICAgICAgICAgICAgICAgICAgICBjb250YWluZXIgPSBvcHRpb25zLmNvbnRhaW5lciB8fCBnZXRXaW5kb3coYXV0b1Njcm9sbC5pbnRlcmFjdGlvbi5lbGVtZW50KSxcbiAgICAgICAgICAgICAgICAgICAgbm93ID0gbmV3IERhdGUoKS5nZXRUaW1lKCksXG4gICAgICAgICAgICAgICAgICAgIC8vIGNoYW5nZSBpbiB0aW1lIGluIHNlY29uZHNcbiAgICAgICAgICAgICAgICAgICAgZHR4ID0gKG5vdyAtIGF1dG9TY3JvbGwucHJldlRpbWVYKSAvIDEwMDAsXG4gICAgICAgICAgICAgICAgICAgIGR0eSA9IChub3cgLSBhdXRvU2Nyb2xsLnByZXZUaW1lWSkgLyAxMDAwLFxuICAgICAgICAgICAgICAgICAgICB2eCwgdnksIHN4LCBzeTtcblxuICAgICAgICAgICAgICAgIC8vIGRpc3BsYWNlbWVudFxuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLnZlbG9jaXR5KSB7XG4gICAgICAgICAgICAgICAgICB2eCA9IG9wdGlvbnMudmVsb2NpdHkueDtcbiAgICAgICAgICAgICAgICAgIHZ5ID0gb3B0aW9ucy52ZWxvY2l0eS55O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIHZ4ID0gdnkgPSBvcHRpb25zLnNwZWVkXG4gICAgICAgICAgICAgICAgfVxuIFxuICAgICAgICAgICAgICAgIHN4ID0gdnggKiBkdHg7XG4gICAgICAgICAgICAgICAgc3kgPSB2eSAqIGR0eTtcblxuICAgICAgICAgICAgICAgIGlmIChzeCA+PSAxIHx8IHN5ID49IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzV2luZG93KGNvbnRhaW5lcikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRhaW5lci5zY3JvbGxCeShhdXRvU2Nyb2xsLnggKiBzeCwgYXV0b1Njcm9sbC55ICogc3kpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNvbnRhaW5lcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyLnNjcm9sbExlZnQgKz0gYXV0b1Njcm9sbC54ICogc3g7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250YWluZXIuc2Nyb2xsVG9wICArPSBhdXRvU2Nyb2xsLnkgKiBzeTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGlmIChzeCA+PTEpIGF1dG9TY3JvbGwucHJldlRpbWVYID0gbm93O1xuICAgICAgICAgICAgICAgICAgICBpZiAoc3kgPj0gMSkgYXV0b1Njcm9sbC5wcmV2VGltZVkgPSBub3c7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKGF1dG9TY3JvbGwuaXNTY3JvbGxpbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FuY2VsRnJhbWUoYXV0b1Njcm9sbC5pKTtcbiAgICAgICAgICAgICAgICAgICAgYXV0b1Njcm9sbC5pID0gcmVxRnJhbWUoYXV0b1Njcm9sbC5zY3JvbGwpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIGlzU2Nyb2xsaW5nOiBmYWxzZSxcbiAgICAgICAgICAgIHByZXZUaW1lWDogMCxcbiAgICAgICAgICAgIHByZXZUaW1lWTogMCxcblxuICAgICAgICAgICAgc3RhcnQ6IGZ1bmN0aW9uIChpbnRlcmFjdGlvbikge1xuICAgICAgICAgICAgICAgIGF1dG9TY3JvbGwuaXNTY3JvbGxpbmcgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGNhbmNlbEZyYW1lKGF1dG9TY3JvbGwuaSk7XG5cbiAgICAgICAgICAgICAgICBhdXRvU2Nyb2xsLmludGVyYWN0aW9uID0gaW50ZXJhY3Rpb247XG4gICAgICAgICAgICAgICAgYXV0b1Njcm9sbC5wcmV2VGltZVggPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICAgICAgICAgICAgICBhdXRvU2Nyb2xsLnByZXZUaW1lWSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgICAgICAgICAgICAgIGF1dG9TY3JvbGwuaSA9IHJlcUZyYW1lKGF1dG9TY3JvbGwuc2Nyb2xsKTtcbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIHN0b3A6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBhdXRvU2Nyb2xsLmlzU2Nyb2xsaW5nID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgY2FuY2VsRnJhbWUoYXV0b1Njcm9sbC5pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICAvLyBEb2VzIHRoZSBicm93c2VyIHN1cHBvcnQgdG91Y2ggaW5wdXQ/XG4gICAgICAgIHN1cHBvcnRzVG91Y2ggPSAoKCdvbnRvdWNoc3RhcnQnIGluIHdpbmRvdykgfHwgd2luZG93LkRvY3VtZW50VG91Y2ggJiYgZG9jdW1lbnQgaW5zdGFuY2VvZiB3aW5kb3cuRG9jdW1lbnRUb3VjaCksXG5cbiAgICAgICAgLy8gRG9lcyB0aGUgYnJvd3NlciBzdXBwb3J0IFBvaW50ZXJFdmVudHNcbiAgICAgICAgLy8gQXZvaWQgUG9pbnRlckV2ZW50IGJ1Z3MgaW50cm9kdWNlZCBpbiBDaHJvbWUgNTVcbiAgICAgICAgc3VwcG9ydHNQb2ludGVyRXZlbnQgPSBQb2ludGVyRXZlbnQgJiYgIS9DaHJvbWUvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCksXG5cbiAgICAgICAgLy8gTGVzcyBQcmVjaXNpb24gd2l0aCB0b3VjaCBpbnB1dFxuICAgICAgICBtYXJnaW4gPSBzdXBwb3J0c1RvdWNoIHx8IHN1cHBvcnRzUG9pbnRlckV2ZW50PyAyMDogMTAsXG5cbiAgICAgICAgcG9pbnRlck1vdmVUb2xlcmFuY2UgPSAxLFxuXG4gICAgICAgIC8vIGZvciBpZ25vcmluZyBicm93c2VyJ3Mgc2ltdWxhdGVkIG1vdXNlIGV2ZW50c1xuICAgICAgICBwcmV2VG91Y2hUaW1lID0gMCxcblxuICAgICAgICAvLyBBbGxvdyB0aGlzIG1hbnkgaW50ZXJhY3Rpb25zIHRvIGhhcHBlbiBzaW11bHRhbmVvdXNseVxuICAgICAgICBtYXhJbnRlcmFjdGlvbnMgPSBJbmZpbml0eSxcblxuICAgICAgICAvLyBDaGVjayBpZiBpcyBJRTkgb3Igb2xkZXJcbiAgICAgICAgYWN0aW9uQ3Vyc29ycyA9IChkb2N1bWVudC5hbGwgJiYgIXdpbmRvdy5hdG9iKSA/IHtcbiAgICAgICAgICAgIGRyYWcgICAgOiAnbW92ZScsXG4gICAgICAgICAgICByZXNpemV4IDogJ2UtcmVzaXplJyxcbiAgICAgICAgICAgIHJlc2l6ZXkgOiAncy1yZXNpemUnLFxuICAgICAgICAgICAgcmVzaXpleHk6ICdzZS1yZXNpemUnLFxuXG4gICAgICAgICAgICByZXNpemV0b3AgICAgICAgIDogJ24tcmVzaXplJyxcbiAgICAgICAgICAgIHJlc2l6ZWxlZnQgICAgICAgOiAndy1yZXNpemUnLFxuICAgICAgICAgICAgcmVzaXplYm90dG9tICAgICA6ICdzLXJlc2l6ZScsXG4gICAgICAgICAgICByZXNpemVyaWdodCAgICAgIDogJ2UtcmVzaXplJyxcbiAgICAgICAgICAgIHJlc2l6ZXRvcGxlZnQgICAgOiAnc2UtcmVzaXplJyxcbiAgICAgICAgICAgIHJlc2l6ZWJvdHRvbXJpZ2h0OiAnc2UtcmVzaXplJyxcbiAgICAgICAgICAgIHJlc2l6ZXRvcHJpZ2h0ICAgOiAnbmUtcmVzaXplJyxcbiAgICAgICAgICAgIHJlc2l6ZWJvdHRvbWxlZnQgOiAnbmUtcmVzaXplJyxcblxuICAgICAgICAgICAgZ2VzdHVyZSA6ICcnXG4gICAgICAgIH0gOiB7XG4gICAgICAgICAgICBkcmFnICAgIDogJ21vdmUnLFxuICAgICAgICAgICAgcmVzaXpleCA6ICdldy1yZXNpemUnLFxuICAgICAgICAgICAgcmVzaXpleSA6ICducy1yZXNpemUnLFxuICAgICAgICAgICAgcmVzaXpleHk6ICdud3NlLXJlc2l6ZScsXG5cbiAgICAgICAgICAgIHJlc2l6ZXRvcCAgICAgICAgOiAnbnMtcmVzaXplJyxcbiAgICAgICAgICAgIHJlc2l6ZWxlZnQgICAgICAgOiAnZXctcmVzaXplJyxcbiAgICAgICAgICAgIHJlc2l6ZWJvdHRvbSAgICAgOiAnbnMtcmVzaXplJyxcbiAgICAgICAgICAgIHJlc2l6ZXJpZ2h0ICAgICAgOiAnZXctcmVzaXplJyxcbiAgICAgICAgICAgIHJlc2l6ZXRvcGxlZnQgICAgOiAnbndzZS1yZXNpemUnLFxuICAgICAgICAgICAgcmVzaXplYm90dG9tcmlnaHQ6ICdud3NlLXJlc2l6ZScsXG4gICAgICAgICAgICByZXNpemV0b3ByaWdodCAgIDogJ25lc3ctcmVzaXplJyxcbiAgICAgICAgICAgIHJlc2l6ZWJvdHRvbWxlZnQgOiAnbmVzdy1yZXNpemUnLFxuXG4gICAgICAgICAgICBnZXN0dXJlIDogJydcbiAgICAgICAgfSxcblxuICAgICAgICBhY3Rpb25Jc0VuYWJsZWQgPSB7XG4gICAgICAgICAgICBkcmFnICAgOiB0cnVlLFxuICAgICAgICAgICAgcmVzaXplIDogdHJ1ZSxcbiAgICAgICAgICAgIGdlc3R1cmU6IHRydWVcbiAgICAgICAgfSxcblxuICAgICAgICAvLyBiZWNhdXNlIFdlYmtpdCBhbmQgT3BlcmEgc3RpbGwgdXNlICdtb3VzZXdoZWVsJyBldmVudCB0eXBlXG4gICAgICAgIHdoZWVsRXZlbnQgPSAnb25tb3VzZXdoZWVsJyBpbiBkb2N1bWVudD8gJ21vdXNld2hlZWwnOiAnd2hlZWwnLFxuXG4gICAgICAgIGV2ZW50VHlwZXMgPSBbXG4gICAgICAgICAgICAnZHJhZ3N0YXJ0JyxcbiAgICAgICAgICAgICdkcmFnbW92ZScsXG4gICAgICAgICAgICAnZHJhZ2luZXJ0aWFzdGFydCcsXG4gICAgICAgICAgICAnZHJhZ2VuZCcsXG4gICAgICAgICAgICAnZHJhZ2VudGVyJyxcbiAgICAgICAgICAgICdkcmFnbGVhdmUnLFxuICAgICAgICAgICAgJ2Ryb3BhY3RpdmF0ZScsXG4gICAgICAgICAgICAnZHJvcGRlYWN0aXZhdGUnLFxuICAgICAgICAgICAgJ2Ryb3Btb3ZlJyxcbiAgICAgICAgICAgICdkcm9wJyxcbiAgICAgICAgICAgICdyZXNpemVzdGFydCcsXG4gICAgICAgICAgICAncmVzaXplbW92ZScsXG4gICAgICAgICAgICAncmVzaXplaW5lcnRpYXN0YXJ0JyxcbiAgICAgICAgICAgICdyZXNpemVlbmQnLFxuICAgICAgICAgICAgJ2dlc3R1cmVzdGFydCcsXG4gICAgICAgICAgICAnZ2VzdHVyZW1vdmUnLFxuICAgICAgICAgICAgJ2dlc3R1cmVpbmVydGlhc3RhcnQnLFxuICAgICAgICAgICAgJ2dlc3R1cmVlbmQnLFxuXG4gICAgICAgICAgICAnZG93bicsXG4gICAgICAgICAgICAnbW92ZScsXG4gICAgICAgICAgICAndXAnLFxuICAgICAgICAgICAgJ2NhbmNlbCcsXG4gICAgICAgICAgICAndGFwJyxcbiAgICAgICAgICAgICdkb3VibGV0YXAnLFxuICAgICAgICAgICAgJ2hvbGQnXG4gICAgICAgIF0sXG5cbiAgICAgICAgZ2xvYmFsRXZlbnRzID0ge30sXG5cbiAgICAgICAgLy8gT3BlcmEgTW9iaWxlIG11c3QgYmUgaGFuZGxlZCBkaWZmZXJlbnRseVxuICAgICAgICBpc09wZXJhTW9iaWxlID0gbmF2aWdhdG9yLmFwcE5hbWUgPT0gJ09wZXJhJyAmJlxuICAgICAgICAgICAgc3VwcG9ydHNUb3VjaCAmJlxuICAgICAgICAgICAgbmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgnUHJlc3RvJyksXG5cbiAgICAgICAgLy8gc2Nyb2xsaW5nIGRvZXNuJ3QgY2hhbmdlIHRoZSByZXN1bHQgb2YgZ2V0Q2xpZW50UmVjdHMgb24gaU9TIDdcbiAgICAgICAgaXNJT1M3ID0gKC9pUChob25lfG9kfGFkKS8udGVzdChuYXZpZ2F0b3IucGxhdGZvcm0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgJiYgL09TIDdbXlxcZF0vLnRlc3QobmF2aWdhdG9yLmFwcFZlcnNpb24pKSxcblxuICAgICAgICAvLyBwcmVmaXggbWF0Y2hlc1NlbGVjdG9yXG4gICAgICAgIHByZWZpeGVkTWF0Y2hlc1NlbGVjdG9yID0gJ21hdGNoZXMnIGluIEVsZW1lbnQucHJvdG90eXBlP1xuICAgICAgICAgICAgICAgICdtYXRjaGVzJzogJ3dlYmtpdE1hdGNoZXNTZWxlY3RvcicgaW4gRWxlbWVudC5wcm90b3R5cGU/XG4gICAgICAgICAgICAgICAgICAgICd3ZWJraXRNYXRjaGVzU2VsZWN0b3InOiAnbW96TWF0Y2hlc1NlbGVjdG9yJyBpbiBFbGVtZW50LnByb3RvdHlwZT9cbiAgICAgICAgICAgICAgICAgICAgICAgICdtb3pNYXRjaGVzU2VsZWN0b3InOiAnb01hdGNoZXNTZWxlY3RvcicgaW4gRWxlbWVudC5wcm90b3R5cGU/XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ29NYXRjaGVzU2VsZWN0b3InOiAnbXNNYXRjaGVzU2VsZWN0b3InLFxuXG4gICAgICAgIC8vIHdpbGwgYmUgcG9seWZpbGwgZnVuY3Rpb24gaWYgYnJvd3NlciBpcyBJRThcbiAgICAgICAgaWU4TWF0Y2hlc1NlbGVjdG9yLFxuXG4gICAgICAgIC8vIG5hdGl2ZSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUgb3IgcG9seWZpbGxcbiAgICAgICAgcmVxRnJhbWUgPSByZWFsV2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSxcbiAgICAgICAgY2FuY2VsRnJhbWUgPSByZWFsV2luZG93LmNhbmNlbEFuaW1hdGlvbkZyYW1lLFxuXG4gICAgICAgIC8vIEV2ZW50cyB3cmFwcGVyXG4gICAgICAgIGV2ZW50cyA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgdXNlQXR0YWNoRXZlbnQgPSAoJ2F0dGFjaEV2ZW50JyBpbiB3aW5kb3cpICYmICEoJ2FkZEV2ZW50TGlzdGVuZXInIGluIHdpbmRvdyksXG4gICAgICAgICAgICAgICAgYWRkRXZlbnQgICAgICAgPSB1c2VBdHRhY2hFdmVudD8gICdhdHRhY2hFdmVudCc6ICdhZGRFdmVudExpc3RlbmVyJyxcbiAgICAgICAgICAgICAgICByZW1vdmVFdmVudCAgICA9IHVzZUF0dGFjaEV2ZW50PyAgJ2RldGFjaEV2ZW50JzogJ3JlbW92ZUV2ZW50TGlzdGVuZXInLFxuICAgICAgICAgICAgICAgIG9uICAgICAgICAgICAgID0gdXNlQXR0YWNoRXZlbnQ/ICdvbic6ICcnLFxuXG4gICAgICAgICAgICAgICAgZWxlbWVudHMgICAgICAgICAgPSBbXSxcbiAgICAgICAgICAgICAgICB0YXJnZXRzICAgICAgICAgICA9IFtdLFxuICAgICAgICAgICAgICAgIGF0dGFjaGVkTGlzdGVuZXJzID0gW107XG5cbiAgICAgICAgICAgIGZ1bmN0aW9uIGFkZCAoZWxlbWVudCwgdHlwZSwgbGlzdGVuZXIsIHVzZUNhcHR1cmUpIHtcbiAgICAgICAgICAgICAgICB2YXIgZWxlbWVudEluZGV4ID0gaW5kZXhPZihlbGVtZW50cywgZWxlbWVudCksXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldCA9IHRhcmdldHNbZWxlbWVudEluZGV4XTtcblxuICAgICAgICAgICAgICAgIGlmICghdGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgICAgIHRhcmdldCA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50czoge30sXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlQ291bnQ6IDBcbiAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICBlbGVtZW50SW5kZXggPSBlbGVtZW50cy5wdXNoKGVsZW1lbnQpIC0gMTtcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0cy5wdXNoKHRhcmdldCk7XG5cbiAgICAgICAgICAgICAgICAgICAgYXR0YWNoZWRMaXN0ZW5lcnMucHVzaCgodXNlQXR0YWNoRXZlbnQgPyB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VwcGxpZWQ6IFtdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyYXBwZWQgOiBbXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1c2VDb3VudDogW11cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gOiBudWxsKSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKCF0YXJnZXQuZXZlbnRzW3R5cGVdKSB7XG4gICAgICAgICAgICAgICAgICAgIHRhcmdldC5ldmVudHNbdHlwZV0gPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LnR5cGVDb3VudCsrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICghY29udGFpbnModGFyZ2V0LmV2ZW50c1t0eXBlXSwgbGlzdGVuZXIpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciByZXQ7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHVzZUF0dGFjaEV2ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbGlzdGVuZXJzID0gYXR0YWNoZWRMaXN0ZW5lcnNbZWxlbWVudEluZGV4XSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lckluZGV4ID0gaW5kZXhPZihsaXN0ZW5lcnMuc3VwcGxpZWQsIGxpc3RlbmVyKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHdyYXBwZWQgPSBsaXN0ZW5lcnMud3JhcHBlZFtsaXN0ZW5lckluZGV4XSB8fCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWV2ZW50LmltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudC50YXJnZXQgPSBldmVudC5zcmNFbGVtZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudC5jdXJyZW50VGFyZ2V0ID0gZWxlbWVudDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCA9IGV2ZW50LnByZXZlbnREZWZhdWx0IHx8IHByZXZlbnREZWY7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbiA9IGV2ZW50LnN0b3BQcm9wYWdhdGlvbiB8fCBzdG9wUHJvcDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uID0gZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uIHx8IHN0b3BJbW1Qcm9wO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgvbW91c2V8Y2xpY2svLnRlc3QoZXZlbnQudHlwZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnBhZ2VYID0gZXZlbnQuY2xpZW50WCArIGdldFdpbmRvdyhlbGVtZW50KS5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsTGVmdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnBhZ2VZID0gZXZlbnQuY2xpZW50WSArIGdldFdpbmRvdyhlbGVtZW50KS5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsVG9wO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXIoZXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldCA9IGVsZW1lbnRbYWRkRXZlbnRdKG9uICsgdHlwZSwgd3JhcHBlZCwgQm9vbGVhbih1c2VDYXB0dXJlKSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsaXN0ZW5lckluZGV4ID09PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3RlbmVycy5zdXBwbGllZC5wdXNoKGxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnMud3JhcHBlZC5wdXNoKHdyYXBwZWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3RlbmVycy51c2VDb3VudC5wdXNoKDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXJzLnVzZUNvdW50W2xpc3RlbmVySW5kZXhdKys7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXQgPSBlbGVtZW50W2FkZEV2ZW50XSh0eXBlLCBsaXN0ZW5lciwgdXNlQ2FwdHVyZSB8fCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LmV2ZW50c1t0eXBlXS5wdXNoKGxpc3RlbmVyKTtcblxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZnVuY3Rpb24gcmVtb3ZlIChlbGVtZW50LCB0eXBlLCBsaXN0ZW5lciwgdXNlQ2FwdHVyZSkge1xuICAgICAgICAgICAgICAgIHZhciBpLFxuICAgICAgICAgICAgICAgICAgICBlbGVtZW50SW5kZXggPSBpbmRleE9mKGVsZW1lbnRzLCBlbGVtZW50KSxcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0ID0gdGFyZ2V0c1tlbGVtZW50SW5kZXhdLFxuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnMsXG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVySW5kZXgsXG4gICAgICAgICAgICAgICAgICAgIHdyYXBwZWQgPSBsaXN0ZW5lcjtcblxuICAgICAgICAgICAgICAgIGlmICghdGFyZ2V0IHx8ICF0YXJnZXQuZXZlbnRzKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAodXNlQXR0YWNoRXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXJzID0gYXR0YWNoZWRMaXN0ZW5lcnNbZWxlbWVudEluZGV4XTtcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXJJbmRleCA9IGluZGV4T2YobGlzdGVuZXJzLnN1cHBsaWVkLCBsaXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgICAgIHdyYXBwZWQgPSBsaXN0ZW5lcnMud3JhcHBlZFtsaXN0ZW5lckluZGV4XTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZSA9PT0gJ2FsbCcpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yICh0eXBlIGluIHRhcmdldC5ldmVudHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0YXJnZXQuZXZlbnRzLmhhc093blByb3BlcnR5KHR5cGUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlKGVsZW1lbnQsIHR5cGUsICdhbGwnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKHRhcmdldC5ldmVudHNbdHlwZV0pIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGxlbiA9IHRhcmdldC5ldmVudHNbdHlwZV0ubGVuZ3RoO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChsaXN0ZW5lciA9PT0gJ2FsbCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZShlbGVtZW50LCB0eXBlLCB0YXJnZXQuZXZlbnRzW3R5cGVdW2ldLCBCb29sZWFuKHVzZUNhcHR1cmUpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0YXJnZXQuZXZlbnRzW3R5cGVdW2ldID09PSBsaXN0ZW5lcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50W3JlbW92ZUV2ZW50XShvbiArIHR5cGUsIHdyYXBwZWQsIHVzZUNhcHR1cmUgfHwgZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQuZXZlbnRzW3R5cGVdLnNwbGljZShpLCAxKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodXNlQXR0YWNoRXZlbnQgJiYgbGlzdGVuZXJzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnMudXNlQ291bnRbbGlzdGVuZXJJbmRleF0tLTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsaXN0ZW5lcnMudXNlQ291bnRbbGlzdGVuZXJJbmRleF0gPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnMuc3VwcGxpZWQuc3BsaWNlKGxpc3RlbmVySW5kZXgsIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3RlbmVycy53cmFwcGVkLnNwbGljZShsaXN0ZW5lckluZGV4LCAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnMudXNlQ291bnQuc3BsaWNlKGxpc3RlbmVySW5kZXgsIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHRhcmdldC5ldmVudHNbdHlwZV0gJiYgdGFyZ2V0LmV2ZW50c1t0eXBlXS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldC5ldmVudHNbdHlwZV0gPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LnR5cGVDb3VudC0tO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKCF0YXJnZXQudHlwZUNvdW50KSB7XG4gICAgICAgICAgICAgICAgICAgIHRhcmdldHMuc3BsaWNlKGVsZW1lbnRJbmRleCwgMSk7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnRzLnNwbGljZShlbGVtZW50SW5kZXgsIDEpO1xuICAgICAgICAgICAgICAgICAgICBhdHRhY2hlZExpc3RlbmVycy5zcGxpY2UoZWxlbWVudEluZGV4LCAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZ1bmN0aW9uIHByZXZlbnREZWYgKCkge1xuICAgICAgICAgICAgICAgIHRoaXMucmV0dXJuVmFsdWUgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZnVuY3Rpb24gc3RvcFByb3AgKCkge1xuICAgICAgICAgICAgICAgIHRoaXMuY2FuY2VsQnViYmxlID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZnVuY3Rpb24gc3RvcEltbVByb3AgKCkge1xuICAgICAgICAgICAgICAgIHRoaXMuY2FuY2VsQnViYmxlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB0aGlzLmltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZCA9IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgYWRkOiBhZGQsXG4gICAgICAgICAgICAgICAgcmVtb3ZlOiByZW1vdmUsXG4gICAgICAgICAgICAgICAgdXNlQXR0YWNoRXZlbnQ6IHVzZUF0dGFjaEV2ZW50LFxuXG4gICAgICAgICAgICAgICAgX2VsZW1lbnRzOiBlbGVtZW50cyxcbiAgICAgICAgICAgICAgICBfdGFyZ2V0czogdGFyZ2V0cyxcbiAgICAgICAgICAgICAgICBfYXR0YWNoZWRMaXN0ZW5lcnM6IGF0dGFjaGVkTGlzdGVuZXJzXG4gICAgICAgICAgICB9O1xuICAgICAgICB9KCkpO1xuXG4gICAgZnVuY3Rpb24gYmxhbmsgKCkge31cblxuICAgIGZ1bmN0aW9uIGlzRWxlbWVudCAobykge1xuICAgICAgICBpZiAoIW8gfHwgKHR5cGVvZiBvICE9PSAnb2JqZWN0JykpIHsgcmV0dXJuIGZhbHNlOyB9XG5cbiAgICAgICAgdmFyIF93aW5kb3cgPSBnZXRXaW5kb3cobykgfHwgd2luZG93O1xuXG4gICAgICAgIHJldHVybiAoL29iamVjdHxmdW5jdGlvbi8udGVzdCh0eXBlb2YgX3dpbmRvdy5FbGVtZW50KVxuICAgICAgICAgICAgPyBvIGluc3RhbmNlb2YgX3dpbmRvdy5FbGVtZW50IC8vRE9NMlxuICAgICAgICAgICAgOiBvLm5vZGVUeXBlID09PSAxICYmIHR5cGVvZiBvLm5vZGVOYW1lID09PSBcInN0cmluZ1wiKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gaXNXaW5kb3cgKHRoaW5nKSB7IHJldHVybiB0aGluZyA9PT0gd2luZG93IHx8ICEhKHRoaW5nICYmIHRoaW5nLldpbmRvdykgJiYgKHRoaW5nIGluc3RhbmNlb2YgdGhpbmcuV2luZG93KTsgfVxuICAgIGZ1bmN0aW9uIGlzRG9jRnJhZyAodGhpbmcpIHsgcmV0dXJuICEhdGhpbmcgJiYgdGhpbmcgaW5zdGFuY2VvZiBEb2N1bWVudEZyYWdtZW50OyB9XG4gICAgZnVuY3Rpb24gaXNBcnJheSAodGhpbmcpIHtcbiAgICAgICAgcmV0dXJuIGlzT2JqZWN0KHRoaW5nKVxuICAgICAgICAgICAgICAgICYmICh0eXBlb2YgdGhpbmcubGVuZ3RoICE9PSB1bmRlZmluZWQpXG4gICAgICAgICAgICAgICAgJiYgaXNGdW5jdGlvbih0aGluZy5zcGxpY2UpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBpc09iamVjdCAgICh0aGluZykgeyByZXR1cm4gISF0aGluZyAmJiAodHlwZW9mIHRoaW5nID09PSAnb2JqZWN0Jyk7IH1cbiAgICBmdW5jdGlvbiBpc0Z1bmN0aW9uICh0aGluZykgeyByZXR1cm4gdHlwZW9mIHRoaW5nID09PSAnZnVuY3Rpb24nOyB9XG4gICAgZnVuY3Rpb24gaXNOdW1iZXIgICAodGhpbmcpIHsgcmV0dXJuIHR5cGVvZiB0aGluZyA9PT0gJ251bWJlcicgIDsgfVxuICAgIGZ1bmN0aW9uIGlzQm9vbCAgICAgKHRoaW5nKSB7IHJldHVybiB0eXBlb2YgdGhpbmcgPT09ICdib29sZWFuJyA7IH1cbiAgICBmdW5jdGlvbiBpc1N0cmluZyAgICh0aGluZykgeyByZXR1cm4gdHlwZW9mIHRoaW5nID09PSAnc3RyaW5nJyAgOyB9XG5cbiAgICBmdW5jdGlvbiB0cnlTZWxlY3RvciAodmFsdWUpIHtcbiAgICAgICAgaWYgKCFpc1N0cmluZyh2YWx1ZSkpIHsgcmV0dXJuIGZhbHNlOyB9XG5cbiAgICAgICAgLy8gYW4gZXhjZXB0aW9uIHdpbGwgYmUgcmFpc2VkIGlmIGl0IGlzIGludmFsaWRcbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih2YWx1ZSk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGV4dGVuZCAoZGVzdCwgc291cmNlKSB7XG4gICAgICAgIGZvciAodmFyIHByb3AgaW4gc291cmNlKSB7XG4gICAgICAgICAgICBkZXN0W3Byb3BdID0gc291cmNlW3Byb3BdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkZXN0O1xuICAgIH1cblxuICAgIHZhciBwcmVmaXhlZFByb3BSRXMgPSB7XG4gICAgICB3ZWJraXQ6IC8oTW92ZW1lbnRbWFldfFJhZGl1c1tYWV18Um90YXRpb25BbmdsZXxGb3JjZSkkL1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBwb2ludGVyRXh0ZW5kIChkZXN0LCBzb3VyY2UpIHtcbiAgICAgICAgZm9yICh2YXIgcHJvcCBpbiBzb3VyY2UpIHtcbiAgICAgICAgICB2YXIgZGVwcmVjYXRlZCA9IGZhbHNlO1xuXG4gICAgICAgICAgLy8gc2tpcCBkZXByZWNhdGVkIHByZWZpeGVkIHByb3BlcnRpZXNcbiAgICAgICAgICBmb3IgKHZhciB2ZW5kb3IgaW4gcHJlZml4ZWRQcm9wUkVzKSB7XG4gICAgICAgICAgICBpZiAocHJvcC5pbmRleE9mKHZlbmRvcikgPT09IDAgJiYgcHJlZml4ZWRQcm9wUkVzW3ZlbmRvcl0udGVzdChwcm9wKSkge1xuICAgICAgICAgICAgICBkZXByZWNhdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKCFkZXByZWNhdGVkKSB7XG4gICAgICAgICAgICBkZXN0W3Byb3BdID0gc291cmNlW3Byb3BdO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGVzdDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjb3B5Q29vcmRzIChkZXN0LCBzcmMpIHtcbiAgICAgICAgZGVzdC5wYWdlID0gZGVzdC5wYWdlIHx8IHt9O1xuICAgICAgICBkZXN0LnBhZ2UueCA9IHNyYy5wYWdlLng7XG4gICAgICAgIGRlc3QucGFnZS55ID0gc3JjLnBhZ2UueTtcblxuICAgICAgICBkZXN0LmNsaWVudCA9IGRlc3QuY2xpZW50IHx8IHt9O1xuICAgICAgICBkZXN0LmNsaWVudC54ID0gc3JjLmNsaWVudC54O1xuICAgICAgICBkZXN0LmNsaWVudC55ID0gc3JjLmNsaWVudC55O1xuXG4gICAgICAgIGRlc3QudGltZVN0YW1wID0gc3JjLnRpbWVTdGFtcDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzZXRFdmVudFhZICh0YXJnZXRPYmosIHBvaW50ZXJzLCBpbnRlcmFjdGlvbikge1xuICAgICAgICB2YXIgcG9pbnRlciA9IChwb2ludGVycy5sZW5ndGggPiAxXG4gICAgICAgICAgICAgICAgICAgICAgID8gcG9pbnRlckF2ZXJhZ2UocG9pbnRlcnMpXG4gICAgICAgICAgICAgICAgICAgICAgIDogcG9pbnRlcnNbMF0pO1xuXG4gICAgICAgIGdldFBhZ2VYWShwb2ludGVyLCB0bXBYWSwgaW50ZXJhY3Rpb24pO1xuICAgICAgICB0YXJnZXRPYmoucGFnZS54ID0gdG1wWFkueDtcbiAgICAgICAgdGFyZ2V0T2JqLnBhZ2UueSA9IHRtcFhZLnk7XG5cbiAgICAgICAgZ2V0Q2xpZW50WFkocG9pbnRlciwgdG1wWFksIGludGVyYWN0aW9uKTtcbiAgICAgICAgdGFyZ2V0T2JqLmNsaWVudC54ID0gdG1wWFkueDtcbiAgICAgICAgdGFyZ2V0T2JqLmNsaWVudC55ID0gdG1wWFkueTtcblxuICAgICAgICB0YXJnZXRPYmoudGltZVN0YW1wID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc2V0RXZlbnREZWx0YXMgKHRhcmdldE9iaiwgcHJldiwgY3VyKSB7XG4gICAgICAgIHRhcmdldE9iai5wYWdlLnggICAgID0gY3VyLnBhZ2UueCAgICAgIC0gcHJldi5wYWdlLng7XG4gICAgICAgIHRhcmdldE9iai5wYWdlLnkgICAgID0gY3VyLnBhZ2UueSAgICAgIC0gcHJldi5wYWdlLnk7XG4gICAgICAgIHRhcmdldE9iai5jbGllbnQueCAgID0gY3VyLmNsaWVudC54ICAgIC0gcHJldi5jbGllbnQueDtcbiAgICAgICAgdGFyZ2V0T2JqLmNsaWVudC55ICAgPSBjdXIuY2xpZW50LnkgICAgLSBwcmV2LmNsaWVudC55O1xuICAgICAgICB0YXJnZXRPYmoudGltZVN0YW1wID0gbmV3IERhdGUoKS5nZXRUaW1lKCkgLSBwcmV2LnRpbWVTdGFtcDtcblxuICAgICAgICAvLyBzZXQgcG9pbnRlciB2ZWxvY2l0eVxuICAgICAgICB2YXIgZHQgPSBNYXRoLm1heCh0YXJnZXRPYmoudGltZVN0YW1wIC8gMTAwMCwgMC4wMDEpO1xuICAgICAgICB0YXJnZXRPYmoucGFnZS5zcGVlZCAgID0gaHlwb3QodGFyZ2V0T2JqLnBhZ2UueCwgdGFyZ2V0T2JqLnBhZ2UueSkgLyBkdDtcbiAgICAgICAgdGFyZ2V0T2JqLnBhZ2UudnggICAgICA9IHRhcmdldE9iai5wYWdlLnggLyBkdDtcbiAgICAgICAgdGFyZ2V0T2JqLnBhZ2UudnkgICAgICA9IHRhcmdldE9iai5wYWdlLnkgLyBkdDtcblxuICAgICAgICB0YXJnZXRPYmouY2xpZW50LnNwZWVkID0gaHlwb3QodGFyZ2V0T2JqLmNsaWVudC54LCB0YXJnZXRPYmoucGFnZS55KSAvIGR0O1xuICAgICAgICB0YXJnZXRPYmouY2xpZW50LnZ4ICAgID0gdGFyZ2V0T2JqLmNsaWVudC54IC8gZHQ7XG4gICAgICAgIHRhcmdldE9iai5jbGllbnQudnkgICAgPSB0YXJnZXRPYmouY2xpZW50LnkgLyBkdDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc05hdGl2ZVBvaW50ZXIgKHBvaW50ZXIpIHtcbiAgICAgICAgcmV0dXJuIChwb2ludGVyIGluc3RhbmNlb2Ygd2luZG93LkV2ZW50XG4gICAgICAgICAgICB8fCAoc3VwcG9ydHNUb3VjaCAmJiB3aW5kb3cuVG91Y2ggJiYgcG9pbnRlciBpbnN0YW5jZW9mIHdpbmRvdy5Ub3VjaCkpO1xuICAgIH1cblxuICAgIC8vIEdldCBzcGVjaWZpZWQgWC9ZIGNvb3JkcyBmb3IgbW91c2Ugb3IgZXZlbnQudG91Y2hlc1swXVxuICAgIGZ1bmN0aW9uIGdldFhZICh0eXBlLCBwb2ludGVyLCB4eSkge1xuICAgICAgICB4eSA9IHh5IHx8IHt9O1xuICAgICAgICB0eXBlID0gdHlwZSB8fCAncGFnZSc7XG5cbiAgICAgICAgeHkueCA9IHBvaW50ZXJbdHlwZSArICdYJ107XG4gICAgICAgIHh5LnkgPSBwb2ludGVyW3R5cGUgKyAnWSddO1xuXG4gICAgICAgIHJldHVybiB4eTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRQYWdlWFkgKHBvaW50ZXIsIHBhZ2UpIHtcbiAgICAgICAgcGFnZSA9IHBhZ2UgfHwge307XG5cbiAgICAgICAgLy8gT3BlcmEgTW9iaWxlIGhhbmRsZXMgdGhlIHZpZXdwb3J0IGFuZCBzY3JvbGxpbmcgb2RkbHlcbiAgICAgICAgaWYgKGlzT3BlcmFNb2JpbGUgJiYgaXNOYXRpdmVQb2ludGVyKHBvaW50ZXIpKSB7XG4gICAgICAgICAgICBnZXRYWSgnc2NyZWVuJywgcG9pbnRlciwgcGFnZSk7XG5cbiAgICAgICAgICAgIHBhZ2UueCArPSB3aW5kb3cuc2Nyb2xsWDtcbiAgICAgICAgICAgIHBhZ2UueSArPSB3aW5kb3cuc2Nyb2xsWTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGdldFhZKCdwYWdlJywgcG9pbnRlciwgcGFnZSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcGFnZTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRDbGllbnRYWSAocG9pbnRlciwgY2xpZW50KSB7XG4gICAgICAgIGNsaWVudCA9IGNsaWVudCB8fCB7fTtcblxuICAgICAgICBpZiAoaXNPcGVyYU1vYmlsZSAmJiBpc05hdGl2ZVBvaW50ZXIocG9pbnRlcikpIHtcbiAgICAgICAgICAgIC8vIE9wZXJhIE1vYmlsZSBoYW5kbGVzIHRoZSB2aWV3cG9ydCBhbmQgc2Nyb2xsaW5nIG9kZGx5XG4gICAgICAgICAgICBnZXRYWSgnc2NyZWVuJywgcG9pbnRlciwgY2xpZW50KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBnZXRYWSgnY2xpZW50JywgcG9pbnRlciwgY2xpZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBjbGllbnQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZ2V0U2Nyb2xsWFkgKHdpbikge1xuICAgICAgICB3aW4gPSB3aW4gfHwgd2luZG93O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeDogd2luLnNjcm9sbFggfHwgd2luLmRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxMZWZ0LFxuICAgICAgICAgICAgeTogd2luLnNjcm9sbFkgfHwgd2luLmRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3BcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRQb2ludGVySWQgKHBvaW50ZXIpIHtcbiAgICAgICAgcmV0dXJuIGlzTnVtYmVyKHBvaW50ZXIucG9pbnRlcklkKT8gcG9pbnRlci5wb2ludGVySWQgOiBwb2ludGVyLmlkZW50aWZpZXI7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZ2V0QWN0dWFsRWxlbWVudCAoZWxlbWVudCkge1xuICAgICAgICByZXR1cm4gKGVsZW1lbnQgaW5zdGFuY2VvZiBTVkdFbGVtZW50SW5zdGFuY2VcbiAgICAgICAgICAgID8gZWxlbWVudC5jb3JyZXNwb25kaW5nVXNlRWxlbWVudFxuICAgICAgICAgICAgOiBlbGVtZW50KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRXaW5kb3cgKG5vZGUpIHtcbiAgICAgICAgaWYgKGlzV2luZG93KG5vZGUpKSB7XG4gICAgICAgICAgICByZXR1cm4gbm9kZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciByb290Tm9kZSA9IChub2RlLm93bmVyRG9jdW1lbnQgfHwgbm9kZSk7XG5cbiAgICAgICAgcmV0dXJuIHJvb3ROb2RlLmRlZmF1bHRWaWV3IHx8IHJvb3ROb2RlLnBhcmVudFdpbmRvdyB8fCB3aW5kb3c7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZ2V0RWxlbWVudENsaWVudFJlY3QgKGVsZW1lbnQpIHtcbiAgICAgICAgdmFyIGNsaWVudFJlY3QgPSAoZWxlbWVudCBpbnN0YW5jZW9mIFNWR0VsZW1lbnRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGVsZW1lbnQuZ2V0Q2xpZW50UmVjdHMoKVswXSk7XG5cbiAgICAgICAgcmV0dXJuIGNsaWVudFJlY3QgJiYge1xuICAgICAgICAgICAgbGVmdCAgOiBjbGllbnRSZWN0LmxlZnQsXG4gICAgICAgICAgICByaWdodCA6IGNsaWVudFJlY3QucmlnaHQsXG4gICAgICAgICAgICB0b3AgICA6IGNsaWVudFJlY3QudG9wLFxuICAgICAgICAgICAgYm90dG9tOiBjbGllbnRSZWN0LmJvdHRvbSxcbiAgICAgICAgICAgIHdpZHRoIDogY2xpZW50UmVjdC53aWR0aCB8fCBjbGllbnRSZWN0LnJpZ2h0IC0gY2xpZW50UmVjdC5sZWZ0LFxuICAgICAgICAgICAgaGVpZ2h0OiBjbGllbnRSZWN0LmhlaWdodCB8fCBjbGllbnRSZWN0LmJvdHRvbSAtIGNsaWVudFJlY3QudG9wXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZ2V0RWxlbWVudFJlY3QgKGVsZW1lbnQpIHtcbiAgICAgICAgdmFyIGNsaWVudFJlY3QgPSBnZXRFbGVtZW50Q2xpZW50UmVjdChlbGVtZW50KTtcblxuICAgICAgICBpZiAoIWlzSU9TNyAmJiBjbGllbnRSZWN0KSB7XG4gICAgICAgICAgICB2YXIgc2Nyb2xsID0gZ2V0U2Nyb2xsWFkoZ2V0V2luZG93KGVsZW1lbnQpKTtcblxuICAgICAgICAgICAgY2xpZW50UmVjdC5sZWZ0ICAgKz0gc2Nyb2xsLng7XG4gICAgICAgICAgICBjbGllbnRSZWN0LnJpZ2h0ICArPSBzY3JvbGwueDtcbiAgICAgICAgICAgIGNsaWVudFJlY3QudG9wICAgICs9IHNjcm9sbC55O1xuICAgICAgICAgICAgY2xpZW50UmVjdC5ib3R0b20gKz0gc2Nyb2xsLnk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gY2xpZW50UmVjdDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRUb3VjaFBhaXIgKGV2ZW50KSB7XG4gICAgICAgIHZhciB0b3VjaGVzID0gW107XG5cbiAgICAgICAgLy8gYXJyYXkgb2YgdG91Y2hlcyBpcyBzdXBwbGllZFxuICAgICAgICBpZiAoaXNBcnJheShldmVudCkpIHtcbiAgICAgICAgICAgIHRvdWNoZXNbMF0gPSBldmVudFswXTtcbiAgICAgICAgICAgIHRvdWNoZXNbMV0gPSBldmVudFsxXTtcbiAgICAgICAgfVxuICAgICAgICAvLyBhbiBldmVudFxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmIChldmVudC50eXBlID09PSAndG91Y2hlbmQnKSB7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50LnRvdWNoZXMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIHRvdWNoZXNbMF0gPSBldmVudC50b3VjaGVzWzBdO1xuICAgICAgICAgICAgICAgICAgICB0b3VjaGVzWzFdID0gZXZlbnQuY2hhbmdlZFRvdWNoZXNbMF07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGV2ZW50LnRvdWNoZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHRvdWNoZXNbMF0gPSBldmVudC5jaGFuZ2VkVG91Y2hlc1swXTtcbiAgICAgICAgICAgICAgICAgICAgdG91Y2hlc1sxXSA9IGV2ZW50LmNoYW5nZWRUb3VjaGVzWzFdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRvdWNoZXNbMF0gPSBldmVudC50b3VjaGVzWzBdO1xuICAgICAgICAgICAgICAgIHRvdWNoZXNbMV0gPSBldmVudC50b3VjaGVzWzFdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRvdWNoZXM7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcG9pbnRlckF2ZXJhZ2UgKHBvaW50ZXJzKSB7XG4gICAgICAgIHZhciBhdmVyYWdlID0ge1xuICAgICAgICAgICAgcGFnZVggIDogMCxcbiAgICAgICAgICAgIHBhZ2VZICA6IDAsXG4gICAgICAgICAgICBjbGllbnRYOiAwLFxuICAgICAgICAgICAgY2xpZW50WTogMCxcbiAgICAgICAgICAgIHNjcmVlblg6IDAsXG4gICAgICAgICAgICBzY3JlZW5ZOiAwXG4gICAgICAgIH07XG4gICAgICAgIHZhciBwcm9wO1xuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcG9pbnRlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGZvciAocHJvcCBpbiBhdmVyYWdlKSB7XG4gICAgICAgICAgICAgICAgYXZlcmFnZVtwcm9wXSArPSBwb2ludGVyc1tpXVtwcm9wXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmb3IgKHByb3AgaW4gYXZlcmFnZSkge1xuICAgICAgICAgICAgYXZlcmFnZVtwcm9wXSAvPSBwb2ludGVycy5sZW5ndGg7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYXZlcmFnZTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB0b3VjaEJCb3ggKGV2ZW50KSB7XG4gICAgICAgIGlmICghZXZlbnQubGVuZ3RoICYmICEoZXZlbnQudG91Y2hlcyAmJiBldmVudC50b3VjaGVzLmxlbmd0aCA+IDEpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgdG91Y2hlcyA9IGdldFRvdWNoUGFpcihldmVudCksXG4gICAgICAgICAgICBtaW5YID0gTWF0aC5taW4odG91Y2hlc1swXS5wYWdlWCwgdG91Y2hlc1sxXS5wYWdlWCksXG4gICAgICAgICAgICBtaW5ZID0gTWF0aC5taW4odG91Y2hlc1swXS5wYWdlWSwgdG91Y2hlc1sxXS5wYWdlWSksXG4gICAgICAgICAgICBtYXhYID0gTWF0aC5tYXgodG91Y2hlc1swXS5wYWdlWCwgdG91Y2hlc1sxXS5wYWdlWCksXG4gICAgICAgICAgICBtYXhZID0gTWF0aC5tYXgodG91Y2hlc1swXS5wYWdlWSwgdG91Y2hlc1sxXS5wYWdlWSk7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IG1pblgsXG4gICAgICAgICAgICB5OiBtaW5ZLFxuICAgICAgICAgICAgbGVmdDogbWluWCxcbiAgICAgICAgICAgIHRvcDogbWluWSxcbiAgICAgICAgICAgIHdpZHRoOiBtYXhYIC0gbWluWCxcbiAgICAgICAgICAgIGhlaWdodDogbWF4WSAtIG1pbllcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB0b3VjaERpc3RhbmNlIChldmVudCwgZGVsdGFTb3VyY2UpIHtcbiAgICAgICAgZGVsdGFTb3VyY2UgPSBkZWx0YVNvdXJjZSB8fCBkZWZhdWx0T3B0aW9ucy5kZWx0YVNvdXJjZTtcblxuICAgICAgICB2YXIgc291cmNlWCA9IGRlbHRhU291cmNlICsgJ1gnLFxuICAgICAgICAgICAgc291cmNlWSA9IGRlbHRhU291cmNlICsgJ1knLFxuICAgICAgICAgICAgdG91Y2hlcyA9IGdldFRvdWNoUGFpcihldmVudCk7XG5cblxuICAgICAgICB2YXIgZHggPSB0b3VjaGVzWzBdW3NvdXJjZVhdIC0gdG91Y2hlc1sxXVtzb3VyY2VYXSxcbiAgICAgICAgICAgIGR5ID0gdG91Y2hlc1swXVtzb3VyY2VZXSAtIHRvdWNoZXNbMV1bc291cmNlWV07XG5cbiAgICAgICAgcmV0dXJuIGh5cG90KGR4LCBkeSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdG91Y2hBbmdsZSAoZXZlbnQsIHByZXZBbmdsZSwgZGVsdGFTb3VyY2UpIHtcbiAgICAgICAgZGVsdGFTb3VyY2UgPSBkZWx0YVNvdXJjZSB8fCBkZWZhdWx0T3B0aW9ucy5kZWx0YVNvdXJjZTtcblxuICAgICAgICB2YXIgc291cmNlWCA9IGRlbHRhU291cmNlICsgJ1gnLFxuICAgICAgICAgICAgc291cmNlWSA9IGRlbHRhU291cmNlICsgJ1knLFxuICAgICAgICAgICAgdG91Y2hlcyA9IGdldFRvdWNoUGFpcihldmVudCksXG4gICAgICAgICAgICBkeCA9IHRvdWNoZXNbMF1bc291cmNlWF0gLSB0b3VjaGVzWzFdW3NvdXJjZVhdLFxuICAgICAgICAgICAgZHkgPSB0b3VjaGVzWzBdW3NvdXJjZVldIC0gdG91Y2hlc1sxXVtzb3VyY2VZXSxcbiAgICAgICAgICAgIGFuZ2xlID0gMTgwICogTWF0aC5hdGFuKGR5IC8gZHgpIC8gTWF0aC5QSTtcblxuICAgICAgICBpZiAoaXNOdW1iZXIocHJldkFuZ2xlKSkge1xuICAgICAgICAgICAgdmFyIGRyID0gYW5nbGUgLSBwcmV2QW5nbGUsXG4gICAgICAgICAgICAgICAgZHJDbGFtcGVkID0gZHIgJSAzNjA7XG5cbiAgICAgICAgICAgIGlmIChkckNsYW1wZWQgPiAzMTUpIHtcbiAgICAgICAgICAgICAgICBhbmdsZSAtPSAzNjAgKyAoYW5nbGUgLyAzNjApfDAgKiAzNjA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChkckNsYW1wZWQgPiAxMzUpIHtcbiAgICAgICAgICAgICAgICBhbmdsZSAtPSAxODAgKyAoYW5nbGUgLyAzNjApfDAgKiAzNjA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChkckNsYW1wZWQgPCAtMzE1KSB7XG4gICAgICAgICAgICAgICAgYW5nbGUgKz0gMzYwICsgKGFuZ2xlIC8gMzYwKXwwICogMzYwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoZHJDbGFtcGVkIDwgLTEzNSkge1xuICAgICAgICAgICAgICAgIGFuZ2xlICs9IDE4MCArIChhbmdsZSAvIDM2MCl8MCAqIDM2MDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiAgYW5nbGU7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZ2V0T3JpZ2luWFkgKGludGVyYWN0YWJsZSwgZWxlbWVudCkge1xuICAgICAgICB2YXIgb3JpZ2luID0gaW50ZXJhY3RhYmxlXG4gICAgICAgICAgICAgICAgPyBpbnRlcmFjdGFibGUub3B0aW9ucy5vcmlnaW5cbiAgICAgICAgICAgICAgICA6IGRlZmF1bHRPcHRpb25zLm9yaWdpbjtcblxuICAgICAgICBpZiAob3JpZ2luID09PSAncGFyZW50Jykge1xuICAgICAgICAgICAgb3JpZ2luID0gcGFyZW50RWxlbWVudChlbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChvcmlnaW4gPT09ICdzZWxmJykge1xuICAgICAgICAgICAgb3JpZ2luID0gaW50ZXJhY3RhYmxlLmdldFJlY3QoZWxlbWVudCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodHJ5U2VsZWN0b3Iob3JpZ2luKSkge1xuICAgICAgICAgICAgb3JpZ2luID0gY2xvc2VzdChlbGVtZW50LCBvcmlnaW4pIHx8IHsgeDogMCwgeTogMCB9O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzRnVuY3Rpb24ob3JpZ2luKSkge1xuICAgICAgICAgICAgb3JpZ2luID0gb3JpZ2luKGludGVyYWN0YWJsZSAmJiBlbGVtZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc0VsZW1lbnQob3JpZ2luKSkgIHtcbiAgICAgICAgICAgIG9yaWdpbiA9IGdldEVsZW1lbnRSZWN0KG9yaWdpbik7XG4gICAgICAgIH1cblxuICAgICAgICBvcmlnaW4ueCA9ICgneCcgaW4gb3JpZ2luKT8gb3JpZ2luLnggOiBvcmlnaW4ubGVmdDtcbiAgICAgICAgb3JpZ2luLnkgPSAoJ3knIGluIG9yaWdpbik/IG9yaWdpbi55IDogb3JpZ2luLnRvcDtcblxuICAgICAgICByZXR1cm4gb3JpZ2luO1xuICAgIH1cblxuICAgIC8vIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzU2MzQ1MjgvMjI4MDg4OFxuICAgIGZ1bmN0aW9uIF9nZXRRQmV6aWVyVmFsdWUodCwgcDEsIHAyLCBwMykge1xuICAgICAgICB2YXIgaVQgPSAxIC0gdDtcbiAgICAgICAgcmV0dXJuIGlUICogaVQgKiBwMSArIDIgKiBpVCAqIHQgKiBwMiArIHQgKiB0ICogcDM7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZ2V0UXVhZHJhdGljQ3VydmVQb2ludChzdGFydFgsIHN0YXJ0WSwgY3BYLCBjcFksIGVuZFgsIGVuZFksIHBvc2l0aW9uKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4OiAgX2dldFFCZXppZXJWYWx1ZShwb3NpdGlvbiwgc3RhcnRYLCBjcFgsIGVuZFgpLFxuICAgICAgICAgICAgeTogIF9nZXRRQmV6aWVyVmFsdWUocG9zaXRpb24sIHN0YXJ0WSwgY3BZLCBlbmRZKVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8vIGh0dHA6Ly9naXptYS5jb20vZWFzaW5nL1xuICAgIGZ1bmN0aW9uIGVhc2VPdXRRdWFkICh0LCBiLCBjLCBkKSB7XG4gICAgICAgIHQgLz0gZDtcbiAgICAgICAgcmV0dXJuIC1jICogdCoodC0yKSArIGI7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbm9kZUNvbnRhaW5zIChwYXJlbnQsIGNoaWxkKSB7XG4gICAgICAgIHdoaWxlIChjaGlsZCkge1xuICAgICAgICAgICAgaWYgKGNoaWxkID09PSBwYXJlbnQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC5wYXJlbnROb2RlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNsb3Nlc3QgKGNoaWxkLCBzZWxlY3Rvcikge1xuICAgICAgICB2YXIgcGFyZW50ID0gcGFyZW50RWxlbWVudChjaGlsZCk7XG5cbiAgICAgICAgd2hpbGUgKGlzRWxlbWVudChwYXJlbnQpKSB7XG4gICAgICAgICAgICBpZiAobWF0Y2hlc1NlbGVjdG9yKHBhcmVudCwgc2VsZWN0b3IpKSB7IHJldHVybiBwYXJlbnQ7IH1cblxuICAgICAgICAgICAgcGFyZW50ID0gcGFyZW50RWxlbWVudChwYXJlbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyZW50RWxlbWVudCAobm9kZSkge1xuICAgICAgICB2YXIgcGFyZW50ID0gbm9kZS5wYXJlbnROb2RlO1xuXG4gICAgICAgIGlmIChpc0RvY0ZyYWcocGFyZW50KSkge1xuICAgICAgICAgICAgLy8gc2tpcCBwYXN0ICNzaGFkby1yb290IGZyYWdtZW50c1xuICAgICAgICAgICAgd2hpbGUgKChwYXJlbnQgPSBwYXJlbnQuaG9zdCkgJiYgaXNEb2NGcmFnKHBhcmVudCkpIHt9XG5cbiAgICAgICAgICAgIHJldHVybiBwYXJlbnQ7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcGFyZW50O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGluQ29udGV4dCAoaW50ZXJhY3RhYmxlLCBlbGVtZW50KSB7XG4gICAgICAgIHJldHVybiBpbnRlcmFjdGFibGUuX2NvbnRleHQgPT09IGVsZW1lbnQub3duZXJEb2N1bWVudFxuICAgICAgICAgICAgICAgIHx8IG5vZGVDb250YWlucyhpbnRlcmFjdGFibGUuX2NvbnRleHQsIGVsZW1lbnQpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHRlc3RJZ25vcmUgKGludGVyYWN0YWJsZSwgaW50ZXJhY3RhYmxlRWxlbWVudCwgZWxlbWVudCkge1xuICAgICAgICB2YXIgaWdub3JlRnJvbSA9IGludGVyYWN0YWJsZS5vcHRpb25zLmlnbm9yZUZyb207XG5cbiAgICAgICAgaWYgKCFpZ25vcmVGcm9tIHx8ICFpc0VsZW1lbnQoZWxlbWVudCkpIHsgcmV0dXJuIGZhbHNlOyB9XG5cbiAgICAgICAgaWYgKGlzU3RyaW5nKGlnbm9yZUZyb20pKSB7XG4gICAgICAgICAgICByZXR1cm4gbWF0Y2hlc1VwVG8oZWxlbWVudCwgaWdub3JlRnJvbSwgaW50ZXJhY3RhYmxlRWxlbWVudCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNFbGVtZW50KGlnbm9yZUZyb20pKSB7XG4gICAgICAgICAgICByZXR1cm4gbm9kZUNvbnRhaW5zKGlnbm9yZUZyb20sIGVsZW1lbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHRlc3RBbGxvdyAoaW50ZXJhY3RhYmxlLCBpbnRlcmFjdGFibGVFbGVtZW50LCBlbGVtZW50KSB7XG4gICAgICAgIHZhciBhbGxvd0Zyb20gPSBpbnRlcmFjdGFibGUub3B0aW9ucy5hbGxvd0Zyb207XG5cbiAgICAgICAgaWYgKCFhbGxvd0Zyb20pIHsgcmV0dXJuIHRydWU7IH1cblxuICAgICAgICBpZiAoIWlzRWxlbWVudChlbGVtZW50KSkgeyByZXR1cm4gZmFsc2U7IH1cblxuICAgICAgICBpZiAoaXNTdHJpbmcoYWxsb3dGcm9tKSkge1xuICAgICAgICAgICAgcmV0dXJuIG1hdGNoZXNVcFRvKGVsZW1lbnQsIGFsbG93RnJvbSwgaW50ZXJhY3RhYmxlRWxlbWVudCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNFbGVtZW50KGFsbG93RnJvbSkpIHtcbiAgICAgICAgICAgIHJldHVybiBub2RlQ29udGFpbnMoYWxsb3dGcm9tLCBlbGVtZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjaGVja0F4aXMgKGF4aXMsIGludGVyYWN0YWJsZSkge1xuICAgICAgICBpZiAoIWludGVyYWN0YWJsZSkgeyByZXR1cm4gZmFsc2U7IH1cblxuICAgICAgICB2YXIgdGhpc0F4aXMgPSBpbnRlcmFjdGFibGUub3B0aW9ucy5kcmFnLmF4aXM7XG5cbiAgICAgICAgcmV0dXJuIChheGlzID09PSAneHknIHx8IHRoaXNBeGlzID09PSAneHknIHx8IHRoaXNBeGlzID09PSBheGlzKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjaGVja1NuYXAgKGludGVyYWN0YWJsZSwgYWN0aW9uKSB7XG4gICAgICAgIHZhciBvcHRpb25zID0gaW50ZXJhY3RhYmxlLm9wdGlvbnM7XG5cbiAgICAgICAgaWYgKC9ecmVzaXplLy50ZXN0KGFjdGlvbikpIHtcbiAgICAgICAgICAgIGFjdGlvbiA9ICdyZXNpemUnO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG9wdGlvbnNbYWN0aW9uXS5zbmFwICYmIG9wdGlvbnNbYWN0aW9uXS5zbmFwLmVuYWJsZWQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2hlY2tSZXN0cmljdCAoaW50ZXJhY3RhYmxlLCBhY3Rpb24pIHtcbiAgICAgICAgdmFyIG9wdGlvbnMgPSBpbnRlcmFjdGFibGUub3B0aW9ucztcblxuICAgICAgICBpZiAoL15yZXNpemUvLnRlc3QoYWN0aW9uKSkge1xuICAgICAgICAgICAgYWN0aW9uID0gJ3Jlc2l6ZSc7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gIG9wdGlvbnNbYWN0aW9uXS5yZXN0cmljdCAmJiBvcHRpb25zW2FjdGlvbl0ucmVzdHJpY3QuZW5hYmxlZDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjaGVja0F1dG9TY3JvbGwgKGludGVyYWN0YWJsZSwgYWN0aW9uKSB7XG4gICAgICAgIHZhciBvcHRpb25zID0gaW50ZXJhY3RhYmxlLm9wdGlvbnM7XG5cbiAgICAgICAgaWYgKC9ecmVzaXplLy50ZXN0KGFjdGlvbikpIHtcbiAgICAgICAgICAgIGFjdGlvbiA9ICdyZXNpemUnO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuICBvcHRpb25zW2FjdGlvbl0uYXV0b1Njcm9sbCAmJiBvcHRpb25zW2FjdGlvbl0uYXV0b1Njcm9sbC5lbmFibGVkO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHdpdGhpbkludGVyYWN0aW9uTGltaXQgKGludGVyYWN0YWJsZSwgZWxlbWVudCwgYWN0aW9uKSB7XG4gICAgICAgIHZhciBvcHRpb25zID0gaW50ZXJhY3RhYmxlLm9wdGlvbnMsXG4gICAgICAgICAgICBtYXhBY3Rpb25zID0gb3B0aW9uc1thY3Rpb24ubmFtZV0ubWF4LFxuICAgICAgICAgICAgbWF4UGVyRWxlbWVudCA9IG9wdGlvbnNbYWN0aW9uLm5hbWVdLm1heFBlckVsZW1lbnQsXG4gICAgICAgICAgICBhY3RpdmVJbnRlcmFjdGlvbnMgPSAwLFxuICAgICAgICAgICAgdGFyZ2V0Q291bnQgPSAwLFxuICAgICAgICAgICAgdGFyZ2V0RWxlbWVudENvdW50ID0gMDtcblxuICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gaW50ZXJhY3Rpb25zLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgaW50ZXJhY3Rpb24gPSBpbnRlcmFjdGlvbnNbaV0sXG4gICAgICAgICAgICAgICAgb3RoZXJBY3Rpb24gPSBpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lLFxuICAgICAgICAgICAgICAgIGFjdGl2ZSA9IGludGVyYWN0aW9uLmludGVyYWN0aW5nKCk7XG5cbiAgICAgICAgICAgIGlmICghYWN0aXZlKSB7IGNvbnRpbnVlOyB9XG5cbiAgICAgICAgICAgIGFjdGl2ZUludGVyYWN0aW9ucysrO1xuXG4gICAgICAgICAgICBpZiAoYWN0aXZlSW50ZXJhY3Rpb25zID49IG1heEludGVyYWN0aW9ucykge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGludGVyYWN0aW9uLnRhcmdldCAhPT0gaW50ZXJhY3RhYmxlKSB7IGNvbnRpbnVlOyB9XG5cbiAgICAgICAgICAgIHRhcmdldENvdW50ICs9IChvdGhlckFjdGlvbiA9PT0gYWN0aW9uLm5hbWUpfDA7XG5cbiAgICAgICAgICAgIGlmICh0YXJnZXRDb3VudCA+PSBtYXhBY3Rpb25zKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoaW50ZXJhY3Rpb24uZWxlbWVudCA9PT0gZWxlbWVudCkge1xuICAgICAgICAgICAgICAgIHRhcmdldEVsZW1lbnRDb3VudCsrO1xuXG4gICAgICAgICAgICAgICAgaWYgKG90aGVyQWN0aW9uICE9PSBhY3Rpb24ubmFtZSB8fCB0YXJnZXRFbGVtZW50Q291bnQgPj0gbWF4UGVyRWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG1heEludGVyYWN0aW9ucyA+IDA7XG4gICAgfVxuXG4gICAgLy8gVGVzdCBmb3IgdGhlIGVsZW1lbnQgdGhhdCdzIFwiYWJvdmVcIiBhbGwgb3RoZXIgcXVhbGlmaWVyc1xuICAgIGZ1bmN0aW9uIGluZGV4T2ZEZWVwZXN0RWxlbWVudCAoZWxlbWVudHMpIHtcbiAgICAgICAgdmFyIGRyb3B6b25lLFxuICAgICAgICAgICAgZGVlcGVzdFpvbmUgPSBlbGVtZW50c1swXSxcbiAgICAgICAgICAgIGluZGV4ID0gZGVlcGVzdFpvbmU/IDA6IC0xLFxuICAgICAgICAgICAgcGFyZW50LFxuICAgICAgICAgICAgZGVlcGVzdFpvbmVQYXJlbnRzID0gW10sXG4gICAgICAgICAgICBkcm9wem9uZVBhcmVudHMgPSBbXSxcbiAgICAgICAgICAgIGNoaWxkLFxuICAgICAgICAgICAgaSxcbiAgICAgICAgICAgIG47XG5cbiAgICAgICAgZm9yIChpID0gMTsgaSA8IGVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBkcm9wem9uZSA9IGVsZW1lbnRzW2ldO1xuXG4gICAgICAgICAgICAvLyBhbiBlbGVtZW50IG1pZ2h0IGJlbG9uZyB0byBtdWx0aXBsZSBzZWxlY3RvciBkcm9wem9uZXNcbiAgICAgICAgICAgIGlmICghZHJvcHpvbmUgfHwgZHJvcHpvbmUgPT09IGRlZXBlc3Rab25lKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghZGVlcGVzdFpvbmUpIHtcbiAgICAgICAgICAgICAgICBkZWVwZXN0Wm9uZSA9IGRyb3B6b25lO1xuICAgICAgICAgICAgICAgIGluZGV4ID0gaTtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gY2hlY2sgaWYgdGhlIGRlZXBlc3Qgb3IgY3VycmVudCBhcmUgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50IG9yIGRvY3VtZW50LnJvb3RFbGVtZW50XG4gICAgICAgICAgICAvLyAtIGlmIHRoZSBjdXJyZW50IGRyb3B6b25lIGlzLCBkbyBub3RoaW5nIGFuZCBjb250aW51ZVxuICAgICAgICAgICAgaWYgKGRyb3B6b25lLnBhcmVudE5vZGUgPT09IGRyb3B6b25lLm93bmVyRG9jdW1lbnQpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIC0gaWYgZGVlcGVzdCBpcywgdXBkYXRlIHdpdGggdGhlIGN1cnJlbnQgZHJvcHpvbmUgYW5kIGNvbnRpbnVlIHRvIG5leHRcbiAgICAgICAgICAgIGVsc2UgaWYgKGRlZXBlc3Rab25lLnBhcmVudE5vZGUgPT09IGRyb3B6b25lLm93bmVyRG9jdW1lbnQpIHtcbiAgICAgICAgICAgICAgICBkZWVwZXN0Wm9uZSA9IGRyb3B6b25lO1xuICAgICAgICAgICAgICAgIGluZGV4ID0gaTtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCFkZWVwZXN0Wm9uZVBhcmVudHMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgcGFyZW50ID0gZGVlcGVzdFpvbmU7XG4gICAgICAgICAgICAgICAgd2hpbGUgKHBhcmVudC5wYXJlbnROb2RlICYmIHBhcmVudC5wYXJlbnROb2RlICE9PSBwYXJlbnQub3duZXJEb2N1bWVudCkge1xuICAgICAgICAgICAgICAgICAgICBkZWVwZXN0Wm9uZVBhcmVudHMudW5zaGlmdChwYXJlbnQpO1xuICAgICAgICAgICAgICAgICAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50Tm9kZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGlmIHRoaXMgZWxlbWVudCBpcyBhbiBzdmcgZWxlbWVudCBhbmQgdGhlIGN1cnJlbnQgZGVlcGVzdCBpc1xuICAgICAgICAgICAgLy8gYW4gSFRNTEVsZW1lbnRcbiAgICAgICAgICAgIGlmIChkZWVwZXN0Wm9uZSBpbnN0YW5jZW9mIEhUTUxFbGVtZW50XG4gICAgICAgICAgICAgICAgJiYgZHJvcHpvbmUgaW5zdGFuY2VvZiBTVkdFbGVtZW50XG4gICAgICAgICAgICAgICAgJiYgIShkcm9wem9uZSBpbnN0YW5jZW9mIFNWR1NWR0VsZW1lbnQpKSB7XG5cbiAgICAgICAgICAgICAgICBpZiAoZHJvcHpvbmUgPT09IGRlZXBlc3Rab25lLnBhcmVudE5vZGUpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcGFyZW50ID0gZHJvcHpvbmUub3duZXJTVkdFbGVtZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcGFyZW50ID0gZHJvcHpvbmU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGRyb3B6b25lUGFyZW50cyA9IFtdO1xuXG4gICAgICAgICAgICB3aGlsZSAocGFyZW50LnBhcmVudE5vZGUgIT09IHBhcmVudC5vd25lckRvY3VtZW50KSB7XG4gICAgICAgICAgICAgICAgZHJvcHpvbmVQYXJlbnRzLnVuc2hpZnQocGFyZW50KTtcbiAgICAgICAgICAgICAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50Tm9kZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbiA9IDA7XG5cbiAgICAgICAgICAgIC8vIGdldCAocG9zaXRpb24gb2YgbGFzdCBjb21tb24gYW5jZXN0b3IpICsgMVxuICAgICAgICAgICAgd2hpbGUgKGRyb3B6b25lUGFyZW50c1tuXSAmJiBkcm9wem9uZVBhcmVudHNbbl0gPT09IGRlZXBlc3Rab25lUGFyZW50c1tuXSkge1xuICAgICAgICAgICAgICAgIG4rKztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIHBhcmVudHMgPSBbXG4gICAgICAgICAgICAgICAgZHJvcHpvbmVQYXJlbnRzW24gLSAxXSxcbiAgICAgICAgICAgICAgICBkcm9wem9uZVBhcmVudHNbbl0sXG4gICAgICAgICAgICAgICAgZGVlcGVzdFpvbmVQYXJlbnRzW25dXG4gICAgICAgICAgICBdO1xuXG4gICAgICAgICAgICBjaGlsZCA9IHBhcmVudHNbMF0ubGFzdENoaWxkO1xuXG4gICAgICAgICAgICB3aGlsZSAoY2hpbGQpIHtcbiAgICAgICAgICAgICAgICBpZiAoY2hpbGQgPT09IHBhcmVudHNbMV0pIHtcbiAgICAgICAgICAgICAgICAgICAgZGVlcGVzdFpvbmUgPSBkcm9wem9uZTtcbiAgICAgICAgICAgICAgICAgICAgaW5kZXggPSBpO1xuICAgICAgICAgICAgICAgICAgICBkZWVwZXN0Wm9uZVBhcmVudHMgPSBbXTtcblxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoY2hpbGQgPT09IHBhcmVudHNbMl0pIHtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC5wcmV2aW91c1NpYmxpbmc7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gaW5kZXg7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gSW50ZXJhY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnRhcmdldCAgICAgICAgICA9IG51bGw7IC8vIGN1cnJlbnQgaW50ZXJhY3RhYmxlIGJlaW5nIGludGVyYWN0ZWQgd2l0aFxuICAgICAgICB0aGlzLmVsZW1lbnQgICAgICAgICA9IG51bGw7IC8vIHRoZSB0YXJnZXQgZWxlbWVudCBvZiB0aGUgaW50ZXJhY3RhYmxlXG4gICAgICAgIHRoaXMuZHJvcFRhcmdldCAgICAgID0gbnVsbDsgLy8gdGhlIGRyb3B6b25lIGEgZHJhZyB0YXJnZXQgbWlnaHQgYmUgZHJvcHBlZCBpbnRvXG4gICAgICAgIHRoaXMuZHJvcEVsZW1lbnQgICAgID0gbnVsbDsgLy8gdGhlIGVsZW1lbnQgYXQgdGhlIHRpbWUgb2YgY2hlY2tpbmdcbiAgICAgICAgdGhpcy5wcmV2RHJvcFRhcmdldCAgPSBudWxsOyAvLyB0aGUgZHJvcHpvbmUgdGhhdCB3YXMgcmVjZW50bHkgZHJhZ2dlZCBhd2F5IGZyb21cbiAgICAgICAgdGhpcy5wcmV2RHJvcEVsZW1lbnQgPSBudWxsOyAvLyB0aGUgZWxlbWVudCBhdCB0aGUgdGltZSBvZiBjaGVja2luZ1xuXG4gICAgICAgIHRoaXMucHJlcGFyZWQgICAgICAgID0geyAgICAgLy8gYWN0aW9uIHRoYXQncyByZWFkeSB0byBiZSBmaXJlZCBvbiBuZXh0IG1vdmUgZXZlbnRcbiAgICAgICAgICAgIG5hbWUgOiBudWxsLFxuICAgICAgICAgICAgYXhpcyA6IG51bGwsXG4gICAgICAgICAgICBlZGdlczogbnVsbFxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMubWF0Y2hlcyAgICAgICAgID0gW107ICAgLy8gYWxsIHNlbGVjdG9ycyB0aGF0IGFyZSBtYXRjaGVkIGJ5IHRhcmdldCBlbGVtZW50XG4gICAgICAgIHRoaXMubWF0Y2hFbGVtZW50cyAgID0gW107ICAgLy8gY29ycmVzcG9uZGluZyBlbGVtZW50c1xuXG4gICAgICAgIHRoaXMuaW5lcnRpYVN0YXR1cyA9IHtcbiAgICAgICAgICAgIGFjdGl2ZSAgICAgICA6IGZhbHNlLFxuICAgICAgICAgICAgc21vb3RoRW5kICAgIDogZmFsc2UsXG4gICAgICAgICAgICBlbmRpbmcgICAgICAgOiBmYWxzZSxcblxuICAgICAgICAgICAgc3RhcnRFdmVudDogbnVsbCxcbiAgICAgICAgICAgIHVwQ29vcmRzOiB7fSxcblxuICAgICAgICAgICAgeGU6IDAsIHllOiAwLFxuICAgICAgICAgICAgc3g6IDAsIHN5OiAwLFxuXG4gICAgICAgICAgICB0MDogMCxcbiAgICAgICAgICAgIHZ4MDogMCwgdnlzOiAwLFxuICAgICAgICAgICAgZHVyYXRpb246IDAsXG5cbiAgICAgICAgICAgIHJlc3VtZUR4OiAwLFxuICAgICAgICAgICAgcmVzdW1lRHk6IDAsXG5cbiAgICAgICAgICAgIGxhbWJkYV92MDogMCxcbiAgICAgICAgICAgIG9uZV92ZV92MDogMCxcbiAgICAgICAgICAgIGkgIDogbnVsbFxuICAgICAgICB9O1xuXG4gICAgICAgIGlmIChpc0Z1bmN0aW9uKEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kKSkge1xuICAgICAgICAgICAgdGhpcy5ib3VuZEluZXJ0aWFGcmFtZSA9IHRoaXMuaW5lcnRpYUZyYW1lLmJpbmQodGhpcyk7XG4gICAgICAgICAgICB0aGlzLmJvdW5kU21vb3RoRW5kRnJhbWUgPSB0aGlzLnNtb290aEVuZEZyYW1lLmJpbmQodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXM7XG5cbiAgICAgICAgICAgIHRoaXMuYm91bmRJbmVydGlhRnJhbWUgPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGF0LmluZXJ0aWFGcmFtZSgpOyB9O1xuICAgICAgICAgICAgdGhpcy5ib3VuZFNtb290aEVuZEZyYW1lID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhhdC5zbW9vdGhFbmRGcmFtZSgpOyB9O1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5hY3RpdmVEcm9wcyA9IHtcbiAgICAgICAgICAgIGRyb3B6b25lczogW10sICAgICAgLy8gdGhlIGRyb3B6b25lcyB0aGF0IGFyZSBtZW50aW9uZWQgYmVsb3dcbiAgICAgICAgICAgIGVsZW1lbnRzIDogW10sICAgICAgLy8gZWxlbWVudHMgb2YgZHJvcHpvbmVzIHRoYXQgYWNjZXB0IHRoZSB0YXJnZXQgZHJhZ2dhYmxlXG4gICAgICAgICAgICByZWN0cyAgICA6IFtdICAgICAgIC8vIHRoZSByZWN0cyBvZiB0aGUgZWxlbWVudHMgbWVudGlvbmVkIGFib3ZlXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8ga2VlcCB0cmFjayBvZiBhZGRlZCBwb2ludGVyc1xuICAgICAgICB0aGlzLnBvaW50ZXJzICAgID0gW107XG4gICAgICAgIHRoaXMucG9pbnRlcklkcyAgPSBbXTtcbiAgICAgICAgdGhpcy5kb3duVGFyZ2V0cyA9IFtdO1xuICAgICAgICB0aGlzLmRvd25UaW1lcyAgID0gW107XG4gICAgICAgIHRoaXMuaG9sZFRpbWVycyAgPSBbXTtcblxuICAgICAgICAvLyBQcmV2aW91cyBuYXRpdmUgcG9pbnRlciBtb3ZlIGV2ZW50IGNvb3JkaW5hdGVzXG4gICAgICAgIHRoaXMucHJldkNvb3JkcyA9IHtcbiAgICAgICAgICAgIHBhZ2UgICAgIDogeyB4OiAwLCB5OiAwIH0sXG4gICAgICAgICAgICBjbGllbnQgICA6IHsgeDogMCwgeTogMCB9LFxuICAgICAgICAgICAgdGltZVN0YW1wOiAwXG4gICAgICAgIH07XG4gICAgICAgIC8vIGN1cnJlbnQgbmF0aXZlIHBvaW50ZXIgbW92ZSBldmVudCBjb29yZGluYXRlc1xuICAgICAgICB0aGlzLmN1ckNvb3JkcyA9IHtcbiAgICAgICAgICAgIHBhZ2UgICAgIDogeyB4OiAwLCB5OiAwIH0sXG4gICAgICAgICAgICBjbGllbnQgICA6IHsgeDogMCwgeTogMCB9LFxuICAgICAgICAgICAgdGltZVN0YW1wOiAwXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gU3RhcnRpbmcgSW50ZXJhY3RFdmVudCBwb2ludGVyIGNvb3JkaW5hdGVzXG4gICAgICAgIHRoaXMuc3RhcnRDb29yZHMgPSB7XG4gICAgICAgICAgICBwYWdlICAgICA6IHsgeDogMCwgeTogMCB9LFxuICAgICAgICAgICAgY2xpZW50ICAgOiB7IHg6IDAsIHk6IDAgfSxcbiAgICAgICAgICAgIHRpbWVTdGFtcDogMFxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIENoYW5nZSBpbiBjb29yZGluYXRlcyBhbmQgdGltZSBvZiB0aGUgcG9pbnRlclxuICAgICAgICB0aGlzLnBvaW50ZXJEZWx0YSA9IHtcbiAgICAgICAgICAgIHBhZ2UgICAgIDogeyB4OiAwLCB5OiAwLCB2eDogMCwgdnk6IDAsIHNwZWVkOiAwIH0sXG4gICAgICAgICAgICBjbGllbnQgICA6IHsgeDogMCwgeTogMCwgdng6IDAsIHZ5OiAwLCBzcGVlZDogMCB9LFxuICAgICAgICAgICAgdGltZVN0YW1wOiAwXG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5kb3duRXZlbnQgICA9IG51bGw7ICAgIC8vIHBvaW50ZXJkb3duL21vdXNlZG93bi90b3VjaHN0YXJ0IGV2ZW50XG4gICAgICAgIHRoaXMuZG93blBvaW50ZXIgPSB7fTtcblxuICAgICAgICB0aGlzLl9ldmVudFRhcmdldCAgICA9IG51bGw7XG4gICAgICAgIHRoaXMuX2N1ckV2ZW50VGFyZ2V0ID0gbnVsbDtcblxuICAgICAgICB0aGlzLnByZXZFdmVudCA9IG51bGw7ICAgICAgLy8gcHJldmlvdXMgYWN0aW9uIGV2ZW50XG4gICAgICAgIHRoaXMudGFwVGltZSAgID0gMDsgICAgICAgICAvLyB0aW1lIG9mIHRoZSBtb3N0IHJlY2VudCB0YXAgZXZlbnRcbiAgICAgICAgdGhpcy5wcmV2VGFwICAgPSBudWxsO1xuXG4gICAgICAgIHRoaXMuc3RhcnRPZmZzZXQgICAgPSB7IGxlZnQ6IDAsIHJpZ2h0OiAwLCB0b3A6IDAsIGJvdHRvbTogMCB9O1xuICAgICAgICB0aGlzLnJlc3RyaWN0T2Zmc2V0ID0geyBsZWZ0OiAwLCByaWdodDogMCwgdG9wOiAwLCBib3R0b206IDAgfTtcbiAgICAgICAgdGhpcy5zbmFwT2Zmc2V0cyAgICA9IFtdO1xuXG4gICAgICAgIHRoaXMuZ2VzdHVyZSA9IHtcbiAgICAgICAgICAgIHN0YXJ0OiB7IHg6IDAsIHk6IDAgfSxcblxuICAgICAgICAgICAgc3RhcnREaXN0YW5jZTogMCwgICAvLyBkaXN0YW5jZSBiZXR3ZWVuIHR3byB0b3VjaGVzIG9mIHRvdWNoU3RhcnRcbiAgICAgICAgICAgIHByZXZEaXN0YW5jZSA6IDAsXG4gICAgICAgICAgICBkaXN0YW5jZSAgICAgOiAwLFxuXG4gICAgICAgICAgICBzY2FsZTogMSwgICAgICAgICAgIC8vIGdlc3R1cmUuZGlzdGFuY2UgLyBnZXN0dXJlLnN0YXJ0RGlzdGFuY2VcblxuICAgICAgICAgICAgc3RhcnRBbmdsZTogMCwgICAgICAvLyBhbmdsZSBvZiBsaW5lIGpvaW5pbmcgdHdvIHRvdWNoZXNcbiAgICAgICAgICAgIHByZXZBbmdsZSA6IDAgICAgICAgLy8gYW5nbGUgb2YgdGhlIHByZXZpb3VzIGdlc3R1cmUgZXZlbnRcbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLnNuYXBTdGF0dXMgPSB7XG4gICAgICAgICAgICB4ICAgICAgIDogMCwgeSAgICAgICA6IDAsXG4gICAgICAgICAgICBkeCAgICAgIDogMCwgZHkgICAgICA6IDAsXG4gICAgICAgICAgICByZWFsWCAgIDogMCwgcmVhbFkgICA6IDAsXG4gICAgICAgICAgICBzbmFwcGVkWDogMCwgc25hcHBlZFk6IDAsXG4gICAgICAgICAgICB0YXJnZXRzIDogW10sXG4gICAgICAgICAgICBsb2NrZWQgIDogZmFsc2UsXG4gICAgICAgICAgICBjaGFuZ2VkIDogZmFsc2VcbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLnJlc3RyaWN0U3RhdHVzID0ge1xuICAgICAgICAgICAgZHggICAgICAgICA6IDAsIGR5ICAgICAgICAgOiAwLFxuICAgICAgICAgICAgcmVzdHJpY3RlZFg6IDAsIHJlc3RyaWN0ZWRZOiAwLFxuICAgICAgICAgICAgc25hcCAgICAgICA6IG51bGwsXG4gICAgICAgICAgICByZXN0cmljdGVkIDogZmFsc2UsXG4gICAgICAgICAgICBjaGFuZ2VkICAgIDogZmFsc2VcbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLnJlc3RyaWN0U3RhdHVzLnNuYXAgPSB0aGlzLnNuYXBTdGF0dXM7XG5cbiAgICAgICAgdGhpcy5wb2ludGVySXNEb3duICAgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5wb2ludGVyV2FzTW92ZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5nZXN0dXJpbmcgICAgICAgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5kcmFnZ2luZyAgICAgICAgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5yZXNpemluZyAgICAgICAgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5yZXNpemVBeGVzICAgICAgPSAneHknO1xuXG4gICAgICAgIHRoaXMubW91c2UgPSBmYWxzZTtcblxuICAgICAgICBpbnRlcmFjdGlvbnMucHVzaCh0aGlzKTtcbiAgICB9XG5cbiAgICBJbnRlcmFjdGlvbi5wcm90b3R5cGUgPSB7XG4gICAgICAgIGdldFBhZ2VYWSAgOiBmdW5jdGlvbiAocG9pbnRlciwgeHkpIHsgcmV0dXJuICAgZ2V0UGFnZVhZKHBvaW50ZXIsIHh5LCB0aGlzKTsgfSxcbiAgICAgICAgZ2V0Q2xpZW50WFk6IGZ1bmN0aW9uIChwb2ludGVyLCB4eSkgeyByZXR1cm4gZ2V0Q2xpZW50WFkocG9pbnRlciwgeHksIHRoaXMpOyB9LFxuICAgICAgICBzZXRFdmVudFhZIDogZnVuY3Rpb24gKHRhcmdldCwgcHRyKSB7IHJldHVybiAgc2V0RXZlbnRYWSh0YXJnZXQsIHB0ciwgdGhpcyk7IH0sXG5cbiAgICAgICAgcG9pbnRlck92ZXI6IGZ1bmN0aW9uIChwb2ludGVyLCBldmVudCwgZXZlbnRUYXJnZXQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnByZXBhcmVkLm5hbWUgfHwgIXRoaXMubW91c2UpIHsgcmV0dXJuOyB9XG5cbiAgICAgICAgICAgIHZhciBjdXJNYXRjaGVzID0gW10sXG4gICAgICAgICAgICAgICAgY3VyTWF0Y2hFbGVtZW50cyA9IFtdLFxuICAgICAgICAgICAgICAgIHByZXZUYXJnZXRFbGVtZW50ID0gdGhpcy5lbGVtZW50O1xuXG4gICAgICAgICAgICB0aGlzLmFkZFBvaW50ZXIocG9pbnRlcik7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnRhcmdldFxuICAgICAgICAgICAgICAgICYmICh0ZXN0SWdub3JlKHRoaXMudGFyZ2V0LCB0aGlzLmVsZW1lbnQsIGV2ZW50VGFyZ2V0KVxuICAgICAgICAgICAgICAgICAgICB8fCAhdGVzdEFsbG93KHRoaXMudGFyZ2V0LCB0aGlzLmVsZW1lbnQsIGV2ZW50VGFyZ2V0KSkpIHtcbiAgICAgICAgICAgICAgICAvLyBpZiB0aGUgZXZlbnRUYXJnZXQgc2hvdWxkIGJlIGlnbm9yZWQgb3Igc2hvdWxkbid0IGJlIGFsbG93ZWRcbiAgICAgICAgICAgICAgICAvLyBjbGVhciB0aGUgcHJldmlvdXMgdGFyZ2V0XG4gICAgICAgICAgICAgICAgdGhpcy50YXJnZXQgPSBudWxsO1xuICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudCA9IG51bGw7XG4gICAgICAgICAgICAgICAgdGhpcy5tYXRjaGVzID0gW107XG4gICAgICAgICAgICAgICAgdGhpcy5tYXRjaEVsZW1lbnRzID0gW107XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBlbGVtZW50SW50ZXJhY3RhYmxlID0gaW50ZXJhY3RhYmxlcy5nZXQoZXZlbnRUYXJnZXQpLFxuICAgICAgICAgICAgICAgIGVsZW1lbnRBY3Rpb24gPSAoZWxlbWVudEludGVyYWN0YWJsZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgIXRlc3RJZ25vcmUoZWxlbWVudEludGVyYWN0YWJsZSwgZXZlbnRUYXJnZXQsIGV2ZW50VGFyZ2V0KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgdGVzdEFsbG93KGVsZW1lbnRJbnRlcmFjdGFibGUsIGV2ZW50VGFyZ2V0LCBldmVudFRhcmdldClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIHZhbGlkYXRlQWN0aW9uKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRJbnRlcmFjdGFibGUuZ2V0QWN0aW9uKHBvaW50ZXIsIGV2ZW50LCB0aGlzLCBldmVudFRhcmdldCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudEludGVyYWN0YWJsZSkpO1xuXG4gICAgICAgICAgICBpZiAoZWxlbWVudEFjdGlvbiAmJiAhd2l0aGluSW50ZXJhY3Rpb25MaW1pdChlbGVtZW50SW50ZXJhY3RhYmxlLCBldmVudFRhcmdldCwgZWxlbWVudEFjdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgZWxlbWVudEFjdGlvbiA9IG51bGw7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZ1bmN0aW9uIHB1c2hDdXJNYXRjaGVzIChpbnRlcmFjdGFibGUsIHNlbGVjdG9yKSB7XG4gICAgICAgICAgICAgICAgaWYgKGludGVyYWN0YWJsZVxuICAgICAgICAgICAgICAgICAgICAmJiBpbkNvbnRleHQoaW50ZXJhY3RhYmxlLCBldmVudFRhcmdldClcbiAgICAgICAgICAgICAgICAgICAgJiYgIXRlc3RJZ25vcmUoaW50ZXJhY3RhYmxlLCBldmVudFRhcmdldCwgZXZlbnRUYXJnZXQpXG4gICAgICAgICAgICAgICAgICAgICYmIHRlc3RBbGxvdyhpbnRlcmFjdGFibGUsIGV2ZW50VGFyZ2V0LCBldmVudFRhcmdldClcbiAgICAgICAgICAgICAgICAgICAgJiYgbWF0Y2hlc1NlbGVjdG9yKGV2ZW50VGFyZ2V0LCBzZWxlY3RvcikpIHtcblxuICAgICAgICAgICAgICAgICAgICBjdXJNYXRjaGVzLnB1c2goaW50ZXJhY3RhYmxlKTtcbiAgICAgICAgICAgICAgICAgICAgY3VyTWF0Y2hFbGVtZW50cy5wdXNoKGV2ZW50VGFyZ2V0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChlbGVtZW50QWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgdGhpcy50YXJnZXQgPSBlbGVtZW50SW50ZXJhY3RhYmxlO1xuICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudCA9IGV2ZW50VGFyZ2V0O1xuICAgICAgICAgICAgICAgIHRoaXMubWF0Y2hlcyA9IFtdO1xuICAgICAgICAgICAgICAgIHRoaXMubWF0Y2hFbGVtZW50cyA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaW50ZXJhY3RhYmxlcy5mb3JFYWNoU2VsZWN0b3IocHVzaEN1ck1hdGNoZXMpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMudmFsaWRhdGVTZWxlY3Rvcihwb2ludGVyLCBldmVudCwgY3VyTWF0Y2hlcywgY3VyTWF0Y2hFbGVtZW50cykpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tYXRjaGVzID0gY3VyTWF0Y2hlcztcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tYXRjaEVsZW1lbnRzID0gY3VyTWF0Y2hFbGVtZW50cztcblxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBvaW50ZXJIb3Zlcihwb2ludGVyLCBldmVudCwgdGhpcy5tYXRjaGVzLCB0aGlzLm1hdGNoRWxlbWVudHMpO1xuICAgICAgICAgICAgICAgICAgICBldmVudHMuYWRkKGV2ZW50VGFyZ2V0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1cHBvcnRzUG9pbnRlckV2ZW50PyBwRXZlbnRUeXBlcy5tb3ZlIDogJ21vdXNlbW92ZScsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXJzLnBvaW50ZXJIb3Zlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMudGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChub2RlQ29udGFpbnMocHJldlRhcmdldEVsZW1lbnQsIGV2ZW50VGFyZ2V0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wb2ludGVySG92ZXIocG9pbnRlciwgZXZlbnQsIHRoaXMubWF0Y2hlcywgdGhpcy5tYXRjaEVsZW1lbnRzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5hZGQodGhpcy5lbGVtZW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXBwb3J0c1BvaW50ZXJFdmVudD8gcEV2ZW50VHlwZXMubW92ZSA6ICdtb3VzZW1vdmUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnMucG9pbnRlckhvdmVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudGFyZ2V0ID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudCA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1hdGNoZXMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubWF0Y2hFbGVtZW50cyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIC8vIENoZWNrIHdoYXQgYWN0aW9uIHdvdWxkIGJlIHBlcmZvcm1lZCBvbiBwb2ludGVyTW92ZSB0YXJnZXQgaWYgYSBtb3VzZVxuICAgICAgICAvLyBidXR0b24gd2VyZSBwcmVzc2VkIGFuZCBjaGFuZ2UgdGhlIGN1cnNvciBhY2NvcmRpbmdseVxuICAgICAgICBwb2ludGVySG92ZXI6IGZ1bmN0aW9uIChwb2ludGVyLCBldmVudCwgZXZlbnRUYXJnZXQsIGN1ckV2ZW50VGFyZ2V0LCBtYXRjaGVzLCBtYXRjaEVsZW1lbnRzKSB7XG4gICAgICAgICAgICB2YXIgdGFyZ2V0ID0gdGhpcy50YXJnZXQ7XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5wcmVwYXJlZC5uYW1lICYmIHRoaXMubW91c2UpIHtcblxuICAgICAgICAgICAgICAgIHZhciBhY3Rpb247XG5cbiAgICAgICAgICAgICAgICAvLyB1cGRhdGUgcG9pbnRlciBjb29yZHMgZm9yIGRlZmF1bHRBY3Rpb25DaGVja2VyIHRvIHVzZVxuICAgICAgICAgICAgICAgIHRoaXMuc2V0RXZlbnRYWSh0aGlzLmN1ckNvb3JkcywgW3BvaW50ZXJdKTtcblxuICAgICAgICAgICAgICAgIGlmIChtYXRjaGVzKSB7XG4gICAgICAgICAgICAgICAgICAgIGFjdGlvbiA9IHRoaXMudmFsaWRhdGVTZWxlY3Rvcihwb2ludGVyLCBldmVudCwgbWF0Y2hlcywgbWF0Y2hFbGVtZW50cyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHRhcmdldCkge1xuICAgICAgICAgICAgICAgICAgICBhY3Rpb24gPSB2YWxpZGF0ZUFjdGlvbih0YXJnZXQuZ2V0QWN0aW9uKHRoaXMucG9pbnRlcnNbMF0sIGV2ZW50LCB0aGlzLCB0aGlzLmVsZW1lbnQpLCB0aGlzLnRhcmdldCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKHRhcmdldCAmJiB0YXJnZXQub3B0aW9ucy5zdHlsZUN1cnNvcikge1xuICAgICAgICAgICAgICAgICAgICBpZiAoYWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQuX2RvYy5kb2N1bWVudEVsZW1lbnQuc3R5bGUuY3Vyc29yID0gZ2V0QWN0aW9uQ3Vyc29yKGFjdGlvbik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQuX2RvYy5kb2N1bWVudEVsZW1lbnQuc3R5bGUuY3Vyc29yID0gJyc7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh0aGlzLnByZXBhcmVkLm5hbWUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNoZWNrQW5kUHJldmVudERlZmF1bHQoZXZlbnQsIHRhcmdldCwgdGhpcy5lbGVtZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICBwb2ludGVyT3V0OiBmdW5jdGlvbiAocG9pbnRlciwgZXZlbnQsIGV2ZW50VGFyZ2V0KSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wcmVwYXJlZC5uYW1lKSB7IHJldHVybjsgfVxuXG4gICAgICAgICAgICAvLyBSZW1vdmUgdGVtcG9yYXJ5IGV2ZW50IGxpc3RlbmVycyBmb3Igc2VsZWN0b3IgSW50ZXJhY3RhYmxlc1xuICAgICAgICAgICAgaWYgKCFpbnRlcmFjdGFibGVzLmdldChldmVudFRhcmdldCkpIHtcbiAgICAgICAgICAgICAgICBldmVudHMucmVtb3ZlKGV2ZW50VGFyZ2V0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VwcG9ydHNQb2ludGVyRXZlbnQ/IHBFdmVudFR5cGVzLm1vdmUgOiAnbW91c2Vtb3ZlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3RlbmVycy5wb2ludGVySG92ZXIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy50YXJnZXQgJiYgdGhpcy50YXJnZXQub3B0aW9ucy5zdHlsZUN1cnNvciAmJiAhdGhpcy5pbnRlcmFjdGluZygpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy50YXJnZXQuX2RvYy5kb2N1bWVudEVsZW1lbnQuc3R5bGUuY3Vyc29yID0gJyc7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgc2VsZWN0b3JEb3duOiBmdW5jdGlvbiAocG9pbnRlciwgZXZlbnQsIGV2ZW50VGFyZ2V0LCBjdXJFdmVudFRhcmdldCkge1xuICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzLFxuICAgICAgICAgICAgICAgIC8vIGNvcHkgZXZlbnQgdG8gYmUgdXNlZCBpbiB0aW1lb3V0IGZvciBJRThcbiAgICAgICAgICAgICAgICBldmVudENvcHkgPSBldmVudHMudXNlQXR0YWNoRXZlbnQ/IGV4dGVuZCh7fSwgZXZlbnQpIDogZXZlbnQsXG4gICAgICAgICAgICAgICAgZWxlbWVudCA9IGV2ZW50VGFyZ2V0LFxuICAgICAgICAgICAgICAgIHBvaW50ZXJJbmRleCA9IHRoaXMuYWRkUG9pbnRlcihwb2ludGVyKSxcbiAgICAgICAgICAgICAgICBhY3Rpb247XG5cbiAgICAgICAgICAgIHRoaXMuaG9sZFRpbWVyc1twb2ludGVySW5kZXhdID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdGhhdC5wb2ludGVySG9sZChldmVudHMudXNlQXR0YWNoRXZlbnQ/IGV2ZW50Q29weSA6IHBvaW50ZXIsIGV2ZW50Q29weSwgZXZlbnRUYXJnZXQsIGN1ckV2ZW50VGFyZ2V0KTtcbiAgICAgICAgICAgIH0sIGRlZmF1bHRPcHRpb25zLl9ob2xkRHVyYXRpb24pO1xuXG4gICAgICAgICAgICB0aGlzLnBvaW50ZXJJc0Rvd24gPSB0cnVlO1xuXG4gICAgICAgICAgICAvLyBDaGVjayBpZiB0aGUgZG93biBldmVudCBoaXRzIHRoZSBjdXJyZW50IGluZXJ0aWEgdGFyZ2V0XG4gICAgICAgICAgICBpZiAodGhpcy5pbmVydGlhU3RhdHVzLmFjdGl2ZSAmJiB0aGlzLnRhcmdldC5zZWxlY3Rvcikge1xuICAgICAgICAgICAgICAgIC8vIGNsaW1iIHVwIHRoZSBET00gdHJlZSBmcm9tIHRoZSBldmVudCB0YXJnZXRcbiAgICAgICAgICAgICAgICB3aGlsZSAoaXNFbGVtZW50KGVsZW1lbnQpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gaWYgdGhpcyBlbGVtZW50IGlzIHRoZSBjdXJyZW50IGluZXJ0aWEgdGFyZ2V0IGVsZW1lbnRcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQgPT09IHRoaXMuZWxlbWVudFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gYW5kIHRoZSBwcm9zcGVjdGl2ZSBhY3Rpb24gaXMgdGhlIHNhbWUgYXMgdGhlIG9uZ29pbmcgb25lXG4gICAgICAgICAgICAgICAgICAgICAgICAmJiB2YWxpZGF0ZUFjdGlvbih0aGlzLnRhcmdldC5nZXRBY3Rpb24ocG9pbnRlciwgZXZlbnQsIHRoaXMsIHRoaXMuZWxlbWVudCksIHRoaXMudGFyZ2V0KS5uYW1lID09PSB0aGlzLnByZXBhcmVkLm5hbWUpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3RvcCBpbmVydGlhIHNvIHRoYXQgdGhlIG5leHQgbW92ZSB3aWxsIGJlIGEgbm9ybWFsIG9uZVxuICAgICAgICAgICAgICAgICAgICAgICAgY2FuY2VsRnJhbWUodGhpcy5pbmVydGlhU3RhdHVzLmkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbmVydGlhU3RhdHVzLmFjdGl2ZSA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbGxlY3RFdmVudFRhcmdldHMocG9pbnRlciwgZXZlbnQsIGV2ZW50VGFyZ2V0LCAnZG93bicpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQgPSBwYXJlbnRFbGVtZW50KGVsZW1lbnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gZG8gbm90aGluZyBpZiBpbnRlcmFjdGluZ1xuICAgICAgICAgICAgaWYgKHRoaXMuaW50ZXJhY3RpbmcoKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuY29sbGVjdEV2ZW50VGFyZ2V0cyhwb2ludGVyLCBldmVudCwgZXZlbnRUYXJnZXQsICdkb3duJyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmdW5jdGlvbiBwdXNoTWF0Y2hlcyAoaW50ZXJhY3RhYmxlLCBzZWxlY3RvciwgY29udGV4dCkge1xuICAgICAgICAgICAgICAgIHZhciBlbGVtZW50cyA9IGllOE1hdGNoZXNTZWxlY3RvclxuICAgICAgICAgICAgICAgICAgICA/IGNvbnRleHQucXVlcnlTZWxlY3RvckFsbChzZWxlY3RvcilcbiAgICAgICAgICAgICAgICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgICAgICAgICBpZiAoaW5Db250ZXh0KGludGVyYWN0YWJsZSwgZWxlbWVudClcbiAgICAgICAgICAgICAgICAgICAgJiYgIXRlc3RJZ25vcmUoaW50ZXJhY3RhYmxlLCBlbGVtZW50LCBldmVudFRhcmdldClcbiAgICAgICAgICAgICAgICAgICAgJiYgdGVzdEFsbG93KGludGVyYWN0YWJsZSwgZWxlbWVudCwgZXZlbnRUYXJnZXQpXG4gICAgICAgICAgICAgICAgICAgICYmIG1hdGNoZXNTZWxlY3RvcihlbGVtZW50LCBzZWxlY3RvciwgZWxlbWVudHMpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgdGhhdC5tYXRjaGVzLnB1c2goaW50ZXJhY3RhYmxlKTtcbiAgICAgICAgICAgICAgICAgICAgdGhhdC5tYXRjaEVsZW1lbnRzLnB1c2goZWxlbWVudCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyB1cGRhdGUgcG9pbnRlciBjb29yZHMgZm9yIGRlZmF1bHRBY3Rpb25DaGVja2VyIHRvIHVzZVxuICAgICAgICAgICAgdGhpcy5zZXRFdmVudFhZKHRoaXMuY3VyQ29vcmRzLCBbcG9pbnRlcl0pO1xuICAgICAgICAgICAgdGhpcy5kb3duRXZlbnQgPSBldmVudDtcblxuICAgICAgICAgICAgd2hpbGUgKGlzRWxlbWVudChlbGVtZW50KSAmJiAhYWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5tYXRjaGVzID0gW107XG4gICAgICAgICAgICAgICAgdGhpcy5tYXRjaEVsZW1lbnRzID0gW107XG5cbiAgICAgICAgICAgICAgICBpbnRlcmFjdGFibGVzLmZvckVhY2hTZWxlY3RvcihwdXNoTWF0Y2hlcyk7XG5cbiAgICAgICAgICAgICAgICBhY3Rpb24gPSB0aGlzLnZhbGlkYXRlU2VsZWN0b3IocG9pbnRlciwgZXZlbnQsIHRoaXMubWF0Y2hlcywgdGhpcy5tYXRjaEVsZW1lbnRzKTtcbiAgICAgICAgICAgICAgICBlbGVtZW50ID0gcGFyZW50RWxlbWVudChlbGVtZW50KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGFjdGlvbikge1xuICAgICAgICAgICAgICAgIHRoaXMucHJlcGFyZWQubmFtZSAgPSBhY3Rpb24ubmFtZTtcbiAgICAgICAgICAgICAgICB0aGlzLnByZXBhcmVkLmF4aXMgID0gYWN0aW9uLmF4aXM7XG4gICAgICAgICAgICAgICAgdGhpcy5wcmVwYXJlZC5lZGdlcyA9IGFjdGlvbi5lZGdlcztcblxuICAgICAgICAgICAgICAgIHRoaXMuY29sbGVjdEV2ZW50VGFyZ2V0cyhwb2ludGVyLCBldmVudCwgZXZlbnRUYXJnZXQsICdkb3duJyk7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wb2ludGVyRG93bihwb2ludGVyLCBldmVudCwgZXZlbnRUYXJnZXQsIGN1ckV2ZW50VGFyZ2V0LCBhY3Rpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gZG8gdGhlc2Ugbm93IHNpbmNlIHBvaW50ZXJEb3duIGlzbid0IGJlaW5nIGNhbGxlZCBmcm9tIGhlcmVcbiAgICAgICAgICAgICAgICB0aGlzLmRvd25UaW1lc1twb2ludGVySW5kZXhdID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5kb3duVGFyZ2V0c1twb2ludGVySW5kZXhdID0gZXZlbnRUYXJnZXQ7XG4gICAgICAgICAgICAgICAgcG9pbnRlckV4dGVuZCh0aGlzLmRvd25Qb2ludGVyLCBwb2ludGVyKTtcblxuICAgICAgICAgICAgICAgIGNvcHlDb29yZHModGhpcy5wcmV2Q29vcmRzLCB0aGlzLmN1ckNvb3Jkcyk7XG4gICAgICAgICAgICAgICAgdGhpcy5wb2ludGVyV2FzTW92ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5jb2xsZWN0RXZlbnRUYXJnZXRzKHBvaW50ZXIsIGV2ZW50LCBldmVudFRhcmdldCwgJ2Rvd24nKTtcbiAgICAgICAgfSxcblxuICAgICAgICAvLyBEZXRlcm1pbmUgYWN0aW9uIHRvIGJlIHBlcmZvcm1lZCBvbiBuZXh0IHBvaW50ZXJNb3ZlIGFuZCBhZGQgYXBwcm9wcmlhdGVcbiAgICAgICAgLy8gc3R5bGUgYW5kIGV2ZW50IExpc3RlbmVyc1xuICAgICAgICBwb2ludGVyRG93bjogZnVuY3Rpb24gKHBvaW50ZXIsIGV2ZW50LCBldmVudFRhcmdldCwgY3VyRXZlbnRUYXJnZXQsIGZvcmNlQWN0aW9uKSB7XG4gICAgICAgICAgICBpZiAoIWZvcmNlQWN0aW9uICYmICF0aGlzLmluZXJ0aWFTdGF0dXMuYWN0aXZlICYmIHRoaXMucG9pbnRlcldhc01vdmVkICYmIHRoaXMucHJlcGFyZWQubmFtZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuY2hlY2tBbmRQcmV2ZW50RGVmYXVsdChldmVudCwgdGhpcy50YXJnZXQsIHRoaXMuZWxlbWVudCk7XG5cbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMucG9pbnRlcklzRG93biA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLmRvd25FdmVudCA9IGV2ZW50O1xuXG4gICAgICAgICAgICB2YXIgcG9pbnRlckluZGV4ID0gdGhpcy5hZGRQb2ludGVyKHBvaW50ZXIpLFxuICAgICAgICAgICAgICAgIGFjdGlvbjtcblxuICAgICAgICAgICAgLy8gSWYgaXQgaXMgdGhlIHNlY29uZCB0b3VjaCBvZiBhIG11bHRpLXRvdWNoIGdlc3R1cmUsIGtlZXAgdGhlXG4gICAgICAgICAgICAvLyB0YXJnZXQgdGhlIHNhbWUgYW5kIGdldCBhIG5ldyBhY3Rpb24gaWYgYSB0YXJnZXQgd2FzIHNldCBieSB0aGVcbiAgICAgICAgICAgIC8vIGZpcnN0IHRvdWNoXG4gICAgICAgICAgICBpZiAodGhpcy5wb2ludGVySWRzLmxlbmd0aCA+IDEgJiYgdGhpcy50YXJnZXQuX2VsZW1lbnQgPT09IHRoaXMuZWxlbWVudCkge1xuICAgICAgICAgICAgICAgIHZhciBuZXdBY3Rpb24gPSB2YWxpZGF0ZUFjdGlvbihmb3JjZUFjdGlvbiB8fCB0aGlzLnRhcmdldC5nZXRBY3Rpb24ocG9pbnRlciwgZXZlbnQsIHRoaXMsIHRoaXMuZWxlbWVudCksIHRoaXMudGFyZ2V0KTtcblxuICAgICAgICAgICAgICAgIGlmICh3aXRoaW5JbnRlcmFjdGlvbkxpbWl0KHRoaXMudGFyZ2V0LCB0aGlzLmVsZW1lbnQsIG5ld0FjdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgYWN0aW9uID0gbmV3QWN0aW9uO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMucHJlcGFyZWQubmFtZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBPdGhlcndpc2UsIHNldCB0aGUgdGFyZ2V0IGlmIHRoZXJlIGlzIG5vIGFjdGlvbiBwcmVwYXJlZFxuICAgICAgICAgICAgZWxzZSBpZiAoIXRoaXMucHJlcGFyZWQubmFtZSkge1xuICAgICAgICAgICAgICAgIHZhciBpbnRlcmFjdGFibGUgPSBpbnRlcmFjdGFibGVzLmdldChjdXJFdmVudFRhcmdldCk7XG5cbiAgICAgICAgICAgICAgICBpZiAoaW50ZXJhY3RhYmxlXG4gICAgICAgICAgICAgICAgICAgICYmICF0ZXN0SWdub3JlKGludGVyYWN0YWJsZSwgY3VyRXZlbnRUYXJnZXQsIGV2ZW50VGFyZ2V0KVxuICAgICAgICAgICAgICAgICAgICAmJiB0ZXN0QWxsb3coaW50ZXJhY3RhYmxlLCBjdXJFdmVudFRhcmdldCwgZXZlbnRUYXJnZXQpXG4gICAgICAgICAgICAgICAgICAgICYmIChhY3Rpb24gPSB2YWxpZGF0ZUFjdGlvbihmb3JjZUFjdGlvbiB8fCBpbnRlcmFjdGFibGUuZ2V0QWN0aW9uKHBvaW50ZXIsIGV2ZW50LCB0aGlzLCBjdXJFdmVudFRhcmdldCksIGludGVyYWN0YWJsZSwgZXZlbnRUYXJnZXQpKVxuICAgICAgICAgICAgICAgICAgICAmJiB3aXRoaW5JbnRlcmFjdGlvbkxpbWl0KGludGVyYWN0YWJsZSwgY3VyRXZlbnRUYXJnZXQsIGFjdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50YXJnZXQgPSBpbnRlcmFjdGFibGU7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudCA9IGN1ckV2ZW50VGFyZ2V0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIHRhcmdldCA9IHRoaXMudGFyZ2V0LFxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB0YXJnZXQgJiYgdGFyZ2V0Lm9wdGlvbnM7XG5cbiAgICAgICAgICAgIGlmICh0YXJnZXQgJiYgKGZvcmNlQWN0aW9uIHx8ICF0aGlzLnByZXBhcmVkLm5hbWUpKSB7XG4gICAgICAgICAgICAgICAgYWN0aW9uID0gYWN0aW9uIHx8IHZhbGlkYXRlQWN0aW9uKGZvcmNlQWN0aW9uIHx8IHRhcmdldC5nZXRBY3Rpb24ocG9pbnRlciwgZXZlbnQsIHRoaXMsIGN1ckV2ZW50VGFyZ2V0KSwgdGFyZ2V0LCB0aGlzLmVsZW1lbnQpO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5zZXRFdmVudFhZKHRoaXMuc3RhcnRDb29yZHMsIHRoaXMucG9pbnRlcnMpO1xuXG4gICAgICAgICAgICAgICAgaWYgKCFhY3Rpb24pIHsgcmV0dXJuOyB9XG5cbiAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5zdHlsZUN1cnNvcikge1xuICAgICAgICAgICAgICAgICAgICB0YXJnZXQuX2RvYy5kb2N1bWVudEVsZW1lbnQuc3R5bGUuY3Vyc29yID0gZ2V0QWN0aW9uQ3Vyc29yKGFjdGlvbik7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5yZXNpemVBeGVzID0gYWN0aW9uLm5hbWUgPT09ICdyZXNpemUnPyBhY3Rpb24uYXhpcyA6IG51bGw7XG5cbiAgICAgICAgICAgICAgICBpZiAoYWN0aW9uID09PSAnZ2VzdHVyZScgJiYgdGhpcy5wb2ludGVySWRzLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgYWN0aW9uID0gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLnByZXBhcmVkLm5hbWUgID0gYWN0aW9uLm5hbWU7XG4gICAgICAgICAgICAgICAgdGhpcy5wcmVwYXJlZC5heGlzICA9IGFjdGlvbi5heGlzO1xuICAgICAgICAgICAgICAgIHRoaXMucHJlcGFyZWQuZWRnZXMgPSBhY3Rpb24uZWRnZXM7XG5cbiAgICAgICAgICAgICAgICB0aGlzLnNuYXBTdGF0dXMuc25hcHBlZFggPSB0aGlzLnNuYXBTdGF0dXMuc25hcHBlZFkgPVxuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc3RyaWN0U3RhdHVzLnJlc3RyaWN0ZWRYID0gdGhpcy5yZXN0cmljdFN0YXR1cy5yZXN0cmljdGVkWSA9IE5hTjtcblxuICAgICAgICAgICAgICAgIHRoaXMuZG93blRpbWVzW3BvaW50ZXJJbmRleF0gPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICAgICAgICAgICAgICB0aGlzLmRvd25UYXJnZXRzW3BvaW50ZXJJbmRleF0gPSBldmVudFRhcmdldDtcbiAgICAgICAgICAgICAgICBwb2ludGVyRXh0ZW5kKHRoaXMuZG93blBvaW50ZXIsIHBvaW50ZXIpO1xuXG4gICAgICAgICAgICAgICAgY29weUNvb3Jkcyh0aGlzLnByZXZDb29yZHMsIHRoaXMuc3RhcnRDb29yZHMpO1xuICAgICAgICAgICAgICAgIHRoaXMucG9pbnRlcldhc01vdmVkID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICB0aGlzLmNoZWNrQW5kUHJldmVudERlZmF1bHQoZXZlbnQsIHRhcmdldCwgdGhpcy5lbGVtZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIGlmIGluZXJ0aWEgaXMgYWN0aXZlIHRyeSB0byByZXN1bWUgYWN0aW9uXG4gICAgICAgICAgICBlbHNlIGlmICh0aGlzLmluZXJ0aWFTdGF0dXMuYWN0aXZlXG4gICAgICAgICAgICAgICAgJiYgY3VyRXZlbnRUYXJnZXQgPT09IHRoaXMuZWxlbWVudFxuICAgICAgICAgICAgICAgICYmIHZhbGlkYXRlQWN0aW9uKHRhcmdldC5nZXRBY3Rpb24ocG9pbnRlciwgZXZlbnQsIHRoaXMsIHRoaXMuZWxlbWVudCksIHRhcmdldCkubmFtZSA9PT0gdGhpcy5wcmVwYXJlZC5uYW1lKSB7XG5cbiAgICAgICAgICAgICAgICBjYW5jZWxGcmFtZSh0aGlzLmluZXJ0aWFTdGF0dXMuaSk7XG4gICAgICAgICAgICAgICAgdGhpcy5pbmVydGlhU3RhdHVzLmFjdGl2ZSA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5jaGVja0FuZFByZXZlbnREZWZhdWx0KGV2ZW50LCB0YXJnZXQsIHRoaXMuZWxlbWVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgc2V0TW9kaWZpY2F0aW9uczogZnVuY3Rpb24gKGNvb3JkcywgcHJlRW5kKSB7XG4gICAgICAgICAgICB2YXIgdGFyZ2V0ICAgICAgICAgPSB0aGlzLnRhcmdldCxcbiAgICAgICAgICAgICAgICBzaG91bGRNb3ZlICAgICA9IHRydWUsXG4gICAgICAgICAgICAgICAgc2hvdWxkU25hcCAgICAgPSBjaGVja1NuYXAodGFyZ2V0LCB0aGlzLnByZXBhcmVkLm5hbWUpICAgICAmJiAoIXRhcmdldC5vcHRpb25zW3RoaXMucHJlcGFyZWQubmFtZV0uc25hcC5lbmRPbmx5ICAgICB8fCBwcmVFbmQpLFxuICAgICAgICAgICAgICAgIHNob3VsZFJlc3RyaWN0ID0gY2hlY2tSZXN0cmljdCh0YXJnZXQsIHRoaXMucHJlcGFyZWQubmFtZSkgJiYgKCF0YXJnZXQub3B0aW9uc1t0aGlzLnByZXBhcmVkLm5hbWVdLnJlc3RyaWN0LmVuZE9ubHkgfHwgcHJlRW5kKTtcblxuICAgICAgICAgICAgaWYgKHNob3VsZFNuYXAgICAgKSB7IHRoaXMuc2V0U25hcHBpbmcgICAoY29vcmRzKTsgfSBlbHNlIHsgdGhpcy5zbmFwU3RhdHVzICAgIC5sb2NrZWQgICAgID0gZmFsc2U7IH1cbiAgICAgICAgICAgIGlmIChzaG91bGRSZXN0cmljdCkgeyB0aGlzLnNldFJlc3RyaWN0aW9uKGNvb3Jkcyk7IH0gZWxzZSB7IHRoaXMucmVzdHJpY3RTdGF0dXMucmVzdHJpY3RlZCA9IGZhbHNlOyB9XG5cbiAgICAgICAgICAgIGlmIChzaG91bGRTbmFwICYmIHRoaXMuc25hcFN0YXR1cy5sb2NrZWQgJiYgIXRoaXMuc25hcFN0YXR1cy5jaGFuZ2VkKSB7XG4gICAgICAgICAgICAgICAgc2hvdWxkTW92ZSA9IHNob3VsZFJlc3RyaWN0ICYmIHRoaXMucmVzdHJpY3RTdGF0dXMucmVzdHJpY3RlZCAmJiB0aGlzLnJlc3RyaWN0U3RhdHVzLmNoYW5nZWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChzaG91bGRSZXN0cmljdCAmJiB0aGlzLnJlc3RyaWN0U3RhdHVzLnJlc3RyaWN0ZWQgJiYgIXRoaXMucmVzdHJpY3RTdGF0dXMuY2hhbmdlZCkge1xuICAgICAgICAgICAgICAgIHNob3VsZE1vdmUgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHNob3VsZE1vdmU7XG4gICAgICAgIH0sXG5cbiAgICAgICAgc2V0U3RhcnRPZmZzZXRzOiBmdW5jdGlvbiAoYWN0aW9uLCBpbnRlcmFjdGFibGUsIGVsZW1lbnQpIHtcbiAgICAgICAgICAgIHZhciByZWN0ID0gaW50ZXJhY3RhYmxlLmdldFJlY3QoZWxlbWVudCksXG4gICAgICAgICAgICAgICAgb3JpZ2luID0gZ2V0T3JpZ2luWFkoaW50ZXJhY3RhYmxlLCBlbGVtZW50KSxcbiAgICAgICAgICAgICAgICBzbmFwID0gaW50ZXJhY3RhYmxlLm9wdGlvbnNbdGhpcy5wcmVwYXJlZC5uYW1lXS5zbmFwLFxuICAgICAgICAgICAgICAgIHJlc3RyaWN0ID0gaW50ZXJhY3RhYmxlLm9wdGlvbnNbdGhpcy5wcmVwYXJlZC5uYW1lXS5yZXN0cmljdCxcbiAgICAgICAgICAgICAgICB3aWR0aCwgaGVpZ2h0O1xuXG4gICAgICAgICAgICBpZiAocmVjdCkge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhcnRPZmZzZXQubGVmdCA9IHRoaXMuc3RhcnRDb29yZHMucGFnZS54IC0gcmVjdC5sZWZ0O1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhcnRPZmZzZXQudG9wICA9IHRoaXMuc3RhcnRDb29yZHMucGFnZS55IC0gcmVjdC50b3A7XG5cbiAgICAgICAgICAgICAgICB0aGlzLnN0YXJ0T2Zmc2V0LnJpZ2h0ICA9IHJlY3QucmlnaHQgIC0gdGhpcy5zdGFydENvb3Jkcy5wYWdlLng7XG4gICAgICAgICAgICAgICAgdGhpcy5zdGFydE9mZnNldC5ib3R0b20gPSByZWN0LmJvdHRvbSAtIHRoaXMuc3RhcnRDb29yZHMucGFnZS55O1xuXG4gICAgICAgICAgICAgICAgaWYgKCd3aWR0aCcgaW4gcmVjdCkgeyB3aWR0aCA9IHJlY3Qud2lkdGg7IH1cbiAgICAgICAgICAgICAgICBlbHNlIHsgd2lkdGggPSByZWN0LnJpZ2h0IC0gcmVjdC5sZWZ0OyB9XG4gICAgICAgICAgICAgICAgaWYgKCdoZWlnaHQnIGluIHJlY3QpIHsgaGVpZ2h0ID0gcmVjdC5oZWlnaHQ7IH1cbiAgICAgICAgICAgICAgICBlbHNlIHsgaGVpZ2h0ID0gcmVjdC5ib3R0b20gLSByZWN0LnRvcDsgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdGFydE9mZnNldC5sZWZ0ID0gdGhpcy5zdGFydE9mZnNldC50b3AgPSB0aGlzLnN0YXJ0T2Zmc2V0LnJpZ2h0ID0gdGhpcy5zdGFydE9mZnNldC5ib3R0b20gPSAwO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnNuYXBPZmZzZXRzLnNwbGljZSgwKTtcblxuICAgICAgICAgICAgdmFyIHNuYXBPZmZzZXQgPSBzbmFwICYmIHNuYXAub2Zmc2V0ID09PSAnc3RhcnRDb29yZHMnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeDogdGhpcy5zdGFydENvb3Jkcy5wYWdlLnggLSBvcmlnaW4ueCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IHRoaXMuc3RhcnRDb29yZHMucGFnZS55IC0gb3JpZ2luLnlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHNuYXAgJiYgc25hcC5vZmZzZXQgfHwgeyB4OiAwLCB5OiAwIH07XG5cbiAgICAgICAgICAgIGlmIChyZWN0ICYmIHNuYXAgJiYgc25hcC5yZWxhdGl2ZVBvaW50cyAmJiBzbmFwLnJlbGF0aXZlUG9pbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc25hcC5yZWxhdGl2ZVBvaW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNuYXBPZmZzZXRzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgeDogdGhpcy5zdGFydE9mZnNldC5sZWZ0IC0gKHdpZHRoICAqIHNuYXAucmVsYXRpdmVQb2ludHNbaV0ueCkgKyBzbmFwT2Zmc2V0LngsXG4gICAgICAgICAgICAgICAgICAgICAgICB5OiB0aGlzLnN0YXJ0T2Zmc2V0LnRvcCAgLSAoaGVpZ2h0ICogc25hcC5yZWxhdGl2ZVBvaW50c1tpXS55KSArIHNuYXBPZmZzZXQueVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNuYXBPZmZzZXRzLnB1c2goc25hcE9mZnNldCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChyZWN0ICYmIHJlc3RyaWN0LmVsZW1lbnRSZWN0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZXN0cmljdE9mZnNldC5sZWZ0ID0gdGhpcy5zdGFydE9mZnNldC5sZWZ0IC0gKHdpZHRoICAqIHJlc3RyaWN0LmVsZW1lbnRSZWN0LmxlZnQpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVzdHJpY3RPZmZzZXQudG9wICA9IHRoaXMuc3RhcnRPZmZzZXQudG9wICAtIChoZWlnaHQgKiByZXN0cmljdC5lbGVtZW50UmVjdC50b3ApO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5yZXN0cmljdE9mZnNldC5yaWdodCAgPSB0aGlzLnN0YXJ0T2Zmc2V0LnJpZ2h0ICAtICh3aWR0aCAgKiAoMSAtIHJlc3RyaWN0LmVsZW1lbnRSZWN0LnJpZ2h0KSk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZXN0cmljdE9mZnNldC5ib3R0b20gPSB0aGlzLnN0YXJ0T2Zmc2V0LmJvdHRvbSAtIChoZWlnaHQgKiAoMSAtIHJlc3RyaWN0LmVsZW1lbnRSZWN0LmJvdHRvbSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZXN0cmljdE9mZnNldC5sZWZ0ID0gdGhpcy5yZXN0cmljdE9mZnNldC50b3AgPSB0aGlzLnJlc3RyaWN0T2Zmc2V0LnJpZ2h0ID0gdGhpcy5yZXN0cmljdE9mZnNldC5ib3R0b20gPSAwO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIC8qXFxcbiAgICAgICAgICogSW50ZXJhY3Rpb24uc3RhcnRcbiAgICAgICAgIFsgbWV0aG9kIF1cbiAgICAgICAgICpcbiAgICAgICAgICogU3RhcnQgYW4gYWN0aW9uIHdpdGggdGhlIGdpdmVuIEludGVyYWN0YWJsZSBhbmQgRWxlbWVudCBhcyB0YXJ0Z2V0cy4gVGhlXG4gICAgICAgICAqIGFjdGlvbiBtdXN0IGJlIGVuYWJsZWQgZm9yIHRoZSB0YXJnZXQgSW50ZXJhY3RhYmxlIGFuZCBhbiBhcHByb3ByaWF0ZSBudW1iZXJcbiAgICAgICAgICogb2YgcG9pbnRlcnMgbXVzdCBiZSBoZWxkIGRvd24g4oCTIDEgZm9yIGRyYWcvcmVzaXplLCAyIGZvciBnZXN0dXJlLlxuICAgICAgICAgKlxuICAgICAgICAgKiBVc2UgaXQgd2l0aCBgaW50ZXJhY3RhYmxlLjxhY3Rpb24+YWJsZSh7IG1hbnVhbFN0YXJ0OiBmYWxzZSB9KWAgdG8gYWx3YXlzXG4gICAgICAgICAqIFtzdGFydCBhY3Rpb25zIG1hbnVhbGx5XShodHRwczovL2dpdGh1Yi5jb20vdGF5ZS9pbnRlcmFjdC5qcy9pc3N1ZXMvMTE0KVxuICAgICAgICAgKlxuICAgICAgICAgLSBhY3Rpb24gICAgICAgKG9iamVjdCkgIFRoZSBhY3Rpb24gdG8gYmUgcGVyZm9ybWVkIC0gZHJhZywgcmVzaXplLCBldGMuXG4gICAgICAgICAtIGludGVyYWN0YWJsZSAoSW50ZXJhY3RhYmxlKSBUaGUgSW50ZXJhY3RhYmxlIHRvIHRhcmdldFxuICAgICAgICAgLSBlbGVtZW50ICAgICAgKEVsZW1lbnQpIFRoZSBET00gRWxlbWVudCB0byB0YXJnZXRcbiAgICAgICAgID0gKG9iamVjdCkgaW50ZXJhY3RcbiAgICAgICAgICoqXG4gICAgICAgICB8IGludGVyYWN0KHRhcmdldClcbiAgICAgICAgIHwgICAuZHJhZ2dhYmxlKHtcbiAgICAgICAgIHwgICAgIC8vIGRpc2FibGUgdGhlIGRlZmF1bHQgZHJhZyBzdGFydCBieSBkb3duLT5tb3ZlXG4gICAgICAgICB8ICAgICBtYW51YWxTdGFydDogdHJ1ZVxuICAgICAgICAgfCAgIH0pXG4gICAgICAgICB8ICAgLy8gc3RhcnQgZHJhZ2dpbmcgYWZ0ZXIgdGhlIHVzZXIgaG9sZHMgdGhlIHBvaW50ZXIgZG93blxuICAgICAgICAgfCAgIC5vbignaG9sZCcsIGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICAgfCAgICAgdmFyIGludGVyYWN0aW9uID0gZXZlbnQuaW50ZXJhY3Rpb247XG4gICAgICAgICB8XG4gICAgICAgICB8ICAgICBpZiAoIWludGVyYWN0aW9uLmludGVyYWN0aW5nKCkpIHtcbiAgICAgICAgIHwgICAgICAgaW50ZXJhY3Rpb24uc3RhcnQoeyBuYW1lOiAnZHJhZycgfSxcbiAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQuaW50ZXJhY3RhYmxlLFxuICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICBldmVudC5jdXJyZW50VGFyZ2V0KTtcbiAgICAgICAgIHwgICAgIH1cbiAgICAgICAgIHwgfSk7XG4gICAgICAgIFxcKi9cbiAgICAgICAgc3RhcnQ6IGZ1bmN0aW9uIChhY3Rpb24sIGludGVyYWN0YWJsZSwgZWxlbWVudCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuaW50ZXJhY3RpbmcoKVxuICAgICAgICAgICAgICAgIHx8ICF0aGlzLnBvaW50ZXJJc0Rvd25cbiAgICAgICAgICAgICAgICB8fCB0aGlzLnBvaW50ZXJJZHMubGVuZ3RoIDwgKGFjdGlvbi5uYW1lID09PSAnZ2VzdHVyZSc/IDIgOiAxKSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gaWYgdGhpcyBpbnRlcmFjdGlvbiBoYWQgYmVlbiByZW1vdmVkIGFmdGVyIHN0b3BwaW5nXG4gICAgICAgICAgICAvLyBhZGQgaXQgYmFja1xuICAgICAgICAgICAgaWYgKGluZGV4T2YoaW50ZXJhY3Rpb25zLCB0aGlzKSA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgICBpbnRlcmFjdGlvbnMucHVzaCh0aGlzKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gc2V0IHRoZSBzdGFydENvb3JkcyBpZiB0aGVyZSB3YXMgbm8gcHJlcGFyZWQgYWN0aW9uXG4gICAgICAgICAgICBpZiAoIXRoaXMucHJlcGFyZWQubmFtZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0RXZlbnRYWSh0aGlzLnN0YXJ0Q29vcmRzLCB0aGlzLnBvaW50ZXJzKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5wcmVwYXJlZC5uYW1lICA9IGFjdGlvbi5uYW1lO1xuICAgICAgICAgICAgdGhpcy5wcmVwYXJlZC5heGlzICA9IGFjdGlvbi5heGlzO1xuICAgICAgICAgICAgdGhpcy5wcmVwYXJlZC5lZGdlcyA9IGFjdGlvbi5lZGdlcztcbiAgICAgICAgICAgIHRoaXMudGFyZ2V0ICAgICAgICAgPSBpbnRlcmFjdGFibGU7XG4gICAgICAgICAgICB0aGlzLmVsZW1lbnQgICAgICAgID0gZWxlbWVudDtcblxuICAgICAgICAgICAgdGhpcy5zZXRTdGFydE9mZnNldHMoYWN0aW9uLm5hbWUsIGludGVyYWN0YWJsZSwgZWxlbWVudCk7XG4gICAgICAgICAgICB0aGlzLnNldE1vZGlmaWNhdGlvbnModGhpcy5zdGFydENvb3Jkcy5wYWdlKTtcblxuICAgICAgICAgICAgdGhpcy5wcmV2RXZlbnQgPSB0aGlzW3RoaXMucHJlcGFyZWQubmFtZSArICdTdGFydCddKHRoaXMuZG93bkV2ZW50KTtcbiAgICAgICAgfSxcblxuICAgICAgICBwb2ludGVyTW92ZTogZnVuY3Rpb24gKHBvaW50ZXIsIGV2ZW50LCBldmVudFRhcmdldCwgY3VyRXZlbnRUYXJnZXQsIHByZUVuZCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuaW5lcnRpYVN0YXR1cy5hY3RpdmUpIHtcbiAgICAgICAgICAgICAgICB2YXIgcGFnZVVwICAgPSB0aGlzLmluZXJ0aWFTdGF0dXMudXBDb29yZHMucGFnZTtcbiAgICAgICAgICAgICAgICB2YXIgY2xpZW50VXAgPSB0aGlzLmluZXJ0aWFTdGF0dXMudXBDb29yZHMuY2xpZW50O1xuXG4gICAgICAgICAgICAgICAgdmFyIGluZXJ0aWFQb3NpdGlvbiA9IHtcbiAgICAgICAgICAgICAgICAgICAgcGFnZVggIDogcGFnZVVwLnggICArIHRoaXMuaW5lcnRpYVN0YXR1cy5zeCxcbiAgICAgICAgICAgICAgICAgICAgcGFnZVkgIDogcGFnZVVwLnkgICArIHRoaXMuaW5lcnRpYVN0YXR1cy5zeSxcbiAgICAgICAgICAgICAgICAgICAgY2xpZW50WDogY2xpZW50VXAueCArIHRoaXMuaW5lcnRpYVN0YXR1cy5zeCxcbiAgICAgICAgICAgICAgICAgICAgY2xpZW50WTogY2xpZW50VXAueSArIHRoaXMuaW5lcnRpYVN0YXR1cy5zeVxuICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICB0aGlzLnNldEV2ZW50WFkodGhpcy5jdXJDb29yZHMsIFtpbmVydGlhUG9zaXRpb25dKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMucmVjb3JkUG9pbnRlcihwb2ludGVyKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNldEV2ZW50WFkodGhpcy5jdXJDb29yZHMsIHRoaXMucG9pbnRlcnMpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgZHVwbGljYXRlTW92ZSA9ICh0aGlzLmN1ckNvb3Jkcy5wYWdlLnggPT09IHRoaXMucHJldkNvb3Jkcy5wYWdlLnhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIHRoaXMuY3VyQ29vcmRzLnBhZ2UueSA9PT0gdGhpcy5wcmV2Q29vcmRzLnBhZ2UueVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgdGhpcy5jdXJDb29yZHMuY2xpZW50LnggPT09IHRoaXMucHJldkNvb3Jkcy5jbGllbnQueFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgdGhpcy5jdXJDb29yZHMuY2xpZW50LnkgPT09IHRoaXMucHJldkNvb3Jkcy5jbGllbnQueSk7XG5cbiAgICAgICAgICAgIHZhciBkeCwgZHksXG4gICAgICAgICAgICAgICAgcG9pbnRlckluZGV4ID0gdGhpcy5tb3VzZT8gMCA6IGluZGV4T2YodGhpcy5wb2ludGVySWRzLCBnZXRQb2ludGVySWQocG9pbnRlcikpO1xuXG4gICAgICAgICAgICAvLyByZWdpc3RlciBtb3ZlbWVudCBncmVhdGVyIHRoYW4gcG9pbnRlck1vdmVUb2xlcmFuY2VcbiAgICAgICAgICAgIGlmICh0aGlzLnBvaW50ZXJJc0Rvd24gJiYgIXRoaXMucG9pbnRlcldhc01vdmVkKSB7XG4gICAgICAgICAgICAgICAgZHggPSB0aGlzLmN1ckNvb3Jkcy5jbGllbnQueCAtIHRoaXMuc3RhcnRDb29yZHMuY2xpZW50Lng7XG4gICAgICAgICAgICAgICAgZHkgPSB0aGlzLmN1ckNvb3Jkcy5jbGllbnQueSAtIHRoaXMuc3RhcnRDb29yZHMuY2xpZW50Lnk7XG5cbiAgICAgICAgICAgICAgICB0aGlzLnBvaW50ZXJXYXNNb3ZlZCA9IGh5cG90KGR4LCBkeSkgPiBwb2ludGVyTW92ZVRvbGVyYW5jZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCFkdXBsaWNhdGVNb3ZlICYmICghdGhpcy5wb2ludGVySXNEb3duIHx8IHRoaXMucG9pbnRlcldhc01vdmVkKSkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnBvaW50ZXJJc0Rvd24pIHtcbiAgICAgICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuaG9sZFRpbWVyc1twb2ludGVySW5kZXhdKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLmNvbGxlY3RFdmVudFRhcmdldHMocG9pbnRlciwgZXZlbnQsIGV2ZW50VGFyZ2V0LCAnbW92ZScpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIXRoaXMucG9pbnRlcklzRG93bikgeyByZXR1cm47IH1cblxuICAgICAgICAgICAgaWYgKGR1cGxpY2F0ZU1vdmUgJiYgdGhpcy5wb2ludGVyV2FzTW92ZWQgJiYgIXByZUVuZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuY2hlY2tBbmRQcmV2ZW50RGVmYXVsdChldmVudCwgdGhpcy50YXJnZXQsIHRoaXMuZWxlbWVudCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBzZXQgcG9pbnRlciBjb29yZGluYXRlLCB0aW1lIGNoYW5nZXMgYW5kIHNwZWVkc1xuICAgICAgICAgICAgc2V0RXZlbnREZWx0YXModGhpcy5wb2ludGVyRGVsdGEsIHRoaXMucHJldkNvb3JkcywgdGhpcy5jdXJDb29yZHMpO1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMucHJlcGFyZWQubmFtZSkgeyByZXR1cm47IH1cblxuICAgICAgICAgICAgaWYgKHRoaXMucG9pbnRlcldhc01vdmVkXG4gICAgICAgICAgICAgICAgLy8gaWdub3JlIG1vdmVtZW50IHdoaWxlIGluZXJ0aWEgaXMgYWN0aXZlXG4gICAgICAgICAgICAgICAgJiYgKCF0aGlzLmluZXJ0aWFTdGF0dXMuYWN0aXZlIHx8IChwb2ludGVyIGluc3RhbmNlb2YgSW50ZXJhY3RFdmVudCAmJiAvaW5lcnRpYXN0YXJ0Ly50ZXN0KHBvaW50ZXIudHlwZSkpKSkge1xuXG4gICAgICAgICAgICAgICAgLy8gaWYganVzdCBzdGFydGluZyBhbiBhY3Rpb24sIGNhbGN1bGF0ZSB0aGUgcG9pbnRlciBzcGVlZCBub3dcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuaW50ZXJhY3RpbmcoKSkge1xuICAgICAgICAgICAgICAgICAgICBzZXRFdmVudERlbHRhcyh0aGlzLnBvaW50ZXJEZWx0YSwgdGhpcy5wcmV2Q29vcmRzLCB0aGlzLmN1ckNvb3Jkcyk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgaWYgYSBkcmFnIGlzIGluIHRoZSBjb3JyZWN0IGF4aXNcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucHJlcGFyZWQubmFtZSA9PT0gJ2RyYWcnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgYWJzWCA9IE1hdGguYWJzKGR4KSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhYnNZID0gTWF0aC5hYnMoZHkpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldEF4aXMgPSB0aGlzLnRhcmdldC5vcHRpb25zLmRyYWcuYXhpcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBheGlzID0gKGFic1ggPiBhYnNZID8gJ3gnIDogYWJzWCA8IGFic1kgPyAneScgOiAneHknKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgdGhlIG1vdmVtZW50IGlzbid0IGluIHRoZSBheGlzIG9mIHRoZSBpbnRlcmFjdGFibGVcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChheGlzICE9PSAneHknICYmIHRhcmdldEF4aXMgIT09ICd4eScgJiYgdGFyZ2V0QXhpcyAhPT0gYXhpcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNhbmNlbCB0aGUgcHJlcGFyZWQgYWN0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcmVwYXJlZC5uYW1lID0gbnVsbDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoZW4gdHJ5IHRvIGdldCBhIGRyYWcgZnJvbSBhbm90aGVyIGluZXJhY3RhYmxlXG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZWxlbWVudCA9IGV2ZW50VGFyZ2V0O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgZWxlbWVudCBpbnRlcmFjdGFibGVzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGlzRWxlbWVudChlbGVtZW50KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZWxlbWVudEludGVyYWN0YWJsZSA9IGludGVyYWN0YWJsZXMuZ2V0KGVsZW1lbnQpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbGVtZW50SW50ZXJhY3RhYmxlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBlbGVtZW50SW50ZXJhY3RhYmxlICE9PSB0aGlzLnRhcmdldFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgIWVsZW1lbnRJbnRlcmFjdGFibGUub3B0aW9ucy5kcmFnLm1hbnVhbFN0YXJ0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBlbGVtZW50SW50ZXJhY3RhYmxlLmdldEFjdGlvbih0aGlzLmRvd25Qb2ludGVyLCB0aGlzLmRvd25FdmVudCwgdGhpcywgZWxlbWVudCkubmFtZSA9PT0gJ2RyYWcnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBjaGVja0F4aXMoYXhpcywgZWxlbWVudEludGVyYWN0YWJsZSkpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcmVwYXJlZC5uYW1lID0gJ2RyYWcnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50YXJnZXQgPSBlbGVtZW50SW50ZXJhY3RhYmxlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lbGVtZW50ID0gZWxlbWVudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudCA9IHBhcmVudEVsZW1lbnQoZWxlbWVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgdGhlcmUncyBubyBkcmFnIGZyb20gZWxlbWVudCBpbnRlcmFjdGFibGVzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIHRoZSBzZWxlY3RvciBpbnRlcmFjdGFibGVzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLnByZXBhcmVkLm5hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRoaXNJbnRlcmFjdGlvbiA9IHRoaXM7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGdldERyYWdnYWJsZSA9IGZ1bmN0aW9uIChpbnRlcmFjdGFibGUsIHNlbGVjdG9yLCBjb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZWxlbWVudHMgPSBpZThNYXRjaGVzU2VsZWN0b3JcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGNvbnRleHQucXVlcnlTZWxlY3RvckFsbChzZWxlY3RvcilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHVuZGVmaW5lZDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGludGVyYWN0YWJsZSA9PT0gdGhpc0ludGVyYWN0aW9uLnRhcmdldCkgeyByZXR1cm47IH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluQ29udGV4dChpbnRlcmFjdGFibGUsIGV2ZW50VGFyZ2V0KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmICFpbnRlcmFjdGFibGUub3B0aW9ucy5kcmFnLm1hbnVhbFN0YXJ0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgIXRlc3RJZ25vcmUoaW50ZXJhY3RhYmxlLCBlbGVtZW50LCBldmVudFRhcmdldClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiB0ZXN0QWxsb3coaW50ZXJhY3RhYmxlLCBlbGVtZW50LCBldmVudFRhcmdldClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBtYXRjaGVzU2VsZWN0b3IoZWxlbWVudCwgc2VsZWN0b3IsIGVsZW1lbnRzKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIGludGVyYWN0YWJsZS5nZXRBY3Rpb24odGhpc0ludGVyYWN0aW9uLmRvd25Qb2ludGVyLCB0aGlzSW50ZXJhY3Rpb24uZG93bkV2ZW50LCB0aGlzSW50ZXJhY3Rpb24sIGVsZW1lbnQpLm5hbWUgPT09ICdkcmFnJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIGNoZWNrQXhpcyhheGlzLCBpbnRlcmFjdGFibGUpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgd2l0aGluSW50ZXJhY3Rpb25MaW1pdChpbnRlcmFjdGFibGUsIGVsZW1lbnQsICdkcmFnJykpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpbnRlcmFjdGFibGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudCA9IGV2ZW50VGFyZ2V0O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChpc0VsZW1lbnQoZWxlbWVudCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzZWxlY3RvckludGVyYWN0YWJsZSA9IGludGVyYWN0YWJsZXMuZm9yRWFjaFNlbGVjdG9yKGdldERyYWdnYWJsZSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxlY3RvckludGVyYWN0YWJsZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJlcGFyZWQubmFtZSA9ICdkcmFnJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRhcmdldCA9IHNlbGVjdG9ySW50ZXJhY3RhYmxlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQgPSBwYXJlbnRFbGVtZW50KGVsZW1lbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdmFyIHN0YXJ0aW5nID0gISF0aGlzLnByZXBhcmVkLm5hbWUgJiYgIXRoaXMuaW50ZXJhY3RpbmcoKTtcblxuICAgICAgICAgICAgICAgIGlmIChzdGFydGluZ1xuICAgICAgICAgICAgICAgICAgICAmJiAodGhpcy50YXJnZXQub3B0aW9uc1t0aGlzLnByZXBhcmVkLm5hbWVdLm1hbnVhbFN0YXJ0XG4gICAgICAgICAgICAgICAgICAgICAgICB8fCAhd2l0aGluSW50ZXJhY3Rpb25MaW1pdCh0aGlzLnRhcmdldCwgdGhpcy5lbGVtZW50LCB0aGlzLnByZXBhcmVkKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdG9wKGV2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnByZXBhcmVkLm5hbWUgJiYgdGhpcy50YXJnZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXJ0aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXJ0KHRoaXMucHJlcGFyZWQsIHRoaXMudGFyZ2V0LCB0aGlzLmVsZW1lbnQpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgdmFyIHNob3VsZE1vdmUgPSB0aGlzLnNldE1vZGlmaWNhdGlvbnModGhpcy5jdXJDb29yZHMucGFnZSwgcHJlRW5kKTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBtb3ZlIGlmIHNuYXBwaW5nIG9yIHJlc3RyaWN0aW9uIGRvZXNuJ3QgcHJldmVudCBpdFxuICAgICAgICAgICAgICAgICAgICBpZiAoc2hvdWxkTW92ZSB8fCBzdGFydGluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcmV2RXZlbnQgPSB0aGlzW3RoaXMucHJlcGFyZWQubmFtZSArICdNb3ZlJ10oZXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jaGVja0FuZFByZXZlbnREZWZhdWx0KGV2ZW50LCB0aGlzLnRhcmdldCwgdGhpcy5lbGVtZW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvcHlDb29yZHModGhpcy5wcmV2Q29vcmRzLCB0aGlzLmN1ckNvb3Jkcyk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmRyYWdnaW5nIHx8IHRoaXMucmVzaXppbmcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmF1dG9TY3JvbGxNb3ZlKHBvaW50ZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIGRyYWdTdGFydDogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgICB2YXIgZHJhZ0V2ZW50ID0gbmV3IEludGVyYWN0RXZlbnQodGhpcywgZXZlbnQsICdkcmFnJywgJ3N0YXJ0JywgdGhpcy5lbGVtZW50KTtcblxuICAgICAgICAgICAgdGhpcy5kcmFnZ2luZyA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLnRhcmdldC5maXJlKGRyYWdFdmVudCk7XG5cbiAgICAgICAgICAgIC8vIHJlc2V0IGFjdGl2ZSBkcm9wem9uZXNcbiAgICAgICAgICAgIHRoaXMuYWN0aXZlRHJvcHMuZHJvcHpvbmVzID0gW107XG4gICAgICAgICAgICB0aGlzLmFjdGl2ZURyb3BzLmVsZW1lbnRzICA9IFtdO1xuICAgICAgICAgICAgdGhpcy5hY3RpdmVEcm9wcy5yZWN0cyAgICAgPSBbXTtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLmR5bmFtaWNEcm9wKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRBY3RpdmVEcm9wcyh0aGlzLmVsZW1lbnQpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgZHJvcEV2ZW50cyA9IHRoaXMuZ2V0RHJvcEV2ZW50cyhldmVudCwgZHJhZ0V2ZW50KTtcblxuICAgICAgICAgICAgaWYgKGRyb3BFdmVudHMuYWN0aXZhdGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZpcmVBY3RpdmVEcm9wcyhkcm9wRXZlbnRzLmFjdGl2YXRlKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGRyYWdFdmVudDtcbiAgICAgICAgfSxcblxuICAgICAgICBkcmFnTW92ZTogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgICB2YXIgdGFyZ2V0ID0gdGhpcy50YXJnZXQsXG4gICAgICAgICAgICAgICAgZHJhZ0V2ZW50ICA9IG5ldyBJbnRlcmFjdEV2ZW50KHRoaXMsIGV2ZW50LCAnZHJhZycsICdtb3ZlJywgdGhpcy5lbGVtZW50KSxcbiAgICAgICAgICAgICAgICBkcmFnZ2FibGVFbGVtZW50ID0gdGhpcy5lbGVtZW50LFxuICAgICAgICAgICAgICAgIGRyb3AgPSB0aGlzLmdldERyb3AoZHJhZ0V2ZW50LCBldmVudCwgZHJhZ2dhYmxlRWxlbWVudCk7XG5cbiAgICAgICAgICAgIHRoaXMuZHJvcFRhcmdldCA9IGRyb3AuZHJvcHpvbmU7XG4gICAgICAgICAgICB0aGlzLmRyb3BFbGVtZW50ID0gZHJvcC5lbGVtZW50O1xuXG4gICAgICAgICAgICB2YXIgZHJvcEV2ZW50cyA9IHRoaXMuZ2V0RHJvcEV2ZW50cyhldmVudCwgZHJhZ0V2ZW50KTtcblxuICAgICAgICAgICAgdGFyZ2V0LmZpcmUoZHJhZ0V2ZW50KTtcblxuICAgICAgICAgICAgaWYgKGRyb3BFdmVudHMubGVhdmUpIHsgdGhpcy5wcmV2RHJvcFRhcmdldC5maXJlKGRyb3BFdmVudHMubGVhdmUpOyB9XG4gICAgICAgICAgICBpZiAoZHJvcEV2ZW50cy5lbnRlcikgeyAgICAgdGhpcy5kcm9wVGFyZ2V0LmZpcmUoZHJvcEV2ZW50cy5lbnRlcik7IH1cbiAgICAgICAgICAgIGlmIChkcm9wRXZlbnRzLm1vdmUgKSB7ICAgICB0aGlzLmRyb3BUYXJnZXQuZmlyZShkcm9wRXZlbnRzLm1vdmUgKTsgfVxuXG4gICAgICAgICAgICB0aGlzLnByZXZEcm9wVGFyZ2V0ICA9IHRoaXMuZHJvcFRhcmdldDtcbiAgICAgICAgICAgIHRoaXMucHJldkRyb3BFbGVtZW50ID0gdGhpcy5kcm9wRWxlbWVudDtcblxuICAgICAgICAgICAgcmV0dXJuIGRyYWdFdmVudDtcbiAgICAgICAgfSxcblxuICAgICAgICByZXNpemVTdGFydDogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgICB2YXIgcmVzaXplRXZlbnQgPSBuZXcgSW50ZXJhY3RFdmVudCh0aGlzLCBldmVudCwgJ3Jlc2l6ZScsICdzdGFydCcsIHRoaXMuZWxlbWVudCk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnByZXBhcmVkLmVkZ2VzKSB7XG4gICAgICAgICAgICAgICAgdmFyIHN0YXJ0UmVjdCA9IHRoaXMudGFyZ2V0LmdldFJlY3QodGhpcy5lbGVtZW50KTtcblxuICAgICAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgICAgICogV2hlbiB1c2luZyB0aGUgYHJlc2l6YWJsZS5zcXVhcmVgIG9yIGByZXNpemFibGUucHJlc2VydmVBc3BlY3RSYXRpb2Agb3B0aW9ucywgcmVzaXppbmcgZnJvbSBvbmUgZWRnZVxuICAgICAgICAgICAgICAgICAqIHdpbGwgYWZmZWN0IGFub3RoZXIuIEUuZy4gd2l0aCBgcmVzaXphYmxlLnNxdWFyZWAsIHJlc2l6aW5nIHRvIG1ha2UgdGhlIHJpZ2h0IGVkZ2UgbGFyZ2VyIHdpbGwgbWFrZVxuICAgICAgICAgICAgICAgICAqIHRoZSBib3R0b20gZWRnZSBsYXJnZXIgYnkgdGhlIHNhbWUgYW1vdW50LiBXZSBjYWxsIHRoZXNlICdsaW5rZWQnIGVkZ2VzLiBBbnkgbGlua2VkIGVkZ2VzIHdpbGwgZGVwZW5kXG4gICAgICAgICAgICAgICAgICogb24gdGhlIGFjdGl2ZSBlZGdlcyBhbmQgdGhlIGVkZ2UgYmVpbmcgaW50ZXJhY3RlZCB3aXRoLlxuICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnRhcmdldC5vcHRpb25zLnJlc2l6ZS5zcXVhcmUgfHwgdGhpcy50YXJnZXQub3B0aW9ucy5yZXNpemUucHJlc2VydmVBc3BlY3RSYXRpbykge1xuICAgICAgICAgICAgICAgICAgICB2YXIgbGlua2VkRWRnZXMgPSBleHRlbmQoe30sIHRoaXMucHJlcGFyZWQuZWRnZXMpO1xuXG4gICAgICAgICAgICAgICAgICAgIGxpbmtlZEVkZ2VzLnRvcCAgICA9IGxpbmtlZEVkZ2VzLnRvcCAgICB8fCAobGlua2VkRWRnZXMubGVmdCAgICYmICFsaW5rZWRFZGdlcy5ib3R0b20pO1xuICAgICAgICAgICAgICAgICAgICBsaW5rZWRFZGdlcy5sZWZ0ICAgPSBsaW5rZWRFZGdlcy5sZWZ0ICAgfHwgKGxpbmtlZEVkZ2VzLnRvcCAgICAmJiAhbGlua2VkRWRnZXMucmlnaHQgKTtcbiAgICAgICAgICAgICAgICAgICAgbGlua2VkRWRnZXMuYm90dG9tID0gbGlua2VkRWRnZXMuYm90dG9tIHx8IChsaW5rZWRFZGdlcy5yaWdodCAgJiYgIWxpbmtlZEVkZ2VzLnRvcCAgICk7XG4gICAgICAgICAgICAgICAgICAgIGxpbmtlZEVkZ2VzLnJpZ2h0ICA9IGxpbmtlZEVkZ2VzLnJpZ2h0ICB8fCAobGlua2VkRWRnZXMuYm90dG9tICYmICFsaW5rZWRFZGdlcy5sZWZ0ICApO1xuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJlcGFyZWQuX2xpbmtlZEVkZ2VzID0gbGlua2VkRWRnZXM7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnByZXBhcmVkLl9saW5rZWRFZGdlcyA9IG51bGw7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gaWYgdXNpbmcgYHJlc2l6YWJsZS5wcmVzZXJ2ZUFzcGVjdFJhdGlvYCBvcHRpb24sIHJlY29yZCBhc3BlY3QgcmF0aW8gYXQgdGhlIHN0YXJ0IG9mIHRoZSByZXNpemVcbiAgICAgICAgICAgICAgICBpZiAodGhpcy50YXJnZXQub3B0aW9ucy5yZXNpemUucHJlc2VydmVBc3BlY3RSYXRpbykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc2l6ZVN0YXJ0QXNwZWN0UmF0aW8gPSBzdGFydFJlY3Qud2lkdGggLyBzdGFydFJlY3QuaGVpZ2h0O1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMucmVzaXplUmVjdHMgPSB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXJ0ICAgICA6IHN0YXJ0UmVjdCxcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudCAgIDogZXh0ZW5kKHt9LCBzdGFydFJlY3QpLFxuICAgICAgICAgICAgICAgICAgICByZXN0cmljdGVkOiBleHRlbmQoe30sIHN0YXJ0UmVjdCksXG4gICAgICAgICAgICAgICAgICAgIHByZXZpb3VzICA6IGV4dGVuZCh7fSwgc3RhcnRSZWN0KSxcbiAgICAgICAgICAgICAgICAgICAgZGVsdGEgICAgIDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGVmdDogMCwgcmlnaHQgOiAwLCB3aWR0aCA6IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICB0b3AgOiAwLCBib3R0b206IDAsIGhlaWdodDogMFxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgIHJlc2l6ZUV2ZW50LnJlY3QgPSB0aGlzLnJlc2l6ZVJlY3RzLnJlc3RyaWN0ZWQ7XG4gICAgICAgICAgICAgICAgcmVzaXplRXZlbnQuZGVsdGFSZWN0ID0gdGhpcy5yZXNpemVSZWN0cy5kZWx0YTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy50YXJnZXQuZmlyZShyZXNpemVFdmVudCk7XG5cbiAgICAgICAgICAgIHRoaXMucmVzaXppbmcgPSB0cnVlO1xuXG4gICAgICAgICAgICByZXR1cm4gcmVzaXplRXZlbnQ7XG4gICAgICAgIH0sXG5cbiAgICAgICAgcmVzaXplTW92ZTogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgICB2YXIgcmVzaXplRXZlbnQgPSBuZXcgSW50ZXJhY3RFdmVudCh0aGlzLCBldmVudCwgJ3Jlc2l6ZScsICdtb3ZlJywgdGhpcy5lbGVtZW50KTtcblxuICAgICAgICAgICAgdmFyIGVkZ2VzID0gdGhpcy5wcmVwYXJlZC5lZGdlcyxcbiAgICAgICAgICAgICAgICBpbnZlcnQgPSB0aGlzLnRhcmdldC5vcHRpb25zLnJlc2l6ZS5pbnZlcnQsXG4gICAgICAgICAgICAgICAgaW52ZXJ0aWJsZSA9IGludmVydCA9PT0gJ3JlcG9zaXRpb24nIHx8IGludmVydCA9PT0gJ25lZ2F0ZSc7XG5cbiAgICAgICAgICAgIGlmIChlZGdlcykge1xuICAgICAgICAgICAgICAgIHZhciBkeCA9IHJlc2l6ZUV2ZW50LmR4LFxuICAgICAgICAgICAgICAgICAgICBkeSA9IHJlc2l6ZUV2ZW50LmR5LFxuXG4gICAgICAgICAgICAgICAgICAgIHN0YXJ0ICAgICAgPSB0aGlzLnJlc2l6ZVJlY3RzLnN0YXJ0LFxuICAgICAgICAgICAgICAgICAgICBjdXJyZW50ICAgID0gdGhpcy5yZXNpemVSZWN0cy5jdXJyZW50LFxuICAgICAgICAgICAgICAgICAgICByZXN0cmljdGVkID0gdGhpcy5yZXNpemVSZWN0cy5yZXN0cmljdGVkLFxuICAgICAgICAgICAgICAgICAgICBkZWx0YSAgICAgID0gdGhpcy5yZXNpemVSZWN0cy5kZWx0YSxcbiAgICAgICAgICAgICAgICAgICAgcHJldmlvdXMgICA9IGV4dGVuZCh0aGlzLnJlc2l6ZVJlY3RzLnByZXZpb3VzLCByZXN0cmljdGVkKSxcblxuICAgICAgICAgICAgICAgICAgICBvcmlnaW5hbEVkZ2VzID0gZWRnZXM7XG5cbiAgICAgICAgICAgICAgICAvLyBgcmVzaXplLnByZXNlcnZlQXNwZWN0UmF0aW9gIHRha2VzIHByZWNlZGVuY2Ugb3ZlciBgcmVzaXplLnNxdWFyZWBcbiAgICAgICAgICAgICAgICBpZiAodGhpcy50YXJnZXQub3B0aW9ucy5yZXNpemUucHJlc2VydmVBc3BlY3RSYXRpbykge1xuICAgICAgICAgICAgICAgICAgICB2YXIgcmVzaXplU3RhcnRBc3BlY3RSYXRpbyA9IHRoaXMucmVzaXplU3RhcnRBc3BlY3RSYXRpbztcblxuICAgICAgICAgICAgICAgICAgICBlZGdlcyA9IHRoaXMucHJlcGFyZWQuX2xpbmtlZEVkZ2VzO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICgob3JpZ2luYWxFZGdlcy5sZWZ0ICYmIG9yaWdpbmFsRWRnZXMuYm90dG9tKVxuICAgICAgICAgICAgICAgICAgICAgICAgfHwgKG9yaWdpbmFsRWRnZXMucmlnaHQgJiYgb3JpZ2luYWxFZGdlcy50b3ApKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkeSA9IC1keCAvIHJlc2l6ZVN0YXJ0QXNwZWN0UmF0aW87XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAob3JpZ2luYWxFZGdlcy5sZWZ0IHx8IG9yaWdpbmFsRWRnZXMucmlnaHQpIHsgZHkgPSBkeCAvIHJlc2l6ZVN0YXJ0QXNwZWN0UmF0aW87IH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAob3JpZ2luYWxFZGdlcy50b3AgfHwgb3JpZ2luYWxFZGdlcy5ib3R0b20pIHsgZHggPSBkeSAqIHJlc2l6ZVN0YXJ0QXNwZWN0UmF0aW87IH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodGhpcy50YXJnZXQub3B0aW9ucy5yZXNpemUuc3F1YXJlKSB7XG4gICAgICAgICAgICAgICAgICAgIGVkZ2VzID0gdGhpcy5wcmVwYXJlZC5fbGlua2VkRWRnZXM7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKChvcmlnaW5hbEVkZ2VzLmxlZnQgJiYgb3JpZ2luYWxFZGdlcy5ib3R0b20pXG4gICAgICAgICAgICAgICAgICAgICAgICB8fCAob3JpZ2luYWxFZGdlcy5yaWdodCAmJiBvcmlnaW5hbEVkZ2VzLnRvcCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGR5ID0gLWR4O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKG9yaWdpbmFsRWRnZXMubGVmdCB8fCBvcmlnaW5hbEVkZ2VzLnJpZ2h0KSB7IGR5ID0gZHg7IH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAob3JpZ2luYWxFZGdlcy50b3AgfHwgb3JpZ2luYWxFZGdlcy5ib3R0b20pIHsgZHggPSBkeTsgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIHVwZGF0ZSB0aGUgJ2N1cnJlbnQnIHJlY3Qgd2l0aG91dCBtb2RpZmljYXRpb25zXG4gICAgICAgICAgICAgICAgaWYgKGVkZ2VzLnRvcCAgICkgeyBjdXJyZW50LnRvcCAgICArPSBkeTsgfVxuICAgICAgICAgICAgICAgIGlmIChlZGdlcy5ib3R0b20pIHsgY3VycmVudC5ib3R0b20gKz0gZHk7IH1cbiAgICAgICAgICAgICAgICBpZiAoZWRnZXMubGVmdCAgKSB7IGN1cnJlbnQubGVmdCAgICs9IGR4OyB9XG4gICAgICAgICAgICAgICAgaWYgKGVkZ2VzLnJpZ2h0ICkgeyBjdXJyZW50LnJpZ2h0ICArPSBkeDsgfVxuXG4gICAgICAgICAgICAgICAgaWYgKGludmVydGlibGUpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gaWYgaW52ZXJ0aWJsZSwgY29weSB0aGUgY3VycmVudCByZWN0XG4gICAgICAgICAgICAgICAgICAgIGV4dGVuZChyZXN0cmljdGVkLCBjdXJyZW50KTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoaW52ZXJ0ID09PSAncmVwb3NpdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHN3YXAgZWRnZSB2YWx1ZXMgaWYgbmVjZXNzYXJ5IHRvIGtlZXAgd2lkdGgvaGVpZ2h0IHBvc2l0aXZlXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3dhcDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3RyaWN0ZWQudG9wID4gcmVzdHJpY3RlZC5ib3R0b20pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2FwID0gcmVzdHJpY3RlZC50b3A7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN0cmljdGVkLnRvcCA9IHJlc3RyaWN0ZWQuYm90dG9tO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3RyaWN0ZWQuYm90dG9tID0gc3dhcDtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXN0cmljdGVkLmxlZnQgPiByZXN0cmljdGVkLnJpZ2h0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3dhcCA9IHJlc3RyaWN0ZWQubGVmdDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3RyaWN0ZWQubGVmdCA9IHJlc3RyaWN0ZWQucmlnaHQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdHJpY3RlZC5yaWdodCA9IHN3YXA7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGlmIG5vdCBpbnZlcnRpYmxlLCByZXN0cmljdCB0byBtaW5pbXVtIG9mIDB4MCByZWN0XG4gICAgICAgICAgICAgICAgICAgIHJlc3RyaWN0ZWQudG9wICAgID0gTWF0aC5taW4oY3VycmVudC50b3AsIHN0YXJ0LmJvdHRvbSk7XG4gICAgICAgICAgICAgICAgICAgIHJlc3RyaWN0ZWQuYm90dG9tID0gTWF0aC5tYXgoY3VycmVudC5ib3R0b20sIHN0YXJ0LnRvcCk7XG4gICAgICAgICAgICAgICAgICAgIHJlc3RyaWN0ZWQubGVmdCAgID0gTWF0aC5taW4oY3VycmVudC5sZWZ0LCBzdGFydC5yaWdodCk7XG4gICAgICAgICAgICAgICAgICAgIHJlc3RyaWN0ZWQucmlnaHQgID0gTWF0aC5tYXgoY3VycmVudC5yaWdodCwgc3RhcnQubGVmdCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmVzdHJpY3RlZC53aWR0aCAgPSByZXN0cmljdGVkLnJpZ2h0ICAtIHJlc3RyaWN0ZWQubGVmdDtcbiAgICAgICAgICAgICAgICByZXN0cmljdGVkLmhlaWdodCA9IHJlc3RyaWN0ZWQuYm90dG9tIC0gcmVzdHJpY3RlZC50b3AgO1xuXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgZWRnZSBpbiByZXN0cmljdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbHRhW2VkZ2VdID0gcmVzdHJpY3RlZFtlZGdlXSAtIHByZXZpb3VzW2VkZ2VdO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJlc2l6ZUV2ZW50LmVkZ2VzID0gdGhpcy5wcmVwYXJlZC5lZGdlcztcbiAgICAgICAgICAgICAgICByZXNpemVFdmVudC5yZWN0ID0gcmVzdHJpY3RlZDtcbiAgICAgICAgICAgICAgICByZXNpemVFdmVudC5kZWx0YVJlY3QgPSBkZWx0YTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy50YXJnZXQuZmlyZShyZXNpemVFdmVudCk7XG5cbiAgICAgICAgICAgIHJldHVybiByZXNpemVFdmVudDtcbiAgICAgICAgfSxcblxuICAgICAgICBnZXN0dXJlU3RhcnQ6IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICAgICAgdmFyIGdlc3R1cmVFdmVudCA9IG5ldyBJbnRlcmFjdEV2ZW50KHRoaXMsIGV2ZW50LCAnZ2VzdHVyZScsICdzdGFydCcsIHRoaXMuZWxlbWVudCk7XG5cbiAgICAgICAgICAgIGdlc3R1cmVFdmVudC5kcyA9IDA7XG5cbiAgICAgICAgICAgIHRoaXMuZ2VzdHVyZS5zdGFydERpc3RhbmNlID0gdGhpcy5nZXN0dXJlLnByZXZEaXN0YW5jZSA9IGdlc3R1cmVFdmVudC5kaXN0YW5jZTtcbiAgICAgICAgICAgIHRoaXMuZ2VzdHVyZS5zdGFydEFuZ2xlID0gdGhpcy5nZXN0dXJlLnByZXZBbmdsZSA9IGdlc3R1cmVFdmVudC5hbmdsZTtcbiAgICAgICAgICAgIHRoaXMuZ2VzdHVyZS5zY2FsZSA9IDE7XG5cbiAgICAgICAgICAgIHRoaXMuZ2VzdHVyaW5nID0gdHJ1ZTtcblxuICAgICAgICAgICAgdGhpcy50YXJnZXQuZmlyZShnZXN0dXJlRXZlbnQpO1xuXG4gICAgICAgICAgICByZXR1cm4gZ2VzdHVyZUV2ZW50O1xuICAgICAgICB9LFxuXG4gICAgICAgIGdlc3R1cmVNb3ZlOiBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5wb2ludGVySWRzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnByZXZFdmVudDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIGdlc3R1cmVFdmVudDtcblxuICAgICAgICAgICAgZ2VzdHVyZUV2ZW50ID0gbmV3IEludGVyYWN0RXZlbnQodGhpcywgZXZlbnQsICdnZXN0dXJlJywgJ21vdmUnLCB0aGlzLmVsZW1lbnQpO1xuICAgICAgICAgICAgZ2VzdHVyZUV2ZW50LmRzID0gZ2VzdHVyZUV2ZW50LnNjYWxlIC0gdGhpcy5nZXN0dXJlLnNjYWxlO1xuXG4gICAgICAgICAgICB0aGlzLnRhcmdldC5maXJlKGdlc3R1cmVFdmVudCk7XG5cbiAgICAgICAgICAgIHRoaXMuZ2VzdHVyZS5wcmV2QW5nbGUgPSBnZXN0dXJlRXZlbnQuYW5nbGU7XG4gICAgICAgICAgICB0aGlzLmdlc3R1cmUucHJldkRpc3RhbmNlID0gZ2VzdHVyZUV2ZW50LmRpc3RhbmNlO1xuXG4gICAgICAgICAgICBpZiAoZ2VzdHVyZUV2ZW50LnNjYWxlICE9PSBJbmZpbml0eSAmJlxuICAgICAgICAgICAgICAgIGdlc3R1cmVFdmVudC5zY2FsZSAhPT0gbnVsbCAmJlxuICAgICAgICAgICAgICAgIGdlc3R1cmVFdmVudC5zY2FsZSAhPT0gdW5kZWZpbmVkICAmJlxuICAgICAgICAgICAgICAgICFpc05hTihnZXN0dXJlRXZlbnQuc2NhbGUpKSB7XG5cbiAgICAgICAgICAgICAgICB0aGlzLmdlc3R1cmUuc2NhbGUgPSBnZXN0dXJlRXZlbnQuc2NhbGU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBnZXN0dXJlRXZlbnQ7XG4gICAgICAgIH0sXG5cbiAgICAgICAgcG9pbnRlckhvbGQ6IGZ1bmN0aW9uIChwb2ludGVyLCBldmVudCwgZXZlbnRUYXJnZXQpIHtcbiAgICAgICAgICAgIHRoaXMuY29sbGVjdEV2ZW50VGFyZ2V0cyhwb2ludGVyLCBldmVudCwgZXZlbnRUYXJnZXQsICdob2xkJyk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgcG9pbnRlclVwOiBmdW5jdGlvbiAocG9pbnRlciwgZXZlbnQsIGV2ZW50VGFyZ2V0LCBjdXJFdmVudFRhcmdldCkge1xuICAgICAgICAgICAgdmFyIHBvaW50ZXJJbmRleCA9IHRoaXMubW91c2U/IDAgOiBpbmRleE9mKHRoaXMucG9pbnRlcklkcywgZ2V0UG9pbnRlcklkKHBvaW50ZXIpKTtcblxuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuaG9sZFRpbWVyc1twb2ludGVySW5kZXhdKTtcblxuICAgICAgICAgICAgdGhpcy5jb2xsZWN0RXZlbnRUYXJnZXRzKHBvaW50ZXIsIGV2ZW50LCBldmVudFRhcmdldCwgJ3VwJyApO1xuICAgICAgICAgICAgdGhpcy5jb2xsZWN0RXZlbnRUYXJnZXRzKHBvaW50ZXIsIGV2ZW50LCBldmVudFRhcmdldCwgJ3RhcCcpO1xuXG4gICAgICAgICAgICB0aGlzLnBvaW50ZXJFbmQocG9pbnRlciwgZXZlbnQsIGV2ZW50VGFyZ2V0LCBjdXJFdmVudFRhcmdldCk7XG5cbiAgICAgICAgICAgIHRoaXMucmVtb3ZlUG9pbnRlcihwb2ludGVyKTtcbiAgICAgICAgfSxcblxuICAgICAgICBwb2ludGVyQ2FuY2VsOiBmdW5jdGlvbiAocG9pbnRlciwgZXZlbnQsIGV2ZW50VGFyZ2V0LCBjdXJFdmVudFRhcmdldCkge1xuICAgICAgICAgICAgdmFyIHBvaW50ZXJJbmRleCA9IHRoaXMubW91c2U/IDAgOiBpbmRleE9mKHRoaXMucG9pbnRlcklkcywgZ2V0UG9pbnRlcklkKHBvaW50ZXIpKTtcblxuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuaG9sZFRpbWVyc1twb2ludGVySW5kZXhdKTtcblxuICAgICAgICAgICAgdGhpcy5jb2xsZWN0RXZlbnRUYXJnZXRzKHBvaW50ZXIsIGV2ZW50LCBldmVudFRhcmdldCwgJ2NhbmNlbCcpO1xuICAgICAgICAgICAgdGhpcy5wb2ludGVyRW5kKHBvaW50ZXIsIGV2ZW50LCBldmVudFRhcmdldCwgY3VyRXZlbnRUYXJnZXQpO1xuXG4gICAgICAgICAgICB0aGlzLnJlbW92ZVBvaW50ZXIocG9pbnRlcik7XG4gICAgICAgIH0sXG5cbiAgICAgICAgLy8gaHR0cDovL3d3dy5xdWlya3Ntb2RlLm9yZy9kb20vZXZlbnRzL2NsaWNrLmh0bWxcbiAgICAgICAgLy8gPkV2ZW50cyBsZWFkaW5nIHRvIGRibGNsaWNrXG4gICAgICAgIC8vXG4gICAgICAgIC8vIElFOCBkb2Vzbid0IGZpcmUgZG93biBldmVudCBiZWZvcmUgZGJsY2xpY2suXG4gICAgICAgIC8vIFRoaXMgd29ya2Fyb3VuZCB0cmllcyB0byBmaXJlIGEgdGFwIGFuZCBkb3VibGV0YXAgYWZ0ZXIgZGJsY2xpY2tcbiAgICAgICAgaWU4RGJsY2xpY2s6IGZ1bmN0aW9uIChwb2ludGVyLCBldmVudCwgZXZlbnRUYXJnZXQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnByZXZUYXBcbiAgICAgICAgICAgICAgICAmJiBldmVudC5jbGllbnRYID09PSB0aGlzLnByZXZUYXAuY2xpZW50WFxuICAgICAgICAgICAgICAgICYmIGV2ZW50LmNsaWVudFkgPT09IHRoaXMucHJldlRhcC5jbGllbnRZXG4gICAgICAgICAgICAgICAgJiYgZXZlbnRUYXJnZXQgICA9PT0gdGhpcy5wcmV2VGFwLnRhcmdldCkge1xuXG4gICAgICAgICAgICAgICAgdGhpcy5kb3duVGFyZ2V0c1swXSA9IGV2ZW50VGFyZ2V0O1xuICAgICAgICAgICAgICAgIHRoaXMuZG93blRpbWVzWzBdID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5jb2xsZWN0RXZlbnRUYXJnZXRzKHBvaW50ZXIsIGV2ZW50LCBldmVudFRhcmdldCwgJ3RhcCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIC8vIEVuZCBpbnRlcmFjdCBtb3ZlIGV2ZW50cyBhbmQgc3RvcCBhdXRvLXNjcm9sbCB1bmxlc3MgaW5lcnRpYSBpcyBlbmFibGVkXG4gICAgICAgIHBvaW50ZXJFbmQ6IGZ1bmN0aW9uIChwb2ludGVyLCBldmVudCwgZXZlbnRUYXJnZXQsIGN1ckV2ZW50VGFyZ2V0KSB7XG4gICAgICAgICAgICB2YXIgZW5kRXZlbnQsXG4gICAgICAgICAgICAgICAgdGFyZ2V0ID0gdGhpcy50YXJnZXQsXG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IHRhcmdldCAmJiB0YXJnZXQub3B0aW9ucyxcbiAgICAgICAgICAgICAgICBpbmVydGlhT3B0aW9ucyA9IG9wdGlvbnMgJiYgdGhpcy5wcmVwYXJlZC5uYW1lICYmIG9wdGlvbnNbdGhpcy5wcmVwYXJlZC5uYW1lXS5pbmVydGlhLFxuICAgICAgICAgICAgICAgIGluZXJ0aWFTdGF0dXMgPSB0aGlzLmluZXJ0aWFTdGF0dXM7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmludGVyYWN0aW5nKCkpIHtcblxuICAgICAgICAgICAgICAgIGlmIChpbmVydGlhU3RhdHVzLmFjdGl2ZSAmJiAhaW5lcnRpYVN0YXR1cy5lbmRpbmcpIHsgcmV0dXJuOyB9XG5cbiAgICAgICAgICAgICAgICB2YXIgcG9pbnRlclNwZWVkLFxuICAgICAgICAgICAgICAgICAgICBub3cgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKSxcbiAgICAgICAgICAgICAgICAgICAgaW5lcnRpYVBvc3NpYmxlID0gZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIGluZXJ0aWEgPSBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgc21vb3RoRW5kID0gZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIGVuZFNuYXAgPSBjaGVja1NuYXAodGFyZ2V0LCB0aGlzLnByZXBhcmVkLm5hbWUpICYmIG9wdGlvbnNbdGhpcy5wcmVwYXJlZC5uYW1lXS5zbmFwLmVuZE9ubHksXG4gICAgICAgICAgICAgICAgICAgIGVuZFJlc3RyaWN0ID0gY2hlY2tSZXN0cmljdCh0YXJnZXQsIHRoaXMucHJlcGFyZWQubmFtZSkgJiYgb3B0aW9uc1t0aGlzLnByZXBhcmVkLm5hbWVdLnJlc3RyaWN0LmVuZE9ubHksXG4gICAgICAgICAgICAgICAgICAgIGR4ID0gMCxcbiAgICAgICAgICAgICAgICAgICAgZHkgPSAwLFxuICAgICAgICAgICAgICAgICAgICBzdGFydEV2ZW50O1xuXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZHJhZ2dpbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgICAgICAob3B0aW9ucy5kcmFnLmF4aXMgPT09ICd4JyApIHsgcG9pbnRlclNwZWVkID0gTWF0aC5hYnModGhpcy5wb2ludGVyRGVsdGEuY2xpZW50LnZ4KTsgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChvcHRpb25zLmRyYWcuYXhpcyA9PT0gJ3knICkgeyBwb2ludGVyU3BlZWQgPSBNYXRoLmFicyh0aGlzLnBvaW50ZXJEZWx0YS5jbGllbnQudnkpOyB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgICAvKm9wdGlvbnMuZHJhZy5heGlzID09PSAneHknKi97IHBvaW50ZXJTcGVlZCA9IHRoaXMucG9pbnRlckRlbHRhLmNsaWVudC5zcGVlZDsgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcG9pbnRlclNwZWVkID0gdGhpcy5wb2ludGVyRGVsdGEuY2xpZW50LnNwZWVkO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIGNoZWNrIGlmIGluZXJ0aWEgc2hvdWxkIGJlIHN0YXJ0ZWRcbiAgICAgICAgICAgICAgICBpbmVydGlhUG9zc2libGUgPSAoaW5lcnRpYU9wdGlvbnMgJiYgaW5lcnRpYU9wdGlvbnMuZW5hYmxlZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiB0aGlzLnByZXBhcmVkLm5hbWUgIT09ICdnZXN0dXJlJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBldmVudCAhPT0gaW5lcnRpYVN0YXR1cy5zdGFydEV2ZW50KTtcblxuICAgICAgICAgICAgICAgIGluZXJ0aWEgPSAoaW5lcnRpYVBvc3NpYmxlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAmJiAobm93IC0gdGhpcy5jdXJDb29yZHMudGltZVN0YW1wKSA8IDUwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBwb2ludGVyU3BlZWQgPiBpbmVydGlhT3B0aW9ucy5taW5TcGVlZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgcG9pbnRlclNwZWVkID4gaW5lcnRpYU9wdGlvbnMuZW5kU3BlZWQpO1xuXG4gICAgICAgICAgICAgICAgaWYgKGluZXJ0aWFQb3NzaWJsZSAmJiAhaW5lcnRpYSAmJiAoZW5kU25hcCB8fCBlbmRSZXN0cmljdCkpIHtcblxuICAgICAgICAgICAgICAgICAgICB2YXIgc25hcFJlc3RyaWN0ID0ge307XG5cbiAgICAgICAgICAgICAgICAgICAgc25hcFJlc3RyaWN0LnNuYXAgPSBzbmFwUmVzdHJpY3QucmVzdHJpY3QgPSBzbmFwUmVzdHJpY3Q7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGVuZFNuYXApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0U25hcHBpbmcodGhpcy5jdXJDb29yZHMucGFnZSwgc25hcFJlc3RyaWN0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzbmFwUmVzdHJpY3QubG9ja2VkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZHggKz0gc25hcFJlc3RyaWN0LmR4O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR5ICs9IHNuYXBSZXN0cmljdC5keTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGlmIChlbmRSZXN0cmljdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRSZXN0cmljdGlvbih0aGlzLmN1ckNvb3Jkcy5wYWdlLCBzbmFwUmVzdHJpY3QpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNuYXBSZXN0cmljdC5yZXN0cmljdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZHggKz0gc25hcFJlc3RyaWN0LmR4O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR5ICs9IHNuYXBSZXN0cmljdC5keTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGlmIChkeCB8fCBkeSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc21vb3RoRW5kID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChpbmVydGlhIHx8IHNtb290aEVuZCkge1xuICAgICAgICAgICAgICAgICAgICBjb3B5Q29vcmRzKGluZXJ0aWFTdGF0dXMudXBDb29yZHMsIHRoaXMuY3VyQ29vcmRzKTtcblxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBvaW50ZXJzWzBdID0gaW5lcnRpYVN0YXR1cy5zdGFydEV2ZW50ID0gc3RhcnRFdmVudCA9XG4gICAgICAgICAgICAgICAgICAgICAgICBuZXcgSW50ZXJhY3RFdmVudCh0aGlzLCBldmVudCwgdGhpcy5wcmVwYXJlZC5uYW1lLCAnaW5lcnRpYXN0YXJ0JywgdGhpcy5lbGVtZW50KTtcblxuICAgICAgICAgICAgICAgICAgICBpbmVydGlhU3RhdHVzLnQwID0gbm93O1xuXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldC5maXJlKGluZXJ0aWFTdGF0dXMuc3RhcnRFdmVudCk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGluZXJ0aWEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGluZXJ0aWFTdGF0dXMudngwID0gdGhpcy5wb2ludGVyRGVsdGEuY2xpZW50LnZ4O1xuICAgICAgICAgICAgICAgICAgICAgICAgaW5lcnRpYVN0YXR1cy52eTAgPSB0aGlzLnBvaW50ZXJEZWx0YS5jbGllbnQudnk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpbmVydGlhU3RhdHVzLnYwID0gcG9pbnRlclNwZWVkO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNhbGNJbmVydGlhKGluZXJ0aWFTdGF0dXMpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGFnZSA9IGV4dGVuZCh7fSwgdGhpcy5jdXJDb29yZHMucGFnZSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luID0gZ2V0T3JpZ2luWFkodGFyZ2V0LCB0aGlzLmVsZW1lbnQpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1c09iamVjdDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgcGFnZS54ID0gcGFnZS54ICsgaW5lcnRpYVN0YXR1cy54ZSAtIG9yaWdpbi54O1xuICAgICAgICAgICAgICAgICAgICAgICAgcGFnZS55ID0gcGFnZS55ICsgaW5lcnRpYVN0YXR1cy55ZSAtIG9yaWdpbi55O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXNPYmplY3QgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlU3RhdHVzWFk6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeDogcGFnZS54LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IHBhZ2UueSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkeDogMCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkeTogMCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbmFwOiBudWxsXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXNPYmplY3Quc25hcCA9IHN0YXR1c09iamVjdDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgZHggPSBkeSA9IDA7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbmRTbmFwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNuYXAgPSB0aGlzLnNldFNuYXBwaW5nKHRoaXMuY3VyQ29vcmRzLnBhZ2UsIHN0YXR1c09iamVjdCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc25hcC5sb2NrZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHggKz0gc25hcC5keDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHkgKz0gc25hcC5keTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbmRSZXN0cmljdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZXN0cmljdCA9IHRoaXMuc2V0UmVzdHJpY3Rpb24odGhpcy5jdXJDb29yZHMucGFnZSwgc3RhdHVzT2JqZWN0KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXN0cmljdC5yZXN0cmljdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR4ICs9IHJlc3RyaWN0LmR4O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkeSArPSByZXN0cmljdC5keTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGluZXJ0aWFTdGF0dXMubW9kaWZpZWRYZSArPSBkeDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGluZXJ0aWFTdGF0dXMubW9kaWZpZWRZZSArPSBkeTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaW5lcnRpYVN0YXR1cy5pID0gcmVxRnJhbWUodGhpcy5ib3VuZEluZXJ0aWFGcmFtZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpbmVydGlhU3RhdHVzLnNtb290aEVuZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBpbmVydGlhU3RhdHVzLnhlID0gZHg7XG4gICAgICAgICAgICAgICAgICAgICAgICBpbmVydGlhU3RhdHVzLnllID0gZHk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGluZXJ0aWFTdGF0dXMuc3ggPSBpbmVydGlhU3RhdHVzLnN5ID0gMDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaW5lcnRpYVN0YXR1cy5pID0gcmVxRnJhbWUodGhpcy5ib3VuZFNtb290aEVuZEZyYW1lKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGluZXJ0aWFTdGF0dXMuYWN0aXZlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChlbmRTbmFwIHx8IGVuZFJlc3RyaWN0KSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGZpcmUgYSBtb3ZlIGV2ZW50IGF0IHRoZSBzbmFwcGVkIGNvb3JkaW5hdGVzXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucG9pbnRlck1vdmUocG9pbnRlciwgZXZlbnQsIGV2ZW50VGFyZ2V0LCBjdXJFdmVudFRhcmdldCwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy5kcmFnZ2luZykge1xuICAgICAgICAgICAgICAgIGVuZEV2ZW50ID0gbmV3IEludGVyYWN0RXZlbnQodGhpcywgZXZlbnQsICdkcmFnJywgJ2VuZCcsIHRoaXMuZWxlbWVudCk7XG5cbiAgICAgICAgICAgICAgICB2YXIgZHJhZ2dhYmxlRWxlbWVudCA9IHRoaXMuZWxlbWVudCxcbiAgICAgICAgICAgICAgICAgICAgZHJvcCA9IHRoaXMuZ2V0RHJvcChlbmRFdmVudCwgZXZlbnQsIGRyYWdnYWJsZUVsZW1lbnQpO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5kcm9wVGFyZ2V0ID0gZHJvcC5kcm9wem9uZTtcbiAgICAgICAgICAgICAgICB0aGlzLmRyb3BFbGVtZW50ID0gZHJvcC5lbGVtZW50O1xuXG4gICAgICAgICAgICAgICAgdmFyIGRyb3BFdmVudHMgPSB0aGlzLmdldERyb3BFdmVudHMoZXZlbnQsIGVuZEV2ZW50KTtcblxuICAgICAgICAgICAgICAgIGlmIChkcm9wRXZlbnRzLmxlYXZlKSB7IHRoaXMucHJldkRyb3BUYXJnZXQuZmlyZShkcm9wRXZlbnRzLmxlYXZlKTsgfVxuICAgICAgICAgICAgICAgIGlmIChkcm9wRXZlbnRzLmVudGVyKSB7ICAgICB0aGlzLmRyb3BUYXJnZXQuZmlyZShkcm9wRXZlbnRzLmVudGVyKTsgfVxuICAgICAgICAgICAgICAgIGlmIChkcm9wRXZlbnRzLmRyb3AgKSB7ICAgICB0aGlzLmRyb3BUYXJnZXQuZmlyZShkcm9wRXZlbnRzLmRyb3AgKTsgfVxuICAgICAgICAgICAgICAgIGlmIChkcm9wRXZlbnRzLmRlYWN0aXZhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5maXJlQWN0aXZlRHJvcHMoZHJvcEV2ZW50cy5kZWFjdGl2YXRlKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0YXJnZXQuZmlyZShlbmRFdmVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh0aGlzLnJlc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgZW5kRXZlbnQgPSBuZXcgSW50ZXJhY3RFdmVudCh0aGlzLCBldmVudCwgJ3Jlc2l6ZScsICdlbmQnLCB0aGlzLmVsZW1lbnQpO1xuICAgICAgICAgICAgICAgIHRhcmdldC5maXJlKGVuZEV2ZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuZ2VzdHVyaW5nKSB7XG4gICAgICAgICAgICAgICAgZW5kRXZlbnQgPSBuZXcgSW50ZXJhY3RFdmVudCh0aGlzLCBldmVudCwgJ2dlc3R1cmUnLCAnZW5kJywgdGhpcy5lbGVtZW50KTtcbiAgICAgICAgICAgICAgICB0YXJnZXQuZmlyZShlbmRFdmVudCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuc3RvcChldmVudCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgY29sbGVjdERyb3BzOiBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICAgICAgICAgdmFyIGRyb3BzID0gW10sXG4gICAgICAgICAgICAgICAgZWxlbWVudHMgPSBbXSxcbiAgICAgICAgICAgICAgICBpO1xuXG4gICAgICAgICAgICBlbGVtZW50ID0gZWxlbWVudCB8fCB0aGlzLmVsZW1lbnQ7XG5cbiAgICAgICAgICAgIC8vIGNvbGxlY3QgYWxsIGRyb3B6b25lcyBhbmQgdGhlaXIgZWxlbWVudHMgd2hpY2ggcXVhbGlmeSBmb3IgYSBkcm9wXG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgaW50ZXJhY3RhYmxlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmICghaW50ZXJhY3RhYmxlc1tpXS5vcHRpb25zLmRyb3AuZW5hYmxlZCkgeyBjb250aW51ZTsgfVxuXG4gICAgICAgICAgICAgICAgdmFyIGN1cnJlbnQgPSBpbnRlcmFjdGFibGVzW2ldLFxuICAgICAgICAgICAgICAgICAgICBhY2NlcHQgPSBjdXJyZW50Lm9wdGlvbnMuZHJvcC5hY2NlcHQ7XG5cbiAgICAgICAgICAgICAgICAvLyB0ZXN0IHRoZSBkcmFnZ2FibGUgZWxlbWVudCBhZ2FpbnN0IHRoZSBkcm9wem9uZSdzIGFjY2VwdCBzZXR0aW5nXG4gICAgICAgICAgICAgICAgaWYgKChpc0VsZW1lbnQoYWNjZXB0KSAmJiBhY2NlcHQgIT09IGVsZW1lbnQpXG4gICAgICAgICAgICAgICAgICAgIHx8IChpc1N0cmluZyhhY2NlcHQpXG4gICAgICAgICAgICAgICAgICAgICAgICAmJiAhbWF0Y2hlc1NlbGVjdG9yKGVsZW1lbnQsIGFjY2VwdCkpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gcXVlcnkgZm9yIG5ldyBlbGVtZW50cyBpZiBuZWNlc3NhcnlcbiAgICAgICAgICAgICAgICB2YXIgZHJvcEVsZW1lbnRzID0gY3VycmVudC5zZWxlY3Rvcj8gY3VycmVudC5fY29udGV4dC5xdWVyeVNlbGVjdG9yQWxsKGN1cnJlbnQuc2VsZWN0b3IpIDogW2N1cnJlbnQuX2VsZW1lbnRdO1xuXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDAsIGxlbiA9IGRyb3BFbGVtZW50cy5sZW5ndGg7IGogPCBsZW47IGorKykge1xuICAgICAgICAgICAgICAgICAgICB2YXIgY3VycmVudEVsZW1lbnQgPSBkcm9wRWxlbWVudHNbal07XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRFbGVtZW50ID09PSBlbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGRyb3BzLnB1c2goY3VycmVudCk7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnRzLnB1c2goY3VycmVudEVsZW1lbnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBkcm9wem9uZXM6IGRyb3BzLFxuICAgICAgICAgICAgICAgIGVsZW1lbnRzOiBlbGVtZW50c1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSxcblxuICAgICAgICBmaXJlQWN0aXZlRHJvcHM6IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICAgICAgdmFyIGksXG4gICAgICAgICAgICAgICAgY3VycmVudCxcbiAgICAgICAgICAgICAgICBjdXJyZW50RWxlbWVudCxcbiAgICAgICAgICAgICAgICBwcmV2RWxlbWVudDtcblxuICAgICAgICAgICAgLy8gbG9vcCB0aHJvdWdoIGFsbCBhY3RpdmUgZHJvcHpvbmVzIGFuZCB0cmlnZ2VyIGV2ZW50XG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgdGhpcy5hY3RpdmVEcm9wcy5kcm9wem9uZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50ID0gdGhpcy5hY3RpdmVEcm9wcy5kcm9wem9uZXNbaV07XG4gICAgICAgICAgICAgICAgY3VycmVudEVsZW1lbnQgPSB0aGlzLmFjdGl2ZURyb3BzLmVsZW1lbnRzIFtpXTtcblxuICAgICAgICAgICAgICAgIC8vIHByZXZlbnQgdHJpZ2dlciBvZiBkdXBsaWNhdGUgZXZlbnRzIG9uIHNhbWUgZWxlbWVudFxuICAgICAgICAgICAgICAgIGlmIChjdXJyZW50RWxlbWVudCAhPT0gcHJldkVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gc2V0IGN1cnJlbnQgZWxlbWVudCBhcyBldmVudCB0YXJnZXRcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQudGFyZ2V0ID0gY3VycmVudEVsZW1lbnQ7XG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnQuZmlyZShldmVudCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHByZXZFbGVtZW50ID0gY3VycmVudEVsZW1lbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgLy8gQ29sbGVjdCBhIG5ldyBzZXQgb2YgcG9zc2libGUgZHJvcHMgYW5kIHNhdmUgdGhlbSBpbiBhY3RpdmVEcm9wcy5cbiAgICAgICAgLy8gc2V0QWN0aXZlRHJvcHMgc2hvdWxkIGFsd2F5cyBiZSBjYWxsZWQgd2hlbiBhIGRyYWcgaGFzIGp1c3Qgc3RhcnRlZCBvciBhXG4gICAgICAgIC8vIGRyYWcgZXZlbnQgaGFwcGVucyB3aGlsZSBkeW5hbWljRHJvcCBpcyB0cnVlXG4gICAgICAgIHNldEFjdGl2ZURyb3BzOiBmdW5jdGlvbiAoZHJhZ0VsZW1lbnQpIHtcbiAgICAgICAgICAgIC8vIGdldCBkcm9wem9uZXMgYW5kIHRoZWlyIGVsZW1lbnRzIHRoYXQgY291bGQgcmVjZWl2ZSB0aGUgZHJhZ2dhYmxlXG4gICAgICAgICAgICB2YXIgcG9zc2libGVEcm9wcyA9IHRoaXMuY29sbGVjdERyb3BzKGRyYWdFbGVtZW50LCB0cnVlKTtcblxuICAgICAgICAgICAgdGhpcy5hY3RpdmVEcm9wcy5kcm9wem9uZXMgPSBwb3NzaWJsZURyb3BzLmRyb3B6b25lcztcbiAgICAgICAgICAgIHRoaXMuYWN0aXZlRHJvcHMuZWxlbWVudHMgID0gcG9zc2libGVEcm9wcy5lbGVtZW50cztcbiAgICAgICAgICAgIHRoaXMuYWN0aXZlRHJvcHMucmVjdHMgICAgID0gW107XG5cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5hY3RpdmVEcm9wcy5kcm9wem9uZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICB0aGlzLmFjdGl2ZURyb3BzLnJlY3RzW2ldID0gdGhpcy5hY3RpdmVEcm9wcy5kcm9wem9uZXNbaV0uZ2V0UmVjdCh0aGlzLmFjdGl2ZURyb3BzLmVsZW1lbnRzW2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICBnZXREcm9wOiBmdW5jdGlvbiAoZHJhZ0V2ZW50LCBldmVudCwgZHJhZ0VsZW1lbnQpIHtcbiAgICAgICAgICAgIHZhciB2YWxpZERyb3BzID0gW107XG5cbiAgICAgICAgICAgIGlmIChkeW5hbWljRHJvcCkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0QWN0aXZlRHJvcHMoZHJhZ0VsZW1lbnQpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBjb2xsZWN0IGFsbCBkcm9wem9uZXMgYW5kIHRoZWlyIGVsZW1lbnRzIHdoaWNoIHF1YWxpZnkgZm9yIGEgZHJvcFxuICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCB0aGlzLmFjdGl2ZURyb3BzLmRyb3B6b25lcy5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgICAgIHZhciBjdXJyZW50ICAgICAgICA9IHRoaXMuYWN0aXZlRHJvcHMuZHJvcHpvbmVzW2pdLFxuICAgICAgICAgICAgICAgICAgICBjdXJyZW50RWxlbWVudCA9IHRoaXMuYWN0aXZlRHJvcHMuZWxlbWVudHMgW2pdLFxuICAgICAgICAgICAgICAgICAgICByZWN0ICAgICAgICAgICA9IHRoaXMuYWN0aXZlRHJvcHMucmVjdHMgICAgW2pdO1xuXG4gICAgICAgICAgICAgICAgdmFsaWREcm9wcy5wdXNoKGN1cnJlbnQuZHJvcENoZWNrKGRyYWdFdmVudCwgZXZlbnQsIHRoaXMudGFyZ2V0LCBkcmFnRWxlbWVudCwgY3VycmVudEVsZW1lbnQsIHJlY3QpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gY3VycmVudEVsZW1lbnRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBudWxsKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gZ2V0IHRoZSBtb3N0IGFwcHJvcHJpYXRlIGRyb3B6b25lIGJhc2VkIG9uIERPTSBkZXB0aCBhbmQgb3JkZXJcbiAgICAgICAgICAgIHZhciBkcm9wSW5kZXggPSBpbmRleE9mRGVlcGVzdEVsZW1lbnQodmFsaWREcm9wcyksXG4gICAgICAgICAgICAgICAgZHJvcHpvbmUgID0gdGhpcy5hY3RpdmVEcm9wcy5kcm9wem9uZXNbZHJvcEluZGV4XSB8fCBudWxsLFxuICAgICAgICAgICAgICAgIGVsZW1lbnQgICA9IHRoaXMuYWN0aXZlRHJvcHMuZWxlbWVudHMgW2Ryb3BJbmRleF0gfHwgbnVsbDtcblxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBkcm9wem9uZTogZHJvcHpvbmUsXG4gICAgICAgICAgICAgICAgZWxlbWVudDogZWxlbWVudFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSxcblxuICAgICAgICBnZXREcm9wRXZlbnRzOiBmdW5jdGlvbiAocG9pbnRlckV2ZW50LCBkcmFnRXZlbnQpIHtcbiAgICAgICAgICAgIHZhciBkcm9wRXZlbnRzID0ge1xuICAgICAgICAgICAgICAgIGVudGVyICAgICA6IG51bGwsXG4gICAgICAgICAgICAgICAgbGVhdmUgICAgIDogbnVsbCxcbiAgICAgICAgICAgICAgICBhY3RpdmF0ZSAgOiBudWxsLFxuICAgICAgICAgICAgICAgIGRlYWN0aXZhdGU6IG51bGwsXG4gICAgICAgICAgICAgICAgbW92ZSAgICAgIDogbnVsbCxcbiAgICAgICAgICAgICAgICBkcm9wICAgICAgOiBudWxsXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBpZiAodGhpcy5kcm9wRWxlbWVudCAhPT0gdGhpcy5wcmV2RHJvcEVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICAvLyBpZiB0aGVyZSB3YXMgYSBwcmV2RHJvcFRhcmdldCwgY3JlYXRlIGEgZHJhZ2xlYXZlIGV2ZW50XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMucHJldkRyb3BUYXJnZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgZHJvcEV2ZW50cy5sZWF2ZSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldCAgICAgICA6IHRoaXMucHJldkRyb3BFbGVtZW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgZHJvcHpvbmUgICAgIDogdGhpcy5wcmV2RHJvcFRhcmdldCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbGF0ZWRUYXJnZXQ6IGRyYWdFdmVudC50YXJnZXQsXG4gICAgICAgICAgICAgICAgICAgICAgICBkcmFnZ2FibGUgICAgOiBkcmFnRXZlbnQuaW50ZXJhY3RhYmxlLFxuICAgICAgICAgICAgICAgICAgICAgICAgZHJhZ0V2ZW50ICAgIDogZHJhZ0V2ZW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJhY3Rpb24gIDogdGhpcyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVTdGFtcCAgICA6IGRyYWdFdmVudC50aW1lU3RhbXAsXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlICAgICAgICAgOiAnZHJhZ2xlYXZlJ1xuICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgIGRyYWdFdmVudC5kcmFnTGVhdmUgPSB0aGlzLnByZXZEcm9wRWxlbWVudDtcbiAgICAgICAgICAgICAgICAgICAgZHJhZ0V2ZW50LnByZXZEcm9wem9uZSA9IHRoaXMucHJldkRyb3BUYXJnZXQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIGlmIHRoZSBkcm9wVGFyZ2V0IGlzIG5vdCBudWxsLCBjcmVhdGUgYSBkcmFnZW50ZXIgZXZlbnRcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5kcm9wVGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgICAgIGRyb3BFdmVudHMuZW50ZXIgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQgICAgICAgOiB0aGlzLmRyb3BFbGVtZW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgZHJvcHpvbmUgICAgIDogdGhpcy5kcm9wVGFyZ2V0LFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVsYXRlZFRhcmdldDogZHJhZ0V2ZW50LnRhcmdldCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRyYWdnYWJsZSAgICA6IGRyYWdFdmVudC5pbnRlcmFjdGFibGUsXG4gICAgICAgICAgICAgICAgICAgICAgICBkcmFnRXZlbnQgICAgOiBkcmFnRXZlbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICBpbnRlcmFjdGlvbiAgOiB0aGlzLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGltZVN0YW1wICAgIDogZHJhZ0V2ZW50LnRpbWVTdGFtcCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUgICAgICAgICA6ICdkcmFnZW50ZXInXG4gICAgICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAgICAgZHJhZ0V2ZW50LmRyYWdFbnRlciA9IHRoaXMuZHJvcEVsZW1lbnQ7XG4gICAgICAgICAgICAgICAgICAgIGRyYWdFdmVudC5kcm9wem9uZSA9IHRoaXMuZHJvcFRhcmdldDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChkcmFnRXZlbnQudHlwZSA9PT0gJ2RyYWdlbmQnICYmIHRoaXMuZHJvcFRhcmdldCkge1xuICAgICAgICAgICAgICAgIGRyb3BFdmVudHMuZHJvcCA9IHtcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0ICAgICAgIDogdGhpcy5kcm9wRWxlbWVudCxcbiAgICAgICAgICAgICAgICAgICAgZHJvcHpvbmUgICAgIDogdGhpcy5kcm9wVGFyZ2V0LFxuICAgICAgICAgICAgICAgICAgICByZWxhdGVkVGFyZ2V0OiBkcmFnRXZlbnQudGFyZ2V0LFxuICAgICAgICAgICAgICAgICAgICBkcmFnZ2FibGUgICAgOiBkcmFnRXZlbnQuaW50ZXJhY3RhYmxlLFxuICAgICAgICAgICAgICAgICAgICBkcmFnRXZlbnQgICAgOiBkcmFnRXZlbnQsXG4gICAgICAgICAgICAgICAgICAgIGludGVyYWN0aW9uICA6IHRoaXMsXG4gICAgICAgICAgICAgICAgICAgIHRpbWVTdGFtcCAgICA6IGRyYWdFdmVudC50aW1lU3RhbXAsXG4gICAgICAgICAgICAgICAgICAgIHR5cGUgICAgICAgICA6ICdkcm9wJ1xuICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICBkcmFnRXZlbnQuZHJvcHpvbmUgPSB0aGlzLmRyb3BUYXJnZXQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZHJhZ0V2ZW50LnR5cGUgPT09ICdkcmFnc3RhcnQnKSB7XG4gICAgICAgICAgICAgICAgZHJvcEV2ZW50cy5hY3RpdmF0ZSA9IHtcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0ICAgICAgIDogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgZHJvcHpvbmUgICAgIDogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgcmVsYXRlZFRhcmdldDogZHJhZ0V2ZW50LnRhcmdldCxcbiAgICAgICAgICAgICAgICAgICAgZHJhZ2dhYmxlICAgIDogZHJhZ0V2ZW50LmludGVyYWN0YWJsZSxcbiAgICAgICAgICAgICAgICAgICAgZHJhZ0V2ZW50ICAgIDogZHJhZ0V2ZW50LFxuICAgICAgICAgICAgICAgICAgICBpbnRlcmFjdGlvbiAgOiB0aGlzLFxuICAgICAgICAgICAgICAgICAgICB0aW1lU3RhbXAgICAgOiBkcmFnRXZlbnQudGltZVN0YW1wLFxuICAgICAgICAgICAgICAgICAgICB0eXBlICAgICAgICAgOiAnZHJvcGFjdGl2YXRlJ1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZHJhZ0V2ZW50LnR5cGUgPT09ICdkcmFnZW5kJykge1xuICAgICAgICAgICAgICAgIGRyb3BFdmVudHMuZGVhY3RpdmF0ZSA9IHtcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0ICAgICAgIDogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgZHJvcHpvbmUgICAgIDogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgcmVsYXRlZFRhcmdldDogZHJhZ0V2ZW50LnRhcmdldCxcbiAgICAgICAgICAgICAgICAgICAgZHJhZ2dhYmxlICAgIDogZHJhZ0V2ZW50LmludGVyYWN0YWJsZSxcbiAgICAgICAgICAgICAgICAgICAgZHJhZ0V2ZW50ICAgIDogZHJhZ0V2ZW50LFxuICAgICAgICAgICAgICAgICAgICBpbnRlcmFjdGlvbiAgOiB0aGlzLFxuICAgICAgICAgICAgICAgICAgICB0aW1lU3RhbXAgICAgOiBkcmFnRXZlbnQudGltZVN0YW1wLFxuICAgICAgICAgICAgICAgICAgICB0eXBlICAgICAgICAgOiAnZHJvcGRlYWN0aXZhdGUnXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChkcmFnRXZlbnQudHlwZSA9PT0gJ2RyYWdtb3ZlJyAmJiB0aGlzLmRyb3BUYXJnZXQpIHtcbiAgICAgICAgICAgICAgICBkcm9wRXZlbnRzLm1vdmUgPSB7XG4gICAgICAgICAgICAgICAgICAgIHRhcmdldCAgICAgICA6IHRoaXMuZHJvcEVsZW1lbnQsXG4gICAgICAgICAgICAgICAgICAgIGRyb3B6b25lICAgICA6IHRoaXMuZHJvcFRhcmdldCxcbiAgICAgICAgICAgICAgICAgICAgcmVsYXRlZFRhcmdldDogZHJhZ0V2ZW50LnRhcmdldCxcbiAgICAgICAgICAgICAgICAgICAgZHJhZ2dhYmxlICAgIDogZHJhZ0V2ZW50LmludGVyYWN0YWJsZSxcbiAgICAgICAgICAgICAgICAgICAgZHJhZ0V2ZW50ICAgIDogZHJhZ0V2ZW50LFxuICAgICAgICAgICAgICAgICAgICBpbnRlcmFjdGlvbiAgOiB0aGlzLFxuICAgICAgICAgICAgICAgICAgICBkcmFnbW92ZSAgICAgOiBkcmFnRXZlbnQsXG4gICAgICAgICAgICAgICAgICAgIHRpbWVTdGFtcCAgICA6IGRyYWdFdmVudC50aW1lU3RhbXAsXG4gICAgICAgICAgICAgICAgICAgIHR5cGUgICAgICAgICA6ICdkcm9wbW92ZSdcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGRyYWdFdmVudC5kcm9wem9uZSA9IHRoaXMuZHJvcFRhcmdldDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGRyb3BFdmVudHM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgY3VycmVudEFjdGlvbjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuICh0aGlzLmRyYWdnaW5nICYmICdkcmFnJykgfHwgKHRoaXMucmVzaXppbmcgJiYgJ3Jlc2l6ZScpIHx8ICh0aGlzLmdlc3R1cmluZyAmJiAnZ2VzdHVyZScpIHx8IG51bGw7XG4gICAgICAgIH0sXG5cbiAgICAgICAgaW50ZXJhY3Rpbmc6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmRyYWdnaW5nIHx8IHRoaXMucmVzaXppbmcgfHwgdGhpcy5nZXN0dXJpbmc7XG4gICAgICAgIH0sXG5cbiAgICAgICAgY2xlYXJUYXJnZXRzOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB0aGlzLnRhcmdldCA9IHRoaXMuZWxlbWVudCA9IG51bGw7XG5cbiAgICAgICAgICAgIHRoaXMuZHJvcFRhcmdldCA9IHRoaXMuZHJvcEVsZW1lbnQgPSB0aGlzLnByZXZEcm9wVGFyZ2V0ID0gdGhpcy5wcmV2RHJvcEVsZW1lbnQgPSBudWxsO1xuICAgICAgICB9LFxuXG4gICAgICAgIHN0b3A6IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuaW50ZXJhY3RpbmcoKSkge1xuICAgICAgICAgICAgICAgIGF1dG9TY3JvbGwuc3RvcCgpO1xuICAgICAgICAgICAgICAgIHRoaXMubWF0Y2hlcyA9IFtdO1xuICAgICAgICAgICAgICAgIHRoaXMubWF0Y2hFbGVtZW50cyA9IFtdO1xuXG4gICAgICAgICAgICAgICAgdmFyIHRhcmdldCA9IHRoaXMudGFyZ2V0O1xuXG4gICAgICAgICAgICAgICAgaWYgKHRhcmdldC5vcHRpb25zLnN0eWxlQ3Vyc29yKSB7XG4gICAgICAgICAgICAgICAgICAgIHRhcmdldC5fZG9jLmRvY3VtZW50RWxlbWVudC5zdHlsZS5jdXJzb3IgPSAnJztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBwcmV2ZW50IERlZmF1bHQgb25seSBpZiB3ZXJlIHByZXZpb3VzbHkgaW50ZXJhY3RpbmdcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnQgJiYgaXNGdW5jdGlvbihldmVudC5wcmV2ZW50RGVmYXVsdCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jaGVja0FuZFByZXZlbnREZWZhdWx0KGV2ZW50LCB0YXJnZXQsIHRoaXMuZWxlbWVudCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZHJhZ2dpbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hY3RpdmVEcm9wcy5kcm9wem9uZXMgPSB0aGlzLmFjdGl2ZURyb3BzLmVsZW1lbnRzID0gdGhpcy5hY3RpdmVEcm9wcy5yZWN0cyA9IG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLmNsZWFyVGFyZ2V0cygpO1xuXG4gICAgICAgICAgICB0aGlzLnBvaW50ZXJJc0Rvd24gPSB0aGlzLnNuYXBTdGF0dXMubG9ja2VkID0gdGhpcy5kcmFnZ2luZyA9IHRoaXMucmVzaXppbmcgPSB0aGlzLmdlc3R1cmluZyA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5wcmVwYXJlZC5uYW1lID0gdGhpcy5wcmV2RXZlbnQgPSBudWxsO1xuICAgICAgICAgICAgdGhpcy5pbmVydGlhU3RhdHVzLnJlc3VtZUR4ID0gdGhpcy5pbmVydGlhU3RhdHVzLnJlc3VtZUR5ID0gMDtcblxuICAgICAgICAgICAgLy8gcmVtb3ZlIHBvaW50ZXJzIGlmIHRoZWlyIElEIGlzbid0IGluIHRoaXMucG9pbnRlcklkc1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnBvaW50ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGluZGV4T2YodGhpcy5wb2ludGVySWRzLCBnZXRQb2ludGVySWQodGhpcy5wb2ludGVyc1tpXSkpID09PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBvaW50ZXJzLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgaW5lcnRpYUZyYW1lOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgaW5lcnRpYVN0YXR1cyA9IHRoaXMuaW5lcnRpYVN0YXR1cyxcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gdGhpcy50YXJnZXQub3B0aW9uc1t0aGlzLnByZXBhcmVkLm5hbWVdLmluZXJ0aWEsXG4gICAgICAgICAgICAgICAgbGFtYmRhID0gb3B0aW9ucy5yZXNpc3RhbmNlLFxuICAgICAgICAgICAgICAgIHQgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKSAvIDEwMDAgLSBpbmVydGlhU3RhdHVzLnQwO1xuXG4gICAgICAgICAgICBpZiAodCA8IGluZXJ0aWFTdGF0dXMudGUpIHtcblxuICAgICAgICAgICAgICAgIHZhciBwcm9ncmVzcyA9ICAxIC0gKE1hdGguZXhwKC1sYW1iZGEgKiB0KSAtIGluZXJ0aWFTdGF0dXMubGFtYmRhX3YwKSAvIGluZXJ0aWFTdGF0dXMub25lX3ZlX3YwO1xuXG4gICAgICAgICAgICAgICAgaWYgKGluZXJ0aWFTdGF0dXMubW9kaWZpZWRYZSA9PT0gaW5lcnRpYVN0YXR1cy54ZSAmJiBpbmVydGlhU3RhdHVzLm1vZGlmaWVkWWUgPT09IGluZXJ0aWFTdGF0dXMueWUpIHtcbiAgICAgICAgICAgICAgICAgICAgaW5lcnRpYVN0YXR1cy5zeCA9IGluZXJ0aWFTdGF0dXMueGUgKiBwcm9ncmVzcztcbiAgICAgICAgICAgICAgICAgICAgaW5lcnRpYVN0YXR1cy5zeSA9IGluZXJ0aWFTdGF0dXMueWUgKiBwcm9ncmVzcztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBxdWFkUG9pbnQgPSBnZXRRdWFkcmF0aWNDdXJ2ZVBvaW50KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5lcnRpYVN0YXR1cy54ZSwgaW5lcnRpYVN0YXR1cy55ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmVydGlhU3RhdHVzLm1vZGlmaWVkWGUsIGluZXJ0aWFTdGF0dXMubW9kaWZpZWRZZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9ncmVzcyk7XG5cbiAgICAgICAgICAgICAgICAgICAgaW5lcnRpYVN0YXR1cy5zeCA9IHF1YWRQb2ludC54O1xuICAgICAgICAgICAgICAgICAgICBpbmVydGlhU3RhdHVzLnN5ID0gcXVhZFBvaW50Lnk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5wb2ludGVyTW92ZShpbmVydGlhU3RhdHVzLnN0YXJ0RXZlbnQsIGluZXJ0aWFTdGF0dXMuc3RhcnRFdmVudCk7XG5cbiAgICAgICAgICAgICAgICBpbmVydGlhU3RhdHVzLmkgPSByZXFGcmFtZSh0aGlzLmJvdW5kSW5lcnRpYUZyYW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGluZXJ0aWFTdGF0dXMuZW5kaW5nID0gdHJ1ZTtcblxuICAgICAgICAgICAgICAgIGluZXJ0aWFTdGF0dXMuc3ggPSBpbmVydGlhU3RhdHVzLm1vZGlmaWVkWGU7XG4gICAgICAgICAgICAgICAgaW5lcnRpYVN0YXR1cy5zeSA9IGluZXJ0aWFTdGF0dXMubW9kaWZpZWRZZTtcblxuICAgICAgICAgICAgICAgIHRoaXMucG9pbnRlck1vdmUoaW5lcnRpYVN0YXR1cy5zdGFydEV2ZW50LCBpbmVydGlhU3RhdHVzLnN0YXJ0RXZlbnQpO1xuICAgICAgICAgICAgICAgIHRoaXMucG9pbnRlckVuZChpbmVydGlhU3RhdHVzLnN0YXJ0RXZlbnQsIGluZXJ0aWFTdGF0dXMuc3RhcnRFdmVudCk7XG5cbiAgICAgICAgICAgICAgICBpbmVydGlhU3RhdHVzLmFjdGl2ZSA9IGluZXJ0aWFTdGF0dXMuZW5kaW5nID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgc21vb3RoRW5kRnJhbWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBpbmVydGlhU3RhdHVzID0gdGhpcy5pbmVydGlhU3RhdHVzLFxuICAgICAgICAgICAgICAgIHQgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIGluZXJ0aWFTdGF0dXMudDAsXG4gICAgICAgICAgICAgICAgZHVyYXRpb24gPSB0aGlzLnRhcmdldC5vcHRpb25zW3RoaXMucHJlcGFyZWQubmFtZV0uaW5lcnRpYS5zbW9vdGhFbmREdXJhdGlvbjtcblxuICAgICAgICAgICAgaWYgKHQgPCBkdXJhdGlvbikge1xuICAgICAgICAgICAgICAgIGluZXJ0aWFTdGF0dXMuc3ggPSBlYXNlT3V0UXVhZCh0LCAwLCBpbmVydGlhU3RhdHVzLnhlLCBkdXJhdGlvbik7XG4gICAgICAgICAgICAgICAgaW5lcnRpYVN0YXR1cy5zeSA9IGVhc2VPdXRRdWFkKHQsIDAsIGluZXJ0aWFTdGF0dXMueWUsIGR1cmF0aW9uKTtcblxuICAgICAgICAgICAgICAgIHRoaXMucG9pbnRlck1vdmUoaW5lcnRpYVN0YXR1cy5zdGFydEV2ZW50LCBpbmVydGlhU3RhdHVzLnN0YXJ0RXZlbnQpO1xuXG4gICAgICAgICAgICAgICAgaW5lcnRpYVN0YXR1cy5pID0gcmVxRnJhbWUodGhpcy5ib3VuZFNtb290aEVuZEZyYW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGluZXJ0aWFTdGF0dXMuZW5kaW5nID0gdHJ1ZTtcblxuICAgICAgICAgICAgICAgIGluZXJ0aWFTdGF0dXMuc3ggPSBpbmVydGlhU3RhdHVzLnhlO1xuICAgICAgICAgICAgICAgIGluZXJ0aWFTdGF0dXMuc3kgPSBpbmVydGlhU3RhdHVzLnllO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5wb2ludGVyTW92ZShpbmVydGlhU3RhdHVzLnN0YXJ0RXZlbnQsIGluZXJ0aWFTdGF0dXMuc3RhcnRFdmVudCk7XG4gICAgICAgICAgICAgICAgdGhpcy5wb2ludGVyRW5kKGluZXJ0aWFTdGF0dXMuc3RhcnRFdmVudCwgaW5lcnRpYVN0YXR1cy5zdGFydEV2ZW50KTtcblxuICAgICAgICAgICAgICAgIGluZXJ0aWFTdGF0dXMuc21vb3RoRW5kID1cbiAgICAgICAgICAgICAgICAgIGluZXJ0aWFTdGF0dXMuYWN0aXZlID0gaW5lcnRpYVN0YXR1cy5lbmRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICBhZGRQb2ludGVyOiBmdW5jdGlvbiAocG9pbnRlcikge1xuICAgICAgICAgICAgdmFyIGlkID0gZ2V0UG9pbnRlcklkKHBvaW50ZXIpLFxuICAgICAgICAgICAgICAgIGluZGV4ID0gdGhpcy5tb3VzZT8gMCA6IGluZGV4T2YodGhpcy5wb2ludGVySWRzLCBpZCk7XG5cbiAgICAgICAgICAgIGlmIChpbmRleCA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgICBpbmRleCA9IHRoaXMucG9pbnRlcklkcy5sZW5ndGg7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMucG9pbnRlcklkc1tpbmRleF0gPSBpZDtcbiAgICAgICAgICAgIHRoaXMucG9pbnRlcnNbaW5kZXhdID0gcG9pbnRlcjtcblxuICAgICAgICAgICAgcmV0dXJuIGluZGV4O1xuICAgICAgICB9LFxuXG4gICAgICAgIHJlbW92ZVBvaW50ZXI6IGZ1bmN0aW9uIChwb2ludGVyKSB7XG4gICAgICAgICAgICB2YXIgaWQgPSBnZXRQb2ludGVySWQocG9pbnRlciksXG4gICAgICAgICAgICAgICAgaW5kZXggPSB0aGlzLm1vdXNlPyAwIDogaW5kZXhPZih0aGlzLnBvaW50ZXJJZHMsIGlkKTtcblxuICAgICAgICAgICAgaWYgKGluZGV4ID09PSAtMSkgeyByZXR1cm47IH1cblxuICAgICAgICAgICAgdGhpcy5wb2ludGVycyAgIC5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgICAgdGhpcy5wb2ludGVySWRzIC5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgICAgdGhpcy5kb3duVGFyZ2V0cy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgICAgdGhpcy5kb3duVGltZXMgIC5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgICAgdGhpcy5ob2xkVGltZXJzIC5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICB9LFxuXG4gICAgICAgIHJlY29yZFBvaW50ZXI6IGZ1bmN0aW9uIChwb2ludGVyKSB7XG4gICAgICAgICAgICB2YXIgaW5kZXggPSB0aGlzLm1vdXNlPyAwOiBpbmRleE9mKHRoaXMucG9pbnRlcklkcywgZ2V0UG9pbnRlcklkKHBvaW50ZXIpKTtcblxuICAgICAgICAgICAgaWYgKGluZGV4ID09PSAtMSkgeyByZXR1cm47IH1cblxuICAgICAgICAgICAgdGhpcy5wb2ludGVyc1tpbmRleF0gPSBwb2ludGVyO1xuICAgICAgICB9LFxuXG4gICAgICAgIGNvbGxlY3RFdmVudFRhcmdldHM6IGZ1bmN0aW9uIChwb2ludGVyLCBldmVudCwgZXZlbnRUYXJnZXQsIGV2ZW50VHlwZSkge1xuICAgICAgICAgICAgdmFyIHBvaW50ZXJJbmRleCA9IHRoaXMubW91c2U/IDAgOiBpbmRleE9mKHRoaXMucG9pbnRlcklkcywgZ2V0UG9pbnRlcklkKHBvaW50ZXIpKTtcblxuICAgICAgICAgICAgLy8gZG8gbm90IGZpcmUgYSB0YXAgZXZlbnQgaWYgdGhlIHBvaW50ZXIgd2FzIG1vdmVkIGJlZm9yZSBiZWluZyBsaWZ0ZWRcbiAgICAgICAgICAgIGlmIChldmVudFR5cGUgPT09ICd0YXAnICYmICh0aGlzLnBvaW50ZXJXYXNNb3ZlZFxuICAgICAgICAgICAgICAgIC8vIG9yIGlmIHRoZSBwb2ludGVydXAgdGFyZ2V0IGlzIGRpZmZlcmVudCB0byB0aGUgcG9pbnRlcmRvd24gdGFyZ2V0XG4gICAgICAgICAgICAgICAgfHwgISh0aGlzLmRvd25UYXJnZXRzW3BvaW50ZXJJbmRleF0gJiYgdGhpcy5kb3duVGFyZ2V0c1twb2ludGVySW5kZXhdID09PSBldmVudFRhcmdldCkpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgdGFyZ2V0cyA9IFtdLFxuICAgICAgICAgICAgICAgIGVsZW1lbnRzID0gW10sXG4gICAgICAgICAgICAgICAgZWxlbWVudCA9IGV2ZW50VGFyZ2V0O1xuXG4gICAgICAgICAgICBmdW5jdGlvbiBjb2xsZWN0U2VsZWN0b3JzIChpbnRlcmFjdGFibGUsIHNlbGVjdG9yLCBjb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgdmFyIGVscyA9IGllOE1hdGNoZXNTZWxlY3RvclxuICAgICAgICAgICAgICAgICAgICAgICAgPyBjb250ZXh0LnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpXG4gICAgICAgICAgICAgICAgICAgICAgICA6IHVuZGVmaW5lZDtcblxuICAgICAgICAgICAgICAgIGlmIChpbnRlcmFjdGFibGUuX2lFdmVudHNbZXZlbnRUeXBlXVxuICAgICAgICAgICAgICAgICAgICAmJiBpc0VsZW1lbnQoZWxlbWVudClcbiAgICAgICAgICAgICAgICAgICAgJiYgaW5Db250ZXh0KGludGVyYWN0YWJsZSwgZWxlbWVudClcbiAgICAgICAgICAgICAgICAgICAgJiYgIXRlc3RJZ25vcmUoaW50ZXJhY3RhYmxlLCBlbGVtZW50LCBldmVudFRhcmdldClcbiAgICAgICAgICAgICAgICAgICAgJiYgdGVzdEFsbG93KGludGVyYWN0YWJsZSwgZWxlbWVudCwgZXZlbnRUYXJnZXQpXG4gICAgICAgICAgICAgICAgICAgICYmIG1hdGNoZXNTZWxlY3RvcihlbGVtZW50LCBzZWxlY3RvciwgZWxzKSkge1xuXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldHMucHVzaChpbnRlcmFjdGFibGUpO1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50cy5wdXNoKGVsZW1lbnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgd2hpbGUgKGVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICBpZiAoaW50ZXJhY3QuaXNTZXQoZWxlbWVudCkgJiYgaW50ZXJhY3QoZWxlbWVudCkuX2lFdmVudHNbZXZlbnRUeXBlXSkge1xuICAgICAgICAgICAgICAgICAgICB0YXJnZXRzLnB1c2goaW50ZXJhY3QoZWxlbWVudCkpO1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50cy5wdXNoKGVsZW1lbnQpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGludGVyYWN0YWJsZXMuZm9yRWFjaFNlbGVjdG9yKGNvbGxlY3RTZWxlY3RvcnMpO1xuXG4gICAgICAgICAgICAgICAgZWxlbWVudCA9IHBhcmVudEVsZW1lbnQoZWxlbWVudCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGNyZWF0ZSB0aGUgdGFwIGV2ZW50IGV2ZW4gaWYgdGhlcmUgYXJlIG5vIGxpc3RlbmVycyBzbyB0aGF0XG4gICAgICAgICAgICAvLyBkb3VibGV0YXAgY2FuIHN0aWxsIGJlIGNyZWF0ZWQgYW5kIGZpcmVkXG4gICAgICAgICAgICBpZiAodGFyZ2V0cy5sZW5ndGggfHwgZXZlbnRUeXBlID09PSAndGFwJykge1xuICAgICAgICAgICAgICAgIHRoaXMuZmlyZVBvaW50ZXJzKHBvaW50ZXIsIGV2ZW50LCBldmVudFRhcmdldCwgdGFyZ2V0cywgZWxlbWVudHMsIGV2ZW50VHlwZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgZmlyZVBvaW50ZXJzOiBmdW5jdGlvbiAocG9pbnRlciwgZXZlbnQsIGV2ZW50VGFyZ2V0LCB0YXJnZXRzLCBlbGVtZW50cywgZXZlbnRUeXBlKSB7XG4gICAgICAgICAgICB2YXIgcG9pbnRlckluZGV4ID0gdGhpcy5tb3VzZT8gMCA6IGluZGV4T2YodGhpcy5wb2ludGVySWRzLCBnZXRQb2ludGVySWQocG9pbnRlcikpLFxuICAgICAgICAgICAgICAgIHBvaW50ZXJFdmVudCA9IHt9LFxuICAgICAgICAgICAgICAgIGksXG4gICAgICAgICAgICAgICAgLy8gZm9yIHRhcCBldmVudHNcbiAgICAgICAgICAgICAgICBpbnRlcnZhbCwgY3JlYXRlTmV3RG91YmxlVGFwO1xuXG4gICAgICAgICAgICAvLyBpZiBpdCdzIGEgZG91YmxldGFwIHRoZW4gdGhlIGV2ZW50IHByb3BlcnRpZXMgd291bGQgaGF2ZSBiZWVuXG4gICAgICAgICAgICAvLyBjb3BpZWQgZnJvbSB0aGUgdGFwIGV2ZW50IGFuZCBwcm92aWRlZCBhcyB0aGUgcG9pbnRlciBhcmd1bWVudFxuICAgICAgICAgICAgaWYgKGV2ZW50VHlwZSA9PT0gJ2RvdWJsZXRhcCcpIHtcbiAgICAgICAgICAgICAgICBwb2ludGVyRXZlbnQgPSBwb2ludGVyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcG9pbnRlckV4dGVuZChwb2ludGVyRXZlbnQsIGV2ZW50KTtcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnQgIT09IHBvaW50ZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgcG9pbnRlckV4dGVuZChwb2ludGVyRXZlbnQsIHBvaW50ZXIpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHBvaW50ZXJFdmVudC5wcmV2ZW50RGVmYXVsdCAgICAgICAgICAgPSBwcmV2ZW50T3JpZ2luYWxEZWZhdWx0O1xuICAgICAgICAgICAgICAgIHBvaW50ZXJFdmVudC5zdG9wUHJvcGFnYXRpb24gICAgICAgICAgPSBJbnRlcmFjdEV2ZW50LnByb3RvdHlwZS5zdG9wUHJvcGFnYXRpb247XG4gICAgICAgICAgICAgICAgcG9pbnRlckV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbiA9IEludGVyYWN0RXZlbnQucHJvdG90eXBlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbjtcbiAgICAgICAgICAgICAgICBwb2ludGVyRXZlbnQuaW50ZXJhY3Rpb24gICAgICAgICAgICAgID0gdGhpcztcblxuICAgICAgICAgICAgICAgIHBvaW50ZXJFdmVudC50aW1lU3RhbXAgICAgICAgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICAgICAgICAgICAgICBwb2ludGVyRXZlbnQub3JpZ2luYWxFdmVudCAgID0gZXZlbnQ7XG4gICAgICAgICAgICAgICAgcG9pbnRlckV2ZW50Lm9yaWdpbmFsUG9pbnRlciA9IHBvaW50ZXI7XG4gICAgICAgICAgICAgICAgcG9pbnRlckV2ZW50LnR5cGUgICAgICAgICAgICA9IGV2ZW50VHlwZTtcbiAgICAgICAgICAgICAgICBwb2ludGVyRXZlbnQucG9pbnRlcklkICAgICAgID0gZ2V0UG9pbnRlcklkKHBvaW50ZXIpO1xuICAgICAgICAgICAgICAgIHBvaW50ZXJFdmVudC5wb2ludGVyVHlwZSAgICAgPSB0aGlzLm1vdXNlPyAnbW91c2UnIDogIXN1cHBvcnRzUG9pbnRlckV2ZW50PyAndG91Y2gnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBpc1N0cmluZyhwb2ludGVyLnBvaW50ZXJUeXBlKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHBvaW50ZXIucG9pbnRlclR5cGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBbLCwndG91Y2gnLCAncGVuJywgJ21vdXNlJ11bcG9pbnRlci5wb2ludGVyVHlwZV07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChldmVudFR5cGUgPT09ICd0YXAnKSB7XG4gICAgICAgICAgICAgICAgcG9pbnRlckV2ZW50LmR0ID0gcG9pbnRlckV2ZW50LnRpbWVTdGFtcCAtIHRoaXMuZG93blRpbWVzW3BvaW50ZXJJbmRleF07XG5cbiAgICAgICAgICAgICAgICBpbnRlcnZhbCA9IHBvaW50ZXJFdmVudC50aW1lU3RhbXAgLSB0aGlzLnRhcFRpbWU7XG4gICAgICAgICAgICAgICAgY3JlYXRlTmV3RG91YmxlVGFwID0gISEodGhpcy5wcmV2VGFwICYmIHRoaXMucHJldlRhcC50eXBlICE9PSAnZG91YmxldGFwJ1xuICAgICAgICAgICAgICAgICAgICAgICAmJiB0aGlzLnByZXZUYXAudGFyZ2V0ID09PSBwb2ludGVyRXZlbnQudGFyZ2V0XG4gICAgICAgICAgICAgICAgICAgICAgICYmIGludGVydmFsIDwgNTAwKTtcblxuICAgICAgICAgICAgICAgIHBvaW50ZXJFdmVudC5kb3VibGUgPSBjcmVhdGVOZXdEb3VibGVUYXA7XG5cbiAgICAgICAgICAgICAgICB0aGlzLnRhcFRpbWUgPSBwb2ludGVyRXZlbnQudGltZVN0YW1wO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgdGFyZ2V0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIHBvaW50ZXJFdmVudC5jdXJyZW50VGFyZ2V0ID0gZWxlbWVudHNbaV07XG4gICAgICAgICAgICAgICAgcG9pbnRlckV2ZW50LmludGVyYWN0YWJsZSA9IHRhcmdldHNbaV07XG4gICAgICAgICAgICAgICAgdGFyZ2V0c1tpXS5maXJlKHBvaW50ZXJFdmVudCk7XG5cbiAgICAgICAgICAgICAgICBpZiAocG9pbnRlckV2ZW50LmltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZFxuICAgICAgICAgICAgICAgICAgICB8fChwb2ludGVyRXZlbnQucHJvcGFnYXRpb25TdG9wcGVkICYmIGVsZW1lbnRzW2kgKyAxXSAhPT0gcG9pbnRlckV2ZW50LmN1cnJlbnRUYXJnZXQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGNyZWF0ZU5ld0RvdWJsZVRhcCkge1xuICAgICAgICAgICAgICAgIHZhciBkb3VibGVUYXAgPSB7fTtcblxuICAgICAgICAgICAgICAgIGV4dGVuZChkb3VibGVUYXAsIHBvaW50ZXJFdmVudCk7XG5cbiAgICAgICAgICAgICAgICBkb3VibGVUYXAuZHQgICA9IGludGVydmFsO1xuICAgICAgICAgICAgICAgIGRvdWJsZVRhcC50eXBlID0gJ2RvdWJsZXRhcCc7XG5cbiAgICAgICAgICAgICAgICB0aGlzLmNvbGxlY3RFdmVudFRhcmdldHMoZG91YmxlVGFwLCBldmVudCwgZXZlbnRUYXJnZXQsICdkb3VibGV0YXAnKTtcblxuICAgICAgICAgICAgICAgIHRoaXMucHJldlRhcCA9IGRvdWJsZVRhcDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGV2ZW50VHlwZSA9PT0gJ3RhcCcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnByZXZUYXAgPSBwb2ludGVyRXZlbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgdmFsaWRhdGVTZWxlY3RvcjogZnVuY3Rpb24gKHBvaW50ZXIsIGV2ZW50LCBtYXRjaGVzLCBtYXRjaEVsZW1lbnRzKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gbWF0Y2hlcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgICAgIHZhciBtYXRjaCA9IG1hdGNoZXNbaV0sXG4gICAgICAgICAgICAgICAgICAgIG1hdGNoRWxlbWVudCA9IG1hdGNoRWxlbWVudHNbaV0sXG4gICAgICAgICAgICAgICAgICAgIGFjdGlvbiA9IHZhbGlkYXRlQWN0aW9uKG1hdGNoLmdldEFjdGlvbihwb2ludGVyLCBldmVudCwgdGhpcywgbWF0Y2hFbGVtZW50KSwgbWF0Y2gpO1xuXG4gICAgICAgICAgICAgICAgaWYgKGFjdGlvbiAmJiB3aXRoaW5JbnRlcmFjdGlvbkxpbWl0KG1hdGNoLCBtYXRjaEVsZW1lbnQsIGFjdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50YXJnZXQgPSBtYXRjaDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lbGVtZW50ID0gbWF0Y2hFbGVtZW50O1xuXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBhY3Rpb247XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIHNldFNuYXBwaW5nOiBmdW5jdGlvbiAocGFnZUNvb3Jkcywgc3RhdHVzKSB7XG4gICAgICAgICAgICB2YXIgc25hcCA9IHRoaXMudGFyZ2V0Lm9wdGlvbnNbdGhpcy5wcmVwYXJlZC5uYW1lXS5zbmFwLFxuICAgICAgICAgICAgICAgIHRhcmdldHMgPSBbXSxcbiAgICAgICAgICAgICAgICB0YXJnZXQsXG4gICAgICAgICAgICAgICAgcGFnZSxcbiAgICAgICAgICAgICAgICBpO1xuXG4gICAgICAgICAgICBzdGF0dXMgPSBzdGF0dXMgfHwgdGhpcy5zbmFwU3RhdHVzO1xuXG4gICAgICAgICAgICBpZiAoc3RhdHVzLnVzZVN0YXR1c1hZKSB7XG4gICAgICAgICAgICAgICAgcGFnZSA9IHsgeDogc3RhdHVzLngsIHk6IHN0YXR1cy55IH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YXIgb3JpZ2luID0gZ2V0T3JpZ2luWFkodGhpcy50YXJnZXQsIHRoaXMuZWxlbWVudCk7XG5cbiAgICAgICAgICAgICAgICBwYWdlID0gZXh0ZW5kKHt9LCBwYWdlQ29vcmRzKTtcblxuICAgICAgICAgICAgICAgIHBhZ2UueCAtPSBvcmlnaW4ueDtcbiAgICAgICAgICAgICAgICBwYWdlLnkgLT0gb3JpZ2luLnk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHN0YXR1cy5yZWFsWCA9IHBhZ2UueDtcbiAgICAgICAgICAgIHN0YXR1cy5yZWFsWSA9IHBhZ2UueTtcblxuICAgICAgICAgICAgcGFnZS54ID0gcGFnZS54IC0gdGhpcy5pbmVydGlhU3RhdHVzLnJlc3VtZUR4O1xuICAgICAgICAgICAgcGFnZS55ID0gcGFnZS55IC0gdGhpcy5pbmVydGlhU3RhdHVzLnJlc3VtZUR5O1xuXG4gICAgICAgICAgICB2YXIgbGVuID0gc25hcC50YXJnZXRzPyBzbmFwLnRhcmdldHMubGVuZ3RoIDogMDtcblxuICAgICAgICAgICAgZm9yICh2YXIgcmVsSW5kZXggPSAwOyByZWxJbmRleCA8IHRoaXMuc25hcE9mZnNldHMubGVuZ3RoOyByZWxJbmRleCsrKSB7XG4gICAgICAgICAgICAgICAgdmFyIHJlbGF0aXZlID0ge1xuICAgICAgICAgICAgICAgICAgICB4OiBwYWdlLnggLSB0aGlzLnNuYXBPZmZzZXRzW3JlbEluZGV4XS54LFxuICAgICAgICAgICAgICAgICAgICB5OiBwYWdlLnkgLSB0aGlzLnNuYXBPZmZzZXRzW3JlbEluZGV4XS55XG4gICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNGdW5jdGlvbihzbmFwLnRhcmdldHNbaV0pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQgPSBzbmFwLnRhcmdldHNbaV0ocmVsYXRpdmUueCwgcmVsYXRpdmUueSwgdGhpcyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQgPSBzbmFwLnRhcmdldHNbaV07XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAoIXRhcmdldCkgeyBjb250aW51ZTsgfVxuXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldHMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgICAgICB4OiBpc051bWJlcih0YXJnZXQueCkgPyAodGFyZ2V0LnggKyB0aGlzLnNuYXBPZmZzZXRzW3JlbEluZGV4XS54KSA6IHJlbGF0aXZlLngsXG4gICAgICAgICAgICAgICAgICAgICAgICB5OiBpc051bWJlcih0YXJnZXQueSkgPyAodGFyZ2V0LnkgKyB0aGlzLnNuYXBPZmZzZXRzW3JlbEluZGV4XS55KSA6IHJlbGF0aXZlLnksXG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJhbmdlOiBpc051bWJlcih0YXJnZXQucmFuZ2UpPyB0YXJnZXQucmFuZ2U6IHNuYXAucmFuZ2VcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgY2xvc2VzdCA9IHtcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0OiBudWxsLFxuICAgICAgICAgICAgICAgICAgICBpblJhbmdlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgZGlzdGFuY2U6IDAsXG4gICAgICAgICAgICAgICAgICAgIHJhbmdlOiAwLFxuICAgICAgICAgICAgICAgICAgICBkeDogMCxcbiAgICAgICAgICAgICAgICAgICAgZHk6IDBcbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBmb3IgKGkgPSAwLCBsZW4gPSB0YXJnZXRzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdGFyZ2V0ID0gdGFyZ2V0c1tpXTtcblxuICAgICAgICAgICAgICAgIHZhciByYW5nZSA9IHRhcmdldC5yYW5nZSxcbiAgICAgICAgICAgICAgICAgICAgZHggPSB0YXJnZXQueCAtIHBhZ2UueCxcbiAgICAgICAgICAgICAgICAgICAgZHkgPSB0YXJnZXQueSAtIHBhZ2UueSxcbiAgICAgICAgICAgICAgICAgICAgZGlzdGFuY2UgPSBoeXBvdChkeCwgZHkpLFxuICAgICAgICAgICAgICAgICAgICBpblJhbmdlID0gZGlzdGFuY2UgPD0gcmFuZ2U7XG5cbiAgICAgICAgICAgICAgICAvLyBJbmZpbml0ZSB0YXJnZXRzIGNvdW50IGFzIGJlaW5nIG91dCBvZiByYW5nZVxuICAgICAgICAgICAgICAgIC8vIGNvbXBhcmVkIHRvIG5vbiBpbmZpbml0ZSBvbmVzIHRoYXQgYXJlIGluIHJhbmdlXG4gICAgICAgICAgICAgICAgaWYgKHJhbmdlID09PSBJbmZpbml0eSAmJiBjbG9zZXN0LmluUmFuZ2UgJiYgY2xvc2VzdC5yYW5nZSAhPT0gSW5maW5pdHkpIHtcbiAgICAgICAgICAgICAgICAgICAgaW5SYW5nZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICghY2xvc2VzdC50YXJnZXQgfHwgKGluUmFuZ2VcbiAgICAgICAgICAgICAgICAgICAgLy8gaXMgdGhlIGNsb3Nlc3QgdGFyZ2V0IGluIHJhbmdlP1xuICAgICAgICAgICAgICAgICAgICA/IChjbG9zZXN0LmluUmFuZ2UgJiYgcmFuZ2UgIT09IEluZmluaXR5XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgcG9pbnRlciBpcyByZWxhdGl2ZWx5IGRlZXBlciBpbiB0aGlzIHRhcmdldFxuICAgICAgICAgICAgICAgICAgICAgICAgPyBkaXN0YW5jZSAvIHJhbmdlIDwgY2xvc2VzdC5kaXN0YW5jZSAvIGNsb3Nlc3QucmFuZ2VcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgdGFyZ2V0IGhhcyBJbmZpbml0ZSByYW5nZSBhbmQgdGhlIGNsb3Nlc3QgZG9lc24ndFxuICAgICAgICAgICAgICAgICAgICAgICAgOiAocmFuZ2UgPT09IEluZmluaXR5ICYmIGNsb3Nlc3QucmFuZ2UgIT09IEluZmluaXR5KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9SIHRoaXMgdGFyZ2V0IGlzIGNsb3NlciB0aGF0IHRoZSBwcmV2aW91cyBjbG9zZXN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgZGlzdGFuY2UgPCBjbG9zZXN0LmRpc3RhbmNlKVxuICAgICAgICAgICAgICAgICAgICAvLyBUaGUgb3RoZXIgaXMgbm90IGluIHJhbmdlIGFuZCB0aGUgcG9pbnRlciBpcyBjbG9zZXIgdG8gdGhpcyB0YXJnZXRcbiAgICAgICAgICAgICAgICAgICAgOiAoIWNsb3Nlc3QuaW5SYW5nZSAmJiBkaXN0YW5jZSA8IGNsb3Nlc3QuZGlzdGFuY2UpKSkge1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChyYW5nZSA9PT0gSW5maW5pdHkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGluUmFuZ2UgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgY2xvc2VzdC50YXJnZXQgPSB0YXJnZXQ7XG4gICAgICAgICAgICAgICAgICAgIGNsb3Nlc3QuZGlzdGFuY2UgPSBkaXN0YW5jZTtcbiAgICAgICAgICAgICAgICAgICAgY2xvc2VzdC5yYW5nZSA9IHJhbmdlO1xuICAgICAgICAgICAgICAgICAgICBjbG9zZXN0LmluUmFuZ2UgPSBpblJhbmdlO1xuICAgICAgICAgICAgICAgICAgICBjbG9zZXN0LmR4ID0gZHg7XG4gICAgICAgICAgICAgICAgICAgIGNsb3Nlc3QuZHkgPSBkeTtcblxuICAgICAgICAgICAgICAgICAgICBzdGF0dXMucmFuZ2UgPSByYW5nZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBzbmFwQ2hhbmdlZDtcblxuICAgICAgICAgICAgaWYgKGNsb3Nlc3QudGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgc25hcENoYW5nZWQgPSAoc3RhdHVzLnNuYXBwZWRYICE9PSBjbG9zZXN0LnRhcmdldC54IHx8IHN0YXR1cy5zbmFwcGVkWSAhPT0gY2xvc2VzdC50YXJnZXQueSk7XG5cbiAgICAgICAgICAgICAgICBzdGF0dXMuc25hcHBlZFggPSBjbG9zZXN0LnRhcmdldC54O1xuICAgICAgICAgICAgICAgIHN0YXR1cy5zbmFwcGVkWSA9IGNsb3Nlc3QudGFyZ2V0Lnk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBzbmFwQ2hhbmdlZCA9IHRydWU7XG5cbiAgICAgICAgICAgICAgICBzdGF0dXMuc25hcHBlZFggPSBOYU47XG4gICAgICAgICAgICAgICAgc3RhdHVzLnNuYXBwZWRZID0gTmFOO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBzdGF0dXMuZHggPSBjbG9zZXN0LmR4O1xuICAgICAgICAgICAgc3RhdHVzLmR5ID0gY2xvc2VzdC5keTtcblxuICAgICAgICAgICAgc3RhdHVzLmNoYW5nZWQgPSAoc25hcENoYW5nZWQgfHwgKGNsb3Nlc3QuaW5SYW5nZSAmJiAhc3RhdHVzLmxvY2tlZCkpO1xuICAgICAgICAgICAgc3RhdHVzLmxvY2tlZCA9IGNsb3Nlc3QuaW5SYW5nZTtcblxuICAgICAgICAgICAgcmV0dXJuIHN0YXR1cztcbiAgICAgICAgfSxcblxuICAgICAgICBzZXRSZXN0cmljdGlvbjogZnVuY3Rpb24gKHBhZ2VDb29yZHMsIHN0YXR1cykge1xuICAgICAgICAgICAgdmFyIHRhcmdldCA9IHRoaXMudGFyZ2V0LFxuICAgICAgICAgICAgICAgIHJlc3RyaWN0ID0gdGFyZ2V0ICYmIHRhcmdldC5vcHRpb25zW3RoaXMucHJlcGFyZWQubmFtZV0ucmVzdHJpY3QsXG4gICAgICAgICAgICAgICAgcmVzdHJpY3Rpb24gPSByZXN0cmljdCAmJiByZXN0cmljdC5yZXN0cmljdGlvbixcbiAgICAgICAgICAgICAgICBwYWdlO1xuXG4gICAgICAgICAgICBpZiAoIXJlc3RyaWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHN0YXR1cztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgc3RhdHVzID0gc3RhdHVzIHx8IHRoaXMucmVzdHJpY3RTdGF0dXM7XG5cbiAgICAgICAgICAgIHBhZ2UgPSBzdGF0dXMudXNlU3RhdHVzWFlcbiAgICAgICAgICAgICAgICAgICAgPyBwYWdlID0geyB4OiBzdGF0dXMueCwgeTogc3RhdHVzLnkgfVxuICAgICAgICAgICAgICAgICAgICA6IHBhZ2UgPSBleHRlbmQoe30sIHBhZ2VDb29yZHMpO1xuXG4gICAgICAgICAgICBpZiAoc3RhdHVzLnNuYXAgJiYgc3RhdHVzLnNuYXAubG9ja2VkKSB7XG4gICAgICAgICAgICAgICAgcGFnZS54ICs9IHN0YXR1cy5zbmFwLmR4IHx8IDA7XG4gICAgICAgICAgICAgICAgcGFnZS55ICs9IHN0YXR1cy5zbmFwLmR5IHx8IDA7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHBhZ2UueCAtPSB0aGlzLmluZXJ0aWFTdGF0dXMucmVzdW1lRHg7XG4gICAgICAgICAgICBwYWdlLnkgLT0gdGhpcy5pbmVydGlhU3RhdHVzLnJlc3VtZUR5O1xuXG4gICAgICAgICAgICBzdGF0dXMuZHggPSAwO1xuICAgICAgICAgICAgc3RhdHVzLmR5ID0gMDtcbiAgICAgICAgICAgIHN0YXR1cy5yZXN0cmljdGVkID0gZmFsc2U7XG5cbiAgICAgICAgICAgIHZhciByZWN0LCByZXN0cmljdGVkWCwgcmVzdHJpY3RlZFk7XG5cbiAgICAgICAgICAgIGlmIChpc1N0cmluZyhyZXN0cmljdGlvbikpIHtcbiAgICAgICAgICAgICAgICBpZiAocmVzdHJpY3Rpb24gPT09ICdwYXJlbnQnKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3RyaWN0aW9uID0gcGFyZW50RWxlbWVudCh0aGlzLmVsZW1lbnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChyZXN0cmljdGlvbiA9PT0gJ3NlbGYnKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3RyaWN0aW9uID0gdGFyZ2V0LmdldFJlY3QodGhpcy5lbGVtZW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3RyaWN0aW9uID0gY2xvc2VzdCh0aGlzLmVsZW1lbnQsIHJlc3RyaWN0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoIXJlc3RyaWN0aW9uKSB7IHJldHVybiBzdGF0dXM7IH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGlzRnVuY3Rpb24ocmVzdHJpY3Rpb24pKSB7XG4gICAgICAgICAgICAgICAgcmVzdHJpY3Rpb24gPSByZXN0cmljdGlvbihwYWdlLngsIHBhZ2UueSwgdGhpcy5lbGVtZW50KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGlzRWxlbWVudChyZXN0cmljdGlvbikpIHtcbiAgICAgICAgICAgICAgICByZXN0cmljdGlvbiA9IGdldEVsZW1lbnRSZWN0KHJlc3RyaWN0aW9uKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmVjdCA9IHJlc3RyaWN0aW9uO1xuXG4gICAgICAgICAgICBpZiAoIXJlc3RyaWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgcmVzdHJpY3RlZFggPSBwYWdlLng7XG4gICAgICAgICAgICAgICAgcmVzdHJpY3RlZFkgPSBwYWdlLnk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBvYmplY3QgaXMgYXNzdW1lZCB0byBoYXZlXG4gICAgICAgICAgICAvLyB4LCB5LCB3aWR0aCwgaGVpZ2h0IG9yXG4gICAgICAgICAgICAvLyBsZWZ0LCB0b3AsIHJpZ2h0LCBib3R0b21cbiAgICAgICAgICAgIGVsc2UgaWYgKCd4JyBpbiByZXN0cmljdGlvbiAmJiAneScgaW4gcmVzdHJpY3Rpb24pIHtcbiAgICAgICAgICAgICAgICByZXN0cmljdGVkWCA9IE1hdGgubWF4KE1hdGgubWluKHJlY3QueCArIHJlY3Qud2lkdGggIC0gdGhpcy5yZXN0cmljdE9mZnNldC5yaWdodCAsIHBhZ2UueCksIHJlY3QueCArIHRoaXMucmVzdHJpY3RPZmZzZXQubGVmdCk7XG4gICAgICAgICAgICAgICAgcmVzdHJpY3RlZFkgPSBNYXRoLm1heChNYXRoLm1pbihyZWN0LnkgKyByZWN0LmhlaWdodCAtIHRoaXMucmVzdHJpY3RPZmZzZXQuYm90dG9tLCBwYWdlLnkpLCByZWN0LnkgKyB0aGlzLnJlc3RyaWN0T2Zmc2V0LnRvcCApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVzdHJpY3RlZFggPSBNYXRoLm1heChNYXRoLm1pbihyZWN0LnJpZ2h0ICAtIHRoaXMucmVzdHJpY3RPZmZzZXQucmlnaHQgLCBwYWdlLngpLCByZWN0LmxlZnQgKyB0aGlzLnJlc3RyaWN0T2Zmc2V0LmxlZnQpO1xuICAgICAgICAgICAgICAgIHJlc3RyaWN0ZWRZID0gTWF0aC5tYXgoTWF0aC5taW4ocmVjdC5ib3R0b20gLSB0aGlzLnJlc3RyaWN0T2Zmc2V0LmJvdHRvbSwgcGFnZS55KSwgcmVjdC50b3AgICsgdGhpcy5yZXN0cmljdE9mZnNldC50b3AgKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgc3RhdHVzLmR4ID0gcmVzdHJpY3RlZFggLSBwYWdlLng7XG4gICAgICAgICAgICBzdGF0dXMuZHkgPSByZXN0cmljdGVkWSAtIHBhZ2UueTtcblxuICAgICAgICAgICAgc3RhdHVzLmNoYW5nZWQgPSBzdGF0dXMucmVzdHJpY3RlZFggIT09IHJlc3RyaWN0ZWRYIHx8IHN0YXR1cy5yZXN0cmljdGVkWSAhPT0gcmVzdHJpY3RlZFk7XG4gICAgICAgICAgICBzdGF0dXMucmVzdHJpY3RlZCA9ICEhKHN0YXR1cy5keCB8fCBzdGF0dXMuZHkpO1xuXG4gICAgICAgICAgICBzdGF0dXMucmVzdHJpY3RlZFggPSByZXN0cmljdGVkWDtcbiAgICAgICAgICAgIHN0YXR1cy5yZXN0cmljdGVkWSA9IHJlc3RyaWN0ZWRZO1xuXG4gICAgICAgICAgICByZXR1cm4gc3RhdHVzO1xuICAgICAgICB9LFxuXG4gICAgICAgIGNoZWNrQW5kUHJldmVudERlZmF1bHQ6IGZ1bmN0aW9uIChldmVudCwgaW50ZXJhY3RhYmxlLCBlbGVtZW50KSB7XG4gICAgICAgICAgICBpZiAoIShpbnRlcmFjdGFibGUgPSBpbnRlcmFjdGFibGUgfHwgdGhpcy50YXJnZXQpKSB7IHJldHVybjsgfVxuXG4gICAgICAgICAgICB2YXIgb3B0aW9ucyA9IGludGVyYWN0YWJsZS5vcHRpb25zLFxuICAgICAgICAgICAgICAgIHByZXZlbnQgPSBvcHRpb25zLnByZXZlbnREZWZhdWx0O1xuXG4gICAgICAgICAgICBpZiAocHJldmVudCA9PT0gJ2F1dG8nICYmIGVsZW1lbnQgJiYgIS9eKGlucHV0fHNlbGVjdHx0ZXh0YXJlYSkkL2kudGVzdChldmVudC50YXJnZXQubm9kZU5hbWUpKSB7XG4gICAgICAgICAgICAgICAgLy8gZG8gbm90IHByZXZlbnREZWZhdWx0IG9uIHBvaW50ZXJkb3duIGlmIHRoZSBwcmVwYXJlZCBhY3Rpb24gaXMgYSBkcmFnXG4gICAgICAgICAgICAgICAgLy8gYW5kIGRyYWdnaW5nIGNhbiBvbmx5IHN0YXJ0IGZyb20gYSBjZXJ0YWluIGRpcmVjdGlvbiAtIHRoaXMgYWxsb3dzXG4gICAgICAgICAgICAgICAgLy8gYSB0b3VjaCB0byBwYW4gdGhlIHZpZXdwb3J0IGlmIGEgZHJhZyBpc24ndCBpbiB0aGUgcmlnaHQgZGlyZWN0aW9uXG4gICAgICAgICAgICAgICAgaWYgKC9kb3dufHN0YXJ0L2kudGVzdChldmVudC50eXBlKVxuICAgICAgICAgICAgICAgICAgICAmJiB0aGlzLnByZXBhcmVkLm5hbWUgPT09ICdkcmFnJyAmJiBvcHRpb25zLmRyYWcuYXhpcyAhPT0gJ3h5Jykge1xuXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyB3aXRoIG1hbnVhbFN0YXJ0LCBvbmx5IHByZXZlbnREZWZhdWx0IHdoaWxlIGludGVyYWN0aW5nXG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbnNbdGhpcy5wcmVwYXJlZC5uYW1lXSAmJiBvcHRpb25zW3RoaXMucHJlcGFyZWQubmFtZV0ubWFudWFsU3RhcnRcbiAgICAgICAgICAgICAgICAgICAgJiYgIXRoaXMuaW50ZXJhY3RpbmcoKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChwcmV2ZW50ID09PSAnYWx3YXlzJykge1xuICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIGNhbGNJbmVydGlhOiBmdW5jdGlvbiAoc3RhdHVzKSB7XG4gICAgICAgICAgICB2YXIgaW5lcnRpYU9wdGlvbnMgPSB0aGlzLnRhcmdldC5vcHRpb25zW3RoaXMucHJlcGFyZWQubmFtZV0uaW5lcnRpYSxcbiAgICAgICAgICAgICAgICBsYW1iZGEgPSBpbmVydGlhT3B0aW9ucy5yZXNpc3RhbmNlLFxuICAgICAgICAgICAgICAgIGluZXJ0aWFEdXIgPSAtTWF0aC5sb2coaW5lcnRpYU9wdGlvbnMuZW5kU3BlZWQgLyBzdGF0dXMudjApIC8gbGFtYmRhO1xuXG4gICAgICAgICAgICBzdGF0dXMueDAgPSB0aGlzLnByZXZFdmVudC5wYWdlWDtcbiAgICAgICAgICAgIHN0YXR1cy55MCA9IHRoaXMucHJldkV2ZW50LnBhZ2VZO1xuICAgICAgICAgICAgc3RhdHVzLnQwID0gc3RhdHVzLnN0YXJ0RXZlbnQudGltZVN0YW1wIC8gMTAwMDtcbiAgICAgICAgICAgIHN0YXR1cy5zeCA9IHN0YXR1cy5zeSA9IDA7XG5cbiAgICAgICAgICAgIHN0YXR1cy5tb2RpZmllZFhlID0gc3RhdHVzLnhlID0gKHN0YXR1cy52eDAgLSBpbmVydGlhRHVyKSAvIGxhbWJkYTtcbiAgICAgICAgICAgIHN0YXR1cy5tb2RpZmllZFllID0gc3RhdHVzLnllID0gKHN0YXR1cy52eTAgLSBpbmVydGlhRHVyKSAvIGxhbWJkYTtcbiAgICAgICAgICAgIHN0YXR1cy50ZSA9IGluZXJ0aWFEdXI7XG5cbiAgICAgICAgICAgIHN0YXR1cy5sYW1iZGFfdjAgPSBsYW1iZGEgLyBzdGF0dXMudjA7XG4gICAgICAgICAgICBzdGF0dXMub25lX3ZlX3YwID0gMSAtIGluZXJ0aWFPcHRpb25zLmVuZFNwZWVkIC8gc3RhdHVzLnYwO1xuICAgICAgICB9LFxuXG4gICAgICAgIGF1dG9TY3JvbGxNb3ZlOiBmdW5jdGlvbiAocG9pbnRlcikge1xuICAgICAgICAgICAgaWYgKCEodGhpcy5pbnRlcmFjdGluZygpXG4gICAgICAgICAgICAgICAgJiYgY2hlY2tBdXRvU2Nyb2xsKHRoaXMudGFyZ2V0LCB0aGlzLnByZXBhcmVkLm5hbWUpKSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMuaW5lcnRpYVN0YXR1cy5hY3RpdmUpIHtcbiAgICAgICAgICAgICAgICBhdXRvU2Nyb2xsLnggPSBhdXRvU2Nyb2xsLnkgPSAwO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIHRvcCxcbiAgICAgICAgICAgICAgICByaWdodCxcbiAgICAgICAgICAgICAgICBib3R0b20sXG4gICAgICAgICAgICAgICAgbGVmdCxcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gdGhpcy50YXJnZXQub3B0aW9uc1t0aGlzLnByZXBhcmVkLm5hbWVdLmF1dG9TY3JvbGwsXG4gICAgICAgICAgICAgICAgY29udGFpbmVyID0gb3B0aW9ucy5jb250YWluZXIgfHwgZ2V0V2luZG93KHRoaXMuZWxlbWVudCk7XG5cbiAgICAgICAgICAgIGlmIChpc1dpbmRvdyhjb250YWluZXIpKSB7XG4gICAgICAgICAgICAgICAgbGVmdCAgID0gcG9pbnRlci5jbGllbnRYIDwgYXV0b1Njcm9sbC5tYXJnaW47XG4gICAgICAgICAgICAgICAgdG9wICAgID0gcG9pbnRlci5jbGllbnRZIDwgYXV0b1Njcm9sbC5tYXJnaW47XG4gICAgICAgICAgICAgICAgcmlnaHQgID0gcG9pbnRlci5jbGllbnRYID4gY29udGFpbmVyLmlubmVyV2lkdGggIC0gYXV0b1Njcm9sbC5tYXJnaW47XG4gICAgICAgICAgICAgICAgYm90dG9tID0gcG9pbnRlci5jbGllbnRZID4gY29udGFpbmVyLmlubmVySGVpZ2h0IC0gYXV0b1Njcm9sbC5tYXJnaW47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YXIgcmVjdCA9IGdldEVsZW1lbnRDbGllbnRSZWN0KGNvbnRhaW5lcik7XG5cbiAgICAgICAgICAgICAgICBsZWZ0ICAgPSBwb2ludGVyLmNsaWVudFggPCByZWN0LmxlZnQgICArIGF1dG9TY3JvbGwubWFyZ2luO1xuICAgICAgICAgICAgICAgIHRvcCAgICA9IHBvaW50ZXIuY2xpZW50WSA8IHJlY3QudG9wICAgICsgYXV0b1Njcm9sbC5tYXJnaW47XG4gICAgICAgICAgICAgICAgcmlnaHQgID0gcG9pbnRlci5jbGllbnRYID4gcmVjdC5yaWdodCAgLSBhdXRvU2Nyb2xsLm1hcmdpbjtcbiAgICAgICAgICAgICAgICBib3R0b20gPSBwb2ludGVyLmNsaWVudFkgPiByZWN0LmJvdHRvbSAtIGF1dG9TY3JvbGwubWFyZ2luO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBhdXRvU2Nyb2xsLnggPSAocmlnaHQgPyAxOiBsZWZ0PyAtMTogMCk7XG4gICAgICAgICAgICBhdXRvU2Nyb2xsLnkgPSAoYm90dG9tPyAxOiAgdG9wPyAtMTogMCk7XG5cbiAgICAgICAgICAgIGlmICghYXV0b1Njcm9sbC5pc1Njcm9sbGluZykge1xuICAgICAgICAgICAgICAgIC8vIHNldCB0aGUgYXV0b1Njcm9sbCBwcm9wZXJ0aWVzIHRvIHRob3NlIG9mIHRoZSB0YXJnZXRcbiAgICAgICAgICAgICAgICBhdXRvU2Nyb2xsLm1hcmdpbiA9IG9wdGlvbnMubWFyZ2luO1xuICAgICAgICAgICAgICAgIGF1dG9TY3JvbGwuc3BlZWQgID0gb3B0aW9ucy5zcGVlZDtcblxuICAgICAgICAgICAgICAgIGF1dG9TY3JvbGwuc3RhcnQodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgX3VwZGF0ZUV2ZW50VGFyZ2V0czogZnVuY3Rpb24gKHRhcmdldCwgY3VycmVudFRhcmdldCkge1xuICAgICAgICAgICAgdGhpcy5fZXZlbnRUYXJnZXQgICAgPSB0YXJnZXQ7XG4gICAgICAgICAgICB0aGlzLl9jdXJFdmVudFRhcmdldCA9IGN1cnJlbnRUYXJnZXQ7XG4gICAgICAgIH1cblxuICAgIH07XG5cbiAgICBmdW5jdGlvbiBnZXRJbnRlcmFjdGlvbkZyb21Qb2ludGVyIChwb2ludGVyLCBldmVudFR5cGUsIGV2ZW50VGFyZ2V0KSB7XG4gICAgICAgIHZhciBpID0gMCwgbGVuID0gaW50ZXJhY3Rpb25zLmxlbmd0aCxcbiAgICAgICAgICAgIG1vdXNlRXZlbnQgPSAoL21vdXNlL2kudGVzdChwb2ludGVyLnBvaW50ZXJUeXBlIHx8IGV2ZW50VHlwZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTVNQb2ludGVyRXZlbnQuTVNQT0lOVEVSX1RZUEVfTU9VU0VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgcG9pbnRlci5wb2ludGVyVHlwZSA9PT0gNCksXG4gICAgICAgICAgICBpbnRlcmFjdGlvbjtcblxuICAgICAgICB2YXIgaWQgPSBnZXRQb2ludGVySWQocG9pbnRlcik7XG5cbiAgICAgICAgLy8gdHJ5IHRvIHJlc3VtZSBpbmVydGlhIHdpdGggYSBuZXcgcG9pbnRlclxuICAgICAgICBpZiAoL2Rvd258c3RhcnQvaS50ZXN0KGV2ZW50VHlwZSkpIHtcbiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgICAgIGludGVyYWN0aW9uID0gaW50ZXJhY3Rpb25zW2ldO1xuXG4gICAgICAgICAgICAgICAgdmFyIGVsZW1lbnQgPSBldmVudFRhcmdldDtcblxuICAgICAgICAgICAgICAgIGlmIChpbnRlcmFjdGlvbi5pbmVydGlhU3RhdHVzLmFjdGl2ZSAmJiBpbnRlcmFjdGlvbi50YXJnZXQub3B0aW9uc1tpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lXS5pbmVydGlhLmFsbG93UmVzdW1lXG4gICAgICAgICAgICAgICAgICAgICYmIChpbnRlcmFjdGlvbi5tb3VzZSA9PT0gbW91c2VFdmVudCkpIHtcbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIHRoZSBlbGVtZW50IGlzIHRoZSBpbnRlcmFjdGlvbiBlbGVtZW50XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZWxlbWVudCA9PT0gaW50ZXJhY3Rpb24uZWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpbnRlcmFjdGlvbjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQgPSBwYXJlbnRFbGVtZW50KGVsZW1lbnQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gaWYgaXQncyBhIG1vdXNlIGludGVyYWN0aW9uXG4gICAgICAgIGlmIChtb3VzZUV2ZW50IHx8ICEoc3VwcG9ydHNUb3VjaCB8fCBzdXBwb3J0c1BvaW50ZXJFdmVudCkpIHtcblxuICAgICAgICAgICAgLy8gZmluZCBhIG1vdXNlIGludGVyYWN0aW9uIHRoYXQncyBub3QgaW4gaW5lcnRpYSBwaGFzZVxuICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGludGVyYWN0aW9uc1tpXS5tb3VzZSAmJiAhaW50ZXJhY3Rpb25zW2ldLmluZXJ0aWFTdGF0dXMuYWN0aXZlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpbnRlcmFjdGlvbnNbaV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBmaW5kIGFueSBpbnRlcmFjdGlvbiBzcGVjaWZpY2FsbHkgZm9yIG1vdXNlLlxuICAgICAgICAgICAgLy8gaWYgdGhlIGV2ZW50VHlwZSBpcyBhIG1vdXNlZG93biwgYW5kIGluZXJ0aWEgaXMgYWN0aXZlXG4gICAgICAgICAgICAvLyBpZ25vcmUgdGhlIGludGVyYWN0aW9uXG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoaW50ZXJhY3Rpb25zW2ldLm1vdXNlICYmICEoL2Rvd24vLnRlc3QoZXZlbnRUeXBlKSAmJiBpbnRlcmFjdGlvbnNbaV0uaW5lcnRpYVN0YXR1cy5hY3RpdmUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpbnRlcmFjdGlvbjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGNyZWF0ZSBhIG5ldyBpbnRlcmFjdGlvbiBmb3IgbW91c2VcbiAgICAgICAgICAgIGludGVyYWN0aW9uID0gbmV3IEludGVyYWN0aW9uKCk7XG4gICAgICAgICAgICBpbnRlcmFjdGlvbi5tb3VzZSA9IHRydWU7XG5cbiAgICAgICAgICAgIHJldHVybiBpbnRlcmFjdGlvbjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGdldCBpbnRlcmFjdGlvbiB0aGF0IGhhcyB0aGlzIHBvaW50ZXJcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoY29udGFpbnMoaW50ZXJhY3Rpb25zW2ldLnBvaW50ZXJJZHMsIGlkKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnRlcmFjdGlvbnNbaV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBhdCB0aGlzIHN0YWdlLCBhIHBvaW50ZXJVcCBzaG91bGQgbm90IHJldHVybiBhbiBpbnRlcmFjdGlvblxuICAgICAgICBpZiAoL3VwfGVuZHxvdXQvaS50ZXN0KGV2ZW50VHlwZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gZ2V0IGZpcnN0IGlkbGUgaW50ZXJhY3Rpb25cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICBpbnRlcmFjdGlvbiA9IGludGVyYWN0aW9uc1tpXTtcblxuICAgICAgICAgICAgaWYgKCghaW50ZXJhY3Rpb24ucHJlcGFyZWQubmFtZSB8fCAoaW50ZXJhY3Rpb24udGFyZ2V0Lm9wdGlvbnMuZ2VzdHVyZS5lbmFibGVkKSlcbiAgICAgICAgICAgICAgICAmJiAhaW50ZXJhY3Rpb24uaW50ZXJhY3RpbmcoKVxuICAgICAgICAgICAgICAgICYmICEoIW1vdXNlRXZlbnQgJiYgaW50ZXJhY3Rpb24ubW91c2UpKSB7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gaW50ZXJhY3Rpb247XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmV3IEludGVyYWN0aW9uKCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZG9PbkludGVyYWN0aW9ucyAobWV0aG9kKSB7XG4gICAgICAgIHJldHVybiAoZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgICB2YXIgaW50ZXJhY3Rpb24sXG4gICAgICAgICAgICAgICAgZXZlbnRUYXJnZXQgPSBnZXRBY3R1YWxFbGVtZW50KGV2ZW50LnBhdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBldmVudC5wYXRoWzBdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogZXZlbnQudGFyZ2V0KSxcbiAgICAgICAgICAgICAgICBjdXJFdmVudFRhcmdldCA9IGdldEFjdHVhbEVsZW1lbnQoZXZlbnQuY3VycmVudFRhcmdldCksXG4gICAgICAgICAgICAgICAgaTtcblxuICAgICAgICAgICAgaWYgKHN1cHBvcnRzVG91Y2ggJiYgL3RvdWNoLy50ZXN0KGV2ZW50LnR5cGUpKSB7XG4gICAgICAgICAgICAgICAgcHJldlRvdWNoVGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuXG4gICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGV2ZW50LmNoYW5nZWRUb3VjaGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBwb2ludGVyID0gZXZlbnQuY2hhbmdlZFRvdWNoZXNbaV07XG5cbiAgICAgICAgICAgICAgICAgICAgaW50ZXJhY3Rpb24gPSBnZXRJbnRlcmFjdGlvbkZyb21Qb2ludGVyKHBvaW50ZXIsIGV2ZW50LnR5cGUsIGV2ZW50VGFyZ2V0KTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoIWludGVyYWN0aW9uKSB7IGNvbnRpbnVlOyB9XG5cbiAgICAgICAgICAgICAgICAgICAgaW50ZXJhY3Rpb24uX3VwZGF0ZUV2ZW50VGFyZ2V0cyhldmVudFRhcmdldCwgY3VyRXZlbnRUYXJnZXQpO1xuXG4gICAgICAgICAgICAgICAgICAgIGludGVyYWN0aW9uW21ldGhvZF0ocG9pbnRlciwgZXZlbnQsIGV2ZW50VGFyZ2V0LCBjdXJFdmVudFRhcmdldCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKCFzdXBwb3J0c1BvaW50ZXJFdmVudCAmJiAvbW91c2UvLnRlc3QoZXZlbnQudHlwZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gaWdub3JlIG1vdXNlIGV2ZW50cyB3aGlsZSB0b3VjaCBpbnRlcmFjdGlvbnMgYXJlIGFjdGl2ZVxuICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgaW50ZXJhY3Rpb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWludGVyYWN0aW9uc1tpXS5tb3VzZSAmJiBpbnRlcmFjdGlvbnNbaV0ucG9pbnRlcklzRG93bikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIHRyeSB0byBpZ25vcmUgbW91c2UgZXZlbnRzIHRoYXQgYXJlIHNpbXVsYXRlZCBieSB0aGUgYnJvd3NlclxuICAgICAgICAgICAgICAgICAgICAvLyBhZnRlciBhIHRvdWNoIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgIGlmIChuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIHByZXZUb3VjaFRpbWUgPCA1MDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGludGVyYWN0aW9uID0gZ2V0SW50ZXJhY3Rpb25Gcm9tUG9pbnRlcihldmVudCwgZXZlbnQudHlwZSwgZXZlbnRUYXJnZXQpO1xuXG4gICAgICAgICAgICAgICAgaWYgKCFpbnRlcmFjdGlvbikgeyByZXR1cm47IH1cblxuICAgICAgICAgICAgICAgIGludGVyYWN0aW9uLl91cGRhdGVFdmVudFRhcmdldHMoZXZlbnRUYXJnZXQsIGN1ckV2ZW50VGFyZ2V0KTtcblxuICAgICAgICAgICAgICAgIGludGVyYWN0aW9uW21ldGhvZF0oZXZlbnQsIGV2ZW50LCBldmVudFRhcmdldCwgY3VyRXZlbnRUYXJnZXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBJbnRlcmFjdEV2ZW50IChpbnRlcmFjdGlvbiwgZXZlbnQsIGFjdGlvbiwgcGhhc2UsIGVsZW1lbnQsIHJlbGF0ZWQpIHtcbiAgICAgICAgdmFyIGNsaWVudCxcbiAgICAgICAgICAgIHBhZ2UsXG4gICAgICAgICAgICB0YXJnZXQgICAgICA9IGludGVyYWN0aW9uLnRhcmdldCxcbiAgICAgICAgICAgIHNuYXBTdGF0dXMgID0gaW50ZXJhY3Rpb24uc25hcFN0YXR1cyxcbiAgICAgICAgICAgIHJlc3RyaWN0U3RhdHVzICA9IGludGVyYWN0aW9uLnJlc3RyaWN0U3RhdHVzLFxuICAgICAgICAgICAgcG9pbnRlcnMgICAgPSBpbnRlcmFjdGlvbi5wb2ludGVycyxcbiAgICAgICAgICAgIGRlbHRhU291cmNlID0gKHRhcmdldCAmJiB0YXJnZXQub3B0aW9ucyB8fCBkZWZhdWx0T3B0aW9ucykuZGVsdGFTb3VyY2UsXG4gICAgICAgICAgICBzb3VyY2VYICAgICA9IGRlbHRhU291cmNlICsgJ1gnLFxuICAgICAgICAgICAgc291cmNlWSAgICAgPSBkZWx0YVNvdXJjZSArICdZJyxcbiAgICAgICAgICAgIG9wdGlvbnMgICAgID0gdGFyZ2V0PyB0YXJnZXQub3B0aW9uczogZGVmYXVsdE9wdGlvbnMsXG4gICAgICAgICAgICBvcmlnaW4gICAgICA9IGdldE9yaWdpblhZKHRhcmdldCwgZWxlbWVudCksXG4gICAgICAgICAgICBzdGFydGluZyAgICA9IHBoYXNlID09PSAnc3RhcnQnLFxuICAgICAgICAgICAgZW5kaW5nICAgICAgPSBwaGFzZSA9PT0gJ2VuZCcsXG4gICAgICAgICAgICBjb29yZHMgICAgICA9IHN0YXJ0aW5nPyBpbnRlcmFjdGlvbi5zdGFydENvb3JkcyA6IGludGVyYWN0aW9uLmN1ckNvb3JkcztcblxuICAgICAgICBlbGVtZW50ID0gZWxlbWVudCB8fCBpbnRlcmFjdGlvbi5lbGVtZW50O1xuXG4gICAgICAgIHBhZ2UgICA9IGV4dGVuZCh7fSwgY29vcmRzLnBhZ2UpO1xuICAgICAgICBjbGllbnQgPSBleHRlbmQoe30sIGNvb3Jkcy5jbGllbnQpO1xuXG4gICAgICAgIHBhZ2UueCAtPSBvcmlnaW4ueDtcbiAgICAgICAgcGFnZS55IC09IG9yaWdpbi55O1xuXG4gICAgICAgIGNsaWVudC54IC09IG9yaWdpbi54O1xuICAgICAgICBjbGllbnQueSAtPSBvcmlnaW4ueTtcblxuICAgICAgICB2YXIgcmVsYXRpdmVQb2ludHMgPSBvcHRpb25zW2FjdGlvbl0uc25hcCAmJiBvcHRpb25zW2FjdGlvbl0uc25hcC5yZWxhdGl2ZVBvaW50cyA7XG5cbiAgICAgICAgaWYgKGNoZWNrU25hcCh0YXJnZXQsIGFjdGlvbikgJiYgIShzdGFydGluZyAmJiByZWxhdGl2ZVBvaW50cyAmJiByZWxhdGl2ZVBvaW50cy5sZW5ndGgpKSB7XG4gICAgICAgICAgICB0aGlzLnNuYXAgPSB7XG4gICAgICAgICAgICAgICAgcmFuZ2UgIDogc25hcFN0YXR1cy5yYW5nZSxcbiAgICAgICAgICAgICAgICBsb2NrZWQgOiBzbmFwU3RhdHVzLmxvY2tlZCxcbiAgICAgICAgICAgICAgICB4ICAgICAgOiBzbmFwU3RhdHVzLnNuYXBwZWRYLFxuICAgICAgICAgICAgICAgIHkgICAgICA6IHNuYXBTdGF0dXMuc25hcHBlZFksXG4gICAgICAgICAgICAgICAgcmVhbFggIDogc25hcFN0YXR1cy5yZWFsWCxcbiAgICAgICAgICAgICAgICByZWFsWSAgOiBzbmFwU3RhdHVzLnJlYWxZLFxuICAgICAgICAgICAgICAgIGR4ICAgICA6IHNuYXBTdGF0dXMuZHgsXG4gICAgICAgICAgICAgICAgZHkgICAgIDogc25hcFN0YXR1cy5keVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKHNuYXBTdGF0dXMubG9ja2VkKSB7XG4gICAgICAgICAgICAgICAgcGFnZS54ICs9IHNuYXBTdGF0dXMuZHg7XG4gICAgICAgICAgICAgICAgcGFnZS55ICs9IHNuYXBTdGF0dXMuZHk7XG4gICAgICAgICAgICAgICAgY2xpZW50LnggKz0gc25hcFN0YXR1cy5keDtcbiAgICAgICAgICAgICAgICBjbGllbnQueSArPSBzbmFwU3RhdHVzLmR5O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNoZWNrUmVzdHJpY3QodGFyZ2V0LCBhY3Rpb24pICYmICEoc3RhcnRpbmcgJiYgb3B0aW9uc1thY3Rpb25dLnJlc3RyaWN0LmVsZW1lbnRSZWN0KSAmJiByZXN0cmljdFN0YXR1cy5yZXN0cmljdGVkKSB7XG4gICAgICAgICAgICBwYWdlLnggKz0gcmVzdHJpY3RTdGF0dXMuZHg7XG4gICAgICAgICAgICBwYWdlLnkgKz0gcmVzdHJpY3RTdGF0dXMuZHk7XG4gICAgICAgICAgICBjbGllbnQueCArPSByZXN0cmljdFN0YXR1cy5keDtcbiAgICAgICAgICAgIGNsaWVudC55ICs9IHJlc3RyaWN0U3RhdHVzLmR5O1xuXG4gICAgICAgICAgICB0aGlzLnJlc3RyaWN0ID0ge1xuICAgICAgICAgICAgICAgIGR4OiByZXN0cmljdFN0YXR1cy5keCxcbiAgICAgICAgICAgICAgICBkeTogcmVzdHJpY3RTdGF0dXMuZHlcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnBhZ2VYICAgICA9IHBhZ2UueDtcbiAgICAgICAgdGhpcy5wYWdlWSAgICAgPSBwYWdlLnk7XG4gICAgICAgIHRoaXMuY2xpZW50WCAgID0gY2xpZW50Lng7XG4gICAgICAgIHRoaXMuY2xpZW50WSAgID0gY2xpZW50Lnk7XG5cbiAgICAgICAgdGhpcy54MCAgICAgICAgPSBpbnRlcmFjdGlvbi5zdGFydENvb3Jkcy5wYWdlLnggLSBvcmlnaW4ueDtcbiAgICAgICAgdGhpcy55MCAgICAgICAgPSBpbnRlcmFjdGlvbi5zdGFydENvb3Jkcy5wYWdlLnkgLSBvcmlnaW4ueTtcbiAgICAgICAgdGhpcy5jbGllbnRYMCAgPSBpbnRlcmFjdGlvbi5zdGFydENvb3Jkcy5jbGllbnQueCAtIG9yaWdpbi54O1xuICAgICAgICB0aGlzLmNsaWVudFkwICA9IGludGVyYWN0aW9uLnN0YXJ0Q29vcmRzLmNsaWVudC55IC0gb3JpZ2luLnk7XG4gICAgICAgIHRoaXMuY3RybEtleSAgID0gZXZlbnQuY3RybEtleTtcbiAgICAgICAgdGhpcy5hbHRLZXkgICAgPSBldmVudC5hbHRLZXk7XG4gICAgICAgIHRoaXMuc2hpZnRLZXkgID0gZXZlbnQuc2hpZnRLZXk7XG4gICAgICAgIHRoaXMubWV0YUtleSAgID0gZXZlbnQubWV0YUtleTtcbiAgICAgICAgdGhpcy5idXR0b24gICAgPSBldmVudC5idXR0b247XG4gICAgICAgIHRoaXMuYnV0dG9ucyAgID0gZXZlbnQuYnV0dG9ucztcbiAgICAgICAgdGhpcy50YXJnZXQgICAgPSBlbGVtZW50O1xuICAgICAgICB0aGlzLnQwICAgICAgICA9IGludGVyYWN0aW9uLmRvd25UaW1lc1swXTtcbiAgICAgICAgdGhpcy50eXBlICAgICAgPSBhY3Rpb24gKyAocGhhc2UgfHwgJycpO1xuXG4gICAgICAgIHRoaXMuaW50ZXJhY3Rpb24gPSBpbnRlcmFjdGlvbjtcbiAgICAgICAgdGhpcy5pbnRlcmFjdGFibGUgPSB0YXJnZXQ7XG5cbiAgICAgICAgdmFyIGluZXJ0aWFTdGF0dXMgPSBpbnRlcmFjdGlvbi5pbmVydGlhU3RhdHVzO1xuXG4gICAgICAgIGlmIChpbmVydGlhU3RhdHVzLmFjdGl2ZSkge1xuICAgICAgICAgICAgdGhpcy5kZXRhaWwgPSAnaW5lcnRpYSc7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocmVsYXRlZCkge1xuICAgICAgICAgICAgdGhpcy5yZWxhdGVkVGFyZ2V0ID0gcmVsYXRlZDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGVuZCBldmVudCBkeCwgZHkgaXMgZGlmZmVyZW5jZSBiZXR3ZWVuIHN0YXJ0IGFuZCBlbmQgcG9pbnRzXG4gICAgICAgIGlmIChlbmRpbmcpIHtcbiAgICAgICAgICAgIGlmIChkZWx0YVNvdXJjZSA9PT0gJ2NsaWVudCcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmR4ID0gY2xpZW50LnggLSBpbnRlcmFjdGlvbi5zdGFydENvb3Jkcy5jbGllbnQueDtcbiAgICAgICAgICAgICAgICB0aGlzLmR5ID0gY2xpZW50LnkgLSBpbnRlcmFjdGlvbi5zdGFydENvb3Jkcy5jbGllbnQueTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuZHggPSBwYWdlLnggLSBpbnRlcmFjdGlvbi5zdGFydENvb3Jkcy5wYWdlLng7XG4gICAgICAgICAgICAgICAgdGhpcy5keSA9IHBhZ2UueSAtIGludGVyYWN0aW9uLnN0YXJ0Q29vcmRzLnBhZ2UueTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChzdGFydGluZykge1xuICAgICAgICAgICAgdGhpcy5keCA9IDA7XG4gICAgICAgICAgICB0aGlzLmR5ID0gMDtcbiAgICAgICAgfVxuICAgICAgICAvLyBjb3B5IHByb3BlcnRpZXMgZnJvbSBwcmV2aW91c21vdmUgaWYgc3RhcnRpbmcgaW5lcnRpYVxuICAgICAgICBlbHNlIGlmIChwaGFzZSA9PT0gJ2luZXJ0aWFzdGFydCcpIHtcbiAgICAgICAgICAgIHRoaXMuZHggPSBpbnRlcmFjdGlvbi5wcmV2RXZlbnQuZHg7XG4gICAgICAgICAgICB0aGlzLmR5ID0gaW50ZXJhY3Rpb24ucHJldkV2ZW50LmR5O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaWYgKGRlbHRhU291cmNlID09PSAnY2xpZW50Jykge1xuICAgICAgICAgICAgICAgIHRoaXMuZHggPSBjbGllbnQueCAtIGludGVyYWN0aW9uLnByZXZFdmVudC5jbGllbnRYO1xuICAgICAgICAgICAgICAgIHRoaXMuZHkgPSBjbGllbnQueSAtIGludGVyYWN0aW9uLnByZXZFdmVudC5jbGllbnRZO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5keCA9IHBhZ2UueCAtIGludGVyYWN0aW9uLnByZXZFdmVudC5wYWdlWDtcbiAgICAgICAgICAgICAgICB0aGlzLmR5ID0gcGFnZS55IC0gaW50ZXJhY3Rpb24ucHJldkV2ZW50LnBhZ2VZO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChpbnRlcmFjdGlvbi5wcmV2RXZlbnQgJiYgaW50ZXJhY3Rpb24ucHJldkV2ZW50LmRldGFpbCA9PT0gJ2luZXJ0aWEnXG4gICAgICAgICAgICAmJiAhaW5lcnRpYVN0YXR1cy5hY3RpdmVcbiAgICAgICAgICAgICYmIG9wdGlvbnNbYWN0aW9uXS5pbmVydGlhICYmIG9wdGlvbnNbYWN0aW9uXS5pbmVydGlhLnplcm9SZXN1bWVEZWx0YSkge1xuXG4gICAgICAgICAgICBpbmVydGlhU3RhdHVzLnJlc3VtZUR4ICs9IHRoaXMuZHg7XG4gICAgICAgICAgICBpbmVydGlhU3RhdHVzLnJlc3VtZUR5ICs9IHRoaXMuZHk7XG5cbiAgICAgICAgICAgIHRoaXMuZHggPSB0aGlzLmR5ID0gMDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChhY3Rpb24gPT09ICdyZXNpemUnICYmIGludGVyYWN0aW9uLnJlc2l6ZUF4ZXMpIHtcbiAgICAgICAgICAgIGlmIChvcHRpb25zLnJlc2l6ZS5zcXVhcmUpIHtcbiAgICAgICAgICAgICAgICBpZiAoaW50ZXJhY3Rpb24ucmVzaXplQXhlcyA9PT0gJ3knKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZHggPSB0aGlzLmR5O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5keSA9IHRoaXMuZHg7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuYXhlcyA9ICd4eSc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmF4ZXMgPSBpbnRlcmFjdGlvbi5yZXNpemVBeGVzO1xuXG4gICAgICAgICAgICAgICAgaWYgKGludGVyYWN0aW9uLnJlc2l6ZUF4ZXMgPT09ICd4Jykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmR5ID0gMDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoaW50ZXJhY3Rpb24ucmVzaXplQXhlcyA9PT0gJ3knKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZHggPSAwO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChhY3Rpb24gPT09ICdnZXN0dXJlJykge1xuICAgICAgICAgICAgdGhpcy50b3VjaGVzID0gW3BvaW50ZXJzWzBdLCBwb2ludGVyc1sxXV07XG5cbiAgICAgICAgICAgIGlmIChzdGFydGluZykge1xuICAgICAgICAgICAgICAgIHRoaXMuZGlzdGFuY2UgPSB0b3VjaERpc3RhbmNlKHBvaW50ZXJzLCBkZWx0YVNvdXJjZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5ib3ggICAgICA9IHRvdWNoQkJveChwb2ludGVycyk7XG4gICAgICAgICAgICAgICAgdGhpcy5zY2FsZSAgICA9IDE7XG4gICAgICAgICAgICAgICAgdGhpcy5kcyAgICAgICA9IDA7XG4gICAgICAgICAgICAgICAgdGhpcy5hbmdsZSAgICA9IHRvdWNoQW5nbGUocG9pbnRlcnMsIHVuZGVmaW5lZCwgZGVsdGFTb3VyY2UpO1xuICAgICAgICAgICAgICAgIHRoaXMuZGEgICAgICAgPSAwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoZW5kaW5nIHx8IGV2ZW50IGluc3RhbmNlb2YgSW50ZXJhY3RFdmVudCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGlzdGFuY2UgPSBpbnRlcmFjdGlvbi5wcmV2RXZlbnQuZGlzdGFuY2U7XG4gICAgICAgICAgICAgICAgdGhpcy5ib3ggICAgICA9IGludGVyYWN0aW9uLnByZXZFdmVudC5ib3g7XG4gICAgICAgICAgICAgICAgdGhpcy5zY2FsZSAgICA9IGludGVyYWN0aW9uLnByZXZFdmVudC5zY2FsZTtcbiAgICAgICAgICAgICAgICB0aGlzLmRzICAgICAgID0gdGhpcy5zY2FsZSAtIDE7XG4gICAgICAgICAgICAgICAgdGhpcy5hbmdsZSAgICA9IGludGVyYWN0aW9uLnByZXZFdmVudC5hbmdsZTtcbiAgICAgICAgICAgICAgICB0aGlzLmRhICAgICAgID0gdGhpcy5hbmdsZSAtIGludGVyYWN0aW9uLmdlc3R1cmUuc3RhcnRBbmdsZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuZGlzdGFuY2UgPSB0b3VjaERpc3RhbmNlKHBvaW50ZXJzLCBkZWx0YVNvdXJjZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5ib3ggICAgICA9IHRvdWNoQkJveChwb2ludGVycyk7XG4gICAgICAgICAgICAgICAgdGhpcy5zY2FsZSAgICA9IHRoaXMuZGlzdGFuY2UgLyBpbnRlcmFjdGlvbi5nZXN0dXJlLnN0YXJ0RGlzdGFuY2U7XG4gICAgICAgICAgICAgICAgdGhpcy5hbmdsZSAgICA9IHRvdWNoQW5nbGUocG9pbnRlcnMsIGludGVyYWN0aW9uLmdlc3R1cmUucHJldkFuZ2xlLCBkZWx0YVNvdXJjZSk7XG5cbiAgICAgICAgICAgICAgICB0aGlzLmRzID0gdGhpcy5zY2FsZSAtIGludGVyYWN0aW9uLmdlc3R1cmUucHJldlNjYWxlO1xuICAgICAgICAgICAgICAgIHRoaXMuZGEgPSB0aGlzLmFuZ2xlIC0gaW50ZXJhY3Rpb24uZ2VzdHVyZS5wcmV2QW5nbGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc3RhcnRpbmcpIHtcbiAgICAgICAgICAgIHRoaXMudGltZVN0YW1wID0gaW50ZXJhY3Rpb24uZG93blRpbWVzWzBdO1xuICAgICAgICAgICAgdGhpcy5kdCAgICAgICAgPSAwO1xuICAgICAgICAgICAgdGhpcy5kdXJhdGlvbiAgPSAwO1xuICAgICAgICAgICAgdGhpcy5zcGVlZCAgICAgPSAwO1xuICAgICAgICAgICAgdGhpcy52ZWxvY2l0eVggPSAwO1xuICAgICAgICAgICAgdGhpcy52ZWxvY2l0eVkgPSAwO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHBoYXNlID09PSAnaW5lcnRpYXN0YXJ0Jykge1xuICAgICAgICAgICAgdGhpcy50aW1lU3RhbXAgPSBpbnRlcmFjdGlvbi5wcmV2RXZlbnQudGltZVN0YW1wO1xuICAgICAgICAgICAgdGhpcy5kdCAgICAgICAgPSBpbnRlcmFjdGlvbi5wcmV2RXZlbnQuZHQ7XG4gICAgICAgICAgICB0aGlzLmR1cmF0aW9uICA9IGludGVyYWN0aW9uLnByZXZFdmVudC5kdXJhdGlvbjtcbiAgICAgICAgICAgIHRoaXMuc3BlZWQgICAgID0gaW50ZXJhY3Rpb24ucHJldkV2ZW50LnNwZWVkO1xuICAgICAgICAgICAgdGhpcy52ZWxvY2l0eVggPSBpbnRlcmFjdGlvbi5wcmV2RXZlbnQudmVsb2NpdHlYO1xuICAgICAgICAgICAgdGhpcy52ZWxvY2l0eVkgPSBpbnRlcmFjdGlvbi5wcmV2RXZlbnQudmVsb2NpdHlZO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy50aW1lU3RhbXAgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICAgICAgICAgIHRoaXMuZHQgICAgICAgID0gdGhpcy50aW1lU3RhbXAgLSBpbnRlcmFjdGlvbi5wcmV2RXZlbnQudGltZVN0YW1wO1xuICAgICAgICAgICAgdGhpcy5kdXJhdGlvbiAgPSB0aGlzLnRpbWVTdGFtcCAtIGludGVyYWN0aW9uLmRvd25UaW1lc1swXTtcblxuICAgICAgICAgICAgaWYgKGV2ZW50IGluc3RhbmNlb2YgSW50ZXJhY3RFdmVudCkge1xuICAgICAgICAgICAgICAgIHZhciBkeCA9IHRoaXNbc291cmNlWF0gLSBpbnRlcmFjdGlvbi5wcmV2RXZlbnRbc291cmNlWF0sXG4gICAgICAgICAgICAgICAgICAgIGR5ID0gdGhpc1tzb3VyY2VZXSAtIGludGVyYWN0aW9uLnByZXZFdmVudFtzb3VyY2VZXSxcbiAgICAgICAgICAgICAgICAgICAgZHQgPSB0aGlzLmR0IC8gMTAwMDtcblxuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWQgPSBoeXBvdChkeCwgZHkpIC8gZHQ7XG4gICAgICAgICAgICAgICAgdGhpcy52ZWxvY2l0eVggPSBkeCAvIGR0O1xuICAgICAgICAgICAgICAgIHRoaXMudmVsb2NpdHlZID0gZHkgLyBkdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIGlmIG5vcm1hbCBtb3ZlIG9yIGVuZCBldmVudCwgdXNlIHByZXZpb3VzIHVzZXIgZXZlbnQgY29vcmRzXG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBzcGVlZCBhbmQgdmVsb2NpdHkgaW4gcGl4ZWxzIHBlciBzZWNvbmRcbiAgICAgICAgICAgICAgICB0aGlzLnNwZWVkID0gaW50ZXJhY3Rpb24ucG9pbnRlckRlbHRhW2RlbHRhU291cmNlXS5zcGVlZDtcbiAgICAgICAgICAgICAgICB0aGlzLnZlbG9jaXR5WCA9IGludGVyYWN0aW9uLnBvaW50ZXJEZWx0YVtkZWx0YVNvdXJjZV0udng7XG4gICAgICAgICAgICAgICAgdGhpcy52ZWxvY2l0eVkgPSBpbnRlcmFjdGlvbi5wb2ludGVyRGVsdGFbZGVsdGFTb3VyY2VdLnZ5O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKChlbmRpbmcgfHwgcGhhc2UgPT09ICdpbmVydGlhc3RhcnQnKVxuICAgICAgICAgICAgJiYgaW50ZXJhY3Rpb24ucHJldkV2ZW50LnNwZWVkID4gNjAwICYmIHRoaXMudGltZVN0YW1wIC0gaW50ZXJhY3Rpb24ucHJldkV2ZW50LnRpbWVTdGFtcCA8IDE1MCkge1xuXG4gICAgICAgICAgICB2YXIgYW5nbGUgPSAxODAgKiBNYXRoLmF0YW4yKGludGVyYWN0aW9uLnByZXZFdmVudC52ZWxvY2l0eVksIGludGVyYWN0aW9uLnByZXZFdmVudC52ZWxvY2l0eVgpIC8gTWF0aC5QSSxcbiAgICAgICAgICAgICAgICBvdmVybGFwID0gMjIuNTtcblxuICAgICAgICAgICAgaWYgKGFuZ2xlIDwgMCkge1xuICAgICAgICAgICAgICAgIGFuZ2xlICs9IDM2MDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIGxlZnQgPSAxMzUgLSBvdmVybGFwIDw9IGFuZ2xlICYmIGFuZ2xlIDwgMjI1ICsgb3ZlcmxhcCxcbiAgICAgICAgICAgICAgICB1cCAgID0gMjI1IC0gb3ZlcmxhcCA8PSBhbmdsZSAmJiBhbmdsZSA8IDMxNSArIG92ZXJsYXAsXG5cbiAgICAgICAgICAgICAgICByaWdodCA9ICFsZWZ0ICYmICgzMTUgLSBvdmVybGFwIDw9IGFuZ2xlIHx8IGFuZ2xlIDwgIDQ1ICsgb3ZlcmxhcCksXG4gICAgICAgICAgICAgICAgZG93biAgPSAhdXAgICAmJiAgIDQ1IC0gb3ZlcmxhcCA8PSBhbmdsZSAmJiBhbmdsZSA8IDEzNSArIG92ZXJsYXA7XG5cbiAgICAgICAgICAgIHRoaXMuc3dpcGUgPSB7XG4gICAgICAgICAgICAgICAgdXAgICA6IHVwLFxuICAgICAgICAgICAgICAgIGRvd24gOiBkb3duLFxuICAgICAgICAgICAgICAgIGxlZnQgOiBsZWZ0LFxuICAgICAgICAgICAgICAgIHJpZ2h0OiByaWdodCxcbiAgICAgICAgICAgICAgICBhbmdsZTogYW5nbGUsXG4gICAgICAgICAgICAgICAgc3BlZWQ6IGludGVyYWN0aW9uLnByZXZFdmVudC5zcGVlZCxcbiAgICAgICAgICAgICAgICB2ZWxvY2l0eToge1xuICAgICAgICAgICAgICAgICAgICB4OiBpbnRlcmFjdGlvbi5wcmV2RXZlbnQudmVsb2NpdHlYLFxuICAgICAgICAgICAgICAgICAgICB5OiBpbnRlcmFjdGlvbi5wcmV2RXZlbnQudmVsb2NpdHlZXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIEludGVyYWN0RXZlbnQucHJvdG90eXBlID0ge1xuICAgICAgICBwcmV2ZW50RGVmYXVsdDogYmxhbmssXG4gICAgICAgIHN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdGhpcy5pbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQgPSB0aGlzLnByb3BhZ2F0aW9uU3RvcHBlZCA9IHRydWU7XG4gICAgICAgIH0sXG4gICAgICAgIHN0b3BQcm9wYWdhdGlvbjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdGhpcy5wcm9wYWdhdGlvblN0b3BwZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIHByZXZlbnRPcmlnaW5hbERlZmF1bHQgKCkge1xuICAgICAgICB0aGlzLm9yaWdpbmFsRXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRBY3Rpb25DdXJzb3IgKGFjdGlvbikge1xuICAgICAgICB2YXIgY3Vyc29yID0gJyc7XG5cbiAgICAgICAgaWYgKGFjdGlvbi5uYW1lID09PSAnZHJhZycpIHtcbiAgICAgICAgICAgIGN1cnNvciA9ICBhY3Rpb25DdXJzb3JzLmRyYWc7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGFjdGlvbi5uYW1lID09PSAncmVzaXplJykge1xuICAgICAgICAgICAgaWYgKGFjdGlvbi5heGlzKSB7XG4gICAgICAgICAgICAgICAgY3Vyc29yID0gIGFjdGlvbkN1cnNvcnNbYWN0aW9uLm5hbWUgKyBhY3Rpb24uYXhpc107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChhY3Rpb24uZWRnZXMpIHtcbiAgICAgICAgICAgICAgICB2YXIgY3Vyc29yS2V5ID0gJ3Jlc2l6ZScsXG4gICAgICAgICAgICAgICAgICAgIGVkZ2VOYW1lcyA9IFsndG9wJywgJ2JvdHRvbScsICdsZWZ0JywgJ3JpZ2h0J107XG5cbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDQ7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoYWN0aW9uLmVkZ2VzW2VkZ2VOYW1lc1tpXV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnNvcktleSArPSBlZGdlTmFtZXNbaV07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjdXJzb3IgPSBhY3Rpb25DdXJzb3JzW2N1cnNvcktleV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gY3Vyc29yO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNoZWNrUmVzaXplRWRnZSAobmFtZSwgdmFsdWUsIHBhZ2UsIGVsZW1lbnQsIGludGVyYWN0YWJsZUVsZW1lbnQsIHJlY3QsIG1hcmdpbikge1xuICAgICAgICAvLyBmYWxzZSwgJycsIHVuZGVmaW5lZCwgbnVsbFxuICAgICAgICBpZiAoIXZhbHVlKSB7IHJldHVybiBmYWxzZTsgfVxuXG4gICAgICAgIC8vIHRydWUgdmFsdWUsIHVzZSBwb2ludGVyIGNvb3JkcyBhbmQgZWxlbWVudCByZWN0XG4gICAgICAgIGlmICh2YWx1ZSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgLy8gaWYgZGltZW5zaW9ucyBhcmUgbmVnYXRpdmUsIFwic3dpdGNoXCIgZWRnZXNcbiAgICAgICAgICAgIHZhciB3aWR0aCA9IGlzTnVtYmVyKHJlY3Qud2lkdGgpPyByZWN0LndpZHRoIDogcmVjdC5yaWdodCAtIHJlY3QubGVmdCxcbiAgICAgICAgICAgICAgICBoZWlnaHQgPSBpc051bWJlcihyZWN0LmhlaWdodCk/IHJlY3QuaGVpZ2h0IDogcmVjdC5ib3R0b20gLSByZWN0LnRvcDtcblxuICAgICAgICAgICAgaWYgKHdpZHRoIDwgMCkge1xuICAgICAgICAgICAgICAgIGlmICAgICAgKG5hbWUgPT09ICdsZWZ0JyApIHsgbmFtZSA9ICdyaWdodCc7IH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChuYW1lID09PSAncmlnaHQnKSB7IG5hbWUgPSAnbGVmdCcgOyB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaGVpZ2h0IDwgMCkge1xuICAgICAgICAgICAgICAgIGlmICAgICAgKG5hbWUgPT09ICd0b3AnICAgKSB7IG5hbWUgPSAnYm90dG9tJzsgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUgPT09ICdib3R0b20nKSB7IG5hbWUgPSAndG9wJyAgIDsgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAobmFtZSA9PT0gJ2xlZnQnICApIHsgcmV0dXJuIHBhZ2UueCA8ICgod2lkdGggID49IDA/IHJlY3QubGVmdDogcmVjdC5yaWdodCApICsgbWFyZ2luKTsgfVxuICAgICAgICAgICAgaWYgKG5hbWUgPT09ICd0b3AnICAgKSB7IHJldHVybiBwYWdlLnkgPCAoKGhlaWdodCA+PSAwPyByZWN0LnRvcCA6IHJlY3QuYm90dG9tKSArIG1hcmdpbik7IH1cblxuICAgICAgICAgICAgaWYgKG5hbWUgPT09ICdyaWdodCcgKSB7IHJldHVybiBwYWdlLnggPiAoKHdpZHRoICA+PSAwPyByZWN0LnJpZ2h0IDogcmVjdC5sZWZ0KSAtIG1hcmdpbik7IH1cbiAgICAgICAgICAgIGlmIChuYW1lID09PSAnYm90dG9tJykgeyByZXR1cm4gcGFnZS55ID4gKChoZWlnaHQgPj0gMD8gcmVjdC5ib3R0b206IHJlY3QudG9wICkgLSBtYXJnaW4pOyB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyB0aGUgcmVtYWluaW5nIGNoZWNrcyByZXF1aXJlIGFuIGVsZW1lbnRcbiAgICAgICAgaWYgKCFpc0VsZW1lbnQoZWxlbWVudCkpIHsgcmV0dXJuIGZhbHNlOyB9XG5cbiAgICAgICAgcmV0dXJuIGlzRWxlbWVudCh2YWx1ZSlcbiAgICAgICAgICAgICAgICAgICAgLy8gdGhlIHZhbHVlIGlzIGFuIGVsZW1lbnQgdG8gdXNlIGFzIGEgcmVzaXplIGhhbmRsZVxuICAgICAgICAgICAgICAgICAgICA/IHZhbHVlID09PSBlbGVtZW50XG4gICAgICAgICAgICAgICAgICAgIC8vIG90aGVyd2lzZSBjaGVjayBpZiBlbGVtZW50IG1hdGNoZXMgdmFsdWUgYXMgc2VsZWN0b3JcbiAgICAgICAgICAgICAgICAgICAgOiBtYXRjaGVzVXBUbyhlbGVtZW50LCB2YWx1ZSwgaW50ZXJhY3RhYmxlRWxlbWVudCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZGVmYXVsdEFjdGlvbkNoZWNrZXIgKHBvaW50ZXIsIGludGVyYWN0aW9uLCBlbGVtZW50KSB7XG4gICAgICAgIHZhciByZWN0ID0gdGhpcy5nZXRSZWN0KGVsZW1lbnQpLFxuICAgICAgICAgICAgc2hvdWxkUmVzaXplID0gZmFsc2UsXG4gICAgICAgICAgICBhY3Rpb24gPSBudWxsLFxuICAgICAgICAgICAgcmVzaXplQXhlcyA9IG51bGwsXG4gICAgICAgICAgICByZXNpemVFZGdlcyxcbiAgICAgICAgICAgIHBhZ2UgPSBleHRlbmQoe30sIGludGVyYWN0aW9uLmN1ckNvb3Jkcy5wYWdlKSxcbiAgICAgICAgICAgIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG5cbiAgICAgICAgaWYgKCFyZWN0KSB7IHJldHVybiBudWxsOyB9XG5cbiAgICAgICAgaWYgKGFjdGlvbklzRW5hYmxlZC5yZXNpemUgJiYgb3B0aW9ucy5yZXNpemUuZW5hYmxlZCkge1xuICAgICAgICAgICAgdmFyIHJlc2l6ZU9wdGlvbnMgPSBvcHRpb25zLnJlc2l6ZTtcblxuICAgICAgICAgICAgcmVzaXplRWRnZXMgPSB7XG4gICAgICAgICAgICAgICAgbGVmdDogZmFsc2UsIHJpZ2h0OiBmYWxzZSwgdG9wOiBmYWxzZSwgYm90dG9tOiBmYWxzZVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLy8gaWYgdXNpbmcgcmVzaXplLmVkZ2VzXG4gICAgICAgICAgICBpZiAoaXNPYmplY3QocmVzaXplT3B0aW9ucy5lZGdlcykpIHtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBlZGdlIGluIHJlc2l6ZUVkZ2VzKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc2l6ZUVkZ2VzW2VkZ2VdID0gY2hlY2tSZXNpemVFZGdlKGVkZ2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc2l6ZU9wdGlvbnMuZWRnZXNbZWRnZV0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludGVyYWN0aW9uLl9ldmVudFRhcmdldCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjdCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzaXplT3B0aW9ucy5tYXJnaW4gfHwgbWFyZ2luKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXNpemVFZGdlcy5sZWZ0ID0gcmVzaXplRWRnZXMubGVmdCAmJiAhcmVzaXplRWRnZXMucmlnaHQ7XG4gICAgICAgICAgICAgICAgcmVzaXplRWRnZXMudG9wICA9IHJlc2l6ZUVkZ2VzLnRvcCAgJiYgIXJlc2l6ZUVkZ2VzLmJvdHRvbTtcblxuICAgICAgICAgICAgICAgIHNob3VsZFJlc2l6ZSA9IHJlc2l6ZUVkZ2VzLmxlZnQgfHwgcmVzaXplRWRnZXMucmlnaHQgfHwgcmVzaXplRWRnZXMudG9wIHx8IHJlc2l6ZUVkZ2VzLmJvdHRvbTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhciByaWdodCAgPSBvcHRpb25zLnJlc2l6ZS5heGlzICE9PSAneScgJiYgcGFnZS54ID4gKHJlY3QucmlnaHQgIC0gbWFyZ2luKSxcbiAgICAgICAgICAgICAgICAgICAgYm90dG9tID0gb3B0aW9ucy5yZXNpemUuYXhpcyAhPT0gJ3gnICYmIHBhZ2UueSA+IChyZWN0LmJvdHRvbSAtIG1hcmdpbik7XG5cbiAgICAgICAgICAgICAgICBzaG91bGRSZXNpemUgPSByaWdodCB8fCBib3R0b207XG4gICAgICAgICAgICAgICAgcmVzaXplQXhlcyA9IChyaWdodD8gJ3gnIDogJycpICsgKGJvdHRvbT8gJ3knIDogJycpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgYWN0aW9uID0gc2hvdWxkUmVzaXplXG4gICAgICAgICAgICA/ICdyZXNpemUnXG4gICAgICAgICAgICA6IGFjdGlvbklzRW5hYmxlZC5kcmFnICYmIG9wdGlvbnMuZHJhZy5lbmFibGVkXG4gICAgICAgICAgICAgICAgPyAnZHJhZydcbiAgICAgICAgICAgICAgICA6IG51bGw7XG5cbiAgICAgICAgaWYgKGFjdGlvbklzRW5hYmxlZC5nZXN0dXJlXG4gICAgICAgICAgICAmJiBpbnRlcmFjdGlvbi5wb2ludGVySWRzLmxlbmd0aCA+PTJcbiAgICAgICAgICAgICYmICEoaW50ZXJhY3Rpb24uZHJhZ2dpbmcgfHwgaW50ZXJhY3Rpb24ucmVzaXppbmcpKSB7XG4gICAgICAgICAgICBhY3Rpb24gPSAnZ2VzdHVyZSc7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYWN0aW9uKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIG5hbWU6IGFjdGlvbixcbiAgICAgICAgICAgICAgICBheGlzOiByZXNpemVBeGVzLFxuICAgICAgICAgICAgICAgIGVkZ2VzOiByZXNpemVFZGdlc1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIC8vIENoZWNrIGlmIGFjdGlvbiBpcyBlbmFibGVkIGdsb2JhbGx5IGFuZCB0aGUgY3VycmVudCB0YXJnZXQgc3VwcG9ydHMgaXRcbiAgICAvLyBJZiBzbywgcmV0dXJuIHRoZSB2YWxpZGF0ZWQgYWN0aW9uLiBPdGhlcndpc2UsIHJldHVybiBudWxsXG4gICAgZnVuY3Rpb24gdmFsaWRhdGVBY3Rpb24gKGFjdGlvbiwgaW50ZXJhY3RhYmxlKSB7XG4gICAgICAgIGlmICghaXNPYmplY3QoYWN0aW9uKSkgeyByZXR1cm4gbnVsbDsgfVxuXG4gICAgICAgIHZhciBhY3Rpb25OYW1lID0gYWN0aW9uLm5hbWUsXG4gICAgICAgICAgICBvcHRpb25zID0gaW50ZXJhY3RhYmxlLm9wdGlvbnM7XG5cbiAgICAgICAgaWYgKCggIChhY3Rpb25OYW1lICA9PT0gJ3Jlc2l6ZScgICAmJiBvcHRpb25zLnJlc2l6ZS5lbmFibGVkIClcbiAgICAgICAgICAgIHx8IChhY3Rpb25OYW1lICAgICAgPT09ICdkcmFnJyAgICAgJiYgb3B0aW9ucy5kcmFnLmVuYWJsZWQgIClcbiAgICAgICAgICAgIHx8IChhY3Rpb25OYW1lICAgICAgPT09ICdnZXN0dXJlJyAgJiYgb3B0aW9ucy5nZXN0dXJlLmVuYWJsZWQpKVxuICAgICAgICAgICAgJiYgYWN0aW9uSXNFbmFibGVkW2FjdGlvbk5hbWVdKSB7XG5cbiAgICAgICAgICAgIGlmIChhY3Rpb25OYW1lID09PSAncmVzaXplJyB8fCBhY3Rpb25OYW1lID09PSAncmVzaXpleXgnKSB7XG4gICAgICAgICAgICAgICAgYWN0aW9uTmFtZSA9ICdyZXNpemV4eSc7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBhY3Rpb247XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgdmFyIGxpc3RlbmVycyA9IHt9LFxuICAgICAgICBpbnRlcmFjdGlvbkxpc3RlbmVycyA9IFtcbiAgICAgICAgICAgICdkcmFnU3RhcnQnLCAnZHJhZ01vdmUnLCAncmVzaXplU3RhcnQnLCAncmVzaXplTW92ZScsICdnZXN0dXJlU3RhcnQnLCAnZ2VzdHVyZU1vdmUnLFxuICAgICAgICAgICAgJ3BvaW50ZXJPdmVyJywgJ3BvaW50ZXJPdXQnLCAncG9pbnRlckhvdmVyJywgJ3NlbGVjdG9yRG93bicsXG4gICAgICAgICAgICAncG9pbnRlckRvd24nLCAncG9pbnRlck1vdmUnLCAncG9pbnRlclVwJywgJ3BvaW50ZXJDYW5jZWwnLCAncG9pbnRlckVuZCcsXG4gICAgICAgICAgICAnYWRkUG9pbnRlcicsICdyZW1vdmVQb2ludGVyJywgJ3JlY29yZFBvaW50ZXInLCAnYXV0b1Njcm9sbE1vdmUnXG4gICAgICAgIF07XG5cbiAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gaW50ZXJhY3Rpb25MaXN0ZW5lcnMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgdmFyIG5hbWUgPSBpbnRlcmFjdGlvbkxpc3RlbmVyc1tpXTtcblxuICAgICAgICBsaXN0ZW5lcnNbbmFtZV0gPSBkb09uSW50ZXJhY3Rpb25zKG5hbWUpO1xuICAgIH1cblxuICAgIC8vIGJvdW5kIHRvIHRoZSBpbnRlcmFjdGFibGUgY29udGV4dCB3aGVuIGEgRE9NIGV2ZW50XG4gICAgLy8gbGlzdGVuZXIgaXMgYWRkZWQgdG8gYSBzZWxlY3RvciBpbnRlcmFjdGFibGVcbiAgICBmdW5jdGlvbiBkZWxlZ2F0ZUxpc3RlbmVyIChldmVudCwgdXNlQ2FwdHVyZSkge1xuICAgICAgICB2YXIgZmFrZUV2ZW50ID0ge30sXG4gICAgICAgICAgICBkZWxlZ2F0ZWQgPSBkZWxlZ2F0ZWRFdmVudHNbZXZlbnQudHlwZV0sXG4gICAgICAgICAgICBldmVudFRhcmdldCA9IGdldEFjdHVhbEVsZW1lbnQoZXZlbnQucGF0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gZXZlbnQucGF0aFswXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogZXZlbnQudGFyZ2V0KSxcbiAgICAgICAgICAgIGVsZW1lbnQgPSBldmVudFRhcmdldDtcblxuICAgICAgICB1c2VDYXB0dXJlID0gdXNlQ2FwdHVyZT8gdHJ1ZTogZmFsc2U7XG5cbiAgICAgICAgLy8gZHVwbGljYXRlIHRoZSBldmVudCBzbyB0aGF0IGN1cnJlbnRUYXJnZXQgY2FuIGJlIGNoYW5nZWRcbiAgICAgICAgZm9yICh2YXIgcHJvcCBpbiBldmVudCkge1xuICAgICAgICAgICAgZmFrZUV2ZW50W3Byb3BdID0gZXZlbnRbcHJvcF07XG4gICAgICAgIH1cblxuICAgICAgICBmYWtlRXZlbnQub3JpZ2luYWxFdmVudCA9IGV2ZW50O1xuICAgICAgICBmYWtlRXZlbnQucHJldmVudERlZmF1bHQgPSBwcmV2ZW50T3JpZ2luYWxEZWZhdWx0O1xuXG4gICAgICAgIC8vIGNsaW1iIHVwIGRvY3VtZW50IHRyZWUgbG9va2luZyBmb3Igc2VsZWN0b3IgbWF0Y2hlc1xuICAgICAgICB3aGlsZSAoaXNFbGVtZW50KGVsZW1lbnQpKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRlbGVnYXRlZC5zZWxlY3RvcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICB2YXIgc2VsZWN0b3IgPSBkZWxlZ2F0ZWQuc2VsZWN0b3JzW2ldLFxuICAgICAgICAgICAgICAgICAgICBjb250ZXh0ID0gZGVsZWdhdGVkLmNvbnRleHRzW2ldO1xuXG4gICAgICAgICAgICAgICAgaWYgKG1hdGNoZXNTZWxlY3RvcihlbGVtZW50LCBzZWxlY3RvcilcbiAgICAgICAgICAgICAgICAgICAgJiYgbm9kZUNvbnRhaW5zKGNvbnRleHQsIGV2ZW50VGFyZ2V0KVxuICAgICAgICAgICAgICAgICAgICAmJiBub2RlQ29udGFpbnMoY29udGV4dCwgZWxlbWVudCkpIHtcblxuICAgICAgICAgICAgICAgICAgICB2YXIgbGlzdGVuZXJzID0gZGVsZWdhdGVkLmxpc3RlbmVyc1tpXTtcblxuICAgICAgICAgICAgICAgICAgICBmYWtlRXZlbnQuY3VycmVudFRhcmdldCA9IGVsZW1lbnQ7XG5cbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBsaXN0ZW5lcnMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsaXN0ZW5lcnNbal1bMV0gPT09IHVzZUNhcHR1cmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnNbal1bMF0oZmFrZUV2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZWxlbWVudCA9IHBhcmVudEVsZW1lbnQoZWxlbWVudCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBkZWxlZ2F0ZVVzZUNhcHR1cmUgKGV2ZW50KSB7XG4gICAgICAgIHJldHVybiBkZWxlZ2F0ZUxpc3RlbmVyLmNhbGwodGhpcywgZXZlbnQsIHRydWUpO1xuICAgIH1cblxuICAgIGludGVyYWN0YWJsZXMuaW5kZXhPZkVsZW1lbnQgPSBmdW5jdGlvbiBpbmRleE9mRWxlbWVudCAoZWxlbWVudCwgY29udGV4dCkge1xuICAgICAgICBjb250ZXh0ID0gY29udGV4dCB8fCBkb2N1bWVudDtcblxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBpbnRlcmFjdGFibGUgPSB0aGlzW2ldO1xuXG4gICAgICAgICAgICBpZiAoKGludGVyYWN0YWJsZS5zZWxlY3RvciA9PT0gZWxlbWVudFxuICAgICAgICAgICAgICAgICYmIChpbnRlcmFjdGFibGUuX2NvbnRleHQgPT09IGNvbnRleHQpKVxuICAgICAgICAgICAgICAgIHx8ICghaW50ZXJhY3RhYmxlLnNlbGVjdG9yICYmIGludGVyYWN0YWJsZS5fZWxlbWVudCA9PT0gZWxlbWVudCkpIHtcblxuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiAtMTtcbiAgICB9O1xuXG4gICAgaW50ZXJhY3RhYmxlcy5nZXQgPSBmdW5jdGlvbiBpbnRlcmFjdGFibGVHZXQgKGVsZW1lbnQsIG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbdGhpcy5pbmRleE9mRWxlbWVudChlbGVtZW50LCBvcHRpb25zICYmIG9wdGlvbnMuY29udGV4dCldO1xuICAgIH07XG5cbiAgICBpbnRlcmFjdGFibGVzLmZvckVhY2hTZWxlY3RvciA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBpbnRlcmFjdGFibGUgPSB0aGlzW2ldO1xuXG4gICAgICAgICAgICBpZiAoIWludGVyYWN0YWJsZS5zZWxlY3Rvcikge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgcmV0ID0gY2FsbGJhY2soaW50ZXJhY3RhYmxlLCBpbnRlcmFjdGFibGUuc2VsZWN0b3IsIGludGVyYWN0YWJsZS5fY29udGV4dCwgaSwgdGhpcyk7XG5cbiAgICAgICAgICAgIGlmIChyZXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgLypcXFxuICAgICAqIGludGVyYWN0XG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKlxuICAgICAqIFRoZSBtZXRob2RzIG9mIHRoaXMgdmFyaWFibGUgY2FuIGJlIHVzZWQgdG8gc2V0IGVsZW1lbnRzIGFzXG4gICAgICogaW50ZXJhY3RhYmxlcyBhbmQgYWxzbyB0byBjaGFuZ2UgdmFyaW91cyBkZWZhdWx0IHNldHRpbmdzLlxuICAgICAqXG4gICAgICogQ2FsbGluZyBpdCBhcyBhIGZ1bmN0aW9uIGFuZCBwYXNzaW5nIGFuIGVsZW1lbnQgb3IgYSB2YWxpZCBDU1Mgc2VsZWN0b3JcbiAgICAgKiBzdHJpbmcgcmV0dXJucyBhbiBJbnRlcmFjdGFibGUgb2JqZWN0IHdoaWNoIGhhcyB2YXJpb3VzIG1ldGhvZHMgdG9cbiAgICAgKiBjb25maWd1cmUgaXQuXG4gICAgICpcbiAgICAgLSBlbGVtZW50IChFbGVtZW50IHwgc3RyaW5nKSBUaGUgSFRNTCBvciBTVkcgRWxlbWVudCB0byBpbnRlcmFjdCB3aXRoIG9yIENTUyBzZWxlY3RvclxuICAgICA9IChvYmplY3QpIEFuIEBJbnRlcmFjdGFibGVcbiAgICAgKlxuICAgICA+IFVzYWdlXG4gICAgIHwgaW50ZXJhY3QoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RyYWdnYWJsZScpKS5kcmFnZ2FibGUodHJ1ZSk7XG4gICAgIHxcbiAgICAgfCB2YXIgcmVjdGFibGVzID0gaW50ZXJhY3QoJ3JlY3QnKTtcbiAgICAgfCByZWN0YWJsZXNcbiAgICAgfCAgICAgLmdlc3R1cmFibGUodHJ1ZSlcbiAgICAgfCAgICAgLm9uKCdnZXN0dXJlbW92ZScsIGZ1bmN0aW9uIChldmVudCkge1xuICAgICB8ICAgICAgICAgLy8gc29tZXRoaW5nIGNvb2wuLi5cbiAgICAgfCAgICAgfSlcbiAgICAgfCAgICAgLmF1dG9TY3JvbGwodHJ1ZSk7XG4gICAgXFwqL1xuICAgIGZ1bmN0aW9uIGludGVyYWN0IChlbGVtZW50LCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiBpbnRlcmFjdGFibGVzLmdldChlbGVtZW50LCBvcHRpb25zKSB8fCBuZXcgSW50ZXJhY3RhYmxlKGVsZW1lbnQsIG9wdGlvbnMpO1xuICAgIH1cblxuICAgIC8qXFxcbiAgICAgKiBJbnRlcmFjdGFibGVcbiAgICAgWyBwcm9wZXJ0eSBdXG4gICAgICoqXG4gICAgICogT2JqZWN0IHR5cGUgcmV0dXJuZWQgYnkgQGludGVyYWN0XG4gICAgXFwqL1xuICAgIGZ1bmN0aW9uIEludGVyYWN0YWJsZSAoZWxlbWVudCwgb3B0aW9ucykge1xuICAgICAgICB0aGlzLl9lbGVtZW50ID0gZWxlbWVudDtcbiAgICAgICAgdGhpcy5faUV2ZW50cyA9IHRoaXMuX2lFdmVudHMgfHwge307XG5cbiAgICAgICAgdmFyIF93aW5kb3c7XG5cbiAgICAgICAgaWYgKHRyeVNlbGVjdG9yKGVsZW1lbnQpKSB7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdG9yID0gZWxlbWVudDtcblxuICAgICAgICAgICAgdmFyIGNvbnRleHQgPSBvcHRpb25zICYmIG9wdGlvbnMuY29udGV4dDtcblxuICAgICAgICAgICAgX3dpbmRvdyA9IGNvbnRleHQ/IGdldFdpbmRvdyhjb250ZXh0KSA6IHdpbmRvdztcblxuICAgICAgICAgICAgaWYgKGNvbnRleHQgJiYgKF93aW5kb3cuTm9kZVxuICAgICAgICAgICAgICAgICAgICA/IGNvbnRleHQgaW5zdGFuY2VvZiBfd2luZG93Lk5vZGVcbiAgICAgICAgICAgICAgICAgICAgOiAoaXNFbGVtZW50KGNvbnRleHQpIHx8IGNvbnRleHQgPT09IF93aW5kb3cuZG9jdW1lbnQpKSkge1xuXG4gICAgICAgICAgICAgICAgdGhpcy5fY29udGV4dCA9IGNvbnRleHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBfd2luZG93ID0gZ2V0V2luZG93KGVsZW1lbnQpO1xuXG4gICAgICAgICAgICBpZiAoaXNFbGVtZW50KGVsZW1lbnQsIF93aW5kb3cpKSB7XG5cbiAgICAgICAgICAgICAgICBpZiAoc3VwcG9ydHNQb2ludGVyRXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnRzLmFkZCh0aGlzLl9lbGVtZW50LCBwRXZlbnRUeXBlcy5kb3duLCBsaXN0ZW5lcnMucG9pbnRlckRvd24gKTtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnRzLmFkZCh0aGlzLl9lbGVtZW50LCBwRXZlbnRUeXBlcy5tb3ZlLCBsaXN0ZW5lcnMucG9pbnRlckhvdmVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50cy5hZGQodGhpcy5fZWxlbWVudCwgJ21vdXNlZG93bicgLCBsaXN0ZW5lcnMucG9pbnRlckRvd24gKTtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnRzLmFkZCh0aGlzLl9lbGVtZW50LCAnbW91c2Vtb3ZlJyAsIGxpc3RlbmVycy5wb2ludGVySG92ZXIpO1xuICAgICAgICAgICAgICAgICAgICBldmVudHMuYWRkKHRoaXMuX2VsZW1lbnQsICd0b3VjaHN0YXJ0JywgbGlzdGVuZXJzLnBvaW50ZXJEb3duICk7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50cy5hZGQodGhpcy5fZWxlbWVudCwgJ3RvdWNobW92ZScgLCBsaXN0ZW5lcnMucG9pbnRlckhvdmVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9kb2MgPSBfd2luZG93LmRvY3VtZW50O1xuXG4gICAgICAgIGlmICghY29udGFpbnMoZG9jdW1lbnRzLCB0aGlzLl9kb2MpKSB7XG4gICAgICAgICAgICBsaXN0ZW5Ub0RvY3VtZW50KHRoaXMuX2RvYyk7XG4gICAgICAgIH1cblxuICAgICAgICBpbnRlcmFjdGFibGVzLnB1c2godGhpcyk7XG5cbiAgICAgICAgdGhpcy5zZXQob3B0aW9ucyk7XG4gICAgfVxuXG4gICAgSW50ZXJhY3RhYmxlLnByb3RvdHlwZSA9IHtcbiAgICAgICAgc2V0T25FdmVudHM6IGZ1bmN0aW9uIChhY3Rpb24sIHBoYXNlcykge1xuICAgICAgICAgICAgaWYgKGFjdGlvbiA9PT0gJ2Ryb3AnKSB7XG4gICAgICAgICAgICAgICAgaWYgKGlzRnVuY3Rpb24ocGhhc2VzLm9uZHJvcCkgICAgICAgICAgKSB7IHRoaXMub25kcm9wICAgICAgICAgICA9IHBoYXNlcy5vbmRyb3AgICAgICAgICAgOyB9XG4gICAgICAgICAgICAgICAgaWYgKGlzRnVuY3Rpb24ocGhhc2VzLm9uZHJvcGFjdGl2YXRlKSAgKSB7IHRoaXMub25kcm9wYWN0aXZhdGUgICA9IHBoYXNlcy5vbmRyb3BhY3RpdmF0ZSAgOyB9XG4gICAgICAgICAgICAgICAgaWYgKGlzRnVuY3Rpb24ocGhhc2VzLm9uZHJvcGRlYWN0aXZhdGUpKSB7IHRoaXMub25kcm9wZGVhY3RpdmF0ZSA9IHBoYXNlcy5vbmRyb3BkZWFjdGl2YXRlOyB9XG4gICAgICAgICAgICAgICAgaWYgKGlzRnVuY3Rpb24ocGhhc2VzLm9uZHJhZ2VudGVyKSAgICAgKSB7IHRoaXMub25kcmFnZW50ZXIgICAgICA9IHBoYXNlcy5vbmRyYWdlbnRlciAgICAgOyB9XG4gICAgICAgICAgICAgICAgaWYgKGlzRnVuY3Rpb24ocGhhc2VzLm9uZHJhZ2xlYXZlKSAgICAgKSB7IHRoaXMub25kcmFnbGVhdmUgICAgICA9IHBoYXNlcy5vbmRyYWdsZWF2ZSAgICAgOyB9XG4gICAgICAgICAgICAgICAgaWYgKGlzRnVuY3Rpb24ocGhhc2VzLm9uZHJvcG1vdmUpICAgICAgKSB7IHRoaXMub25kcm9wbW92ZSAgICAgICA9IHBoYXNlcy5vbmRyb3Btb3ZlICAgICAgOyB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhY3Rpb24gPSAnb24nICsgYWN0aW9uO1xuXG4gICAgICAgICAgICAgICAgaWYgKGlzRnVuY3Rpb24ocGhhc2VzLm9uc3RhcnQpICAgICAgICkgeyB0aGlzW2FjdGlvbiArICdzdGFydCcgICAgICAgICBdID0gcGhhc2VzLm9uc3RhcnQgICAgICAgICA7IH1cbiAgICAgICAgICAgICAgICBpZiAoaXNGdW5jdGlvbihwaGFzZXMub25tb3ZlKSAgICAgICAgKSB7IHRoaXNbYWN0aW9uICsgJ21vdmUnICAgICAgICAgIF0gPSBwaGFzZXMub25tb3ZlICAgICAgICAgIDsgfVxuICAgICAgICAgICAgICAgIGlmIChpc0Z1bmN0aW9uKHBoYXNlcy5vbmVuZCkgICAgICAgICApIHsgdGhpc1thY3Rpb24gKyAnZW5kJyAgICAgICAgICAgXSA9IHBoYXNlcy5vbmVuZCAgICAgICAgICAgOyB9XG4gICAgICAgICAgICAgICAgaWYgKGlzRnVuY3Rpb24ocGhhc2VzLm9uaW5lcnRpYXN0YXJ0KSkgeyB0aGlzW2FjdGlvbiArICdpbmVydGlhc3RhcnQnICBdID0gcGhhc2VzLm9uaW5lcnRpYXN0YXJ0ICA7IH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgLypcXFxuICAgICAgICAgKiBJbnRlcmFjdGFibGUuZHJhZ2dhYmxlXG4gICAgICAgICBbIG1ldGhvZCBdXG4gICAgICAgICAqXG4gICAgICAgICAqIEdldHMgb3Igc2V0cyB3aGV0aGVyIGRyYWcgYWN0aW9ucyBjYW4gYmUgcGVyZm9ybWVkIG9uIHRoZVxuICAgICAgICAgKiBJbnRlcmFjdGFibGVcbiAgICAgICAgICpcbiAgICAgICAgID0gKGJvb2xlYW4pIEluZGljYXRlcyBpZiB0aGlzIGNhbiBiZSB0aGUgdGFyZ2V0IG9mIGRyYWcgZXZlbnRzXG4gICAgICAgICB8IHZhciBpc0RyYWdnYWJsZSA9IGludGVyYWN0KCd1bCBsaScpLmRyYWdnYWJsZSgpO1xuICAgICAgICAgKiBvclxuICAgICAgICAgLSBvcHRpb25zIChib29sZWFuIHwgb2JqZWN0KSAjb3B0aW9uYWwgdHJ1ZS9mYWxzZSBvciBBbiBvYmplY3Qgd2l0aCBldmVudCBsaXN0ZW5lcnMgdG8gYmUgZmlyZWQgb24gZHJhZyBldmVudHMgKG9iamVjdCBtYWtlcyB0aGUgSW50ZXJhY3RhYmxlIGRyYWdnYWJsZSlcbiAgICAgICAgID0gKG9iamVjdCkgVGhpcyBJbnRlcmFjdGFibGVcbiAgICAgICAgIHwgaW50ZXJhY3QoZWxlbWVudCkuZHJhZ2dhYmxlKHtcbiAgICAgICAgIHwgICAgIG9uc3RhcnQ6IGZ1bmN0aW9uIChldmVudCkge30sXG4gICAgICAgICB8ICAgICBvbm1vdmUgOiBmdW5jdGlvbiAoZXZlbnQpIHt9LFxuICAgICAgICAgfCAgICAgb25lbmQgIDogZnVuY3Rpb24gKGV2ZW50KSB7fSxcbiAgICAgICAgIHxcbiAgICAgICAgIHwgICAgIC8vIHRoZSBheGlzIGluIHdoaWNoIHRoZSBmaXJzdCBtb3ZlbWVudCBtdXN0IGJlXG4gICAgICAgICB8ICAgICAvLyBmb3IgdGhlIGRyYWcgc2VxdWVuY2UgdG8gc3RhcnRcbiAgICAgICAgIHwgICAgIC8vICd4eScgYnkgZGVmYXVsdCAtIGFueSBkaXJlY3Rpb25cbiAgICAgICAgIHwgICAgIGF4aXM6ICd4JyB8fCAneScgfHwgJ3h5JyxcbiAgICAgICAgIHxcbiAgICAgICAgIHwgICAgIC8vIG1heCBudW1iZXIgb2YgZHJhZ3MgdGhhdCBjYW4gaGFwcGVuIGNvbmN1cnJlbnRseVxuICAgICAgICAgfCAgICAgLy8gd2l0aCBlbGVtZW50cyBvZiB0aGlzIEludGVyYWN0YWJsZS4gSW5maW5pdHkgYnkgZGVmYXVsdFxuICAgICAgICAgfCAgICAgbWF4OiBJbmZpbml0eSxcbiAgICAgICAgIHxcbiAgICAgICAgIHwgICAgIC8vIG1heCBudW1iZXIgb2YgZHJhZ3MgdGhhdCBjYW4gdGFyZ2V0IHRoZSBzYW1lIGVsZW1lbnQrSW50ZXJhY3RhYmxlXG4gICAgICAgICB8ICAgICAvLyAxIGJ5IGRlZmF1bHRcbiAgICAgICAgIHwgICAgIG1heFBlckVsZW1lbnQ6IDJcbiAgICAgICAgIHwgfSk7XG4gICAgICAgIFxcKi9cbiAgICAgICAgZHJhZ2dhYmxlOiBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgICAgICAgICAgaWYgKGlzT2JqZWN0KG9wdGlvbnMpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zLmRyYWcuZW5hYmxlZCA9IG9wdGlvbnMuZW5hYmxlZCA9PT0gZmFsc2U/IGZhbHNlOiB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0UGVyQWN0aW9uKCdkcmFnJywgb3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRPbkV2ZW50cygnZHJhZycsIG9wdGlvbnMpO1xuXG4gICAgICAgICAgICAgICAgaWYgKC9eeCR8XnkkfF54eSQvLnRlc3Qob3B0aW9ucy5heGlzKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMuZHJhZy5heGlzID0gb3B0aW9ucy5heGlzO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChvcHRpb25zLmF4aXMgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMub3B0aW9ucy5kcmFnLmF4aXM7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChpc0Jvb2wob3B0aW9ucykpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMuZHJhZy5lbmFibGVkID0gb3B0aW9ucztcblxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zLmRyYWc7XG4gICAgICAgIH0sXG5cbiAgICAgICAgc2V0UGVyQWN0aW9uOiBmdW5jdGlvbiAoYWN0aW9uLCBvcHRpb25zKSB7XG4gICAgICAgICAgICAvLyBmb3IgYWxsIHRoZSBkZWZhdWx0IHBlci1hY3Rpb24gb3B0aW9uc1xuICAgICAgICAgICAgZm9yICh2YXIgb3B0aW9uIGluIG9wdGlvbnMpIHtcbiAgICAgICAgICAgICAgICAvLyBpZiB0aGlzIG9wdGlvbiBleGlzdHMgZm9yIHRoaXMgYWN0aW9uXG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbiBpbiBkZWZhdWx0T3B0aW9uc1thY3Rpb25dKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGlmIHRoZSBvcHRpb24gaW4gdGhlIG9wdGlvbnMgYXJnIGlzIGFuIG9iamVjdCB2YWx1ZVxuICAgICAgICAgICAgICAgICAgICBpZiAoaXNPYmplY3Qob3B0aW9uc1tvcHRpb25dKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gZHVwbGljYXRlIHRoZSBvYmplY3RcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub3B0aW9uc1thY3Rpb25dW29wdGlvbl0gPSBleHRlbmQodGhpcy5vcHRpb25zW2FjdGlvbl1bb3B0aW9uXSB8fCB7fSwgb3B0aW9uc1tvcHRpb25dKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzT2JqZWN0KGRlZmF1bHRPcHRpb25zLnBlckFjdGlvbltvcHRpb25dKSAmJiAnZW5hYmxlZCcgaW4gZGVmYXVsdE9wdGlvbnMucGVyQWN0aW9uW29wdGlvbl0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnNbYWN0aW9uXVtvcHRpb25dLmVuYWJsZWQgPSBvcHRpb25zW29wdGlvbl0uZW5hYmxlZCA9PT0gZmFsc2U/IGZhbHNlIDogdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChpc0Jvb2wob3B0aW9uc1tvcHRpb25dKSAmJiBpc09iamVjdChkZWZhdWx0T3B0aW9ucy5wZXJBY3Rpb25bb3B0aW9uXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub3B0aW9uc1thY3Rpb25dW29wdGlvbl0uZW5hYmxlZCA9IG9wdGlvbnNbb3B0aW9uXTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChvcHRpb25zW29wdGlvbl0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gb3IgaWYgaXQncyBub3QgdW5kZWZpbmVkLCBkbyBhIHBsYWluIGFzc2lnbm1lbnRcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub3B0aW9uc1thY3Rpb25dW29wdGlvbl0gPSBvcHRpb25zW29wdGlvbl07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgLypcXFxuICAgICAgICAgKiBJbnRlcmFjdGFibGUuZHJvcHpvbmVcbiAgICAgICAgIFsgbWV0aG9kIF1cbiAgICAgICAgICpcbiAgICAgICAgICogUmV0dXJucyBvciBzZXRzIHdoZXRoZXIgZWxlbWVudHMgY2FuIGJlIGRyb3BwZWQgb250byB0aGlzXG4gICAgICAgICAqIEludGVyYWN0YWJsZSB0byB0cmlnZ2VyIGRyb3AgZXZlbnRzXG4gICAgICAgICAqXG4gICAgICAgICAqIERyb3B6b25lcyBjYW4gcmVjZWl2ZSB0aGUgZm9sbG93aW5nIGV2ZW50czpcbiAgICAgICAgICogIC0gYGRyb3BhY3RpdmF0ZWAgYW5kIGBkcm9wZGVhY3RpdmF0ZWAgd2hlbiBhbiBhY2NlcHRhYmxlIGRyYWcgc3RhcnRzIGFuZCBlbmRzXG4gICAgICAgICAqICAtIGBkcmFnZW50ZXJgIGFuZCBgZHJhZ2xlYXZlYCB3aGVuIGEgZHJhZ2dhYmxlIGVudGVycyBhbmQgbGVhdmVzIHRoZSBkcm9wem9uZVxuICAgICAgICAgKiAgLSBgZHJhZ21vdmVgIHdoZW4gYSBkcmFnZ2FibGUgdGhhdCBoYXMgZW50ZXJlZCB0aGUgZHJvcHpvbmUgaXMgbW92ZWRcbiAgICAgICAgICogIC0gYGRyb3BgIHdoZW4gYSBkcmFnZ2FibGUgaXMgZHJvcHBlZCBpbnRvIHRoaXMgZHJvcHpvbmVcbiAgICAgICAgICpcbiAgICAgICAgICogIFVzZSB0aGUgYGFjY2VwdGAgb3B0aW9uIHRvIGFsbG93IG9ubHkgZWxlbWVudHMgdGhhdCBtYXRjaCB0aGUgZ2l2ZW4gQ1NTIHNlbGVjdG9yIG9yIGVsZW1lbnQuXG4gICAgICAgICAqXG4gICAgICAgICAqICBVc2UgdGhlIGBvdmVybGFwYCBvcHRpb24gdG8gc2V0IGhvdyBkcm9wcyBhcmUgY2hlY2tlZCBmb3IuIFRoZSBhbGxvd2VkIHZhbHVlcyBhcmU6XG4gICAgICAgICAqICAgLSBgJ3BvaW50ZXInYCwgdGhlIHBvaW50ZXIgbXVzdCBiZSBvdmVyIHRoZSBkcm9wem9uZSAoZGVmYXVsdClcbiAgICAgICAgICogICAtIGAnY2VudGVyJ2AsIHRoZSBkcmFnZ2FibGUgZWxlbWVudCdzIGNlbnRlciBtdXN0IGJlIG92ZXIgdGhlIGRyb3B6b25lXG4gICAgICAgICAqICAgLSBhIG51bWJlciBmcm9tIDAtMSB3aGljaCBpcyB0aGUgYChpbnRlcnNlY3Rpb24gYXJlYSkgLyAoZHJhZ2dhYmxlIGFyZWEpYC5cbiAgICAgICAgICogICAgICAgZS5nLiBgMC41YCBmb3IgZHJvcCB0byBoYXBwZW4gd2hlbiBoYWxmIG9mIHRoZSBhcmVhIG9mIHRoZVxuICAgICAgICAgKiAgICAgICBkcmFnZ2FibGUgaXMgb3ZlciB0aGUgZHJvcHpvbmVcbiAgICAgICAgICpcbiAgICAgICAgIC0gb3B0aW9ucyAoYm9vbGVhbiB8IG9iamVjdCB8IG51bGwpICNvcHRpb25hbCBUaGUgbmV3IHZhbHVlIHRvIGJlIHNldC5cbiAgICAgICAgIHwgaW50ZXJhY3QoJy5kcm9wJykuZHJvcHpvbmUoe1xuICAgICAgICAgfCAgIGFjY2VwdDogJy5jYW4tZHJvcCcgfHwgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NpbmdsZS1kcm9wJyksXG4gICAgICAgICB8ICAgb3ZlcmxhcDogJ3BvaW50ZXInIHx8ICdjZW50ZXInIHx8IHplcm9Ub09uZVxuICAgICAgICAgfCB9XG4gICAgICAgICA9IChib29sZWFuIHwgb2JqZWN0KSBUaGUgY3VycmVudCBzZXR0aW5nIG9yIHRoaXMgSW50ZXJhY3RhYmxlXG4gICAgICAgIFxcKi9cbiAgICAgICAgZHJvcHpvbmU6IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgICAgICAgICBpZiAoaXNPYmplY3Qob3B0aW9ucykpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMuZHJvcC5lbmFibGVkID0gb3B0aW9ucy5lbmFibGVkID09PSBmYWxzZT8gZmFsc2U6IHRydWU7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRPbkV2ZW50cygnZHJvcCcsIG9wdGlvbnMpO1xuXG4gICAgICAgICAgICAgICAgaWYgKC9eKHBvaW50ZXJ8Y2VudGVyKSQvLnRlc3Qob3B0aW9ucy5vdmVybGFwKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMuZHJvcC5vdmVybGFwID0gb3B0aW9ucy5vdmVybGFwO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChpc051bWJlcihvcHRpb25zLm92ZXJsYXApKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5kcm9wLm92ZXJsYXAgPSBNYXRoLm1heChNYXRoLm1pbigxLCBvcHRpb25zLm92ZXJsYXApLCAwKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCdhY2NlcHQnIGluIG9wdGlvbnMpIHtcbiAgICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5kcm9wLmFjY2VwdCA9IG9wdGlvbnMuYWNjZXB0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoJ2NoZWNrZXInIGluIG9wdGlvbnMpIHtcbiAgICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5kcm9wLmNoZWNrZXIgPSBvcHRpb25zLmNoZWNrZXI7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChpc0Jvb2wob3B0aW9ucykpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMuZHJvcC5lbmFibGVkID0gb3B0aW9ucztcblxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zLmRyb3A7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZHJvcENoZWNrOiBmdW5jdGlvbiAoZHJhZ0V2ZW50LCBldmVudCwgZHJhZ2dhYmxlLCBkcmFnZ2FibGVFbGVtZW50LCBkcm9wRWxlbWVudCwgcmVjdCkge1xuICAgICAgICAgICAgdmFyIGRyb3BwZWQgPSBmYWxzZTtcblxuICAgICAgICAgICAgLy8gaWYgdGhlIGRyb3B6b25lIGhhcyBubyByZWN0IChlZy4gZGlzcGxheTogbm9uZSlcbiAgICAgICAgICAgIC8vIGNhbGwgdGhlIGN1c3RvbSBkcm9wQ2hlY2tlciBvciBqdXN0IHJldHVybiBmYWxzZVxuICAgICAgICAgICAgaWYgKCEocmVjdCA9IHJlY3QgfHwgdGhpcy5nZXRSZWN0KGRyb3BFbGVtZW50KSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gKHRoaXMub3B0aW9ucy5kcm9wLmNoZWNrZXJcbiAgICAgICAgICAgICAgICAgICAgPyB0aGlzLm9wdGlvbnMuZHJvcC5jaGVja2VyKGRyYWdFdmVudCwgZXZlbnQsIGRyb3BwZWQsIHRoaXMsIGRyb3BFbGVtZW50LCBkcmFnZ2FibGUsIGRyYWdnYWJsZUVsZW1lbnQpXG4gICAgICAgICAgICAgICAgICAgIDogZmFsc2UpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgZHJvcE92ZXJsYXAgPSB0aGlzLm9wdGlvbnMuZHJvcC5vdmVybGFwO1xuXG4gICAgICAgICAgICBpZiAoZHJvcE92ZXJsYXAgPT09ICdwb2ludGVyJykge1xuICAgICAgICAgICAgICAgIHZhciBwYWdlID0gZ2V0UGFnZVhZKGRyYWdFdmVudCksXG4gICAgICAgICAgICAgICAgICAgIG9yaWdpbiA9IGdldE9yaWdpblhZKGRyYWdnYWJsZSwgZHJhZ2dhYmxlRWxlbWVudCksXG4gICAgICAgICAgICAgICAgICAgIGhvcml6b250YWwsXG4gICAgICAgICAgICAgICAgICAgIHZlcnRpY2FsO1xuXG4gICAgICAgICAgICAgICAgcGFnZS54ICs9IG9yaWdpbi54O1xuICAgICAgICAgICAgICAgIHBhZ2UueSArPSBvcmlnaW4ueTtcblxuICAgICAgICAgICAgICAgIGhvcml6b250YWwgPSAocGFnZS54ID4gcmVjdC5sZWZ0KSAmJiAocGFnZS54IDwgcmVjdC5yaWdodCk7XG4gICAgICAgICAgICAgICAgdmVydGljYWwgICA9IChwYWdlLnkgPiByZWN0LnRvcCApICYmIChwYWdlLnkgPCByZWN0LmJvdHRvbSk7XG5cbiAgICAgICAgICAgICAgICBkcm9wcGVkID0gaG9yaXpvbnRhbCAmJiB2ZXJ0aWNhbDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIGRyYWdSZWN0ID0gZHJhZ2dhYmxlLmdldFJlY3QoZHJhZ2dhYmxlRWxlbWVudCk7XG5cbiAgICAgICAgICAgIGlmIChkcm9wT3ZlcmxhcCA9PT0gJ2NlbnRlcicpIHtcbiAgICAgICAgICAgICAgICB2YXIgY3ggPSBkcmFnUmVjdC5sZWZ0ICsgZHJhZ1JlY3Qud2lkdGggIC8gMixcbiAgICAgICAgICAgICAgICAgICAgY3kgPSBkcmFnUmVjdC50b3AgICsgZHJhZ1JlY3QuaGVpZ2h0IC8gMjtcblxuICAgICAgICAgICAgICAgIGRyb3BwZWQgPSBjeCA+PSByZWN0LmxlZnQgJiYgY3ggPD0gcmVjdC5yaWdodCAmJiBjeSA+PSByZWN0LnRvcCAmJiBjeSA8PSByZWN0LmJvdHRvbTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGlzTnVtYmVyKGRyb3BPdmVybGFwKSkge1xuICAgICAgICAgICAgICAgIHZhciBvdmVybGFwQXJlYSAgPSAoTWF0aC5tYXgoMCwgTWF0aC5taW4ocmVjdC5yaWdodCAsIGRyYWdSZWN0LnJpZ2h0ICkgLSBNYXRoLm1heChyZWN0LmxlZnQsIGRyYWdSZWN0LmxlZnQpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogTWF0aC5tYXgoMCwgTWF0aC5taW4ocmVjdC5ib3R0b20sIGRyYWdSZWN0LmJvdHRvbSkgLSBNYXRoLm1heChyZWN0LnRvcCAsIGRyYWdSZWN0LnRvcCApKSksXG4gICAgICAgICAgICAgICAgICAgIG92ZXJsYXBSYXRpbyA9IG92ZXJsYXBBcmVhIC8gKGRyYWdSZWN0LndpZHRoICogZHJhZ1JlY3QuaGVpZ2h0KTtcblxuICAgICAgICAgICAgICAgIGRyb3BwZWQgPSBvdmVybGFwUmF0aW8gPj0gZHJvcE92ZXJsYXA7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuZHJvcC5jaGVja2VyKSB7XG4gICAgICAgICAgICAgICAgZHJvcHBlZCA9IHRoaXMub3B0aW9ucy5kcm9wLmNoZWNrZXIoZHJhZ0V2ZW50LCBldmVudCwgZHJvcHBlZCwgdGhpcywgZHJvcEVsZW1lbnQsIGRyYWdnYWJsZSwgZHJhZ2dhYmxlRWxlbWVudCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBkcm9wcGVkO1xuICAgICAgICB9LFxuXG4gICAgICAgIC8qXFxcbiAgICAgICAgICogSW50ZXJhY3RhYmxlLmRyb3BDaGVja2VyXG4gICAgICAgICBbIG1ldGhvZCBdXG4gICAgICAgICAqXG4gICAgICAgICAqIERFUFJFQ0FURUQuIFVzZSBpbnRlcmFjdGFibGUuZHJvcHpvbmUoeyBjaGVja2VyOiBmdW5jdGlvbi4uLiB9KSBpbnN0ZWFkLlxuICAgICAgICAgKlxuICAgICAgICAgKiBHZXRzIG9yIHNldHMgdGhlIGZ1bmN0aW9uIHVzZWQgdG8gY2hlY2sgaWYgYSBkcmFnZ2VkIGVsZW1lbnQgaXNcbiAgICAgICAgICogb3ZlciB0aGlzIEludGVyYWN0YWJsZS5cbiAgICAgICAgICpcbiAgICAgICAgIC0gY2hlY2tlciAoZnVuY3Rpb24pICNvcHRpb25hbCBUaGUgZnVuY3Rpb24gdGhhdCB3aWxsIGJlIGNhbGxlZCB3aGVuIGNoZWNraW5nIGZvciBhIGRyb3BcbiAgICAgICAgID0gKEZ1bmN0aW9uIHwgSW50ZXJhY3RhYmxlKSBUaGUgY2hlY2tlciBmdW5jdGlvbiBvciB0aGlzIEludGVyYWN0YWJsZVxuICAgICAgICAgKlxuICAgICAgICAgKiBUaGUgY2hlY2tlciBmdW5jdGlvbiB0YWtlcyB0aGUgZm9sbG93aW5nIGFyZ3VtZW50czpcbiAgICAgICAgICpcbiAgICAgICAgIC0gZHJhZ0V2ZW50IChJbnRlcmFjdEV2ZW50KSBUaGUgcmVsYXRlZCBkcmFnbW92ZSBvciBkcmFnZW5kIGV2ZW50XG4gICAgICAgICAtIGV2ZW50IChUb3VjaEV2ZW50IHwgUG9pbnRlckV2ZW50IHwgTW91c2VFdmVudCkgVGhlIHVzZXIgbW92ZS91cC9lbmQgRXZlbnQgcmVsYXRlZCB0byB0aGUgZHJhZ0V2ZW50XG4gICAgICAgICAtIGRyb3BwZWQgKGJvb2xlYW4pIFRoZSB2YWx1ZSBmcm9tIHRoZSBkZWZhdWx0IGRyb3AgY2hlY2tlclxuICAgICAgICAgLSBkcm9wem9uZSAoSW50ZXJhY3RhYmxlKSBUaGUgZHJvcHpvbmUgaW50ZXJhY3RhYmxlXG4gICAgICAgICAtIGRyb3BFbGVtZW50IChFbGVtZW50KSBUaGUgZHJvcHpvbmUgZWxlbWVudFxuICAgICAgICAgLSBkcmFnZ2FibGUgKEludGVyYWN0YWJsZSkgVGhlIEludGVyYWN0YWJsZSBiZWluZyBkcmFnZ2VkXG4gICAgICAgICAtIGRyYWdnYWJsZUVsZW1lbnQgKEVsZW1lbnQpIFRoZSBhY3R1YWwgZWxlbWVudCB0aGF0J3MgYmVpbmcgZHJhZ2dlZFxuICAgICAgICAgKlxuICAgICAgICAgPiBVc2FnZTpcbiAgICAgICAgIHwgaW50ZXJhY3QodGFyZ2V0KVxuICAgICAgICAgfCAuZHJvcENoZWNrZXIoZnVuY3Rpb24oZHJhZ0V2ZW50LCAgICAgICAgIC8vIHJlbGF0ZWQgZHJhZ21vdmUgb3IgZHJhZ2VuZCBldmVudFxuICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQsICAgICAgICAgICAgIC8vIFRvdWNoRXZlbnQvUG9pbnRlckV2ZW50L01vdXNlRXZlbnRcbiAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgIGRyb3BwZWQsICAgICAgICAgICAvLyBib29sIHJlc3VsdCBvZiB0aGUgZGVmYXVsdCBjaGVja2VyXG4gICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICBkcm9wem9uZSwgICAgICAgICAgLy8gZHJvcHpvbmUgSW50ZXJhY3RhYmxlXG4gICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICBkcm9wRWxlbWVudCwgICAgICAgLy8gZHJvcHpvbmUgZWxlbW50XG4gICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICBkcmFnZ2FibGUsICAgICAgICAgLy8gZHJhZ2dhYmxlIEludGVyYWN0YWJsZVxuICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgZHJhZ2dhYmxlRWxlbWVudCkgey8vIGRyYWdnYWJsZSBlbGVtZW50XG4gICAgICAgICB8XG4gICAgICAgICB8ICAgcmV0dXJuIGRyb3BwZWQgJiYgZXZlbnQudGFyZ2V0Lmhhc0F0dHJpYnV0ZSgnYWxsb3ctZHJvcCcpO1xuICAgICAgICAgfCB9XG4gICAgICAgIFxcKi9cbiAgICAgICAgZHJvcENoZWNrZXI6IGZ1bmN0aW9uIChjaGVja2VyKSB7XG4gICAgICAgICAgICBpZiAoaXNGdW5jdGlvbihjaGVja2VyKSkge1xuICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5kcm9wLmNoZWNrZXIgPSBjaGVja2VyO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoY2hlY2tlciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLm9wdGlvbnMuZ2V0UmVjdDtcblxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zLmRyb3AuY2hlY2tlcjtcbiAgICAgICAgfSxcblxuICAgICAgICAvKlxcXG4gICAgICAgICAqIEludGVyYWN0YWJsZS5hY2NlcHRcbiAgICAgICAgIFsgbWV0aG9kIF1cbiAgICAgICAgICpcbiAgICAgICAgICogRGVwcmVjYXRlZC4gYWRkIGFuIGBhY2NlcHRgIHByb3BlcnR5IHRvIHRoZSBvcHRpb25zIG9iamVjdCBwYXNzZWQgdG9cbiAgICAgICAgICogQEludGVyYWN0YWJsZS5kcm9wem9uZSBpbnN0ZWFkLlxuICAgICAgICAgKlxuICAgICAgICAgKiBHZXRzIG9yIHNldHMgdGhlIEVsZW1lbnQgb3IgQ1NTIHNlbGVjdG9yIG1hdGNoIHRoYXQgdGhpc1xuICAgICAgICAgKiBJbnRlcmFjdGFibGUgYWNjZXB0cyBpZiBpdCBpcyBhIGRyb3B6b25lLlxuICAgICAgICAgKlxuICAgICAgICAgLSBuZXdWYWx1ZSAoRWxlbWVudCB8IHN0cmluZyB8IG51bGwpICNvcHRpb25hbFxuICAgICAgICAgKiBJZiBpdCBpcyBhbiBFbGVtZW50LCB0aGVuIG9ubHkgdGhhdCBlbGVtZW50IGNhbiBiZSBkcm9wcGVkIGludG8gdGhpcyBkcm9wem9uZS5cbiAgICAgICAgICogSWYgaXQgaXMgYSBzdHJpbmcsIHRoZSBlbGVtZW50IGJlaW5nIGRyYWdnZWQgbXVzdCBtYXRjaCBpdCBhcyBhIHNlbGVjdG9yLlxuICAgICAgICAgKiBJZiBpdCBpcyBudWxsLCB0aGUgYWNjZXB0IG9wdGlvbnMgaXMgY2xlYXJlZCAtIGl0IGFjY2VwdHMgYW55IGVsZW1lbnQuXG4gICAgICAgICAqXG4gICAgICAgICA9IChzdHJpbmcgfCBFbGVtZW50IHwgbnVsbCB8IEludGVyYWN0YWJsZSkgVGhlIGN1cnJlbnQgYWNjZXB0IG9wdGlvbiBpZiBnaXZlbiBgdW5kZWZpbmVkYCBvciB0aGlzIEludGVyYWN0YWJsZVxuICAgICAgICBcXCovXG4gICAgICAgIGFjY2VwdDogZnVuY3Rpb24gKG5ld1ZhbHVlKSB7XG4gICAgICAgICAgICBpZiAoaXNFbGVtZW50KG5ld1ZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5kcm9wLmFjY2VwdCA9IG5ld1ZhbHVlO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIHRlc3QgaWYgaXQgaXMgYSB2YWxpZCBDU1Mgc2VsZWN0b3JcbiAgICAgICAgICAgIGlmICh0cnlTZWxlY3RvcihuZXdWYWx1ZSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMuZHJvcC5hY2NlcHQgPSBuZXdWYWx1ZTtcblxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAobmV3VmFsdWUgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5vcHRpb25zLmRyb3AuYWNjZXB0O1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMuZHJvcC5hY2NlcHQ7XG4gICAgICAgIH0sXG5cbiAgICAgICAgLypcXFxuICAgICAgICAgKiBJbnRlcmFjdGFibGUucmVzaXphYmxlXG4gICAgICAgICBbIG1ldGhvZCBdXG4gICAgICAgICAqXG4gICAgICAgICAqIEdldHMgb3Igc2V0cyB3aGV0aGVyIHJlc2l6ZSBhY3Rpb25zIGNhbiBiZSBwZXJmb3JtZWQgb24gdGhlXG4gICAgICAgICAqIEludGVyYWN0YWJsZVxuICAgICAgICAgKlxuICAgICAgICAgPSAoYm9vbGVhbikgSW5kaWNhdGVzIGlmIHRoaXMgY2FuIGJlIHRoZSB0YXJnZXQgb2YgcmVzaXplIGVsZW1lbnRzXG4gICAgICAgICB8IHZhciBpc1Jlc2l6ZWFibGUgPSBpbnRlcmFjdCgnaW5wdXRbdHlwZT10ZXh0XScpLnJlc2l6YWJsZSgpO1xuICAgICAgICAgKiBvclxuICAgICAgICAgLSBvcHRpb25zIChib29sZWFuIHwgb2JqZWN0KSAjb3B0aW9uYWwgdHJ1ZS9mYWxzZSBvciBBbiBvYmplY3Qgd2l0aCBldmVudCBsaXN0ZW5lcnMgdG8gYmUgZmlyZWQgb24gcmVzaXplIGV2ZW50cyAob2JqZWN0IG1ha2VzIHRoZSBJbnRlcmFjdGFibGUgcmVzaXphYmxlKVxuICAgICAgICAgPSAob2JqZWN0KSBUaGlzIEludGVyYWN0YWJsZVxuICAgICAgICAgfCBpbnRlcmFjdChlbGVtZW50KS5yZXNpemFibGUoe1xuICAgICAgICAgfCAgICAgb25zdGFydDogZnVuY3Rpb24gKGV2ZW50KSB7fSxcbiAgICAgICAgIHwgICAgIG9ubW92ZSA6IGZ1bmN0aW9uIChldmVudCkge30sXG4gICAgICAgICB8ICAgICBvbmVuZCAgOiBmdW5jdGlvbiAoZXZlbnQpIHt9LFxuICAgICAgICAgfFxuICAgICAgICAgfCAgICAgZWRnZXM6IHtcbiAgICAgICAgIHwgICAgICAgdG9wICAgOiB0cnVlLCAgICAgICAvLyBVc2UgcG9pbnRlciBjb29yZHMgdG8gY2hlY2sgZm9yIHJlc2l6ZS5cbiAgICAgICAgIHwgICAgICAgbGVmdCAgOiBmYWxzZSwgICAgICAvLyBEaXNhYmxlIHJlc2l6aW5nIGZyb20gbGVmdCBlZGdlLlxuICAgICAgICAgfCAgICAgICBib3R0b206ICcucmVzaXplLXMnLC8vIFJlc2l6ZSBpZiBwb2ludGVyIHRhcmdldCBtYXRjaGVzIHNlbGVjdG9yXG4gICAgICAgICB8ICAgICAgIHJpZ2h0IDogaGFuZGxlRWwgICAgLy8gUmVzaXplIGlmIHBvaW50ZXIgdGFyZ2V0IGlzIHRoZSBnaXZlbiBFbGVtZW50XG4gICAgICAgICB8ICAgICB9LFxuICAgICAgICAgfFxuICAgICAgICAgfCAgICAgLy8gV2lkdGggYW5kIGhlaWdodCBjYW4gYmUgYWRqdXN0ZWQgaW5kZXBlbmRlbnRseS4gV2hlbiBgdHJ1ZWAsIHdpZHRoIGFuZFxuICAgICAgICAgfCAgICAgLy8gaGVpZ2h0IGFyZSBhZGp1c3RlZCBhdCBhIDE6MSByYXRpby5cbiAgICAgICAgIHwgICAgIHNxdWFyZTogZmFsc2UsXG4gICAgICAgICB8XG4gICAgICAgICB8ICAgICAvLyBXaWR0aCBhbmQgaGVpZ2h0IGNhbiBiZSBhZGp1c3RlZCBpbmRlcGVuZGVudGx5LiBXaGVuIGB0cnVlYCwgd2lkdGggYW5kXG4gICAgICAgICB8ICAgICAvLyBoZWlnaHQgbWFpbnRhaW4gdGhlIGFzcGVjdCByYXRpbyB0aGV5IGhhZCB3aGVuIHJlc2l6aW5nIHN0YXJ0ZWQuXG4gICAgICAgICB8ICAgICBwcmVzZXJ2ZUFzcGVjdFJhdGlvOiBmYWxzZSxcbiAgICAgICAgIHxcbiAgICAgICAgIHwgICAgIC8vIGEgdmFsdWUgb2YgJ25vbmUnIHdpbGwgbGltaXQgdGhlIHJlc2l6ZSByZWN0IHRvIGEgbWluaW11bSBvZiAweDBcbiAgICAgICAgIHwgICAgIC8vICduZWdhdGUnIHdpbGwgYWxsb3cgdGhlIHJlY3QgdG8gaGF2ZSBuZWdhdGl2ZSB3aWR0aC9oZWlnaHRcbiAgICAgICAgIHwgICAgIC8vICdyZXBvc2l0aW9uJyB3aWxsIGtlZXAgdGhlIHdpZHRoL2hlaWdodCBwb3NpdGl2ZSBieSBzd2FwcGluZ1xuICAgICAgICAgfCAgICAgLy8gdGhlIHRvcCBhbmQgYm90dG9tIGVkZ2VzIGFuZC9vciBzd2FwcGluZyB0aGUgbGVmdCBhbmQgcmlnaHQgZWRnZXNcbiAgICAgICAgIHwgICAgIGludmVydDogJ25vbmUnIHx8ICduZWdhdGUnIHx8ICdyZXBvc2l0aW9uJ1xuICAgICAgICAgfFxuICAgICAgICAgfCAgICAgLy8gbGltaXQgbXVsdGlwbGUgcmVzaXplcy5cbiAgICAgICAgIHwgICAgIC8vIFNlZSB0aGUgZXhwbGFuYXRpb24gaW4gdGhlIEBJbnRlcmFjdGFibGUuZHJhZ2dhYmxlIGV4YW1wbGVcbiAgICAgICAgIHwgICAgIG1heDogSW5maW5pdHksXG4gICAgICAgICB8ICAgICBtYXhQZXJFbGVtZW50OiAxLFxuICAgICAgICAgfCB9KTtcbiAgICAgICAgXFwqL1xuICAgICAgICByZXNpemFibGU6IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgICAgICAgICBpZiAoaXNPYmplY3Qob3B0aW9ucykpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMucmVzaXplLmVuYWJsZWQgPSBvcHRpb25zLmVuYWJsZWQgPT09IGZhbHNlPyBmYWxzZTogdHJ1ZTtcbiAgICAgICAgICAgICAgICB0aGlzLnNldFBlckFjdGlvbigncmVzaXplJywgb3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRPbkV2ZW50cygncmVzaXplJywgb3B0aW9ucyk7XG5cbiAgICAgICAgICAgICAgICBpZiAoL154JHxeeSR8Xnh5JC8udGVzdChvcHRpb25zLmF4aXMpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5yZXNpemUuYXhpcyA9IG9wdGlvbnMuYXhpcztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAob3B0aW9ucy5heGlzID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5yZXNpemUuYXhpcyA9IGRlZmF1bHRPcHRpb25zLnJlc2l6ZS5heGlzO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChpc0Jvb2wob3B0aW9ucy5wcmVzZXJ2ZUFzcGVjdFJhdGlvKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMucmVzaXplLnByZXNlcnZlQXNwZWN0UmF0aW8gPSBvcHRpb25zLnByZXNlcnZlQXNwZWN0UmF0aW87XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGlzQm9vbChvcHRpb25zLnNxdWFyZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zLnJlc2l6ZS5zcXVhcmUgPSBvcHRpb25zLnNxdWFyZTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpc0Jvb2wob3B0aW9ucykpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMucmVzaXplLmVuYWJsZWQgPSBvcHRpb25zO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zLnJlc2l6ZTtcbiAgICAgICAgfSxcblxuICAgICAgICAvKlxcXG4gICAgICAgICAqIEludGVyYWN0YWJsZS5zcXVhcmVSZXNpemVcbiAgICAgICAgIFsgbWV0aG9kIF1cbiAgICAgICAgICpcbiAgICAgICAgICogRGVwcmVjYXRlZC4gQWRkIGEgYHNxdWFyZTogdHJ1ZSB8fCBmYWxzZWAgcHJvcGVydHkgdG8gQEludGVyYWN0YWJsZS5yZXNpemFibGUgaW5zdGVhZFxuICAgICAgICAgKlxuICAgICAgICAgKiBHZXRzIG9yIHNldHMgd2hldGhlciByZXNpemluZyBpcyBmb3JjZWQgMToxIGFzcGVjdFxuICAgICAgICAgKlxuICAgICAgICAgPSAoYm9vbGVhbikgQ3VycmVudCBzZXR0aW5nXG4gICAgICAgICAqXG4gICAgICAgICAqIG9yXG4gICAgICAgICAqXG4gICAgICAgICAtIG5ld1ZhbHVlIChib29sZWFuKSAjb3B0aW9uYWxcbiAgICAgICAgID0gKG9iamVjdCkgdGhpcyBJbnRlcmFjdGFibGVcbiAgICAgICAgXFwqL1xuICAgICAgICBzcXVhcmVSZXNpemU6IGZ1bmN0aW9uIChuZXdWYWx1ZSkge1xuICAgICAgICAgICAgaWYgKGlzQm9vbChuZXdWYWx1ZSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMucmVzaXplLnNxdWFyZSA9IG5ld1ZhbHVlO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChuZXdWYWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLm9wdGlvbnMucmVzaXplLnNxdWFyZTtcblxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zLnJlc2l6ZS5zcXVhcmU7XG4gICAgICAgIH0sXG5cbiAgICAgICAgLypcXFxuICAgICAgICAgKiBJbnRlcmFjdGFibGUuZ2VzdHVyYWJsZVxuICAgICAgICAgWyBtZXRob2QgXVxuICAgICAgICAgKlxuICAgICAgICAgKiBHZXRzIG9yIHNldHMgd2hldGhlciBtdWx0aXRvdWNoIGdlc3R1cmVzIGNhbiBiZSBwZXJmb3JtZWQgb24gdGhlXG4gICAgICAgICAqIEludGVyYWN0YWJsZSdzIGVsZW1lbnRcbiAgICAgICAgICpcbiAgICAgICAgID0gKGJvb2xlYW4pIEluZGljYXRlcyBpZiB0aGlzIGNhbiBiZSB0aGUgdGFyZ2V0IG9mIGdlc3R1cmUgZXZlbnRzXG4gICAgICAgICB8IHZhciBpc0dlc3R1cmVhYmxlID0gaW50ZXJhY3QoZWxlbWVudCkuZ2VzdHVyYWJsZSgpO1xuICAgICAgICAgKiBvclxuICAgICAgICAgLSBvcHRpb25zIChib29sZWFuIHwgb2JqZWN0KSAjb3B0aW9uYWwgdHJ1ZS9mYWxzZSBvciBBbiBvYmplY3Qgd2l0aCBldmVudCBsaXN0ZW5lcnMgdG8gYmUgZmlyZWQgb24gZ2VzdHVyZSBldmVudHMgKG1ha2VzIHRoZSBJbnRlcmFjdGFibGUgZ2VzdHVyYWJsZSlcbiAgICAgICAgID0gKG9iamVjdCkgdGhpcyBJbnRlcmFjdGFibGVcbiAgICAgICAgIHwgaW50ZXJhY3QoZWxlbWVudCkuZ2VzdHVyYWJsZSh7XG4gICAgICAgICB8ICAgICBvbnN0YXJ0OiBmdW5jdGlvbiAoZXZlbnQpIHt9LFxuICAgICAgICAgfCAgICAgb25tb3ZlIDogZnVuY3Rpb24gKGV2ZW50KSB7fSxcbiAgICAgICAgIHwgICAgIG9uZW5kICA6IGZ1bmN0aW9uIChldmVudCkge30sXG4gICAgICAgICB8XG4gICAgICAgICB8ICAgICAvLyBsaW1pdCBtdWx0aXBsZSBnZXN0dXJlcy5cbiAgICAgICAgIHwgICAgIC8vIFNlZSB0aGUgZXhwbGFuYXRpb24gaW4gQEludGVyYWN0YWJsZS5kcmFnZ2FibGUgZXhhbXBsZVxuICAgICAgICAgfCAgICAgbWF4OiBJbmZpbml0eSxcbiAgICAgICAgIHwgICAgIG1heFBlckVsZW1lbnQ6IDEsXG4gICAgICAgICB8IH0pO1xuICAgICAgICBcXCovXG4gICAgICAgIGdlc3R1cmFibGU6IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgICAgICAgICBpZiAoaXNPYmplY3Qob3B0aW9ucykpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMuZ2VzdHVyZS5lbmFibGVkID0gb3B0aW9ucy5lbmFibGVkID09PSBmYWxzZT8gZmFsc2U6IHRydWU7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRQZXJBY3Rpb24oJ2dlc3R1cmUnLCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNldE9uRXZlbnRzKCdnZXN0dXJlJywgb3B0aW9ucyk7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGlzQm9vbChvcHRpb25zKSkge1xuICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5nZXN0dXJlLmVuYWJsZWQgPSBvcHRpb25zO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMuZ2VzdHVyZTtcbiAgICAgICAgfSxcblxuICAgICAgICAvKlxcXG4gICAgICAgICAqIEludGVyYWN0YWJsZS5hdXRvU2Nyb2xsXG4gICAgICAgICBbIG1ldGhvZCBdXG4gICAgICAgICAqKlxuICAgICAgICAgKiBEZXByZWNhdGVkLiBBZGQgYW4gYGF1dG9zY3JvbGxgIHByb3BlcnR5IHRvIHRoZSBvcHRpb25zIG9iamVjdFxuICAgICAgICAgKiBwYXNzZWQgdG8gQEludGVyYWN0YWJsZS5kcmFnZ2FibGUgb3IgQEludGVyYWN0YWJsZS5yZXNpemFibGUgaW5zdGVhZC5cbiAgICAgICAgICpcbiAgICAgICAgICogUmV0dXJucyBvciBzZXRzIHdoZXRoZXIgZHJhZ2dpbmcgYW5kIHJlc2l6aW5nIG5lYXIgdGhlIGVkZ2VzIG9mIHRoZVxuICAgICAgICAgKiB3aW5kb3cvY29udGFpbmVyIHRyaWdnZXIgYXV0b1Njcm9sbCBmb3IgdGhpcyBJbnRlcmFjdGFibGVcbiAgICAgICAgICpcbiAgICAgICAgID0gKG9iamVjdCkgT2JqZWN0IHdpdGggYXV0b1Njcm9sbCBwcm9wZXJ0aWVzXG4gICAgICAgICAqXG4gICAgICAgICAqIG9yXG4gICAgICAgICAqXG4gICAgICAgICAtIG9wdGlvbnMgKG9iamVjdCB8IGJvb2xlYW4pICNvcHRpb25hbFxuICAgICAgICAgKiBvcHRpb25zIGNhbiBiZTpcbiAgICAgICAgICogLSBhbiBvYmplY3Qgd2l0aCBtYXJnaW4sIGRpc3RhbmNlIGFuZCBpbnRlcnZhbCBwcm9wZXJ0aWVzLFxuICAgICAgICAgKiAtIHRydWUgb3IgZmFsc2UgdG8gZW5hYmxlIG9yIGRpc2FibGUgYXV0b1Njcm9sbCBvclxuICAgICAgICAgPSAoSW50ZXJhY3RhYmxlKSB0aGlzIEludGVyYWN0YWJsZVxuICAgICAgICBcXCovXG4gICAgICAgIGF1dG9TY3JvbGw6IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgICAgICAgICBpZiAoaXNPYmplY3Qob3B0aW9ucykpIHtcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gZXh0ZW5kKHsgYWN0aW9uczogWydkcmFnJywgJ3Jlc2l6ZSddfSwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChpc0Jvb2wob3B0aW9ucykpIHtcbiAgICAgICAgICAgICAgICBvcHRpb25zID0geyBhY3Rpb25zOiBbJ2RyYWcnLCAncmVzaXplJ10sIGVuYWJsZWQ6IG9wdGlvbnMgfTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2V0T3B0aW9ucygnYXV0b1Njcm9sbCcsIG9wdGlvbnMpO1xuICAgICAgICB9LFxuXG4gICAgICAgIC8qXFxcbiAgICAgICAgICogSW50ZXJhY3RhYmxlLnNuYXBcbiAgICAgICAgIFsgbWV0aG9kIF1cbiAgICAgICAgICoqXG4gICAgICAgICAqIERlcHJlY2F0ZWQuIEFkZCBhIGBzbmFwYCBwcm9wZXJ0eSB0byB0aGUgb3B0aW9ucyBvYmplY3QgcGFzc2VkXG4gICAgICAgICAqIHRvIEBJbnRlcmFjdGFibGUuZHJhZ2dhYmxlIG9yIEBJbnRlcmFjdGFibGUucmVzaXphYmxlIGluc3RlYWQuXG4gICAgICAgICAqXG4gICAgICAgICAqIFJldHVybnMgb3Igc2V0cyBpZiBhbmQgaG93IGFjdGlvbiBjb29yZGluYXRlcyBhcmUgc25hcHBlZC4gQnlcbiAgICAgICAgICogZGVmYXVsdCwgc25hcHBpbmcgaXMgcmVsYXRpdmUgdG8gdGhlIHBvaW50ZXIgY29vcmRpbmF0ZXMuIFlvdSBjYW5cbiAgICAgICAgICogY2hhbmdlIHRoaXMgYnkgc2V0dGluZyB0aGVcbiAgICAgICAgICogW2BlbGVtZW50T3JpZ2luYF0oaHR0cHM6Ly9naXRodWIuY29tL3RheWUvaW50ZXJhY3QuanMvcHVsbC83MikuXG4gICAgICAgICAqKlxuICAgICAgICAgPSAoYm9vbGVhbiB8IG9iamVjdCkgYGZhbHNlYCBpZiBzbmFwIGlzIGRpc2FibGVkOyBvYmplY3Qgd2l0aCBzbmFwIHByb3BlcnRpZXMgaWYgc25hcCBpcyBlbmFibGVkXG4gICAgICAgICAqKlxuICAgICAgICAgKiBvclxuICAgICAgICAgKipcbiAgICAgICAgIC0gb3B0aW9ucyAob2JqZWN0IHwgYm9vbGVhbiB8IG51bGwpICNvcHRpb25hbFxuICAgICAgICAgPSAoSW50ZXJhY3RhYmxlKSB0aGlzIEludGVyYWN0YWJsZVxuICAgICAgICAgPiBVc2FnZVxuICAgICAgICAgfCBpbnRlcmFjdChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjdGhpbmcnKSkuc25hcCh7XG4gICAgICAgICB8ICAgICB0YXJnZXRzOiBbXG4gICAgICAgICB8ICAgICAgICAgLy8gc25hcCB0byB0aGlzIHNwZWNpZmljIHBvaW50XG4gICAgICAgICB8ICAgICAgICAge1xuICAgICAgICAgfCAgICAgICAgICAgICB4OiAxMDAsXG4gICAgICAgICB8ICAgICAgICAgICAgIHk6IDEwMCxcbiAgICAgICAgIHwgICAgICAgICAgICAgcmFuZ2U6IDI1XG4gICAgICAgICB8ICAgICAgICAgfSxcbiAgICAgICAgIHwgICAgICAgICAvLyBnaXZlIHRoaXMgZnVuY3Rpb24gdGhlIHggYW5kIHkgcGFnZSBjb29yZHMgYW5kIHNuYXAgdG8gdGhlIG9iamVjdCByZXR1cm5lZFxuICAgICAgICAgfCAgICAgICAgIGZ1bmN0aW9uICh4LCB5KSB7XG4gICAgICAgICB8ICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICB8ICAgICAgICAgICAgICAgICB4OiB4LFxuICAgICAgICAgfCAgICAgICAgICAgICAgICAgeTogKDc1ICsgNTAgKiBNYXRoLnNpbih4ICogMC4wNCkpLFxuICAgICAgICAgfCAgICAgICAgICAgICAgICAgcmFuZ2U6IDQwXG4gICAgICAgICB8ICAgICAgICAgICAgIH07XG4gICAgICAgICB8ICAgICAgICAgfSxcbiAgICAgICAgIHwgICAgICAgICAvLyBjcmVhdGUgYSBmdW5jdGlvbiB0aGF0IHNuYXBzIHRvIGEgZ3JpZFxuICAgICAgICAgfCAgICAgICAgIGludGVyYWN0LmNyZWF0ZVNuYXBHcmlkKHtcbiAgICAgICAgIHwgICAgICAgICAgICAgeDogNTAsXG4gICAgICAgICB8ICAgICAgICAgICAgIHk6IDUwLFxuICAgICAgICAgfCAgICAgICAgICAgICByYW5nZTogMTAsICAgICAgICAgICAgICAvLyBvcHRpb25hbFxuICAgICAgICAgfCAgICAgICAgICAgICBvZmZzZXQ6IHsgeDogNSwgeTogMTAgfSAvLyBvcHRpb25hbFxuICAgICAgICAgfCAgICAgICAgIH0pXG4gICAgICAgICB8ICAgICBdLFxuICAgICAgICAgfCAgICAgLy8gZG8gbm90IHNuYXAgZHVyaW5nIG5vcm1hbCBtb3ZlbWVudC5cbiAgICAgICAgIHwgICAgIC8vIEluc3RlYWQsIHRyaWdnZXIgb25seSBvbmUgc25hcHBlZCBtb3ZlIGV2ZW50XG4gICAgICAgICB8ICAgICAvLyBpbW1lZGlhdGVseSBiZWZvcmUgdGhlIGVuZCBldmVudC5cbiAgICAgICAgIHwgICAgIGVuZE9ubHk6IHRydWUsXG4gICAgICAgICB8XG4gICAgICAgICB8ICAgICByZWxhdGl2ZVBvaW50czogW1xuICAgICAgICAgfCAgICAgICAgIHsgeDogMCwgeTogMCB9LCAgLy8gc25hcCByZWxhdGl2ZSB0byB0aGUgdG9wIGxlZnQgb2YgdGhlIGVsZW1lbnRcbiAgICAgICAgIHwgICAgICAgICB7IHg6IDEsIHk6IDEgfSwgIC8vIGFuZCBhbHNvIHRvIHRoZSBib3R0b20gcmlnaHRcbiAgICAgICAgIHwgICAgIF0sICBcbiAgICAgICAgIHxcbiAgICAgICAgIHwgICAgIC8vIG9mZnNldCB0aGUgc25hcCB0YXJnZXQgY29vcmRpbmF0ZXNcbiAgICAgICAgIHwgICAgIC8vIGNhbiBiZSBhbiBvYmplY3Qgd2l0aCB4L3kgb3IgJ3N0YXJ0Q29vcmRzJ1xuICAgICAgICAgfCAgICAgb2Zmc2V0OiB7IHg6IDUwLCB5OiA1MCB9XG4gICAgICAgICB8ICAgfVxuICAgICAgICAgfCB9KTtcbiAgICAgICAgXFwqL1xuICAgICAgICBzbmFwOiBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgICAgICAgICAgdmFyIHJldCA9IHRoaXMuc2V0T3B0aW9ucygnc25hcCcsIG9wdGlvbnMpO1xuXG4gICAgICAgICAgICBpZiAocmV0ID09PSB0aGlzKSB7IHJldHVybiB0aGlzOyB9XG5cbiAgICAgICAgICAgIHJldHVybiByZXQuZHJhZztcbiAgICAgICAgfSxcblxuICAgICAgICBzZXRPcHRpb25zOiBmdW5jdGlvbiAob3B0aW9uLCBvcHRpb25zKSB7XG4gICAgICAgICAgICB2YXIgYWN0aW9ucyA9IG9wdGlvbnMgJiYgaXNBcnJheShvcHRpb25zLmFjdGlvbnMpXG4gICAgICAgICAgICAgICAgICAgID8gb3B0aW9ucy5hY3Rpb25zXG4gICAgICAgICAgICAgICAgICAgIDogWydkcmFnJ107XG5cbiAgICAgICAgICAgIHZhciBpO1xuXG4gICAgICAgICAgICBpZiAoaXNPYmplY3Qob3B0aW9ucykgfHwgaXNCb29sKG9wdGlvbnMpKSB7XG4gICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGFjdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGFjdGlvbiA9IC9yZXNpemUvLnRlc3QoYWN0aW9uc1tpXSk/ICdyZXNpemUnIDogYWN0aW9uc1tpXTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoIWlzT2JqZWN0KHRoaXMub3B0aW9uc1thY3Rpb25dKSkgeyBjb250aW51ZTsgfVxuXG4gICAgICAgICAgICAgICAgICAgIHZhciB0aGlzT3B0aW9uID0gdGhpcy5vcHRpb25zW2FjdGlvbl1bb3B0aW9uXTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoaXNPYmplY3Qob3B0aW9ucykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuZCh0aGlzT3B0aW9uLCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNPcHRpb24uZW5hYmxlZCA9IG9wdGlvbnMuZW5hYmxlZCA9PT0gZmFsc2U/IGZhbHNlOiB0cnVlO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAob3B0aW9uID09PSAnc25hcCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpc09wdGlvbi5tb2RlID09PSAnZ3JpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpc09wdGlvbi50YXJnZXRzID0gW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJhY3QuY3JlYXRlU25hcEdyaWQoZXh0ZW5kKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQ6IHRoaXNPcHRpb24uZ3JpZE9mZnNldCB8fCB7IHg6IDAsIHk6IDAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgdGhpc09wdGlvbi5ncmlkIHx8IHt9KSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodGhpc09wdGlvbi5tb2RlID09PSAnYW5jaG9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzT3B0aW9uLnRhcmdldHMgPSB0aGlzT3B0aW9uLmFuY2hvcnM7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHRoaXNPcHRpb24ubW9kZSA9PT0gJ3BhdGgnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNPcHRpb24udGFyZ2V0cyA9IHRoaXNPcHRpb24ucGF0aHM7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCdlbGVtZW50T3JpZ2luJyBpbiBvcHRpb25zKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNPcHRpb24ucmVsYXRpdmVQb2ludHMgPSBbb3B0aW9ucy5lbGVtZW50T3JpZ2luXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoaXNCb29sKG9wdGlvbnMpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzT3B0aW9uLmVuYWJsZWQgPSBvcHRpb25zO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciByZXQgPSB7fSxcbiAgICAgICAgICAgICAgICBhbGxBY3Rpb25zID0gWydkcmFnJywgJ3Jlc2l6ZScsICdnZXN0dXJlJ107XG5cbiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBhbGxBY3Rpb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbiBpbiBkZWZhdWx0T3B0aW9uc1thbGxBY3Rpb25zW2ldXSkge1xuICAgICAgICAgICAgICAgICAgICByZXRbYWxsQWN0aW9uc1tpXV0gPSB0aGlzLm9wdGlvbnNbYWxsQWN0aW9uc1tpXV1bb3B0aW9uXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiByZXQ7XG4gICAgICAgIH0sXG5cblxuICAgICAgICAvKlxcXG4gICAgICAgICAqIEludGVyYWN0YWJsZS5pbmVydGlhXG4gICAgICAgICBbIG1ldGhvZCBdXG4gICAgICAgICAqKlxuICAgICAgICAgKiBEZXByZWNhdGVkLiBBZGQgYW4gYGluZXJ0aWFgIHByb3BlcnR5IHRvIHRoZSBvcHRpb25zIG9iamVjdCBwYXNzZWRcbiAgICAgICAgICogdG8gQEludGVyYWN0YWJsZS5kcmFnZ2FibGUgb3IgQEludGVyYWN0YWJsZS5yZXNpemFibGUgaW5zdGVhZC5cbiAgICAgICAgICpcbiAgICAgICAgICogUmV0dXJucyBvciBzZXRzIGlmIGFuZCBob3cgZXZlbnRzIGNvbnRpbnVlIHRvIHJ1biBhZnRlciB0aGUgcG9pbnRlciBpcyByZWxlYXNlZFxuICAgICAgICAgKipcbiAgICAgICAgID0gKGJvb2xlYW4gfCBvYmplY3QpIGBmYWxzZWAgaWYgaW5lcnRpYSBpcyBkaXNhYmxlZDsgYG9iamVjdGAgd2l0aCBpbmVydGlhIHByb3BlcnRpZXMgaWYgaW5lcnRpYSBpcyBlbmFibGVkXG4gICAgICAgICAqKlxuICAgICAgICAgKiBvclxuICAgICAgICAgKipcbiAgICAgICAgIC0gb3B0aW9ucyAob2JqZWN0IHwgYm9vbGVhbiB8IG51bGwpICNvcHRpb25hbFxuICAgICAgICAgPSAoSW50ZXJhY3RhYmxlKSB0aGlzIEludGVyYWN0YWJsZVxuICAgICAgICAgPiBVc2FnZVxuICAgICAgICAgfCAvLyBlbmFibGUgYW5kIHVzZSBkZWZhdWx0IHNldHRpbmdzXG4gICAgICAgICB8IGludGVyYWN0KGVsZW1lbnQpLmluZXJ0aWEodHJ1ZSk7XG4gICAgICAgICB8XG4gICAgICAgICB8IC8vIGVuYWJsZSBhbmQgdXNlIGN1c3RvbSBzZXR0aW5nc1xuICAgICAgICAgfCBpbnRlcmFjdChlbGVtZW50KS5pbmVydGlhKHtcbiAgICAgICAgIHwgICAgIC8vIHZhbHVlIGdyZWF0ZXIgdGhhbiAwXG4gICAgICAgICB8ICAgICAvLyBoaWdoIHZhbHVlcyBzbG93IHRoZSBvYmplY3QgZG93biBtb3JlIHF1aWNrbHlcbiAgICAgICAgIHwgICAgIHJlc2lzdGFuY2UgICAgIDogMTYsXG4gICAgICAgICB8XG4gICAgICAgICB8ICAgICAvLyB0aGUgbWluaW11bSBsYXVuY2ggc3BlZWQgKHBpeGVscyBwZXIgc2Vjb25kKSB0aGF0IHJlc3VsdHMgaW4gaW5lcnRpYSBzdGFydFxuICAgICAgICAgfCAgICAgbWluU3BlZWQgICAgICAgOiAyMDAsXG4gICAgICAgICB8XG4gICAgICAgICB8ICAgICAvLyBpbmVydGlhIHdpbGwgc3RvcCB3aGVuIHRoZSBvYmplY3Qgc2xvd3MgZG93biB0byB0aGlzIHNwZWVkXG4gICAgICAgICB8ICAgICBlbmRTcGVlZCAgICAgICA6IDIwLFxuICAgICAgICAgfFxuICAgICAgICAgfCAgICAgLy8gYm9vbGVhbjsgc2hvdWxkIGFjdGlvbnMgYmUgcmVzdW1lZCB3aGVuIHRoZSBwb2ludGVyIGdvZXMgZG93biBkdXJpbmcgaW5lcnRpYVxuICAgICAgICAgfCAgICAgYWxsb3dSZXN1bWUgICAgOiB0cnVlLFxuICAgICAgICAgfFxuICAgICAgICAgfCAgICAgLy8gYm9vbGVhbjsgc2hvdWxkIHRoZSBqdW1wIHdoZW4gcmVzdW1pbmcgZnJvbSBpbmVydGlhIGJlIGlnbm9yZWQgaW4gZXZlbnQuZHgvZHlcbiAgICAgICAgIHwgICAgIHplcm9SZXN1bWVEZWx0YTogZmFsc2UsXG4gICAgICAgICB8XG4gICAgICAgICB8ICAgICAvLyBpZiBzbmFwL3Jlc3RyaWN0IGFyZSBzZXQgdG8gYmUgZW5kT25seSBhbmQgaW5lcnRpYSBpcyBlbmFibGVkLCByZWxlYXNpbmdcbiAgICAgICAgIHwgICAgIC8vIHRoZSBwb2ludGVyIHdpdGhvdXQgdHJpZ2dlcmluZyBpbmVydGlhIHdpbGwgYW5pbWF0ZSBmcm9tIHRoZSByZWxlYXNlXG4gICAgICAgICB8ICAgICAvLyBwb2ludCB0byB0aGUgc25hcGVkL3Jlc3RyaWN0ZWQgcG9pbnQgaW4gdGhlIGdpdmVuIGFtb3VudCBvZiB0aW1lIChtcylcbiAgICAgICAgIHwgICAgIHNtb290aEVuZER1cmF0aW9uOiAzMDAsXG4gICAgICAgICB8XG4gICAgICAgICB8ICAgICAvLyBhbiBhcnJheSBvZiBhY3Rpb24gdHlwZXMgdGhhdCBjYW4gaGF2ZSBpbmVydGlhIChubyBnZXN0dXJlKVxuICAgICAgICAgfCAgICAgYWN0aW9ucyAgICAgICAgOiBbJ2RyYWcnLCAncmVzaXplJ11cbiAgICAgICAgIHwgfSk7XG4gICAgICAgICB8XG4gICAgICAgICB8IC8vIHJlc2V0IGN1c3RvbSBzZXR0aW5ncyBhbmQgdXNlIGFsbCBkZWZhdWx0c1xuICAgICAgICAgfCBpbnRlcmFjdChlbGVtZW50KS5pbmVydGlhKG51bGwpO1xuICAgICAgICBcXCovXG4gICAgICAgIGluZXJ0aWE6IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgICAgICAgICB2YXIgcmV0ID0gdGhpcy5zZXRPcHRpb25zKCdpbmVydGlhJywgb3B0aW9ucyk7XG5cbiAgICAgICAgICAgIGlmIChyZXQgPT09IHRoaXMpIHsgcmV0dXJuIHRoaXM7IH1cblxuICAgICAgICAgICAgcmV0dXJuIHJldC5kcmFnO1xuICAgICAgICB9LFxuXG4gICAgICAgIGdldEFjdGlvbjogZnVuY3Rpb24gKHBvaW50ZXIsIGV2ZW50LCBpbnRlcmFjdGlvbiwgZWxlbWVudCkge1xuICAgICAgICAgICAgdmFyIGFjdGlvbiA9IHRoaXMuZGVmYXVsdEFjdGlvbkNoZWNrZXIocG9pbnRlciwgaW50ZXJhY3Rpb24sIGVsZW1lbnQpO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLmFjdGlvbkNoZWNrZXIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zLmFjdGlvbkNoZWNrZXIocG9pbnRlciwgZXZlbnQsIGFjdGlvbiwgdGhpcywgZWxlbWVudCwgaW50ZXJhY3Rpb24pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gYWN0aW9uO1xuICAgICAgICB9LFxuXG4gICAgICAgIGRlZmF1bHRBY3Rpb25DaGVja2VyOiBkZWZhdWx0QWN0aW9uQ2hlY2tlcixcblxuICAgICAgICAvKlxcXG4gICAgICAgICAqIEludGVyYWN0YWJsZS5hY3Rpb25DaGVja2VyXG4gICAgICAgICBbIG1ldGhvZCBdXG4gICAgICAgICAqXG4gICAgICAgICAqIEdldHMgb3Igc2V0cyB0aGUgZnVuY3Rpb24gdXNlZCB0byBjaGVjayBhY3Rpb24gdG8gYmUgcGVyZm9ybWVkIG9uXG4gICAgICAgICAqIHBvaW50ZXJEb3duXG4gICAgICAgICAqXG4gICAgICAgICAtIGNoZWNrZXIgKGZ1bmN0aW9uIHwgbnVsbCkgI29wdGlvbmFsIEEgZnVuY3Rpb24gd2hpY2ggdGFrZXMgYSBwb2ludGVyIGV2ZW50LCBkZWZhdWx0QWN0aW9uIHN0cmluZywgaW50ZXJhY3RhYmxlLCBlbGVtZW50IGFuZCBpbnRlcmFjdGlvbiBhcyBwYXJhbWV0ZXJzIGFuZCByZXR1cm5zIGFuIG9iamVjdCB3aXRoIG5hbWUgcHJvcGVydHkgJ2RyYWcnICdyZXNpemUnIG9yICdnZXN0dXJlJyBhbmQgb3B0aW9uYWxseSBhbiBgZWRnZXNgIG9iamVjdCB3aXRoIGJvb2xlYW4gJ3RvcCcsICdsZWZ0JywgJ2JvdHRvbScgYW5kIHJpZ2h0IHByb3BzLlxuICAgICAgICAgPSAoRnVuY3Rpb24gfCBJbnRlcmFjdGFibGUpIFRoZSBjaGVja2VyIGZ1bmN0aW9uIG9yIHRoaXMgSW50ZXJhY3RhYmxlXG4gICAgICAgICAqXG4gICAgICAgICB8IGludGVyYWN0KCcucmVzaXplLWRyYWcnKVxuICAgICAgICAgfCAgIC5yZXNpemFibGUodHJ1ZSlcbiAgICAgICAgIHwgICAuZHJhZ2dhYmxlKHRydWUpXG4gICAgICAgICB8ICAgLmFjdGlvbkNoZWNrZXIoZnVuY3Rpb24gKHBvaW50ZXIsIGV2ZW50LCBhY3Rpb24sIGludGVyYWN0YWJsZSwgZWxlbWVudCwgaW50ZXJhY3Rpb24pIHtcbiAgICAgICAgIHxcbiAgICAgICAgIHwgICBpZiAoaW50ZXJhY3QubWF0Y2hlc1NlbGVjdG9yKGV2ZW50LnRhcmdldCwgJy5kcmFnLWhhbmRsZScpIHtcbiAgICAgICAgIHwgICAgIC8vIGZvcmNlIGRyYWcgd2l0aCBoYW5kbGUgdGFyZ2V0XG4gICAgICAgICB8ICAgICBhY3Rpb24ubmFtZSA9IGRyYWc7XG4gICAgICAgICB8ICAgfVxuICAgICAgICAgfCAgIGVsc2Uge1xuICAgICAgICAgfCAgICAgLy8gcmVzaXplIGZyb20gdGhlIHRvcCBhbmQgcmlnaHQgZWRnZXNcbiAgICAgICAgIHwgICAgIGFjdGlvbi5uYW1lICA9ICdyZXNpemUnO1xuICAgICAgICAgfCAgICAgYWN0aW9uLmVkZ2VzID0geyB0b3A6IHRydWUsIHJpZ2h0OiB0cnVlIH07XG4gICAgICAgICB8ICAgfVxuICAgICAgICAgfFxuICAgICAgICAgfCAgIHJldHVybiBhY3Rpb247XG4gICAgICAgICB8IH0pO1xuICAgICAgICBcXCovXG4gICAgICAgIGFjdGlvbkNoZWNrZXI6IGZ1bmN0aW9uIChjaGVja2VyKSB7XG4gICAgICAgICAgICBpZiAoaXNGdW5jdGlvbihjaGVja2VyKSkge1xuICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5hY3Rpb25DaGVja2VyID0gY2hlY2tlcjtcblxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoY2hlY2tlciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLm9wdGlvbnMuYWN0aW9uQ2hlY2tlcjtcblxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zLmFjdGlvbkNoZWNrZXI7XG4gICAgICAgIH0sXG5cbiAgICAgICAgLypcXFxuICAgICAgICAgKiBJbnRlcmFjdGFibGUuZ2V0UmVjdFxuICAgICAgICAgWyBtZXRob2QgXVxuICAgICAgICAgKlxuICAgICAgICAgKiBUaGUgZGVmYXVsdCBmdW5jdGlvbiB0byBnZXQgYW4gSW50ZXJhY3RhYmxlcyBib3VuZGluZyByZWN0LiBDYW4gYmVcbiAgICAgICAgICogb3ZlcnJpZGRlbiB1c2luZyBASW50ZXJhY3RhYmxlLnJlY3RDaGVja2VyLlxuICAgICAgICAgKlxuICAgICAgICAgLSBlbGVtZW50IChFbGVtZW50KSAjb3B0aW9uYWwgVGhlIGVsZW1lbnQgdG8gbWVhc3VyZS5cbiAgICAgICAgID0gKG9iamVjdCkgVGhlIG9iamVjdCdzIGJvdW5kaW5nIHJlY3RhbmdsZS5cbiAgICAgICAgIG8ge1xuICAgICAgICAgbyAgICAgdG9wICAgOiAwLFxuICAgICAgICAgbyAgICAgbGVmdCAgOiAwLFxuICAgICAgICAgbyAgICAgYm90dG9tOiAwLFxuICAgICAgICAgbyAgICAgcmlnaHQgOiAwLFxuICAgICAgICAgbyAgICAgd2lkdGggOiAwLFxuICAgICAgICAgbyAgICAgaGVpZ2h0OiAwXG4gICAgICAgICBvIH1cbiAgICAgICAgXFwqL1xuICAgICAgICBnZXRSZWN0OiBmdW5jdGlvbiByZWN0Q2hlY2sgKGVsZW1lbnQpIHtcbiAgICAgICAgICAgIGVsZW1lbnQgPSBlbGVtZW50IHx8IHRoaXMuX2VsZW1lbnQ7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnNlbGVjdG9yICYmICEoaXNFbGVtZW50KGVsZW1lbnQpKSkge1xuICAgICAgICAgICAgICAgIGVsZW1lbnQgPSB0aGlzLl9jb250ZXh0LnF1ZXJ5U2VsZWN0b3IodGhpcy5zZWxlY3Rvcik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBnZXRFbGVtZW50UmVjdChlbGVtZW50KTtcbiAgICAgICAgfSxcblxuICAgICAgICAvKlxcXG4gICAgICAgICAqIEludGVyYWN0YWJsZS5yZWN0Q2hlY2tlclxuICAgICAgICAgWyBtZXRob2QgXVxuICAgICAgICAgKlxuICAgICAgICAgKiBSZXR1cm5zIG9yIHNldHMgdGhlIGZ1bmN0aW9uIHVzZWQgdG8gY2FsY3VsYXRlIHRoZSBpbnRlcmFjdGFibGUnc1xuICAgICAgICAgKiBlbGVtZW50J3MgcmVjdGFuZ2xlXG4gICAgICAgICAqXG4gICAgICAgICAtIGNoZWNrZXIgKGZ1bmN0aW9uKSAjb3B0aW9uYWwgQSBmdW5jdGlvbiB3aGljaCByZXR1cm5zIHRoaXMgSW50ZXJhY3RhYmxlJ3MgYm91bmRpbmcgcmVjdGFuZ2xlLiBTZWUgQEludGVyYWN0YWJsZS5nZXRSZWN0XG4gICAgICAgICA9IChmdW5jdGlvbiB8IG9iamVjdCkgVGhlIGNoZWNrZXIgZnVuY3Rpb24gb3IgdGhpcyBJbnRlcmFjdGFibGVcbiAgICAgICAgXFwqL1xuICAgICAgICByZWN0Q2hlY2tlcjogZnVuY3Rpb24gKGNoZWNrZXIpIHtcbiAgICAgICAgICAgIGlmIChpc0Z1bmN0aW9uKGNoZWNrZXIpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5nZXRSZWN0ID0gY2hlY2tlcjtcblxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoY2hlY2tlciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLm9wdGlvbnMuZ2V0UmVjdDtcblxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRSZWN0O1xuICAgICAgICB9LFxuXG4gICAgICAgIC8qXFxcbiAgICAgICAgICogSW50ZXJhY3RhYmxlLnN0eWxlQ3Vyc29yXG4gICAgICAgICBbIG1ldGhvZCBdXG4gICAgICAgICAqXG4gICAgICAgICAqIFJldHVybnMgb3Igc2V0cyB3aGV0aGVyIHRoZSBhY3Rpb24gdGhhdCB3b3VsZCBiZSBwZXJmb3JtZWQgd2hlbiB0aGVcbiAgICAgICAgICogbW91c2Ugb24gdGhlIGVsZW1lbnQgYXJlIGNoZWNrZWQgb24gYG1vdXNlbW92ZWAgc28gdGhhdCB0aGUgY3Vyc29yXG4gICAgICAgICAqIG1heSBiZSBzdHlsZWQgYXBwcm9wcmlhdGVseVxuICAgICAgICAgKlxuICAgICAgICAgLSBuZXdWYWx1ZSAoYm9vbGVhbikgI29wdGlvbmFsXG4gICAgICAgICA9IChib29sZWFuIHwgSW50ZXJhY3RhYmxlKSBUaGUgY3VycmVudCBzZXR0aW5nIG9yIHRoaXMgSW50ZXJhY3RhYmxlXG4gICAgICAgIFxcKi9cbiAgICAgICAgc3R5bGVDdXJzb3I6IGZ1bmN0aW9uIChuZXdWYWx1ZSkge1xuICAgICAgICAgICAgaWYgKGlzQm9vbChuZXdWYWx1ZSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMuc3R5bGVDdXJzb3IgPSBuZXdWYWx1ZTtcblxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAobmV3VmFsdWUgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5vcHRpb25zLnN0eWxlQ3Vyc29yO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMuc3R5bGVDdXJzb3I7XG4gICAgICAgIH0sXG5cbiAgICAgICAgLypcXFxuICAgICAgICAgKiBJbnRlcmFjdGFibGUucHJldmVudERlZmF1bHRcbiAgICAgICAgIFsgbWV0aG9kIF1cbiAgICAgICAgICpcbiAgICAgICAgICogUmV0dXJucyBvciBzZXRzIHdoZXRoZXIgdG8gcHJldmVudCB0aGUgYnJvd3NlcidzIGRlZmF1bHQgYmVoYXZpb3VyXG4gICAgICAgICAqIGluIHJlc3BvbnNlIHRvIHBvaW50ZXIgZXZlbnRzLiBDYW4gYmUgc2V0IHRvOlxuICAgICAgICAgKiAgLSBgJ2Fsd2F5cydgIHRvIGFsd2F5cyBwcmV2ZW50XG4gICAgICAgICAqICAtIGAnbmV2ZXInYCB0byBuZXZlciBwcmV2ZW50XG4gICAgICAgICAqICAtIGAnYXV0bydgIHRvIGxldCBpbnRlcmFjdC5qcyB0cnkgdG8gZGV0ZXJtaW5lIHdoYXQgd291bGQgYmUgYmVzdFxuICAgICAgICAgKlxuICAgICAgICAgLSBuZXdWYWx1ZSAoc3RyaW5nKSAjb3B0aW9uYWwgYHRydWVgLCBgZmFsc2VgIG9yIGAnYXV0bydgXG4gICAgICAgICA9IChzdHJpbmcgfCBJbnRlcmFjdGFibGUpIFRoZSBjdXJyZW50IHNldHRpbmcgb3IgdGhpcyBJbnRlcmFjdGFibGVcbiAgICAgICAgXFwqL1xuICAgICAgICBwcmV2ZW50RGVmYXVsdDogZnVuY3Rpb24gKG5ld1ZhbHVlKSB7XG4gICAgICAgICAgICBpZiAoL14oYWx3YXlzfG5ldmVyfGF1dG8pJC8udGVzdChuZXdWYWx1ZSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMucHJldmVudERlZmF1bHQgPSBuZXdWYWx1ZTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGlzQm9vbChuZXdWYWx1ZSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMucHJldmVudERlZmF1bHQgPSBuZXdWYWx1ZT8gJ2Fsd2F5cycgOiAnbmV2ZXInO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zLnByZXZlbnREZWZhdWx0O1xuICAgICAgICB9LFxuXG4gICAgICAgIC8qXFxcbiAgICAgICAgICogSW50ZXJhY3RhYmxlLm9yaWdpblxuICAgICAgICAgWyBtZXRob2QgXVxuICAgICAgICAgKlxuICAgICAgICAgKiBHZXRzIG9yIHNldHMgdGhlIG9yaWdpbiBvZiB0aGUgSW50ZXJhY3RhYmxlJ3MgZWxlbWVudC4gIFRoZSB4IGFuZCB5XG4gICAgICAgICAqIG9mIHRoZSBvcmlnaW4gd2lsbCBiZSBzdWJ0cmFjdGVkIGZyb20gYWN0aW9uIGV2ZW50IGNvb3JkaW5hdGVzLlxuICAgICAgICAgKlxuICAgICAgICAgLSBvcmlnaW4gKG9iamVjdCB8IHN0cmluZykgI29wdGlvbmFsIEFuIG9iamVjdCBlZy4geyB4OiAwLCB5OiAwIH0gb3Igc3RyaW5nICdwYXJlbnQnLCAnc2VsZicgb3IgYW55IENTUyBzZWxlY3RvclxuICAgICAgICAgKiBPUlxuICAgICAgICAgLSBvcmlnaW4gKEVsZW1lbnQpICNvcHRpb25hbCBBbiBIVE1MIG9yIFNWRyBFbGVtZW50IHdob3NlIHJlY3Qgd2lsbCBiZSB1c2VkXG4gICAgICAgICAqKlxuICAgICAgICAgPSAob2JqZWN0KSBUaGUgY3VycmVudCBvcmlnaW4gb3IgdGhpcyBJbnRlcmFjdGFibGVcbiAgICAgICAgXFwqL1xuICAgICAgICBvcmlnaW46IGZ1bmN0aW9uIChuZXdWYWx1ZSkge1xuICAgICAgICAgICAgaWYgKHRyeVNlbGVjdG9yKG5ld1ZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5vcmlnaW4gPSBuZXdWYWx1ZTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGlzT2JqZWN0KG5ld1ZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5vcmlnaW4gPSBuZXdWYWx1ZTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucy5vcmlnaW47XG4gICAgICAgIH0sXG5cbiAgICAgICAgLypcXFxuICAgICAgICAgKiBJbnRlcmFjdGFibGUuZGVsdGFTb3VyY2VcbiAgICAgICAgIFsgbWV0aG9kIF1cbiAgICAgICAgICpcbiAgICAgICAgICogUmV0dXJucyBvciBzZXRzIHRoZSBtb3VzZSBjb29yZGluYXRlIHR5cGVzIHVzZWQgdG8gY2FsY3VsYXRlIHRoZVxuICAgICAgICAgKiBtb3ZlbWVudCBvZiB0aGUgcG9pbnRlci5cbiAgICAgICAgICpcbiAgICAgICAgIC0gbmV3VmFsdWUgKHN0cmluZykgI29wdGlvbmFsIFVzZSAnY2xpZW50JyBpZiB5b3Ugd2lsbCBiZSBzY3JvbGxpbmcgd2hpbGUgaW50ZXJhY3Rpbmc7IFVzZSAncGFnZScgaWYgeW91IHdhbnQgYXV0b1Njcm9sbCB0byB3b3JrXG4gICAgICAgICA9IChzdHJpbmcgfCBvYmplY3QpIFRoZSBjdXJyZW50IGRlbHRhU291cmNlIG9yIHRoaXMgSW50ZXJhY3RhYmxlXG4gICAgICAgIFxcKi9cbiAgICAgICAgZGVsdGFTb3VyY2U6IGZ1bmN0aW9uIChuZXdWYWx1ZSkge1xuICAgICAgICAgICAgaWYgKG5ld1ZhbHVlID09PSAncGFnZScgfHwgbmV3VmFsdWUgPT09ICdjbGllbnQnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zLmRlbHRhU291cmNlID0gbmV3VmFsdWU7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucy5kZWx0YVNvdXJjZTtcbiAgICAgICAgfSxcblxuICAgICAgICAvKlxcXG4gICAgICAgICAqIEludGVyYWN0YWJsZS5yZXN0cmljdFxuICAgICAgICAgWyBtZXRob2QgXVxuICAgICAgICAgKipcbiAgICAgICAgICogRGVwcmVjYXRlZC4gQWRkIGEgYHJlc3RyaWN0YCBwcm9wZXJ0eSB0byB0aGUgb3B0aW9ucyBvYmplY3QgcGFzc2VkIHRvXG4gICAgICAgICAqIEBJbnRlcmFjdGFibGUuZHJhZ2dhYmxlLCBASW50ZXJhY3RhYmxlLnJlc2l6YWJsZSBvciBASW50ZXJhY3RhYmxlLmdlc3R1cmFibGUgaW5zdGVhZC5cbiAgICAgICAgICpcbiAgICAgICAgICogUmV0dXJucyBvciBzZXRzIHRoZSByZWN0YW5nbGVzIHdpdGhpbiB3aGljaCBhY3Rpb25zIG9uIHRoaXNcbiAgICAgICAgICogaW50ZXJhY3RhYmxlIChhZnRlciBzbmFwIGNhbGN1bGF0aW9ucykgYXJlIHJlc3RyaWN0ZWQuIEJ5IGRlZmF1bHQsXG4gICAgICAgICAqIHJlc3RyaWN0aW5nIGlzIHJlbGF0aXZlIHRvIHRoZSBwb2ludGVyIGNvb3JkaW5hdGVzLiBZb3UgY2FuIGNoYW5nZVxuICAgICAgICAgKiB0aGlzIGJ5IHNldHRpbmcgdGhlXG4gICAgICAgICAqIFtgZWxlbWVudFJlY3RgXShodHRwczovL2dpdGh1Yi5jb20vdGF5ZS9pbnRlcmFjdC5qcy9wdWxsLzcyKS5cbiAgICAgICAgICoqXG4gICAgICAgICAtIG9wdGlvbnMgKG9iamVjdCkgI29wdGlvbmFsIGFuIG9iamVjdCB3aXRoIGtleXMgZHJhZywgcmVzaXplLCBhbmQvb3IgZ2VzdHVyZSB3aG9zZSB2YWx1ZXMgYXJlIHJlY3RzLCBFbGVtZW50cywgQ1NTIHNlbGVjdG9ycywgb3IgJ3BhcmVudCcgb3IgJ3NlbGYnXG4gICAgICAgICA9IChvYmplY3QpIFRoZSBjdXJyZW50IHJlc3RyaWN0aW9ucyBvYmplY3Qgb3IgdGhpcyBJbnRlcmFjdGFibGVcbiAgICAgICAgICoqXG4gICAgICAgICB8IGludGVyYWN0KGVsZW1lbnQpLnJlc3RyaWN0KHtcbiAgICAgICAgIHwgICAgIC8vIHRoZSByZWN0IHdpbGwgYmUgYGludGVyYWN0LmdldEVsZW1lbnRSZWN0KGVsZW1lbnQucGFyZW50Tm9kZSlgXG4gICAgICAgICB8ICAgICBkcmFnOiBlbGVtZW50LnBhcmVudE5vZGUsXG4gICAgICAgICB8XG4gICAgICAgICB8ICAgICAvLyB4IGFuZCB5IGFyZSByZWxhdGl2ZSB0byB0aGUgdGhlIGludGVyYWN0YWJsZSdzIG9yaWdpblxuICAgICAgICAgfCAgICAgcmVzaXplOiB7IHg6IDEwMCwgeTogMTAwLCB3aWR0aDogMjAwLCBoZWlnaHQ6IDIwMCB9XG4gICAgICAgICB8IH0pXG4gICAgICAgICB8XG4gICAgICAgICB8IGludGVyYWN0KCcuZHJhZ2dhYmxlJykucmVzdHJpY3Qoe1xuICAgICAgICAgfCAgICAgLy8gdGhlIHJlY3Qgd2lsbCBiZSB0aGUgc2VsZWN0ZWQgZWxlbWVudCdzIHBhcmVudFxuICAgICAgICAgfCAgICAgZHJhZzogJ3BhcmVudCcsXG4gICAgICAgICB8XG4gICAgICAgICB8ICAgICAvLyBkbyBub3QgcmVzdHJpY3QgZHVyaW5nIG5vcm1hbCBtb3ZlbWVudC5cbiAgICAgICAgIHwgICAgIC8vIEluc3RlYWQsIHRyaWdnZXIgb25seSBvbmUgcmVzdHJpY3RlZCBtb3ZlIGV2ZW50XG4gICAgICAgICB8ICAgICAvLyBpbW1lZGlhdGVseSBiZWZvcmUgdGhlIGVuZCBldmVudC5cbiAgICAgICAgIHwgICAgIGVuZE9ubHk6IHRydWUsXG4gICAgICAgICB8XG4gICAgICAgICB8ICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vdGF5ZS9pbnRlcmFjdC5qcy9wdWxsLzcyI2lzc3VlLTQxODEzNDkzXG4gICAgICAgICB8ICAgICBlbGVtZW50UmVjdDogeyB0b3A6IDAsIGxlZnQ6IDAsIGJvdHRvbTogMSwgcmlnaHQ6IDEgfVxuICAgICAgICAgfCB9KTtcbiAgICAgICAgXFwqL1xuICAgICAgICByZXN0cmljdDogZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGlmICghaXNPYmplY3Qob3B0aW9ucykpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5zZXRPcHRpb25zKCdyZXN0cmljdCcsIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgYWN0aW9ucyA9IFsnZHJhZycsICdyZXNpemUnLCAnZ2VzdHVyZSddLFxuICAgICAgICAgICAgICAgIHJldDtcblxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhY3Rpb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdmFyIGFjdGlvbiA9IGFjdGlvbnNbaV07XG5cbiAgICAgICAgICAgICAgICBpZiAoYWN0aW9uIGluIG9wdGlvbnMpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBlckFjdGlvbiA9IGV4dGVuZCh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0aW9uczogW2FjdGlvbl0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdHJpY3Rpb246IG9wdGlvbnNbYWN0aW9uXVxuICAgICAgICAgICAgICAgICAgICAgICAgfSwgb3B0aW9ucyk7XG5cbiAgICAgICAgICAgICAgICAgICAgcmV0ID0gdGhpcy5zZXRPcHRpb25zKCdyZXN0cmljdCcsIHBlckFjdGlvbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICB9LFxuXG4gICAgICAgIC8qXFxcbiAgICAgICAgICogSW50ZXJhY3RhYmxlLmNvbnRleHRcbiAgICAgICAgIFsgbWV0aG9kIF1cbiAgICAgICAgICpcbiAgICAgICAgICogR2V0cyB0aGUgc2VsZWN0b3IgY29udGV4dCBOb2RlIG9mIHRoZSBJbnRlcmFjdGFibGUuIFRoZSBkZWZhdWx0IGlzIGB3aW5kb3cuZG9jdW1lbnRgLlxuICAgICAgICAgKlxuICAgICAgICAgPSAoTm9kZSkgVGhlIGNvbnRleHQgTm9kZSBvZiB0aGlzIEludGVyYWN0YWJsZVxuICAgICAgICAgKipcbiAgICAgICAgXFwqL1xuICAgICAgICBjb250ZXh0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dDtcbiAgICAgICAgfSxcblxuICAgICAgICBfY29udGV4dDogZG9jdW1lbnQsXG5cbiAgICAgICAgLypcXFxuICAgICAgICAgKiBJbnRlcmFjdGFibGUuaWdub3JlRnJvbVxuICAgICAgICAgWyBtZXRob2QgXVxuICAgICAgICAgKlxuICAgICAgICAgKiBJZiB0aGUgdGFyZ2V0IG9mIHRoZSBgbW91c2Vkb3duYCwgYHBvaW50ZXJkb3duYCBvciBgdG91Y2hzdGFydGBcbiAgICAgICAgICogZXZlbnQgb3IgYW55IG9mIGl0J3MgcGFyZW50cyBtYXRjaCB0aGUgZ2l2ZW4gQ1NTIHNlbGVjdG9yIG9yXG4gICAgICAgICAqIEVsZW1lbnQsIG5vIGRyYWcvcmVzaXplL2dlc3R1cmUgaXMgc3RhcnRlZC5cbiAgICAgICAgICpcbiAgICAgICAgIC0gbmV3VmFsdWUgKHN0cmluZyB8IEVsZW1lbnQgfCBudWxsKSAjb3B0aW9uYWwgYSBDU1Mgc2VsZWN0b3Igc3RyaW5nLCBhbiBFbGVtZW50IG9yIGBudWxsYCB0byBub3QgaWdub3JlIGFueSBlbGVtZW50c1xuICAgICAgICAgPSAoc3RyaW5nIHwgRWxlbWVudCB8IG9iamVjdCkgVGhlIGN1cnJlbnQgaWdub3JlRnJvbSB2YWx1ZSBvciB0aGlzIEludGVyYWN0YWJsZVxuICAgICAgICAgKipcbiAgICAgICAgIHwgaW50ZXJhY3QoZWxlbWVudCwgeyBpZ25vcmVGcm9tOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbm8tYWN0aW9uJykgfSk7XG4gICAgICAgICB8IC8vIG9yXG4gICAgICAgICB8IGludGVyYWN0KGVsZW1lbnQpLmlnbm9yZUZyb20oJ2lucHV0LCB0ZXh0YXJlYSwgYScpO1xuICAgICAgICBcXCovXG4gICAgICAgIGlnbm9yZUZyb206IGZ1bmN0aW9uIChuZXdWYWx1ZSkge1xuICAgICAgICAgICAgaWYgKHRyeVNlbGVjdG9yKG5ld1ZhbHVlKSkgeyAgICAgICAgICAgIC8vIENTUyBzZWxlY3RvciB0byBtYXRjaCBldmVudC50YXJnZXRcbiAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMuaWdub3JlRnJvbSA9IG5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoaXNFbGVtZW50KG5ld1ZhbHVlKSkgeyAgICAgICAgICAgICAgLy8gc3BlY2lmaWMgZWxlbWVudFxuICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5pZ25vcmVGcm9tID0gbmV3VmFsdWU7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMuaWdub3JlRnJvbTtcbiAgICAgICAgfSxcblxuICAgICAgICAvKlxcXG4gICAgICAgICAqIEludGVyYWN0YWJsZS5hbGxvd0Zyb21cbiAgICAgICAgIFsgbWV0aG9kIF1cbiAgICAgICAgICpcbiAgICAgICAgICogQSBkcmFnL3Jlc2l6ZS9nZXN0dXJlIGlzIHN0YXJ0ZWQgb25seSBJZiB0aGUgdGFyZ2V0IG9mIHRoZVxuICAgICAgICAgKiBgbW91c2Vkb3duYCwgYHBvaW50ZXJkb3duYCBvciBgdG91Y2hzdGFydGAgZXZlbnQgb3IgYW55IG9mIGl0J3NcbiAgICAgICAgICogcGFyZW50cyBtYXRjaCB0aGUgZ2l2ZW4gQ1NTIHNlbGVjdG9yIG9yIEVsZW1lbnQuXG4gICAgICAgICAqXG4gICAgICAgICAtIG5ld1ZhbHVlIChzdHJpbmcgfCBFbGVtZW50IHwgbnVsbCkgI29wdGlvbmFsIGEgQ1NTIHNlbGVjdG9yIHN0cmluZywgYW4gRWxlbWVudCBvciBgbnVsbGAgdG8gYWxsb3cgZnJvbSBhbnkgZWxlbWVudFxuICAgICAgICAgPSAoc3RyaW5nIHwgRWxlbWVudCB8IG9iamVjdCkgVGhlIGN1cnJlbnQgYWxsb3dGcm9tIHZhbHVlIG9yIHRoaXMgSW50ZXJhY3RhYmxlXG4gICAgICAgICAqKlxuICAgICAgICAgfCBpbnRlcmFjdChlbGVtZW50LCB7IGFsbG93RnJvbTogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RyYWctaGFuZGxlJykgfSk7XG4gICAgICAgICB8IC8vIG9yXG4gICAgICAgICB8IGludGVyYWN0KGVsZW1lbnQpLmFsbG93RnJvbSgnLmhhbmRsZScpO1xuICAgICAgICBcXCovXG4gICAgICAgIGFsbG93RnJvbTogZnVuY3Rpb24gKG5ld1ZhbHVlKSB7XG4gICAgICAgICAgICBpZiAodHJ5U2VsZWN0b3IobmV3VmFsdWUpKSB7ICAgICAgICAgICAgLy8gQ1NTIHNlbGVjdG9yIHRvIG1hdGNoIGV2ZW50LnRhcmdldFxuICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5hbGxvd0Zyb20gPSBuZXdWYWx1ZTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGlzRWxlbWVudChuZXdWYWx1ZSkpIHsgICAgICAgICAgICAgIC8vIHNwZWNpZmljIGVsZW1lbnRcbiAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMuYWxsb3dGcm9tID0gbmV3VmFsdWU7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMuYWxsb3dGcm9tO1xuICAgICAgICB9LFxuXG4gICAgICAgIC8qXFxcbiAgICAgICAgICogSW50ZXJhY3RhYmxlLmVsZW1lbnRcbiAgICAgICAgIFsgbWV0aG9kIF1cbiAgICAgICAgICpcbiAgICAgICAgICogSWYgdGhpcyBpcyBub3QgYSBzZWxlY3RvciBJbnRlcmFjdGFibGUsIGl0IHJldHVybnMgdGhlIGVsZW1lbnQgdGhpc1xuICAgICAgICAgKiBpbnRlcmFjdGFibGUgcmVwcmVzZW50c1xuICAgICAgICAgKlxuICAgICAgICAgPSAoRWxlbWVudCkgSFRNTCAvIFNWRyBFbGVtZW50XG4gICAgICAgIFxcKi9cbiAgICAgICAgZWxlbWVudDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2VsZW1lbnQ7XG4gICAgICAgIH0sXG5cbiAgICAgICAgLypcXFxuICAgICAgICAgKiBJbnRlcmFjdGFibGUuZmlyZVxuICAgICAgICAgWyBtZXRob2QgXVxuICAgICAgICAgKlxuICAgICAgICAgKiBDYWxscyBsaXN0ZW5lcnMgZm9yIHRoZSBnaXZlbiBJbnRlcmFjdEV2ZW50IHR5cGUgYm91bmQgZ2xvYmFsbHlcbiAgICAgICAgICogYW5kIGRpcmVjdGx5IHRvIHRoaXMgSW50ZXJhY3RhYmxlXG4gICAgICAgICAqXG4gICAgICAgICAtIGlFdmVudCAoSW50ZXJhY3RFdmVudCkgVGhlIEludGVyYWN0RXZlbnQgb2JqZWN0IHRvIGJlIGZpcmVkIG9uIHRoaXMgSW50ZXJhY3RhYmxlXG4gICAgICAgICA9IChJbnRlcmFjdGFibGUpIHRoaXMgSW50ZXJhY3RhYmxlXG4gICAgICAgIFxcKi9cbiAgICAgICAgZmlyZTogZnVuY3Rpb24gKGlFdmVudCkge1xuICAgICAgICAgICAgaWYgKCEoaUV2ZW50ICYmIGlFdmVudC50eXBlKSB8fCAhY29udGFpbnMoZXZlbnRUeXBlcywgaUV2ZW50LnR5cGUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBsaXN0ZW5lcnMsXG4gICAgICAgICAgICAgICAgaSxcbiAgICAgICAgICAgICAgICBsZW4sXG4gICAgICAgICAgICAgICAgb25FdmVudCA9ICdvbicgKyBpRXZlbnQudHlwZSxcbiAgICAgICAgICAgICAgICBmdW5jTmFtZSA9ICcnO1xuXG4gICAgICAgICAgICAvLyBJbnRlcmFjdGFibGUjb24oKSBsaXN0ZW5lcnNcbiAgICAgICAgICAgIGlmIChpRXZlbnQudHlwZSBpbiB0aGlzLl9pRXZlbnRzKSB7XG4gICAgICAgICAgICAgICAgbGlzdGVuZXJzID0gdGhpcy5faUV2ZW50c1tpRXZlbnQudHlwZV07XG5cbiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwLCBsZW4gPSBsaXN0ZW5lcnMubGVuZ3RoOyBpIDwgbGVuICYmICFpRXZlbnQuaW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgZnVuY05hbWUgPSBsaXN0ZW5lcnNbaV0ubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXJzW2ldKGlFdmVudCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBpbnRlcmFjdGFibGUub25ldmVudCBsaXN0ZW5lclxuICAgICAgICAgICAgaWYgKGlzRnVuY3Rpb24odGhpc1tvbkV2ZW50XSkpIHtcbiAgICAgICAgICAgICAgICBmdW5jTmFtZSA9IHRoaXNbb25FdmVudF0ubmFtZTtcbiAgICAgICAgICAgICAgICB0aGlzW29uRXZlbnRdKGlFdmVudCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGludGVyYWN0Lm9uKCkgbGlzdGVuZXJzXG4gICAgICAgICAgICBpZiAoaUV2ZW50LnR5cGUgaW4gZ2xvYmFsRXZlbnRzICYmIChsaXN0ZW5lcnMgPSBnbG9iYWxFdmVudHNbaUV2ZW50LnR5cGVdKSkgIHtcblxuICAgICAgICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGxpc3RlbmVycy5sZW5ndGg7IGkgPCBsZW4gJiYgIWlFdmVudC5pbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQ7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBmdW5jTmFtZSA9IGxpc3RlbmVyc1tpXS5uYW1lO1xuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnNbaV0oaUV2ZW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9LFxuXG4gICAgICAgIC8qXFxcbiAgICAgICAgICogSW50ZXJhY3RhYmxlLm9uXG4gICAgICAgICBbIG1ldGhvZCBdXG4gICAgICAgICAqXG4gICAgICAgICAqIEJpbmRzIGEgbGlzdGVuZXIgZm9yIGFuIEludGVyYWN0RXZlbnQgb3IgRE9NIGV2ZW50LlxuICAgICAgICAgKlxuICAgICAgICAgLSBldmVudFR5cGUgIChzdHJpbmcgfCBhcnJheSB8IG9iamVjdCkgVGhlIHR5cGVzIG9mIGV2ZW50cyB0byBsaXN0ZW4gZm9yXG4gICAgICAgICAtIGxpc3RlbmVyICAgKGZ1bmN0aW9uKSBUaGUgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIG9uIHRoZSBnaXZlbiBldmVudChzKVxuICAgICAgICAgLSB1c2VDYXB0dXJlIChib29sZWFuKSAjb3B0aW9uYWwgdXNlQ2FwdHVyZSBmbGFnIGZvciBhZGRFdmVudExpc3RlbmVyXG4gICAgICAgICA9IChvYmplY3QpIFRoaXMgSW50ZXJhY3RhYmxlXG4gICAgICAgIFxcKi9cbiAgICAgICAgb246IGZ1bmN0aW9uIChldmVudFR5cGUsIGxpc3RlbmVyLCB1c2VDYXB0dXJlKSB7XG4gICAgICAgICAgICB2YXIgaTtcblxuICAgICAgICAgICAgaWYgKGlzU3RyaW5nKGV2ZW50VHlwZSkgJiYgZXZlbnRUeXBlLnNlYXJjaCgnICcpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIGV2ZW50VHlwZSA9IGV2ZW50VHlwZS50cmltKCkuc3BsaXQoLyArLyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChpc0FycmF5KGV2ZW50VHlwZSkpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgZXZlbnRUeXBlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMub24oZXZlbnRUeXBlW2ldLCBsaXN0ZW5lciwgdXNlQ2FwdHVyZSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChpc09iamVjdChldmVudFR5cGUpKSB7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgcHJvcCBpbiBldmVudFR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vbihwcm9wLCBldmVudFR5cGVbcHJvcF0sIGxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGV2ZW50VHlwZSA9PT0gJ3doZWVsJykge1xuICAgICAgICAgICAgICAgIGV2ZW50VHlwZSA9IHdoZWVsRXZlbnQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGNvbnZlcnQgdG8gYm9vbGVhblxuICAgICAgICAgICAgdXNlQ2FwdHVyZSA9IHVzZUNhcHR1cmU/IHRydWU6IGZhbHNlO1xuXG4gICAgICAgICAgICBpZiAoY29udGFpbnMoZXZlbnRUeXBlcywgZXZlbnRUeXBlKSkge1xuICAgICAgICAgICAgICAgIC8vIGlmIHRoaXMgdHlwZSBvZiBldmVudCB3YXMgbmV2ZXIgYm91bmQgdG8gdGhpcyBJbnRlcmFjdGFibGVcbiAgICAgICAgICAgICAgICBpZiAoIShldmVudFR5cGUgaW4gdGhpcy5faUV2ZW50cykpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5faUV2ZW50c1tldmVudFR5cGVdID0gW2xpc3RlbmVyXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2lFdmVudHNbZXZlbnRUeXBlXS5wdXNoKGxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBkZWxlZ2F0ZWQgZXZlbnQgZm9yIHNlbGVjdG9yXG4gICAgICAgICAgICBlbHNlIGlmICh0aGlzLnNlbGVjdG9yKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFkZWxlZ2F0ZWRFdmVudHNbZXZlbnRUeXBlXSkge1xuICAgICAgICAgICAgICAgICAgICBkZWxlZ2F0ZWRFdmVudHNbZXZlbnRUeXBlXSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdG9yczogW10sXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0cyA6IFtdLFxuICAgICAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXJzOiBbXVxuICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIGFkZCBkZWxlZ2F0ZSBsaXN0ZW5lciBmdW5jdGlvbnNcbiAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGRvY3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLmFkZChkb2N1bWVudHNbaV0sIGV2ZW50VHlwZSwgZGVsZWdhdGVMaXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudHMuYWRkKGRvY3VtZW50c1tpXSwgZXZlbnRUeXBlLCBkZWxlZ2F0ZVVzZUNhcHR1cmUsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdmFyIGRlbGVnYXRlZCA9IGRlbGVnYXRlZEV2ZW50c1tldmVudFR5cGVdLFxuICAgICAgICAgICAgICAgICAgICBpbmRleDtcblxuICAgICAgICAgICAgICAgIGZvciAoaW5kZXggPSBkZWxlZ2F0ZWQuc2VsZWN0b3JzLmxlbmd0aCAtIDE7IGluZGV4ID49IDA7IGluZGV4LS0pIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRlbGVnYXRlZC5zZWxlY3RvcnNbaW5kZXhdID09PSB0aGlzLnNlbGVjdG9yXG4gICAgICAgICAgICAgICAgICAgICAgICAmJiBkZWxlZ2F0ZWQuY29udGV4dHNbaW5kZXhdID09PSB0aGlzLl9jb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChpbmRleCA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgaW5kZXggPSBkZWxlZ2F0ZWQuc2VsZWN0b3JzLmxlbmd0aDtcblxuICAgICAgICAgICAgICAgICAgICBkZWxlZ2F0ZWQuc2VsZWN0b3JzLnB1c2godGhpcy5zZWxlY3Rvcik7XG4gICAgICAgICAgICAgICAgICAgIGRlbGVnYXRlZC5jb250ZXh0cyAucHVzaCh0aGlzLl9jb250ZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgZGVsZWdhdGVkLmxpc3RlbmVycy5wdXNoKFtdKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBrZWVwIGxpc3RlbmVyIGFuZCB1c2VDYXB0dXJlIGZsYWdcbiAgICAgICAgICAgICAgICBkZWxlZ2F0ZWQubGlzdGVuZXJzW2luZGV4XS5wdXNoKFtsaXN0ZW5lciwgdXNlQ2FwdHVyZV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZXZlbnRzLmFkZCh0aGlzLl9lbGVtZW50LCBldmVudFR5cGUsIGxpc3RlbmVyLCB1c2VDYXB0dXJlKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgLypcXFxuICAgICAgICAgKiBJbnRlcmFjdGFibGUub2ZmXG4gICAgICAgICBbIG1ldGhvZCBdXG4gICAgICAgICAqXG4gICAgICAgICAqIFJlbW92ZXMgYW4gSW50ZXJhY3RFdmVudCBvciBET00gZXZlbnQgbGlzdGVuZXJcbiAgICAgICAgICpcbiAgICAgICAgIC0gZXZlbnRUeXBlICAoc3RyaW5nIHwgYXJyYXkgfCBvYmplY3QpIFRoZSB0eXBlcyBvZiBldmVudHMgdGhhdCB3ZXJlIGxpc3RlbmVkIGZvclxuICAgICAgICAgLSBsaXN0ZW5lciAgIChmdW5jdGlvbikgVGhlIGxpc3RlbmVyIGZ1bmN0aW9uIHRvIGJlIHJlbW92ZWRcbiAgICAgICAgIC0gdXNlQ2FwdHVyZSAoYm9vbGVhbikgI29wdGlvbmFsIHVzZUNhcHR1cmUgZmxhZyBmb3IgcmVtb3ZlRXZlbnRMaXN0ZW5lclxuICAgICAgICAgPSAob2JqZWN0KSBUaGlzIEludGVyYWN0YWJsZVxuICAgICAgICBcXCovXG4gICAgICAgIG9mZjogZnVuY3Rpb24gKGV2ZW50VHlwZSwgbGlzdGVuZXIsIHVzZUNhcHR1cmUpIHtcbiAgICAgICAgICAgIHZhciBpO1xuXG4gICAgICAgICAgICBpZiAoaXNTdHJpbmcoZXZlbnRUeXBlKSAmJiBldmVudFR5cGUuc2VhcmNoKCcgJykgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgZXZlbnRUeXBlID0gZXZlbnRUeXBlLnRyaW0oKS5zcGxpdCgvICsvKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGlzQXJyYXkoZXZlbnRUeXBlKSkge1xuICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBldmVudFR5cGUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vZmYoZXZlbnRUeXBlW2ldLCBsaXN0ZW5lciwgdXNlQ2FwdHVyZSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChpc09iamVjdChldmVudFR5cGUpKSB7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgcHJvcCBpbiBldmVudFR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vZmYocHJvcCwgZXZlbnRUeXBlW3Byb3BdLCBsaXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBldmVudExpc3QsXG4gICAgICAgICAgICAgICAgaW5kZXggPSAtMTtcblxuICAgICAgICAgICAgLy8gY29udmVydCB0byBib29sZWFuXG4gICAgICAgICAgICB1c2VDYXB0dXJlID0gdXNlQ2FwdHVyZT8gdHJ1ZTogZmFsc2U7XG5cbiAgICAgICAgICAgIGlmIChldmVudFR5cGUgPT09ICd3aGVlbCcpIHtcbiAgICAgICAgICAgICAgICBldmVudFR5cGUgPSB3aGVlbEV2ZW50O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBpZiBpdCBpcyBhbiBhY3Rpb24gZXZlbnQgdHlwZVxuICAgICAgICAgICAgaWYgKGNvbnRhaW5zKGV2ZW50VHlwZXMsIGV2ZW50VHlwZSkpIHtcbiAgICAgICAgICAgICAgICBldmVudExpc3QgPSB0aGlzLl9pRXZlbnRzW2V2ZW50VHlwZV07XG5cbiAgICAgICAgICAgICAgICBpZiAoZXZlbnRMaXN0ICYmIChpbmRleCA9IGluZGV4T2YoZXZlbnRMaXN0LCBsaXN0ZW5lcikpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9pRXZlbnRzW2V2ZW50VHlwZV0uc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBkZWxlZ2F0ZWQgZXZlbnRcbiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuc2VsZWN0b3IpIHtcbiAgICAgICAgICAgICAgICB2YXIgZGVsZWdhdGVkID0gZGVsZWdhdGVkRXZlbnRzW2V2ZW50VHlwZV0sXG4gICAgICAgICAgICAgICAgICAgIG1hdGNoRm91bmQgPSBmYWxzZTtcblxuICAgICAgICAgICAgICAgIGlmICghZGVsZWdhdGVkKSB7IHJldHVybiB0aGlzOyB9XG5cbiAgICAgICAgICAgICAgICAvLyBjb3VudCBmcm9tIGxhc3QgaW5kZXggb2YgZGVsZWdhdGVkIHRvIDBcbiAgICAgICAgICAgICAgICBmb3IgKGluZGV4ID0gZGVsZWdhdGVkLnNlbGVjdG9ycy5sZW5ndGggLSAxOyBpbmRleCA+PSAwOyBpbmRleC0tKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGxvb2sgZm9yIG1hdGNoaW5nIHNlbGVjdG9yIGFuZCBjb250ZXh0IE5vZGVcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRlbGVnYXRlZC5zZWxlY3RvcnNbaW5kZXhdID09PSB0aGlzLnNlbGVjdG9yXG4gICAgICAgICAgICAgICAgICAgICAgICAmJiBkZWxlZ2F0ZWQuY29udGV4dHNbaW5kZXhdID09PSB0aGlzLl9jb250ZXh0KSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBsaXN0ZW5lcnMgPSBkZWxlZ2F0ZWQubGlzdGVuZXJzW2luZGV4XTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gZWFjaCBpdGVtIG9mIHRoZSBsaXN0ZW5lcnMgYXJyYXkgaXMgYW4gYXJyYXk6IFtmdW5jdGlvbiwgdXNlQ2FwdHVyZUZsYWddXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSBsaXN0ZW5lcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZm4gPSBsaXN0ZW5lcnNbaV1bMF0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVzZUNhcCA9IGxpc3RlbmVyc1tpXVsxXTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIGlmIHRoZSBsaXN0ZW5lciBmdW5jdGlvbnMgYW5kIHVzZUNhcHR1cmUgZmxhZ3MgbWF0Y2hcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZm4gPT09IGxpc3RlbmVyICYmIHVzZUNhcCA9PT0gdXNlQ2FwdHVyZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyByZW1vdmUgdGhlIGxpc3RlbmVyIGZyb20gdGhlIGFycmF5IG9mIGxpc3RlbmVyc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnMuc3BsaWNlKGksIDEpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIGFsbCBsaXN0ZW5lcnMgZm9yIHRoaXMgaW50ZXJhY3RhYmxlIGhhdmUgYmVlbiByZW1vdmVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlbW92ZSB0aGUgaW50ZXJhY3RhYmxlIGZyb20gdGhlIGRlbGVnYXRlZCBhcnJheXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFsaXN0ZW5lcnMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxlZ2F0ZWQuc2VsZWN0b3JzLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxlZ2F0ZWQuY29udGV4dHMgLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxlZ2F0ZWQubGlzdGVuZXJzLnNwbGljZShpbmRleCwgMSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlbW92ZSBkZWxlZ2F0ZSBmdW5jdGlvbiBmcm9tIGNvbnRleHRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5yZW1vdmUodGhpcy5fY29udGV4dCwgZXZlbnRUeXBlLCBkZWxlZ2F0ZUxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5yZW1vdmUodGhpcy5fY29udGV4dCwgZXZlbnRUeXBlLCBkZWxlZ2F0ZVVzZUNhcHR1cmUsIHRydWUpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyByZW1vdmUgdGhlIGFycmF5cyBpZiB0aGV5IGFyZSBlbXB0eVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFkZWxlZ2F0ZWQuc2VsZWN0b3JzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGVnYXRlZEV2ZW50c1tldmVudFR5cGVdID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG9ubHkgcmVtb3ZlIG9uZSBsaXN0ZW5lclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRjaEZvdW5kID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobWF0Y2hGb3VuZCkgeyBicmVhazsgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gcmVtb3ZlIGxpc3RlbmVyIGZyb20gdGhpcyBJbnRlcmF0YWJsZSdzIGVsZW1lbnRcbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGV2ZW50cy5yZW1vdmUodGhpcy5fZWxlbWVudCwgZXZlbnRUeXBlLCBsaXN0ZW5lciwgdXNlQ2FwdHVyZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9LFxuXG4gICAgICAgIC8qXFxcbiAgICAgICAgICogSW50ZXJhY3RhYmxlLnNldFxuICAgICAgICAgWyBtZXRob2QgXVxuICAgICAgICAgKlxuICAgICAgICAgKiBSZXNldCB0aGUgb3B0aW9ucyBvZiB0aGlzIEludGVyYWN0YWJsZVxuICAgICAgICAgLSBvcHRpb25zIChvYmplY3QpIFRoZSBuZXcgc2V0dGluZ3MgdG8gYXBwbHlcbiAgICAgICAgID0gKG9iamVjdCkgVGhpcyBJbnRlcmFjdGFibGVcbiAgICAgICAgXFwqL1xuICAgICAgICBzZXQ6IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgICAgICAgICBpZiAoIWlzT2JqZWN0KG9wdGlvbnMpKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLm9wdGlvbnMgPSBleHRlbmQoe30sIGRlZmF1bHRPcHRpb25zLmJhc2UpO1xuXG4gICAgICAgICAgICB2YXIgaSxcbiAgICAgICAgICAgICAgICBhY3Rpb25zID0gWydkcmFnJywgJ2Ryb3AnLCAncmVzaXplJywgJ2dlc3R1cmUnXSxcbiAgICAgICAgICAgICAgICBtZXRob2RzID0gWydkcmFnZ2FibGUnLCAnZHJvcHpvbmUnLCAncmVzaXphYmxlJywgJ2dlc3R1cmFibGUnXSxcbiAgICAgICAgICAgICAgICBwZXJBY3Rpb25zID0gZXh0ZW5kKGV4dGVuZCh7fSwgZGVmYXVsdE9wdGlvbnMucGVyQWN0aW9uKSwgb3B0aW9uc1thY3Rpb25dIHx8IHt9KTtcblxuICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGFjdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICB2YXIgYWN0aW9uID0gYWN0aW9uc1tpXTtcblxuICAgICAgICAgICAgICAgIHRoaXMub3B0aW9uc1thY3Rpb25dID0gZXh0ZW5kKHt9LCBkZWZhdWx0T3B0aW9uc1thY3Rpb25dKTtcblxuICAgICAgICAgICAgICAgIHRoaXMuc2V0UGVyQWN0aW9uKGFjdGlvbiwgcGVyQWN0aW9ucyk7XG5cbiAgICAgICAgICAgICAgICB0aGlzW21ldGhvZHNbaV1dKG9wdGlvbnNbYWN0aW9uXSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBzZXR0aW5ncyA9IFtcbiAgICAgICAgICAgICAgICAgICAgJ2FjY2VwdCcsICdhY3Rpb25DaGVja2VyJywgJ2FsbG93RnJvbScsICdkZWx0YVNvdXJjZScsXG4gICAgICAgICAgICAgICAgICAgICdkcm9wQ2hlY2tlcicsICdpZ25vcmVGcm9tJywgJ29yaWdpbicsICdwcmV2ZW50RGVmYXVsdCcsXG4gICAgICAgICAgICAgICAgICAgICdyZWN0Q2hlY2tlcicsICdzdHlsZUN1cnNvcidcbiAgICAgICAgICAgICAgICBdO1xuXG4gICAgICAgICAgICBmb3IgKGkgPSAwLCBsZW4gPSBzZXR0aW5ncy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgICAgIHZhciBzZXR0aW5nID0gc2V0dGluZ3NbaV07XG5cbiAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnNbc2V0dGluZ10gPSBkZWZhdWx0T3B0aW9ucy5iYXNlW3NldHRpbmddO1xuXG4gICAgICAgICAgICAgICAgaWYgKHNldHRpbmcgaW4gb3B0aW9ucykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzW3NldHRpbmddKG9wdGlvbnNbc2V0dGluZ10pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgLypcXFxuICAgICAgICAgKiBJbnRlcmFjdGFibGUudW5zZXRcbiAgICAgICAgIFsgbWV0aG9kIF1cbiAgICAgICAgICpcbiAgICAgICAgICogUmVtb3ZlIHRoaXMgaW50ZXJhY3RhYmxlIGZyb20gdGhlIGxpc3Qgb2YgaW50ZXJhY3RhYmxlcyBhbmQgcmVtb3ZlXG4gICAgICAgICAqIGl0J3MgZHJhZywgZHJvcCwgcmVzaXplIGFuZCBnZXN0dXJlIGNhcGFiaWxpdGllc1xuICAgICAgICAgKlxuICAgICAgICAgPSAob2JqZWN0KSBAaW50ZXJhY3RcbiAgICAgICAgXFwqL1xuICAgICAgICB1bnNldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXZlbnRzLnJlbW92ZSh0aGlzLl9lbGVtZW50LCAnYWxsJyk7XG5cbiAgICAgICAgICAgIGlmICghaXNTdHJpbmcodGhpcy5zZWxlY3RvcikpIHtcbiAgICAgICAgICAgICAgICBldmVudHMucmVtb3ZlKHRoaXMsICdhbGwnKTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLnN0eWxlQ3Vyc29yKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2VsZW1lbnQuc3R5bGUuY3Vyc29yID0gJyc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gcmVtb3ZlIGRlbGVnYXRlZCBldmVudHNcbiAgICAgICAgICAgICAgICBmb3IgKHZhciB0eXBlIGluIGRlbGVnYXRlZEV2ZW50cykge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZGVsZWdhdGVkID0gZGVsZWdhdGVkRXZlbnRzW3R5cGVdO1xuXG4gICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGVsZWdhdGVkLnNlbGVjdG9ycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRlbGVnYXRlZC5zZWxlY3RvcnNbaV0gPT09IHRoaXMuc2VsZWN0b3JcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBkZWxlZ2F0ZWQuY29udGV4dHNbaV0gPT09IHRoaXMuX2NvbnRleHQpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGVnYXRlZC5zZWxlY3RvcnMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGVnYXRlZC5jb250ZXh0cyAuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGVnYXRlZC5saXN0ZW5lcnMuc3BsaWNlKGksIDEpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSBhcnJheXMgaWYgdGhleSBhcmUgZW1wdHlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWRlbGVnYXRlZC5zZWxlY3RvcnMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGVnYXRlZEV2ZW50c1t0eXBlXSA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudHMucmVtb3ZlKHRoaXMuX2NvbnRleHQsIHR5cGUsIGRlbGVnYXRlTGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLnJlbW92ZSh0aGlzLl9jb250ZXh0LCB0eXBlLCBkZWxlZ2F0ZVVzZUNhcHR1cmUsIHRydWUpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5kcm9wem9uZShmYWxzZSk7XG5cbiAgICAgICAgICAgIGludGVyYWN0YWJsZXMuc3BsaWNlKGluZGV4T2YoaW50ZXJhY3RhYmxlcywgdGhpcyksIDEpO1xuXG4gICAgICAgICAgICByZXR1cm4gaW50ZXJhY3Q7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gd2Fybk9uY2UgKG1ldGhvZCwgbWVzc2FnZSkge1xuICAgICAgICB2YXIgd2FybmVkID0gZmFsc2U7XG5cbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmICghd2FybmVkKSB7XG4gICAgICAgICAgICAgICAgd2luZG93LmNvbnNvbGUud2FybihtZXNzYWdlKTtcbiAgICAgICAgICAgICAgICB3YXJuZWQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gbWV0aG9kLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5zbmFwID0gd2Fybk9uY2UoSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5zbmFwLFxuICAgICAgICAgJ0ludGVyYWN0YWJsZSNzbmFwIGlzIGRlcHJlY2F0ZWQuIFNlZSB0aGUgbmV3IGRvY3VtZW50YXRpb24gZm9yIHNuYXBwaW5nIGF0IGh0dHA6Ly9pbnRlcmFjdGpzLmlvL2RvY3Mvc25hcHBpbmcnKTtcbiAgICBJbnRlcmFjdGFibGUucHJvdG90eXBlLnJlc3RyaWN0ID0gd2Fybk9uY2UoSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5yZXN0cmljdCxcbiAgICAgICAgICdJbnRlcmFjdGFibGUjcmVzdHJpY3QgaXMgZGVwcmVjYXRlZC4gU2VlIHRoZSBuZXcgZG9jdW1lbnRhdGlvbiBmb3IgcmVzdGljdGluZyBhdCBodHRwOi8vaW50ZXJhY3Rqcy5pby9kb2NzL3Jlc3RyaWN0aW9uJyk7XG4gICAgSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5pbmVydGlhID0gd2Fybk9uY2UoSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5pbmVydGlhLFxuICAgICAgICAgJ0ludGVyYWN0YWJsZSNpbmVydGlhIGlzIGRlcHJlY2F0ZWQuIFNlZSB0aGUgbmV3IGRvY3VtZW50YXRpb24gZm9yIGluZXJ0aWEgYXQgaHR0cDovL2ludGVyYWN0anMuaW8vZG9jcy9pbmVydGlhJyk7XG4gICAgSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5hdXRvU2Nyb2xsID0gd2Fybk9uY2UoSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5hdXRvU2Nyb2xsLFxuICAgICAgICAgJ0ludGVyYWN0YWJsZSNhdXRvU2Nyb2xsIGlzIGRlcHJlY2F0ZWQuIFNlZSB0aGUgbmV3IGRvY3VtZW50YXRpb24gZm9yIGF1dG9TY3JvbGwgYXQgaHR0cDovL2ludGVyYWN0anMuaW8vZG9jcy8jYXV0b3Njcm9sbCcpO1xuICAgIEludGVyYWN0YWJsZS5wcm90b3R5cGUuc3F1YXJlUmVzaXplID0gd2Fybk9uY2UoSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5zcXVhcmVSZXNpemUsXG4gICAgICAgICAnSW50ZXJhY3RhYmxlI3NxdWFyZVJlc2l6ZSBpcyBkZXByZWNhdGVkLiBTZWUgaHR0cDovL2ludGVyYWN0anMuaW8vZG9jcy8jcmVzaXplLXNxdWFyZScpO1xuXG4gICAgSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5hY2NlcHQgPSB3YXJuT25jZShJbnRlcmFjdGFibGUucHJvdG90eXBlLmFjY2VwdCxcbiAgICAgICAgICdJbnRlcmFjdGFibGUjYWNjZXB0IGlzIGRlcHJlY2F0ZWQuIHVzZSBJbnRlcmFjdGFibGUjZHJvcHpvbmUoeyBhY2NlcHQ6IHRhcmdldCB9KSBpbnN0ZWFkJyk7XG4gICAgSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5kcm9wQ2hlY2tlciA9IHdhcm5PbmNlKEludGVyYWN0YWJsZS5wcm90b3R5cGUuZHJvcENoZWNrZXIsXG4gICAgICAgICAnSW50ZXJhY3RhYmxlI2Ryb3BDaGVja2VyIGlzIGRlcHJlY2F0ZWQuIHVzZSBJbnRlcmFjdGFibGUjZHJvcHpvbmUoeyBkcm9wQ2hlY2tlcjogY2hlY2tlckZ1bmN0aW9uIH0pIGluc3RlYWQnKTtcbiAgICBJbnRlcmFjdGFibGUucHJvdG90eXBlLmNvbnRleHQgPSB3YXJuT25jZShJbnRlcmFjdGFibGUucHJvdG90eXBlLmNvbnRleHQsXG4gICAgICAgICAnSW50ZXJhY3RhYmxlI2NvbnRleHQgYXMgYSBtZXRob2QgaXMgZGVwcmVjYXRlZC4gSXQgd2lsbCBzb29uIGJlIGEgRE9NIE5vZGUgaW5zdGVhZCcpO1xuXG4gICAgLypcXFxuICAgICAqIGludGVyYWN0LmlzU2V0XG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKlxuICAgICAqIENoZWNrIGlmIGFuIGVsZW1lbnQgaGFzIGJlZW4gc2V0XG4gICAgIC0gZWxlbWVudCAoRWxlbWVudCkgVGhlIEVsZW1lbnQgYmVpbmcgc2VhcmNoZWQgZm9yXG4gICAgID0gKGJvb2xlYW4pIEluZGljYXRlcyBpZiB0aGUgZWxlbWVudCBvciBDU1Mgc2VsZWN0b3Igd2FzIHByZXZpb3VzbHkgcGFzc2VkIHRvIGludGVyYWN0XG4gICAgXFwqL1xuICAgIGludGVyYWN0LmlzU2V0ID0gZnVuY3Rpb24oZWxlbWVudCwgb3B0aW9ucykge1xuICAgICAgICByZXR1cm4gaW50ZXJhY3RhYmxlcy5pbmRleE9mRWxlbWVudChlbGVtZW50LCBvcHRpb25zICYmIG9wdGlvbnMuY29udGV4dCkgIT09IC0xO1xuICAgIH07XG5cbiAgICAvKlxcXG4gICAgICogaW50ZXJhY3Qub25cbiAgICAgWyBtZXRob2QgXVxuICAgICAqXG4gICAgICogQWRkcyBhIGdsb2JhbCBsaXN0ZW5lciBmb3IgYW4gSW50ZXJhY3RFdmVudCBvciBhZGRzIGEgRE9NIGV2ZW50IHRvXG4gICAgICogYGRvY3VtZW50YFxuICAgICAqXG4gICAgIC0gdHlwZSAgICAgICAoc3RyaW5nIHwgYXJyYXkgfCBvYmplY3QpIFRoZSB0eXBlcyBvZiBldmVudHMgdG8gbGlzdGVuIGZvclxuICAgICAtIGxpc3RlbmVyICAgKGZ1bmN0aW9uKSBUaGUgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIG9uIHRoZSBnaXZlbiBldmVudChzKVxuICAgICAtIHVzZUNhcHR1cmUgKGJvb2xlYW4pICNvcHRpb25hbCB1c2VDYXB0dXJlIGZsYWcgZm9yIGFkZEV2ZW50TGlzdGVuZXJcbiAgICAgPSAob2JqZWN0KSBpbnRlcmFjdFxuICAgIFxcKi9cbiAgICBpbnRlcmFjdC5vbiA9IGZ1bmN0aW9uICh0eXBlLCBsaXN0ZW5lciwgdXNlQ2FwdHVyZSkge1xuICAgICAgICBpZiAoaXNTdHJpbmcodHlwZSkgJiYgdHlwZS5zZWFyY2goJyAnKSAhPT0gLTEpIHtcbiAgICAgICAgICAgIHR5cGUgPSB0eXBlLnRyaW0oKS5zcGxpdCgvICsvKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc0FycmF5KHR5cGUpKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHR5cGUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpbnRlcmFjdC5vbih0eXBlW2ldLCBsaXN0ZW5lciwgdXNlQ2FwdHVyZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBpbnRlcmFjdDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc09iamVjdCh0eXBlKSkge1xuICAgICAgICAgICAgZm9yICh2YXIgcHJvcCBpbiB0eXBlKSB7XG4gICAgICAgICAgICAgICAgaW50ZXJhY3Qub24ocHJvcCwgdHlwZVtwcm9wXSwgbGlzdGVuZXIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gaW50ZXJhY3Q7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBpZiBpdCBpcyBhbiBJbnRlcmFjdEV2ZW50IHR5cGUsIGFkZCBsaXN0ZW5lciB0byBnbG9iYWxFdmVudHNcbiAgICAgICAgaWYgKGNvbnRhaW5zKGV2ZW50VHlwZXMsIHR5cGUpKSB7XG4gICAgICAgICAgICAvLyBpZiB0aGlzIHR5cGUgb2YgZXZlbnQgd2FzIG5ldmVyIGJvdW5kXG4gICAgICAgICAgICBpZiAoIWdsb2JhbEV2ZW50c1t0eXBlXSkge1xuICAgICAgICAgICAgICAgIGdsb2JhbEV2ZW50c1t0eXBlXSA9IFtsaXN0ZW5lcl07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBnbG9iYWxFdmVudHNbdHlwZV0ucHVzaChsaXN0ZW5lcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gSWYgbm9uIEludGVyYWN0RXZlbnQgdHlwZSwgYWRkRXZlbnRMaXN0ZW5lciB0byBkb2N1bWVudFxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGV2ZW50cy5hZGQoZG9jdW1lbnQsIHR5cGUsIGxpc3RlbmVyLCB1c2VDYXB0dXJlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBpbnRlcmFjdDtcbiAgICB9O1xuXG4gICAgLypcXFxuICAgICAqIGludGVyYWN0Lm9mZlxuICAgICBbIG1ldGhvZCBdXG4gICAgICpcbiAgICAgKiBSZW1vdmVzIGEgZ2xvYmFsIEludGVyYWN0RXZlbnQgbGlzdGVuZXIgb3IgRE9NIGV2ZW50IGZyb20gYGRvY3VtZW50YFxuICAgICAqXG4gICAgIC0gdHlwZSAgICAgICAoc3RyaW5nIHwgYXJyYXkgfCBvYmplY3QpIFRoZSB0eXBlcyBvZiBldmVudHMgdGhhdCB3ZXJlIGxpc3RlbmVkIGZvclxuICAgICAtIGxpc3RlbmVyICAgKGZ1bmN0aW9uKSBUaGUgbGlzdGVuZXIgZnVuY3Rpb24gdG8gYmUgcmVtb3ZlZFxuICAgICAtIHVzZUNhcHR1cmUgKGJvb2xlYW4pICNvcHRpb25hbCB1c2VDYXB0dXJlIGZsYWcgZm9yIHJlbW92ZUV2ZW50TGlzdGVuZXJcbiAgICAgPSAob2JqZWN0KSBpbnRlcmFjdFxuICAgICBcXCovXG4gICAgaW50ZXJhY3Qub2ZmID0gZnVuY3Rpb24gKHR5cGUsIGxpc3RlbmVyLCB1c2VDYXB0dXJlKSB7XG4gICAgICAgIGlmIChpc1N0cmluZyh0eXBlKSAmJiB0eXBlLnNlYXJjaCgnICcpICE9PSAtMSkge1xuICAgICAgICAgICAgdHlwZSA9IHR5cGUudHJpbSgpLnNwbGl0KC8gKy8pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzQXJyYXkodHlwZSkpIHtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdHlwZS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGludGVyYWN0Lm9mZih0eXBlW2ldLCBsaXN0ZW5lciwgdXNlQ2FwdHVyZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBpbnRlcmFjdDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc09iamVjdCh0eXBlKSkge1xuICAgICAgICAgICAgZm9yICh2YXIgcHJvcCBpbiB0eXBlKSB7XG4gICAgICAgICAgICAgICAgaW50ZXJhY3Qub2ZmKHByb3AsIHR5cGVbcHJvcF0sIGxpc3RlbmVyKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGludGVyYWN0O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFjb250YWlucyhldmVudFR5cGVzLCB0eXBlKSkge1xuICAgICAgICAgICAgZXZlbnRzLnJlbW92ZShkb2N1bWVudCwgdHlwZSwgbGlzdGVuZXIsIHVzZUNhcHR1cmUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmFyIGluZGV4O1xuXG4gICAgICAgICAgICBpZiAodHlwZSBpbiBnbG9iYWxFdmVudHNcbiAgICAgICAgICAgICAgICAmJiAoaW5kZXggPSBpbmRleE9mKGdsb2JhbEV2ZW50c1t0eXBlXSwgbGlzdGVuZXIpKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICBnbG9iYWxFdmVudHNbdHlwZV0uc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBpbnRlcmFjdDtcbiAgICB9O1xuXG4gICAgLypcXFxuICAgICAqIGludGVyYWN0LmVuYWJsZURyYWdnaW5nXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKlxuICAgICAqIERlcHJlY2F0ZWQuXG4gICAgICpcbiAgICAgKiBSZXR1cm5zIG9yIHNldHMgd2hldGhlciBkcmFnZ2luZyBpcyBlbmFibGVkIGZvciBhbnkgSW50ZXJhY3RhYmxlc1xuICAgICAqXG4gICAgIC0gbmV3VmFsdWUgKGJvb2xlYW4pICNvcHRpb25hbCBgdHJ1ZWAgdG8gYWxsb3cgdGhlIGFjdGlvbjsgYGZhbHNlYCB0byBkaXNhYmxlIGFjdGlvbiBmb3IgYWxsIEludGVyYWN0YWJsZXNcbiAgICAgPSAoYm9vbGVhbiB8IG9iamVjdCkgVGhlIGN1cnJlbnQgc2V0dGluZyBvciBpbnRlcmFjdFxuICAgIFxcKi9cbiAgICBpbnRlcmFjdC5lbmFibGVEcmFnZ2luZyA9IHdhcm5PbmNlKGZ1bmN0aW9uIChuZXdWYWx1ZSkge1xuICAgICAgICBpZiAobmV3VmFsdWUgIT09IG51bGwgJiYgbmV3VmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgYWN0aW9uSXNFbmFibGVkLmRyYWcgPSBuZXdWYWx1ZTtcblxuICAgICAgICAgICAgcmV0dXJuIGludGVyYWN0O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhY3Rpb25Jc0VuYWJsZWQuZHJhZztcbiAgICB9LCAnaW50ZXJhY3QuZW5hYmxlRHJhZ2dpbmcgaXMgZGVwcmVjYXRlZCBhbmQgd2lsbCBzb29uIGJlIHJlbW92ZWQuJyk7XG5cbiAgICAvKlxcXG4gICAgICogaW50ZXJhY3QuZW5hYmxlUmVzaXppbmdcbiAgICAgWyBtZXRob2QgXVxuICAgICAqXG4gICAgICogRGVwcmVjYXRlZC5cbiAgICAgKlxuICAgICAqIFJldHVybnMgb3Igc2V0cyB3aGV0aGVyIHJlc2l6aW5nIGlzIGVuYWJsZWQgZm9yIGFueSBJbnRlcmFjdGFibGVzXG4gICAgICpcbiAgICAgLSBuZXdWYWx1ZSAoYm9vbGVhbikgI29wdGlvbmFsIGB0cnVlYCB0byBhbGxvdyB0aGUgYWN0aW9uOyBgZmFsc2VgIHRvIGRpc2FibGUgYWN0aW9uIGZvciBhbGwgSW50ZXJhY3RhYmxlc1xuICAgICA9IChib29sZWFuIHwgb2JqZWN0KSBUaGUgY3VycmVudCBzZXR0aW5nIG9yIGludGVyYWN0XG4gICAgXFwqL1xuICAgIGludGVyYWN0LmVuYWJsZVJlc2l6aW5nID0gd2Fybk9uY2UoZnVuY3Rpb24gKG5ld1ZhbHVlKSB7XG4gICAgICAgIGlmIChuZXdWYWx1ZSAhPT0gbnVsbCAmJiBuZXdWYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBhY3Rpb25Jc0VuYWJsZWQucmVzaXplID0gbmV3VmFsdWU7XG5cbiAgICAgICAgICAgIHJldHVybiBpbnRlcmFjdDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYWN0aW9uSXNFbmFibGVkLnJlc2l6ZTtcbiAgICB9LCAnaW50ZXJhY3QuZW5hYmxlUmVzaXppbmcgaXMgZGVwcmVjYXRlZCBhbmQgd2lsbCBzb29uIGJlIHJlbW92ZWQuJyk7XG5cbiAgICAvKlxcXG4gICAgICogaW50ZXJhY3QuZW5hYmxlR2VzdHVyaW5nXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKlxuICAgICAqIERlcHJlY2F0ZWQuXG4gICAgICpcbiAgICAgKiBSZXR1cm5zIG9yIHNldHMgd2hldGhlciBnZXN0dXJpbmcgaXMgZW5hYmxlZCBmb3IgYW55IEludGVyYWN0YWJsZXNcbiAgICAgKlxuICAgICAtIG5ld1ZhbHVlIChib29sZWFuKSAjb3B0aW9uYWwgYHRydWVgIHRvIGFsbG93IHRoZSBhY3Rpb247IGBmYWxzZWAgdG8gZGlzYWJsZSBhY3Rpb24gZm9yIGFsbCBJbnRlcmFjdGFibGVzXG4gICAgID0gKGJvb2xlYW4gfCBvYmplY3QpIFRoZSBjdXJyZW50IHNldHRpbmcgb3IgaW50ZXJhY3RcbiAgICBcXCovXG4gICAgaW50ZXJhY3QuZW5hYmxlR2VzdHVyaW5nID0gd2Fybk9uY2UoZnVuY3Rpb24gKG5ld1ZhbHVlKSB7XG4gICAgICAgIGlmIChuZXdWYWx1ZSAhPT0gbnVsbCAmJiBuZXdWYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBhY3Rpb25Jc0VuYWJsZWQuZ2VzdHVyZSA9IG5ld1ZhbHVlO1xuXG4gICAgICAgICAgICByZXR1cm4gaW50ZXJhY3Q7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFjdGlvbklzRW5hYmxlZC5nZXN0dXJlO1xuICAgIH0sICdpbnRlcmFjdC5lbmFibGVHZXN0dXJpbmcgaXMgZGVwcmVjYXRlZCBhbmQgd2lsbCBzb29uIGJlIHJlbW92ZWQuJyk7XG5cbiAgICBpbnRlcmFjdC5ldmVudFR5cGVzID0gZXZlbnRUeXBlcztcblxuICAgIC8qXFxcbiAgICAgKiBpbnRlcmFjdC5kZWJ1Z1xuICAgICBbIG1ldGhvZCBdXG4gICAgICpcbiAgICAgKiBSZXR1cm5zIGRlYnVnZ2luZyBkYXRhXG4gICAgID0gKG9iamVjdCkgQW4gb2JqZWN0IHdpdGggcHJvcGVydGllcyB0aGF0IG91dGxpbmUgdGhlIGN1cnJlbnQgc3RhdGUgYW5kIGV4cG9zZSBpbnRlcm5hbCBmdW5jdGlvbnMgYW5kIHZhcmlhYmxlc1xuICAgIFxcKi9cbiAgICBpbnRlcmFjdC5kZWJ1ZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGludGVyYWN0aW9uID0gaW50ZXJhY3Rpb25zWzBdIHx8IG5ldyBJbnRlcmFjdGlvbigpO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBpbnRlcmFjdGlvbnMgICAgICAgICAgOiBpbnRlcmFjdGlvbnMsXG4gICAgICAgICAgICB0YXJnZXQgICAgICAgICAgICAgICAgOiBpbnRlcmFjdGlvbi50YXJnZXQsXG4gICAgICAgICAgICBkcmFnZ2luZyAgICAgICAgICAgICAgOiBpbnRlcmFjdGlvbi5kcmFnZ2luZyxcbiAgICAgICAgICAgIHJlc2l6aW5nICAgICAgICAgICAgICA6IGludGVyYWN0aW9uLnJlc2l6aW5nLFxuICAgICAgICAgICAgZ2VzdHVyaW5nICAgICAgICAgICAgIDogaW50ZXJhY3Rpb24uZ2VzdHVyaW5nLFxuICAgICAgICAgICAgcHJlcGFyZWQgICAgICAgICAgICAgIDogaW50ZXJhY3Rpb24ucHJlcGFyZWQsXG4gICAgICAgICAgICBtYXRjaGVzICAgICAgICAgICAgICAgOiBpbnRlcmFjdGlvbi5tYXRjaGVzLFxuICAgICAgICAgICAgbWF0Y2hFbGVtZW50cyAgICAgICAgIDogaW50ZXJhY3Rpb24ubWF0Y2hFbGVtZW50cyxcblxuICAgICAgICAgICAgcHJldkNvb3JkcyAgICAgICAgICAgIDogaW50ZXJhY3Rpb24ucHJldkNvb3JkcyxcbiAgICAgICAgICAgIHN0YXJ0Q29vcmRzICAgICAgICAgICA6IGludGVyYWN0aW9uLnN0YXJ0Q29vcmRzLFxuXG4gICAgICAgICAgICBwb2ludGVySWRzICAgICAgICAgICAgOiBpbnRlcmFjdGlvbi5wb2ludGVySWRzLFxuICAgICAgICAgICAgcG9pbnRlcnMgICAgICAgICAgICAgIDogaW50ZXJhY3Rpb24ucG9pbnRlcnMsXG4gICAgICAgICAgICBhZGRQb2ludGVyICAgICAgICAgICAgOiBsaXN0ZW5lcnMuYWRkUG9pbnRlcixcbiAgICAgICAgICAgIHJlbW92ZVBvaW50ZXIgICAgICAgICA6IGxpc3RlbmVycy5yZW1vdmVQb2ludGVyLFxuICAgICAgICAgICAgcmVjb3JkUG9pbnRlciAgICAgICAgOiBsaXN0ZW5lcnMucmVjb3JkUG9pbnRlcixcblxuICAgICAgICAgICAgc25hcCAgICAgICAgICAgICAgICAgIDogaW50ZXJhY3Rpb24uc25hcFN0YXR1cyxcbiAgICAgICAgICAgIHJlc3RyaWN0ICAgICAgICAgICAgICA6IGludGVyYWN0aW9uLnJlc3RyaWN0U3RhdHVzLFxuICAgICAgICAgICAgaW5lcnRpYSAgICAgICAgICAgICAgIDogaW50ZXJhY3Rpb24uaW5lcnRpYVN0YXR1cyxcblxuICAgICAgICAgICAgZG93blRpbWUgICAgICAgICAgICAgIDogaW50ZXJhY3Rpb24uZG93blRpbWVzWzBdLFxuICAgICAgICAgICAgZG93bkV2ZW50ICAgICAgICAgICAgIDogaW50ZXJhY3Rpb24uZG93bkV2ZW50LFxuICAgICAgICAgICAgZG93blBvaW50ZXIgICAgICAgICAgIDogaW50ZXJhY3Rpb24uZG93blBvaW50ZXIsXG4gICAgICAgICAgICBwcmV2RXZlbnQgICAgICAgICAgICAgOiBpbnRlcmFjdGlvbi5wcmV2RXZlbnQsXG5cbiAgICAgICAgICAgIEludGVyYWN0YWJsZSAgICAgICAgICA6IEludGVyYWN0YWJsZSxcbiAgICAgICAgICAgIGludGVyYWN0YWJsZXMgICAgICAgICA6IGludGVyYWN0YWJsZXMsXG4gICAgICAgICAgICBwb2ludGVySXNEb3duICAgICAgICAgOiBpbnRlcmFjdGlvbi5wb2ludGVySXNEb3duLFxuICAgICAgICAgICAgZGVmYXVsdE9wdGlvbnMgICAgICAgIDogZGVmYXVsdE9wdGlvbnMsXG4gICAgICAgICAgICBkZWZhdWx0QWN0aW9uQ2hlY2tlciAgOiBkZWZhdWx0QWN0aW9uQ2hlY2tlcixcblxuICAgICAgICAgICAgYWN0aW9uQ3Vyc29ycyAgICAgICAgIDogYWN0aW9uQ3Vyc29ycyxcbiAgICAgICAgICAgIGRyYWdNb3ZlICAgICAgICAgICAgICA6IGxpc3RlbmVycy5kcmFnTW92ZSxcbiAgICAgICAgICAgIHJlc2l6ZU1vdmUgICAgICAgICAgICA6IGxpc3RlbmVycy5yZXNpemVNb3ZlLFxuICAgICAgICAgICAgZ2VzdHVyZU1vdmUgICAgICAgICAgIDogbGlzdGVuZXJzLmdlc3R1cmVNb3ZlLFxuICAgICAgICAgICAgcG9pbnRlclVwICAgICAgICAgICAgIDogbGlzdGVuZXJzLnBvaW50ZXJVcCxcbiAgICAgICAgICAgIHBvaW50ZXJEb3duICAgICAgICAgICA6IGxpc3RlbmVycy5wb2ludGVyRG93bixcbiAgICAgICAgICAgIHBvaW50ZXJNb3ZlICAgICAgICAgICA6IGxpc3RlbmVycy5wb2ludGVyTW92ZSxcbiAgICAgICAgICAgIHBvaW50ZXJIb3ZlciAgICAgICAgICA6IGxpc3RlbmVycy5wb2ludGVySG92ZXIsXG5cbiAgICAgICAgICAgIGV2ZW50VHlwZXMgICAgICAgICAgICA6IGV2ZW50VHlwZXMsXG5cbiAgICAgICAgICAgIGV2ZW50cyAgICAgICAgICAgICAgICA6IGV2ZW50cyxcbiAgICAgICAgICAgIGdsb2JhbEV2ZW50cyAgICAgICAgICA6IGdsb2JhbEV2ZW50cyxcbiAgICAgICAgICAgIGRlbGVnYXRlZEV2ZW50cyAgICAgICA6IGRlbGVnYXRlZEV2ZW50cyxcblxuICAgICAgICAgICAgcHJlZml4ZWRQcm9wUkVzICAgICAgIDogcHJlZml4ZWRQcm9wUkVzXG4gICAgICAgIH07XG4gICAgfTtcblxuICAgIC8vIGV4cG9zZSB0aGUgZnVuY3Rpb25zIHVzZWQgdG8gY2FsY3VsYXRlIG11bHRpLXRvdWNoIHByb3BlcnRpZXNcbiAgICBpbnRlcmFjdC5nZXRQb2ludGVyQXZlcmFnZSA9IHBvaW50ZXJBdmVyYWdlO1xuICAgIGludGVyYWN0LmdldFRvdWNoQkJveCAgICAgPSB0b3VjaEJCb3g7XG4gICAgaW50ZXJhY3QuZ2V0VG91Y2hEaXN0YW5jZSA9IHRvdWNoRGlzdGFuY2U7XG4gICAgaW50ZXJhY3QuZ2V0VG91Y2hBbmdsZSAgICA9IHRvdWNoQW5nbGU7XG5cbiAgICBpbnRlcmFjdC5nZXRFbGVtZW50UmVjdCAgICAgICAgID0gZ2V0RWxlbWVudFJlY3Q7XG4gICAgaW50ZXJhY3QuZ2V0RWxlbWVudENsaWVudFJlY3QgICA9IGdldEVsZW1lbnRDbGllbnRSZWN0O1xuICAgIGludGVyYWN0Lm1hdGNoZXNTZWxlY3RvciAgICAgICAgPSBtYXRjaGVzU2VsZWN0b3I7XG4gICAgaW50ZXJhY3QuY2xvc2VzdCAgICAgICAgICAgICAgICA9IGNsb3Nlc3Q7XG5cbiAgICAvKlxcXG4gICAgICogaW50ZXJhY3QubWFyZ2luXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKlxuICAgICAqIERlcHJlY2F0ZWQuIFVzZSBgaW50ZXJhY3QodGFyZ2V0KS5yZXNpemFibGUoeyBtYXJnaW46IG51bWJlciB9KTtgIGluc3RlYWQuXG4gICAgICogUmV0dXJucyBvciBzZXRzIHRoZSBtYXJnaW4gZm9yIGF1dG9jaGVjayByZXNpemluZyB1c2VkIGluXG4gICAgICogQEludGVyYWN0YWJsZS5nZXRBY3Rpb24uIFRoYXQgaXMgdGhlIGRpc3RhbmNlIGZyb20gdGhlIGJvdHRvbSBhbmQgcmlnaHRcbiAgICAgKiBlZGdlcyBvZiBhbiBlbGVtZW50IGNsaWNraW5nIGluIHdoaWNoIHdpbGwgc3RhcnQgcmVzaXppbmdcbiAgICAgKlxuICAgICAtIG5ld1ZhbHVlIChudW1iZXIpICNvcHRpb25hbFxuICAgICA9IChudW1iZXIgfCBpbnRlcmFjdCkgVGhlIGN1cnJlbnQgbWFyZ2luIHZhbHVlIG9yIGludGVyYWN0XG4gICAgXFwqL1xuICAgIGludGVyYWN0Lm1hcmdpbiA9IHdhcm5PbmNlKGZ1bmN0aW9uIChuZXd2YWx1ZSkge1xuICAgICAgICBpZiAoaXNOdW1iZXIobmV3dmFsdWUpKSB7XG4gICAgICAgICAgICBtYXJnaW4gPSBuZXd2YWx1ZTtcblxuICAgICAgICAgICAgcmV0dXJuIGludGVyYWN0O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtYXJnaW47XG4gICAgfSxcbiAgICAnaW50ZXJhY3QubWFyZ2luIGlzIGRlcHJlY2F0ZWQuIFVzZSBpbnRlcmFjdCh0YXJnZXQpLnJlc2l6YWJsZSh7IG1hcmdpbjogbnVtYmVyIH0pOyBpbnN0ZWFkLicpIDtcblxuICAgIC8qXFxcbiAgICAgKiBpbnRlcmFjdC5zdXBwb3J0c1RvdWNoXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKlxuICAgICA9IChib29sZWFuKSBXaGV0aGVyIG9yIG5vdCB0aGUgYnJvd3NlciBzdXBwb3J0cyB0b3VjaCBpbnB1dFxuICAgIFxcKi9cbiAgICBpbnRlcmFjdC5zdXBwb3J0c1RvdWNoID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gc3VwcG9ydHNUb3VjaDtcbiAgICB9O1xuXG4gICAgLypcXFxuICAgICAqIGludGVyYWN0LnN1cHBvcnRzUG9pbnRlckV2ZW50XG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKlxuICAgICA9IChib29sZWFuKSBXaGV0aGVyIG9yIG5vdCB0aGUgYnJvd3NlciBzdXBwb3J0cyBQb2ludGVyRXZlbnRzXG4gICAgXFwqL1xuICAgIGludGVyYWN0LnN1cHBvcnRzUG9pbnRlckV2ZW50ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gc3VwcG9ydHNQb2ludGVyRXZlbnQ7XG4gICAgfTtcblxuICAgIC8qXFxcbiAgICAgKiBpbnRlcmFjdC5zdG9wXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKlxuICAgICAqIENhbmNlbHMgYWxsIGludGVyYWN0aW9ucyAoZW5kIGV2ZW50cyBhcmUgbm90IGZpcmVkKVxuICAgICAqXG4gICAgIC0gZXZlbnQgKEV2ZW50KSBBbiBldmVudCBvbiB3aGljaCB0byBjYWxsIHByZXZlbnREZWZhdWx0KClcbiAgICAgPSAob2JqZWN0KSBpbnRlcmFjdFxuICAgIFxcKi9cbiAgICBpbnRlcmFjdC5zdG9wID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgIGZvciAodmFyIGkgPSBpbnRlcmFjdGlvbnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIGludGVyYWN0aW9uc1tpXS5zdG9wKGV2ZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBpbnRlcmFjdDtcbiAgICB9O1xuXG4gICAgLypcXFxuICAgICAqIGludGVyYWN0LmR5bmFtaWNEcm9wXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKlxuICAgICAqIFJldHVybnMgb3Igc2V0cyB3aGV0aGVyIHRoZSBkaW1lbnNpb25zIG9mIGRyb3B6b25lIGVsZW1lbnRzIGFyZVxuICAgICAqIGNhbGN1bGF0ZWQgb24gZXZlcnkgZHJhZ21vdmUgb3Igb25seSBvbiBkcmFnc3RhcnQgZm9yIHRoZSBkZWZhdWx0XG4gICAgICogZHJvcENoZWNrZXJcbiAgICAgKlxuICAgICAtIG5ld1ZhbHVlIChib29sZWFuKSAjb3B0aW9uYWwgVHJ1ZSB0byBjaGVjayBvbiBlYWNoIG1vdmUuIEZhbHNlIHRvIGNoZWNrIG9ubHkgYmVmb3JlIHN0YXJ0XG4gICAgID0gKGJvb2xlYW4gfCBpbnRlcmFjdCkgVGhlIGN1cnJlbnQgc2V0dGluZyBvciBpbnRlcmFjdFxuICAgIFxcKi9cbiAgICBpbnRlcmFjdC5keW5hbWljRHJvcCA9IGZ1bmN0aW9uIChuZXdWYWx1ZSkge1xuICAgICAgICBpZiAoaXNCb29sKG5ld1ZhbHVlKSkge1xuICAgICAgICAgICAgLy9pZiAoZHJhZ2dpbmcgJiYgZHluYW1pY0Ryb3AgIT09IG5ld1ZhbHVlICYmICFuZXdWYWx1ZSkge1xuICAgICAgICAgICAgICAgIC8vY2FsY1JlY3RzKGRyb3B6b25lcyk7XG4gICAgICAgICAgICAvL31cblxuICAgICAgICAgICAgZHluYW1pY0Ryb3AgPSBuZXdWYWx1ZTtcblxuICAgICAgICAgICAgcmV0dXJuIGludGVyYWN0O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkeW5hbWljRHJvcDtcbiAgICB9O1xuXG4gICAgLypcXFxuICAgICAqIGludGVyYWN0LnBvaW50ZXJNb3ZlVG9sZXJhbmNlXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKiBSZXR1cm5zIG9yIHNldHMgdGhlIGRpc3RhbmNlIHRoZSBwb2ludGVyIG11c3QgYmUgbW92ZWQgYmVmb3JlIGFuIGFjdGlvblxuICAgICAqIHNlcXVlbmNlIG9jY3Vycy4gVGhpcyBhbHNvIGFmZmVjdHMgdG9sZXJhbmNlIGZvciB0YXAgZXZlbnRzLlxuICAgICAqXG4gICAgIC0gbmV3VmFsdWUgKG51bWJlcikgI29wdGlvbmFsIFRoZSBtb3ZlbWVudCBmcm9tIHRoZSBzdGFydCBwb3NpdGlvbiBtdXN0IGJlIGdyZWF0ZXIgdGhhbiB0aGlzIHZhbHVlXG4gICAgID0gKG51bWJlciB8IEludGVyYWN0YWJsZSkgVGhlIGN1cnJlbnQgc2V0dGluZyBvciBpbnRlcmFjdFxuICAgIFxcKi9cbiAgICBpbnRlcmFjdC5wb2ludGVyTW92ZVRvbGVyYW5jZSA9IGZ1bmN0aW9uIChuZXdWYWx1ZSkge1xuICAgICAgICBpZiAoaXNOdW1iZXIobmV3VmFsdWUpKSB7XG4gICAgICAgICAgICBwb2ludGVyTW92ZVRvbGVyYW5jZSA9IG5ld1ZhbHVlO1xuXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBwb2ludGVyTW92ZVRvbGVyYW5jZTtcbiAgICB9O1xuXG4gICAgLypcXFxuICAgICAqIGludGVyYWN0Lm1heEludGVyYWN0aW9uc1xuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmV0dXJucyBvciBzZXRzIHRoZSBtYXhpbXVtIG51bWJlciBvZiBjb25jdXJyZW50IGludGVyYWN0aW9ucyBhbGxvd2VkLlxuICAgICAqIEJ5IGRlZmF1bHQgb25seSAxIGludGVyYWN0aW9uIGlzIGFsbG93ZWQgYXQgYSB0aW1lIChmb3IgYmFja3dhcmRzXG4gICAgICogY29tcGF0aWJpbGl0eSkuIFRvIGFsbG93IG11bHRpcGxlIGludGVyYWN0aW9ucyBvbiB0aGUgc2FtZSBJbnRlcmFjdGFibGVzXG4gICAgICogYW5kIGVsZW1lbnRzLCB5b3UgbmVlZCB0byBlbmFibGUgaXQgaW4gdGhlIGRyYWdnYWJsZSwgcmVzaXphYmxlIGFuZFxuICAgICAqIGdlc3R1cmFibGUgYCdtYXgnYCBhbmQgYCdtYXhQZXJFbGVtZW50J2Agb3B0aW9ucy5cbiAgICAgKipcbiAgICAgLSBuZXdWYWx1ZSAobnVtYmVyKSAjb3B0aW9uYWwgQW55IG51bWJlci4gbmV3VmFsdWUgPD0gMCBtZWFucyBubyBpbnRlcmFjdGlvbnMuXG4gICAgXFwqL1xuICAgIGludGVyYWN0Lm1heEludGVyYWN0aW9ucyA9IGZ1bmN0aW9uIChuZXdWYWx1ZSkge1xuICAgICAgICBpZiAoaXNOdW1iZXIobmV3VmFsdWUpKSB7XG4gICAgICAgICAgICBtYXhJbnRlcmFjdGlvbnMgPSBuZXdWYWx1ZTtcblxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbWF4SW50ZXJhY3Rpb25zO1xuICAgIH07XG5cbiAgICBpbnRlcmFjdC5jcmVhdGVTbmFwR3JpZCA9IGZ1bmN0aW9uIChncmlkKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoeCwgeSkge1xuICAgICAgICAgICAgdmFyIG9mZnNldFggPSAwLFxuICAgICAgICAgICAgICAgIG9mZnNldFkgPSAwO1xuXG4gICAgICAgICAgICBpZiAoaXNPYmplY3QoZ3JpZC5vZmZzZXQpKSB7XG4gICAgICAgICAgICAgICAgb2Zmc2V0WCA9IGdyaWQub2Zmc2V0Lng7XG4gICAgICAgICAgICAgICAgb2Zmc2V0WSA9IGdyaWQub2Zmc2V0Lnk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBncmlkeCA9IE1hdGgucm91bmQoKHggLSBvZmZzZXRYKSAvIGdyaWQueCksXG4gICAgICAgICAgICAgICAgZ3JpZHkgPSBNYXRoLnJvdW5kKCh5IC0gb2Zmc2V0WSkgLyBncmlkLnkpLFxuXG4gICAgICAgICAgICAgICAgbmV3WCA9IGdyaWR4ICogZ3JpZC54ICsgb2Zmc2V0WCxcbiAgICAgICAgICAgICAgICBuZXdZID0gZ3JpZHkgKiBncmlkLnkgKyBvZmZzZXRZO1xuXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHg6IG5ld1gsXG4gICAgICAgICAgICAgICAgeTogbmV3WSxcbiAgICAgICAgICAgICAgICByYW5nZTogZ3JpZC5yYW5nZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfTtcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gZW5kQWxsSW50ZXJhY3Rpb25zIChldmVudCkge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGludGVyYWN0aW9ucy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaW50ZXJhY3Rpb25zW2ldLnBvaW50ZXJFbmQoZXZlbnQsIGV2ZW50KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxpc3RlblRvRG9jdW1lbnQgKGRvYykge1xuICAgICAgICBpZiAoY29udGFpbnMoZG9jdW1lbnRzLCBkb2MpKSB7IHJldHVybjsgfVxuXG4gICAgICAgIHZhciB3aW4gPSBkb2MuZGVmYXVsdFZpZXcgfHwgZG9jLnBhcmVudFdpbmRvdztcblxuICAgICAgICAvLyBhZGQgZGVsZWdhdGUgZXZlbnQgbGlzdGVuZXJcbiAgICAgICAgZm9yICh2YXIgZXZlbnRUeXBlIGluIGRlbGVnYXRlZEV2ZW50cykge1xuICAgICAgICAgICAgZXZlbnRzLmFkZChkb2MsIGV2ZW50VHlwZSwgZGVsZWdhdGVMaXN0ZW5lcik7XG4gICAgICAgICAgICBldmVudHMuYWRkKGRvYywgZXZlbnRUeXBlLCBkZWxlZ2F0ZVVzZUNhcHR1cmUsIHRydWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHN1cHBvcnRzUG9pbnRlckV2ZW50KSB7XG4gICAgICAgICAgICBpZiAoUG9pbnRlckV2ZW50ID09PSB3aW4uTVNQb2ludGVyRXZlbnQpIHtcbiAgICAgICAgICAgICAgICBwRXZlbnRUeXBlcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgdXA6ICdNU1BvaW50ZXJVcCcsIGRvd246ICdNU1BvaW50ZXJEb3duJywgb3ZlcjogJ21vdXNlb3ZlcicsXG4gICAgICAgICAgICAgICAgICAgIG91dDogJ21vdXNlb3V0JywgbW92ZTogJ01TUG9pbnRlck1vdmUnLCBjYW5jZWw6ICdNU1BvaW50ZXJDYW5jZWwnIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBwRXZlbnRUeXBlcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgdXA6ICdwb2ludGVydXAnLCBkb3duOiAncG9pbnRlcmRvd24nLCBvdmVyOiAncG9pbnRlcm92ZXInLFxuICAgICAgICAgICAgICAgICAgICBvdXQ6ICdwb2ludGVyb3V0JywgbW92ZTogJ3BvaW50ZXJtb3ZlJywgY2FuY2VsOiAncG9pbnRlcmNhbmNlbCcgfTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZXZlbnRzLmFkZChkb2MsIHBFdmVudFR5cGVzLmRvd24gICwgbGlzdGVuZXJzLnNlbGVjdG9yRG93biApO1xuICAgICAgICAgICAgZXZlbnRzLmFkZChkb2MsIHBFdmVudFR5cGVzLm1vdmUgICwgbGlzdGVuZXJzLnBvaW50ZXJNb3ZlICApO1xuICAgICAgICAgICAgZXZlbnRzLmFkZChkb2MsIHBFdmVudFR5cGVzLm92ZXIgICwgbGlzdGVuZXJzLnBvaW50ZXJPdmVyICApO1xuICAgICAgICAgICAgZXZlbnRzLmFkZChkb2MsIHBFdmVudFR5cGVzLm91dCAgICwgbGlzdGVuZXJzLnBvaW50ZXJPdXQgICApO1xuICAgICAgICAgICAgZXZlbnRzLmFkZChkb2MsIHBFdmVudFR5cGVzLnVwICAgICwgbGlzdGVuZXJzLnBvaW50ZXJVcCAgICApO1xuICAgICAgICAgICAgZXZlbnRzLmFkZChkb2MsIHBFdmVudFR5cGVzLmNhbmNlbCwgbGlzdGVuZXJzLnBvaW50ZXJDYW5jZWwpO1xuXG4gICAgICAgICAgICAvLyBhdXRvc2Nyb2xsXG4gICAgICAgICAgICBldmVudHMuYWRkKGRvYywgcEV2ZW50VHlwZXMubW92ZSwgbGlzdGVuZXJzLmF1dG9TY3JvbGxNb3ZlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGV2ZW50cy5hZGQoZG9jLCAnbW91c2Vkb3duJywgbGlzdGVuZXJzLnNlbGVjdG9yRG93bik7XG4gICAgICAgICAgICBldmVudHMuYWRkKGRvYywgJ21vdXNlbW92ZScsIGxpc3RlbmVycy5wb2ludGVyTW92ZSApO1xuICAgICAgICAgICAgZXZlbnRzLmFkZChkb2MsICdtb3VzZXVwJyAgLCBsaXN0ZW5lcnMucG9pbnRlclVwICAgKTtcbiAgICAgICAgICAgIGV2ZW50cy5hZGQoZG9jLCAnbW91c2VvdmVyJywgbGlzdGVuZXJzLnBvaW50ZXJPdmVyICk7XG4gICAgICAgICAgICBldmVudHMuYWRkKGRvYywgJ21vdXNlb3V0JyAsIGxpc3RlbmVycy5wb2ludGVyT3V0ICApO1xuXG4gICAgICAgICAgICBldmVudHMuYWRkKGRvYywgJ3RvdWNoc3RhcnQnICwgbGlzdGVuZXJzLnNlbGVjdG9yRG93biApO1xuICAgICAgICAgICAgZXZlbnRzLmFkZChkb2MsICd0b3VjaG1vdmUnICAsIGxpc3RlbmVycy5wb2ludGVyTW92ZSAgKTtcbiAgICAgICAgICAgIGV2ZW50cy5hZGQoZG9jLCAndG91Y2hlbmQnICAgLCBsaXN0ZW5lcnMucG9pbnRlclVwICAgICk7XG4gICAgICAgICAgICBldmVudHMuYWRkKGRvYywgJ3RvdWNoY2FuY2VsJywgbGlzdGVuZXJzLnBvaW50ZXJDYW5jZWwpO1xuXG4gICAgICAgICAgICAvLyBhdXRvc2Nyb2xsXG4gICAgICAgICAgICBldmVudHMuYWRkKGRvYywgJ21vdXNlbW92ZScsIGxpc3RlbmVycy5hdXRvU2Nyb2xsTW92ZSk7XG4gICAgICAgICAgICBldmVudHMuYWRkKGRvYywgJ3RvdWNobW92ZScsIGxpc3RlbmVycy5hdXRvU2Nyb2xsTW92ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBldmVudHMuYWRkKHdpbiwgJ2JsdXInLCBlbmRBbGxJbnRlcmFjdGlvbnMpO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAod2luLmZyYW1lRWxlbWVudCkge1xuICAgICAgICAgICAgICAgIHZhciBwYXJlbnREb2MgPSB3aW4uZnJhbWVFbGVtZW50Lm93bmVyRG9jdW1lbnQsXG4gICAgICAgICAgICAgICAgICAgIHBhcmVudFdpbmRvdyA9IHBhcmVudERvYy5kZWZhdWx0VmlldztcblxuICAgICAgICAgICAgICAgIGV2ZW50cy5hZGQocGFyZW50RG9jICAgLCAnbW91c2V1cCcgICAgICAsIGxpc3RlbmVycy5wb2ludGVyRW5kKTtcbiAgICAgICAgICAgICAgICBldmVudHMuYWRkKHBhcmVudERvYyAgICwgJ3RvdWNoZW5kJyAgICAgLCBsaXN0ZW5lcnMucG9pbnRlckVuZCk7XG4gICAgICAgICAgICAgICAgZXZlbnRzLmFkZChwYXJlbnREb2MgICAsICd0b3VjaGNhbmNlbCcgICwgbGlzdGVuZXJzLnBvaW50ZXJFbmQpO1xuICAgICAgICAgICAgICAgIGV2ZW50cy5hZGQocGFyZW50RG9jICAgLCAncG9pbnRlcnVwJyAgICAsIGxpc3RlbmVycy5wb2ludGVyRW5kKTtcbiAgICAgICAgICAgICAgICBldmVudHMuYWRkKHBhcmVudERvYyAgICwgJ01TUG9pbnRlclVwJyAgLCBsaXN0ZW5lcnMucG9pbnRlckVuZCk7XG4gICAgICAgICAgICAgICAgZXZlbnRzLmFkZChwYXJlbnRXaW5kb3csICdibHVyJyAgICAgICAgICwgZW5kQWxsSW50ZXJhY3Rpb25zICk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBpbnRlcmFjdC53aW5kb3dQYXJlbnRFcnJvciA9IGVycm9yO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gcHJldmVudCBuYXRpdmUgSFRNTDUgZHJhZyBvbiBpbnRlcmFjdC5qcyB0YXJnZXQgZWxlbWVudHNcbiAgICAgICAgZXZlbnRzLmFkZChkb2MsICdkcmFnc3RhcnQnLCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaW50ZXJhY3Rpb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdmFyIGludGVyYWN0aW9uID0gaW50ZXJhY3Rpb25zW2ldO1xuXG4gICAgICAgICAgICAgICAgaWYgKGludGVyYWN0aW9uLmVsZW1lbnRcbiAgICAgICAgICAgICAgICAgICAgJiYgKGludGVyYWN0aW9uLmVsZW1lbnQgPT09IGV2ZW50LnRhcmdldFxuICAgICAgICAgICAgICAgICAgICAgICAgfHwgbm9kZUNvbnRhaW5zKGludGVyYWN0aW9uLmVsZW1lbnQsIGV2ZW50LnRhcmdldCkpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgaW50ZXJhY3Rpb24uY2hlY2tBbmRQcmV2ZW50RGVmYXVsdChldmVudCwgaW50ZXJhY3Rpb24udGFyZ2V0LCBpbnRlcmFjdGlvbi5lbGVtZW50KTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKGV2ZW50cy51c2VBdHRhY2hFdmVudCkge1xuICAgICAgICAgICAgLy8gRm9yIElFJ3MgbGFjayBvZiBFdmVudCNwcmV2ZW50RGVmYXVsdFxuICAgICAgICAgICAgZXZlbnRzLmFkZChkb2MsICdzZWxlY3RzdGFydCcsIGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICAgICAgICAgIHZhciBpbnRlcmFjdGlvbiA9IGludGVyYWN0aW9uc1swXTtcblxuICAgICAgICAgICAgICAgIGlmIChpbnRlcmFjdGlvbi5jdXJyZW50QWN0aW9uKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgaW50ZXJhY3Rpb24uY2hlY2tBbmRQcmV2ZW50RGVmYXVsdChldmVudCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIC8vIEZvciBJRSdzIGJhZCBkYmxjbGljayBldmVudCBzZXF1ZW5jZVxuICAgICAgICAgICAgZXZlbnRzLmFkZChkb2MsICdkYmxjbGljaycsIGRvT25JbnRlcmFjdGlvbnMoJ2llOERibGNsaWNrJykpO1xuICAgICAgICB9XG5cbiAgICAgICAgZG9jdW1lbnRzLnB1c2goZG9jKTtcbiAgICB9XG5cbiAgICBsaXN0ZW5Ub0RvY3VtZW50KGRvY3VtZW50KTtcblxuICAgIGZ1bmN0aW9uIGluZGV4T2YgKGFycmF5LCB0YXJnZXQpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGFycmF5Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoYXJyYXlbaV0gPT09IHRhcmdldCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIC0xO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNvbnRhaW5zIChhcnJheSwgdGFyZ2V0KSB7XG4gICAgICAgIHJldHVybiBpbmRleE9mKGFycmF5LCB0YXJnZXQpICE9PSAtMTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYXRjaGVzU2VsZWN0b3IgKGVsZW1lbnQsIHNlbGVjdG9yLCBub2RlTGlzdCkge1xuICAgICAgICBpZiAoaWU4TWF0Y2hlc1NlbGVjdG9yKSB7XG4gICAgICAgICAgICByZXR1cm4gaWU4TWF0Y2hlc1NlbGVjdG9yKGVsZW1lbnQsIHNlbGVjdG9yLCBub2RlTGlzdCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyByZW1vdmUgL2RlZXAvIGZyb20gc2VsZWN0b3JzIGlmIHNoYWRvd0RPTSBwb2x5ZmlsbCBpcyB1c2VkXG4gICAgICAgIGlmICh3aW5kb3cgIT09IHJlYWxXaW5kb3cpIHtcbiAgICAgICAgICAgIHNlbGVjdG9yID0gc2VsZWN0b3IucmVwbGFjZSgvXFwvZGVlcFxcLy9nLCAnICcpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGVsZW1lbnRbcHJlZml4ZWRNYXRjaGVzU2VsZWN0b3JdKHNlbGVjdG9yKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYXRjaGVzVXBUbyAoZWxlbWVudCwgc2VsZWN0b3IsIGxpbWl0KSB7XG4gICAgICAgIHdoaWxlIChpc0VsZW1lbnQoZWxlbWVudCkpIHtcbiAgICAgICAgICAgIGlmIChtYXRjaGVzU2VsZWN0b3IoZWxlbWVudCwgc2VsZWN0b3IpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGVsZW1lbnQgPSBwYXJlbnRFbGVtZW50KGVsZW1lbnQpO1xuXG4gICAgICAgICAgICBpZiAoZWxlbWVudCA9PT0gbGltaXQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbWF0Y2hlc1NlbGVjdG9yKGVsZW1lbnQsIHNlbGVjdG9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBGb3IgSUU4J3MgbGFjayBvZiBhbiBFbGVtZW50I21hdGNoZXNTZWxlY3RvclxuICAgIC8vIHRha2VuIGZyb20gaHR0cDovL3RhbmFsaW4uY29tL2VuL2Jsb2cvMjAxMi8xMi9tYXRjaGVzLXNlbGVjdG9yLWllOC8gYW5kIG1vZGlmaWVkXG4gICAgaWYgKCEocHJlZml4ZWRNYXRjaGVzU2VsZWN0b3IgaW4gRWxlbWVudC5wcm90b3R5cGUpIHx8ICFpc0Z1bmN0aW9uKEVsZW1lbnQucHJvdG90eXBlW3ByZWZpeGVkTWF0Y2hlc1NlbGVjdG9yXSkpIHtcbiAgICAgICAgaWU4TWF0Y2hlc1NlbGVjdG9yID0gZnVuY3Rpb24gKGVsZW1lbnQsIHNlbGVjdG9yLCBlbGVtcykge1xuICAgICAgICAgICAgZWxlbXMgPSBlbGVtcyB8fCBlbGVtZW50LnBhcmVudE5vZGUucXVlcnlTZWxlY3RvckFsbChzZWxlY3Rvcik7XG5cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBlbGVtcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgICAgIGlmIChlbGVtc1tpXSA9PT0gZWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyByZXF1ZXN0QW5pbWF0aW9uRnJhbWUgcG9seWZpbGxcbiAgICAoZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBsYXN0VGltZSA9IDAsXG4gICAgICAgICAgICB2ZW5kb3JzID0gWydtcycsICdtb3onLCAnd2Via2l0JywgJ28nXTtcblxuICAgICAgICBmb3IodmFyIHggPSAwOyB4IDwgdmVuZG9ycy5sZW5ndGggJiYgIXJlYWxXaW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lOyArK3gpIHtcbiAgICAgICAgICAgIHJlcUZyYW1lID0gcmVhbFdpbmRvd1t2ZW5kb3JzW3hdKydSZXF1ZXN0QW5pbWF0aW9uRnJhbWUnXTtcbiAgICAgICAgICAgIGNhbmNlbEZyYW1lID0gcmVhbFdpbmRvd1t2ZW5kb3JzW3hdKydDYW5jZWxBbmltYXRpb25GcmFtZSddIHx8IHJlYWxXaW5kb3dbdmVuZG9yc1t4XSsnQ2FuY2VsUmVxdWVzdEFuaW1hdGlvbkZyYW1lJ107XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXJlcUZyYW1lKSB7XG4gICAgICAgICAgICByZXFGcmFtZSA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgdmFyIGN1cnJUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCksXG4gICAgICAgICAgICAgICAgICAgIHRpbWVUb0NhbGwgPSBNYXRoLm1heCgwLCAxNiAtIChjdXJyVGltZSAtIGxhc3RUaW1lKSksXG4gICAgICAgICAgICAgICAgICAgIGlkID0gc2V0VGltZW91dChmdW5jdGlvbigpIHsgY2FsbGJhY2soY3VyclRpbWUgKyB0aW1lVG9DYWxsKTsgfSxcbiAgICAgICAgICAgICAgICAgIHRpbWVUb0NhbGwpO1xuICAgICAgICAgICAgICAgIGxhc3RUaW1lID0gY3VyclRpbWUgKyB0aW1lVG9DYWxsO1xuICAgICAgICAgICAgICAgIHJldHVybiBpZDtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWNhbmNlbEZyYW1lKSB7XG4gICAgICAgICAgICBjYW5jZWxGcmFtZSA9IGZ1bmN0aW9uKGlkKSB7XG4gICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KGlkKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9KCkpO1xuXG4gICAgLyogZ2xvYmFsIGV4cG9ydHM6IHRydWUsIG1vZHVsZSwgZGVmaW5lICovXG5cbiAgICAvLyBodHRwOi8vZG9jdW1lbnRjbG91ZC5naXRodWIuaW8vdW5kZXJzY29yZS9kb2NzL3VuZGVyc2NvcmUuaHRtbCNzZWN0aW9uLTExXG4gICAgaWYgKHR5cGVvZiBleHBvcnRzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBpZiAodHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgJiYgbW9kdWxlLmV4cG9ydHMpIHtcbiAgICAgICAgICAgIGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IGludGVyYWN0O1xuICAgICAgICB9XG4gICAgICAgIGV4cG9ydHMuaW50ZXJhY3QgPSBpbnRlcmFjdDtcbiAgICB9XG4gICAgLy8gQU1EXG4gICAgZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7XG4gICAgICAgIGRlZmluZSgnaW50ZXJhY3QnLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHJldHVybiBpbnRlcmFjdDtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICByZWFsV2luZG93LmludGVyYWN0ID0gaW50ZXJhY3Q7XG4gICAgfVxuXG59ICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJz8gdW5kZWZpbmVkIDogd2luZG93KSk7XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vaW50ZXJhY3QuanMvaW50ZXJhY3QuanNcbi8vIG1vZHVsZSBpZCA9IDI5XG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0="); - -/***/ }, -/* 30 */ -/***/ 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-layout\",\n style: (_vm.mergedStyle)\n }, [_vm._t(\"default\"), _vm._v(\" \"), _c('grid-item', {\n directives: [{\n name: \"show\",\n rawName: \"v-show\",\n value: (_vm.isDragging),\n expression: \"isDragging\"\n }],\n staticClass: \"vue-grid-placeholder\",\n attrs: {\n \"x\": _vm.placeholder.x,\n \"y\": _vm.placeholder.y,\n \"w\": _vm.placeholder.w,\n \"h\": _vm.placeholder.h,\n \"i\": _vm.placeholder.i\n }\n })], 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-66d6d8cb\", module.exports)\n }\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvR3JpZExheW91dC52dWU/N2ZiZSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxnQkFBZ0IsbUJBQW1CLGFBQWEsMEJBQTBCO0FBQzFFO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiMzAuanMiLCJzb3VyY2VzQ29udGVudCI6WyJtb2R1bGUuZXhwb3J0cz17cmVuZGVyOmZ1bmN0aW9uICgpe3ZhciBfdm09dGhpczt2YXIgX2g9X3ZtLiRjcmVhdGVFbGVtZW50O3ZhciBfYz1fdm0uX3NlbGYuX2N8fF9oO1xuICByZXR1cm4gX2MoJ2RpdicsIHtcbiAgICByZWY6IFwiaXRlbVwiLFxuICAgIHN0YXRpY0NsYXNzOiBcInZ1ZS1ncmlkLWxheW91dFwiLFxuICAgIHN0eWxlOiAoX3ZtLm1lcmdlZFN0eWxlKVxuICB9LCBbX3ZtLl90KFwiZGVmYXVsdFwiKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ2dyaWQtaXRlbScsIHtcbiAgICBkaXJlY3RpdmVzOiBbe1xuICAgICAgbmFtZTogXCJzaG93XCIsXG4gICAgICByYXdOYW1lOiBcInYtc2hvd1wiLFxuICAgICAgdmFsdWU6IChfdm0uaXNEcmFnZ2luZyksXG4gICAgICBleHByZXNzaW9uOiBcImlzRHJhZ2dpbmdcIlxuICAgIH1dLFxuICAgIHN0YXRpY0NsYXNzOiBcInZ1ZS1ncmlkLXBsYWNlaG9sZGVyXCIsXG4gICAgYXR0cnM6IHtcbiAgICAgIFwieFwiOiBfdm0ucGxhY2Vob2xkZXIueCxcbiAgICAgIFwieVwiOiBfdm0ucGxhY2Vob2xkZXIueSxcbiAgICAgIFwid1wiOiBfdm0ucGxhY2Vob2xkZXIudyxcbiAgICAgIFwiaFwiOiBfdm0ucGxhY2Vob2xkZXIuaCxcbiAgICAgIFwiaVwiOiBfdm0ucGxhY2Vob2xkZXIuaVxuICAgIH1cbiAgfSldLCAyKVxufSxzdGF0aWNSZW5kZXJGbnM6IFtdfVxubW9kdWxlLmV4cG9ydHMucmVuZGVyLl93aXRoU3RyaXBwZWQgPSB0cnVlXG5pZiAobW9kdWxlLmhvdCkge1xuICBtb2R1bGUuaG90LmFjY2VwdCgpXG4gIGlmIChtb2R1bGUuaG90LmRhdGEpIHtcbiAgICAgcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKS5yZXJlbmRlcihcImRhdGEtdi02NmQ2ZDhjYlwiLCBtb2R1bGUuZXhwb3J0cylcbiAgfVxufVxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi92dWUtbG9hZGVyL2xpYi90ZW1wbGF0ZS1jb21waWxlci5qcz9pZD1kYXRhLXYtNjZkNmQ4Y2IhLi9+L3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9dGVtcGxhdGUmaW5kZXg9MCEuL3NyYy9HcmlkTGF5b3V0LnZ1ZVxuLy8gbW9kdWxlIGlkID0gMzBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sInNvdXJjZVJvb3QiOiIifQ=="); - -/***/ }, -/* 31 */ -/***/ 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-layout\",\n style: (_vm.mergedStyle)\n }, [_vm._t(\"default\")], 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-6d0d2fdf\", module.exports)\n }\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvUmVzcG9uc2l2ZUdyaWRMYXlvdXQudnVlP2Q0MmQiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsZ0JBQWdCLG1CQUFtQixhQUFhLDBCQUEwQjtBQUMxRTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiMzEuanMiLCJzb3VyY2VzQ29udGVudCI6WyJtb2R1bGUuZXhwb3J0cz17cmVuZGVyOmZ1bmN0aW9uICgpe3ZhciBfdm09dGhpczt2YXIgX2g9X3ZtLiRjcmVhdGVFbGVtZW50O3ZhciBfYz1fdm0uX3NlbGYuX2N8fF9oO1xuICByZXR1cm4gX2MoJ2RpdicsIHtcbiAgICByZWY6IFwiaXRlbVwiLFxuICAgIHN0YXRpY0NsYXNzOiBcInZ1ZS1ncmlkLWxheW91dFwiLFxuICAgIHN0eWxlOiAoX3ZtLm1lcmdlZFN0eWxlKVxuICB9LCBbX3ZtLl90KFwiZGVmYXVsdFwiKV0sIDIpXG59LHN0YXRpY1JlbmRlckZuczogW119XG5tb2R1bGUuZXhwb3J0cy5yZW5kZXIuX3dpdGhTdHJpcHBlZCA9IHRydWVcbmlmIChtb2R1bGUuaG90KSB7XG4gIG1vZHVsZS5ob3QuYWNjZXB0KClcbiAgaWYgKG1vZHVsZS5ob3QuZGF0YSkge1xuICAgICByZXF1aXJlKFwidnVlLWhvdC1yZWxvYWQtYXBpXCIpLnJlcmVuZGVyKFwiZGF0YS12LTZkMGQyZmRmXCIsIG1vZHVsZS5leHBvcnRzKVxuICB9XG59XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3Z1ZS1sb2FkZXIvbGliL3RlbXBsYXRlLWNvbXBpbGVyLmpzP2lkPWRhdGEtdi02ZDBkMmZkZiEuL34vdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT10ZW1wbGF0ZSZpbmRleD0wIS4vc3JjL1Jlc3BvbnNpdmVHcmlkTGF5b3V0LnZ1ZVxuLy8gbW9kdWxlIGlkID0gMzFcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sInNvdXJjZVJvb3QiOiIifQ=="); - -/***/ }, -/* 32 */ -/***/ 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.isResizable, 'resizing': _vm.isResizing, 'vue-draggable-dragging': _vm.isDragging, 'cssTransforms': _vm.useCssTransforms\n },\n style: (_vm.style)\n }, [_vm._t(\"default\"), _vm._v(\" \"), (_vm.isResizable) ? _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-e800ab18\", module.exports)\n }\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvR3JpZEl0ZW0udnVlPzI4ZjkiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsZ0JBQWdCLG1CQUFtQixhQUFhLDBCQUEwQjtBQUMxRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6IjMyLmpzIiwic291cmNlc0NvbnRlbnQiOlsibW9kdWxlLmV4cG9ydHM9e3JlbmRlcjpmdW5jdGlvbiAoKXt2YXIgX3ZtPXRoaXM7dmFyIF9oPV92bS4kY3JlYXRlRWxlbWVudDt2YXIgX2M9X3ZtLl9zZWxmLl9jfHxfaDtcbiAgcmV0dXJuIF9jKCdkaXYnLCB7XG4gICAgcmVmOiBcIml0ZW1cIixcbiAgICBzdGF0aWNDbGFzczogXCJ2dWUtZ3JpZC1pdGVtXCIsXG4gICAgY2xhc3M6IHtcbiAgICAgICd2dWUtcmVzaXphYmxlJzogX3ZtLmlzUmVzaXphYmxlLCAncmVzaXppbmcnOiBfdm0uaXNSZXNpemluZywgJ3Z1ZS1kcmFnZ2FibGUtZHJhZ2dpbmcnOiBfdm0uaXNEcmFnZ2luZywgJ2Nzc1RyYW5zZm9ybXMnOiBfdm0udXNlQ3NzVHJhbnNmb3Jtc1xuICAgIH0sXG4gICAgc3R5bGU6IChfdm0uc3R5bGUpXG4gIH0sIFtfdm0uX3QoXCJkZWZhdWx0XCIpLCBfdm0uX3YoXCIgXCIpLCAoX3ZtLmlzUmVzaXphYmxlKSA/IF9jKCdzcGFuJywge1xuICAgIHJlZjogXCJoYW5kbGVcIixcbiAgICBjbGFzczogX3ZtLnJlc2l6YWJsZUhhbmRsZUNsYXNzXG4gIH0pIDogX3ZtLl9lKCldLCAyKVxufSxzdGF0aWNSZW5kZXJGbnM6IFtdfVxubW9kdWxlLmV4cG9ydHMucmVuZGVyLl93aXRoU3RyaXBwZWQgPSB0cnVlXG5pZiAobW9kdWxlLmhvdCkge1xuICBtb2R1bGUuaG90LmFjY2VwdCgpXG4gIGlmIChtb2R1bGUuaG90LmRhdGEpIHtcbiAgICAgcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKS5yZXJlbmRlcihcImRhdGEtdi1lODAwYWIxOFwiLCBtb2R1bGUuZXhwb3J0cylcbiAgfVxufVxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi92dWUtbG9hZGVyL2xpYi90ZW1wbGF0ZS1jb21waWxlci5qcz9pZD1kYXRhLXYtZTgwMGFiMTghLi9+L3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9dGVtcGxhdGUmaW5kZXg9MCEuL3NyYy9HcmlkSXRlbS52dWVcbi8vIG1vZHVsZSBpZCA9IDMyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0="); - -/***/ }, -/* 33 */ -/***/ function(module, exports, __webpack_require__) { - -eval("// style-loader: Adds some css to the DOM by adding a \\r\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader?sourceMap!./~/vue-loader/lib/style-rewriter.js!./~/vue-loader/lib/selector.js?type=style&index=0!./src/GridItem.vue\n ** module id = 3\n ** module chunks = 0\n **/","/*\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\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader/lib/css-base.js\n ** module id = 4\n ** module chunks = 0\n **/","/*\n\tMIT License http://www.opensource.org/licenses/mit-license.php\n\tAuthor Tobias Koppers @sokra\n*/\nvar stylesInDom = {},\n\tmemoize = function(fn) {\n\t\tvar memo;\n\t\treturn function () {\n\t\t\tif (typeof memo === \"undefined\") memo = fn.apply(this, arguments);\n\t\t\treturn memo;\n\t\t};\n\t},\n\tisOldIE = memoize(function() {\n\t\treturn /msie [6-9]\\b/.test(window.navigator.userAgent.toLowerCase());\n\t}),\n\tgetHeadElement = memoize(function () {\n\t\treturn document.head || document.getElementsByTagName(\"head\")[0];\n\t}),\n\tsingletonElement = null,\n\tsingletonCounter = 0,\n\tstyleElementsInsertedAtTop = [];\n\nmodule.exports = function(list, options) {\n\tif(typeof DEBUG !== \"undefined\" && DEBUG) {\n\t\tif(typeof document !== \"object\") throw new Error(\"The style-loader cannot be used in a non-browser environment\");\n\t}\n\n\toptions = options || {};\n\t// Force single-tag solution on IE6-9, which has a hard limit on the # of \r\n\n\n\n/** WEBPACK FOOTER **\n ** GridItem.vue?8d105490\n **/","// @flow\r\nexport type LayoutItemRequired = {w: number, h: number, x: number, y: number, i: string};\r\nexport 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};\r\nexport type Layout = Array;\r\nexport type Position = {left: number, top: number, width: number, height: number};\r\nexport 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};\r\nexport type DragEvent = {e: Event} & DragCallbackData;\r\nexport type Size = {width: number, height: number};\r\nexport type ResizeEvent = {e: Event, node: HTMLElement, size: Size};\r\n\r\nconst isProduction = process.env.NODE_ENV === 'production';\r\n\r\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 */\r\nexport function bottom(layout: Layout): number {\r\n let max = 0, bottomY;\r\n for (let i = 0, len = layout.length; i < len; i++) {\r\n bottomY = layout[i].y + layout[i].h;\r\n if (bottomY > max) max = bottomY;\r\n }\r\n return max;\r\n}\r\n\r\nexport function cloneLayout(layout: Layout): Layout {\r\n const newLayout = Array(layout.length);\r\n for (let i = 0, len = layout.length; i < len; i++) {\r\n newLayout[i] = cloneLayoutItem(layout[i]);\r\n }\r\n return newLayout;\r\n}\r\n\r\n// Fast path to cloning, since this is monomorphic\r\nexport function cloneLayoutItem(layoutItem: LayoutItem): LayoutItem {\r\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 };*/\r\n return JSON.parse(JSON.stringify(layoutItem));\r\n}\r\n\r\n/**\r\n * Given two layoutitems, check if they collide.\r\n *\r\n * @return {Boolean} True if colliding.\r\n */\r\nexport function collides(l1: LayoutItem, l2: LayoutItem): boolean {\r\n if (l1 === l2) return false; // same element\r\n if (l1.x + l1.w <= l2.x) return false; // l1 is left of l2\r\n if (l1.x >= l2.x + l2.w) return false; // l1 is right of l2\r\n if (l1.y + l1.h <= l2.y) return false; // l1 is above l2\r\n if (l1.y >= l2.y + l2.h) return false; // l1 is below l2\r\n return true; // boxes overlap\r\n}\r\n\r\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 */\r\nexport function compact(layout: Layout, verticalCompact: Boolean): Layout {\r\n // Statics go in the compareWith array right away so items flow around them.\r\n const compareWith = getStatics(layout);\r\n // We go through the items by row and column.\r\n const sorted = sortLayoutItemsByRowCol(layout);\r\n // Holding for new items.\r\n const out = Array(layout.length);\r\n\r\n for (let i = 0, len = sorted.length; i < len; i++) {\r\n let l = sorted[i];\r\n\r\n // Don't move static elements\r\n if (!l.static) {\r\n l = compactItem(compareWith, l, verticalCompact);\r\n\r\n // Add to comparison array. We only collide with items before this one.\r\n // Statics are already in this array.\r\n compareWith.push(l);\r\n }\r\n\r\n // Add to output array to make sure they still come out in the right order.\r\n out[layout.indexOf(l)] = l;\r\n\r\n // Clear moved flag, if it exists.\r\n l.moved = false;\r\n }\r\n\r\n return out;\r\n}\r\n\r\n/**\r\n * Compact an item in the layout.\r\n */\r\nexport function compactItem(compareWith: Layout, l: LayoutItem, verticalCompact: boolean): LayoutItem {\r\n if (verticalCompact) {\r\n // Move the element up as far as it can go without colliding.\r\n while (l.y > 0 && !getFirstCollision(compareWith, l)) {\r\n l.y--;\r\n }\r\n }\r\n\r\n // Move it down, and keep moving it down if it's colliding.\r\n let collides;\r\n while((collides = getFirstCollision(compareWith, l))) {\r\n l.y = collides.y + collides.h;\r\n }\r\n return l;\r\n}\r\n\r\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 */\r\nexport function correctBounds(layout: Layout, bounds: {cols: number}): Layout {\r\n const collidesWith = getStatics(layout);\r\n for (let i = 0, len = layout.length; i < len; i++) {\r\n const l = layout[i];\r\n // Overflows right\r\n if (l.x + l.w > bounds.cols) l.x = bounds.cols - l.w;\r\n // Overflows left\r\n if (l.x < 0) {\r\n l.x = 0;\r\n l.w = bounds.cols;\r\n }\r\n if (!l.static) collidesWith.push(l);\r\n else {\r\n // If this is static and collides with other statics, we must move it down.\r\n // We have to do something nicer than just letting them overlap.\r\n while(getFirstCollision(collidesWith, l)) {\r\n l.y++;\r\n }\r\n }\r\n }\r\n return layout;\r\n}\r\n\r\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 */\r\nexport function getLayoutItem(layout: Layout, id: string): ?LayoutItem {\r\n for (let i = 0, len = layout.length; i < len; i++) {\r\n if (layout[i].i === id) return layout[i];\r\n }\r\n}\r\n\r\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 */\r\nexport function getFirstCollision(layout: Layout, layoutItem: LayoutItem): ?LayoutItem {\r\n for (let i = 0, len = layout.length; i < len; i++) {\r\n if (collides(layout[i], layoutItem)) return layout[i];\r\n }\r\n}\r\n\r\nexport function getAllCollisions(layout: Layout, layoutItem: LayoutItem): Array {\r\n return layout.filter((l) => collides(l, layoutItem));\r\n}\r\n\r\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 */\r\nexport function getStatics(layout: Layout): Array {\r\n //return [];\r\n return layout.filter((l) => l.static);\r\n}\r\n\r\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 */\r\nexport function moveElement(layout: Layout, l: LayoutItem, x: Number, y: Number, isUserAction: Boolean): Layout {\r\n if (l.static) return layout;\r\n\r\n // Short-circuit if nothing to do.\r\n //if (l.y === y && l.x === x) return layout;\r\n\r\n const movingUp = y && l.y > y;\r\n // This is quite a bit faster than extending the object\r\n if (typeof x === 'number') l.x = x;\r\n if (typeof y === 'number') l.y = y;\r\n l.moved = true;\r\n\r\n // If this collides with anything, move it.\r\n // When doing this comparison, we have to sort the items we compare with\r\n // to ensure, in the case of multiple collisions, that we're getting the\r\n // nearest collision.\r\n let sorted = sortLayoutItemsByRowCol(layout);\r\n if (movingUp) sorted = sorted.reverse();\r\n const collisions = getAllCollisions(sorted, l);\r\n\r\n // Move each item that collides away from this element.\r\n for (let i = 0, len = collisions.length; i < len; i++) {\r\n const collision = collisions[i];\r\n // console.log('resolving collision between', l.i, 'at', l.y, 'and', collision.i, 'at', collision.y);\r\n\r\n // Short circuit so we can't infinite loop\r\n if (collision.moved) continue;\r\n\r\n // This makes it feel a bit more precise by waiting to swap for just a bit when moving up.\r\n if (l.y > collision.y && l.y - collision.y > collision.h / 4) continue;\r\n\r\n // Don't move static items - we have to move *this* element away\r\n if (collision.static) {\r\n layout = moveElementAwayFromCollision(layout, collision, l, isUserAction);\r\n } else {\r\n layout = moveElementAwayFromCollision(layout, l, collision, isUserAction);\r\n }\r\n }\r\n\r\n return layout;\r\n}\r\n\r\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 */\r\nexport function moveElementAwayFromCollision(layout: Layout, collidesWith: LayoutItem,\r\n itemToMove: LayoutItem, isUserAction: ?boolean): Layout {\r\n\r\n // If there is enough space above the collision to put this element, move it there.\r\n // We only do this on the main collision as this can get funky in cascades and cause\r\n // unwanted swapping behavior.\r\n if (isUserAction) {\r\n // Make a mock item so we don't modify the item here, only modify in moveElement.\r\n const fakeItem: LayoutItem = {\r\n x: itemToMove.x,\r\n y: itemToMove.y,\r\n w: itemToMove.w,\r\n h: itemToMove.h,\r\n i: '-1'\r\n };\r\n fakeItem.y = Math.max(collidesWith.y - itemToMove.h, 0);\r\n if (!getFirstCollision(layout, fakeItem)) {\r\n return moveElement(layout, itemToMove, undefined, fakeItem.y);\r\n }\r\n }\r\n\r\n // Previously this was optimized to move below the collision directly, but this can cause problems\r\n // with cascading moves, as an item may actually leapflog a collision and cause a reversal in order.\r\n return moveElement(layout, itemToMove, undefined, itemToMove.y + 1);\r\n}\r\n\r\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 */\r\nexport function perc(num: number): string {\r\n return num * 100 + '%';\r\n}\r\n\r\nexport function setTransform(top, left, width, height): Object {\r\n // Replace unitless items with px\r\n const translate = \"translate(\" + left + \"px,\" + top + \"px)\";\r\n return {\r\n transform: translate,\r\n WebkitTransform: translate,\r\n MozTransform: translate,\r\n msTransform: translate,\r\n OTransform: translate,\r\n width: width + \"px\",\r\n height: height + \"px\",\r\n position: 'absolute'\r\n };\r\n}\r\n\r\nexport function setTopLeft(top, left, width, height): Object {\r\n return {\r\n top: top + \"px\",\r\n left: left + \"px\",\r\n width: width + \"px\",\r\n height: height + \"px\",\r\n position: 'absolute'\r\n };\r\n}\r\n\r\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 */\r\nexport function sortLayoutItemsByRowCol(layout: Layout): Layout {\r\n return [].concat(layout).sort(function(a, b) {\r\n if (a.y > b.y || (a.y === b.y && a.x > b.x)) {\r\n return 1;\r\n }\r\n return -1;\r\n });\r\n}\r\n\r\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 */\r\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*/\r\n\r\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 */\r\nexport function validateLayout(layout: Layout, contextName: string): void {\r\n contextName = contextName || \"Layout\";\r\n const subProps = ['x', 'y', 'w', 'h'];\r\n if (!Array.isArray(layout)) throw new Error(contextName + \" must be an array!\");\r\n for (let i = 0, len = layout.length; i < len; i++) {\r\n const item = layout[i];\r\n for (let j = 0; j < subProps.length; j++) {\r\n if (typeof item[subProps[j]] !== 'number') {\r\n throw new Error('VueGridLayout: ' + contextName + '[' + i + '].' + subProps[j] + ' must be a number!');\r\n }\r\n }\r\n if (item.i && typeof item.i !== 'string') {\r\n throw new Error('VueGridLayout: ' + contextName + '[' + i + '].i must be a string!');\r\n }\r\n if (item.static !== undefined && typeof item.static !== 'boolean') {\r\n throw new Error('VueGridLayout: ' + contextName + '[' + i + '].static must be a boolean!');\r\n }\r\n }\r\n}\r\n\r\n// Flow can't really figure this out, so we just use Object\r\nexport function autoBindHandlers(el: Object, fns: Array): void {\r\n fns.forEach((key) => el[key] = el[key].bind(el));\r\n}\r\n\r\n\r\n\r\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 */\r\nexport function createMarkup(obj) {\r\n var keys = Object.keys(obj);\r\n if (!keys.length) return '';\r\n var i, len = keys.length;\r\n var result = '';\r\n\r\n for (i = 0; i < len; i++) {\r\n var key = keys[i];\r\n var val = obj[key];\r\n result += hyphenate(key) + ':' + addPx(key, val) + ';';\r\n }\r\n\r\n return result;\r\n}\r\n\r\n\r\n/* The following list is defined in React's core */\r\nexport var IS_UNITLESS = {\r\n animationIterationCount: true,\r\n boxFlex: true,\r\n boxFlexGroup: true,\r\n boxOrdinalGroup: true,\r\n columnCount: true,\r\n flex: true,\r\n flexGrow: true,\r\n flexPositive: true,\r\n flexShrink: true,\r\n flexNegative: true,\r\n flexOrder: true,\r\n gridRow: true,\r\n gridColumn: true,\r\n fontWeight: true,\r\n lineClamp: true,\r\n lineHeight: true,\r\n opacity: true,\r\n order: true,\r\n orphans: true,\r\n tabSize: true,\r\n widows: true,\r\n zIndex: true,\r\n zoom: true,\r\n\r\n // SVG-related properties\r\n fillOpacity: true,\r\n stopOpacity: true,\r\n strokeDashoffset: true,\r\n strokeOpacity: true,\r\n strokeWidth: true\r\n};\r\n\r\n\r\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 */\r\nexport function addPx(name, value) {\r\n if(typeof value === 'number' && !IS_UNITLESS[ name ]) {\r\n return value + 'px';\r\n } else {\r\n return value;\r\n }\r\n}\r\n\r\n\r\n/**\r\n * Hyphenate a camelCase string.\r\n *\r\n * @param {String} str\r\n * @return {String}\r\n */\r\n\r\nexport var hyphenateRE = /([a-z\\d])([A-Z])/g;\r\n\r\nexport function hyphenate(str) {\r\n return str.replace(hyphenateRE, '$1-$2').toLowerCase();\r\n}\r\n\r\n\r\nexport function findItemInArray(array, property, value) {\r\n for (var i=0; i < array.length; i++)\r\n if (array[i][property] == value)\r\n return true;\r\n\r\n return false;\r\n}\r\n\r\nexport function findAndRemove(array, property, value) {\r\n array.forEach(function (result, index) {\r\n if (result[property] === value) {\r\n //Remove from array\r\n array.splice(index, 1);\r\n }\r\n });\r\n}\n\n\n/** WEBPACK FOOTER **\n ** ./src/utils.js\n **/","// shim for using process in browser\n\nvar process = module.exports = {};\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = setTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n clearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n setTimeout(drainQueue, 0);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** (webpack)/~/node-libs-browser/~/process/browser.js\n ** module id = 8\n ** module chunks = 0\n **/","module.exports = { \"default\": require(\"core-js/library/fn/object/keys\"), __esModule: true };\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/core-js/object/keys.js\n ** module id = 9\n ** module chunks = 0\n **/","require('../../modules/es6.object.keys');\nmodule.exports = require('../../modules/_core').Object.keys;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/fn/object/keys.js\n ** module id = 10\n ** module chunks = 0\n **/","// 19.1.2.14 Object.keys(O)\nvar toObject = require('./_to-object')\n , $keys = require('./_object-keys');\n\nrequire('./_object-sap')('keys', function(){\n return function keys(it){\n return $keys(toObject(it));\n };\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/modules/es6.object.keys.js\n ** module id = 11\n ** module chunks = 0\n **/","// 7.1.13 ToObject(argument)\nvar defined = require('./_defined');\nmodule.exports = function(it){\n return Object(defined(it));\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/modules/_to-object.js\n ** module id = 12\n ** module chunks = 0\n **/","// 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\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/modules/_defined.js\n ** module id = 13\n ** module chunks = 0\n **/","// 19.1.2.14 / 15.2.3.14 Object.keys(O)\r\nvar $keys = require('./_object-keys-internal')\r\n , enumBugKeys = require('./_enum-bug-keys');\r\n\r\nmodule.exports = Object.keys || function keys(O){\r\n return $keys(O, enumBugKeys);\r\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/modules/_object-keys.js\n ** module id = 14\n ** module chunks = 0\n **/","var has = require('./_has')\r\n , toIObject = require('./_to-iobject')\r\n , arrayIndexOf = require('./_array-includes')(false)\r\n , IE_PROTO = require('./_shared-key')('IE_PROTO');\r\n\r\nmodule.exports = function(object, names){\r\n var O = toIObject(object)\r\n , i = 0\r\n , result = []\r\n , key;\r\n for(key in O)if(key != IE_PROTO)has(O, key) && result.push(key);\r\n // Don't enum bug & hidden keys\r\n while(names.length > i)if(has(O, key = names[i++])){\r\n ~arrayIndexOf(result, key) || result.push(key);\r\n }\r\n return result;\r\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/modules/_object-keys-internal.js\n ** module id = 15\n ** module chunks = 0\n **/","var hasOwnProperty = {}.hasOwnProperty;\nmodule.exports = function(it, key){\n return hasOwnProperty.call(it, key);\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/modules/_has.js\n ** module id = 16\n ** module chunks = 0\n **/","// to indexed object, toObject with fallback for non-array-like ES3 strings\nvar IObject = require('./_iobject')\n , defined = require('./_defined');\nmodule.exports = function(it){\n return IObject(defined(it));\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/modules/_to-iobject.js\n ** module id = 17\n ** module chunks = 0\n **/","// fallback for non-array-like ES3 and non-enumerable old V8 strings\nvar cof = require('./_cof');\nmodule.exports = Object('z').propertyIsEnumerable(0) ? Object : function(it){\n return cof(it) == 'String' ? it.split('') : Object(it);\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/modules/_iobject.js\n ** module id = 18\n ** module chunks = 0\n **/","var toString = {}.toString;\n\nmodule.exports = function(it){\n return toString.call(it).slice(8, -1);\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/modules/_cof.js\n ** module id = 19\n ** module chunks = 0\n **/","// false -> Array#indexOf\n// true -> Array#includes\nvar toIObject = require('./_to-iobject')\n , toLength = require('./_to-length')\n , toIndex = require('./_to-index');\nmodule.exports = function(IS_INCLUDES){\n return function($this, el, fromIndex){\n var O = toIObject($this)\n , length = toLength(O.length)\n , index = toIndex(fromIndex, length)\n , value;\n // Array#includes uses SameValueZero equality algorithm\n if(IS_INCLUDES && el != el)while(length > index){\n value = O[index++];\n if(value != value)return true;\n // Array#toIndex 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\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/modules/_array-includes.js\n ** module id = 20\n ** module chunks = 0\n **/","// 7.1.15 ToLength\nvar toInteger = require('./_to-integer')\n , min = Math.min;\nmodule.exports = function(it){\n return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/modules/_to-length.js\n ** module id = 21\n ** module chunks = 0\n **/","// 7.1.4 ToInteger\nvar ceil = Math.ceil\n , floor = Math.floor;\nmodule.exports = function(it){\n return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/modules/_to-integer.js\n ** module id = 22\n ** module chunks = 0\n **/","var toInteger = require('./_to-integer')\n , max = Math.max\n , min = Math.min;\nmodule.exports = function(index, length){\n index = toInteger(index);\n return index < 0 ? max(index + length, 0) : min(index, length);\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/modules/_to-index.js\n ** module id = 23\n ** module chunks = 0\n **/","var shared = require('./_shared')('keys')\r\n , uid = require('./_uid');\r\nmodule.exports = function(key){\r\n return shared[key] || (shared[key] = uid(key));\r\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/modules/_shared-key.js\n ** module id = 24\n ** module chunks = 0\n **/","var global = require('./_global')\n , SHARED = '__core-js_shared__'\n , store = global[SHARED] || (global[SHARED] = {});\nmodule.exports = function(key){\n return store[key] || (store[key] = {});\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/modules/_shared.js\n ** module id = 25\n ** module chunks = 0\n **/","// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028\nvar global = module.exports = typeof window != 'undefined' && window.Math == Math\n ? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')();\nif(typeof __g == 'number')__g = global; // eslint-disable-line no-undef\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/modules/_global.js\n ** module id = 26\n ** module chunks = 0\n **/","var id = 0\n , px = Math.random();\nmodule.exports = function(key){\n return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/modules/_uid.js\n ** module id = 27\n ** module chunks = 0\n **/","// IE 8- don't enum bug keys\r\nmodule.exports = (\r\n 'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf'\r\n).split(',');\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/modules/_enum-bug-keys.js\n ** module id = 28\n ** module chunks = 0\n **/","// most Object methods by ES6 should accept primitives\nvar $export = require('./_export')\n , core = require('./_core')\n , fails = require('./_fails');\nmodule.exports = function(KEY, exec){\n var fn = (core.Object || {})[KEY] || Object[KEY]\n , exp = {};\n exp[KEY] = exec(fn);\n $export($export.S + $export.F * fails(function(){ fn(1); }), 'Object', exp);\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/modules/_object-sap.js\n ** module id = 29\n ** module chunks = 0\n **/","var global = require('./_global')\n , core = require('./_core')\n , ctx = require('./_ctx')\n , hide = require('./_hide')\n , PROTOTYPE = 'prototype';\n\nvar $export = function(type, name, source){\n var IS_FORCED = type & $export.F\n , IS_GLOBAL = type & $export.G\n , IS_STATIC = type & $export.S\n , IS_PROTO = type & $export.P\n , IS_BIND = type & $export.B\n , IS_WRAP = type & $export.W\n , exports = IS_GLOBAL ? core : core[name] || (core[name] = {})\n , expProto = exports[PROTOTYPE]\n , target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE]\n , key, own, out;\n if(IS_GLOBAL)source = name;\n for(key in source){\n // contains in native\n own = !IS_FORCED && target && target[key] !== undefined;\n if(own && key in exports)continue;\n // export native or passed\n out = own ? target[key] : source[key];\n // prevent global pollution for namespaces\n exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key]\n // bind timers to global for call from export context\n : IS_BIND && own ? ctx(out, global)\n // wrap global constructors for prevent change them in library\n : IS_WRAP && target[key] == out ? (function(C){\n var F = function(a, b, c){\n if(this instanceof C){\n switch(arguments.length){\n case 0: return new C;\n case 1: return new C(a);\n case 2: return new C(a, b);\n } return new C(a, b, c);\n } return C.apply(this, arguments);\n };\n F[PROTOTYPE] = C[PROTOTYPE];\n return F;\n // make static versions for prototype methods\n })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;\n // export proto methods to core.%CONSTRUCTOR%.methods.%NAME%\n if(IS_PROTO){\n (exports.virtual || (exports.virtual = {}))[key] = out;\n // export proto methods to core.%CONSTRUCTOR%.prototype.%NAME%\n if(type & $export.R && expProto && !expProto[key])hide(expProto, key, out);\n }\n }\n};\n// type bitmap\n$export.F = 1; // forced\n$export.G = 2; // global\n$export.S = 4; // static\n$export.P = 8; // proto\n$export.B = 16; // bind\n$export.W = 32; // wrap\n$export.U = 64; // safe\n$export.R = 128; // real proto method for `library` \nmodule.exports = $export;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/modules/_export.js\n ** module id = 30\n ** module chunks = 0\n **/","var core = module.exports = {version: '2.4.0'};\nif(typeof __e == 'number')__e = core; // eslint-disable-line no-undef\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/modules/_core.js\n ** module id = 31\n ** module chunks = 0\n **/","// optional / simple context binding\nvar aFunction = require('./_a-function');\nmodule.exports = function(fn, that, length){\n aFunction(fn);\n if(that === undefined)return fn;\n switch(length){\n case 1: return function(a){\n return fn.call(that, a);\n };\n case 2: return function(a, b){\n return fn.call(that, a, b);\n };\n case 3: return function(a, b, c){\n return fn.call(that, a, b, c);\n };\n }\n return function(/* ...args */){\n return fn.apply(that, arguments);\n };\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/modules/_ctx.js\n ** module id = 32\n ** module chunks = 0\n **/","module.exports = function(it){\n if(typeof it != 'function')throw TypeError(it + ' is not a function!');\n return it;\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/modules/_a-function.js\n ** module id = 33\n ** module chunks = 0\n **/","var dP = require('./_object-dp')\n , createDesc = require('./_property-desc');\nmodule.exports = require('./_descriptors') ? function(object, key, value){\n return dP.f(object, key, createDesc(1, value));\n} : function(object, key, value){\n object[key] = value;\n return object;\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/modules/_hide.js\n ** module id = 34\n ** module chunks = 0\n **/","var anObject = require('./_an-object')\n , IE8_DOM_DEFINE = require('./_ie8-dom-define')\n , toPrimitive = require('./_to-primitive')\n , dP = Object.defineProperty;\n\nexports.f = require('./_descriptors') ? Object.defineProperty : function defineProperty(O, P, Attributes){\n anObject(O);\n P = toPrimitive(P, true);\n anObject(Attributes);\n if(IE8_DOM_DEFINE)try {\n return dP(O, P, Attributes);\n } catch(e){ /* empty */ }\n if('get' in Attributes || 'set' in Attributes)throw TypeError('Accessors not supported!');\n if('value' in Attributes)O[P] = Attributes.value;\n return O;\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/modules/_object-dp.js\n ** module id = 35\n ** module chunks = 0\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\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/modules/_an-object.js\n ** module id = 36\n ** module chunks = 0\n **/","module.exports = function(it){\n return typeof it === 'object' ? it !== null : typeof it === 'function';\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/modules/_is-object.js\n ** module id = 37\n ** module chunks = 0\n **/","module.exports = !require('./_descriptors') && !require('./_fails')(function(){\r\n return Object.defineProperty(require('./_dom-create')('div'), 'a', {get: function(){ return 7; }}).a != 7;\r\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/modules/_ie8-dom-define.js\n ** module id = 38\n ** module chunks = 0\n **/","// Thank's IE8 for his funny defineProperty\nmodule.exports = !require('./_fails')(function(){\n return Object.defineProperty({}, 'a', {get: function(){ return 7; }}).a != 7;\n});\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/modules/_descriptors.js\n ** module id = 39\n ** module chunks = 0\n **/","module.exports = function(exec){\n try {\n return !!exec();\n } catch(e){\n return true;\n }\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/modules/_fails.js\n ** module id = 40\n ** module chunks = 0\n **/","var isObject = require('./_is-object')\n , document = require('./_global').document\n // in old IE typeof document.createElement is 'object'\n , is = isObject(document) && isObject(document.createElement);\nmodule.exports = function(it){\n return is ? document.createElement(it) : {};\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/modules/_dom-create.js\n ** module id = 41\n ** module chunks = 0\n **/","// 7.1.1 ToPrimitive(input [, PreferredType])\nvar isObject = require('./_is-object');\n// instead of the ES6 spec version, we didn't implement @@toPrimitive case\n// and the second argument - flag - preferred type is a string\nmodule.exports = function(it, S){\n if(!isObject(it))return it;\n var fn, val;\n if(S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val;\n if(typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it)))return val;\n if(!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val;\n throw TypeError(\"Can't convert object to primitive value\");\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/modules/_to-primitive.js\n ** module id = 42\n ** module chunks = 0\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\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/modules/_property-desc.js\n ** module id = 43\n ** module chunks = 0\n **/","module.exports = { \"default\": require(\"core-js/library/fn/json/stringify\"), __esModule: true };\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/core-js/json/stringify.js\n ** module id = 44\n ** module chunks = 0\n **/","var core = require('../../modules/_core')\n , $JSON = core.JSON || (core.JSON = {stringify: JSON.stringify});\nmodule.exports = function stringify(it){ // eslint-disable-line no-unused-vars\n return $JSON.stringify.apply($JSON, arguments);\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/babel-runtime/~/core-js/library/fn/json/stringify.js\n ** module id = 45\n ** module chunks = 0\n **/","// Get {x, y} positions from event.\r\nexport function getControlPosition(e) {\r\n return offsetXYFromParentOf(e);\r\n}\r\n\r\n\r\n// Get from offsetParent\r\nexport function offsetXYFromParentOf(evt) {\r\n const offsetParent = evt.target.offsetParent || document.body;\r\n const offsetParentRect = evt.offsetParent === document.body ? {left: 0, top: 0} : offsetParent.getBoundingClientRect();\r\n\r\n const x = evt.clientX + offsetParent.scrollLeft - offsetParentRect.left;\r\n const y = evt.clientY + offsetParent.scrollTop - offsetParentRect.top;\r\n\r\n /*const x = Math.round(evt.clientX + offsetParent.scrollLeft - offsetParentRect.left);\r\n const y = Math.round(evt.clientY + offsetParent.scrollTop - offsetParentRect.top);*/\r\n\r\n\r\n return {x, y};\r\n}\r\n\r\n\r\n// Create an data object exposed by 's events\r\nexport function createCoreData(lastX, lastY, x, y) {\r\n // State changes are often (but not always!) async. We want the latest value.\r\n const isStart = !isNum(lastX);\r\n\r\n if (isStart) {\r\n // If this is our first move, use the x and y as last coords.\r\n return {\r\n deltaX: 0, deltaY: 0,\r\n lastX: x, lastY: y,\r\n x: x, y: y\r\n };\r\n } else {\r\n // Otherwise calculate proper values.\r\n return {\r\n deltaX: x - lastX, deltaY: y - lastY,\r\n lastX: lastX, lastY: lastY,\r\n x: x, y: y\r\n };\r\n }\r\n}\r\n\r\n\r\nfunction isNum(num) {\r\n return typeof num === 'number' && !isNaN(num);\r\n}\r\n\r\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/draggableUtils.js\n **/","/**\n * interact.js v1.2.6\n *\n * Copyright (c) 2012-2015 Taye Adeyemi \n * Open source under the MIT License.\n * https://raw.github.com/taye/interact.js/master/LICENSE\n */\n(function (realWindow) {\n 'use strict';\n\n // return early if there's no window to work with (eg. Node.js)\n if (!realWindow) { return; }\n\n var // get wrapped window if using Shadow DOM polyfill\n window = (function () {\n // create a TextNode\n var el = realWindow.document.createTextNode('');\n\n // check if it's wrapped by a polyfill\n if (el.ownerDocument !== realWindow.document\n && typeof realWindow.wrap === 'function'\n && realWindow.wrap(el) === el) {\n // return wrapped window\n return realWindow.wrap(realWindow);\n }\n\n // no Shadow DOM polyfil or native implementation\n return realWindow;\n }()),\n\n document = window.document,\n DocumentFragment = window.DocumentFragment || blank,\n SVGElement = window.SVGElement || blank,\n SVGSVGElement = window.SVGSVGElement || blank,\n SVGElementInstance = window.SVGElementInstance || blank,\n HTMLElement = window.HTMLElement || window.Element,\n\n PointerEvent = (window.PointerEvent || window.MSPointerEvent),\n pEventTypes,\n\n hypot = Math.hypot || function (x, y) { return Math.sqrt(x * x + y * y); },\n\n tmpXY = {}, // reduce object creation in getXY()\n\n documents = [], // all documents being listened to\n\n interactables = [], // all set interactables\n interactions = [], // all interactions\n\n dynamicDrop = false,\n\n // {\n // type: {\n // selectors: ['selector', ...],\n // contexts : [document, ...],\n // listeners: [[listener, useCapture], ...]\n // }\n // }\n delegatedEvents = {},\n\n defaultOptions = {\n base: {\n accept : null,\n actionChecker : null,\n styleCursor : true,\n preventDefault: 'auto',\n origin : { x: 0, y: 0 },\n deltaSource : 'page',\n allowFrom : null,\n ignoreFrom : null,\n _context : document,\n dropChecker : null\n },\n\n drag: {\n enabled: false,\n manualStart: true,\n max: Infinity,\n maxPerElement: 1,\n\n snap: null,\n restrict: null,\n inertia: null,\n autoScroll: null,\n\n axis: 'xy'\n },\n\n drop: {\n enabled: false,\n accept: null,\n overlap: 'pointer'\n },\n\n resize: {\n enabled: false,\n manualStart: false,\n max: Infinity,\n maxPerElement: 1,\n\n snap: null,\n restrict: null,\n inertia: null,\n autoScroll: null,\n\n square: false,\n preserveAspectRatio: false,\n axis: 'xy',\n\n // use default margin\n margin: NaN,\n\n // object with props left, right, top, bottom which are\n // true/false values to resize when the pointer is over that edge,\n // CSS selectors to match the handles for each direction\n // or the Elements for each handle\n edges: null,\n\n // a value of 'none' will limit the resize rect to a minimum of 0x0\n // 'negate' will alow the rect to have negative width/height\n // 'reposition' will keep the width/height positive by swapping\n // the top and bottom edges and/or swapping the left and right edges\n invert: 'none'\n },\n\n gesture: {\n manualStart: false,\n enabled: false,\n max: Infinity,\n maxPerElement: 1,\n\n restrict: null\n },\n\n perAction: {\n manualStart: false,\n max: Infinity,\n maxPerElement: 1,\n\n snap: {\n enabled : false,\n endOnly : false,\n range : Infinity,\n targets : null,\n offsets : null,\n\n relativePoints: null\n },\n\n restrict: {\n enabled: false,\n endOnly: false\n },\n\n autoScroll: {\n enabled : false,\n container : null, // the item that is scrolled (Window or HTMLElement)\n margin : 60,\n speed : 300 // the scroll speed in pixels per second\n },\n\n inertia: {\n enabled : false,\n resistance : 10, // the lambda in exponential decay\n minSpeed : 100, // target speed must be above this for inertia to start\n endSpeed : 10, // the speed at which inertia is slow enough to stop\n allowResume : true, // allow resuming an action in inertia phase\n zeroResumeDelta : true, // if an action is resumed after launch, set dx/dy to 0\n smoothEndDuration: 300 // animate to snap/restrict endOnly if there's no inertia\n }\n },\n\n _holdDuration: 600\n },\n\n // Things related to autoScroll\n autoScroll = {\n interaction: null,\n i: null, // the handle returned by window.setInterval\n x: 0, y: 0, // Direction each pulse is to scroll in\n\n // scroll the window by the values in scroll.x/y\n scroll: function () {\n var options = autoScroll.interaction.target.options[autoScroll.interaction.prepared.name].autoScroll,\n container = options.container || getWindow(autoScroll.interaction.element),\n now = new Date().getTime(),\n // change in time in seconds\n dtx = (now - autoScroll.prevTimeX) / 1000,\n dty = (now - autoScroll.prevTimeY) / 1000,\n vx, vy, sx, sy;\n\n // displacement\n if (options.velocity) {\n vx = options.velocity.x;\n vy = options.velocity.y;\n }\n else {\n vx = vy = options.speed\n }\n \n sx = vx * dtx;\n sy = vy * dty;\n\n if (sx >= 1 || sy >= 1) {\n if (isWindow(container)) {\n container.scrollBy(autoScroll.x * sx, autoScroll.y * sy);\n }\n else if (container) {\n container.scrollLeft += autoScroll.x * sx;\n container.scrollTop += autoScroll.y * sy;\n }\n\n if (sx >=1) autoScroll.prevTimeX = now;\n if (sy >= 1) autoScroll.prevTimeY = now;\n }\n\n if (autoScroll.isScrolling) {\n cancelFrame(autoScroll.i);\n autoScroll.i = reqFrame(autoScroll.scroll);\n }\n },\n\n isScrolling: false,\n prevTimeX: 0,\n prevTimeY: 0,\n\n start: function (interaction) {\n autoScroll.isScrolling = true;\n cancelFrame(autoScroll.i);\n\n autoScroll.interaction = interaction;\n autoScroll.prevTimeX = new Date().getTime();\n autoScroll.prevTimeY = new Date().getTime();\n autoScroll.i = reqFrame(autoScroll.scroll);\n },\n\n stop: function () {\n autoScroll.isScrolling = false;\n cancelFrame(autoScroll.i);\n }\n },\n\n // Does the browser support touch input?\n supportsTouch = (('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch),\n\n // Does the browser support PointerEvents\n supportsPointerEvent = !!PointerEvent,\n\n // Less Precision with touch input\n margin = supportsTouch || supportsPointerEvent? 20: 10,\n\n pointerMoveTolerance = 1,\n\n // for ignoring browser's simulated mouse events\n prevTouchTime = 0,\n\n // Allow this many interactions to happen simultaneously\n maxInteractions = Infinity,\n\n // Check if is IE9 or older\n actionCursors = (document.all && !window.atob) ? {\n drag : 'move',\n resizex : 'e-resize',\n resizey : 's-resize',\n resizexy: 'se-resize',\n\n resizetop : 'n-resize',\n resizeleft : 'w-resize',\n resizebottom : 's-resize',\n resizeright : 'e-resize',\n resizetopleft : 'se-resize',\n resizebottomright: 'se-resize',\n resizetopright : 'ne-resize',\n resizebottomleft : 'ne-resize',\n\n gesture : ''\n } : {\n drag : 'move',\n resizex : 'ew-resize',\n resizey : 'ns-resize',\n resizexy: 'nwse-resize',\n\n resizetop : 'ns-resize',\n resizeleft : 'ew-resize',\n resizebottom : 'ns-resize',\n resizeright : 'ew-resize',\n resizetopleft : 'nwse-resize',\n resizebottomright: 'nwse-resize',\n resizetopright : 'nesw-resize',\n resizebottomleft : 'nesw-resize',\n\n gesture : ''\n },\n\n actionIsEnabled = {\n drag : true,\n resize : true,\n gesture: true\n },\n\n // because Webkit and Opera still use 'mousewheel' event type\n wheelEvent = 'onmousewheel' in document? 'mousewheel': 'wheel',\n\n eventTypes = [\n 'dragstart',\n 'dragmove',\n 'draginertiastart',\n 'dragend',\n 'dragenter',\n 'dragleave',\n 'dropactivate',\n 'dropdeactivate',\n 'dropmove',\n 'drop',\n 'resizestart',\n 'resizemove',\n 'resizeinertiastart',\n 'resizeend',\n 'gesturestart',\n 'gesturemove',\n 'gestureinertiastart',\n 'gestureend',\n\n 'down',\n 'move',\n 'up',\n 'cancel',\n 'tap',\n 'doubletap',\n 'hold'\n ],\n\n globalEvents = {},\n\n // Opera Mobile must be handled differently\n isOperaMobile = navigator.appName == 'Opera' &&\n supportsTouch &&\n navigator.userAgent.match('Presto'),\n\n // scrolling doesn't change the result of getClientRects on iOS 7\n isIOS7 = (/iP(hone|od|ad)/.test(navigator.platform)\n && /OS 7[^\\d]/.test(navigator.appVersion)),\n\n // prefix matchesSelector\n prefixedMatchesSelector = 'matches' in Element.prototype?\n 'matches': 'webkitMatchesSelector' in Element.prototype?\n 'webkitMatchesSelector': 'mozMatchesSelector' in Element.prototype?\n 'mozMatchesSelector': 'oMatchesSelector' in Element.prototype?\n 'oMatchesSelector': 'msMatchesSelector',\n\n // will be polyfill function if browser is IE8\n ie8MatchesSelector,\n\n // native requestAnimationFrame or polyfill\n reqFrame = realWindow.requestAnimationFrame,\n cancelFrame = realWindow.cancelAnimationFrame,\n\n // Events wrapper\n events = (function () {\n var useAttachEvent = ('attachEvent' in window) && !('addEventListener' in window),\n addEvent = useAttachEvent? 'attachEvent': 'addEventListener',\n removeEvent = useAttachEvent? 'detachEvent': 'removeEventListener',\n on = useAttachEvent? 'on': '',\n\n elements = [],\n targets = [],\n attachedListeners = [];\n\n function add (element, type, listener, useCapture) {\n var elementIndex = indexOf(elements, element),\n target = targets[elementIndex];\n\n if (!target) {\n target = {\n events: {},\n typeCount: 0\n };\n\n elementIndex = elements.push(element) - 1;\n targets.push(target);\n\n attachedListeners.push((useAttachEvent ? {\n supplied: [],\n wrapped : [],\n useCount: []\n } : null));\n }\n\n if (!target.events[type]) {\n target.events[type] = [];\n target.typeCount++;\n }\n\n if (!contains(target.events[type], listener)) {\n var ret;\n\n if (useAttachEvent) {\n var listeners = attachedListeners[elementIndex],\n listenerIndex = indexOf(listeners.supplied, listener);\n\n var wrapped = listeners.wrapped[listenerIndex] || function (event) {\n if (!event.immediatePropagationStopped) {\n event.target = event.srcElement;\n event.currentTarget = element;\n\n event.preventDefault = event.preventDefault || preventDef;\n event.stopPropagation = event.stopPropagation || stopProp;\n event.stopImmediatePropagation = event.stopImmediatePropagation || stopImmProp;\n\n if (/mouse|click/.test(event.type)) {\n event.pageX = event.clientX + getWindow(element).document.documentElement.scrollLeft;\n event.pageY = event.clientY + getWindow(element).document.documentElement.scrollTop;\n }\n\n listener(event);\n }\n };\n\n ret = element[addEvent](on + type, wrapped, Boolean(useCapture));\n\n if (listenerIndex === -1) {\n listeners.supplied.push(listener);\n listeners.wrapped.push(wrapped);\n listeners.useCount.push(1);\n }\n else {\n listeners.useCount[listenerIndex]++;\n }\n }\n else {\n ret = element[addEvent](type, listener, useCapture || false);\n }\n target.events[type].push(listener);\n\n return ret;\n }\n }\n\n function remove (element, type, listener, useCapture) {\n var i,\n elementIndex = indexOf(elements, element),\n target = targets[elementIndex],\n listeners,\n listenerIndex,\n wrapped = listener;\n\n if (!target || !target.events) {\n return;\n }\n\n if (useAttachEvent) {\n listeners = attachedListeners[elementIndex];\n listenerIndex = indexOf(listeners.supplied, listener);\n wrapped = listeners.wrapped[listenerIndex];\n }\n\n if (type === 'all') {\n for (type in target.events) {\n if (target.events.hasOwnProperty(type)) {\n remove(element, type, 'all');\n }\n }\n return;\n }\n\n if (target.events[type]) {\n var len = target.events[type].length;\n\n if (listener === 'all') {\n for (i = 0; i < len; i++) {\n remove(element, type, target.events[type][i], Boolean(useCapture));\n }\n return;\n } else {\n for (i = 0; i < len; i++) {\n if (target.events[type][i] === listener) {\n element[removeEvent](on + type, wrapped, useCapture || false);\n target.events[type].splice(i, 1);\n\n if (useAttachEvent && listeners) {\n listeners.useCount[listenerIndex]--;\n if (listeners.useCount[listenerIndex] === 0) {\n listeners.supplied.splice(listenerIndex, 1);\n listeners.wrapped.splice(listenerIndex, 1);\n listeners.useCount.splice(listenerIndex, 1);\n }\n }\n\n break;\n }\n }\n }\n\n if (target.events[type] && target.events[type].length === 0) {\n target.events[type] = null;\n target.typeCount--;\n }\n }\n\n if (!target.typeCount) {\n targets.splice(elementIndex, 1);\n elements.splice(elementIndex, 1);\n attachedListeners.splice(elementIndex, 1);\n }\n }\n\n function preventDef () {\n this.returnValue = false;\n }\n\n function stopProp () {\n this.cancelBubble = true;\n }\n\n function stopImmProp () {\n this.cancelBubble = true;\n this.immediatePropagationStopped = true;\n }\n\n return {\n add: add,\n remove: remove,\n useAttachEvent: useAttachEvent,\n\n _elements: elements,\n _targets: targets,\n _attachedListeners: attachedListeners\n };\n }());\n\n function blank () {}\n\n function isElement (o) {\n if (!o || (typeof o !== 'object')) { return false; }\n\n var _window = getWindow(o) || window;\n\n return (/object|function/.test(typeof _window.Element)\n ? o instanceof _window.Element //DOM2\n : o.nodeType === 1 && typeof o.nodeName === \"string\");\n }\n function isWindow (thing) { return thing === window || !!(thing && thing.Window) && (thing instanceof thing.Window); }\n function isDocFrag (thing) { return !!thing && thing instanceof DocumentFragment; }\n function isArray (thing) {\n return isObject(thing)\n && (typeof thing.length !== undefined)\n && isFunction(thing.splice);\n }\n function isObject (thing) { return !!thing && (typeof thing === 'object'); }\n function isFunction (thing) { return typeof thing === 'function'; }\n function isNumber (thing) { return typeof thing === 'number' ; }\n function isBool (thing) { return typeof thing === 'boolean' ; }\n function isString (thing) { return typeof thing === 'string' ; }\n\n function trySelector (value) {\n if (!isString(value)) { return false; }\n\n // an exception will be raised if it is invalid\n document.querySelector(value);\n return true;\n }\n\n function extend (dest, source) {\n for (var prop in source) {\n dest[prop] = source[prop];\n }\n return dest;\n }\n\n var prefixedPropREs = {\n webkit: /(Movement[XY]|Radius[XY]|RotationAngle|Force)$/\n };\n\n function pointerExtend (dest, source) {\n for (var prop in source) {\n var deprecated = false;\n\n // skip deprecated prefixed properties\n for (var vendor in prefixedPropREs) {\n if (prop.indexOf(vendor) === 0 && prefixedPropREs[vendor].test(prop)) {\n deprecated = true;\n break;\n }\n }\n\n if (!deprecated) {\n dest[prop] = source[prop];\n }\n }\n return dest;\n }\n\n function copyCoords (dest, src) {\n dest.page = dest.page || {};\n dest.page.x = src.page.x;\n dest.page.y = src.page.y;\n\n dest.client = dest.client || {};\n dest.client.x = src.client.x;\n dest.client.y = src.client.y;\n\n dest.timeStamp = src.timeStamp;\n }\n\n function setEventXY (targetObj, pointers, interaction) {\n var pointer = (pointers.length > 1\n ? pointerAverage(pointers)\n : pointers[0]);\n\n getPageXY(pointer, tmpXY, interaction);\n targetObj.page.x = tmpXY.x;\n targetObj.page.y = tmpXY.y;\n\n getClientXY(pointer, tmpXY, interaction);\n targetObj.client.x = tmpXY.x;\n targetObj.client.y = tmpXY.y;\n\n targetObj.timeStamp = new Date().getTime();\n }\n\n function setEventDeltas (targetObj, prev, cur) {\n targetObj.page.x = cur.page.x - prev.page.x;\n targetObj.page.y = cur.page.y - prev.page.y;\n targetObj.client.x = cur.client.x - prev.client.x;\n targetObj.client.y = cur.client.y - prev.client.y;\n targetObj.timeStamp = new Date().getTime() - prev.timeStamp;\n\n // set pointer velocity\n var dt = Math.max(targetObj.timeStamp / 1000, 0.001);\n targetObj.page.speed = hypot(targetObj.page.x, targetObj.page.y) / dt;\n targetObj.page.vx = targetObj.page.x / dt;\n targetObj.page.vy = targetObj.page.y / dt;\n\n targetObj.client.speed = hypot(targetObj.client.x, targetObj.page.y) / dt;\n targetObj.client.vx = targetObj.client.x / dt;\n targetObj.client.vy = targetObj.client.y / dt;\n }\n\n function isNativePointer (pointer) {\n return (pointer instanceof window.Event\n || (supportsTouch && window.Touch && pointer instanceof window.Touch));\n }\n\n // Get specified X/Y coords for mouse or event.touches[0]\n function getXY (type, pointer, xy) {\n xy = xy || {};\n type = type || 'page';\n\n xy.x = pointer[type + 'X'];\n xy.y = pointer[type + 'Y'];\n\n return xy;\n }\n\n function getPageXY (pointer, page) {\n page = page || {};\n\n // Opera Mobile handles the viewport and scrolling oddly\n if (isOperaMobile && isNativePointer(pointer)) {\n getXY('screen', pointer, page);\n\n page.x += window.scrollX;\n page.y += window.scrollY;\n }\n else {\n getXY('page', pointer, page);\n }\n\n return page;\n }\n\n function getClientXY (pointer, client) {\n client = client || {};\n\n if (isOperaMobile && isNativePointer(pointer)) {\n // Opera Mobile handles the viewport and scrolling oddly\n getXY('screen', pointer, client);\n }\n else {\n getXY('client', pointer, client);\n }\n\n return client;\n }\n\n function getScrollXY (win) {\n win = win || window;\n return {\n x: win.scrollX || win.document.documentElement.scrollLeft,\n y: win.scrollY || win.document.documentElement.scrollTop\n };\n }\n\n function getPointerId (pointer) {\n return isNumber(pointer.pointerId)? pointer.pointerId : pointer.identifier;\n }\n\n function getActualElement (element) {\n return (element instanceof SVGElementInstance\n ? element.correspondingUseElement\n : element);\n }\n\n function getWindow (node) {\n if (isWindow(node)) {\n return node;\n }\n\n var rootNode = (node.ownerDocument || node);\n\n return rootNode.defaultView || rootNode.parentWindow || window;\n }\n\n function getElementClientRect (element) {\n var clientRect = (element instanceof SVGElement\n ? element.getBoundingClientRect()\n : element.getClientRects()[0]);\n\n return clientRect && {\n left : clientRect.left,\n right : clientRect.right,\n top : clientRect.top,\n bottom: clientRect.bottom,\n width : clientRect.width || clientRect.right - clientRect.left,\n height: clientRect.height || clientRect.bottom - clientRect.top\n };\n }\n\n function getElementRect (element) {\n var clientRect = getElementClientRect(element);\n\n if (!isIOS7 && clientRect) {\n var scroll = getScrollXY(getWindow(element));\n\n clientRect.left += scroll.x;\n clientRect.right += scroll.x;\n clientRect.top += scroll.y;\n clientRect.bottom += scroll.y;\n }\n\n return clientRect;\n }\n\n function getTouchPair (event) {\n var touches = [];\n\n // array of touches is supplied\n if (isArray(event)) {\n touches[0] = event[0];\n touches[1] = event[1];\n }\n // an event\n else {\n if (event.type === 'touchend') {\n if (event.touches.length === 1) {\n touches[0] = event.touches[0];\n touches[1] = event.changedTouches[0];\n }\n else if (event.touches.length === 0) {\n touches[0] = event.changedTouches[0];\n touches[1] = event.changedTouches[1];\n }\n }\n else {\n touches[0] = event.touches[0];\n touches[1] = event.touches[1];\n }\n }\n\n return touches;\n }\n\n function pointerAverage (pointers) {\n var average = {\n pageX : 0,\n pageY : 0,\n clientX: 0,\n clientY: 0,\n screenX: 0,\n screenY: 0\n };\n var prop;\n\n for (var i = 0; i < pointers.length; i++) {\n for (prop in average) {\n average[prop] += pointers[i][prop];\n }\n }\n for (prop in average) {\n average[prop] /= pointers.length;\n }\n\n return average;\n }\n\n function touchBBox (event) {\n if (!event.length && !(event.touches && event.touches.length > 1)) {\n return;\n }\n\n var touches = getTouchPair(event),\n minX = Math.min(touches[0].pageX, touches[1].pageX),\n minY = Math.min(touches[0].pageY, touches[1].pageY),\n maxX = Math.max(touches[0].pageX, touches[1].pageX),\n maxY = Math.max(touches[0].pageY, touches[1].pageY);\n\n return {\n x: minX,\n y: minY,\n left: minX,\n top: minY,\n width: maxX - minX,\n height: maxY - minY\n };\n }\n\n function touchDistance (event, deltaSource) {\n deltaSource = deltaSource || defaultOptions.deltaSource;\n\n var sourceX = deltaSource + 'X',\n sourceY = deltaSource + 'Y',\n touches = getTouchPair(event);\n\n\n var dx = touches[0][sourceX] - touches[1][sourceX],\n dy = touches[0][sourceY] - touches[1][sourceY];\n\n return hypot(dx, dy);\n }\n\n function touchAngle (event, prevAngle, deltaSource) {\n deltaSource = deltaSource || defaultOptions.deltaSource;\n\n var sourceX = deltaSource + 'X',\n sourceY = deltaSource + 'Y',\n touches = getTouchPair(event),\n dx = touches[0][sourceX] - touches[1][sourceX],\n dy = touches[0][sourceY] - touches[1][sourceY],\n angle = 180 * Math.atan(dy / dx) / Math.PI;\n\n if (isNumber(prevAngle)) {\n var dr = angle - prevAngle,\n drClamped = dr % 360;\n\n if (drClamped > 315) {\n angle -= 360 + (angle / 360)|0 * 360;\n }\n else if (drClamped > 135) {\n angle -= 180 + (angle / 360)|0 * 360;\n }\n else if (drClamped < -315) {\n angle += 360 + (angle / 360)|0 * 360;\n }\n else if (drClamped < -135) {\n angle += 180 + (angle / 360)|0 * 360;\n }\n }\n\n return angle;\n }\n\n function getOriginXY (interactable, element) {\n var origin = interactable\n ? interactable.options.origin\n : defaultOptions.origin;\n\n if (origin === 'parent') {\n origin = parentElement(element);\n }\n else if (origin === 'self') {\n origin = interactable.getRect(element);\n }\n else if (trySelector(origin)) {\n origin = closest(element, origin) || { x: 0, y: 0 };\n }\n\n if (isFunction(origin)) {\n origin = origin(interactable && element);\n }\n\n if (isElement(origin)) {\n origin = getElementRect(origin);\n }\n\n origin.x = ('x' in origin)? origin.x : origin.left;\n origin.y = ('y' in origin)? origin.y : origin.top;\n\n return origin;\n }\n\n // http://stackoverflow.com/a/5634528/2280888\n function _getQBezierValue(t, p1, p2, p3) {\n var iT = 1 - t;\n return iT * iT * p1 + 2 * iT * t * p2 + t * t * p3;\n }\n\n function getQuadraticCurvePoint(startX, startY, cpX, cpY, endX, endY, position) {\n return {\n x: _getQBezierValue(position, startX, cpX, endX),\n y: _getQBezierValue(position, startY, cpY, endY)\n };\n }\n\n // http://gizma.com/easing/\n function easeOutQuad (t, b, c, d) {\n t /= d;\n return -c * t*(t-2) + b;\n }\n\n function nodeContains (parent, child) {\n while (child) {\n if (child === parent) {\n return true;\n }\n\n child = child.parentNode;\n }\n\n return false;\n }\n\n function closest (child, selector) {\n var parent = parentElement(child);\n\n while (isElement(parent)) {\n if (matchesSelector(parent, selector)) { return parent; }\n\n parent = parentElement(parent);\n }\n\n return null;\n }\n\n function parentElement (node) {\n var parent = node.parentNode;\n\n if (isDocFrag(parent)) {\n // skip past #shado-root fragments\n while ((parent = parent.host) && isDocFrag(parent)) {}\n\n return parent;\n }\n\n return parent;\n }\n\n function inContext (interactable, element) {\n return interactable._context === element.ownerDocument\n || nodeContains(interactable._context, element);\n }\n\n function testIgnore (interactable, interactableElement, element) {\n var ignoreFrom = interactable.options.ignoreFrom;\n\n if (!ignoreFrom || !isElement(element)) { return false; }\n\n if (isString(ignoreFrom)) {\n return matchesUpTo(element, ignoreFrom, interactableElement);\n }\n else if (isElement(ignoreFrom)) {\n return nodeContains(ignoreFrom, element);\n }\n\n return false;\n }\n\n function testAllow (interactable, interactableElement, element) {\n var allowFrom = interactable.options.allowFrom;\n\n if (!allowFrom) { return true; }\n\n if (!isElement(element)) { return false; }\n\n if (isString(allowFrom)) {\n return matchesUpTo(element, allowFrom, interactableElement);\n }\n else if (isElement(allowFrom)) {\n return nodeContains(allowFrom, element);\n }\n\n return false;\n }\n\n function checkAxis (axis, interactable) {\n if (!interactable) { return false; }\n\n var thisAxis = interactable.options.drag.axis;\n\n return (axis === 'xy' || thisAxis === 'xy' || thisAxis === axis);\n }\n\n function checkSnap (interactable, action) {\n var options = interactable.options;\n\n if (/^resize/.test(action)) {\n action = 'resize';\n }\n\n return options[action].snap && options[action].snap.enabled;\n }\n\n function checkRestrict (interactable, action) {\n var options = interactable.options;\n\n if (/^resize/.test(action)) {\n action = 'resize';\n }\n\n return options[action].restrict && options[action].restrict.enabled;\n }\n\n function checkAutoScroll (interactable, action) {\n var options = interactable.options;\n\n if (/^resize/.test(action)) {\n action = 'resize';\n }\n\n return options[action].autoScroll && options[action].autoScroll.enabled;\n }\n\n function withinInteractionLimit (interactable, element, action) {\n var options = interactable.options,\n maxActions = options[action.name].max,\n maxPerElement = options[action.name].maxPerElement,\n activeInteractions = 0,\n targetCount = 0,\n targetElementCount = 0;\n\n for (var i = 0, len = interactions.length; i < len; i++) {\n var interaction = interactions[i],\n otherAction = interaction.prepared.name,\n active = interaction.interacting();\n\n if (!active) { continue; }\n\n activeInteractions++;\n\n if (activeInteractions >= maxInteractions) {\n return false;\n }\n\n if (interaction.target !== interactable) { continue; }\n\n targetCount += (otherAction === action.name)|0;\n\n if (targetCount >= maxActions) {\n return false;\n }\n\n if (interaction.element === element) {\n targetElementCount++;\n\n if (otherAction !== action.name || targetElementCount >= maxPerElement) {\n return false;\n }\n }\n }\n\n return maxInteractions > 0;\n }\n\n // Test for the element that's \"above\" all other qualifiers\n function indexOfDeepestElement (elements) {\n var dropzone,\n deepestZone = elements[0],\n index = deepestZone? 0: -1,\n parent,\n deepestZoneParents = [],\n dropzoneParents = [],\n child,\n i,\n n;\n\n for (i = 1; i < elements.length; i++) {\n dropzone = elements[i];\n\n // an element might belong to multiple selector dropzones\n if (!dropzone || dropzone === deepestZone) {\n continue;\n }\n\n if (!deepestZone) {\n deepestZone = dropzone;\n index = i;\n continue;\n }\n\n // check if the deepest or current are document.documentElement or document.rootElement\n // - if the current dropzone is, do nothing and continue\n if (dropzone.parentNode === dropzone.ownerDocument) {\n continue;\n }\n // - if deepest is, update with the current dropzone and continue to next\n else if (deepestZone.parentNode === dropzone.ownerDocument) {\n deepestZone = dropzone;\n index = i;\n continue;\n }\n\n if (!deepestZoneParents.length) {\n parent = deepestZone;\n while (parent.parentNode && parent.parentNode !== parent.ownerDocument) {\n deepestZoneParents.unshift(parent);\n parent = parent.parentNode;\n }\n }\n\n // if this element is an svg element and the current deepest is\n // an HTMLElement\n if (deepestZone instanceof HTMLElement\n && dropzone instanceof SVGElement\n && !(dropzone instanceof SVGSVGElement)) {\n\n if (dropzone === deepestZone.parentNode) {\n continue;\n }\n\n parent = dropzone.ownerSVGElement;\n }\n else {\n parent = dropzone;\n }\n\n dropzoneParents = [];\n\n while (parent.parentNode !== parent.ownerDocument) {\n dropzoneParents.unshift(parent);\n parent = parent.parentNode;\n }\n\n n = 0;\n\n // get (position of last common ancestor) + 1\n while (dropzoneParents[n] && dropzoneParents[n] === deepestZoneParents[n]) {\n n++;\n }\n\n var parents = [\n dropzoneParents[n - 1],\n dropzoneParents[n],\n deepestZoneParents[n]\n ];\n\n child = parents[0].lastChild;\n\n while (child) {\n if (child === parents[1]) {\n deepestZone = dropzone;\n index = i;\n deepestZoneParents = [];\n\n break;\n }\n else if (child === parents[2]) {\n break;\n }\n\n child = child.previousSibling;\n }\n }\n\n return index;\n }\n\n function Interaction () {\n this.target = null; // current interactable being interacted with\n this.element = null; // the target element of the interactable\n this.dropTarget = null; // the dropzone a drag target might be dropped into\n this.dropElement = null; // the element at the time of checking\n this.prevDropTarget = null; // the dropzone that was recently dragged away from\n this.prevDropElement = null; // the element at the time of checking\n\n this.prepared = { // action that's ready to be fired on next move event\n name : null,\n axis : null,\n edges: null\n };\n\n this.matches = []; // all selectors that are matched by target element\n this.matchElements = []; // corresponding elements\n\n this.inertiaStatus = {\n active : false,\n smoothEnd : false,\n ending : false,\n\n startEvent: null,\n upCoords: {},\n\n xe: 0, ye: 0,\n sx: 0, sy: 0,\n\n t0: 0,\n vx0: 0, vys: 0,\n duration: 0,\n\n resumeDx: 0,\n resumeDy: 0,\n\n lambda_v0: 0,\n one_ve_v0: 0,\n i : null\n };\n\n if (isFunction(Function.prototype.bind)) {\n this.boundInertiaFrame = this.inertiaFrame.bind(this);\n this.boundSmoothEndFrame = this.smoothEndFrame.bind(this);\n }\n else {\n var that = this;\n\n this.boundInertiaFrame = function () { return that.inertiaFrame(); };\n this.boundSmoothEndFrame = function () { return that.smoothEndFrame(); };\n }\n\n this.activeDrops = {\n dropzones: [], // the dropzones that are mentioned below\n elements : [], // elements of dropzones that accept the target draggable\n rects : [] // the rects of the elements mentioned above\n };\n\n // keep track of added pointers\n this.pointers = [];\n this.pointerIds = [];\n this.downTargets = [];\n this.downTimes = [];\n this.holdTimers = [];\n\n // Previous native pointer move event coordinates\n this.prevCoords = {\n page : { x: 0, y: 0 },\n client : { x: 0, y: 0 },\n timeStamp: 0\n };\n // current native pointer move event coordinates\n this.curCoords = {\n page : { x: 0, y: 0 },\n client : { x: 0, y: 0 },\n timeStamp: 0\n };\n\n // Starting InteractEvent pointer coordinates\n this.startCoords = {\n page : { x: 0, y: 0 },\n client : { x: 0, y: 0 },\n timeStamp: 0\n };\n\n // Change in coordinates and time of the pointer\n this.pointerDelta = {\n page : { x: 0, y: 0, vx: 0, vy: 0, speed: 0 },\n client : { x: 0, y: 0, vx: 0, vy: 0, speed: 0 },\n timeStamp: 0\n };\n\n this.downEvent = null; // pointerdown/mousedown/touchstart event\n this.downPointer = {};\n\n this._eventTarget = null;\n this._curEventTarget = null;\n\n this.prevEvent = null; // previous action event\n this.tapTime = 0; // time of the most recent tap event\n this.prevTap = null;\n\n this.startOffset = { left: 0, right: 0, top: 0, bottom: 0 };\n this.restrictOffset = { left: 0, right: 0, top: 0, bottom: 0 };\n this.snapOffsets = [];\n\n this.gesture = {\n start: { x: 0, y: 0 },\n\n startDistance: 0, // distance between two touches of touchStart\n prevDistance : 0,\n distance : 0,\n\n scale: 1, // gesture.distance / gesture.startDistance\n\n startAngle: 0, // angle of line joining two touches\n prevAngle : 0 // angle of the previous gesture event\n };\n\n this.snapStatus = {\n x : 0, y : 0,\n dx : 0, dy : 0,\n realX : 0, realY : 0,\n snappedX: 0, snappedY: 0,\n targets : [],\n locked : false,\n changed : false\n };\n\n this.restrictStatus = {\n dx : 0, dy : 0,\n restrictedX: 0, restrictedY: 0,\n snap : null,\n restricted : false,\n changed : false\n };\n\n this.restrictStatus.snap = this.snapStatus;\n\n this.pointerIsDown = false;\n this.pointerWasMoved = false;\n this.gesturing = false;\n this.dragging = false;\n this.resizing = false;\n this.resizeAxes = 'xy';\n\n this.mouse = false;\n\n interactions.push(this);\n }\n\n Interaction.prototype = {\n getPageXY : function (pointer, xy) { return getPageXY(pointer, xy, this); },\n getClientXY: function (pointer, xy) { return getClientXY(pointer, xy, this); },\n setEventXY : function (target, ptr) { return setEventXY(target, ptr, this); },\n\n pointerOver: function (pointer, event, eventTarget) {\n if (this.prepared.name || !this.mouse) { return; }\n\n var curMatches = [],\n curMatchElements = [],\n prevTargetElement = this.element;\n\n this.addPointer(pointer);\n\n if (this.target\n && (testIgnore(this.target, this.element, eventTarget)\n || !testAllow(this.target, this.element, eventTarget))) {\n // if the eventTarget should be ignored or shouldn't be allowed\n // clear the previous target\n this.target = null;\n this.element = null;\n this.matches = [];\n this.matchElements = [];\n }\n\n var elementInteractable = interactables.get(eventTarget),\n elementAction = (elementInteractable\n && !testIgnore(elementInteractable, eventTarget, eventTarget)\n && testAllow(elementInteractable, eventTarget, eventTarget)\n && validateAction(\n elementInteractable.getAction(pointer, event, this, eventTarget),\n elementInteractable));\n\n if (elementAction && !withinInteractionLimit(elementInteractable, eventTarget, elementAction)) {\n elementAction = null;\n }\n\n function pushCurMatches (interactable, selector) {\n if (interactable\n && inContext(interactable, eventTarget)\n && !testIgnore(interactable, eventTarget, eventTarget)\n && testAllow(interactable, eventTarget, eventTarget)\n && matchesSelector(eventTarget, selector)) {\n\n curMatches.push(interactable);\n curMatchElements.push(eventTarget);\n }\n }\n\n if (elementAction) {\n this.target = elementInteractable;\n this.element = eventTarget;\n this.matches = [];\n this.matchElements = [];\n }\n else {\n interactables.forEachSelector(pushCurMatches);\n\n if (this.validateSelector(pointer, event, curMatches, curMatchElements)) {\n this.matches = curMatches;\n this.matchElements = curMatchElements;\n\n this.pointerHover(pointer, event, this.matches, this.matchElements);\n events.add(eventTarget,\n PointerEvent? pEventTypes.move : 'mousemove',\n listeners.pointerHover);\n }\n else if (this.target) {\n if (nodeContains(prevTargetElement, eventTarget)) {\n this.pointerHover(pointer, event, this.matches, this.matchElements);\n events.add(this.element,\n PointerEvent? pEventTypes.move : 'mousemove',\n listeners.pointerHover);\n }\n else {\n this.target = null;\n this.element = null;\n this.matches = [];\n this.matchElements = [];\n }\n }\n }\n },\n\n // Check what action would be performed on pointerMove target if a mouse\n // button were pressed and change the cursor accordingly\n pointerHover: function (pointer, event, eventTarget, curEventTarget, matches, matchElements) {\n var target = this.target;\n\n if (!this.prepared.name && this.mouse) {\n\n var action;\n\n // update pointer coords for defaultActionChecker to use\n this.setEventXY(this.curCoords, [pointer]);\n\n if (matches) {\n action = this.validateSelector(pointer, event, matches, matchElements);\n }\n else if (target) {\n action = validateAction(target.getAction(this.pointers[0], event, this, this.element), this.target);\n }\n\n if (target && target.options.styleCursor) {\n if (action) {\n target._doc.documentElement.style.cursor = getActionCursor(action);\n }\n else {\n target._doc.documentElement.style.cursor = '';\n }\n }\n }\n else if (this.prepared.name) {\n this.checkAndPreventDefault(event, target, this.element);\n }\n },\n\n pointerOut: function (pointer, event, eventTarget) {\n if (this.prepared.name) { return; }\n\n // Remove temporary event listeners for selector Interactables\n if (!interactables.get(eventTarget)) {\n events.remove(eventTarget,\n PointerEvent? pEventTypes.move : 'mousemove',\n listeners.pointerHover);\n }\n\n if (this.target && this.target.options.styleCursor && !this.interacting()) {\n this.target._doc.documentElement.style.cursor = '';\n }\n },\n\n selectorDown: function (pointer, event, eventTarget, curEventTarget) {\n var that = this,\n // copy event to be used in timeout for IE8\n eventCopy = events.useAttachEvent? extend({}, event) : event,\n element = eventTarget,\n pointerIndex = this.addPointer(pointer),\n action;\n\n this.holdTimers[pointerIndex] = setTimeout(function () {\n that.pointerHold(events.useAttachEvent? eventCopy : pointer, eventCopy, eventTarget, curEventTarget);\n }, defaultOptions._holdDuration);\n\n this.pointerIsDown = true;\n\n // Check if the down event hits the current inertia target\n if (this.inertiaStatus.active && this.target.selector) {\n // climb up the DOM tree from the event target\n while (isElement(element)) {\n\n // if this element is the current inertia target element\n if (element === this.element\n // and the prospective action is the same as the ongoing one\n && validateAction(this.target.getAction(pointer, event, this, this.element), this.target).name === this.prepared.name) {\n\n // stop inertia so that the next move will be a normal one\n cancelFrame(this.inertiaStatus.i);\n this.inertiaStatus.active = false;\n\n this.collectEventTargets(pointer, event, eventTarget, 'down');\n return;\n }\n element = parentElement(element);\n }\n }\n\n // do nothing if interacting\n if (this.interacting()) {\n this.collectEventTargets(pointer, event, eventTarget, 'down');\n return;\n }\n\n function pushMatches (interactable, selector, context) {\n var elements = ie8MatchesSelector\n ? context.querySelectorAll(selector)\n : undefined;\n\n if (inContext(interactable, element)\n && !testIgnore(interactable, element, eventTarget)\n && testAllow(interactable, element, eventTarget)\n && matchesSelector(element, selector, elements)) {\n\n that.matches.push(interactable);\n that.matchElements.push(element);\n }\n }\n\n // update pointer coords for defaultActionChecker to use\n this.setEventXY(this.curCoords, [pointer]);\n this.downEvent = event;\n\n while (isElement(element) && !action) {\n this.matches = [];\n this.matchElements = [];\n\n interactables.forEachSelector(pushMatches);\n\n action = this.validateSelector(pointer, event, this.matches, this.matchElements);\n element = parentElement(element);\n }\n\n if (action) {\n this.prepared.name = action.name;\n this.prepared.axis = action.axis;\n this.prepared.edges = action.edges;\n\n this.collectEventTargets(pointer, event, eventTarget, 'down');\n\n return this.pointerDown(pointer, event, eventTarget, curEventTarget, action);\n }\n else {\n // do these now since pointerDown isn't being called from here\n this.downTimes[pointerIndex] = new Date().getTime();\n this.downTargets[pointerIndex] = eventTarget;\n pointerExtend(this.downPointer, pointer);\n\n copyCoords(this.prevCoords, this.curCoords);\n this.pointerWasMoved = false;\n }\n\n this.collectEventTargets(pointer, event, eventTarget, 'down');\n },\n\n // Determine action to be performed on next pointerMove and add appropriate\n // style and event Listeners\n pointerDown: function (pointer, event, eventTarget, curEventTarget, forceAction) {\n if (!forceAction && !this.inertiaStatus.active && this.pointerWasMoved && this.prepared.name) {\n this.checkAndPreventDefault(event, this.target, this.element);\n\n return;\n }\n\n this.pointerIsDown = true;\n this.downEvent = event;\n\n var pointerIndex = this.addPointer(pointer),\n action;\n\n // If it is the second touch of a multi-touch gesture, keep the\n // target the same and get a new action if a target was set by the\n // first touch\n if (this.pointerIds.length > 1 && this.target._element === this.element) {\n var newAction = validateAction(forceAction || this.target.getAction(pointer, event, this, this.element), this.target);\n\n if (withinInteractionLimit(this.target, this.element, newAction)) {\n action = newAction;\n }\n\n this.prepared.name = null;\n }\n // Otherwise, set the target if there is no action prepared\n else if (!this.prepared.name) {\n var interactable = interactables.get(curEventTarget);\n\n if (interactable\n && !testIgnore(interactable, curEventTarget, eventTarget)\n && testAllow(interactable, curEventTarget, eventTarget)\n && (action = validateAction(forceAction || interactable.getAction(pointer, event, this, curEventTarget), interactable, eventTarget))\n && withinInteractionLimit(interactable, curEventTarget, action)) {\n this.target = interactable;\n this.element = curEventTarget;\n }\n }\n\n var target = this.target,\n options = target && target.options;\n\n if (target && (forceAction || !this.prepared.name)) {\n action = action || validateAction(forceAction || target.getAction(pointer, event, this, curEventTarget), target, this.element);\n\n this.setEventXY(this.startCoords, this.pointers);\n\n if (!action) { return; }\n\n if (options.styleCursor) {\n target._doc.documentElement.style.cursor = getActionCursor(action);\n }\n\n this.resizeAxes = action.name === 'resize'? action.axis : null;\n\n if (action === 'gesture' && this.pointerIds.length < 2) {\n action = null;\n }\n\n this.prepared.name = action.name;\n this.prepared.axis = action.axis;\n this.prepared.edges = action.edges;\n\n this.snapStatus.snappedX = this.snapStatus.snappedY =\n this.restrictStatus.restrictedX = this.restrictStatus.restrictedY = NaN;\n\n this.downTimes[pointerIndex] = new Date().getTime();\n this.downTargets[pointerIndex] = eventTarget;\n pointerExtend(this.downPointer, pointer);\n\n copyCoords(this.prevCoords, this.startCoords);\n this.pointerWasMoved = false;\n\n this.checkAndPreventDefault(event, target, this.element);\n }\n // if inertia is active try to resume action\n else if (this.inertiaStatus.active\n && curEventTarget === this.element\n && validateAction(target.getAction(pointer, event, this, this.element), target).name === this.prepared.name) {\n\n cancelFrame(this.inertiaStatus.i);\n this.inertiaStatus.active = false;\n\n this.checkAndPreventDefault(event, target, this.element);\n }\n },\n\n setModifications: function (coords, preEnd) {\n var target = this.target,\n shouldMove = true,\n shouldSnap = checkSnap(target, this.prepared.name) && (!target.options[this.prepared.name].snap.endOnly || preEnd),\n shouldRestrict = checkRestrict(target, this.prepared.name) && (!target.options[this.prepared.name].restrict.endOnly || preEnd);\n\n if (shouldSnap ) { this.setSnapping (coords); } else { this.snapStatus .locked = false; }\n if (shouldRestrict) { this.setRestriction(coords); } else { this.restrictStatus.restricted = false; }\n\n if (shouldSnap && this.snapStatus.locked && !this.snapStatus.changed) {\n shouldMove = shouldRestrict && this.restrictStatus.restricted && this.restrictStatus.changed;\n }\n else if (shouldRestrict && this.restrictStatus.restricted && !this.restrictStatus.changed) {\n shouldMove = false;\n }\n\n return shouldMove;\n },\n\n setStartOffsets: function (action, interactable, element) {\n var rect = interactable.getRect(element),\n origin = getOriginXY(interactable, element),\n snap = interactable.options[this.prepared.name].snap,\n restrict = interactable.options[this.prepared.name].restrict,\n width, height;\n\n if (rect) {\n this.startOffset.left = this.startCoords.page.x - rect.left;\n this.startOffset.top = this.startCoords.page.y - rect.top;\n\n this.startOffset.right = rect.right - this.startCoords.page.x;\n this.startOffset.bottom = rect.bottom - this.startCoords.page.y;\n\n if ('width' in rect) { width = rect.width; }\n else { width = rect.right - rect.left; }\n if ('height' in rect) { height = rect.height; }\n else { height = rect.bottom - rect.top; }\n }\n else {\n this.startOffset.left = this.startOffset.top = this.startOffset.right = this.startOffset.bottom = 0;\n }\n\n this.snapOffsets.splice(0);\n\n var snapOffset = snap && snap.offset === 'startCoords'\n ? {\n x: this.startCoords.page.x - origin.x,\n y: this.startCoords.page.y - origin.y\n }\n : snap && snap.offset || { x: 0, y: 0 };\n\n if (rect && snap && snap.relativePoints && snap.relativePoints.length) {\n for (var i = 0; i < snap.relativePoints.length; i++) {\n this.snapOffsets.push({\n x: this.startOffset.left - (width * snap.relativePoints[i].x) + snapOffset.x,\n y: this.startOffset.top - (height * snap.relativePoints[i].y) + snapOffset.y\n });\n }\n }\n else {\n this.snapOffsets.push(snapOffset);\n }\n\n if (rect && restrict.elementRect) {\n this.restrictOffset.left = this.startOffset.left - (width * restrict.elementRect.left);\n this.restrictOffset.top = this.startOffset.top - (height * restrict.elementRect.top);\n\n this.restrictOffset.right = this.startOffset.right - (width * (1 - restrict.elementRect.right));\n this.restrictOffset.bottom = this.startOffset.bottom - (height * (1 - restrict.elementRect.bottom));\n }\n else {\n this.restrictOffset.left = this.restrictOffset.top = this.restrictOffset.right = this.restrictOffset.bottom = 0;\n }\n },\n\n /*\\\n * Interaction.start\n [ method ]\n *\n * Start an action with the given Interactable and Element as tartgets. The\n * action must be enabled for the target Interactable and an appropriate number\n * of pointers must be held down – 1 for drag/resize, 2 for gesture.\n *\n * Use it with `interactable.able({ manualStart: false })` to always\n * [start actions manually](https://github.com/taye/interact.js/issues/114)\n *\n - action (object) The action to be performed - drag, resize, etc.\n - interactable (Interactable) The Interactable to target\n - element (Element) The DOM Element to target\n = (object) interact\n **\n | interact(target)\n | .draggable({\n | // disable the default drag start by down->move\n | manualStart: true\n | })\n | // start dragging after the user holds the pointer down\n | .on('hold', function (event) {\n | var interaction = event.interaction;\n |\n | if (!interaction.interacting()) {\n | interaction.start({ name: 'drag' },\n | event.interactable,\n | event.currentTarget);\n | }\n | });\n \\*/\n start: function (action, interactable, element) {\n if (this.interacting()\n || !this.pointerIsDown\n || this.pointerIds.length < (action.name === 'gesture'? 2 : 1)) {\n return;\n }\n\n // if this interaction had been removed after stopping\n // add it back\n if (indexOf(interactions, this) === -1) {\n interactions.push(this);\n }\n\n // set the startCoords if there was no prepared action\n if (!this.prepared.name) {\n this.setEventXY(this.startCoords);\n }\n\n this.prepared.name = action.name;\n this.prepared.axis = action.axis;\n this.prepared.edges = action.edges;\n this.target = interactable;\n this.element = element;\n\n this.setStartOffsets(action.name, interactable, element);\n this.setModifications(this.startCoords.page);\n\n this.prevEvent = this[this.prepared.name + 'Start'](this.downEvent);\n },\n\n pointerMove: function (pointer, event, eventTarget, curEventTarget, preEnd) {\n if (this.inertiaStatus.active) {\n var pageUp = this.inertiaStatus.upCoords.page;\n var clientUp = this.inertiaStatus.upCoords.client;\n\n var inertiaPosition = {\n pageX : pageUp.x + this.inertiaStatus.sx,\n pageY : pageUp.y + this.inertiaStatus.sy,\n clientX: clientUp.x + this.inertiaStatus.sx,\n clientY: clientUp.y + this.inertiaStatus.sy\n };\n\n this.setEventXY(this.curCoords, [inertiaPosition]);\n }\n else {\n this.recordPointer(pointer);\n this.setEventXY(this.curCoords, this.pointers);\n }\n\n var duplicateMove = (this.curCoords.page.x === this.prevCoords.page.x\n && this.curCoords.page.y === this.prevCoords.page.y\n && this.curCoords.client.x === this.prevCoords.client.x\n && this.curCoords.client.y === this.prevCoords.client.y);\n\n var dx, dy,\n pointerIndex = this.mouse? 0 : indexOf(this.pointerIds, getPointerId(pointer));\n\n // register movement greater than pointerMoveTolerance\n if (this.pointerIsDown && !this.pointerWasMoved) {\n dx = this.curCoords.client.x - this.startCoords.client.x;\n dy = this.curCoords.client.y - this.startCoords.client.y;\n\n this.pointerWasMoved = hypot(dx, dy) > pointerMoveTolerance;\n }\n\n if (!duplicateMove && (!this.pointerIsDown || this.pointerWasMoved)) {\n if (this.pointerIsDown) {\n clearTimeout(this.holdTimers[pointerIndex]);\n }\n\n this.collectEventTargets(pointer, event, eventTarget, 'move');\n }\n\n if (!this.pointerIsDown) { return; }\n\n if (duplicateMove && this.pointerWasMoved && !preEnd) {\n this.checkAndPreventDefault(event, this.target, this.element);\n return;\n }\n\n // set pointer coordinate, time changes and speeds\n setEventDeltas(this.pointerDelta, this.prevCoords, this.curCoords);\n\n if (!this.prepared.name) { return; }\n\n if (this.pointerWasMoved\n // ignore movement while inertia is active\n && (!this.inertiaStatus.active || (pointer instanceof InteractEvent && /inertiastart/.test(pointer.type)))) {\n\n // if just starting an action, calculate the pointer speed now\n if (!this.interacting()) {\n setEventDeltas(this.pointerDelta, this.prevCoords, this.curCoords);\n\n // check if a drag is in the correct axis\n if (this.prepared.name === 'drag') {\n var absX = Math.abs(dx),\n absY = Math.abs(dy),\n targetAxis = this.target.options.drag.axis,\n axis = (absX > absY ? 'x' : absX < absY ? 'y' : 'xy');\n\n // if the movement isn't in the axis of the interactable\n if (axis !== 'xy' && targetAxis !== 'xy' && targetAxis !== axis) {\n // cancel the prepared action\n this.prepared.name = null;\n\n // then try to get a drag from another ineractable\n\n var element = eventTarget;\n\n // check element interactables\n while (isElement(element)) {\n var elementInteractable = interactables.get(element);\n\n if (elementInteractable\n && elementInteractable !== this.target\n && !elementInteractable.options.drag.manualStart\n && elementInteractable.getAction(this.downPointer, this.downEvent, this, element).name === 'drag'\n && checkAxis(axis, elementInteractable)) {\n\n this.prepared.name = 'drag';\n this.target = elementInteractable;\n this.element = element;\n break;\n }\n\n element = parentElement(element);\n }\n\n // if there's no drag from element interactables,\n // check the selector interactables\n if (!this.prepared.name) {\n var thisInteraction = this;\n\n var getDraggable = function (interactable, selector, context) {\n var elements = ie8MatchesSelector\n ? context.querySelectorAll(selector)\n : undefined;\n\n if (interactable === thisInteraction.target) { return; }\n\n if (inContext(interactable, eventTarget)\n && !interactable.options.drag.manualStart\n && !testIgnore(interactable, element, eventTarget)\n && testAllow(interactable, element, eventTarget)\n && matchesSelector(element, selector, elements)\n && interactable.getAction(thisInteraction.downPointer, thisInteraction.downEvent, thisInteraction, element).name === 'drag'\n && checkAxis(axis, interactable)\n && withinInteractionLimit(interactable, element, 'drag')) {\n\n return interactable;\n }\n };\n\n element = eventTarget;\n\n while (isElement(element)) {\n var selectorInteractable = interactables.forEachSelector(getDraggable);\n\n if (selectorInteractable) {\n this.prepared.name = 'drag';\n this.target = selectorInteractable;\n this.element = element;\n break;\n }\n\n element = parentElement(element);\n }\n }\n }\n }\n }\n\n var starting = !!this.prepared.name && !this.interacting();\n\n if (starting\n && (this.target.options[this.prepared.name].manualStart\n || !withinInteractionLimit(this.target, this.element, this.prepared))) {\n this.stop(event);\n return;\n }\n\n if (this.prepared.name && this.target) {\n if (starting) {\n this.start(this.prepared, this.target, this.element);\n }\n\n var shouldMove = this.setModifications(this.curCoords.page, preEnd);\n\n // move if snapping or restriction doesn't prevent it\n if (shouldMove || starting) {\n this.prevEvent = this[this.prepared.name + 'Move'](event);\n }\n\n this.checkAndPreventDefault(event, this.target, this.element);\n }\n }\n\n copyCoords(this.prevCoords, this.curCoords);\n\n if (this.dragging || this.resizing) {\n this.autoScrollMove(pointer);\n }\n },\n\n dragStart: function (event) {\n var dragEvent = new InteractEvent(this, event, 'drag', 'start', this.element);\n\n this.dragging = true;\n this.target.fire(dragEvent);\n\n // reset active dropzones\n this.activeDrops.dropzones = [];\n this.activeDrops.elements = [];\n this.activeDrops.rects = [];\n\n if (!this.dynamicDrop) {\n this.setActiveDrops(this.element);\n }\n\n var dropEvents = this.getDropEvents(event, dragEvent);\n\n if (dropEvents.activate) {\n this.fireActiveDrops(dropEvents.activate);\n }\n\n return dragEvent;\n },\n\n dragMove: function (event) {\n var target = this.target,\n dragEvent = new InteractEvent(this, event, 'drag', 'move', this.element),\n draggableElement = this.element,\n drop = this.getDrop(dragEvent, event, draggableElement);\n\n this.dropTarget = drop.dropzone;\n this.dropElement = drop.element;\n\n var dropEvents = this.getDropEvents(event, dragEvent);\n\n target.fire(dragEvent);\n\n if (dropEvents.leave) { this.prevDropTarget.fire(dropEvents.leave); }\n if (dropEvents.enter) { this.dropTarget.fire(dropEvents.enter); }\n if (dropEvents.move ) { this.dropTarget.fire(dropEvents.move ); }\n\n this.prevDropTarget = this.dropTarget;\n this.prevDropElement = this.dropElement;\n\n return dragEvent;\n },\n\n resizeStart: function (event) {\n var resizeEvent = new InteractEvent(this, event, 'resize', 'start', this.element);\n\n if (this.prepared.edges) {\n var startRect = this.target.getRect(this.element);\n\n /*\n * When using the `resizable.square` or `resizable.preserveAspectRatio` options, resizing from one edge\n * will affect another. E.g. with `resizable.square`, resizing to make the right edge larger will make\n * the bottom edge larger by the same amount. We call these 'linked' edges. Any linked edges will depend\n * on the active edges and the edge being interacted with.\n */\n if (this.target.options.resize.square || this.target.options.resize.preserveAspectRatio) {\n var linkedEdges = extend({}, this.prepared.edges);\n\n linkedEdges.top = linkedEdges.top || (linkedEdges.left && !linkedEdges.bottom);\n linkedEdges.left = linkedEdges.left || (linkedEdges.top && !linkedEdges.right );\n linkedEdges.bottom = linkedEdges.bottom || (linkedEdges.right && !linkedEdges.top );\n linkedEdges.right = linkedEdges.right || (linkedEdges.bottom && !linkedEdges.left );\n\n this.prepared._linkedEdges = linkedEdges;\n }\n else {\n this.prepared._linkedEdges = null;\n }\n\n // if using `resizable.preserveAspectRatio` option, record aspect ratio at the start of the resize\n if (this.target.options.resize.preserveAspectRatio) {\n this.resizeStartAspectRatio = startRect.width / startRect.height;\n }\n\n this.resizeRects = {\n start : startRect,\n current : extend({}, startRect),\n restricted: extend({}, startRect),\n previous : extend({}, startRect),\n delta : {\n left: 0, right : 0, width : 0,\n top : 0, bottom: 0, height: 0\n }\n };\n\n resizeEvent.rect = this.resizeRects.restricted;\n resizeEvent.deltaRect = this.resizeRects.delta;\n }\n\n this.target.fire(resizeEvent);\n\n this.resizing = true;\n\n return resizeEvent;\n },\n\n resizeMove: function (event) {\n var resizeEvent = new InteractEvent(this, event, 'resize', 'move', this.element);\n\n var edges = this.prepared.edges,\n invert = this.target.options.resize.invert,\n invertible = invert === 'reposition' || invert === 'negate';\n\n if (edges) {\n var dx = resizeEvent.dx,\n dy = resizeEvent.dy,\n\n start = this.resizeRects.start,\n current = this.resizeRects.current,\n restricted = this.resizeRects.restricted,\n delta = this.resizeRects.delta,\n previous = extend(this.resizeRects.previous, restricted),\n\n originalEdges = edges;\n\n // `resize.preserveAspectRatio` takes precedence over `resize.square`\n if (this.target.options.resize.preserveAspectRatio) {\n var resizeStartAspectRatio = this.resizeStartAspectRatio;\n\n edges = this.prepared._linkedEdges;\n\n if ((originalEdges.left && originalEdges.bottom)\n || (originalEdges.right && originalEdges.top)) {\n dy = -dx / resizeStartAspectRatio;\n }\n else if (originalEdges.left || originalEdges.right) { dy = dx / resizeStartAspectRatio; }\n else if (originalEdges.top || originalEdges.bottom) { dx = dy * resizeStartAspectRatio; }\n }\n else if (this.target.options.resize.square) {\n edges = this.prepared._linkedEdges;\n\n if ((originalEdges.left && originalEdges.bottom)\n || (originalEdges.right && originalEdges.top)) {\n dy = -dx;\n }\n else if (originalEdges.left || originalEdges.right) { dy = dx; }\n else if (originalEdges.top || originalEdges.bottom) { dx = dy; }\n }\n\n // update the 'current' rect without modifications\n if (edges.top ) { current.top += dy; }\n if (edges.bottom) { current.bottom += dy; }\n if (edges.left ) { current.left += dx; }\n if (edges.right ) { current.right += dx; }\n\n if (invertible) {\n // if invertible, copy the current rect\n extend(restricted, current);\n\n if (invert === 'reposition') {\n // swap edge values if necessary to keep width/height positive\n var swap;\n\n if (restricted.top > restricted.bottom) {\n swap = restricted.top;\n\n restricted.top = restricted.bottom;\n restricted.bottom = swap;\n }\n if (restricted.left > restricted.right) {\n swap = restricted.left;\n\n restricted.left = restricted.right;\n restricted.right = swap;\n }\n }\n }\n else {\n // if not invertible, restrict to minimum of 0x0 rect\n restricted.top = Math.min(current.top, start.bottom);\n restricted.bottom = Math.max(current.bottom, start.top);\n restricted.left = Math.min(current.left, start.right);\n restricted.right = Math.max(current.right, start.left);\n }\n\n restricted.width = restricted.right - restricted.left;\n restricted.height = restricted.bottom - restricted.top ;\n\n for (var edge in restricted) {\n delta[edge] = restricted[edge] - previous[edge];\n }\n\n resizeEvent.edges = this.prepared.edges;\n resizeEvent.rect = restricted;\n resizeEvent.deltaRect = delta;\n }\n\n this.target.fire(resizeEvent);\n\n return resizeEvent;\n },\n\n gestureStart: function (event) {\n var gestureEvent = new InteractEvent(this, event, 'gesture', 'start', this.element);\n\n gestureEvent.ds = 0;\n\n this.gesture.startDistance = this.gesture.prevDistance = gestureEvent.distance;\n this.gesture.startAngle = this.gesture.prevAngle = gestureEvent.angle;\n this.gesture.scale = 1;\n\n this.gesturing = true;\n\n this.target.fire(gestureEvent);\n\n return gestureEvent;\n },\n\n gestureMove: function (event) {\n if (!this.pointerIds.length) {\n return this.prevEvent;\n }\n\n var gestureEvent;\n\n gestureEvent = new InteractEvent(this, event, 'gesture', 'move', this.element);\n gestureEvent.ds = gestureEvent.scale - this.gesture.scale;\n\n this.target.fire(gestureEvent);\n\n this.gesture.prevAngle = gestureEvent.angle;\n this.gesture.prevDistance = gestureEvent.distance;\n\n if (gestureEvent.scale !== Infinity &&\n gestureEvent.scale !== null &&\n gestureEvent.scale !== undefined &&\n !isNaN(gestureEvent.scale)) {\n\n this.gesture.scale = gestureEvent.scale;\n }\n\n return gestureEvent;\n },\n\n pointerHold: function (pointer, event, eventTarget) {\n this.collectEventTargets(pointer, event, eventTarget, 'hold');\n },\n\n pointerUp: function (pointer, event, eventTarget, curEventTarget) {\n var pointerIndex = this.mouse? 0 : indexOf(this.pointerIds, getPointerId(pointer));\n\n clearTimeout(this.holdTimers[pointerIndex]);\n\n this.collectEventTargets(pointer, event, eventTarget, 'up' );\n this.collectEventTargets(pointer, event, eventTarget, 'tap');\n\n this.pointerEnd(pointer, event, eventTarget, curEventTarget);\n\n this.removePointer(pointer);\n },\n\n pointerCancel: function (pointer, event, eventTarget, curEventTarget) {\n var pointerIndex = this.mouse? 0 : indexOf(this.pointerIds, getPointerId(pointer));\n\n clearTimeout(this.holdTimers[pointerIndex]);\n\n this.collectEventTargets(pointer, event, eventTarget, 'cancel');\n this.pointerEnd(pointer, event, eventTarget, curEventTarget);\n\n this.removePointer(pointer);\n },\n\n // http://www.quirksmode.org/dom/events/click.html\n // >Events leading to dblclick\n //\n // IE8 doesn't fire down event before dblclick.\n // This workaround tries to fire a tap and doubletap after dblclick\n ie8Dblclick: function (pointer, event, eventTarget) {\n if (this.prevTap\n && event.clientX === this.prevTap.clientX\n && event.clientY === this.prevTap.clientY\n && eventTarget === this.prevTap.target) {\n\n this.downTargets[0] = eventTarget;\n this.downTimes[0] = new Date().getTime();\n this.collectEventTargets(pointer, event, eventTarget, 'tap');\n }\n },\n\n // End interact move events and stop auto-scroll unless inertia is enabled\n pointerEnd: function (pointer, event, eventTarget, curEventTarget) {\n var endEvent,\n target = this.target,\n options = target && target.options,\n inertiaOptions = options && this.prepared.name && options[this.prepared.name].inertia,\n inertiaStatus = this.inertiaStatus;\n\n if (this.interacting()) {\n\n if (inertiaStatus.active && !inertiaStatus.ending) { return; }\n\n var pointerSpeed,\n now = new Date().getTime(),\n inertiaPossible = false,\n inertia = false,\n smoothEnd = false,\n endSnap = checkSnap(target, this.prepared.name) && options[this.prepared.name].snap.endOnly,\n endRestrict = checkRestrict(target, this.prepared.name) && options[this.prepared.name].restrict.endOnly,\n dx = 0,\n dy = 0,\n startEvent;\n\n if (this.dragging) {\n if (options.drag.axis === 'x' ) { pointerSpeed = Math.abs(this.pointerDelta.client.vx); }\n else if (options.drag.axis === 'y' ) { pointerSpeed = Math.abs(this.pointerDelta.client.vy); }\n else /*options.drag.axis === 'xy'*/{ pointerSpeed = this.pointerDelta.client.speed; }\n }\n else {\n pointerSpeed = this.pointerDelta.client.speed;\n }\n\n // check if inertia should be started\n inertiaPossible = (inertiaOptions && inertiaOptions.enabled\n && this.prepared.name !== 'gesture'\n && event !== inertiaStatus.startEvent);\n\n inertia = (inertiaPossible\n && (now - this.curCoords.timeStamp) < 50\n && pointerSpeed > inertiaOptions.minSpeed\n && pointerSpeed > inertiaOptions.endSpeed);\n\n if (inertiaPossible && !inertia && (endSnap || endRestrict)) {\n\n var snapRestrict = {};\n\n snapRestrict.snap = snapRestrict.restrict = snapRestrict;\n\n if (endSnap) {\n this.setSnapping(this.curCoords.page, snapRestrict);\n if (snapRestrict.locked) {\n dx += snapRestrict.dx;\n dy += snapRestrict.dy;\n }\n }\n\n if (endRestrict) {\n this.setRestriction(this.curCoords.page, snapRestrict);\n if (snapRestrict.restricted) {\n dx += snapRestrict.dx;\n dy += snapRestrict.dy;\n }\n }\n\n if (dx || dy) {\n smoothEnd = true;\n }\n }\n\n if (inertia || smoothEnd) {\n copyCoords(inertiaStatus.upCoords, this.curCoords);\n\n this.pointers[0] = inertiaStatus.startEvent = startEvent =\n new InteractEvent(this, event, this.prepared.name, 'inertiastart', this.element);\n\n inertiaStatus.t0 = now;\n\n target.fire(inertiaStatus.startEvent);\n\n if (inertia) {\n inertiaStatus.vx0 = this.pointerDelta.client.vx;\n inertiaStatus.vy0 = this.pointerDelta.client.vy;\n inertiaStatus.v0 = pointerSpeed;\n\n this.calcInertia(inertiaStatus);\n\n var page = extend({}, this.curCoords.page),\n origin = getOriginXY(target, this.element),\n statusObject;\n\n page.x = page.x + inertiaStatus.xe - origin.x;\n page.y = page.y + inertiaStatus.ye - origin.y;\n\n statusObject = {\n useStatusXY: true,\n x: page.x,\n y: page.y,\n dx: 0,\n dy: 0,\n snap: null\n };\n\n statusObject.snap = statusObject;\n\n dx = dy = 0;\n\n if (endSnap) {\n var snap = this.setSnapping(this.curCoords.page, statusObject);\n\n if (snap.locked) {\n dx += snap.dx;\n dy += snap.dy;\n }\n }\n\n if (endRestrict) {\n var restrict = this.setRestriction(this.curCoords.page, statusObject);\n\n if (restrict.restricted) {\n dx += restrict.dx;\n dy += restrict.dy;\n }\n }\n\n inertiaStatus.modifiedXe += dx;\n inertiaStatus.modifiedYe += dy;\n\n inertiaStatus.i = reqFrame(this.boundInertiaFrame);\n }\n else {\n inertiaStatus.smoothEnd = true;\n inertiaStatus.xe = dx;\n inertiaStatus.ye = dy;\n\n inertiaStatus.sx = inertiaStatus.sy = 0;\n\n inertiaStatus.i = reqFrame(this.boundSmoothEndFrame);\n }\n\n inertiaStatus.active = true;\n return;\n }\n\n if (endSnap || endRestrict) {\n // fire a move event at the snapped coordinates\n this.pointerMove(pointer, event, eventTarget, curEventTarget, true);\n }\n }\n\n if (this.dragging) {\n endEvent = new InteractEvent(this, event, 'drag', 'end', this.element);\n\n var draggableElement = this.element,\n drop = this.getDrop(endEvent, event, draggableElement);\n\n this.dropTarget = drop.dropzone;\n this.dropElement = drop.element;\n\n var dropEvents = this.getDropEvents(event, endEvent);\n\n if (dropEvents.leave) { this.prevDropTarget.fire(dropEvents.leave); }\n if (dropEvents.enter) { this.dropTarget.fire(dropEvents.enter); }\n if (dropEvents.drop ) { this.dropTarget.fire(dropEvents.drop ); }\n if (dropEvents.deactivate) {\n this.fireActiveDrops(dropEvents.deactivate);\n }\n\n target.fire(endEvent);\n }\n else if (this.resizing) {\n endEvent = new InteractEvent(this, event, 'resize', 'end', this.element);\n target.fire(endEvent);\n }\n else if (this.gesturing) {\n endEvent = new InteractEvent(this, event, 'gesture', 'end', this.element);\n target.fire(endEvent);\n }\n\n this.stop(event);\n },\n\n collectDrops: function (element) {\n var drops = [],\n elements = [],\n i;\n\n element = element || this.element;\n\n // collect all dropzones and their elements which qualify for a drop\n for (i = 0; i < interactables.length; i++) {\n if (!interactables[i].options.drop.enabled) { continue; }\n\n var current = interactables[i],\n accept = current.options.drop.accept;\n\n // test the draggable element against the dropzone's accept setting\n if ((isElement(accept) && accept !== element)\n || (isString(accept)\n && !matchesSelector(element, accept))) {\n\n continue;\n }\n\n // query for new elements if necessary\n var dropElements = current.selector? current._context.querySelectorAll(current.selector) : [current._element];\n\n for (var j = 0, len = dropElements.length; j < len; j++) {\n var currentElement = dropElements[j];\n\n if (currentElement === element) {\n continue;\n }\n\n drops.push(current);\n elements.push(currentElement);\n }\n }\n\n return {\n dropzones: drops,\n elements: elements\n };\n },\n\n fireActiveDrops: function (event) {\n var i,\n current,\n currentElement,\n prevElement;\n\n // loop through all active dropzones and trigger event\n for (i = 0; i < this.activeDrops.dropzones.length; i++) {\n current = this.activeDrops.dropzones[i];\n currentElement = this.activeDrops.elements [i];\n\n // prevent trigger of duplicate events on same element\n if (currentElement !== prevElement) {\n // set current element as event target\n event.target = currentElement;\n current.fire(event);\n }\n prevElement = currentElement;\n }\n },\n\n // Collect a new set of possible drops and save them in activeDrops.\n // setActiveDrops should always be called when a drag has just started or a\n // drag event happens while dynamicDrop is true\n setActiveDrops: function (dragElement) {\n // get dropzones and their elements that could receive the draggable\n var possibleDrops = this.collectDrops(dragElement, true);\n\n this.activeDrops.dropzones = possibleDrops.dropzones;\n this.activeDrops.elements = possibleDrops.elements;\n this.activeDrops.rects = [];\n\n for (var i = 0; i < this.activeDrops.dropzones.length; i++) {\n this.activeDrops.rects[i] = this.activeDrops.dropzones[i].getRect(this.activeDrops.elements[i]);\n }\n },\n\n getDrop: function (dragEvent, event, dragElement) {\n var validDrops = [];\n\n if (dynamicDrop) {\n this.setActiveDrops(dragElement);\n }\n\n // collect all dropzones and their elements which qualify for a drop\n for (var j = 0; j < this.activeDrops.dropzones.length; j++) {\n var current = this.activeDrops.dropzones[j],\n currentElement = this.activeDrops.elements [j],\n rect = this.activeDrops.rects [j];\n\n validDrops.push(current.dropCheck(dragEvent, event, this.target, dragElement, currentElement, rect)\n ? currentElement\n : null);\n }\n\n // get the most appropriate dropzone based on DOM depth and order\n var dropIndex = indexOfDeepestElement(validDrops),\n dropzone = this.activeDrops.dropzones[dropIndex] || null,\n element = this.activeDrops.elements [dropIndex] || null;\n\n return {\n dropzone: dropzone,\n element: element\n };\n },\n\n getDropEvents: function (pointerEvent, dragEvent) {\n var dropEvents = {\n enter : null,\n leave : null,\n activate : null,\n deactivate: null,\n move : null,\n drop : null\n };\n\n if (this.dropElement !== this.prevDropElement) {\n // if there was a prevDropTarget, create a dragleave event\n if (this.prevDropTarget) {\n dropEvents.leave = {\n target : this.prevDropElement,\n dropzone : this.prevDropTarget,\n relatedTarget: dragEvent.target,\n draggable : dragEvent.interactable,\n dragEvent : dragEvent,\n interaction : this,\n timeStamp : dragEvent.timeStamp,\n type : 'dragleave'\n };\n\n dragEvent.dragLeave = this.prevDropElement;\n dragEvent.prevDropzone = this.prevDropTarget;\n }\n // if the dropTarget is not null, create a dragenter event\n if (this.dropTarget) {\n dropEvents.enter = {\n target : this.dropElement,\n dropzone : this.dropTarget,\n relatedTarget: dragEvent.target,\n draggable : dragEvent.interactable,\n dragEvent : dragEvent,\n interaction : this,\n timeStamp : dragEvent.timeStamp,\n type : 'dragenter'\n };\n\n dragEvent.dragEnter = this.dropElement;\n dragEvent.dropzone = this.dropTarget;\n }\n }\n\n if (dragEvent.type === 'dragend' && this.dropTarget) {\n dropEvents.drop = {\n target : this.dropElement,\n dropzone : this.dropTarget,\n relatedTarget: dragEvent.target,\n draggable : dragEvent.interactable,\n dragEvent : dragEvent,\n interaction : this,\n timeStamp : dragEvent.timeStamp,\n type : 'drop'\n };\n\n dragEvent.dropzone = this.dropTarget;\n }\n if (dragEvent.type === 'dragstart') {\n dropEvents.activate = {\n target : null,\n dropzone : null,\n relatedTarget: dragEvent.target,\n draggable : dragEvent.interactable,\n dragEvent : dragEvent,\n interaction : this,\n timeStamp : dragEvent.timeStamp,\n type : 'dropactivate'\n };\n }\n if (dragEvent.type === 'dragend') {\n dropEvents.deactivate = {\n target : null,\n dropzone : null,\n relatedTarget: dragEvent.target,\n draggable : dragEvent.interactable,\n dragEvent : dragEvent,\n interaction : this,\n timeStamp : dragEvent.timeStamp,\n type : 'dropdeactivate'\n };\n }\n if (dragEvent.type === 'dragmove' && this.dropTarget) {\n dropEvents.move = {\n target : this.dropElement,\n dropzone : this.dropTarget,\n relatedTarget: dragEvent.target,\n draggable : dragEvent.interactable,\n dragEvent : dragEvent,\n interaction : this,\n dragmove : dragEvent,\n timeStamp : dragEvent.timeStamp,\n type : 'dropmove'\n };\n dragEvent.dropzone = this.dropTarget;\n }\n\n return dropEvents;\n },\n\n currentAction: function () {\n return (this.dragging && 'drag') || (this.resizing && 'resize') || (this.gesturing && 'gesture') || null;\n },\n\n interacting: function () {\n return this.dragging || this.resizing || this.gesturing;\n },\n\n clearTargets: function () {\n this.target = this.element = null;\n\n this.dropTarget = this.dropElement = this.prevDropTarget = this.prevDropElement = null;\n },\n\n stop: function (event) {\n if (this.interacting()) {\n autoScroll.stop();\n this.matches = [];\n this.matchElements = [];\n\n var target = this.target;\n\n if (target.options.styleCursor) {\n target._doc.documentElement.style.cursor = '';\n }\n\n // prevent Default only if were previously interacting\n if (event && isFunction(event.preventDefault)) {\n this.checkAndPreventDefault(event, target, this.element);\n }\n\n if (this.dragging) {\n this.activeDrops.dropzones = this.activeDrops.elements = this.activeDrops.rects = null;\n }\n }\n\n this.clearTargets();\n\n this.pointerIsDown = this.snapStatus.locked = this.dragging = this.resizing = this.gesturing = false;\n this.prepared.name = this.prevEvent = null;\n this.inertiaStatus.resumeDx = this.inertiaStatus.resumeDy = 0;\n\n // remove pointers if their ID isn't in this.pointerIds\n for (var i = 0; i < this.pointers.length; i++) {\n if (indexOf(this.pointerIds, getPointerId(this.pointers[i])) === -1) {\n this.pointers.splice(i, 1);\n }\n }\n },\n\n inertiaFrame: function () {\n var inertiaStatus = this.inertiaStatus,\n options = this.target.options[this.prepared.name].inertia,\n lambda = options.resistance,\n t = new Date().getTime() / 1000 - inertiaStatus.t0;\n\n if (t < inertiaStatus.te) {\n\n var progress = 1 - (Math.exp(-lambda * t) - inertiaStatus.lambda_v0) / inertiaStatus.one_ve_v0;\n\n if (inertiaStatus.modifiedXe === inertiaStatus.xe && inertiaStatus.modifiedYe === inertiaStatus.ye) {\n inertiaStatus.sx = inertiaStatus.xe * progress;\n inertiaStatus.sy = inertiaStatus.ye * progress;\n }\n else {\n var quadPoint = getQuadraticCurvePoint(\n 0, 0,\n inertiaStatus.xe, inertiaStatus.ye,\n inertiaStatus.modifiedXe, inertiaStatus.modifiedYe,\n progress);\n\n inertiaStatus.sx = quadPoint.x;\n inertiaStatus.sy = quadPoint.y;\n }\n\n this.pointerMove(inertiaStatus.startEvent, inertiaStatus.startEvent);\n\n inertiaStatus.i = reqFrame(this.boundInertiaFrame);\n }\n else {\n inertiaStatus.ending = true;\n\n inertiaStatus.sx = inertiaStatus.modifiedXe;\n inertiaStatus.sy = inertiaStatus.modifiedYe;\n\n this.pointerMove(inertiaStatus.startEvent, inertiaStatus.startEvent);\n this.pointerEnd(inertiaStatus.startEvent, inertiaStatus.startEvent);\n\n inertiaStatus.active = inertiaStatus.ending = false;\n }\n },\n\n smoothEndFrame: function () {\n var inertiaStatus = this.inertiaStatus,\n t = new Date().getTime() - inertiaStatus.t0,\n duration = this.target.options[this.prepared.name].inertia.smoothEndDuration;\n\n if (t < duration) {\n inertiaStatus.sx = easeOutQuad(t, 0, inertiaStatus.xe, duration);\n inertiaStatus.sy = easeOutQuad(t, 0, inertiaStatus.ye, duration);\n\n this.pointerMove(inertiaStatus.startEvent, inertiaStatus.startEvent);\n\n inertiaStatus.i = reqFrame(this.boundSmoothEndFrame);\n }\n else {\n inertiaStatus.ending = true;\n\n inertiaStatus.sx = inertiaStatus.xe;\n inertiaStatus.sy = inertiaStatus.ye;\n\n this.pointerMove(inertiaStatus.startEvent, inertiaStatus.startEvent);\n this.pointerEnd(inertiaStatus.startEvent, inertiaStatus.startEvent);\n\n inertiaStatus.smoothEnd =\n inertiaStatus.active = inertiaStatus.ending = false;\n }\n },\n\n addPointer: function (pointer) {\n var id = getPointerId(pointer),\n index = this.mouse? 0 : indexOf(this.pointerIds, id);\n\n if (index === -1) {\n index = this.pointerIds.length;\n }\n\n this.pointerIds[index] = id;\n this.pointers[index] = pointer;\n\n return index;\n },\n\n removePointer: function (pointer) {\n var id = getPointerId(pointer),\n index = this.mouse? 0 : indexOf(this.pointerIds, id);\n\n if (index === -1) { return; }\n\n this.pointers .splice(index, 1);\n this.pointerIds .splice(index, 1);\n this.downTargets.splice(index, 1);\n this.downTimes .splice(index, 1);\n this.holdTimers .splice(index, 1);\n },\n\n recordPointer: function (pointer) {\n var index = this.mouse? 0: indexOf(this.pointerIds, getPointerId(pointer));\n\n if (index === -1) { return; }\n\n this.pointers[index] = pointer;\n },\n\n collectEventTargets: function (pointer, event, eventTarget, eventType) {\n var pointerIndex = this.mouse? 0 : indexOf(this.pointerIds, getPointerId(pointer));\n\n // do not fire a tap event if the pointer was moved before being lifted\n if (eventType === 'tap' && (this.pointerWasMoved\n // or if the pointerup target is different to the pointerdown target\n || !(this.downTargets[pointerIndex] && this.downTargets[pointerIndex] === eventTarget))) {\n return;\n }\n\n var targets = [],\n elements = [],\n element = eventTarget;\n\n function collectSelectors (interactable, selector, context) {\n var els = ie8MatchesSelector\n ? context.querySelectorAll(selector)\n : undefined;\n\n if (interactable._iEvents[eventType]\n && isElement(element)\n && inContext(interactable, element)\n && !testIgnore(interactable, element, eventTarget)\n && testAllow(interactable, element, eventTarget)\n && matchesSelector(element, selector, els)) {\n\n targets.push(interactable);\n elements.push(element);\n }\n }\n\n while (element) {\n if (interact.isSet(element) && interact(element)._iEvents[eventType]) {\n targets.push(interact(element));\n elements.push(element);\n }\n\n interactables.forEachSelector(collectSelectors);\n\n element = parentElement(element);\n }\n\n // create the tap event even if there are no listeners so that\n // doubletap can still be created and fired\n if (targets.length || eventType === 'tap') {\n this.firePointers(pointer, event, eventTarget, targets, elements, eventType);\n }\n },\n\n firePointers: function (pointer, event, eventTarget, targets, elements, eventType) {\n var pointerIndex = this.mouse? 0 : indexOf(this.pointerIds, getPointerId(pointer)),\n pointerEvent = {},\n i,\n // for tap events\n interval, createNewDoubleTap;\n\n // if it's a doubletap then the event properties would have been\n // copied from the tap event and provided as the pointer argument\n if (eventType === 'doubletap') {\n pointerEvent = pointer;\n }\n else {\n pointerExtend(pointerEvent, event);\n if (event !== pointer) {\n pointerExtend(pointerEvent, pointer);\n }\n\n pointerEvent.preventDefault = preventOriginalDefault;\n pointerEvent.stopPropagation = InteractEvent.prototype.stopPropagation;\n pointerEvent.stopImmediatePropagation = InteractEvent.prototype.stopImmediatePropagation;\n pointerEvent.interaction = this;\n\n pointerEvent.timeStamp = new Date().getTime();\n pointerEvent.originalEvent = event;\n pointerEvent.originalPointer = pointer;\n pointerEvent.type = eventType;\n pointerEvent.pointerId = getPointerId(pointer);\n pointerEvent.pointerType = this.mouse? 'mouse' : !supportsPointerEvent? 'touch'\n : isString(pointer.pointerType)\n ? pointer.pointerType\n : [,,'touch', 'pen', 'mouse'][pointer.pointerType];\n }\n\n if (eventType === 'tap') {\n pointerEvent.dt = pointerEvent.timeStamp - this.downTimes[pointerIndex];\n\n interval = pointerEvent.timeStamp - this.tapTime;\n createNewDoubleTap = !!(this.prevTap && this.prevTap.type !== 'doubletap'\n && this.prevTap.target === pointerEvent.target\n && interval < 500);\n\n pointerEvent.double = createNewDoubleTap;\n\n this.tapTime = pointerEvent.timeStamp;\n }\n\n for (i = 0; i < targets.length; i++) {\n pointerEvent.currentTarget = elements[i];\n pointerEvent.interactable = targets[i];\n targets[i].fire(pointerEvent);\n\n if (pointerEvent.immediatePropagationStopped\n ||(pointerEvent.propagationStopped && elements[i + 1] !== pointerEvent.currentTarget)) {\n break;\n }\n }\n\n if (createNewDoubleTap) {\n var doubleTap = {};\n\n extend(doubleTap, pointerEvent);\n\n doubleTap.dt = interval;\n doubleTap.type = 'doubletap';\n\n this.collectEventTargets(doubleTap, event, eventTarget, 'doubletap');\n\n this.prevTap = doubleTap;\n }\n else if (eventType === 'tap') {\n this.prevTap = pointerEvent;\n }\n },\n\n validateSelector: function (pointer, event, matches, matchElements) {\n for (var i = 0, len = matches.length; i < len; i++) {\n var match = matches[i],\n matchElement = matchElements[i],\n action = validateAction(match.getAction(pointer, event, this, matchElement), match);\n\n if (action && withinInteractionLimit(match, matchElement, action)) {\n this.target = match;\n this.element = matchElement;\n\n return action;\n }\n }\n },\n\n setSnapping: function (pageCoords, status) {\n var snap = this.target.options[this.prepared.name].snap,\n targets = [],\n target,\n page,\n i;\n\n status = status || this.snapStatus;\n\n if (status.useStatusXY) {\n page = { x: status.x, y: status.y };\n }\n else {\n var origin = getOriginXY(this.target, this.element);\n\n page = extend({}, pageCoords);\n\n page.x -= origin.x;\n page.y -= origin.y;\n }\n\n status.realX = page.x;\n status.realY = page.y;\n\n page.x = page.x - this.inertiaStatus.resumeDx;\n page.y = page.y - this.inertiaStatus.resumeDy;\n\n var len = snap.targets? snap.targets.length : 0;\n\n for (var relIndex = 0; relIndex < this.snapOffsets.length; relIndex++) {\n var relative = {\n x: page.x - this.snapOffsets[relIndex].x,\n y: page.y - this.snapOffsets[relIndex].y\n };\n\n for (i = 0; i < len; i++) {\n if (isFunction(snap.targets[i])) {\n target = snap.targets[i](relative.x, relative.y, this);\n }\n else {\n target = snap.targets[i];\n }\n\n if (!target) { continue; }\n\n targets.push({\n x: isNumber(target.x) ? (target.x + this.snapOffsets[relIndex].x) : relative.x,\n y: isNumber(target.y) ? (target.y + this.snapOffsets[relIndex].y) : relative.y,\n\n range: isNumber(target.range)? target.range: snap.range\n });\n }\n }\n\n var closest = {\n target: null,\n inRange: false,\n distance: 0,\n range: 0,\n dx: 0,\n dy: 0\n };\n\n for (i = 0, len = targets.length; i < len; i++) {\n target = targets[i];\n\n var range = target.range,\n dx = target.x - page.x,\n dy = target.y - page.y,\n distance = hypot(dx, dy),\n inRange = distance <= range;\n\n // Infinite targets count as being out of range\n // compared to non infinite ones that are in range\n if (range === Infinity && closest.inRange && closest.range !== Infinity) {\n inRange = false;\n }\n\n if (!closest.target || (inRange\n // is the closest target in range?\n ? (closest.inRange && range !== Infinity\n // the pointer is relatively deeper in this target\n ? distance / range < closest.distance / closest.range\n // this target has Infinite range and the closest doesn't\n : (range === Infinity && closest.range !== Infinity)\n // OR this target is closer that the previous closest\n || distance < closest.distance)\n // The other is not in range and the pointer is closer to this target\n : (!closest.inRange && distance < closest.distance))) {\n\n if (range === Infinity) {\n inRange = true;\n }\n\n closest.target = target;\n closest.distance = distance;\n closest.range = range;\n closest.inRange = inRange;\n closest.dx = dx;\n closest.dy = dy;\n\n status.range = range;\n }\n }\n\n var snapChanged;\n\n if (closest.target) {\n snapChanged = (status.snappedX !== closest.target.x || status.snappedY !== closest.target.y);\n\n status.snappedX = closest.target.x;\n status.snappedY = closest.target.y;\n }\n else {\n snapChanged = true;\n\n status.snappedX = NaN;\n status.snappedY = NaN;\n }\n\n status.dx = closest.dx;\n status.dy = closest.dy;\n\n status.changed = (snapChanged || (closest.inRange && !status.locked));\n status.locked = closest.inRange;\n\n return status;\n },\n\n setRestriction: function (pageCoords, status) {\n var target = this.target,\n restrict = target && target.options[this.prepared.name].restrict,\n restriction = restrict && restrict.restriction,\n page;\n\n if (!restriction) {\n return status;\n }\n\n status = status || this.restrictStatus;\n\n page = status.useStatusXY\n ? page = { x: status.x, y: status.y }\n : page = extend({}, pageCoords);\n\n if (status.snap && status.snap.locked) {\n page.x += status.snap.dx || 0;\n page.y += status.snap.dy || 0;\n }\n\n page.x -= this.inertiaStatus.resumeDx;\n page.y -= this.inertiaStatus.resumeDy;\n\n status.dx = 0;\n status.dy = 0;\n status.restricted = false;\n\n var rect, restrictedX, restrictedY;\n\n if (isString(restriction)) {\n if (restriction === 'parent') {\n restriction = parentElement(this.element);\n }\n else if (restriction === 'self') {\n restriction = target.getRect(this.element);\n }\n else {\n restriction = closest(this.element, restriction);\n }\n\n if (!restriction) { return status; }\n }\n\n if (isFunction(restriction)) {\n restriction = restriction(page.x, page.y, this.element);\n }\n\n if (isElement(restriction)) {\n restriction = getElementRect(restriction);\n }\n\n rect = restriction;\n\n if (!restriction) {\n restrictedX = page.x;\n restrictedY = page.y;\n }\n // object is assumed to have\n // x, y, width, height or\n // left, top, right, bottom\n else if ('x' in restriction && 'y' in restriction) {\n restrictedX = Math.max(Math.min(rect.x + rect.width - this.restrictOffset.right , page.x), rect.x + this.restrictOffset.left);\n restrictedY = Math.max(Math.min(rect.y + rect.height - this.restrictOffset.bottom, page.y), rect.y + this.restrictOffset.top );\n }\n else {\n restrictedX = Math.max(Math.min(rect.right - this.restrictOffset.right , page.x), rect.left + this.restrictOffset.left);\n restrictedY = Math.max(Math.min(rect.bottom - this.restrictOffset.bottom, page.y), rect.top + this.restrictOffset.top );\n }\n\n status.dx = restrictedX - page.x;\n status.dy = restrictedY - page.y;\n\n status.changed = status.restrictedX !== restrictedX || status.restrictedY !== restrictedY;\n status.restricted = !!(status.dx || status.dy);\n\n status.restrictedX = restrictedX;\n status.restrictedY = restrictedY;\n\n return status;\n },\n\n checkAndPreventDefault: function (event, interactable, element) {\n if (!(interactable = interactable || this.target)) { return; }\n\n var options = interactable.options,\n prevent = options.preventDefault;\n\n if (prevent === 'auto' && element && !/^(input|select|textarea)$/i.test(event.target.nodeName)) {\n // do not preventDefault on pointerdown if the prepared action is a drag\n // and dragging can only start from a certain direction - this allows\n // a touch to pan the viewport if a drag isn't in the right direction\n if (/down|start/i.test(event.type)\n && this.prepared.name === 'drag' && options.drag.axis !== 'xy') {\n\n return;\n }\n\n // with manualStart, only preventDefault while interacting\n if (options[this.prepared.name] && options[this.prepared.name].manualStart\n && !this.interacting()) {\n return;\n }\n\n event.preventDefault();\n return;\n }\n\n if (prevent === 'always') {\n event.preventDefault();\n return;\n }\n },\n\n calcInertia: function (status) {\n var inertiaOptions = this.target.options[this.prepared.name].inertia,\n lambda = inertiaOptions.resistance,\n inertiaDur = -Math.log(inertiaOptions.endSpeed / status.v0) / lambda;\n\n status.x0 = this.prevEvent.pageX;\n status.y0 = this.prevEvent.pageY;\n status.t0 = status.startEvent.timeStamp / 1000;\n status.sx = status.sy = 0;\n\n status.modifiedXe = status.xe = (status.vx0 - inertiaDur) / lambda;\n status.modifiedYe = status.ye = (status.vy0 - inertiaDur) / lambda;\n status.te = inertiaDur;\n\n status.lambda_v0 = lambda / status.v0;\n status.one_ve_v0 = 1 - inertiaOptions.endSpeed / status.v0;\n },\n\n autoScrollMove: function (pointer) {\n if (!(this.interacting()\n && checkAutoScroll(this.target, this.prepared.name))) {\n return;\n }\n\n if (this.inertiaStatus.active) {\n autoScroll.x = autoScroll.y = 0;\n return;\n }\n\n var top,\n right,\n bottom,\n left,\n options = this.target.options[this.prepared.name].autoScroll,\n container = options.container || getWindow(this.element);\n\n if (isWindow(container)) {\n left = pointer.clientX < autoScroll.margin;\n top = pointer.clientY < autoScroll.margin;\n right = pointer.clientX > container.innerWidth - autoScroll.margin;\n bottom = pointer.clientY > container.innerHeight - autoScroll.margin;\n }\n else {\n var rect = getElementClientRect(container);\n\n left = pointer.clientX < rect.left + autoScroll.margin;\n top = pointer.clientY < rect.top + autoScroll.margin;\n right = pointer.clientX > rect.right - autoScroll.margin;\n bottom = pointer.clientY > rect.bottom - autoScroll.margin;\n }\n\n autoScroll.x = (right ? 1: left? -1: 0);\n autoScroll.y = (bottom? 1: top? -1: 0);\n\n if (!autoScroll.isScrolling) {\n // set the autoScroll properties to those of the target\n autoScroll.margin = options.margin;\n autoScroll.speed = options.speed;\n\n autoScroll.start(this);\n }\n },\n\n _updateEventTargets: function (target, currentTarget) {\n this._eventTarget = target;\n this._curEventTarget = currentTarget;\n }\n\n };\n\n function getInteractionFromPointer (pointer, eventType, eventTarget) {\n var i = 0, len = interactions.length,\n mouseEvent = (/mouse/i.test(pointer.pointerType || eventType)\n // MSPointerEvent.MSPOINTER_TYPE_MOUSE\n || pointer.pointerType === 4),\n interaction;\n\n var id = getPointerId(pointer);\n\n // try to resume inertia with a new pointer\n if (/down|start/i.test(eventType)) {\n for (i = 0; i < len; i++) {\n interaction = interactions[i];\n\n var element = eventTarget;\n\n if (interaction.inertiaStatus.active && interaction.target.options[interaction.prepared.name].inertia.allowResume\n && (interaction.mouse === mouseEvent)) {\n while (element) {\n // if the element is the interaction element\n if (element === interaction.element) {\n return interaction;\n }\n element = parentElement(element);\n }\n }\n }\n }\n\n // if it's a mouse interaction\n if (mouseEvent || !(supportsTouch || supportsPointerEvent)) {\n\n // find a mouse interaction that's not in inertia phase\n for (i = 0; i < len; i++) {\n if (interactions[i].mouse && !interactions[i].inertiaStatus.active) {\n return interactions[i];\n }\n }\n\n // find any interaction specifically for mouse.\n // if the eventType is a mousedown, and inertia is active\n // ignore the interaction\n for (i = 0; i < len; i++) {\n if (interactions[i].mouse && !(/down/.test(eventType) && interactions[i].inertiaStatus.active)) {\n return interaction;\n }\n }\n\n // create a new interaction for mouse\n interaction = new Interaction();\n interaction.mouse = true;\n\n return interaction;\n }\n\n // get interaction that has this pointer\n for (i = 0; i < len; i++) {\n if (contains(interactions[i].pointerIds, id)) {\n return interactions[i];\n }\n }\n\n // at this stage, a pointerUp should not return an interaction\n if (/up|end|out/i.test(eventType)) {\n return null;\n }\n\n // get first idle interaction\n for (i = 0; i < len; i++) {\n interaction = interactions[i];\n\n if ((!interaction.prepared.name || (interaction.target.options.gesture.enabled))\n && !interaction.interacting()\n && !(!mouseEvent && interaction.mouse)) {\n\n return interaction;\n }\n }\n\n return new Interaction();\n }\n\n function doOnInteractions (method) {\n return (function (event) {\n var interaction,\n eventTarget = getActualElement(event.path\n ? event.path[0]\n : event.target),\n curEventTarget = getActualElement(event.currentTarget),\n i;\n\n if (supportsTouch && /touch/.test(event.type)) {\n prevTouchTime = new Date().getTime();\n\n for (i = 0; i < event.changedTouches.length; i++) {\n var pointer = event.changedTouches[i];\n\n interaction = getInteractionFromPointer(pointer, event.type, eventTarget);\n\n if (!interaction) { continue; }\n\n interaction._updateEventTargets(eventTarget, curEventTarget);\n\n interaction[method](pointer, event, eventTarget, curEventTarget);\n }\n }\n else {\n if (!supportsPointerEvent && /mouse/.test(event.type)) {\n // ignore mouse events while touch interactions are active\n for (i = 0; i < interactions.length; i++) {\n if (!interactions[i].mouse && interactions[i].pointerIsDown) {\n return;\n }\n }\n\n // try to ignore mouse events that are simulated by the browser\n // after a touch event\n if (new Date().getTime() - prevTouchTime < 500) {\n return;\n }\n }\n\n interaction = getInteractionFromPointer(event, event.type, eventTarget);\n\n if (!interaction) { return; }\n\n interaction._updateEventTargets(eventTarget, curEventTarget);\n\n interaction[method](event, event, eventTarget, curEventTarget);\n }\n });\n }\n\n function InteractEvent (interaction, event, action, phase, element, related) {\n var client,\n page,\n target = interaction.target,\n snapStatus = interaction.snapStatus,\n restrictStatus = interaction.restrictStatus,\n pointers = interaction.pointers,\n deltaSource = (target && target.options || defaultOptions).deltaSource,\n sourceX = deltaSource + 'X',\n sourceY = deltaSource + 'Y',\n options = target? target.options: defaultOptions,\n origin = getOriginXY(target, element),\n starting = phase === 'start',\n ending = phase === 'end',\n coords = starting? interaction.startCoords : interaction.curCoords;\n\n element = element || interaction.element;\n\n page = extend({}, coords.page);\n client = extend({}, coords.client);\n\n page.x -= origin.x;\n page.y -= origin.y;\n\n client.x -= origin.x;\n client.y -= origin.y;\n\n var relativePoints = options[action].snap && options[action].snap.relativePoints ;\n\n if (checkSnap(target, action) && !(starting && relativePoints && relativePoints.length)) {\n this.snap = {\n range : snapStatus.range,\n locked : snapStatus.locked,\n x : snapStatus.snappedX,\n y : snapStatus.snappedY,\n realX : snapStatus.realX,\n realY : snapStatus.realY,\n dx : snapStatus.dx,\n dy : snapStatus.dy\n };\n\n if (snapStatus.locked) {\n page.x += snapStatus.dx;\n page.y += snapStatus.dy;\n client.x += snapStatus.dx;\n client.y += snapStatus.dy;\n }\n }\n\n if (checkRestrict(target, action) && !(starting && options[action].restrict.elementRect) && restrictStatus.restricted) {\n page.x += restrictStatus.dx;\n page.y += restrictStatus.dy;\n client.x += restrictStatus.dx;\n client.y += restrictStatus.dy;\n\n this.restrict = {\n dx: restrictStatus.dx,\n dy: restrictStatus.dy\n };\n }\n\n this.pageX = page.x;\n this.pageY = page.y;\n this.clientX = client.x;\n this.clientY = client.y;\n\n this.x0 = interaction.startCoords.page.x - origin.x;\n this.y0 = interaction.startCoords.page.y - origin.y;\n this.clientX0 = interaction.startCoords.client.x - origin.x;\n this.clientY0 = interaction.startCoords.client.y - origin.y;\n this.ctrlKey = event.ctrlKey;\n this.altKey = event.altKey;\n this.shiftKey = event.shiftKey;\n this.metaKey = event.metaKey;\n this.button = event.button;\n this.buttons = event.buttons;\n this.target = element;\n this.t0 = interaction.downTimes[0];\n this.type = action + (phase || '');\n\n this.interaction = interaction;\n this.interactable = target;\n\n var inertiaStatus = interaction.inertiaStatus;\n\n if (inertiaStatus.active) {\n this.detail = 'inertia';\n }\n\n if (related) {\n this.relatedTarget = related;\n }\n\n // end event dx, dy is difference between start and end points\n if (ending) {\n if (deltaSource === 'client') {\n this.dx = client.x - interaction.startCoords.client.x;\n this.dy = client.y - interaction.startCoords.client.y;\n }\n else {\n this.dx = page.x - interaction.startCoords.page.x;\n this.dy = page.y - interaction.startCoords.page.y;\n }\n }\n else if (starting) {\n this.dx = 0;\n this.dy = 0;\n }\n // copy properties from previousmove if starting inertia\n else if (phase === 'inertiastart') {\n this.dx = interaction.prevEvent.dx;\n this.dy = interaction.prevEvent.dy;\n }\n else {\n if (deltaSource === 'client') {\n this.dx = client.x - interaction.prevEvent.clientX;\n this.dy = client.y - interaction.prevEvent.clientY;\n }\n else {\n this.dx = page.x - interaction.prevEvent.pageX;\n this.dy = page.y - interaction.prevEvent.pageY;\n }\n }\n if (interaction.prevEvent && interaction.prevEvent.detail === 'inertia'\n && !inertiaStatus.active\n && options[action].inertia && options[action].inertia.zeroResumeDelta) {\n\n inertiaStatus.resumeDx += this.dx;\n inertiaStatus.resumeDy += this.dy;\n\n this.dx = this.dy = 0;\n }\n\n if (action === 'resize' && interaction.resizeAxes) {\n if (options.resize.square) {\n if (interaction.resizeAxes === 'y') {\n this.dx = this.dy;\n }\n else {\n this.dy = this.dx;\n }\n this.axes = 'xy';\n }\n else {\n this.axes = interaction.resizeAxes;\n\n if (interaction.resizeAxes === 'x') {\n this.dy = 0;\n }\n else if (interaction.resizeAxes === 'y') {\n this.dx = 0;\n }\n }\n }\n else if (action === 'gesture') {\n this.touches = [pointers[0], pointers[1]];\n\n if (starting) {\n this.distance = touchDistance(pointers, deltaSource);\n this.box = touchBBox(pointers);\n this.scale = 1;\n this.ds = 0;\n this.angle = touchAngle(pointers, undefined, deltaSource);\n this.da = 0;\n }\n else if (ending || event instanceof InteractEvent) {\n this.distance = interaction.prevEvent.distance;\n this.box = interaction.prevEvent.box;\n this.scale = interaction.prevEvent.scale;\n this.ds = this.scale - 1;\n this.angle = interaction.prevEvent.angle;\n this.da = this.angle - interaction.gesture.startAngle;\n }\n else {\n this.distance = touchDistance(pointers, deltaSource);\n this.box = touchBBox(pointers);\n this.scale = this.distance / interaction.gesture.startDistance;\n this.angle = touchAngle(pointers, interaction.gesture.prevAngle, deltaSource);\n\n this.ds = this.scale - interaction.gesture.prevScale;\n this.da = this.angle - interaction.gesture.prevAngle;\n }\n }\n\n if (starting) {\n this.timeStamp = interaction.downTimes[0];\n this.dt = 0;\n this.duration = 0;\n this.speed = 0;\n this.velocityX = 0;\n this.velocityY = 0;\n }\n else if (phase === 'inertiastart') {\n this.timeStamp = interaction.prevEvent.timeStamp;\n this.dt = interaction.prevEvent.dt;\n this.duration = interaction.prevEvent.duration;\n this.speed = interaction.prevEvent.speed;\n this.velocityX = interaction.prevEvent.velocityX;\n this.velocityY = interaction.prevEvent.velocityY;\n }\n else {\n this.timeStamp = new Date().getTime();\n this.dt = this.timeStamp - interaction.prevEvent.timeStamp;\n this.duration = this.timeStamp - interaction.downTimes[0];\n\n if (event instanceof InteractEvent) {\n var dx = this[sourceX] - interaction.prevEvent[sourceX],\n dy = this[sourceY] - interaction.prevEvent[sourceY],\n dt = this.dt / 1000;\n\n this.speed = hypot(dx, dy) / dt;\n this.velocityX = dx / dt;\n this.velocityY = dy / dt;\n }\n // if normal move or end event, use previous user event coords\n else {\n // speed and velocity in pixels per second\n this.speed = interaction.pointerDelta[deltaSource].speed;\n this.velocityX = interaction.pointerDelta[deltaSource].vx;\n this.velocityY = interaction.pointerDelta[deltaSource].vy;\n }\n }\n\n if ((ending || phase === 'inertiastart')\n && interaction.prevEvent.speed > 600 && this.timeStamp - interaction.prevEvent.timeStamp < 150) {\n\n var angle = 180 * Math.atan2(interaction.prevEvent.velocityY, interaction.prevEvent.velocityX) / Math.PI,\n overlap = 22.5;\n\n if (angle < 0) {\n angle += 360;\n }\n\n var left = 135 - overlap <= angle && angle < 225 + overlap,\n up = 225 - overlap <= angle && angle < 315 + overlap,\n\n right = !left && (315 - overlap <= angle || angle < 45 + overlap),\n down = !up && 45 - overlap <= angle && angle < 135 + overlap;\n\n this.swipe = {\n up : up,\n down : down,\n left : left,\n right: right,\n angle: angle,\n speed: interaction.prevEvent.speed,\n velocity: {\n x: interaction.prevEvent.velocityX,\n y: interaction.prevEvent.velocityY\n }\n };\n }\n }\n\n InteractEvent.prototype = {\n preventDefault: blank,\n stopImmediatePropagation: function () {\n this.immediatePropagationStopped = this.propagationStopped = true;\n },\n stopPropagation: function () {\n this.propagationStopped = true;\n }\n };\n\n function preventOriginalDefault () {\n this.originalEvent.preventDefault();\n }\n\n function getActionCursor (action) {\n var cursor = '';\n\n if (action.name === 'drag') {\n cursor = actionCursors.drag;\n }\n if (action.name === 'resize') {\n if (action.axis) {\n cursor = actionCursors[action.name + action.axis];\n }\n else if (action.edges) {\n var cursorKey = 'resize',\n edgeNames = ['top', 'bottom', 'left', 'right'];\n\n for (var i = 0; i < 4; i++) {\n if (action.edges[edgeNames[i]]) {\n cursorKey += edgeNames[i];\n }\n }\n\n cursor = actionCursors[cursorKey];\n }\n }\n\n return cursor;\n }\n\n function checkResizeEdge (name, value, page, element, interactableElement, rect, margin) {\n // false, '', undefined, null\n if (!value) { return false; }\n\n // true value, use pointer coords and element rect\n if (value === true) {\n // if dimensions are negative, \"switch\" edges\n var width = isNumber(rect.width)? rect.width : rect.right - rect.left,\n height = isNumber(rect.height)? rect.height : rect.bottom - rect.top;\n\n if (width < 0) {\n if (name === 'left' ) { name = 'right'; }\n else if (name === 'right') { name = 'left' ; }\n }\n if (height < 0) {\n if (name === 'top' ) { name = 'bottom'; }\n else if (name === 'bottom') { name = 'top' ; }\n }\n\n if (name === 'left' ) { return page.x < ((width >= 0? rect.left: rect.right ) + margin); }\n if (name === 'top' ) { return page.y < ((height >= 0? rect.top : rect.bottom) + margin); }\n\n if (name === 'right' ) { return page.x > ((width >= 0? rect.right : rect.left) - margin); }\n if (name === 'bottom') { return page.y > ((height >= 0? rect.bottom: rect.top ) - margin); }\n }\n\n // the remaining checks require an element\n if (!isElement(element)) { return false; }\n\n return isElement(value)\n // the value is an element to use as a resize handle\n ? value === element\n // otherwise check if element matches value as selector\n : matchesUpTo(element, value, interactableElement);\n }\n\n function defaultActionChecker (pointer, interaction, element) {\n var rect = this.getRect(element),\n shouldResize = false,\n action = null,\n resizeAxes = null,\n resizeEdges,\n page = extend({}, interaction.curCoords.page),\n options = this.options;\n\n if (!rect) { return null; }\n\n if (actionIsEnabled.resize && options.resize.enabled) {\n var resizeOptions = options.resize;\n\n resizeEdges = {\n left: false, right: false, top: false, bottom: false\n };\n\n // if using resize.edges\n if (isObject(resizeOptions.edges)) {\n for (var edge in resizeEdges) {\n resizeEdges[edge] = checkResizeEdge(edge,\n resizeOptions.edges[edge],\n page,\n interaction._eventTarget,\n element,\n rect,\n resizeOptions.margin || margin);\n }\n\n resizeEdges.left = resizeEdges.left && !resizeEdges.right;\n resizeEdges.top = resizeEdges.top && !resizeEdges.bottom;\n\n shouldResize = resizeEdges.left || resizeEdges.right || resizeEdges.top || resizeEdges.bottom;\n }\n else {\n var right = options.resize.axis !== 'y' && page.x > (rect.right - margin),\n bottom = options.resize.axis !== 'x' && page.y > (rect.bottom - margin);\n\n shouldResize = right || bottom;\n resizeAxes = (right? 'x' : '') + (bottom? 'y' : '');\n }\n }\n\n action = shouldResize\n ? 'resize'\n : actionIsEnabled.drag && options.drag.enabled\n ? 'drag'\n : null;\n\n if (actionIsEnabled.gesture\n && interaction.pointerIds.length >=2\n && !(interaction.dragging || interaction.resizing)) {\n action = 'gesture';\n }\n\n if (action) {\n return {\n name: action,\n axis: resizeAxes,\n edges: resizeEdges\n };\n }\n\n return null;\n }\n\n // Check if action is enabled globally and the current target supports it\n // If so, return the validated action. Otherwise, return null\n function validateAction (action, interactable) {\n if (!isObject(action)) { return null; }\n\n var actionName = action.name,\n options = interactable.options;\n\n if (( (actionName === 'resize' && options.resize.enabled )\n || (actionName === 'drag' && options.drag.enabled )\n || (actionName === 'gesture' && options.gesture.enabled))\n && actionIsEnabled[actionName]) {\n\n if (actionName === 'resize' || actionName === 'resizeyx') {\n actionName = 'resizexy';\n }\n\n return action;\n }\n return null;\n }\n\n var listeners = {},\n interactionListeners = [\n 'dragStart', 'dragMove', 'resizeStart', 'resizeMove', 'gestureStart', 'gestureMove',\n 'pointerOver', 'pointerOut', 'pointerHover', 'selectorDown',\n 'pointerDown', 'pointerMove', 'pointerUp', 'pointerCancel', 'pointerEnd',\n 'addPointer', 'removePointer', 'recordPointer', 'autoScrollMove'\n ];\n\n for (var i = 0, len = interactionListeners.length; i < len; i++) {\n var name = interactionListeners[i];\n\n listeners[name] = doOnInteractions(name);\n }\n\n // bound to the interactable context when a DOM event\n // listener is added to a selector interactable\n function delegateListener (event, useCapture) {\n var fakeEvent = {},\n delegated = delegatedEvents[event.type],\n eventTarget = getActualElement(event.path\n ? event.path[0]\n : event.target),\n element = eventTarget;\n\n useCapture = useCapture? true: false;\n\n // duplicate the event so that currentTarget can be changed\n for (var prop in event) {\n fakeEvent[prop] = event[prop];\n }\n\n fakeEvent.originalEvent = event;\n fakeEvent.preventDefault = preventOriginalDefault;\n\n // climb up document tree looking for selector matches\n while (isElement(element)) {\n for (var i = 0; i < delegated.selectors.length; i++) {\n var selector = delegated.selectors[i],\n context = delegated.contexts[i];\n\n if (matchesSelector(element, selector)\n && nodeContains(context, eventTarget)\n && nodeContains(context, element)) {\n\n var listeners = delegated.listeners[i];\n\n fakeEvent.currentTarget = element;\n\n for (var j = 0; j < listeners.length; j++) {\n if (listeners[j][1] === useCapture) {\n listeners[j][0](fakeEvent);\n }\n }\n }\n }\n\n element = parentElement(element);\n }\n }\n\n function delegateUseCapture (event) {\n return delegateListener.call(this, event, true);\n }\n\n interactables.indexOfElement = function indexOfElement (element, context) {\n context = context || document;\n\n for (var i = 0; i < this.length; i++) {\n var interactable = this[i];\n\n if ((interactable.selector === element\n && (interactable._context === context))\n || (!interactable.selector && interactable._element === element)) {\n\n return i;\n }\n }\n return -1;\n };\n\n interactables.get = function interactableGet (element, options) {\n return this[this.indexOfElement(element, options && options.context)];\n };\n\n interactables.forEachSelector = function (callback) {\n for (var i = 0; i < this.length; i++) {\n var interactable = this[i];\n\n if (!interactable.selector) {\n continue;\n }\n\n var ret = callback(interactable, interactable.selector, interactable._context, i, this);\n\n if (ret !== undefined) {\n return ret;\n }\n }\n };\n\n /*\\\n * interact\n [ method ]\n *\n * The methods of this variable can be used to set elements as\n * interactables and also to change various default settings.\n *\n * Calling it as a function and passing an element or a valid CSS selector\n * string returns an Interactable object which has various methods to\n * configure it.\n *\n - element (Element | string) The HTML or SVG Element to interact with or CSS selector\n = (object) An @Interactable\n *\n > Usage\n | interact(document.getElementById('draggable')).draggable(true);\n |\n | var rectables = interact('rect');\n | rectables\n | .gesturable(true)\n | .on('gesturemove', function (event) {\n | // something cool...\n | })\n | .autoScroll(true);\n \\*/\n function interact (element, options) {\n return interactables.get(element, options) || new Interactable(element, options);\n }\n\n /*\\\n * Interactable\n [ property ]\n **\n * Object type returned by @interact\n \\*/\n function Interactable (element, options) {\n this._element = element;\n this._iEvents = this._iEvents || {};\n\n var _window;\n\n if (trySelector(element)) {\n this.selector = element;\n\n var context = options && options.context;\n\n _window = context? getWindow(context) : window;\n\n if (context && (_window.Node\n ? context instanceof _window.Node\n : (isElement(context) || context === _window.document))) {\n\n this._context = context;\n }\n }\n else {\n _window = getWindow(element);\n\n if (isElement(element, _window)) {\n\n if (PointerEvent) {\n events.add(this._element, pEventTypes.down, listeners.pointerDown );\n events.add(this._element, pEventTypes.move, listeners.pointerHover);\n }\n else {\n events.add(this._element, 'mousedown' , listeners.pointerDown );\n events.add(this._element, 'mousemove' , listeners.pointerHover);\n events.add(this._element, 'touchstart', listeners.pointerDown );\n events.add(this._element, 'touchmove' , listeners.pointerHover);\n }\n }\n }\n\n this._doc = _window.document;\n\n if (!contains(documents, this._doc)) {\n listenToDocument(this._doc);\n }\n\n interactables.push(this);\n\n this.set(options);\n }\n\n Interactable.prototype = {\n setOnEvents: function (action, phases) {\n if (action === 'drop') {\n if (isFunction(phases.ondrop) ) { this.ondrop = phases.ondrop ; }\n if (isFunction(phases.ondropactivate) ) { this.ondropactivate = phases.ondropactivate ; }\n if (isFunction(phases.ondropdeactivate)) { this.ondropdeactivate = phases.ondropdeactivate; }\n if (isFunction(phases.ondragenter) ) { this.ondragenter = phases.ondragenter ; }\n if (isFunction(phases.ondragleave) ) { this.ondragleave = phases.ondragleave ; }\n if (isFunction(phases.ondropmove) ) { this.ondropmove = phases.ondropmove ; }\n }\n else {\n action = 'on' + action;\n\n if (isFunction(phases.onstart) ) { this[action + 'start' ] = phases.onstart ; }\n if (isFunction(phases.onmove) ) { this[action + 'move' ] = phases.onmove ; }\n if (isFunction(phases.onend) ) { this[action + 'end' ] = phases.onend ; }\n if (isFunction(phases.oninertiastart)) { this[action + 'inertiastart' ] = phases.oninertiastart ; }\n }\n\n return this;\n },\n\n /*\\\n * Interactable.draggable\n [ method ]\n *\n * Gets or sets whether drag actions can be performed on the\n * Interactable\n *\n = (boolean) Indicates if this can be the target of drag events\n | var isDraggable = interact('ul li').draggable();\n * or\n - options (boolean | object) #optional true/false or An object with event listeners to be fired on drag events (object makes the Interactable draggable)\n = (object) This Interactable\n | interact(element).draggable({\n | onstart: function (event) {},\n | onmove : function (event) {},\n | onend : function (event) {},\n |\n | // the axis in which the first movement must be\n | // for the drag sequence to start\n | // 'xy' by default - any direction\n | axis: 'x' || 'y' || 'xy',\n |\n | // max number of drags that can happen concurrently\n | // with elements of this Interactable. Infinity by default\n | max: Infinity,\n |\n | // max number of drags that can target the same element+Interactable\n | // 1 by default\n | maxPerElement: 2\n | });\n \\*/\n draggable: function (options) {\n if (isObject(options)) {\n this.options.drag.enabled = options.enabled === false? false: true;\n this.setPerAction('drag', options);\n this.setOnEvents('drag', options);\n\n if (/^x$|^y$|^xy$/.test(options.axis)) {\n this.options.drag.axis = options.axis;\n }\n else if (options.axis === null) {\n delete this.options.drag.axis;\n }\n\n return this;\n }\n\n if (isBool(options)) {\n this.options.drag.enabled = options;\n\n return this;\n }\n\n return this.options.drag;\n },\n\n setPerAction: function (action, options) {\n // for all the default per-action options\n for (var option in options) {\n // if this option exists for this action\n if (option in defaultOptions[action]) {\n // if the option in the options arg is an object value\n if (isObject(options[option])) {\n // duplicate the object\n this.options[action][option] = extend(this.options[action][option] || {}, options[option]);\n\n if (isObject(defaultOptions.perAction[option]) && 'enabled' in defaultOptions.perAction[option]) {\n this.options[action][option].enabled = options[option].enabled === false? false : true;\n }\n }\n else if (isBool(options[option]) && isObject(defaultOptions.perAction[option])) {\n this.options[action][option].enabled = options[option];\n }\n else if (options[option] !== undefined) {\n // or if it's not undefined, do a plain assignment\n this.options[action][option] = options[option];\n }\n }\n }\n },\n\n /*\\\n * Interactable.dropzone\n [ method ]\n *\n * Returns or sets whether elements can be dropped onto this\n * Interactable to trigger drop events\n *\n * Dropzones can receive the following events:\n * - `dropactivate` and `dropdeactivate` when an acceptable drag starts and ends\n * - `dragenter` and `dragleave` when a draggable enters and leaves the dropzone\n * - `dragmove` when a draggable that has entered the dropzone is moved\n * - `drop` when a draggable is dropped into this dropzone\n *\n * Use the `accept` option to allow only elements that match the given CSS selector or element.\n *\n * Use the `overlap` option to set how drops are checked for. The allowed values are:\n * - `'pointer'`, the pointer must be over the dropzone (default)\n * - `'center'`, the draggable element's center must be over the dropzone\n * - a number from 0-1 which is the `(intersection area) / (draggable area)`.\n * e.g. `0.5` for drop to happen when half of the area of the\n * draggable is over the dropzone\n *\n - options (boolean | object | null) #optional The new value to be set.\n | interact('.drop').dropzone({\n | accept: '.can-drop' || document.getElementById('single-drop'),\n | overlap: 'pointer' || 'center' || zeroToOne\n | }\n = (boolean | object) The current setting or this Interactable\n \\*/\n dropzone: function (options) {\n if (isObject(options)) {\n this.options.drop.enabled = options.enabled === false? false: true;\n this.setOnEvents('drop', options);\n\n if (/^(pointer|center)$/.test(options.overlap)) {\n this.options.drop.overlap = options.overlap;\n }\n else if (isNumber(options.overlap)) {\n this.options.drop.overlap = Math.max(Math.min(1, options.overlap), 0);\n }\n if ('accept' in options) {\n this.options.drop.accept = options.accept;\n }\n if ('checker' in options) {\n this.options.drop.checker = options.checker;\n }\n\n return this;\n }\n\n if (isBool(options)) {\n this.options.drop.enabled = options;\n\n return this;\n }\n\n return this.options.drop;\n },\n\n dropCheck: function (dragEvent, event, draggable, draggableElement, dropElement, rect) {\n var dropped = false;\n\n // if the dropzone has no rect (eg. display: none)\n // call the custom dropChecker or just return false\n if (!(rect = rect || this.getRect(dropElement))) {\n return (this.options.drop.checker\n ? this.options.drop.checker(dragEvent, event, dropped, this, dropElement, draggable, draggableElement)\n : false);\n }\n\n var dropOverlap = this.options.drop.overlap;\n\n if (dropOverlap === 'pointer') {\n var page = getPageXY(dragEvent),\n origin = getOriginXY(draggable, draggableElement),\n horizontal,\n vertical;\n\n page.x += origin.x;\n page.y += origin.y;\n\n horizontal = (page.x > rect.left) && (page.x < rect.right);\n vertical = (page.y > rect.top ) && (page.y < rect.bottom);\n\n dropped = horizontal && vertical;\n }\n\n var dragRect = draggable.getRect(draggableElement);\n\n if (dropOverlap === 'center') {\n var cx = dragRect.left + dragRect.width / 2,\n cy = dragRect.top + dragRect.height / 2;\n\n dropped = cx >= rect.left && cx <= rect.right && cy >= rect.top && cy <= rect.bottom;\n }\n\n if (isNumber(dropOverlap)) {\n var overlapArea = (Math.max(0, Math.min(rect.right , dragRect.right ) - Math.max(rect.left, dragRect.left))\n * Math.max(0, Math.min(rect.bottom, dragRect.bottom) - Math.max(rect.top , dragRect.top ))),\n overlapRatio = overlapArea / (dragRect.width * dragRect.height);\n\n dropped = overlapRatio >= dropOverlap;\n }\n\n if (this.options.drop.checker) {\n dropped = this.options.drop.checker(dragEvent, event, dropped, this, dropElement, draggable, draggableElement);\n }\n\n return dropped;\n },\n\n /*\\\n * Interactable.dropChecker\n [ method ]\n *\n * DEPRECATED. Use interactable.dropzone({ checker: function... }) instead.\n *\n * Gets or sets the function used to check if a dragged element is\n * over this Interactable.\n *\n - checker (function) #optional The function that will be called when checking for a drop\n = (Function | Interactable) The checker function or this Interactable\n *\n * The checker function takes the following arguments:\n *\n - dragEvent (InteractEvent) The related dragmove or dragend event\n - event (TouchEvent | PointerEvent | MouseEvent) The user move/up/end Event related to the dragEvent\n - dropped (boolean) The value from the default drop checker\n - dropzone (Interactable) The dropzone interactable\n - dropElement (Element) The dropzone element\n - draggable (Interactable) The Interactable being dragged\n - draggableElement (Element) The actual element that's being dragged\n *\n > Usage:\n | interact(target)\n | .dropChecker(function(dragEvent, // related dragmove or dragend event\n | event, // TouchEvent/PointerEvent/MouseEvent\n | dropped, // bool result of the default checker\n | dropzone, // dropzone Interactable\n | dropElement, // dropzone elemnt\n | draggable, // draggable Interactable\n | draggableElement) {// draggable element\n |\n | return dropped && event.target.hasAttribute('allow-drop');\n | }\n \\*/\n dropChecker: function (checker) {\n if (isFunction(checker)) {\n this.options.drop.checker = checker;\n\n return this;\n }\n if (checker === null) {\n delete this.options.getRect;\n\n return this;\n }\n\n return this.options.drop.checker;\n },\n\n /*\\\n * Interactable.accept\n [ method ]\n *\n * Deprecated. add an `accept` property to the options object passed to\n * @Interactable.dropzone instead.\n *\n * Gets or sets the Element or CSS selector match that this\n * Interactable accepts if it is a dropzone.\n *\n - newValue (Element | string | null) #optional\n * If it is an Element, then only that element can be dropped into this dropzone.\n * If it is a string, the element being dragged must match it as a selector.\n * If it is null, the accept options is cleared - it accepts any element.\n *\n = (string | Element | null | Interactable) The current accept option if given `undefined` or this Interactable\n \\*/\n accept: function (newValue) {\n if (isElement(newValue)) {\n this.options.drop.accept = newValue;\n\n return this;\n }\n\n // test if it is a valid CSS selector\n if (trySelector(newValue)) {\n this.options.drop.accept = newValue;\n\n return this;\n }\n\n if (newValue === null) {\n delete this.options.drop.accept;\n\n return this;\n }\n\n return this.options.drop.accept;\n },\n\n /*\\\n * Interactable.resizable\n [ method ]\n *\n * Gets or sets whether resize actions can be performed on the\n * Interactable\n *\n = (boolean) Indicates if this can be the target of resize elements\n | var isResizeable = interact('input[type=text]').resizable();\n * or\n - options (boolean | object) #optional true/false or An object with event listeners to be fired on resize events (object makes the Interactable resizable)\n = (object) This Interactable\n | interact(element).resizable({\n | onstart: function (event) {},\n | onmove : function (event) {},\n | onend : function (event) {},\n |\n | edges: {\n | top : true, // Use pointer coords to check for resize.\n | left : false, // Disable resizing from left edge.\n | bottom: '.resize-s',// Resize if pointer target matches selector\n | right : handleEl // Resize if pointer target is the given Element\n | },\n |\n | // Width and height can be adjusted independently. When `true`, width and\n | // height are adjusted at a 1:1 ratio.\n | square: false,\n |\n | // Width and height can be adjusted independently. When `true`, width and\n | // height maintain the aspect ratio they had when resizing started.\n | preserveAspectRatio: false,\n |\n | // a value of 'none' will limit the resize rect to a minimum of 0x0\n | // 'negate' will allow the rect to have negative width/height\n | // 'reposition' will keep the width/height positive by swapping\n | // the top and bottom edges and/or swapping the left and right edges\n | invert: 'none' || 'negate' || 'reposition'\n |\n | // limit multiple resizes.\n | // See the explanation in the @Interactable.draggable example\n | max: Infinity,\n | maxPerElement: 1,\n | });\n \\*/\n resizable: function (options) {\n if (isObject(options)) {\n this.options.resize.enabled = options.enabled === false? false: true;\n this.setPerAction('resize', options);\n this.setOnEvents('resize', options);\n\n if (/^x$|^y$|^xy$/.test(options.axis)) {\n this.options.resize.axis = options.axis;\n }\n else if (options.axis === null) {\n this.options.resize.axis = defaultOptions.resize.axis;\n }\n\n if (isBool(options.preserveAspectRatio)) {\n this.options.resize.preserveAspectRatio = options.preserveAspectRatio;\n }\n else if (isBool(options.square)) {\n this.options.resize.square = options.square;\n }\n\n return this;\n }\n if (isBool(options)) {\n this.options.resize.enabled = options;\n\n return this;\n }\n return this.options.resize;\n },\n\n /*\\\n * Interactable.squareResize\n [ method ]\n *\n * Deprecated. Add a `square: true || false` property to @Interactable.resizable instead\n *\n * Gets or sets whether resizing is forced 1:1 aspect\n *\n = (boolean) Current setting\n *\n * or\n *\n - newValue (boolean) #optional\n = (object) this Interactable\n \\*/\n squareResize: function (newValue) {\n if (isBool(newValue)) {\n this.options.resize.square = newValue;\n\n return this;\n }\n\n if (newValue === null) {\n delete this.options.resize.square;\n\n return this;\n }\n\n return this.options.resize.square;\n },\n\n /*\\\n * Interactable.gesturable\n [ method ]\n *\n * Gets or sets whether multitouch gestures can be performed on the\n * Interactable's element\n *\n = (boolean) Indicates if this can be the target of gesture events\n | var isGestureable = interact(element).gesturable();\n * or\n - options (boolean | object) #optional true/false or An object with event listeners to be fired on gesture events (makes the Interactable gesturable)\n = (object) this Interactable\n | interact(element).gesturable({\n | onstart: function (event) {},\n | onmove : function (event) {},\n | onend : function (event) {},\n |\n | // limit multiple gestures.\n | // See the explanation in @Interactable.draggable example\n | max: Infinity,\n | maxPerElement: 1,\n | });\n \\*/\n gesturable: function (options) {\n if (isObject(options)) {\n this.options.gesture.enabled = options.enabled === false? false: true;\n this.setPerAction('gesture', options);\n this.setOnEvents('gesture', options);\n\n return this;\n }\n\n if (isBool(options)) {\n this.options.gesture.enabled = options;\n\n return this;\n }\n\n return this.options.gesture;\n },\n\n /*\\\n * Interactable.autoScroll\n [ method ]\n **\n * Deprecated. Add an `autoscroll` property to the options object\n * passed to @Interactable.draggable or @Interactable.resizable instead.\n *\n * Returns or sets whether dragging and resizing near the edges of the\n * window/container trigger autoScroll for this Interactable\n *\n = (object) Object with autoScroll properties\n *\n * or\n *\n - options (object | boolean) #optional\n * options can be:\n * - an object with margin, distance and interval properties,\n * - true or false to enable or disable autoScroll or\n = (Interactable) this Interactable\n \\*/\n autoScroll: function (options) {\n if (isObject(options)) {\n options = extend({ actions: ['drag', 'resize']}, options);\n }\n else if (isBool(options)) {\n options = { actions: ['drag', 'resize'], enabled: options };\n }\n\n return this.setOptions('autoScroll', options);\n },\n\n /*\\\n * Interactable.snap\n [ method ]\n **\n * Deprecated. Add a `snap` property to the options object passed\n * to @Interactable.draggable or @Interactable.resizable instead.\n *\n * Returns or sets if and how action coordinates are snapped. By\n * default, snapping is relative to the pointer coordinates. You can\n * change this by setting the\n * [`elementOrigin`](https://github.com/taye/interact.js/pull/72).\n **\n = (boolean | object) `false` if snap is disabled; object with snap properties if snap is enabled\n **\n * or\n **\n - options (object | boolean | null) #optional\n = (Interactable) this Interactable\n > Usage\n | interact(document.querySelector('#thing')).snap({\n | targets: [\n | // snap to this specific point\n | {\n | x: 100,\n | y: 100,\n | range: 25\n | },\n | // give this function the x and y page coords and snap to the object returned\n | function (x, y) {\n | return {\n | x: x,\n | y: (75 + 50 * Math.sin(x * 0.04)),\n | range: 40\n | };\n | },\n | // create a function that snaps to a grid\n | interact.createSnapGrid({\n | x: 50,\n | y: 50,\n | range: 10, // optional\n | offset: { x: 5, y: 10 } // optional\n | })\n | ],\n | // do not snap during normal movement.\n | // Instead, trigger only one snapped move event\n | // immediately before the end event.\n | endOnly: true,\n |\n | relativePoints: [\n | { x: 0, y: 0 }, // snap relative to the top left of the element\n | { x: 1, y: 1 }, // and also to the bottom right\n | ], \n |\n | // offset the snap target coordinates\n | // can be an object with x/y or 'startCoords'\n | offset: { x: 50, y: 50 }\n | }\n | });\n \\*/\n snap: function (options) {\n var ret = this.setOptions('snap', options);\n\n if (ret === this) { return this; }\n\n return ret.drag;\n },\n\n setOptions: function (option, options) {\n var actions = options && isArray(options.actions)\n ? options.actions\n : ['drag'];\n\n var i;\n\n if (isObject(options) || isBool(options)) {\n for (i = 0; i < actions.length; i++) {\n var action = /resize/.test(actions[i])? 'resize' : actions[i];\n\n if (!isObject(this.options[action])) { continue; }\n\n var thisOption = this.options[action][option];\n\n if (isObject(options)) {\n extend(thisOption, options);\n thisOption.enabled = options.enabled === false? false: true;\n\n if (option === 'snap') {\n if (thisOption.mode === 'grid') {\n thisOption.targets = [\n interact.createSnapGrid(extend({\n offset: thisOption.gridOffset || { x: 0, y: 0 }\n }, thisOption.grid || {}))\n ];\n }\n else if (thisOption.mode === 'anchor') {\n thisOption.targets = thisOption.anchors;\n }\n else if (thisOption.mode === 'path') {\n thisOption.targets = thisOption.paths;\n }\n\n if ('elementOrigin' in options) {\n thisOption.relativePoints = [options.elementOrigin];\n }\n }\n }\n else if (isBool(options)) {\n thisOption.enabled = options;\n }\n }\n\n return this;\n }\n\n var ret = {},\n allActions = ['drag', 'resize', 'gesture'];\n\n for (i = 0; i < allActions.length; i++) {\n if (option in defaultOptions[allActions[i]]) {\n ret[allActions[i]] = this.options[allActions[i]][option];\n }\n }\n\n return ret;\n },\n\n\n /*\\\n * Interactable.inertia\n [ method ]\n **\n * Deprecated. Add an `inertia` property to the options object passed\n * to @Interactable.draggable or @Interactable.resizable instead.\n *\n * Returns or sets if and how events continue to run after the pointer is released\n **\n = (boolean | object) `false` if inertia is disabled; `object` with inertia properties if inertia is enabled\n **\n * or\n **\n - options (object | boolean | null) #optional\n = (Interactable) this Interactable\n > Usage\n | // enable and use default settings\n | interact(element).inertia(true);\n |\n | // enable and use custom settings\n | interact(element).inertia({\n | // value greater than 0\n | // high values slow the object down more quickly\n | resistance : 16,\n |\n | // the minimum launch speed (pixels per second) that results in inertia start\n | minSpeed : 200,\n |\n | // inertia will stop when the object slows down to this speed\n | endSpeed : 20,\n |\n | // boolean; should actions be resumed when the pointer goes down during inertia\n | allowResume : true,\n |\n | // boolean; should the jump when resuming from inertia be ignored in event.dx/dy\n | zeroResumeDelta: false,\n |\n | // if snap/restrict are set to be endOnly and inertia is enabled, releasing\n | // the pointer without triggering inertia will animate from the release\n | // point to the snaped/restricted point in the given amount of time (ms)\n | smoothEndDuration: 300,\n |\n | // an array of action types that can have inertia (no gesture)\n | actions : ['drag', 'resize']\n | });\n |\n | // reset custom settings and use all defaults\n | interact(element).inertia(null);\n \\*/\n inertia: function (options) {\n var ret = this.setOptions('inertia', options);\n\n if (ret === this) { return this; }\n\n return ret.drag;\n },\n\n getAction: function (pointer, event, interaction, element) {\n var action = this.defaultActionChecker(pointer, interaction, element);\n\n if (this.options.actionChecker) {\n return this.options.actionChecker(pointer, event, action, this, element, interaction);\n }\n\n return action;\n },\n\n defaultActionChecker: defaultActionChecker,\n\n /*\\\n * Interactable.actionChecker\n [ method ]\n *\n * Gets or sets the function used to check action to be performed on\n * pointerDown\n *\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.\n = (Function | Interactable) The checker function or this Interactable\n *\n | interact('.resize-drag')\n | .resizable(true)\n | .draggable(true)\n | .actionChecker(function (pointer, event, action, interactable, element, interaction) {\n |\n | if (interact.matchesSelector(event.target, '.drag-handle') {\n | // force drag with handle target\n | action.name = drag;\n | }\n | else {\n | // resize from the top and right edges\n | action.name = 'resize';\n | action.edges = { top: true, right: true };\n | }\n |\n | return action;\n | });\n \\*/\n actionChecker: function (checker) {\n if (isFunction(checker)) {\n this.options.actionChecker = checker;\n\n return this;\n }\n\n if (checker === null) {\n delete this.options.actionChecker;\n\n return this;\n }\n\n return this.options.actionChecker;\n },\n\n /*\\\n * Interactable.getRect\n [ method ]\n *\n * The default function to get an Interactables bounding rect. Can be\n * overridden using @Interactable.rectChecker.\n *\n - element (Element) #optional The element to measure.\n = (object) The object's bounding rectangle.\n o {\n o top : 0,\n o left : 0,\n o bottom: 0,\n o right : 0,\n o width : 0,\n o height: 0\n o }\n \\*/\n getRect: function rectCheck (element) {\n element = element || this._element;\n\n if (this.selector && !(isElement(element))) {\n element = this._context.querySelector(this.selector);\n }\n\n return getElementRect(element);\n },\n\n /*\\\n * Interactable.rectChecker\n [ method ]\n *\n * Returns or sets the function used to calculate the interactable's\n * element's rectangle\n *\n - checker (function) #optional A function which returns this Interactable's bounding rectangle. See @Interactable.getRect\n = (function | object) The checker function or this Interactable\n \\*/\n rectChecker: function (checker) {\n if (isFunction(checker)) {\n this.getRect = checker;\n\n return this;\n }\n\n if (checker === null) {\n delete this.options.getRect;\n\n return this;\n }\n\n return this.getRect;\n },\n\n /*\\\n * Interactable.styleCursor\n [ method ]\n *\n * Returns or sets whether the action that would be performed when the\n * mouse on the element are checked on `mousemove` so that the cursor\n * may be styled appropriately\n *\n - newValue (boolean) #optional\n = (boolean | Interactable) The current setting or this Interactable\n \\*/\n styleCursor: function (newValue) {\n if (isBool(newValue)) {\n this.options.styleCursor = newValue;\n\n return this;\n }\n\n if (newValue === null) {\n delete this.options.styleCursor;\n\n return this;\n }\n\n return this.options.styleCursor;\n },\n\n /*\\\n * Interactable.preventDefault\n [ method ]\n *\n * Returns or sets whether to prevent the browser's default behaviour\n * in response to pointer events. Can be set to:\n * - `'always'` to always prevent\n * - `'never'` to never prevent\n * - `'auto'` to let interact.js try to determine what would be best\n *\n - newValue (string) #optional `true`, `false` or `'auto'`\n = (string | Interactable) The current setting or this Interactable\n \\*/\n preventDefault: function (newValue) {\n if (/^(always|never|auto)$/.test(newValue)) {\n this.options.preventDefault = newValue;\n return this;\n }\n\n if (isBool(newValue)) {\n this.options.preventDefault = newValue? 'always' : 'never';\n return this;\n }\n\n return this.options.preventDefault;\n },\n\n /*\\\n * Interactable.origin\n [ method ]\n *\n * Gets or sets the origin of the Interactable's element. The x and y\n * of the origin will be subtracted from action event coordinates.\n *\n - origin (object | string) #optional An object eg. { x: 0, y: 0 } or string 'parent', 'self' or any CSS selector\n * OR\n - origin (Element) #optional An HTML or SVG Element whose rect will be used\n **\n = (object) The current origin or this Interactable\n \\*/\n origin: function (newValue) {\n if (trySelector(newValue)) {\n this.options.origin = newValue;\n return this;\n }\n else if (isObject(newValue)) {\n this.options.origin = newValue;\n return this;\n }\n\n return this.options.origin;\n },\n\n /*\\\n * Interactable.deltaSource\n [ method ]\n *\n * Returns or sets the mouse coordinate types used to calculate the\n * movement of the pointer.\n *\n - newValue (string) #optional Use 'client' if you will be scrolling while interacting; Use 'page' if you want autoScroll to work\n = (string | object) The current deltaSource or this Interactable\n \\*/\n deltaSource: function (newValue) {\n if (newValue === 'page' || newValue === 'client') {\n this.options.deltaSource = newValue;\n\n return this;\n }\n\n return this.options.deltaSource;\n },\n\n /*\\\n * Interactable.restrict\n [ method ]\n **\n * Deprecated. Add a `restrict` property to the options object passed to\n * @Interactable.draggable, @Interactable.resizable or @Interactable.gesturable instead.\n *\n * Returns or sets the rectangles within which actions on this\n * interactable (after snap calculations) are restricted. By default,\n * restricting is relative to the pointer coordinates. You can change\n * this by setting the\n * [`elementRect`](https://github.com/taye/interact.js/pull/72).\n **\n - options (object) #optional an object with keys drag, resize, and/or gesture whose values are rects, Elements, CSS selectors, or 'parent' or 'self'\n = (object) The current restrictions object or this Interactable\n **\n | interact(element).restrict({\n | // the rect will be `interact.getElementRect(element.parentNode)`\n | drag: element.parentNode,\n |\n | // x and y are relative to the the interactable's origin\n | resize: { x: 100, y: 100, width: 200, height: 200 }\n | })\n |\n | interact('.draggable').restrict({\n | // the rect will be the selected element's parent\n | drag: 'parent',\n |\n | // do not restrict during normal movement.\n | // Instead, trigger only one restricted move event\n | // immediately before the end event.\n | endOnly: true,\n |\n | // https://github.com/taye/interact.js/pull/72#issue-41813493\n | elementRect: { top: 0, left: 0, bottom: 1, right: 1 }\n | });\n \\*/\n restrict: function (options) {\n if (!isObject(options)) {\n return this.setOptions('restrict', options);\n }\n\n var actions = ['drag', 'resize', 'gesture'],\n ret;\n\n for (var i = 0; i < actions.length; i++) {\n var action = actions[i];\n\n if (action in options) {\n var perAction = extend({\n actions: [action],\n restriction: options[action]\n }, options);\n\n ret = this.setOptions('restrict', perAction);\n }\n }\n\n return ret;\n },\n\n /*\\\n * Interactable.context\n [ method ]\n *\n * Gets the selector context Node of the Interactable. The default is `window.document`.\n *\n = (Node) The context Node of this Interactable\n **\n \\*/\n context: function () {\n return this._context;\n },\n\n _context: document,\n\n /*\\\n * Interactable.ignoreFrom\n [ method ]\n *\n * If the target of the `mousedown`, `pointerdown` or `touchstart`\n * event or any of it's parents match the given CSS selector or\n * Element, no drag/resize/gesture is started.\n *\n - newValue (string | Element | null) #optional a CSS selector string, an Element or `null` to not ignore any elements\n = (string | Element | object) The current ignoreFrom value or this Interactable\n **\n | interact(element, { ignoreFrom: document.getElementById('no-action') });\n | // or\n | interact(element).ignoreFrom('input, textarea, a');\n \\*/\n ignoreFrom: function (newValue) {\n if (trySelector(newValue)) { // CSS selector to match event.target\n this.options.ignoreFrom = newValue;\n return this;\n }\n\n if (isElement(newValue)) { // specific element\n this.options.ignoreFrom = newValue;\n return this;\n }\n\n return this.options.ignoreFrom;\n },\n\n /*\\\n * Interactable.allowFrom\n [ method ]\n *\n * A drag/resize/gesture is started only If the target of the\n * `mousedown`, `pointerdown` or `touchstart` event or any of it's\n * parents match the given CSS selector or Element.\n *\n - newValue (string | Element | null) #optional a CSS selector string, an Element or `null` to allow from any element\n = (string | Element | object) The current allowFrom value or this Interactable\n **\n | interact(element, { allowFrom: document.getElementById('drag-handle') });\n | // or\n | interact(element).allowFrom('.handle');\n \\*/\n allowFrom: function (newValue) {\n if (trySelector(newValue)) { // CSS selector to match event.target\n this.options.allowFrom = newValue;\n return this;\n }\n\n if (isElement(newValue)) { // specific element\n this.options.allowFrom = newValue;\n return this;\n }\n\n return this.options.allowFrom;\n },\n\n /*\\\n * Interactable.element\n [ method ]\n *\n * If this is not a selector Interactable, it returns the element this\n * interactable represents\n *\n = (Element) HTML / SVG Element\n \\*/\n element: function () {\n return this._element;\n },\n\n /*\\\n * Interactable.fire\n [ method ]\n *\n * Calls listeners for the given InteractEvent type bound globally\n * and directly to this Interactable\n *\n - iEvent (InteractEvent) The InteractEvent object to be fired on this Interactable\n = (Interactable) this Interactable\n \\*/\n fire: function (iEvent) {\n if (!(iEvent && iEvent.type) || !contains(eventTypes, iEvent.type)) {\n return this;\n }\n\n var listeners,\n i,\n len,\n onEvent = 'on' + iEvent.type,\n funcName = '';\n\n // Interactable#on() listeners\n if (iEvent.type in this._iEvents) {\n listeners = this._iEvents[iEvent.type];\n\n for (i = 0, len = listeners.length; i < len && !iEvent.immediatePropagationStopped; i++) {\n funcName = listeners[i].name;\n listeners[i](iEvent);\n }\n }\n\n // interactable.onevent listener\n if (isFunction(this[onEvent])) {\n funcName = this[onEvent].name;\n this[onEvent](iEvent);\n }\n\n // interact.on() listeners\n if (iEvent.type in globalEvents && (listeners = globalEvents[iEvent.type])) {\n\n for (i = 0, len = listeners.length; i < len && !iEvent.immediatePropagationStopped; i++) {\n funcName = listeners[i].name;\n listeners[i](iEvent);\n }\n }\n\n return this;\n },\n\n /*\\\n * Interactable.on\n [ method ]\n *\n * Binds a listener for an InteractEvent or DOM event.\n *\n - eventType (string | array | object) The types of events to listen for\n - listener (function) The function to be called on the given event(s)\n - useCapture (boolean) #optional useCapture flag for addEventListener\n = (object) This Interactable\n \\*/\n on: function (eventType, listener, useCapture) {\n var i;\n\n if (isString(eventType) && eventType.search(' ') !== -1) {\n eventType = eventType.trim().split(/ +/);\n }\n\n if (isArray(eventType)) {\n for (i = 0; i < eventType.length; i++) {\n this.on(eventType[i], listener, useCapture);\n }\n\n return this;\n }\n\n if (isObject(eventType)) {\n for (var prop in eventType) {\n this.on(prop, eventType[prop], listener);\n }\n\n return this;\n }\n\n if (eventType === 'wheel') {\n eventType = wheelEvent;\n }\n\n // convert to boolean\n useCapture = useCapture? true: false;\n\n if (contains(eventTypes, eventType)) {\n // if this type of event was never bound to this Interactable\n if (!(eventType in this._iEvents)) {\n this._iEvents[eventType] = [listener];\n }\n else {\n this._iEvents[eventType].push(listener);\n }\n }\n // delegated event for selector\n else if (this.selector) {\n if (!delegatedEvents[eventType]) {\n delegatedEvents[eventType] = {\n selectors: [],\n contexts : [],\n listeners: []\n };\n\n // add delegate listener functions\n for (i = 0; i < documents.length; i++) {\n events.add(documents[i], eventType, delegateListener);\n events.add(documents[i], eventType, delegateUseCapture, true);\n }\n }\n\n var delegated = delegatedEvents[eventType],\n index;\n\n for (index = delegated.selectors.length - 1; index >= 0; index--) {\n if (delegated.selectors[index] === this.selector\n && delegated.contexts[index] === this._context) {\n break;\n }\n }\n\n if (index === -1) {\n index = delegated.selectors.length;\n\n delegated.selectors.push(this.selector);\n delegated.contexts .push(this._context);\n delegated.listeners.push([]);\n }\n\n // keep listener and useCapture flag\n delegated.listeners[index].push([listener, useCapture]);\n }\n else {\n events.add(this._element, eventType, listener, useCapture);\n }\n\n return this;\n },\n\n /*\\\n * Interactable.off\n [ method ]\n *\n * Removes an InteractEvent or DOM event listener\n *\n - eventType (string | array | object) The types of events that were listened for\n - listener (function) The listener function to be removed\n - useCapture (boolean) #optional useCapture flag for removeEventListener\n = (object) This Interactable\n \\*/\n off: function (eventType, listener, useCapture) {\n var i;\n\n if (isString(eventType) && eventType.search(' ') !== -1) {\n eventType = eventType.trim().split(/ +/);\n }\n\n if (isArray(eventType)) {\n for (i = 0; i < eventType.length; i++) {\n this.off(eventType[i], listener, useCapture);\n }\n\n return this;\n }\n\n if (isObject(eventType)) {\n for (var prop in eventType) {\n this.off(prop, eventType[prop], listener);\n }\n\n return this;\n }\n\n var eventList,\n index = -1;\n\n // convert to boolean\n useCapture = useCapture? true: false;\n\n if (eventType === 'wheel') {\n eventType = wheelEvent;\n }\n\n // if it is an action event type\n if (contains(eventTypes, eventType)) {\n eventList = this._iEvents[eventType];\n\n if (eventList && (index = indexOf(eventList, listener)) !== -1) {\n this._iEvents[eventType].splice(index, 1);\n }\n }\n // delegated event\n else if (this.selector) {\n var delegated = delegatedEvents[eventType],\n matchFound = false;\n\n if (!delegated) { return this; }\n\n // count from last index of delegated to 0\n for (index = delegated.selectors.length - 1; index >= 0; index--) {\n // look for matching selector and context Node\n if (delegated.selectors[index] === this.selector\n && delegated.contexts[index] === this._context) {\n\n var listeners = delegated.listeners[index];\n\n // each item of the listeners array is an array: [function, useCaptureFlag]\n for (i = listeners.length - 1; i >= 0; i--) {\n var fn = listeners[i][0],\n useCap = listeners[i][1];\n\n // check if the listener functions and useCapture flags match\n if (fn === listener && useCap === useCapture) {\n // remove the listener from the array of listeners\n listeners.splice(i, 1);\n\n // if all listeners for this interactable have been removed\n // remove the interactable from the delegated arrays\n if (!listeners.length) {\n delegated.selectors.splice(index, 1);\n delegated.contexts .splice(index, 1);\n delegated.listeners.splice(index, 1);\n\n // remove delegate function from context\n events.remove(this._context, eventType, delegateListener);\n events.remove(this._context, eventType, delegateUseCapture, true);\n\n // remove the arrays if they are empty\n if (!delegated.selectors.length) {\n delegatedEvents[eventType] = null;\n }\n }\n\n // only remove one listener\n matchFound = true;\n break;\n }\n }\n\n if (matchFound) { break; }\n }\n }\n }\n // remove listener from this Interatable's element\n else {\n events.remove(this._element, eventType, listener, useCapture);\n }\n\n return this;\n },\n\n /*\\\n * Interactable.set\n [ method ]\n *\n * Reset the options of this Interactable\n - options (object) The new settings to apply\n = (object) This Interactable\n \\*/\n set: function (options) {\n if (!isObject(options)) {\n options = {};\n }\n\n this.options = extend({}, defaultOptions.base);\n\n var i,\n actions = ['drag', 'drop', 'resize', 'gesture'],\n methods = ['draggable', 'dropzone', 'resizable', 'gesturable'],\n perActions = extend(extend({}, defaultOptions.perAction), options[action] || {});\n\n for (i = 0; i < actions.length; i++) {\n var action = actions[i];\n\n this.options[action] = extend({}, defaultOptions[action]);\n\n this.setPerAction(action, perActions);\n\n this[methods[i]](options[action]);\n }\n\n var settings = [\n 'accept', 'actionChecker', 'allowFrom', 'deltaSource',\n 'dropChecker', 'ignoreFrom', 'origin', 'preventDefault',\n 'rectChecker', 'styleCursor'\n ];\n\n for (i = 0, len = settings.length; i < len; i++) {\n var setting = settings[i];\n\n this.options[setting] = defaultOptions.base[setting];\n\n if (setting in options) {\n this[setting](options[setting]);\n }\n }\n\n return this;\n },\n\n /*\\\n * Interactable.unset\n [ method ]\n *\n * Remove this interactable from the list of interactables and remove\n * it's drag, drop, resize and gesture capabilities\n *\n = (object) @interact\n \\*/\n unset: function () {\n events.remove(this._element, 'all');\n\n if (!isString(this.selector)) {\n events.remove(this, 'all');\n if (this.options.styleCursor) {\n this._element.style.cursor = '';\n }\n }\n else {\n // remove delegated events\n for (var type in delegatedEvents) {\n var delegated = delegatedEvents[type];\n\n for (var i = 0; i < delegated.selectors.length; i++) {\n if (delegated.selectors[i] === this.selector\n && delegated.contexts[i] === this._context) {\n\n delegated.selectors.splice(i, 1);\n delegated.contexts .splice(i, 1);\n delegated.listeners.splice(i, 1);\n\n // remove the arrays if they are empty\n if (!delegated.selectors.length) {\n delegatedEvents[type] = null;\n }\n }\n\n events.remove(this._context, type, delegateListener);\n events.remove(this._context, type, delegateUseCapture, true);\n\n break;\n }\n }\n }\n\n this.dropzone(false);\n\n interactables.splice(indexOf(interactables, this), 1);\n\n return interact;\n }\n };\n\n function warnOnce (method, message) {\n var warned = false;\n\n return function () {\n if (!warned) {\n window.console.warn(message);\n warned = true;\n }\n\n return method.apply(this, arguments);\n };\n }\n\n Interactable.prototype.snap = warnOnce(Interactable.prototype.snap,\n 'Interactable#snap is deprecated. See the new documentation for snapping at http://interactjs.io/docs/snapping');\n Interactable.prototype.restrict = warnOnce(Interactable.prototype.restrict,\n 'Interactable#restrict is deprecated. See the new documentation for resticting at http://interactjs.io/docs/restriction');\n Interactable.prototype.inertia = warnOnce(Interactable.prototype.inertia,\n 'Interactable#inertia is deprecated. See the new documentation for inertia at http://interactjs.io/docs/inertia');\n Interactable.prototype.autoScroll = warnOnce(Interactable.prototype.autoScroll,\n 'Interactable#autoScroll is deprecated. See the new documentation for autoScroll at http://interactjs.io/docs/#autoscroll');\n Interactable.prototype.squareResize = warnOnce(Interactable.prototype.squareResize,\n 'Interactable#squareResize is deprecated. See http://interactjs.io/docs/#resize-square');\n\n Interactable.prototype.accept = warnOnce(Interactable.prototype.accept,\n 'Interactable#accept is deprecated. use Interactable#dropzone({ accept: target }) instead');\n Interactable.prototype.dropChecker = warnOnce(Interactable.prototype.dropChecker,\n 'Interactable#dropChecker is deprecated. use Interactable#dropzone({ dropChecker: checkerFunction }) instead');\n Interactable.prototype.context = warnOnce(Interactable.prototype.context,\n 'Interactable#context as a method is deprecated. It will soon be a DOM Node instead');\n\n /*\\\n * interact.isSet\n [ method ]\n *\n * Check if an element has been set\n - element (Element) The Element being searched for\n = (boolean) Indicates if the element or CSS selector was previously passed to interact\n \\*/\n interact.isSet = function(element, options) {\n return interactables.indexOfElement(element, options && options.context) !== -1;\n };\n\n /*\\\n * interact.on\n [ method ]\n *\n * Adds a global listener for an InteractEvent or adds a DOM event to\n * `document`\n *\n - type (string | array | object) The types of events to listen for\n - listener (function) The function to be called on the given event(s)\n - useCapture (boolean) #optional useCapture flag for addEventListener\n = (object) interact\n \\*/\n interact.on = function (type, listener, useCapture) {\n if (isString(type) && type.search(' ') !== -1) {\n type = type.trim().split(/ +/);\n }\n\n if (isArray(type)) {\n for (var i = 0; i < type.length; i++) {\n interact.on(type[i], listener, useCapture);\n }\n\n return interact;\n }\n\n if (isObject(type)) {\n for (var prop in type) {\n interact.on(prop, type[prop], listener);\n }\n\n return interact;\n }\n\n // if it is an InteractEvent type, add listener to globalEvents\n if (contains(eventTypes, type)) {\n // if this type of event was never bound\n if (!globalEvents[type]) {\n globalEvents[type] = [listener];\n }\n else {\n globalEvents[type].push(listener);\n }\n }\n // If non InteractEvent type, addEventListener to document\n else {\n events.add(document, type, listener, useCapture);\n }\n\n return interact;\n };\n\n /*\\\n * interact.off\n [ method ]\n *\n * Removes a global InteractEvent listener or DOM event from `document`\n *\n - type (string | array | object) The types of events that were listened for\n - listener (function) The listener function to be removed\n - useCapture (boolean) #optional useCapture flag for removeEventListener\n = (object) interact\n \\*/\n interact.off = function (type, listener, useCapture) {\n if (isString(type) && type.search(' ') !== -1) {\n type = type.trim().split(/ +/);\n }\n\n if (isArray(type)) {\n for (var i = 0; i < type.length; i++) {\n interact.off(type[i], listener, useCapture);\n }\n\n return interact;\n }\n\n if (isObject(type)) {\n for (var prop in type) {\n interact.off(prop, type[prop], listener);\n }\n\n return interact;\n }\n\n if (!contains(eventTypes, type)) {\n events.remove(document, type, listener, useCapture);\n }\n else {\n var index;\n\n if (type in globalEvents\n && (index = indexOf(globalEvents[type], listener)) !== -1) {\n globalEvents[type].splice(index, 1);\n }\n }\n\n return interact;\n };\n\n /*\\\n * interact.enableDragging\n [ method ]\n *\n * Deprecated.\n *\n * Returns or sets whether dragging is enabled for any Interactables\n *\n - newValue (boolean) #optional `true` to allow the action; `false` to disable action for all Interactables\n = (boolean | object) The current setting or interact\n \\*/\n interact.enableDragging = warnOnce(function (newValue) {\n if (newValue !== null && newValue !== undefined) {\n actionIsEnabled.drag = newValue;\n\n return interact;\n }\n return actionIsEnabled.drag;\n }, 'interact.enableDragging is deprecated and will soon be removed.');\n\n /*\\\n * interact.enableResizing\n [ method ]\n *\n * Deprecated.\n *\n * Returns or sets whether resizing is enabled for any Interactables\n *\n - newValue (boolean) #optional `true` to allow the action; `false` to disable action for all Interactables\n = (boolean | object) The current setting or interact\n \\*/\n interact.enableResizing = warnOnce(function (newValue) {\n if (newValue !== null && newValue !== undefined) {\n actionIsEnabled.resize = newValue;\n\n return interact;\n }\n return actionIsEnabled.resize;\n }, 'interact.enableResizing is deprecated and will soon be removed.');\n\n /*\\\n * interact.enableGesturing\n [ method ]\n *\n * Deprecated.\n *\n * Returns or sets whether gesturing is enabled for any Interactables\n *\n - newValue (boolean) #optional `true` to allow the action; `false` to disable action for all Interactables\n = (boolean | object) The current setting or interact\n \\*/\n interact.enableGesturing = warnOnce(function (newValue) {\n if (newValue !== null && newValue !== undefined) {\n actionIsEnabled.gesture = newValue;\n\n return interact;\n }\n return actionIsEnabled.gesture;\n }, 'interact.enableGesturing is deprecated and will soon be removed.');\n\n interact.eventTypes = eventTypes;\n\n /*\\\n * interact.debug\n [ method ]\n *\n * Returns debugging data\n = (object) An object with properties that outline the current state and expose internal functions and variables\n \\*/\n interact.debug = function () {\n var interaction = interactions[0] || new Interaction();\n\n return {\n interactions : interactions,\n target : interaction.target,\n dragging : interaction.dragging,\n resizing : interaction.resizing,\n gesturing : interaction.gesturing,\n prepared : interaction.prepared,\n matches : interaction.matches,\n matchElements : interaction.matchElements,\n\n prevCoords : interaction.prevCoords,\n startCoords : interaction.startCoords,\n\n pointerIds : interaction.pointerIds,\n pointers : interaction.pointers,\n addPointer : listeners.addPointer,\n removePointer : listeners.removePointer,\n recordPointer : listeners.recordPointer,\n\n snap : interaction.snapStatus,\n restrict : interaction.restrictStatus,\n inertia : interaction.inertiaStatus,\n\n downTime : interaction.downTimes[0],\n downEvent : interaction.downEvent,\n downPointer : interaction.downPointer,\n prevEvent : interaction.prevEvent,\n\n Interactable : Interactable,\n interactables : interactables,\n pointerIsDown : interaction.pointerIsDown,\n defaultOptions : defaultOptions,\n defaultActionChecker : defaultActionChecker,\n\n actionCursors : actionCursors,\n dragMove : listeners.dragMove,\n resizeMove : listeners.resizeMove,\n gestureMove : listeners.gestureMove,\n pointerUp : listeners.pointerUp,\n pointerDown : listeners.pointerDown,\n pointerMove : listeners.pointerMove,\n pointerHover : listeners.pointerHover,\n\n eventTypes : eventTypes,\n\n events : events,\n globalEvents : globalEvents,\n delegatedEvents : delegatedEvents,\n\n prefixedPropREs : prefixedPropREs\n };\n };\n\n // expose the functions used to calculate multi-touch properties\n interact.getPointerAverage = pointerAverage;\n interact.getTouchBBox = touchBBox;\n interact.getTouchDistance = touchDistance;\n interact.getTouchAngle = touchAngle;\n\n interact.getElementRect = getElementRect;\n interact.getElementClientRect = getElementClientRect;\n interact.matchesSelector = matchesSelector;\n interact.closest = closest;\n\n /*\\\n * interact.margin\n [ method ]\n *\n * Deprecated. Use `interact(target).resizable({ margin: number });` instead.\n * Returns or sets the margin for autocheck resizing used in\n * @Interactable.getAction. That is the distance from the bottom and right\n * edges of an element clicking in which will start resizing\n *\n - newValue (number) #optional\n = (number | interact) The current margin value or interact\n \\*/\n interact.margin = warnOnce(function (newvalue) {\n if (isNumber(newvalue)) {\n margin = newvalue;\n\n return interact;\n }\n return margin;\n },\n 'interact.margin is deprecated. Use interact(target).resizable({ margin: number }); instead.') ;\n\n /*\\\n * interact.supportsTouch\n [ method ]\n *\n = (boolean) Whether or not the browser supports touch input\n \\*/\n interact.supportsTouch = function () {\n return supportsTouch;\n };\n\n /*\\\n * interact.supportsPointerEvent\n [ method ]\n *\n = (boolean) Whether or not the browser supports PointerEvents\n \\*/\n interact.supportsPointerEvent = function () {\n return supportsPointerEvent;\n };\n\n /*\\\n * interact.stop\n [ method ]\n *\n * Cancels all interactions (end events are not fired)\n *\n - event (Event) An event on which to call preventDefault()\n = (object) interact\n \\*/\n interact.stop = function (event) {\n for (var i = interactions.length - 1; i >= 0; i--) {\n interactions[i].stop(event);\n }\n\n return interact;\n };\n\n /*\\\n * interact.dynamicDrop\n [ method ]\n *\n * Returns or sets whether the dimensions of dropzone elements are\n * calculated on every dragmove or only on dragstart for the default\n * dropChecker\n *\n - newValue (boolean) #optional True to check on each move. False to check only before start\n = (boolean | interact) The current setting or interact\n \\*/\n interact.dynamicDrop = function (newValue) {\n if (isBool(newValue)) {\n //if (dragging && dynamicDrop !== newValue && !newValue) {\n //calcRects(dropzones);\n //}\n\n dynamicDrop = newValue;\n\n return interact;\n }\n return dynamicDrop;\n };\n\n /*\\\n * interact.pointerMoveTolerance\n [ method ]\n * Returns or sets the distance the pointer must be moved before an action\n * sequence occurs. This also affects tolerance for tap events.\n *\n - newValue (number) #optional The movement from the start position must be greater than this value\n = (number | Interactable) The current setting or interact\n \\*/\n interact.pointerMoveTolerance = function (newValue) {\n if (isNumber(newValue)) {\n pointerMoveTolerance = newValue;\n\n return this;\n }\n\n return pointerMoveTolerance;\n };\n\n /*\\\n * interact.maxInteractions\n [ method ]\n **\n * Returns or sets the maximum number of concurrent interactions allowed.\n * By default only 1 interaction is allowed at a time (for backwards\n * compatibility). To allow multiple interactions on the same Interactables\n * and elements, you need to enable it in the draggable, resizable and\n * gesturable `'max'` and `'maxPerElement'` options.\n **\n - newValue (number) #optional Any number. newValue <= 0 means no interactions.\n \\*/\n interact.maxInteractions = function (newValue) {\n if (isNumber(newValue)) {\n maxInteractions = newValue;\n\n return this;\n }\n\n return maxInteractions;\n };\n\n interact.createSnapGrid = function (grid) {\n return function (x, y) {\n var offsetX = 0,\n offsetY = 0;\n\n if (isObject(grid.offset)) {\n offsetX = grid.offset.x;\n offsetY = grid.offset.y;\n }\n\n var gridx = Math.round((x - offsetX) / grid.x),\n gridy = Math.round((y - offsetY) / grid.y),\n\n newX = gridx * grid.x + offsetX,\n newY = gridy * grid.y + offsetY;\n\n return {\n x: newX,\n y: newY,\n range: grid.range\n };\n };\n };\n\n function endAllInteractions (event) {\n for (var i = 0; i < interactions.length; i++) {\n interactions[i].pointerEnd(event, event);\n }\n }\n\n function listenToDocument (doc) {\n if (contains(documents, doc)) { return; }\n\n var win = doc.defaultView || doc.parentWindow;\n\n // add delegate event listener\n for (var eventType in delegatedEvents) {\n events.add(doc, eventType, delegateListener);\n events.add(doc, eventType, delegateUseCapture, true);\n }\n\n if (PointerEvent) {\n if (PointerEvent === win.MSPointerEvent) {\n pEventTypes = {\n up: 'MSPointerUp', down: 'MSPointerDown', over: 'mouseover',\n out: 'mouseout', move: 'MSPointerMove', cancel: 'MSPointerCancel' };\n }\n else {\n pEventTypes = {\n up: 'pointerup', down: 'pointerdown', over: 'pointerover',\n out: 'pointerout', move: 'pointermove', cancel: 'pointercancel' };\n }\n\n events.add(doc, pEventTypes.down , listeners.selectorDown );\n events.add(doc, pEventTypes.move , listeners.pointerMove );\n events.add(doc, pEventTypes.over , listeners.pointerOver );\n events.add(doc, pEventTypes.out , listeners.pointerOut );\n events.add(doc, pEventTypes.up , listeners.pointerUp );\n events.add(doc, pEventTypes.cancel, listeners.pointerCancel);\n\n // autoscroll\n events.add(doc, pEventTypes.move, listeners.autoScrollMove);\n }\n else {\n events.add(doc, 'mousedown', listeners.selectorDown);\n events.add(doc, 'mousemove', listeners.pointerMove );\n events.add(doc, 'mouseup' , listeners.pointerUp );\n events.add(doc, 'mouseover', listeners.pointerOver );\n events.add(doc, 'mouseout' , listeners.pointerOut );\n\n events.add(doc, 'touchstart' , listeners.selectorDown );\n events.add(doc, 'touchmove' , listeners.pointerMove );\n events.add(doc, 'touchend' , listeners.pointerUp );\n events.add(doc, 'touchcancel', listeners.pointerCancel);\n\n // autoscroll\n events.add(doc, 'mousemove', listeners.autoScrollMove);\n events.add(doc, 'touchmove', listeners.autoScrollMove);\n }\n\n events.add(win, 'blur', endAllInteractions);\n\n try {\n if (win.frameElement) {\n var parentDoc = win.frameElement.ownerDocument,\n parentWindow = parentDoc.defaultView;\n\n events.add(parentDoc , 'mouseup' , listeners.pointerEnd);\n events.add(parentDoc , 'touchend' , listeners.pointerEnd);\n events.add(parentDoc , 'touchcancel' , listeners.pointerEnd);\n events.add(parentDoc , 'pointerup' , listeners.pointerEnd);\n events.add(parentDoc , 'MSPointerUp' , listeners.pointerEnd);\n events.add(parentWindow, 'blur' , endAllInteractions );\n }\n }\n catch (error) {\n interact.windowParentError = error;\n }\n\n // prevent native HTML5 drag on interact.js target elements\n events.add(doc, 'dragstart', function (event) {\n for (var i = 0; i < interactions.length; i++) {\n var interaction = interactions[i];\n\n if (interaction.element\n && (interaction.element === event.target\n || nodeContains(interaction.element, event.target))) {\n\n interaction.checkAndPreventDefault(event, interaction.target, interaction.element);\n return;\n }\n }\n });\n\n if (events.useAttachEvent) {\n // For IE's lack of Event#preventDefault\n events.add(doc, 'selectstart', function (event) {\n var interaction = interactions[0];\n\n if (interaction.currentAction()) {\n interaction.checkAndPreventDefault(event);\n }\n });\n\n // For IE's bad dblclick event sequence\n events.add(doc, 'dblclick', doOnInteractions('ie8Dblclick'));\n }\n\n documents.push(doc);\n }\n\n listenToDocument(document);\n\n function indexOf (array, target) {\n for (var i = 0, len = array.length; i < len; i++) {\n if (array[i] === target) {\n return i;\n }\n }\n\n return -1;\n }\n\n function contains (array, target) {\n return indexOf(array, target) !== -1;\n }\n\n function matchesSelector (element, selector, nodeList) {\n if (ie8MatchesSelector) {\n return ie8MatchesSelector(element, selector, nodeList);\n }\n\n // remove /deep/ from selectors if shadowDOM polyfill is used\n if (window !== realWindow) {\n selector = selector.replace(/\\/deep\\//g, ' ');\n }\n\n return element[prefixedMatchesSelector](selector);\n }\n\n function matchesUpTo (element, selector, limit) {\n while (isElement(element)) {\n if (matchesSelector(element, selector)) {\n return true;\n }\n\n element = parentElement(element);\n\n if (element === limit) {\n return matchesSelector(element, selector);\n }\n }\n\n return false;\n }\n\n // For IE8's lack of an Element#matchesSelector\n // taken from http://tanalin.com/en/blog/2012/12/matches-selector-ie8/ and modified\n if (!(prefixedMatchesSelector in Element.prototype) || !isFunction(Element.prototype[prefixedMatchesSelector])) {\n ie8MatchesSelector = function (element, selector, elems) {\n elems = elems || element.parentNode.querySelectorAll(selector);\n\n for (var i = 0, len = elems.length; i < len; i++) {\n if (elems[i] === element) {\n return true;\n }\n }\n\n return false;\n };\n }\n\n // requestAnimationFrame polyfill\n (function() {\n var lastTime = 0,\n vendors = ['ms', 'moz', 'webkit', 'o'];\n\n for(var x = 0; x < vendors.length && !realWindow.requestAnimationFrame; ++x) {\n reqFrame = realWindow[vendors[x]+'RequestAnimationFrame'];\n cancelFrame = realWindow[vendors[x]+'CancelAnimationFrame'] || realWindow[vendors[x]+'CancelRequestAnimationFrame'];\n }\n\n if (!reqFrame) {\n reqFrame = function(callback) {\n var currTime = new Date().getTime(),\n timeToCall = Math.max(0, 16 - (currTime - lastTime)),\n id = setTimeout(function() { callback(currTime + timeToCall); },\n timeToCall);\n lastTime = currTime + timeToCall;\n return id;\n };\n }\n\n if (!cancelFrame) {\n cancelFrame = function(id) {\n clearTimeout(id);\n };\n }\n }());\n\n /* global exports: true, module, define */\n\n // http://documentcloud.github.io/underscore/docs/underscore.html#section-11\n if (typeof exports !== 'undefined') {\n if (typeof module !== 'undefined' && module.exports) {\n exports = module.exports = interact;\n }\n exports.interact = interact;\n }\n // AMD\n else if (typeof define === 'function' && define.amd) {\n define('interact', function() {\n return interact;\n });\n }\n else {\n realWindow.interact = interact;\n }\n\n} (typeof window === 'undefined'? undefined : window));\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/interact.js/interact.js\n ** module id = 47\n ** module chunks = 0\n **/","module.exports = \"\\n
\\n \\n \\n \\n
\\n\";\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/vue-html-loader!./~/vue-loader/lib/selector.js?type=template&index=0!./src/GridItem.vue\n ** module id = 48\n ** module chunks = 0\n **/","var __vue_script__, __vue_template__\nrequire(\"!!vue-style-loader!css-loader?sourceMap!./../node_modules/vue-loader/lib/style-rewriter.js!./../node_modules/vue-loader/lib/selector.js?type=style&index=0!./GridLayout.vue\")\n__vue_script__ = require(\"!!babel-loader!./../node_modules/vue-loader/lib/selector.js?type=script&index=0!./GridLayout.vue\")\nif (__vue_script__ &&\n __vue_script__.__esModule &&\n Object.keys(__vue_script__).length > 1) {\n console.warn(\"[vue-loader] src\\\\GridLayout.vue: named exports in *.vue files are ignored.\")}\n__vue_template__ = require(\"!!vue-html-loader!./../node_modules/vue-loader/lib/selector.js?type=template&index=0!./GridLayout.vue\")\nmodule.exports = __vue_script__ || {}\nif (module.exports.__esModule) module.exports = module.exports.default\nif (__vue_template__) {\n(typeof module.exports === \"function\" ? (module.exports.options || (module.exports.options = {})) : module.exports).template = __vue_template__\n}\nif (module.hot) {(function () { module.hot.accept()\n var hotAPI = require(\"vue-hot-reload-api\")\n hotAPI.install(require(\"vue\"), false)\n if (!hotAPI.compatible) return\n var id = \"./GridLayout.vue\"\n if (!module.hot.data) {\n hotAPI.createRecord(id, module.exports)\n } else {\n hotAPI.update(id, module.exports, __vue_template__)\n }\n})()}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/GridLayout.vue\n ** module id = 49\n ** module chunks = 0\n **/","// style-loader: Adds some css to the DOM by adding a \\r\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader?sourceMap!./~/vue-loader/lib/style-rewriter.js!./~/vue-loader/lib/selector.js?type=style&index=0!./src/GridLayout.vue\n ** module id = 51\n ** module chunks = 0\n **/","\r\n\r\n\n\n\n/** WEBPACK FOOTER **\n ** GridLayout.vue?f5d44fae\n **/","\"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) { 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 strategyOptions = {\n reporter: reporter,\n batchProcessor: batchProcessor,\n stateHandler: stateHandler,\n idHandler: idHandler\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 are 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 }, 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 if (stateHandler.getState(element).startSize) {\n var width = element.offsetWidth;\n var height = element.offsetHeight;\n if (stateHandler.getState(element).startSize.width !== width || stateHandler.getState(element).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 return {\n listenTo: listenTo,\n removeListener: eventListenerHandler.removeListener,\n removeAllListeners: eventListenerHandler.removeAllListeners,\n uninstall: uninstall\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\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/element-resize-detector/src/element-resize-detector.js\n ** module id = 53\n ** module chunks = 0\n **/","\"use strict\";\n\nvar utils = module.exports = {};\n\n/**\n * Loops through the collection and calls the callback for each element. if the callback returns truthy, the loop is broken and returns the same value.\n * @public\n * @param {*} collection The collection to loop through. Needs to have a length property set and have indices set from 0 to length - 1.\n * @param {function} callback The callback to be called for each element. The element will be given as a parameter to the callback. If this callback returns truthy, the loop is broken and the same value is returned.\n * @returns {*} The value that a callback has returned (if truthy). Otherwise nothing.\n */\nutils.forEach = function(collection, callback) {\n for(var i = 0; i < collection.length; i++) {\n var result = callback(collection[i]);\n if(result) {\n return result;\n }\n }\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/element-resize-detector/src/collection-utils.js\n ** module id = 54\n ** module chunks = 0\n **/","\"use strict\";\n\nmodule.exports = function(options) {\n var getState = options.stateHandler.getState;\n\n /**\n * Tells if the element has been made detectable and ready to be listened for resize events.\n * @public\n * @param {element} The element to check.\n * @returns {boolean} True or false depending on if the element is detectable or not.\n */\n function isDetectable(element) {\n var state = getState(element);\n return state && !!state.isDetectable;\n }\n\n /**\n * Marks the element that it has been made detectable and ready to be listened for resize events.\n * @public\n * @param {element} The element to mark.\n */\n function markAsDetectable(element) {\n getState(element).isDetectable = true;\n }\n\n /**\n * Tells if the element is busy or not.\n * @public\n * @param {element} The element to check.\n * @returns {boolean} True or false depending on if the element is busy or not.\n */\n function isBusy(element) {\n return !!getState(element).busy;\n }\n\n /**\n * Marks the object is busy and should not be made detectable.\n * @public\n * @param {element} element The element to mark.\n * @param {boolean} busy If the element is busy or not.\n */\n function markBusy(element, busy) {\n getState(element).busy = !!busy;\n }\n\n return {\n isDetectable: isDetectable,\n markAsDetectable: markAsDetectable,\n isBusy: isBusy,\n markBusy: markBusy\n };\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/element-resize-detector/src/element-utils.js\n ** module id = 55\n ** module chunks = 0\n **/","\"use strict\";\n\nmodule.exports = function(idHandler) {\n var eventListeners = {};\n\n /**\n * Gets all listeners for the given element.\n * @public\n * @param {element} element The element to get all listeners for.\n * @returns All listeners for the given element.\n */\n function getListeners(element) {\n return eventListeners[idHandler.get(element)] || [];\n }\n\n /**\n * Stores the given listener for the given element. Will not actually add the listener to the element.\n * @public\n * @param {element} element The element that should have the listener added.\n * @param {function} listener The callback that the element has added.\n */\n function addListener(element, listener) {\n var id = idHandler.get(element);\n\n if(!eventListeners[id]) {\n eventListeners[id] = [];\n }\n\n eventListeners[id].push(listener);\n }\n\n function removeListener(element, listener) {\n var listeners = getListeners(element);\n for (var i = 0, len = listeners.length; i < len; ++i) {\n if (listeners[i] === listener) {\n listeners.splice(i, 1);\n break;\n }\n }\n }\n\n function removeAllListeners(element) {\n var listeners = eventListeners[idHandler.get(element)];\n if (!listeners) { return; }\n listeners.length = 0;\n }\n\n return {\n get: getListeners,\n add: addListener,\n removeListener: removeListener,\n removeAllListeners: removeAllListeners\n };\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/element-resize-detector/src/listener-handler.js\n ** module id = 56\n ** module chunks = 0\n **/","\"use strict\";\n\nmodule.exports = function() {\n var idCount = 1;\n\n /**\n * Generates a new unique id in the context.\n * @public\n * @returns {number} A unique id in the context.\n */\n function generate() {\n return idCount++;\n }\n\n return {\n generate: generate\n };\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/element-resize-detector/src/id-generator.js\n ** module id = 57\n ** module chunks = 0\n **/","\"use strict\";\n\nmodule.exports = function(options) {\n var idGenerator = options.idGenerator;\n var getState = options.stateHandler.getState;\n\n /**\n * Gets the resize detector id of the element.\n * @public\n * @param {element} element The target element to get the id of.\n * @returns {string|number|null} The id of the element. Null if it has no id.\n */\n function getId(element) {\n var state = getState(element);\n\n if (state && state.id !== undefined) {\n return state.id;\n }\n\n return null;\n }\n\n /**\n * Sets the resize detector id of the element. Requires the element to have a resize detector state initialized.\n * @public\n * @param {element} element The target element to set the id of.\n * @returns {string|number|null} The id of the element.\n */\n function setId(element) {\n var state = getState(element);\n\n if (!state) {\n throw new Error(\"setId required the element to have a resize detection state.\");\n }\n\n var id = idGenerator.generate();\n\n state.id = id;\n\n return id;\n }\n\n return {\n get: getId,\n set: setId\n };\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/element-resize-detector/src/id-handler.js\n ** module id = 58\n ** module chunks = 0\n **/","\"use strict\";\n\n/* global console: false */\n\n/**\n * Reporter that handles the reporting of logs, warnings and errors.\n * @public\n * @param {boolean} quiet Tells if the reporter should be quiet or not.\n */\nmodule.exports = function(quiet) {\n function noop() {\n //Does nothing.\n }\n\n var reporter = {\n log: noop,\n warn: noop,\n error: noop\n };\n\n if(!quiet && window.console) {\n var attachFunction = function(reporter, name) {\n //The proxy is needed to be able to call the method with the console context,\n //since we cannot use bind.\n reporter[name] = function reporterProxy() {\n var f = console[name];\n if (f.apply) { //IE9 does not support console.log.apply :)\n f.apply(console, arguments);\n } else {\n for (var i = 0; i < arguments.length; i++) {\n f(arguments[i]);\n }\n }\n };\n };\n\n attachFunction(reporter, \"log\");\n attachFunction(reporter, \"warn\");\n attachFunction(reporter, \"error\");\n }\n\n return reporter;\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/element-resize-detector/src/reporter.js\n ** module id = 59\n ** module chunks = 0\n **/","\"use strict\";\n\nvar detector = module.exports = {};\n\ndetector.isIE = function(version) {\n function isAnyIeVersion() {\n var agent = navigator.userAgent.toLowerCase();\n return agent.indexOf(\"msie\") !== -1 || agent.indexOf(\"trident\") !== -1 || agent.indexOf(\" edge/\") !== -1;\n }\n\n if(!isAnyIeVersion()) {\n return false;\n }\n\n if(!version) {\n return true;\n }\n\n //Shamelessly stolen from https://gist.github.com/padolsey/527683\n var ieVersion = (function(){\n var undef,\n v = 3,\n div = document.createElement(\"div\"),\n all = div.getElementsByTagName(\"i\");\n\n do {\n div.innerHTML = \"\";\n }\n while (all[0]);\n\n return v > 4 ? v : undef;\n }());\n\n return version === ieVersion;\n};\n\ndetector.isLegacyOpera = function() {\n return !!window.opera;\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/element-resize-detector/src/browser-detector.js\n ** module id = 60\n ** module chunks = 0\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\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/element-resize-detector/~/batch-processor/src/batch-processor.js\n ** module id = 61\n ** module chunks = 0\n **/","\"use strict\";\n\nvar utils = module.exports = {};\n\nutils.getOption = getOption;\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\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/element-resize-detector/~/batch-processor/src/utils.js\n ** module id = 62\n ** module chunks = 0\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\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/element-resize-detector/src/state-handler.js\n ** module id = 63\n ** module chunks = 0\n **/","/**\n * Resize detection strategy that injects objects to elements in order to detect resize events.\n * Heavily inspired by: http://www.backalleycoder.com/2013/03/18/cross-browser-event-based-element-resize-detection/\n */\n\n\"use strict\";\n\nvar browserDetector = require(\"../browser-detector\");\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\n if(!reporter) {\n throw new Error(\"Missing required dependency: reporter.\");\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 if(!getObject(element)) {\n throw new Error(\"Element is not detectable by this strategy.\");\n }\n\n function listenerProxy() {\n listener(element);\n }\n\n if(browserDetector.isIE(8)) {\n //IE 8 does not support object, but supports the resize event directly on elements.\n getState(element).object = {\n proxy: listenerProxy\n };\n element.attachEvent(\"onresize\", listenerProxy);\n } else {\n var object = getObject(element);\n object.contentDocument.defaultView.addEventListener(\"resize\", listenerProxy);\n }\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 var debug = options.debug;\n\n function injectObject(element, callback) {\n var OBJECT_STYLE = \"display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none; padding: 0; margin: 0; opacity: 0; z-index: -1000; pointer-events: none;\";\n\n //The target element needs to be positioned (everything except static) so the absolute positioned object will be positioned relative to the target element.\n\n // Position altering may be performed directly or on object load, depending on if style resolution is possible directly or not.\n var positionCheckPerformed = false;\n\n // The element may not yet be attached to the DOM, and therefore the style object may be empty in some browsers.\n // Since the style object is a reference, it will be updated as soon as the element is attached to the DOM.\n var style = window.getComputedStyle(element);\n var width = element.offsetWidth;\n var height = element.offsetHeight;\n\n getState(element).startSize = {\n width: width,\n height: height\n };\n\n function mutateDom() {\n function alterPositionStyles() {\n if(style.position === \"static\") {\n element.style.position = \"relative\";\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 onObjectLoad() {\n // The object has been loaded, which means that the element now is guaranteed to be attached to the DOM.\n if (!positionCheckPerformed) {\n alterPositionStyles();\n }\n\n /*jshint validthis: true */\n\n function getDocument(element, callback) {\n //Opera 12 seem to call the object.onload before the actual document has been created.\n //So if it is not present, poll it with an timeout until it is present.\n //TODO: Could maybe be handled better with object.onreadystatechange or similar.\n if(!element.contentDocument) {\n setTimeout(function checkForObjectDocument() {\n getDocument(element, callback);\n }, 100);\n\n return;\n }\n\n callback(element.contentDocument);\n }\n\n //Mutating the object element here seems to fire another load event.\n //Mutating the inner document of the object element is fine though.\n var objectElement = this;\n\n //Create the style element to be added to the object.\n getDocument(objectElement, function onObjectDocumentReady(objectDocument) {\n //Notify that the element is ready to be listened to.\n callback(element);\n });\n }\n\n // The element may be detached from the DOM, and some browsers does not support style resolving of detached elements.\n // The alterPositionStyles needs to be delayed until we know the element has been attached to the DOM (which we are sure of when the onObjectLoad has been fired), if style resolution is not possible.\n if (style.position !== \"\") {\n alterPositionStyles(style);\n positionCheckPerformed = true;\n }\n\n //Add an object element as a child to the target element that will be listened to for resize events.\n var object = document.createElement(\"object\");\n object.style.cssText = OBJECT_STYLE;\n object.type = \"text/html\";\n object.onload = onObjectLoad;\n\n //Safari: This must occur before adding the object to the DOM.\n //IE: Does not like that this happens before, even if it is also added after.\n if(!browserDetector.isIE()) {\n object.data = \"about:blank\";\n }\n\n element.appendChild(object);\n getState(element).object = object;\n\n //IE: This must occur after adding the object to the DOM.\n if(browserDetector.isIE()) {\n object.data = \"about:blank\";\n }\n }\n\n if(batchProcessor) {\n batchProcessor.add(mutateDom);\n } else {\n mutateDom();\n }\n }\n\n if(browserDetector.isIE(8)) {\n //IE 8 does not support objects properly. Luckily they do support the resize event.\n //So do not inject the object and notify that the element is already ready to be listened to.\n //The event handler for the resize event is attached in the utils.addListener instead.\n callback(element);\n } else {\n injectObject(element, callback);\n }\n }\n\n /**\n * Returns the child object of the target element.\n * @private\n * @param {element} element The target element.\n * @returns The object element of the target.\n */\n function getObject(element) {\n return getState(element).object;\n }\n\n function uninstall(element) {\n if(browserDetector.isIE(8)) {\n element.detachEvent(\"onresize\", getState(element).object.proxy);\n } else {\n element.removeChild(getObject(element));\n }\n delete getState(element).object;\n }\n\n return {\n makeDetectable: makeDetectable,\n addListener: addListener,\n uninstall: uninstall\n };\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/element-resize-detector/src/detection-strategy/object.js\n ** module id = 64\n ** module chunks = 0\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 // 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 var styleId = \"erd_scroll_detection_scrollbar_style\";\n var detectionContainerClass = \"erd_scroll_detection_container\";\n injectScrollStyle(styleId, detectionContainerClass);\n\n function getScrollbarSizes() {\n var width = 500;\n var height = 500;\n\n var child = document.createElement(\"div\");\n child.style.cssText = \"position: absolute; width: \" + width*2 + \"px; height: \" + height*2 + \"px; visibility: hidden;\";\n\n var container = document.createElement(\"div\");\n container.style.cssText = \"position: absolute; width: \" + width + \"px; height: \" + height + \"px; overflow: scroll; visibility: none; top: \" + -width*3 + \"px; left: \" + -height*3 + \"px; visibility: hidden;\";\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(styleId, containerClass) {\n function injectStyle(style, method) {\n method = method || function (element) {\n document.head.appendChild(element);\n };\n\n var styleElement = document.createElement(\"style\");\n styleElement.innerHTML = style;\n styleElement.id = styleId;\n method(styleElement);\n return styleElement;\n }\n\n if (!document.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 { display: none; }\\n\\n\";\n style += \".\" + containerAnimationActiveClass + \" { -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 /**\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 return element === element.ownerDocument.body || element.ownerDocument.body.contains(element);\n }\n return !isInDocument(element);\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 return getComputedStyle(container).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 = 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 getExpandElement(element) {\n return getState(element).container.childNodes[0].childNodes[0].childNodes[0];\n }\n\n function getExpandChildElement(element) {\n return getExpandElement(element).childNodes[0];\n }\n\n function getShrinkElement(element) {\n return getState(element).container.childNodes[0].childNodes[0].childNodes[1];\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 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 injectContainerElement() {\n var container = getState(element).container;\n\n if (!container) {\n container = document.createElement(\"div\");\n container.className = detectionContainerClass;\n container.style.cssText = \"visibility: hidden; display: inline; width: 0px; height: 0px; z-index: -1; overflow: hidden;\";\n getState(element).container = container;\n addAnimationClass(container);\n element.appendChild(container);\n\n addEvent(container, \"animationstart\", function onAnimationStart () {\n getState(element).onRendered && getState(element).onRendered();\n });\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.position = \"relative\";\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 getTopBottomBottomRightCssText(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 = \"position: absolute; overflow: hidden; z-index: -1; visibility: hidden; width: 100%; height: 100%; left: 0px; top: 0px;\";\n var containerStyle = \"position: absolute; overflow: hidden; z-index: -1; visibility: hidden; \" + getTopBottomBottomRightCssText(-(1 + scrollbarWidth), -(1 + scrollbarHeight), -scrollbarHeight, -scrollbarWidth);\n var expandStyle = \"position: absolute; overflow: scroll; z-index: -1; visibility: hidden; width: 100%; height: 100%;\";\n var shrinkStyle = \"position: absolute; overflow: scroll; z-index: -1; visibility: hidden; width: 100%; height: 100%;\";\n var expandChildStyle = \"position: absolute; left: 0; top: 0;\";\n var shrinkChildStyle = \"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 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 addEvent(expand, \"scroll\", function onExpandScroll() {\n getState(element).onExpand && getState(element).onExpand();\n });\n\n addEvent(shrink, \"scroll\", function onShrinkScroll() {\n getState(element).onShrink && getState(element).onShrink();\n });\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.width = expandWidth + \"px\";\n expandChild.style.height = expandHeight + \"px\";\n }\n\n function updateDetectorElements(done) {\n var width = element.offsetWidth;\n var height = element.offsetHeight;\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 batchProcessor.add(0, function performUpdateChildSizes() {\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 positionScrollbars(element, width, height);\n });\n\n if (done) {\n batchProcessor.add(2, done);\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 the 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 var width = element.offsetWidth;\n var height = element.offsetHeight;\n\n if (width !== element.lastWidth || height !== element.lastHeight) {\n debug(\"Element size changed.\");\n updateDetectorElements(notifyListenersIfNeeded);\n } else {\n debug(\"Element size has not changed (\" + width + \"x\" + height + \").\");\n }\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 if (state.busy) {\n // Uninstall has been called while the element is being prepared.\n // Right between the sync code and async batch.\n return;\n }\n\n element.removeChild(state.container);\n }\n\n return {\n makeDetectable: makeDetectable,\n addListener: addListener,\n uninstall: uninstall\n };\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/element-resize-detector/src/detection-strategy/scroll.js\n ** module id = 65\n ** module chunks = 0\n **/","module.exports = \"\\n\\n
\\n \\n \\n
\\n\";\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/vue-html-loader!./~/vue-loader/lib/selector.js?type=template&index=0!./src/GridLayout.vue\n ** module id = 66\n ** module chunks = 0\n **/","var __vue_script__, __vue_template__\nrequire(\"!!vue-style-loader!css-loader?sourceMap!./../node_modules/vue-loader/lib/style-rewriter.js!./../node_modules/vue-loader/lib/selector.js?type=style&index=0!./ResponsiveGridLayout.vue\")\n__vue_script__ = require(\"!!babel-loader!./../node_modules/vue-loader/lib/selector.js?type=script&index=0!./ResponsiveGridLayout.vue\")\nif (__vue_script__ &&\n __vue_script__.__esModule &&\n Object.keys(__vue_script__).length > 1) {\n console.warn(\"[vue-loader] src\\\\ResponsiveGridLayout.vue: named exports in *.vue files are ignored.\")}\n__vue_template__ = require(\"!!vue-html-loader!./../node_modules/vue-loader/lib/selector.js?type=template&index=0!./ResponsiveGridLayout.vue\")\nmodule.exports = __vue_script__ || {}\nif (module.exports.__esModule) module.exports = module.exports.default\nif (__vue_template__) {\n(typeof module.exports === \"function\" ? (module.exports.options || (module.exports.options = {})) : module.exports).template = __vue_template__\n}\nif (module.hot) {(function () { module.hot.accept()\n var hotAPI = require(\"vue-hot-reload-api\")\n hotAPI.install(require(\"vue\"), false)\n if (!hotAPI.compatible) return\n var id = \"./ResponsiveGridLayout.vue\"\n if (!module.hot.data) {\n hotAPI.createRecord(id, module.exports)\n } else {\n hotAPI.update(id, module.exports, __vue_template__)\n }\n})()}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/ResponsiveGridLayout.vue\n ** module id = 67\n ** module chunks = 0\n **/","// style-loader: Adds some css to the DOM by adding a \\r\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader?sourceMap!./~/vue-loader/lib/style-rewriter.js!./~/vue-loader/lib/selector.js?type=style&index=0!./src/ResponsiveGridLayout.vue\n ** module id = 69\n ** module chunks = 0\n **/","\r\n\r\n\n\n\n/** WEBPACK FOOTER **\n ** ResponsiveGridLayout.vue?75ac06a0\n **/","// @flow\r\n\r\nimport {cloneLayout, compact, correctBounds} from './utils';\r\n\r\nimport type {Layout} from './utils';\r\nexport type ResponsiveLayout = {lg?: Layout, md?: Layout, sm?: Layout, xs?: Layout, xxs?: Layout};\r\ntype Breakpoint = string;\r\ntype Breakpoints = {lg?: number, md?: number, sm?: number, xs?: number, xxs?: number};\r\n\r\n/**\r\n * Given a width, find the highest breakpoint that matches is valid for it (width > breakpoint).\r\n *\r\n * @param {Object} breakpoints Breakpoints object (e.g. {lg: 1200, md: 960, ...})\r\n * @param {Number} width Screen width.\r\n * @return {String} Highest breakpoint that is less than width.\r\n */\r\nexport function getBreakpointFromWidth(breakpoints: Breakpoints, width: number): Breakpoint {\r\n const sorted = sortBreakpoints(breakpoints);\r\n let matching = sorted[0];\r\n for (let i = 1, len = sorted.length; i < len; i++) {\r\n const breakpointName = sorted[i];\r\n if (width > breakpoints[breakpointName]) matching = breakpointName;\r\n }\r\n return matching;\r\n}\r\n\r\n\r\n/**\r\n * Given a breakpoint, get the # of cols set for it.\r\n * @param {String} breakpoint Breakpoint name.\r\n * @param {Object} cols Map of breakpoints to cols.\r\n * @return {Number} Number of cols.\r\n */\r\nexport function getColsFromBreakpoint(breakpoint: Breakpoint, cols: Breakpoints): number {\r\n if (!cols[breakpoint]) {\r\n throw new Error(\"ResponsiveGridLayout: `cols` entry for breakpoint \" + breakpoint + \" is missing!\");\r\n }\r\n return cols[breakpoint];\r\n}\r\n\r\n/**\r\n * Given existing layouts and a new breakpoint, find or generate a new layout.\r\n *\r\n * This finds the layout above the new one and generates from it, if it exists.\r\n *\r\n * @param {Object} layouts Existing layouts.\r\n * @param {Array} breakpoints All breakpoints.\r\n * @param {String} breakpoint New breakpoint.\r\n * @param {String} breakpoint Last breakpoint (for fallback).\r\n * @param {Number} cols Column count at new breakpoint.\r\n * @param {Boolean} verticalCompact Whether or not to compact the layout\r\n * vertically.\r\n * @return {Array} New layout.\r\n */\r\nexport function findOrGenerateResponsiveLayout(layouts: ResponsiveLayout, breakpoints: Breakpoints,\r\n breakpoint: Breakpoint, lastBreakpoint: Breakpoint,\r\n cols: number, verticalCompact: boolean): Layout {\r\n // If it already exists, just return it.\r\n if (layouts[breakpoint]) return cloneLayout(layouts[breakpoint]);\r\n // Find or generate the next layout\r\n let layout = layouts[lastBreakpoint];\r\n const breakpointsSorted = sortBreakpoints(breakpoints);\r\n const breakpointsAbove = breakpointsSorted.slice(breakpointsSorted.indexOf(breakpoint));\r\n for (let i = 0, len = breakpointsAbove.length; i < len; i++) {\r\n const b = breakpointsAbove[i];\r\n if (layouts[b]) {\r\n layout = layouts[b];\r\n break;\r\n }\r\n }\r\n layout = cloneLayout(layout || []); // clone layout so we don't modify existing items\r\n return compact(correctBounds(layout, {cols: cols}), verticalCompact);\r\n}\r\n\r\nexport function generateResponsiveLayout(layout: Layout, breakpoints: Breakpoints,\r\n breakpoint: Breakpoint, lastBreakpoint: Breakpoint,\r\n cols: number, verticalCompact: boolean): Layout {\r\n // If it already exists, just return it.\r\n /*if (layouts[breakpoint]) return cloneLayout(layouts[breakpoint]);\r\n // Find or generate the next layout\r\n let layout = layouts[lastBreakpoint];*/\r\n /*const breakpointsSorted = sortBreakpoints(breakpoints);\r\n const breakpointsAbove = breakpointsSorted.slice(breakpointsSorted.indexOf(breakpoint));\r\n for (let i = 0, len = breakpointsAbove.length; i < len; i++) {\r\n const b = breakpointsAbove[i];\r\n if (layouts[b]) {\r\n layout = layouts[b];\r\n break;\r\n }\r\n }*/\r\n layout = cloneLayout(layout || []); // clone layout so we don't modify existing items\r\n return compact(correctBounds(layout, {cols: cols}), verticalCompact);\r\n}\r\n\r\n/**\r\n * Given breakpoints, return an array of breakpoints sorted by width. This is usually\r\n * e.g. ['xxs', 'xs', 'sm', ...]\r\n *\r\n * @param {Object} breakpoints Key/value pair of breakpoint names to widths.\r\n * @return {Array} Sorted breakpoints.\r\n */\r\nexport function sortBreakpoints(breakpoints: Breakpoints): Array {\r\n const keys: Array = Object.keys(breakpoints);\r\n return keys.sort(function(a, b) {\r\n return breakpoints[a] - breakpoints[b];\r\n });\r\n}\r\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/responsiveUtils.js\n **/","module.exports = \"\\n\\n\\n\\n\\n
\\n \\n
\\n\";\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/vue-html-loader!./~/vue-loader/lib/selector.js?type=template&index=0!./src/ResponsiveGridLayout.vue\n ** module id = 72\n ** module chunks = 0\n **/"],"sourceRoot":""} \ No newline at end of file diff --git a/dist/vue-grid-layout.min.js b/dist/vue-grid-layout.min.js deleted file mode 100644 index 6ec82205..00000000 --- a/dist/vue-grid-layout.min.js +++ /dev/null @@ -1,7 +0,0 @@ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.VueGridLayout=e():t.VueGridLayout=e()}(this,function(){return function(t){function e(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,e),i.l=!0,i.exports}var n={};return e.m=t,e.c=n,e.i=function(t){return t},e.d=function(t,n,r){e.o(t,n)||Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:r})},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=37)}([function(t,e,n){"use strict";function r(t){for(var e=0,n=void 0,r=0,i=t.length;re&&(e=n);return e}function i(t){for(var e=Array(t.length),n=0,r=t.length;n=e.x+e.w)&&(!(t.y+t.h<=e.y)&&!(t.y>=e.y+e.h))))}function a(t,e){for(var n=p(t),r=w(t),i=Array(t.length),o=0,s=r.length;o0&&!d(t,e);)e.y--;for(var r=void 0;r=d(t,e);)e.y=r.y+r.h;return e}function c(t,e){for(var n=p(t),r=0,i=t.length;re.cols&&(o.x=e.cols-o.w),o.x<0&&(o.x=0,o.w=e.cols),o.static)for(;d(n,o);)o.y++;else n.push(o)}return t}function u(t,e){for(var n=0,r=t.length;nr;"number"==typeof n&&(e.x=n),"number"==typeof r&&(e.y=r),e.moved=!0;var s=w(t);o&&(s=s.reverse());for(var a=h(s,e),l=0,c=a.length;lu.y&&e.y-u.y>u.h/4||(t=u.static?v(t,u,e,i):v(t,e,u,i))}return t}function v(t,e,n,r){if(r){var i={x:n.x,y:n.y,w:n.w,h:n.h,i:"-1"};if(i.y=Math.max(e.y-n.h,0),!d(t,i))return f(t,n,void 0,i.y)}return f(t,n,void 0,n.y+1)}function g(t){return 100*t+"%"}function m(t,e,n,r){var i="translate("+e+"px,"+t+"px)";return{transform:i,WebkitTransform:i,MozTransform:i,msTransform:i,OTransform:i,width:n+"px",height:r+"px",position:"absolute"}}function y(t,e,n,r){var i="translate("+e*-1+"px,"+t+"px)";return{transform:i,WebkitTransform:i,MozTransform:i,msTransform:i,OTransform:i,width:n+"px",height:r+"px",position:"absolute"}}function b(t,e,n,r){return{top:t+"px",left:e+"px",width:n+"px",height:r+"px",position:"absolute"}}function x(t,e,n,r){return{top:t+"px",right:e+"px",width:n+"px",height:r+"px",position:"absolute"}}function w(t){return[].concat(t).sort(function(t,e){return t.y>e.y||t.y===e.y&&t.x>e.x?1:-1})}function _(t,e){e=e||"Layout";var n=["x","y","w","h"];if(!Array.isArray(t))throw new Error(e+" must be an array!");for(var r=0,i=t.length;r=0&&g.splice(e,1)}function s(t){var e=document.createElement("style");return e.type="text/css",i(t,e),e}function a(t,e){var n,r,i;if(e.singleton){var a=v++;n=f||(f=s(e)),r=l.bind(null,n,a,!1),i=l.bind(null,n,a,!0)}else n=s(e),r=c.bind(null,n),i=function(){o(n)};return r(t),function(e){if(e){if(e.css===t.css&&e.media===t.media&&e.sourceMap===t.sourceMap)return;r(t=e)}else i()}}function l(t,e,n,r){var i=n?"":r.css;if(t.styleSheet)t.styleSheet.cssText=m(e,i);else{var o=document.createTextNode(i),s=t.childNodes;s[e]&&t.removeChild(s[e]),s.length?t.insertBefore(o,s[e]):t.appendChild(o)}}function c(t,e){var n=e.css,r=e.media,i=e.sourceMap;if(r&&t.setAttribute("media",r),i&&(n+="\n/*# sourceURL="+i.sources[0]+" */",n+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(i))))+" */"),t.styleSheet)t.styleSheet.cssText=n;else{for(;t.firstChild;)t.removeChild(t.firstChild);t.appendChild(document.createTextNode(n))}}var u={},d=function(t){var e;return function(){return"undefined"==typeof e&&(e=t.apply(this,arguments)),e}},h=d(function(){return/msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase())}),p=d(function(){return document.head||document.getElementsByTagName("head")[0]}),f=null,v=0,g=[];t.exports=function(t,e){if("undefined"!=typeof DEBUG&&DEBUG&&"object"!=typeof document)throw new Error("The style-loader cannot be used in a non-browser environment");e=e||{},"undefined"==typeof e.singleton&&(e.singleton=h()),"undefined"==typeof e.insertAt&&(e.insertAt="bottom");var i=r(t);return n(i,e),function(t){for(var o=[],s=0;s";while(r[0]);return e>4?e:t}();return t===n},n.isLegacyOpera=function(){return!!window.opera}},function(t,e){"use strict";var n=t.exports={};n.forEach=function(t,e){for(var n=0;nthis.cols&&(this.x=0,this.w=this.cols);var t=this.calcPosition(this.x,this.y,this.w,this.h);this.isDragging&&(t.top=this.dragging.top,this.rtl?t.right=this.dragging.left:t.left=this.dragging.left),this.isResizing&&(t.width=this.resizing.width,t.height=this.resizing.height);var e=void 0;e=this.useCssTransforms?this.rtl?(0,r.setTransformRtl)(t.top,t.right,t.width,t.height):(0,r.setTransform)(t.top,t.left,t.width,t.height):this.rtl?(0,r.setTopRight)(t.top,t.right,t.width,t.height):(0,r.setTopLeft)(t.top,t.left,t.width,t.height),this.style=e},handleResize:function(t){var e=(0,i.getControlPosition)(t);if(null!=e){var n=e.x,r=e.y,s={width:0,height:0};switch(t.type){case"resizestart":this.previousW=this.w,this.previousH=this.h;var a=this.calcPosition(this.x,this.y,this.w,this.h);s.width=a.width,s.height=a.height,this.resizing=s,this.isResizing=!0;break;case"resizemove":var l=(0,i.createCoreData)(this.lastW,this.lastH,n,r);this.rtl?s.width=this.resizing.width-l.deltaX:s.width=this.resizing.width+l.deltaX,s.height=this.resizing.height+l.deltaY,this.resizing=s;break;case"resizeend":var a=this.calcPosition(this.x,this.y,this.w,this.h);s.width=a.width,s.height=a.height,this.resizing=null,this.isResizing=!1}var a=this.calcWH(s.height,s.width);a.wthis.maxW&&(a.w=this.maxW),a.hthis.maxH&&(a.h=this.maxH),a.h<1&&(a.h=1),a.w<1&&(a.w=1),this.lastW=n,this.lastH=r,this.w===a.w&&this.h===a.h||this.$emit("resize",this.i,a.h,a.w),"resizeend"!==t.type||this.previousW===this.w&&this.previousH===this.h||this.$emit("resized",this.i,a.h,a.w),o.$emit("resizeEvent",t.type,this.i,this.x,this.y,a.h,a.w)}},handleDrag:function(t){if(!this.isResizing){var e=(0,i.getControlPosition)(t);if(null!=e){var n=e.x,r=e.y,s=!1,a={top:0,left:0};switch(t.type){case"dragstart":this.previousX=this.x,this.previousY=this.y;var l=t.target.offsetParent.getBoundingClientRect(),c=t.target.getBoundingClientRect();this.rtl?a.left=(c.right-l.right)*-1:a.left=c.left-l.left,a.top=c.top-l.top,this.dragging=a,this.isDragging=!0;break;case"dragend":if(!this.isDragging)return;l=t.target.offsetParent.getBoundingClientRect(),c=t.target.getBoundingClientRect(),this.rtl?a.left=(c.right-l.right)*-1:a.left=c.left-l.left,a.top=c.top-l.top,this.dragging=null,this.isDragging=!1,s=!0;break;case"dragmove":var u=(0,i.createCoreData)(this.lastX,this.lastY,n,r);this.rtl?a.left=this.dragging.left-u.deltaX:a.left=this.dragging.left+u.deltaX,a.top=this.dragging.top+u.deltaY,this.dragging=a}if(this.rtl)var d=this.calcXY(a.top,a.left);else var d=this.calcXY(a.top,a.left);this.lastX=n,this.lastY=r,this.x===d.x&&this.y===d.y||this.$emit("move",this.i,d.x,d.y),"dragend"!==t.type||this.previousX===this.x&&this.previousY===this.y||this.$emit("moved",this.i,d.x,d.y),o.$emit("dragEvent",t.type,this.i,d.x,d.y,this.h,this.w)}}},calcPosition:function(t,e,n,r){var i=this.calcColWidth();if(this.rtl)var o={right:Math.round(i*t+(t+1)*this.margin[0]),top:Math.round(this.rowHeight*e+(e+1)*this.margin[1]),width:n===1/0?n:Math.round(i*n+Math.max(0,n-1)*this.margin[0]),height:r===1/0?r:Math.round(this.rowHeight*r+Math.max(0,r-1)*this.margin[1])};else var o={left:Math.round(i*t+(t+1)*this.margin[0]),top:Math.round(this.rowHeight*e+(e+1)*this.margin[1]),width:n===1/0?n:Math.round(i*n+Math.max(0,n-1)*this.margin[0]),height:r===1/0?r:Math.round(this.rowHeight*r+Math.max(0,r-1)*this.margin[1])};return o},calcXY:function(t,e){var n=this.calcColWidth(),r=Math.round((e-this.margin[0])/(n+this.margin[0])),i=Math.round((t-this.margin[1])/(this.rowHeight+this.margin[1]));return r=Math.max(Math.min(r,this.cols-this.w),0),i=Math.max(Math.min(i,this.maxRows-this.h),0),{x:r,y:i}},calcColWidth:function(){var t=(this.containerWidth-this.margin[0]*(this.cols+1))/this.cols;return t},calcWH:function(t,e){var n=this.calcColWidth(),r=Math.round((e+this.margin[0])/(n+this.margin[0])),i=Math.round((t+this.margin[1])/(this.rowHeight+this.margin[1]));return r=Math.max(Math.min(r,this.cols-this.x),0),i=Math.max(Math.min(i,this.maxRows-this.y),0),{w:r,h:i}},updateWidth:function(t,e){this.containerWidth=t,void 0!==e&&null!==e&&(this.cols=e)},compact:function(){this.createStyle()}}}},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{default:t}}e.__esModule=!0;var i=n(0),o=n(1),s=r(o),a=n(7),l=n(4);e.default={name:"GridLayout",components:{GridItem:s.default},props:{autoSize:{type:Boolean,default:!0},colNum:{type:Number,default:12},rowHeight:{type:Number,default:150},maxRows:{type:Number,default:1/0},margin:{type:Array,default:function(){return[10,10]}},isDraggable:{type:Boolean,default:!0},isResizable:{type:Boolean,default:!0},useCssTransforms:{type:Boolean,default:!0},verticalCompact:{type:Boolean,default:!0},layout:{type:Array,required:!0}},data:function(){return{width:null,mergedStyle:{},lastLayoutLength:0,isDragging:!1,placeholder:{x:0,y:0,w:0,h:0,i:0}}},created:function(){var t=this;t.resizeEventHandler=function(e,n,r,i,o,s){t.resizeEvent(e,n,r,i,o,s)},t.dragEventHandler=function(e,n,r,i,o,s){t.dragEvent(e,n,r,i,o,s)},l.$on("resizeEvent",t.resizeEventHandler),l.$on("dragEvent",t.dragEventHandler)},beforeDestroy:function(){l.$off("resizeEvent",self.resizeEventHandler),l.$off("dragEvent",self.dragEventHandler),window.removeEventListener("resize",self.onWindowResize)},mounted:function(){this.$nextTick(function(){(0,i.validateLayout)(this.layout);var t=this;this.$nextTick(function(){null===t.width&&(t.onWindowResize(),window.addEventListener("resize",t.onWindowResize)),(0,i.compact)(t.layout,t.verticalCompact),t.updateHeight(),t.$nextTick(function(){var e=a({strategy:"scroll"});e.listenTo(t.$refs.item,function(e){t.onWindowResize()})})}),window.onload=function(){null===t.width&&(t.onWindowResize(),window.addEventListener("resize",t.onWindowResize)),(0,i.compact)(t.layout,t.verticalCompact),t.updateHeight(),t.$nextTick(function(){var e=a({strategy:"scroll"});e.listenTo(t.$refs.item,function(e){t.onWindowResize()})})}})},watch:{width:function(){this.$nextTick(function(){l.$emit("updateWidth",this.width),this.updateHeight()})},layout:function(){this.layoutUpdate()},rowHeight:function(){l.$emit("setRowHeight",this.rowHeight)},isDraggable:function(){l.$emit("setDraggable",this.isDraggable)},isResizable:function(){l.$emit("setResizable",this.isResizable)}},methods:{layoutUpdate:function(){void 0!==this.layout&&this.layout.length!==this.lastLayoutLength&&(this.lastLayoutLength=this.layout.length,(0,i.compact)(this.layout,this.verticalCompact),l.$emit("updateWidth",this.width),this.updateHeight())},updateHeight:function(){this.mergedStyle={height:this.containerHeight()}},onWindowResize:function(){null!==this.$refs&&null!==this.$refs.item&&(this.width=this.$refs.item.offsetWidth)},containerHeight:function(){if(this.autoSize)return(0,i.bottom)(this.layout)*(this.rowHeight+this.margin[1])+this.margin[1]+"px"},dragEvent:function(t,e,n,r,o,s){"dragmove"==t||"dragstart"==t?(this.isDragging=!0,this.placeholder.i=e,this.placeholder.x=n,this.placeholder.y=r,this.placeholder.w=s,this.placeholder.h=o,l.$emit("updateWidth",this.width)):this.isDragging=!1;var a=(0,i.getLayoutItem)(this.layout,e);a.x=n,a.y=r,this.layout=(0,i.moveElement)(this.layout,a,n,r,!0),(0,i.compact)(this.layout,this.verticalCompact),l.$emit("compact"),this.updateHeight()},resizeEvent:function(t,e,n,r,o,s){"resizestart"==t||"resizemove"==t?(this.isDragging=!0,this.placeholder.i=e,this.placeholder.x=n,this.placeholder.y=r,this.placeholder.w=s,this.placeholder.h=o,l.$emit("updateWidth",this.width)):this.isDragging=!1;var a=(0,i.getLayoutItem)(this.layout,e);a.h=o,a.w=s,(0,i.compact)(this.layout,this.verticalCompact),l.$emit("compact"),this.updateHeight()}}}},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{default:t}}e.__esModule=!0;var i=n(0),o=(n(14),n(1)),s=r(o),a=n(7);e.default={name:"ResponsiveGridLayout",components:{GridItem:s.default},props:{autoSize:{type:Boolean,default:!0},colNum:{type:Number,required:!1,default:0},rowHeight:{type:Number,default:150},maxRows:{type:Number,default:1/0},margin:{type:Array,default:function(){return[10,10]}},isDraggable:{type:Boolean,default:!0},isResizable:{type:Boolean,default:!0},useCssTransforms:{type:Boolean,default:!0},verticalCompact:{type:Boolean,default:!0},layout:[]},data:function(){return{originalCols:null,width:null,mergedStyle:{},lastLayoutLength:0}},beforeDestroy:function(){window.removeEventListener("resize",self.onWindowResize)},mounted:function(){this.$nextTick(function(){(0,i.validateLayout)(this.layout),this.originalCols=this.colNum;var t=this;window.onload=function(){t.onWindowResize(),window.addEventListener("resize",t.onWindowResize),(0,i.compact)(t.layout,t.verticalCompact),t.updateHeight(),t.$nextTick(function(){var e=a({strategy:"scroll"});e.listenTo(t.$refs.item,function(e){t.onWindowResize()})})}})},watch:{width:function(){this.width>768?this.colNum=this.originalCols:this.colNum=2,this.$nextTick(function(){var t=this;this.$children.forEach(function(e){e.updateWidth(t.width)}),this.updateHeight(),(0,i.compact)(this.layout,this.verticalCompact)})},layout:function(){if(void 0!==this.layout&&this.layout.length!==this.lastLayoutLength){this.lastLayoutLength=this.layout.length,(0,i.compact)(this.layout,this.verticalCompact);var t=this;this.$children.forEach(function(e){e.updateWidth(t.width)}),this.updateHeight()}}},methods:{onWindowResize:function(){null!==this.$refs&&null!==this.$refs.item&&(this.width=this.$refs.item.offsetWidth)},updateHeight:function(){this.mergedStyle={height:this.containerHeight()}},containerHeight:function(){if(this.autoSize)return(0,i.bottom)(this.layout)*(this.rowHeight+this.margin[1])+this.margin[1]+"px"},dragEvent:function(t,e,n,r){var o=this,s=(0,i.getLayoutItem)(this.layout,e);this.layout=(0,i.moveElement)(this.layout,s,n,r,!0),(0,i.compact)(this.layout,this.verticalCompact),this.$children.forEach(function(t){t.compact(o.layout)}),this.updateHeight()},resizeEvent:function(t,e,n,r){var o=this;(0,i.compact)(this.layout,this.verticalCompact),this.$children.forEach(function(t){t.compact(o.layout)}),this.updateHeight()}}}},function(t,e){"use strict";function n(t){return r(t)}function r(t){var e=t.target.offsetParent||document.body,n=t.offsetParent===document.body?{left:0,top:0}:e.getBoundingClientRect(),r=t.clientX+e.scrollLeft-n.left,i=t.clientY+e.scrollTop-n.top;return{x:r,y:i}}function i(t,e,n,r){var i=!o(t);return i?{deltaX:0,deltaY:0,lastX:n,lastY:r,x:n,y:r}:{deltaX:n-t,deltaY:r-e,lastX:t,lastY:e,x:n,y:r}}function o(t){return"number"==typeof t&&!isNaN(t)}Object.defineProperty(e,"__esModule",{value:!0}),e.getControlPosition=n,e.offsetXYFromParentOf=r,e.createCoreData=i},function(t,e,n){"use strict";function r(t,e){for(var n=a(t),r=n[0],i=1,o=n.length;it[s]&&(r=s)}return r}function i(t,e){if(!e[t])throw new Error("ResponsiveGridLayout: `cols` entry for breakpoint "+t+" is missing!");return e[t]}function o(t,e,n,r,i,o){if(t[n])return(0,l.cloneLayout)(t[n]);for(var s=t[r],c=a(e),u=c.slice(c.indexOf(n)),d=0,h=u.length;do?o=t:t.vue-resizable-handle{position:absolute;width:20px;height:20px;bottom:0;right:0;background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pg08IS0tIEdlbmVyYXRvcjogQWRvYmUgRmlyZXdvcmtzIENTNiwgRXhwb3J0IFNWRyBFeHRlbnNpb24gYnkgQWFyb24gQmVhbGwgKGh0dHA6Ly9maXJld29ya3MuYWJlYWxsLmNvbSkgLiBWZXJzaW9uOiAwLjYuMSAgLS0+DTwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DTxzdmcgaWQ9IlVudGl0bGVkLVBhZ2UlMjAxIiB2aWV3Qm94PSIwIDAgNiA2IiBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjojZmZmZmZmMDAiIHZlcnNpb249IjEuMSINCXhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbDpzcGFjZT0icHJlc2VydmUiDQl4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjZweCIgaGVpZ2h0PSI2cHgiDT4NCTxnIG9wYWNpdHk9IjAuMzAyIj4NCQk8cGF0aCBkPSJNIDYgNiBMIDAgNiBMIDAgNC4yIEwgNCA0LjIgTCA0LjIgNC4yIEwgNC4yIDAgTCA2IDAgTCA2IDYgTCA2IDYgWiIgZmlsbD0iIzAwMDAwMCIvPg0JPC9nPg08L3N2Zz4=");background-position:100% 100%;padding:0 3px 3px 0;background-repeat:no-repeat;background-origin:content-box;box-sizing:border-box;cursor:se-resize}.vue-grid-item>.vue-rtl-resizable-handle{bottom:0;left:0;background:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAuMDAwMDAwMDAwMDAwMDAyIiBoZWlnaHQ9IjEwLjAwMDAwMDAwMDAwMDAwMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KIDwhLS0gQ3JlYXRlZCB3aXRoIE1ldGhvZCBEcmF3IC0gaHR0cDovL2dpdGh1Yi5jb20vZHVvcGl4ZWwvTWV0aG9kLURyYXcvIC0tPgogPGc+CiAgPHRpdGxlPmJhY2tncm91bmQ8L3RpdGxlPgogIDxyZWN0IGZpbGw9Im5vbmUiIGlkPSJjYW52YXNfYmFja2dyb3VuZCIgaGVpZ2h0PSIxMiIgd2lkdGg9IjEyIiB5PSItMSIgeD0iLTEiLz4KICA8ZyBkaXNwbGF5PSJub25lIiBvdmVyZmxvdz0idmlzaWJsZSIgeT0iMCIgeD0iMCIgaGVpZ2h0PSIxMDAlIiB3aWR0aD0iMTAwJSIgaWQ9ImNhbnZhc0dyaWQiPgogICA8cmVjdCBmaWxsPSJ1cmwoI2dyaWRwYXR0ZXJuKSIgc3Ryb2tlLXdpZHRoPSIwIiB5PSIwIiB4PSIwIiBoZWlnaHQ9IjEwMCUiIHdpZHRoPSIxMDAlIi8+CiAgPC9nPgogPC9nPgogPGc+CiAgPHRpdGxlPkxheWVyIDE8L3RpdGxlPgogIDxsaW5lIGNhbnZhcz0iI2ZmZmZmZiIgY2FudmFzLW9wYWNpdHk9IjEiIHN0cm9rZS1saW5lY2FwPSJ1bmRlZmluZWQiIHN0cm9rZS1saW5lam9pbj0idW5kZWZpbmVkIiBpZD0ic3ZnXzEiIHkyPSItNzAuMTc4NDA3IiB4Mj0iMTI0LjQ2NDE3NSIgeTE9Ii0zOC4zOTI3MzciIHgxPSIxNDQuODIxMjg5IiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlPSIjMDAwIiBmaWxsPSJub25lIi8+CiAgPGxpbmUgc3Ryb2tlPSIjNjY2NjY2IiBzdHJva2UtbGluZWNhcD0idW5kZWZpbmVkIiBzdHJva2UtbGluZWpvaW49InVuZGVmaW5lZCIgaWQ9InN2Z181IiB5Mj0iOS4xMDY5NTciIHgyPSIwLjk0NzI0NyIgeTE9Ii0wLjAxODEyOCIgeDE9IjAuOTQ3MjQ3IiBzdHJva2Utd2lkdGg9IjIiIGZpbGw9Im5vbmUiLz4KICA8bGluZSBzdHJva2UtbGluZWNhcD0idW5kZWZpbmVkIiBzdHJva2UtbGluZWpvaW49InVuZGVmaW5lZCIgaWQ9InN2Z183IiB5Mj0iOSIgeDI9IjEwLjA3MzUyOSIgeTE9IjkiIHgxPSItMC42NTU2NCIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2U9IiM2NjY2NjYiIGZpbGw9Im5vbmUiLz4KIDwvZz4KPC9zdmc+);background-position:0 100%;padding-left:3px;background-repeat:no-repeat;background-origin:content-box;cursor:sw-resize;right:auto}',""]); -},function(t,e,n){"use strict";var r=n(5);t.exports=function(t){function e(t,e){function n(){e(t)}if(!i(t))throw new Error("Element is not detectable by this strategy.");if(r.isIE(8))l(t).object={proxy:n},t.attachEvent("onresize",n);else{var o=i(t);o.contentDocument.defaultView.addEventListener("resize",n)}}function n(t,e,n){function i(t,e){function n(){function n(){if("static"===c.position){t.style.position="relative";var e=function(t,e,n,r){function i(t){return t.replace(/[^-\d\.]/g,"")}var o=n[r];"auto"!==o&&"0"!==i(o)&&(t.warn("An element that is positioned static has style."+r+"="+o+" which is ignored due to the static positioning. The element will need to be positioned relative, so the style."+r+" will be set to 0. Element: ",e),e.style[r]=0)};e(s,t,c,"top"),e(s,t,c,"right"),e(s,t,c,"bottom"),e(s,t,c,"left")}}function a(){function r(t,e){return t.contentDocument?void e(t.contentDocument):void setTimeout(function(){r(t,e)},100)}o||n();var i=this;r(i,function(n){e(t)})}""!==c.position&&(n(c),o=!0);var u=document.createElement("object");u.style.cssText=i,u.tabIndex=-1,u.type="text/html",u.onload=a,r.isIE()||(u.data="about:blank"),t.appendChild(u),l(t).object=u,r.isIE()&&(u.data="about:blank")}var i="display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none; padding: 0; margin: 0; opacity: 0; z-index: -1000; pointer-events: none;",o=!1,c=window.getComputedStyle(t),u=t.offsetWidth,d=t.offsetHeight;l(t).startSize={width:u,height:d},a?a.add(n):n()}n||(n=e,e=t,t=null),t=t||{};t.debug;r.isIE(8)?n(e):i(e,n)}function i(t){return l(t).object}function o(t){r.isIE(8)?t.detachEvent("onresize",l(t).object.proxy):t.removeChild(i(t)),delete l(t).object}t=t||{};var s=t.reporter,a=t.batchProcessor,l=t.stateHandler.getState;if(!s)throw new Error("Missing required dependency: reporter.");return{makeDetectable:n,addListener:e,uninstall:o}}},function(t,e,n){"use strict";var r=n(6).forEach;t.exports=function(t){function e(){var t=500,e=500,n=document.createElement("div");n.style.cssText="position: absolute; width: "+2*t+"px; height: "+2*e+"px; visibility: hidden; margin: 0; padding: 0;";var r=document.createElement("div");r.style.cssText="position: absolute; width: "+t+"px; height: "+e+"px; overflow: scroll; visibility: none; top: "+3*-t+"px; left: "+3*-e+"px; visibility: hidden; margin: 0; padding: 0;",r.appendChild(n),document.body.insertBefore(r,document.body.firstChild);var i=t-r.clientWidth,o=e-r.clientHeight;return document.body.removeChild(r),{width:i,height:o}}function n(t,e){function n(e,n){n=n||function(t){document.head.appendChild(t)};var r=document.createElement("style");return r.innerHTML=e,r.id=t,n(r),r}if(!document.getElementById(t)){var r=e+"_animation",i=e+"_animation_active",o="/* Created by the element-resize-detector library. */\n";o+="."+e+" > div::-webkit-scrollbar { display: none; }\n\n",o+="."+i+" { -webkit-animation-duration: 0.1s; animation-duration: 0.1s; -webkit-animation-name: "+r+"; animation-name: "+r+"; }\n",o+="@-webkit-keyframes "+r+" { 0% { opacity: 1; } 50% { opacity: 0; } 100% { opacity: 1; } }\n",o+="@keyframes "+r+" { 0% { opacity: 1; } 50% { opacity: 0; } 100% { opacity: 1; } }",n(o)}}function i(t){t.className+=" "+y+"_animation_active"}function o(t,e,n){if(t.addEventListener)t.addEventListener(e,n);else{if(!t.attachEvent)return h.error("[scroll] Don't know how to add event listeners.");t.attachEvent("on"+e,n)}}function s(t,e,n){if(t.removeEventListener)t.removeEventListener(e,n);else{if(!t.detachEvent)return h.error("[scroll] Don't know how to remove event listeners.");t.detachEvent("on"+e,n)}}function a(t){return f(t).container.childNodes[0].childNodes[0].childNodes[0]}function l(t){return f(t).container.childNodes[0].childNodes[0].childNodes[1]}function c(t,e){var n=f(t).listeners;if(!n.push)throw new Error("Cannot add listener to an element that is not detectable.");f(t).listeners.push(e)}function u(t,e,n){function s(){if(t.debug){var n=Array.prototype.slice.call(arguments);if(n.unshift(v.get(e),"Scroll: "),h.log.apply)h.log.apply(null,n);else for(var r=0;r1?A(e):e[0];w(r,Tt,n),t.page.x=Tt.x,t.page.y=Tt.y,_(r,Tt,n),t.client.x=Tt.x,t.client.y=Tt.y,t.timeStamp=(new Date).getTime()}function y(t,e,n){t.page.x=n.page.x-e.page.x,t.page.y=n.page.y-e.page.y,t.client.x=n.client.x-e.client.x,t.client.y=n.client.y-e.client.y,t.timeStamp=(new Date).getTime()-e.timeStamp;var r=Math.max(t.timeStamp/1e3,.001);t.page.speed=zt(t.page.x,t.page.y)/r,t.page.vx=t.page.x/r,t.page.vy=t.page.y/r,t.client.speed=zt(t.client.x,t.page.y)/r,t.client.vx=t.client.x/r,t.client.vy=t.client.y/r}function b(t){return t instanceof yt.Event||Rt&&yt.Touch&&t instanceof yt.Touch}function x(t,e,n){return n=n||{},t=t||"page",n.x=e[t+"X"],n.y=e[t+"Y"],n}function w(t,e){return e=e||{},Gt&&b(t)?(x("screen",t,e),e.x+=yt.scrollX,e.y+=yt.scrollY):x("page",t,e),e}function _(t,e){return e=e||{},Gt&&b(t)?x("screen",t,e):x("client",t,e),e}function S(t){return t=t||yt,{x:t.scrollX||t.document.documentElement.scrollLeft,y:t.scrollY||t.document.documentElement.scrollTop}}function E(t){return u(t.pointerId)?t.pointerId:t.identifier}function C(t){return t instanceof St?t.correspondingUseElement:t}function z(t){if(o(t))return t;var e=t.ownerDocument||t;return e.defaultView||e.parentWindow||yt}function T(t){var e=t instanceof wt?t.getBoundingClientRect():t.getClientRects()[0];return e&&{left:e.left,right:e.right,top:e.top,bottom:e.bottom,width:e.width||e.right-e.left,height:e.height||e.bottom-e.top}}function D(t){var e=T(t);if(!Zt&&e){var n=S(z(t));e.left+=n.x,e.right+=n.x,e.top+=n.y,e.bottom+=n.y}return e}function k(t){var e=[];return a(t)?(e[0]=t[0],e[1]=t[1]):"touchend"===t.type?1===t.touches.length?(e[0]=t.touches[0],e[1]=t.changedTouches[0]):0===t.touches.length&&(e[0]=t.changedTouches[0],e[1]=t.changedTouches[1]):(e[0]=t.touches[0],e[1]=t.touches[1]),e}function A(t){for(var e,n={pageX:0,pageY:0,clientX:0,clientY:0,screenX:0,screenY:0},r=0;r1){var e=k(t),n=Math.min(e[0].pageX,e[1].pageX),r=Math.min(e[0].pageY,e[1].pageY),i=Math.max(e[0].pageX,e[1].pageX),o=Math.max(e[0].pageY,e[1].pageY);return{x:n,y:r,left:n,top:r,width:i-n,height:o-r}}}function $(t,e){e=e||Mt.deltaSource;var n=e+"X",r=e+"Y",i=k(t),o=i[0][n]-i[1][n],s=i[0][r]-i[1][r];return zt(o,s)}function M(t,e,n){n=n||Mt.deltaSource;var r=n+"X",i=n+"Y",o=k(t),s=o[0][r]-o[1][r],a=o[0][i]-o[1][i],l=180*Math.atan(a/s)/Math.PI;if(u(e)){var c=l-e,d=c%360;d>315?l-=360+l/360|0:d>135?l-=180+l/360|0:d<-315?l+=360+l/360|0:d<-135&&(l+=180+l/360|0)}return l}function O(t,e){var n=t?t.options.origin:Mt.origin;return"parent"===n?n=j(e):"self"===n?n=t.getRect(e):p(n)&&(n=L(e,n)||{x:0,y:0}),c(n)&&(n=n(t&&e)),i(n)&&(n=D(n)),n.x="x"in n?n.x:n.left,n.y="y"in n?n.y:n.top,n}function R(t,e,n,r){var i=1-t;return i*i*e+2*i*t*n+t*t*r}function P(t,e,n,r,i,o,s){return{x:R(s,t,n,i),y:R(s,e,r,o)}}function N(t,e,n,r){return t/=r,-n*t*(t-2)+e}function H(t,e){for(;e;){if(e===t)return!0;e=e.parentNode}return!1}function L(t,e){for(var n=j(t);i(n);){if(ft(n,e))return n;n=j(n)}return null}function j(t){var e=t.parentNode;if(s(e)){for(;(e=e.host)&&s(e););return e}return e}function W(t,e){return t._context===e.ownerDocument||H(t._context,e)}function Y(t,e,n){var r=t.options.ignoreFrom;return!(!r||!i(n))&&(h(r)?vt(n,r,e):!!i(r)&&H(r,n))}function B(t,e,n){var r=t.options.allowFrom;return!r||!!i(n)&&(h(r)?vt(n,r,e):!!i(r)&&H(r,n))}function X(t,e){if(!e)return!1;var n=e.options.drag.axis;return"xy"===t||"xy"===n||n===t}function F(t,e){var n=t.options;return/^resize/.test(e)&&(e="resize"),n[e].snap&&n[e].snap.enabled}function G(t,e){var n=t.options;return/^resize/.test(e)&&(e="resize"),n[e].restrict&&n[e].restrict.enabled}function Z(t,e){var n=t.options;return/^resize/.test(e)&&(e="resize"),n[e].autoScroll&&n[e].autoScroll.enabled}function U(t,e,n){for(var r=t.options,i=r[n.name].max,o=r[n.name].maxPerElement,s=0,a=0,l=0,c=0,u=At.length;c=jt)return!1;if(d.target===t){if(a+=h===n.name|0,a>=i)return!1;if(d.element===e&&(l++,h!==n.name||l>=o))return!1}}}return jt>0}function V(t){var e,n,r,i,o,s=t[0],a=s?0:-1,l=[],c=[];for(i=1;i600&&this.timeStamp-t.prevEvent.timeStamp<150){var z=180*Math.atan2(t.prevEvent.velocityY,t.prevEvent.velocityX)/Math.PI,T=22.5;z<0&&(z+=360);var D=135-T<=z&&z<225+T,k=225-T<=z&&z<315+T,A=!D&&(315-T<=z||z<45+T),R=!k&&45-T<=z&&z<135+T;this.swipe={up:k,down:R,left:D,right:A,angle:z,speed:t.prevEvent.speed,velocity:{x:t.prevEvent.velocityX,y:t.prevEvent.velocityY}}}}function tt(){this.originalEvent.preventDefault()}function et(t){var e="";if("drag"===t.name&&(e=Wt.drag),"resize"===t.name)if(t.axis)e=Wt[t.name+t.axis];else if(t.edges){for(var n="resize",r=["top","bottom","left","right"],i=0;i<4;i++)t.edges[r[i]]&&(n+=r[i]);e=Wt[n]}return e}function nt(t,e,n,r,o,s,a){if(!e)return!1;if(e===!0){var l=u(s.width)?s.width:s.right-s.left,c=u(s.height)?s.height:s.bottom-s.top;if(l<0&&("left"===t?t="right":"right"===t&&(t="left")),c<0&&("top"===t?t="bottom":"bottom"===t&&(t="top")),"left"===t)return n.x<(l>=0?s.left:s.right)+a;if("top"===t)return n.y<(c>=0?s.top:s.bottom)+a;if("right"===t)return n.x>(l>=0?s.right:s.left)-a;if("bottom"===t)return n.y>(c>=0?s.bottom:s.top)-a}return!!i(r)&&(i(e)?e===r:vt(r,e,o))}function rt(t,e,n){var r,i=this.getRect(n),o=!1,s=null,a=null,c=f({},e.curCoords.page),u=this.options;if(!i)return null;if(Yt.resize&&u.resize.enabled){var d=u.resize;if(r={left:!1,right:!1,top:!1,bottom:!1},l(d.edges)){for(var h in r)r[h]=nt(h,d.edges[h],c,e._eventTarget,n,i,d.margin||Nt);r.left=r.left&&!r.right,r.top=r.top&&!r.bottom,o=r.left||r.right||r.top||r.bottom}else{var p="y"!==u.resize.axis&&c.x>i.right-Nt,v="x"!==u.resize.axis&&c.y>i.bottom-Nt;o=p||v,a=(p?"x":"")+(v?"y":"")}}return s=o?"resize":Yt.drag&&u.drag.enabled?"drag":null,Yt.gesture&&e.pointerIds.length>=2&&!e.dragging&&!e.resizing&&(s="gesture"),s?{name:s,axis:a,edges:r}:null}function it(t,e){if(!l(t))return null;var n=t.name,r=e.options;return("resize"===n&&r.resize.enabled||"drag"===n&&r.drag.enabled||"gesture"===n&&r.gesture.enabled)&&Yt[n]?("resize"!==n&&"resizeyx"!==n||(n="resizexy"),t):null}function ot(t,e){var n={},r=$t[t.type],o=C(t.path?t.path[0]:t.target),s=o;e=!!e;for(var a in t)n[a]=t[a];for(n.originalEvent=t,n.preventDefault=tt;i(s);){for(var l=0;l=1||r>=1)&&(o(s)?s.scrollBy(Ot.x*n,Ot.y*r):s&&(s.scrollLeft+=Ot.x*n,s.scrollTop+=Ot.y*r),n>=1&&(Ot.prevTimeX=a),r>=1&&(Ot.prevTimeY=a)),Ot.isScrolling&&(qt(Ot.i),Ot.i=Vt(Ot.scroll))},isScrolling:!1,prevTimeX:0,prevTimeY:0,start:function(t){Ot.isScrolling=!0,qt(Ot.i),Ot.interaction=t,Ot.prevTimeX=(new Date).getTime(),Ot.prevTimeY=(new Date).getTime(),Ot.i=Vt(Ot.scroll)},stop:function(){Ot.isScrolling=!1,qt(Ot.i)}},Rt="ontouchstart"in yt||yt.DocumentTouch&&bt instanceof yt.DocumentTouch,Pt=Ct&&!/Chrome/.test(navigator.userAgent),Nt=Rt||Pt?20:10,Ht=1,Lt=0,jt=1/0,Wt=bt.all&&!yt.atob?{drag:"move",resizex:"e-resize",resizey:"s-resize",resizexy:"se-resize",resizetop:"n-resize",resizeleft:"w-resize",resizebottom:"s-resize", -resizeright:"e-resize",resizetopleft:"se-resize",resizebottomright:"se-resize",resizetopright:"ne-resize",resizebottomleft:"ne-resize",gesture:""}:{drag:"move",resizex:"ew-resize",resizey:"ns-resize",resizexy:"nwse-resize",resizetop:"ns-resize",resizeleft:"ew-resize",resizebottom:"ns-resize",resizeright:"ew-resize",resizetopleft:"nwse-resize",resizebottomright:"nwse-resize",resizetopright:"nesw-resize",resizebottomleft:"nesw-resize",gesture:""},Yt={drag:!0,resize:!0,gesture:!0},Bt="onmousewheel"in bt?"mousewheel":"wheel",Xt=["dragstart","dragmove","draginertiastart","dragend","dragenter","dragleave","dropactivate","dropdeactivate","dropmove","drop","resizestart","resizemove","resizeinertiastart","resizeend","gesturestart","gesturemove","gestureinertiastart","gestureend","down","move","up","cancel","tap","doubletap","hold"],Ft={},Gt="Opera"==navigator.appName&&Rt&&navigator.userAgent.match("Presto"),Zt=/iP(hone|od|ad)/.test(navigator.platform)&&/OS 7[^\d]/.test(navigator.appVersion),Ut="matches"in Element.prototype?"matches":"webkitMatchesSelector"in Element.prototype?"webkitMatchesSelector":"mozMatchesSelector"in Element.prototype?"mozMatchesSelector":"oMatchesSelector"in Element.prototype?"oMatchesSelector":"msMatchesSelector",Vt=n.requestAnimationFrame,qt=n.cancelAnimationFrame,Jt=function(){function t(t,e,a,h){var p=ht(c,t),f=u[p];if(f||(f={events:{},typeCount:0},p=c.push(t)-1,u.push(f),d.push(o?{supplied:[],wrapped:[],useCount:[]}:null)),f.events[e]||(f.events[e]=[],f.typeCount++),!pt(f.events[e],a)){var v;if(o){var g=d[p],m=ht(g.supplied,a),y=g.wrapped[m]||function(e){e.immediatePropagationStopped||(e.target=e.srcElement,e.currentTarget=t,e.preventDefault=e.preventDefault||n,e.stopPropagation=e.stopPropagation||r,e.stopImmediatePropagation=e.stopImmediatePropagation||i,/mouse|click/.test(e.type)&&(e.pageX=e.clientX+z(t).document.documentElement.scrollLeft,e.pageY=e.clientY+z(t).document.documentElement.scrollTop),a(e))};v=t[s](l+e,y,Boolean(h)),m===-1?(g.supplied.push(a),g.wrapped.push(y),g.useCount.push(1)):g.useCount[m]++}else v=t[s](e,a,h||!1);return f.events[e].push(a),v}}function e(t,n,r,i){var s,h,p,f=ht(c,t),v=u[f],g=r;if(v&&v.events)if(o&&(h=d[f],p=ht(h.supplied,r),g=h.wrapped[p]),"all"!==n){if(v.events[n]){var m=v.events[n].length;if("all"===r){for(s=0;s1&&this.target._element===this.element){var a=it(i||this.target.getAction(t,e,this,this.element),this.target);U(this.target,this.element,a)&&(o=a),this.prepared.name=null}else if(!this.prepared.name){var l=kt.get(r);l&&!Y(l,r,n)&&B(l,r,n)&&(o=it(i||l.getAction(t,e,this,r),l,n))&&U(l,r,o)&&(this.target=l,this.element=r)}var c=this.target,u=c&&c.options;if(!c||!i&&this.prepared.name)this.inertiaStatus.active&&r===this.element&&it(c.getAction(t,e,this,this.element),c).name===this.prepared.name&&(qt(this.inertiaStatus.i),this.inertiaStatus.active=!1,this.checkAndPreventDefault(e,c,this.element));else{if(o=o||it(i||c.getAction(t,e,this,r),c,this.element),this.setEventXY(this.startCoords,this.pointers),!o)return;u.styleCursor&&(c._doc.documentElement.style.cursor=et(o)),this.resizeAxes="resize"===o.name?o.axis:null,"gesture"===o&&this.pointerIds.length<2&&(o=null),this.prepared.name=o.name,this.prepared.axis=o.axis,this.prepared.edges=o.edges,this.snapStatus.snappedX=this.snapStatus.snappedY=this.restrictStatus.restrictedX=this.restrictStatus.restrictedY=NaN,this.downTimes[s]=(new Date).getTime(),this.downTargets[s]=n,v(this.downPointer,t),g(this.prevCoords,this.startCoords),this.pointerWasMoved=!1,this.checkAndPreventDefault(e,c,this.element)}},setModifications:function(t,e){var n=this.target,r=!0,i=F(n,this.prepared.name)&&(!n.options[this.prepared.name].snap.endOnly||e),o=G(n,this.prepared.name)&&(!n.options[this.prepared.name].restrict.endOnly||e);return i?this.setSnapping(t):this.snapStatus.locked=!1,o?this.setRestriction(t):this.restrictStatus.restricted=!1,i&&this.snapStatus.locked&&!this.snapStatus.changed?r=o&&this.restrictStatus.restricted&&this.restrictStatus.changed:o&&this.restrictStatus.restricted&&!this.restrictStatus.changed&&(r=!1),r},setStartOffsets:function(t,e,n){var r,i,o=e.getRect(n),s=O(e,n),a=e.options[this.prepared.name].snap,l=e.options[this.prepared.name].restrict;o?(this.startOffset.left=this.startCoords.page.x-o.left,this.startOffset.top=this.startCoords.page.y-o.top,this.startOffset.right=o.right-this.startCoords.page.x,this.startOffset.bottom=o.bottom-this.startCoords.page.y,r="width"in o?o.width:o.right-o.left,i="height"in o?o.height:o.bottom-o.top):this.startOffset.left=this.startOffset.top=this.startOffset.right=this.startOffset.bottom=0,this.snapOffsets.splice(0);var c=a&&"startCoords"===a.offset?{x:this.startCoords.page.x-s.x,y:this.startCoords.page.y-s.y}:a&&a.offset||{x:0,y:0};if(o&&a&&a.relativePoints&&a.relativePoints.length)for(var u=0;uHt),d||this.pointerIsDown&&!this.pointerWasMoved||(this.pointerIsDown&&clearTimeout(this.holdTimers[h]),this.collectEventTargets(t,e,n,"move")),this.pointerIsDown){if(d&&this.pointerWasMoved&&!o)return void this.checkAndPreventDefault(e,this.target,this.element);if(y(this.pointerDelta,this.prevCoords,this.curCoords),this.prepared.name){if(this.pointerWasMoved&&(!this.inertiaStatus.active||t instanceof Q&&/inertiastart/.test(t.type))){if(!this.interacting()&&(y(this.pointerDelta,this.prevCoords,this.curCoords),"drag"===this.prepared.name)){var p=Math.abs(c),f=Math.abs(u),v=this.target.options.drag.axis,m=p>f?"x":pc.bottom&&(v=c.top,c.top=c.bottom,c.bottom=v),c.left>c.right&&(v=c.left,c.left=c.right,c.right=v)}}else c.top=Math.min(l.top,a.bottom),c.bottom=Math.max(l.bottom,a.top),c.left=Math.min(l.left,a.right),c.right=Math.max(l.right,a.left);c.width=c.right-c.left,c.height=c.bottom-c.top;for(var g in c)u[g]=c[g]-d[g];e.edges=this.prepared.edges,e.rect=c,e.deltaRect=u}return this.target.fire(e),e},gestureStart:function(t){var e=new Q(this,t,"gesture","start",this.element);return e.ds=0,this.gesture.startDistance=this.gesture.prevDistance=e.distance,this.gesture.startAngle=this.gesture.prevAngle=e.angle,this.gesture.scale=1,this.gesturing=!0,this.target.fire(e),e},gestureMove:function(t){if(!this.pointerIds.length)return this.prevEvent;var e;return e=new Q(this,t,"gesture","move",this.element),e.ds=e.scale-this.gesture.scale,this.target.fire(e),this.gesture.prevAngle=e.angle,this.gesture.prevDistance=e.distance,e.scale===1/0||null===e.scale||void 0===e.scale||isNaN(e.scale)||(this.gesture.scale=e.scale),e},pointerHold:function(t,e,n){this.collectEventTargets(t,e,n,"hold")},pointerUp:function(t,e,n,r){var i=this.mouse?0:ht(this.pointerIds,E(t));clearTimeout(this.holdTimers[i]),this.collectEventTargets(t,e,n,"up"),this.collectEventTargets(t,e,n,"tap"),this.pointerEnd(t,e,n,r),this.removePointer(t)},pointerCancel:function(t,e,n,r){var i=this.mouse?0:ht(this.pointerIds,E(t));clearTimeout(this.holdTimers[i]),this.collectEventTargets(t,e,n,"cancel"),this.pointerEnd(t,e,n,r),this.removePointer(t)},ie8Dblclick:function(t,e,n){this.prevTap&&e.clientX===this.prevTap.clientX&&e.clientY===this.prevTap.clientY&&n===this.prevTap.target&&(this.downTargets[0]=n,this.downTimes[0]=(new Date).getTime(),this.collectEventTargets(t,e,n,"tap"))},pointerEnd:function(t,e,n,r){var i,o=this.target,s=o&&o.options,a=s&&this.prepared.name&&s[this.prepared.name].inertia,l=this.inertiaStatus;if(this.interacting()){if(l.active&&!l.ending)return;var c,u,d=(new Date).getTime(),h=!1,p=!1,v=!1,m=F(o,this.prepared.name)&&s[this.prepared.name].snap.endOnly,y=G(o,this.prepared.name)&&s[this.prepared.name].restrict.endOnly,b=0,x=0;if(c=this.dragging?"x"===s.drag.axis?Math.abs(this.pointerDelta.client.vx):"y"===s.drag.axis?Math.abs(this.pointerDelta.client.vy):this.pointerDelta.client.speed:this.pointerDelta.client.speed,h=a&&a.enabled&&"gesture"!==this.prepared.name&&e!==l.startEvent,p=h&&d-this.curCoords.timeStamp<50&&c>a.minSpeed&&c>a.endSpeed,h&&!p&&(m||y)){var w={};w.snap=w.restrict=w,m&&(this.setSnapping(this.curCoords.page,w),w.locked&&(b+=w.dx,x+=w.dy)),y&&(this.setRestriction(this.curCoords.page,w),w.restricted&&(b+=w.dx,x+=w.dy)),(b||x)&&(v=!0)}if(p||v){if(g(l.upCoords,this.curCoords),this.pointers[0]=l.startEvent=u=new Q(this,e,this.prepared.name,"inertiastart",this.element),l.t0=d,o.fire(l.startEvent),p){l.vx0=this.pointerDelta.client.vx,l.vy0=this.pointerDelta.client.vy,l.v0=c,this.calcInertia(l);var _,S=f({},this.curCoords.page),E=O(o,this.element);if(S.x=S.x+l.xe-E.x,S.y=S.y+l.ye-E.y,_={useStatusXY:!0,x:S.x,y:S.y,dx:0,dy:0,snap:null},_.snap=_,b=x=0,m){var C=this.setSnapping(this.curCoords.page,_);C.locked&&(b+=C.dx,x+=C.dy)}if(y){var z=this.setRestriction(this.curCoords.page,_);z.restricted&&(b+=z.dx,x+=z.dy)}l.modifiedXe+=b,l.modifiedYe+=x,l.i=Vt(this.boundInertiaFrame)}else l.smoothEnd=!0,l.xe=b,l.ye=x,l.sx=l.sy=0,l.i=Vt(this.boundSmoothEndFrame);return void(l.active=!0)}(m||y)&&this.pointerMove(t,e,n,r,!0)}if(this.dragging){i=new Q(this,e,"drag","end",this.element);var T=this.element,D=this.getDrop(i,e,T);this.dropTarget=D.dropzone,this.dropElement=D.element;var k=this.getDropEvents(e,i);k.leave&&this.prevDropTarget.fire(k.leave),k.enter&&this.dropTarget.fire(k.enter),k.drop&&this.dropTarget.fire(k.drop),k.deactivate&&this.fireActiveDrops(k.deactivate),o.fire(i)}else this.resizing?(i=new Q(this,e,"resize","end",this.element),o.fire(i)):this.gesturing&&(i=new Q(this,e,"gesture","end",this.element),o.fire(i));this.stop(e)},collectDrops:function(t){var e,n=[],r=[];for(t=t||this.element,e=0;ea.innerWidth-Ot.margin,r=t.clientY>a.innerHeight-Ot.margin;else{var l=T(a);i=t.clientXl.right-Ot.margin,r=t.clientY>l.bottom-Ot.margin}Ot.x=n?1:i?-1:0,Ot.y=r?1:e?-1:0,Ot.isScrolling||(Ot.margin=s.margin,Ot.speed=s.speed,Ot.start(this))}},_updateEventTargets:function(t,e){this._eventTarget=t,this._curEventTarget=e}},Q.prototype={preventDefault:r,stopImmediatePropagation:function(){this.immediatePropagationStopped=this.propagationStopped=!0},stopPropagation:function(){this.propagationStopped=!0}};for(var Qt={},te=["dragStart","dragMove","resizeStart","resizeMove","gestureStart","gestureMove","pointerOver","pointerOut","pointerHover","selectorDown","pointerDown","pointerMove","pointerUp","pointerCancel","pointerEnd","addPointer","removePointer","recordPointer","autoScrollMove"],ee=0,ne=te.length;eeo.left&&d.xo.top&&d.y=o.left&&f<=o.right&&v>=o.top&&v<=o.bottom}if(u(a)){var g=Math.max(0,Math.min(o.right,p.right)-Math.max(o.left,p.left))*Math.max(0,Math.min(o.bottom,p.bottom)-Math.max(o.top,p.top)),m=g/(p.width*p.height);s=m>=a}return this.options.drop.checker&&(s=this.options.drop.checker(t,e,s,this,i,n,r)),s},dropChecker:function(t){return c(t)?(this.options.drop.checker=t,this):null===t?(delete this.options.getRect,this):this.options.drop.checker},accept:function(t){return i(t)?(this.options.drop.accept=t,this):p(t)?(this.options.drop.accept=t,this):null===t?(delete this.options.drop.accept,this):this.options.drop.accept},resizable:function(t){return l(t)?(this.options.resize.enabled=t.enabled!==!1,this.setPerAction("resize",t),this.setOnEvents("resize",t),/^x$|^y$|^xy$/.test(t.axis)?this.options.resize.axis=t.axis:null===t.axis&&(this.options.resize.axis=Mt.resize.axis),d(t.preserveAspectRatio)?this.options.resize.preserveAspectRatio=t.preserveAspectRatio:d(t.square)&&(this.options.resize.square=t.square),this):d(t)?(this.options.resize.enabled=t,this):this.options.resize},squareResize:function(t){return d(t)?(this.options.resize.square=t,this):null===t?(delete this.options.resize.square,this):this.options.resize.square},gesturable:function(t){return l(t)?(this.options.gesture.enabled=t.enabled!==!1,this.setPerAction("gesture",t),this.setOnEvents("gesture",t),this):d(t)?(this.options.gesture.enabled=t,this):this.options.gesture},autoScroll:function(t){return l(t)?t=f({actions:["drag","resize"]},t):d(t)&&(t={actions:["drag","resize"],enabled:t}),this.setOptions("autoScroll",t)},snap:function(t){var e=this.setOptions("snap",t);return e===this?this:e.drag},setOptions:function(t,e){var n,r=e&&a(e.actions)?e.actions:["drag"];if(l(e)||d(e)){for(n=0;n=0&&(s.selectors[o]!==this.selector||s.contexts[o]!==this._context);o--);o===-1&&(o=s.selectors.length,s.selectors.push(this.selector),s.contexts.push(this._context),s.listeners.push([])),s.listeners[o].push([e,n])}else Jt.add(this._element,t,e,n);return this},off:function(t,e,n){var r;if(h(t)&&t.search(" ")!==-1&&(t=t.trim().split(/ +/)),a(t)){for(r=0;r=0;s--)if(c.selectors[s]===this.selector&&c.contexts[s]===this._context){var d=c.listeners[s];for(r=d.length-1;r>=0;r--){var p=d[r][0],f=d[r][1];if(p===e&&f===n){d.splice(r,1),d.length||(c.selectors.splice(s,1),c.contexts.splice(s,1),c.listeners.splice(s,1),Jt.remove(this._context,t,ot),Jt.remove(this._context,t,st,!0),c.selectors.length||($t[t]=null)),u=!0;break}}if(u)break}}else Jt.remove(this._element,t,e,n);return this},set:function(t){l(t)||(t={}),this.options=f({},Mt.base);var e,n=["drag","drop","resize","gesture"],r=["draggable","dropzone","resizable","gesturable"],i=f(f({},Mt.perAction),t[o]||{});for(e=0;e=0;e--)At[e].stop(t);return at},at.dynamicDrop=function(t){return d(t)?(It=t,at):It},at.pointerMoveTolerance=function(t){return u(t)?(Ht=t,this):Ht},at.maxInteractions=function(t){return u(t)?(jt=t,this):jt},at.createSnapGrid=function(t){return function(e,n){var r=0,i=0;l(t.offset)&&(r=t.offset.x,i=t.offset.y);var o=Math.round((e-r)/t.x),s=Math.round((n-i)/t.y),a=o*t.x+r,c=s*t.y+i;return{x:a,y:c,range:t.range}}},dt(bt),Ut in Element.prototype&&c(Element.prototype[Ut])||(mt=function(t,e,n){n=n||t.parentNode.querySelectorAll(e);for(var r=0,i=n.length;r-1)return t.splice(n,1)}}function s(t,e){return si.call(t,e)}function a(t){return"string"==typeof t||"number"==typeof t}function l(t){var e=Object.create(null);return function(n){var r=e[n];return r||(e[n]=t(n))}}function c(t,e){function n(n){var r=arguments.length;return r?r>1?t.apply(e,arguments):t.call(e,n):t.call(e)}return n._length=t.length,n}function u(t,e){e=e||0;for(var n=t.length-e,r=new Array(n);n--;)r[n]=t[n+e];return r}function d(t,e){for(var n in e)t[n]=e[n];return t}function h(t){return null!==t&&"object"==typeof t}function p(t){return hi.call(t)===pi}function f(t){for(var e={},n=0;n1?u(n):n;for(var r=u(arguments,1),i=0,o=n.length;i=0&&Ki[n].id>t.id;)n--;Ki.splice(Math.max(n,no)+1,0,t)}else Ki.push(t);to||(to=!0,Di(zt))}}function Dt(t){oo.clear(),kt(t,oo)}function kt(t,e){var n,r,i=Array.isArray(t);if((i||h(t))&&Object.isExtensible(t)){if(t.__ob__){var o=t.__ob__.dep.id;if(e.has(o))return;e.add(o)}if(i)for(n=t.length;n--;)kt(t[n],e);else for(r=Object.keys(t),n=r.length;n--;)kt(t[r[n]],e)}}function At(t){t._watchers=[];var e=t.$options;e.props&&It(t,e.props),e.methods&&Rt(t,e.methods),e.data?$t(t):T(t._data={},!0),e.computed&&Mt(t,e.computed),e.watch&&Pt(t,e.watch)}function It(t,e){var n=t.$options.propsData||{},r=t.$options._propKeys=Object.keys(e),i=!t.$parent;Ni.shouldConvert=i;for(var o=function(i){var o=r[i];D(t,o,L(o,e,n,t))},s=0;s-1:t.test(e)}function qt(t,e){for(var n in t){var r=t[n];if(r){var i=Ut(r.componentOptions);i&&!e(i)&&(Jt(r),t[n]=null)}}}function Jt(t){t&&(t.componentInstance._inactive||Et(t.componentInstance,"deactivated"),t.componentInstance.$destroy())}function Kt(t){var e={};e.get=function(){return gi},Object.defineProperty(t,"config",e),t.util=Wi,t.set=k,t.delete=A,t.nextTick=Di,t.options=Object.create(null),gi._assetTypes.forEach(function(e){t.options[e+"s"]=Object.create(null)}),t.options._base=t,d(t.options.components,uo),Xt(t),Ft(t),Gt(t),Zt(t)}function Qt(t){for(var e=t.data,n=t,r=t;r.componentInstance;)r=r.componentInstance._vnode,r.data&&(e=te(r.data,e));for(;n=n.parent;)n.data&&(e=te(e,n.data));return ee(e)}function te(t,e){return{staticClass:ne(t.staticClass,e.staticClass),class:t.class?[t.class,e.class]:e.class}}function ee(t){var e=t.class,n=t.staticClass;return n||e?ne(n,re(e)):""}function ne(t,e){return t?e?t+" "+e:t:e||""}function re(t){var e="";if(!t)return e;if("string"==typeof t)return t;if(Array.isArray(t)){for(var n,r=0,i=t.length;r-1?To[t]=e.constructor===window.HTMLUnknownElement||e.constructor===window.HTMLElement:To[t]=/HTMLUnknownElement/.test(e.toString())}function se(t){if("string"==typeof t){if(t=document.querySelector(t),!t)return document.createElement("div")}return t}function ae(t,e){var n=document.createElement(t);return"select"!==t?n:(e.data&&e.data.attrs&&"multiple"in e.data.attrs&&n.setAttribute("multiple","multiple"),n)}function le(t,e){return document.createElementNS(_o[t],e)}function ce(t){return document.createTextNode(t)}function ue(t){return document.createComment(t)}function de(t,e,n){t.insertBefore(e,n)}function he(t,e){t.removeChild(e)}function pe(t,e){t.appendChild(e)}function fe(t){return t.parentNode}function ve(t){return t.nextSibling}function ge(t){return t.tagName}function me(t,e){t.textContent=e}function ye(t,e,n){t.setAttribute(e,n)}function be(t,e){var n=t.data.ref;if(n){var r=t.context,i=t.componentInstance||t.elm,s=r.$refs;e?Array.isArray(s[n])?o(s[n],i):s[n]===i&&(s[n]=void 0):t.data.refInFor?Array.isArray(s[n])&&s[n].indexOf(i)<0?s[n].push(i):s[n]=[i]:s[n]=i}}function xe(t){return null==t}function we(t){return null!=t}function _e(t,e){return t.key===e.key&&t.tag===e.tag&&t.isComment===e.isComment&&!t.data==!e.data}function Se(t,e,n){var r,i,o={};for(r=e;r<=n;++r)i=t[r].key,we(i)&&(o[i]=r);return o}function Ee(t){function e(t){return new Yi(T.tagName(t).toLowerCase(),{},[],void 0,t)}function n(t,e){function n(){0===--n.listeners&&r(t)}return n.listeners=e,n}function r(t){var e=T.parentNode(t);e&&T.removeChild(e,t)}function o(t,e,n,r,i){if(t.isRootInsert=!i,!s(t,e,n,r)){var o=t.data,a=t.children,l=t.tag;we(l)?(t.elm=t.ns?T.createElementNS(t.ns,l):T.createElement(l,t),f(t),d(t,a,e),we(o)&&p(t,e),u(n,t.elm,r)):t.isComment?(t.elm=T.createComment(t.text),u(n,t.elm,r)):(t.elm=T.createTextNode(t.text),u(n,t.elm,r))}}function s(t,e,n,r){var i=t.data;if(we(i)){var o=we(t.componentInstance)&&i.keepAlive;if(we(i=i.hook)&&we(i=i.init)&&i(t,!1,n,r),we(t.componentInstance))return l(t,e),o&&c(t,e,n,r),!0}}function l(t,e){t.data.pendingInsert&&e.push.apply(e,t.data.pendingInsert),t.elm=t.componentInstance.$el,h(t)?(p(t,e),f(t)):(be(t),e.push(t))}function c(t,e,n,r){for(var i,o=t;o.componentInstance;)if(o=o.componentInstance._vnode,we(i=o.data)&&we(i=i.transition)){for(i=0;ih?(c=xe(n[g+1])?null:n[g+1].elm,v(t,c,n,d,g,r)):d>g&&m(t,e,u,h)}function x(t,e,n,r){if(t!==e){if(e.isStatic&&t.isStatic&&e.key===t.key&&(e.isCloned||e.isOnce))return e.elm=t.elm,void(e.componentInstance=t.componentInstance);var i,o=e.data,s=we(o);s&&we(i=o.hook)&&we(i=i.prepatch)&&i(t,e);var a=e.elm=t.elm,l=t.children,c=e.children;if(s&&h(e)){for(i=0;i-1?e.split(/\s+/).forEach(function(e){return t.classList.add(e)}):t.classList.add(e);else{var n=" "+t.getAttribute("class")+" ";n.indexOf(" "+e+" ")<0&&t.setAttribute("class",(n+e).trim())}}function Fe(t,e){if(e&&e.trim())if(t.classList)e.indexOf(" ")>-1?e.split(/\s+/).forEach(function(e){return t.classList.remove(e)}):t.classList.remove(e);else{for(var n=" "+t.getAttribute("class")+" ",r=" "+e+" ";n.indexOf(r)>=0;)n=n.replace(r," ");t.setAttribute("class",n.trim())}}function Ge(t){Qo(function(){Qo(t)})}function Ze(t,e){(t._transitionClasses||(t._transitionClasses=[])).push(e),Xe(t,e)}function Ue(t,e){t._transitionClasses&&o(t._transitionClasses,e),Fe(t,e)}function Ve(t,e,n){var r=qe(t,e),i=r.type,o=r.timeout,s=r.propCount;if(!i)return n();var a=i===Zo?qo:Ko,l=0,c=function(){t.removeEventListener(a,u),n()},u=function(e){e.target===t&&++l>=s&&c()};setTimeout(function(){l0&&(n=Zo,u=s,d=o.length):e===Uo?c>0&&(n=Uo,u=c,d=l.length):(u=Math.max(s,c),n=u>0?s>c?Zo:Uo:null,d=n?n===Zo?o.length:l.length:0);var h=n===Zo&&ts.test(r[Vo+"Property"]);return{type:n,timeout:u,propCount:d,hasTransform:h}}function Je(t,e){for(;t.length1,$=n._enterCb=nn(function(){A&&(Ue(n,C),Ue(n,E)),$.cancelled?(A&&Ue(n,S),k&&k(n)):D&&D(n),n._enterCb=null});t.data.show||it(t.data.hook||(t.data.hook={}),"insert",function(){var e=n.parentNode,r=e&&e._pending&&e._pending[t.key];r&&r.tag===t.tag&&r.elm._leaveCb&&r.elm._leaveCb(),T&&T(n,$)},"transition-insert"),z&&z(n),A&&(Ze(n,S),Ze(n,E),Ge(function(){Ze(n,C),Ue(n,S),$.cancelled||I||Ve(n,o,$)})),t.data.show&&(e&&e(),T&&T(n,$)),A||I||$()}}}function tn(t,e){function n(){m.cancelled||(t.data.show||((r.parentNode._pending||(r.parentNode._pending={}))[t.key]=t),u&&u(r),v&&(Ze(r,a),Ze(r,c),Ge(function(){Ze(r,l),Ue(r,a),m.cancelled||g||Ve(r,s,m)})),d&&d(r,m),v||g||m())}var r=t.elm;r._enterCb&&(r._enterCb.cancelled=!0,r._enterCb());var i=en(t.data.transition);if(!i)return e();if(!r._leaveCb&&1===r.nodeType){var o=i.css,s=i.type,a=i.leaveClass,l=i.leaveToClass,c=i.leaveActiveClass,u=i.beforeLeave,d=i.leave,h=i.afterLeave,p=i.leaveCancelled,f=i.delayLeave,v=o!==!1&&!_i,g=d&&(d._length||d.length)>1,m=r._leaveCb=nn(function(){r.parentNode&&r.parentNode._pending&&(r.parentNode._pending[t.key]=null),v&&(Ue(r,l),Ue(r,c)),m.cancelled?(v&&Ue(r,a),p&&p(r)):(e(),h&&h(r)),r._leaveCb=null});f?f(n):n()}}function en(t){if(t){if("object"==typeof t){var e={};return t.css!==!1&&d(e,es(t.name||"v")),d(e,t),e}return"string"==typeof t?es(t):void 0}}function nn(t){var e=!1;return function(){e||(e=!0,t())}}function rn(t,e){e.data.show||Qe(e)}function on(t,e,n){var r=e.value,i=t.multiple;if(!i||Array.isArray(r)){for(var o,s,a=0,l=t.options.length;a-1,s.selected!==o&&(s.selected=o);else if(m(an(s),r))return void(t.selectedIndex!==a&&(t.selectedIndex=a));i||(t.selectedIndex=-1)}}function sn(t,e){for(var n=0,r=e.length;n',n.innerHTML.indexOf(e)>0}function wn(t){return fs=fs||document.createElement("div"),fs.innerHTML=t,fs.textContent}function _n(t,e){return e&&(t=t.replace(aa,"\n")),t.replace(oa,"<").replace(sa,">").replace(la,"&").replace(ca,'"')}function Sn(t,e){function n(e){d+=e,t=t.substring(e)}function r(){var e=t.match(Cs);if(e){var r={tagName:e[1],attrs:[],start:d};n(e[0].length);for(var i,o;!(i=t.match(zs))&&(o=t.match(_s));)n(o[0].length),r.attrs.push(o);if(i)return r.unarySlash=i[1],n(i[0].length),r.end=d,r}}function i(t){var n=t.tagName,r=t.unarySlash;c&&("p"===a&&ys(n)&&o(a),ms(n)&&a===n&&o(n));for(var i=u(n)||"html"===n&&"head"===a||!!r,s=t.attrs.length,d=new Array(s),h=0;h=0&&l[i].lowerCasedTag!==o;i--);else i=0;if(i>=0){for(var s=l.length-1;s>=i;s--)e.end&&e.end(l[s].tag,n,r);l.length=i,a=i&&l[i-1].tag}else"br"===o?e.start&&e.start(t,[],!0,n,r):"p"===o&&(e.start&&e.start(t,[],!1,n,r),e.end&&e.end(t,n,r))}for(var s,a,l=[],c=e.expectHTML,u=e.isUnaryTag||fi,d=0;t;){if(s=t,a&&ra(a)){var h=a.toLowerCase(),p=ia[h]||(ia[h]=new RegExp("([\\s\\S]*?)(]*>)","i")),f=0,v=t.replace(p,function(t,n,r){return f=r.length,"script"!==h&&"style"!==h&&"noscript"!==h&&(n=n.replace(//g,"$1").replace(//g,"$1")),e.chars&&e.chars(n),""});d+=t.length-v.length,t=v,o(h,d-f,d)}else{var g=t.indexOf("<");if(0===g){if(ks.test(t)){var m=t.indexOf("-->");if(m>=0){n(m+3);continue}}if(As.test(t)){var y=t.indexOf("]>");if(y>=0){n(y+2);continue}}var b=t.match(Ds);if(b){n(b[0].length);continue}var x=t.match(Ts);if(x){var w=d;n(x[0].length),o(x[1],w,d);continue}var _=r();if(_){i(_);continue}}var S=void 0,E=void 0,C=void 0;if(g>0){for(E=t.slice(g);!(Ts.test(E)||Cs.test(E)||ks.test(E)||As.test(E)||(C=E.indexOf("<",1),C<0));)g+=C,E=t.slice(g);S=t.substring(0,g),n(g)}g<0&&(S=t,t=""),e.chars&&S&&e.chars(S)}if(t===s&&e.chars){e.chars(t);break}}o()}function En(t){function e(){(s||(s=[])).push(t.slice(f,i).trim()),f=i+1}var n,r,i,o,s,a=!1,l=!1,c=!1,u=!1,d=0,h=0,p=0,f=0;for(i=0;i=0&&(g=t.charAt(v)," "===g);v--);g&&/[\w$]/.test(g)||(u=!0)}}else void 0===o?(f=i+1,o=t.slice(0,i).trim()):e();if(void 0===o?o=t.slice(0,i).trim():0!==f&&e(),s)for(i=0;is&&o.push(JSON.stringify(t.slice(s,i)));var a=En(r[1].trim());o.push("_s("+a+")"),s=i+r[0].length}return s=$s}function Hn(t){return 34===t||39===t}function Ln(t){var e=1;for(Ps=Rs;!Nn();)if(t=Pn(),Hn(t))jn(t);else if(91===t&&e++,93===t&&e--,0===e){Ns=Rs;break}}function jn(t){for(var e=t;!Nn()&&(t=Pn(),t!==e););}function Wn(t,e){Hs=e.warn||Tn,Ls=e.getTagNamespace||fi,js=e.mustUseProp||fi,Ws=e.isPreTag||fi,Ys=Dn(e.modules,"preTransformNode"),Bs=Dn(e.modules,"transformNode"),Xs=Dn(e.modules,"postTransformNode"),Fs=e.delimiters;var n,r,i=[],o=e.preserveWhitespace!==!1,s=!1,a=!1;return Sn(t,{expectHTML:e.expectHTML,isUnaryTag:e.isUnaryTag,shouldDecodeNewlines:e.shouldDecodeNewlines,start:function(t,o,l){function c(t){}var u=r&&r.ns||Ls(t);wi&&"svg"===u&&(o=or(o));var d={type:1,tag:t,attrsList:o,attrsMap:rr(o),parent:r,children:[]};u&&(d.ns=u),ir(d)&&!zi()&&(d.forbidden=!0);for(var h=0;h-1"+("true"===o?":("+e+")":":_q("+e+","+o+")")),$n(t,"click","var $$a="+e+",$$el=$event.target,$$c=$$el.checked?("+o+"):("+s+");if(Array.isArray($$a)){var $$v="+(r?"_n("+i+")":i)+",$$i=_i($$a,$$v);if($$c){$$i<0&&("+e+"=$$a.concat($$v))}else{$$i>-1&&("+e+"=$$a.slice(0,$$i).concat($$a.slice($$i+1)))}}else{"+e+"=$$c}",null,!0)}function Zr(t,e,n){var r=n&&n.number,i=Mn(t,"value")||"null";i=r?"_n("+i+")":i,kn(t,"checked","_q("+e+","+i+")"),$n(t,"click",qr(e,i),null,!0)}function Ur(t,e,n){var r=t.attrsMap.type,i=n||{},o=i.lazy,s=i.number,a=i.trim,l=o||wi&&"range"===r?"change":"input",c=!o&&"range"!==r,u="input"===t.tag||"textarea"===t.tag,d=u?"$event.target.value"+(a?".trim()":""):a?"(typeof $event === 'string' ? $event.trim() : $event)":"$event";d=s||"number"===r?"_n("+d+")":d;var h=qr(e,d);u&&c&&(h="if($event.target.composing)return;"+h),kn(t,"value",u?"_s("+e+")":"("+e+")"),$n(t,l,h,null,!0),(a||s||"number"===r)&&$n(t,"blur","$forceUpdate()")}function Vr(t,e,n){var r=n&&n.number,i='Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = "_value" in o ? o._value : o.value;return '+(r?"_n(val)":"val")+"})"+(null==t.attrsMap.multiple?"[0]":""),o=qr(e,i);$n(t,"change",o,null,!0)}function qr(t,e){var n=Rn(t);return null===n.idx?t+"="+e:"var $$exp = "+n.exp+", $$idx = "+n.idx+";if (!Array.isArray($$exp)){"+t+"="+e+"}else{$$exp.splice($$idx, 1, "+e+")}"}function Jr(t,e){e.value&&kn(t,"textContent","_s("+e.value+")")}function Kr(t,e){e.value&&kn(t,"innerHTML","_s("+e.value+")")}function Qr(t,e){return e=e?d(d({},Oa),e):Oa,jr(t,e)}function ti(t,e,n){var r=(e&&e.warn||Ai,e&&e.delimiters?String(e.delimiters)+t:t);if(Ma[r])return Ma[r];var i={},o=Qr(t,e);i.render=ei(o.render);var s=o.staticRenderFns.length;i.staticRenderFns=new Array(s);for(var a=0;a0,Si=xi&&xi.indexOf("edge/")>0,Ei=xi&&xi.indexOf("android")>0,Ci=xi&&/iphone|ipad|ipod|ios/.test(xi),zi=function(){return void 0===ri&&(ri=!bi&&"undefined"!=typeof e&&"server"===e.process.env.VUE_ENV),ri},Ti=bi&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__,Di=function(){function t(){r=!1;var t=n.slice(0);n.length=0;for(var e=0;e1&&(e[n[0].trim()]=n[1].trim())}}),e}),jo=/^--/,Wo=/\s*!important$/,Yo=function(t,e,n){jo.test(e)?t.style.setProperty(e,n):Wo.test(n)?t.style.setProperty(e,n.replace(Wo,""),"important"):t.style[Xo(e)]=n},Bo=["Webkit","Moz","ms"],Xo=l(function(t){if(po=po||document.createElement("div"),t=li(t),"filter"!==t&&t in po.style)return t;for(var e=t.charAt(0).toUpperCase()+t.slice(1),n=0;n\/=]+)/,xs=/(?:=)/,ws=[/"([^"]*)"+/.source,/'([^']*)'+/.source,/([^\s"'=<>`]+)/.source],_s=new RegExp("^\\s*"+bs.source+"(?:\\s*("+xs.source+")\\s*(?:"+ws.join("|")+"))?"),Ss="[a-zA-Z_][\\w\\-\\.]*",Es="((?:"+Ss+"\\:)?"+Ss+")",Cs=new RegExp("^<"+Es),zs=/^\s*(\/?)>/,Ts=new RegExp("^<\\/"+Es+"[^>]*>"),Ds=/^]+>/i,ks=/^\";\n }\n while (all[0]);\n\n return v > 4 ? v : undef;\n }());\n\n return version === ieVersion;\n};\n\ndetector.isLegacyOpera = function() {\n return !!window.opera;\n};\n\n\n/***/ },\n/* 6 */\n/***/ function(module, exports) {\n\n\"use strict\";\n\"use strict\";\n\nvar utils = module.exports = {};\n\n/**\n * Loops through the collection and calls the callback for each element. if the callback returns truthy, the loop is broken and returns the same value.\n * @public\n * @param {*} collection The collection to loop through. Needs to have a length property set and have indices set from 0 to length - 1.\n * @param {function} callback The callback to be called for each element. The element will be given as a parameter to the callback. If this callback returns truthy, the loop is broken and the same value is returned.\n * @returns {*} The value that a callback has returned (if truthy). Otherwise nothing.\n */\nutils.forEach = function(collection, callback) {\n for(var i = 0; i < collection.length; i++) {\n var result = callback(collection[i]);\n if(result) {\n return result;\n }\n }\n};\n\n\n/***/ },\n/* 7 */\n/***/ function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\"use strict\";\n\nvar forEach = __webpack_require__(6).forEach;\nvar elementUtilsMaker = __webpack_require__(22);\nvar listenerHandlerMaker = __webpack_require__(25);\nvar idGeneratorMaker = __webpack_require__(23);\nvar idHandlerMaker = __webpack_require__(24);\nvar reporterMaker = __webpack_require__(26);\nvar browserDetector = __webpack_require__(5);\nvar batchProcessorMaker = __webpack_require__(15);\nvar stateHandler = __webpack_require__(27);\n\n//Detection strategies.\nvar objectStrategyMaker = __webpack_require__(20);\nvar scrollStrategyMaker = __webpack_require__(21);\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 strategyOptions = {\n reporter: reporter,\n batchProcessor: batchProcessor,\n stateHandler: stateHandler,\n idHandler: idHandler\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 }, 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 return {\n listenTo: listenTo,\n removeListener: eventListenerHandler.removeListener,\n removeAllListeners: eventListenerHandler.removeAllListeners,\n uninstall: uninstall\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\n\n/***/ },\n/* 8 */\n/***/ function(module, exports, __webpack_require__) {\n\nvar __vue_exports__, __vue_options__\nvar __vue_styles__ = {}\n\n/* styles */\n__webpack_require__(32)\n\n/* script */\n__vue_exports__ = __webpack_require__(11)\n\n/* template */\nvar __vue_template__ = __webpack_require__(29)\n__vue_options__ = __vue_exports__ = __vue_exports__ || {}\nif (\n typeof __vue_exports__.default === \"object\" ||\n typeof __vue_exports__.default === \"function\"\n) {\n__vue_options__ = __vue_exports__ = __vue_exports__.default\n}\nif (typeof __vue_options__ === \"function\") {\n __vue_options__ = __vue_options__.options\n}\n\n__vue_options__.render = __vue_template__.render\n__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\nmodule.exports = __vue_exports__\n\n\n/***/ },\n/* 9 */\n/***/ function(module, exports, __webpack_require__) {\n\nvar __vue_exports__, __vue_options__\nvar __vue_styles__ = {}\n\n/* styles */\n__webpack_require__(33)\n\n/* script */\n__vue_exports__ = __webpack_require__(12)\n\n/* template */\nvar __vue_template__ = __webpack_require__(30)\n__vue_options__ = __vue_exports__ = __vue_exports__ || {}\nif (\n typeof __vue_exports__.default === \"object\" ||\n typeof __vue_exports__.default === \"function\"\n) {\n__vue_options__ = __vue_exports__ = __vue_exports__.default\n}\nif (typeof __vue_options__ === \"function\") {\n __vue_options__ = __vue_options__.options\n}\n\n__vue_options__.render = __vue_template__.render\n__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\nmodule.exports = __vue_exports__\n\n\n/***/ },\n/* 10 */\n/***/ function(module, exports, __webpack_require__) {\n\n\"use strict\";\n'use strict';\n\nexports.__esModule = true;\n\nvar _utils = __webpack_require__(0);\n\nvar _draggableUtils = __webpack_require__(13);\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 eventBus = __webpack_require__(4);\n\nvar interact = __webpack_require__(28);\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 },\n data: function data() {\n return {\n cols: 1,\n containerWidth: 100,\n rowHeight: 30,\n margin: [10, 10],\n maxRows: Infinity,\n // isDraggable: null,\n // isResizable: 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 self.isDraggable = isDraggable;\n };\n\n self.setResizableHandler = function (isResizable) {\n self.isResizable = isResizable;\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 eventBus.$on('updateWidth', self.updateWidthHandler);\n eventBus.$on('compact', self.compactHandler);\n eventBus.$on('setDraggable', self.setDraggableHandler);\n eventBus.$on('setResizable', self.setResizableHandler);\n eventBus.$on('setRowHeight', self.setRowHeightHandler);\n eventBus.$on('directionchange', self.directionchangeHandler);\n\n /*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 //Remove listeners\n eventBus.$off('updateWidth', self.updateWidthHandler);\n eventBus.$off('compact', self.compactHandler);\n eventBus.$off('setDraggable', self.setDraggableHandler);\n eventBus.$off('setResizable', self.setResizableHandler);\n eventBus.$off('setRowHeight', self.setRowHeightHandler);\n 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 this.isDraggable = this.$parent.isDraggable;\n this.isResizable = this.$parent.isResizable;\n this.useCssTransforms = this.$parent.useCssTransforms;\n this.createStyle();\n },\n watch: {\n isDraggable: function isDraggable() {\n var self = this;\n if (this.interactObj == null) {\n this.interactObj = interact(this.$refs.item, { ignoreFrom: \"a, button\" });\n }\n if (this.isDraggable) {\n this.interactObj.draggable({});\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 var self = this;\n if (this.interactObj == null) {\n this.interactObj = interact(this.$refs.item, { ignoreFrom: \"a, button\" });\n }\n if (this.isResizable) {\n this.interactObj.resizable({\n preserveAspectRatio: false,\n edges: { left: false, right: true, bottom: true, top: false }\n });\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 },\n computed: {\n resizableHandleClass: function resizableHandleClass() {\n if (this.rtl) {\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.rtl) {\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.rtl) {\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 }\n // top,left (slow)\n else {\n // Add rtl support\n if (this.rtl) {\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.rtl) {\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);\n }\n 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.rtl) {\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.rtl) {\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.rtl) {\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.rtl) {\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 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.rtl) {\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\n/***/ },\n/* 11 */\n/***/ function(module, exports, __webpack_require__) {\n\n\"use strict\";\n'use strict';\n\nexports.__esModule = true;\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\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\nvar elementResizeDetectorMaker = __webpack_require__(7);\n\nvar eventBus = __webpack_require__(4);\nexports.default = {\n name: \"GridLayout\",\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 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: 0\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 eventBus.$on('resizeEvent', self.resizeEventHandler);\n eventBus.$on('dragEvent', self.dragEventHandler);\n },\n\n beforeDestroy: function beforeDestroy() {\n //Remove listeners\n eventBus.$off('resizeEvent', self.resizeEventHandler);\n 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 eventBus.$emit(\"updateWidth\", this.width);\n this.updateHeight();\n });\n },\n layout: function layout() {\n this.layoutUpdate();\n },\n rowHeight: function rowHeight() {\n eventBus.$emit(\"setRowHeight\", this.rowHeight);\n },\n isDraggable: function isDraggable() {\n eventBus.$emit(\"setDraggable\", this.isDraggable);\n },\n isResizable: function isResizable() {\n eventBus.$emit(\"setResizable\", this.isResizable);\n }\n },\n methods: {\n layoutUpdate: function layoutUpdate() {\n if (this.layout !== undefined && this.layout.length !== this.lastLayoutLength) {\n // console.log(\"### LAYOUT UPDATE!\");\n this.lastLayoutLength = this.layout.length;\n (0, _utils.compact)(this.layout, this.verticalCompact);\n\n //this.$broadcast(\"updateWidth\", this.width);\n 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) {\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.isDragging = true;\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.$broadcast(\"updateWidth\", this.width);\n eventBus.$emit(\"updateWidth\", this.width);\n } else {\n this.isDragging = false;\n }\n //console.log(eventName + \" id=\" + id + \", x=\" + x + \", y=\" + y);\n var l = (0, _utils.getLayoutItem)(this.layout, id);\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 eventBus.$emit(\"compact\");\n this.updateHeight();\n },\n resizeEvent: function resizeEvent(eventName, id, x, y, h, w) {\n if (eventName == \"resizestart\" || eventName == \"resizemove\") {\n this.isDragging = true;\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.$broadcast(\"updateWidth\", this.width);\n eventBus.$emit(\"updateWidth\", this.width);\n } else {\n this.isDragging = false;\n }\n var l = (0, _utils.getLayoutItem)(this.layout, id);\n l.h = h;\n l.w = w;\n (0, _utils.compact)(this.layout, this.verticalCompact);\n eventBus.$emit(\"compact\");\n this.updateHeight();\n }\n }\n};\n\n/***/ },\n/* 12 */\n/***/ function(module, exports, __webpack_require__) {\n\n\"use strict\";\n'use strict';\n\nexports.__esModule = true;\n\nvar _utils = __webpack_require__(0);\n\nvar _responsiveUtils = __webpack_require__(14);\n\nvar _GridItem = __webpack_require__(1);\n\nvar _GridItem2 = _interopRequireDefault(_GridItem);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\nvar elementResizeDetectorMaker = __webpack_require__(7);\n\nexports.default = {\n name: \"ResponsiveGridLayout\",\n components: {\n GridItem: _GridItem2.default\n },\n props: {\n autoSize: {\n type: Boolean,\n default: true\n },\n colNum: {\n type: Number,\n required: false,\n default: 0\n },\n rowHeight: {\n type: Number,\n default: 150\n },\n maxRows: {\n type: Number,\n default: Infinity\n },\n // Margin between items [x, y] in px\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 useCssTransforms: {\n type: Boolean,\n default: true\n },\n verticalCompact: {\n type: Boolean,\n default: true\n },\n\n // Optional, but if you are managing width yourself you may want to set the breakpoint\n // yourself as well.\n /*\n breakpoint: {\n type: String,\n required: false,\n default: \"lg\"\n },\n */\n // {name: pxVal}, e.g. {lg: 1200, md: 996, sm: 768, xs: 480}\n /*\n breakpoints: {\n type: Object,\n required: false,\n default: function() {return {lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0}}\n },\n \n // # of cols. This is a breakpoint -> cols map\n cols: {\n type: Object,\n required: false,\n default: function() {return {lg: 12, md: 10, sm: 6, xs: 4, xxs: 2}}\n },\n */\n\n layout: []\n\n },\n data: function data() {\n return {\n originalCols: null,\n width: null,\n mergedStyle: {},\n lastLayoutLength: 0\n };\n },\n beforeDestroy: function beforeDestroy() {\n //Remove listeners\n window.removeEventListener(\"resize\", self.onWindowResize);\n },\n mounted: function mounted() {\n this.$nextTick(function () {\n (0, _utils.validateLayout)(this.layout);\n this.originalCols = this.colNum;\n var self = this;\n window.onload = function () {\n self.onWindowResize();\n //self.width = self.$el.offsetWidth;\n window.addEventListener('resize', self.onWindowResize);\n (0, _utils.compact)(self.layout, self.verticalCompact);\n self.updateHeight();\n self.$nextTick(function () {\n // self.onWindowResize();\n var erd = elementResizeDetectorMaker({\n strategy: \"scroll\" //<- For ultra performance.\n });\n erd.listenTo(self.$refs.item, function (element) {\n self.onWindowResize();\n /*var width = element.offsetWidth;\n var height = element.offsetHeight;\n console.log(\"Size: \" + width + \"x\" + height);*/\n });\n });\n };\n });\n },\n\n watch: {\n width: function width() {\n if (this.width > 768) {\n this.colNum = this.originalCols;\n } else {\n this.colNum = 2;\n }\n this.$nextTick(function () {\n //this.$broadcast(\"updateWidth\", this.width, this.colNum);\n var self = this;\n this.$children.forEach(function (child) {\n child.updateWidth(self.width);\n });\n this.updateHeight();\n (0, _utils.compact)(this.layout, this.verticalCompact);\n });\n },\n layout: function layout() {\n if (this.layout !== undefined && this.layout.length !== this.lastLayoutLength) {\n this.lastLayoutLength = this.layout.length;\n (0, _utils.compact)(this.layout, this.verticalCompact);\n\n //this.$nextTick(function () {\n //this.$broadcast(\"updateWidth\", this.width);\n var self = this;\n this.$children.forEach(function (child) {\n child.updateWidth(self.width);\n });\n\n this.updateHeight();\n //});\n }\n }\n },\n methods: {\n onWindowResize: function onWindowResize() {\n if (this.$refs !== null && this.$refs.item !== null) {\n this.width = this.$refs.item.offsetWidth;\n }\n },\n updateHeight: function updateHeight() {\n this.mergedStyle = {\n height: this.containerHeight()\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) {\n var self = this;\n // console.log(eventName + \" id=\" + id + \", x=\" + x + \", y=\" + y);\n var l = (0, _utils.getLayoutItem)(this.layout, id);\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.$broadcast(\"compact\", this.layout);\n this.$children.forEach(function (child) {\n child.compact(self.layout);\n });\n\n this.updateHeight();\n },\n resizeEvent: function resizeEvent(eventName, id, h, w) {\n var self = this;\n /*if (eventName === \"drag\" && h < -40 && w < -40) {\n return;\n }*/\n // console.log(eventName + \" id=\" + id);\n // Move the element to the dragged location.\n (0, _utils.compact)(this.layout, this.verticalCompact);\n //this.$broadcast(\"compact\", this.layout);\n this.$children.forEach(function (child) {\n child.compact(self.layout);\n });\n\n this.updateHeight();\n }\n }\n};\n\n/***/ },\n/* 13 */\n/***/ function(module, exports) {\n\n\"use strict\";\n'use strict';\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\n/***/ },\n/* 14 */\n/***/ function(module, exports, __webpack_require__) {\n\n\"use strict\";\n'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.getBreakpointFromWidth = getBreakpointFromWidth;\nexports.getColsFromBreakpoint = getColsFromBreakpoint;\nexports.findOrGenerateResponsiveLayout = findOrGenerateResponsiveLayout;\nexports.generateResponsiveLayout = generateResponsiveLayout;\nexports.sortBreakpoints = sortBreakpoints;\n\nvar _utils = __webpack_require__(0);\n\n/*:: import type {Layout} from './utils';*/ // @flow\n\n/*:: export type ResponsiveLayout = {lg?: Layout, md?: Layout, sm?: Layout, xs?: Layout, xxs?: Layout};*/\n/*:: type Breakpoint = string;*/\n\n\n/**\r\n * Given a width, find the highest breakpoint that matches is valid for it (width > breakpoint).\r\n *\r\n * @param {Object} breakpoints Breakpoints object (e.g. {lg: 1200, md: 960, ...})\r\n * @param {Number} width Screen width.\r\n * @return {String} Highest breakpoint that is less than width.\r\n */\n/*:: type Breakpoints = {lg?: number, md?: number, sm?: number, xs?: number, xxs?: number};*/\nfunction getBreakpointFromWidth(breakpoints /*: Breakpoints*/, width /*: number*/) /*: Breakpoint*/ {\n var sorted = sortBreakpoints(breakpoints);\n var matching = sorted[0];\n for (var i = 1, len = sorted.length; i < len; i++) {\n var breakpointName = sorted[i];\n if (width > breakpoints[breakpointName]) matching = breakpointName;\n }\n return matching;\n}\n\n/**\r\n * Given a breakpoint, get the # of cols set for it.\r\n * @param {String} breakpoint Breakpoint name.\r\n * @param {Object} cols Map of breakpoints to cols.\r\n * @return {Number} Number of cols.\r\n */\nfunction getColsFromBreakpoint(breakpoint /*: Breakpoint*/, cols /*: Breakpoints*/) /*: number*/ {\n if (!cols[breakpoint]) {\n throw new Error(\"ResponsiveGridLayout: `cols` entry for breakpoint \" + breakpoint + \" is missing!\");\n }\n return cols[breakpoint];\n}\n\n/**\r\n * Given existing layouts and a new breakpoint, find or generate a new layout.\r\n *\r\n * This finds the layout above the new one and generates from it, if it exists.\r\n *\r\n * @param {Object} layouts Existing layouts.\r\n * @param {Array} breakpoints All breakpoints.\r\n * @param {String} breakpoint New breakpoint.\r\n * @param {String} breakpoint Last breakpoint (for fallback).\r\n * @param {Number} cols Column count at new breakpoint.\r\n * @param {Boolean} verticalCompact Whether or not to compact the layout\r\n * vertically.\r\n * @return {Array} New layout.\r\n */\nfunction findOrGenerateResponsiveLayout(layouts /*: ResponsiveLayout*/, breakpoints /*: Breakpoints*/, breakpoint /*: Breakpoint*/, lastBreakpoint /*: Breakpoint*/, cols /*: number*/, verticalCompact /*: boolean*/) /*: Layout*/ {\n // If it already exists, just return it.\n if (layouts[breakpoint]) return (0, _utils.cloneLayout)(layouts[breakpoint]);\n // Find or generate the next layout\n var layout = layouts[lastBreakpoint];\n var breakpointsSorted = sortBreakpoints(breakpoints);\n var breakpointsAbove = breakpointsSorted.slice(breakpointsSorted.indexOf(breakpoint));\n for (var i = 0, len = breakpointsAbove.length; i < len; i++) {\n var b = breakpointsAbove[i];\n if (layouts[b]) {\n layout = layouts[b];\n break;\n }\n }\n layout = (0, _utils.cloneLayout)(layout || []); // clone layout so we don't modify existing items\n return (0, _utils.compact)((0, _utils.correctBounds)(layout, { cols: cols }), verticalCompact);\n}\n\nfunction generateResponsiveLayout(layout /*: Layout*/, breakpoints /*: Breakpoints*/, breakpoint /*: Breakpoint*/, lastBreakpoint /*: Breakpoint*/, cols /*: number*/, verticalCompact /*: boolean*/) /*: Layout*/ {\n // If it already exists, just return it.\n /*if (layouts[breakpoint]) return cloneLayout(layouts[breakpoint]);\r\n // Find or generate the next layout\r\n let layout = layouts[lastBreakpoint];*/\n /*const breakpointsSorted = sortBreakpoints(breakpoints);\r\n const breakpointsAbove = breakpointsSorted.slice(breakpointsSorted.indexOf(breakpoint));\r\n for (let i = 0, len = breakpointsAbove.length; i < len; i++) {\r\n const b = breakpointsAbove[i];\r\n if (layouts[b]) {\r\n layout = layouts[b];\r\n break;\r\n }\r\n }*/\n layout = (0, _utils.cloneLayout)(layout || []); // clone layout so we don't modify existing items\n return (0, _utils.compact)((0, _utils.correctBounds)(layout, { cols: cols }), verticalCompact);\n}\n\n/**\r\n * Given breakpoints, return an array of breakpoints sorted by width. This is usually\r\n * e.g. ['xxs', 'xs', 'sm', ...]\r\n *\r\n * @param {Object} breakpoints Key/value pair of breakpoint names to widths.\r\n * @return {Array} Sorted breakpoints.\r\n */\nfunction sortBreakpoints(breakpoints /*: Breakpoints*/) /*: Array*/ {\n var keys /*: Array*/ = Object.keys(breakpoints);\n return keys.sort(function (a, b) {\n return breakpoints[a] - breakpoints[b];\n });\n}\n\n/***/ },\n/* 15 */\n/***/ function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\"use strict\";\n\nvar utils = __webpack_require__(16);\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\n\n/***/ },\n/* 16 */\n/***/ function(module, exports) {\n\n\"use strict\";\n\"use strict\";\n\nvar utils = module.exports = {};\n\nutils.getOption = getOption;\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\n\n/***/ },\n/* 17 */\n/***/ function(module, exports, __webpack_require__) {\n\nexports = module.exports = __webpack_require__(2)();\n// imports\n\n\n// module\nexports.push([module.i, \".vue-grid-layout{position:relative;transition:height .2s ease}\", \"\"]);\n\n// exports\n\n\n/***/ },\n/* 18 */\n/***/ function(module, exports, __webpack_require__) {\n\nexports = module.exports = __webpack_require__(2)();\n// imports\n\n\n// module\nexports.push([module.i, \".vue-grid-layout{position:relative;transition:height .2s ease}\", \"\"]);\n\n// exports\n\n\n/***/ },\n/* 19 */\n/***/ function(module, exports, __webpack_require__) {\n\nexports = module.exports = __webpack_require__(2)();\n// imports\n\n\n// module\nexports.push([module.i, \".vue-grid-item{transition:all .2s ease;transition-property:left,top,right}.vue-grid-item.cssTransforms{transition-property:transform}.vue-grid-item.resizing{opacity:.6;z-index:3}.vue-grid-item.vue-draggable-dragging{z-index:3}.vue-grid-item.vue-grid-placeholder{background:red;opacity:.2;transition-duration:.1s;z-index:2;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.vue-grid-item>.vue-resizable-handle{position:absolute;width:20px;height:20px;bottom:0;right:0;background:url(\\\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pg08IS0tIEdlbmVyYXRvcjogQWRvYmUgRmlyZXdvcmtzIENTNiwgRXhwb3J0IFNWRyBFeHRlbnNpb24gYnkgQWFyb24gQmVhbGwgKGh0dHA6Ly9maXJld29ya3MuYWJlYWxsLmNvbSkgLiBWZXJzaW9uOiAwLjYuMSAgLS0+DTwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DTxzdmcgaWQ9IlVudGl0bGVkLVBhZ2UlMjAxIiB2aWV3Qm94PSIwIDAgNiA2IiBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjojZmZmZmZmMDAiIHZlcnNpb249IjEuMSINCXhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbDpzcGFjZT0icHJlc2VydmUiDQl4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjZweCIgaGVpZ2h0PSI2cHgiDT4NCTxnIG9wYWNpdHk9IjAuMzAyIj4NCQk8cGF0aCBkPSJNIDYgNiBMIDAgNiBMIDAgNC4yIEwgNCA0LjIgTCA0LjIgNC4yIEwgNC4yIDAgTCA2IDAgTCA2IDYgTCA2IDYgWiIgZmlsbD0iIzAwMDAwMCIvPg0JPC9nPg08L3N2Zz4=\\\");background-position:100% 100%;padding:0 3px 3px 0;background-repeat:no-repeat;background-origin:content-box;box-sizing:border-box;cursor:se-resize}.vue-grid-item>.vue-rtl-resizable-handle{bottom:0;left:0;background:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAuMDAwMDAwMDAwMDAwMDAyIiBoZWlnaHQ9IjEwLjAwMDAwMDAwMDAwMDAwMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KIDwhLS0gQ3JlYXRlZCB3aXRoIE1ldGhvZCBEcmF3IC0gaHR0cDovL2dpdGh1Yi5jb20vZHVvcGl4ZWwvTWV0aG9kLURyYXcvIC0tPgogPGc+CiAgPHRpdGxlPmJhY2tncm91bmQ8L3RpdGxlPgogIDxyZWN0IGZpbGw9Im5vbmUiIGlkPSJjYW52YXNfYmFja2dyb3VuZCIgaGVpZ2h0PSIxMiIgd2lkdGg9IjEyIiB5PSItMSIgeD0iLTEiLz4KICA8ZyBkaXNwbGF5PSJub25lIiBvdmVyZmxvdz0idmlzaWJsZSIgeT0iMCIgeD0iMCIgaGVpZ2h0PSIxMDAlIiB3aWR0aD0iMTAwJSIgaWQ9ImNhbnZhc0dyaWQiPgogICA8cmVjdCBmaWxsPSJ1cmwoI2dyaWRwYXR0ZXJuKSIgc3Ryb2tlLXdpZHRoPSIwIiB5PSIwIiB4PSIwIiBoZWlnaHQ9IjEwMCUiIHdpZHRoPSIxMDAlIi8+CiAgPC9nPgogPC9nPgogPGc+CiAgPHRpdGxlPkxheWVyIDE8L3RpdGxlPgogIDxsaW5lIGNhbnZhcz0iI2ZmZmZmZiIgY2FudmFzLW9wYWNpdHk9IjEiIHN0cm9rZS1saW5lY2FwPSJ1bmRlZmluZWQiIHN0cm9rZS1saW5lam9pbj0idW5kZWZpbmVkIiBpZD0ic3ZnXzEiIHkyPSItNzAuMTc4NDA3IiB4Mj0iMTI0LjQ2NDE3NSIgeTE9Ii0zOC4zOTI3MzciIHgxPSIxNDQuODIxMjg5IiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlPSIjMDAwIiBmaWxsPSJub25lIi8+CiAgPGxpbmUgc3Ryb2tlPSIjNjY2NjY2IiBzdHJva2UtbGluZWNhcD0idW5kZWZpbmVkIiBzdHJva2UtbGluZWpvaW49InVuZGVmaW5lZCIgaWQ9InN2Z181IiB5Mj0iOS4xMDY5NTciIHgyPSIwLjk0NzI0NyIgeTE9Ii0wLjAxODEyOCIgeDE9IjAuOTQ3MjQ3IiBzdHJva2Utd2lkdGg9IjIiIGZpbGw9Im5vbmUiLz4KICA8bGluZSBzdHJva2UtbGluZWNhcD0idW5kZWZpbmVkIiBzdHJva2UtbGluZWpvaW49InVuZGVmaW5lZCIgaWQ9InN2Z183IiB5Mj0iOSIgeDI9IjEwLjA3MzUyOSIgeTE9IjkiIHgxPSItMC42NTU2NCIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2U9IiM2NjY2NjYiIGZpbGw9Im5vbmUiLz4KIDwvZz4KPC9zdmc+);background-position:0 100%;padding-left:3px;background-repeat:no-repeat;background-origin:content-box;cursor:sw-resize;right:auto}\", \"\"]);\n\n// exports\n\n\n/***/ },\n/* 20 */\n/***/ function(module, exports, __webpack_require__) {\n\n\"use strict\";\n/**\n * Resize detection strategy that injects objects to elements in order to detect resize events.\n * Heavily inspired by: http://www.backalleycoder.com/2013/03/18/cross-browser-event-based-element-resize-detection/\n */\n\n\"use strict\";\n\nvar browserDetector = __webpack_require__(5);\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\n if(!reporter) {\n throw new Error(\"Missing required dependency: reporter.\");\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 if(!getObject(element)) {\n throw new Error(\"Element is not detectable by this strategy.\");\n }\n\n function listenerProxy() {\n listener(element);\n }\n\n if(browserDetector.isIE(8)) {\n //IE 8 does not support object, but supports the resize event directly on elements.\n getState(element).object = {\n proxy: listenerProxy\n };\n element.attachEvent(\"onresize\", listenerProxy);\n } else {\n var object = getObject(element);\n object.contentDocument.defaultView.addEventListener(\"resize\", listenerProxy);\n }\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 var debug = options.debug;\n\n function injectObject(element, callback) {\n var OBJECT_STYLE = \"display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none; padding: 0; margin: 0; opacity: 0; z-index: -1000; pointer-events: none;\";\n\n //The target element needs to be positioned (everything except static) so the absolute positioned object will be positioned relative to the target element.\n\n // Position altering may be performed directly or on object load, depending on if style resolution is possible directly or not.\n var positionCheckPerformed = false;\n\n // The element may not yet be attached to the DOM, and therefore the style object may be empty in some browsers.\n // Since the style object is a reference, it will be updated as soon as the element is attached to the DOM.\n var style = window.getComputedStyle(element);\n var width = element.offsetWidth;\n var height = element.offsetHeight;\n\n getState(element).startSize = {\n width: width,\n height: height\n };\n\n function mutateDom() {\n function alterPositionStyles() {\n if(style.position === \"static\") {\n element.style.position = \"relative\";\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 onObjectLoad() {\n // The object has been loaded, which means that the element now is guaranteed to be attached to the DOM.\n if (!positionCheckPerformed) {\n alterPositionStyles();\n }\n\n /*jshint validthis: true */\n\n function getDocument(element, callback) {\n //Opera 12 seem to call the object.onload before the actual document has been created.\n //So if it is not present, poll it with an timeout until it is present.\n //TODO: Could maybe be handled better with object.onreadystatechange or similar.\n if(!element.contentDocument) {\n setTimeout(function checkForObjectDocument() {\n getDocument(element, callback);\n }, 100);\n\n return;\n }\n\n callback(element.contentDocument);\n }\n\n //Mutating the object element here seems to fire another load event.\n //Mutating the inner document of the object element is fine though.\n var objectElement = this;\n\n //Create the style element to be added to the object.\n getDocument(objectElement, function onObjectDocumentReady(objectDocument) {\n //Notify that the element is ready to be listened to.\n callback(element);\n });\n }\n\n // The element may be detached from the DOM, and some browsers does not support style resolving of detached elements.\n // The alterPositionStyles needs to be delayed until we know the element has been attached to the DOM (which we are sure of when the onObjectLoad has been fired), if style resolution is not possible.\n if (style.position !== \"\") {\n alterPositionStyles(style);\n positionCheckPerformed = true;\n }\n\n //Add an object element as a child to the target element that will be listened to for resize events.\n var object = document.createElement(\"object\");\n object.style.cssText = OBJECT_STYLE;\n object.tabIndex = -1;\n object.type = \"text/html\";\n object.onload = onObjectLoad;\n\n //Safari: This must occur before adding the object to the DOM.\n //IE: Does not like that this happens before, even if it is also added after.\n if(!browserDetector.isIE()) {\n object.data = \"about:blank\";\n }\n\n element.appendChild(object);\n getState(element).object = object;\n\n //IE: This must occur after adding the object to the DOM.\n if(browserDetector.isIE()) {\n object.data = \"about:blank\";\n }\n }\n\n if(batchProcessor) {\n batchProcessor.add(mutateDom);\n } else {\n mutateDom();\n }\n }\n\n if(browserDetector.isIE(8)) {\n //IE 8 does not support objects properly. Luckily they do support the resize event.\n //So do not inject the object and notify that the element is already ready to be listened to.\n //The event handler for the resize event is attached in the utils.addListener instead.\n callback(element);\n } else {\n injectObject(element, callback);\n }\n }\n\n /**\n * Returns the child object of the target element.\n * @private\n * @param {element} element The target element.\n * @returns The object element of the target.\n */\n function getObject(element) {\n return getState(element).object;\n }\n\n function uninstall(element) {\n if(browserDetector.isIE(8)) {\n element.detachEvent(\"onresize\", getState(element).object.proxy);\n } else {\n element.removeChild(getObject(element));\n }\n delete getState(element).object;\n }\n\n return {\n makeDetectable: makeDetectable,\n addListener: addListener,\n uninstall: uninstall\n };\n};\n\n\n/***/ },\n/* 21 */\n/***/ function(module, exports, __webpack_require__) {\n\n\"use strict\";\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 = __webpack_require__(6).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 // 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 var styleId = \"erd_scroll_detection_scrollbar_style\";\n var detectionContainerClass = \"erd_scroll_detection_container\";\n injectScrollStyle(styleId, detectionContainerClass);\n\n function getScrollbarSizes() {\n var width = 500;\n var height = 500;\n\n var child = document.createElement(\"div\");\n child.style.cssText = \"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 = \"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(styleId, containerClass) {\n function injectStyle(style, method) {\n method = method || function (element) {\n document.head.appendChild(element);\n };\n\n var styleElement = document.createElement(\"style\");\n styleElement.innerHTML = style;\n styleElement.id = styleId;\n method(styleElement);\n return styleElement;\n }\n\n if (!document.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 { display: none; }\\n\\n\";\n style += \".\" + containerAnimationActiveClass + \" { -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 return element === element.ownerDocument.body || element.ownerDocument.body.contains(element);\n }\n return !isInDocument(element);\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 return getComputedStyle(container).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 = 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 = \"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.position = \"relative\";\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 = \"position: absolute; flex: none; overflow: hidden; z-index: -1; visibility: hidden; width: 100%; height: 100%; left: 0px; top: 0px;\";\n var containerStyle = \"position: absolute; flex: none; overflow: hidden; z-index: -1; visibility: hidden; \" + getLeftTopBottomRightCssText(-(1 + scrollbarWidth), -(1 + scrollbarHeight), -scrollbarHeight, -scrollbarWidth);\n var expandStyle = \"position: absolute; flex: none; overflow: scroll; z-index: -1; visibility: hidden; width: 100%; height: 100%;\";\n var shrinkStyle = \"position: absolute; flex: none; overflow: scroll; z-index: -1; visibility: hidden; width: 100%; height: 100%;\";\n var expandChildStyle = \"position: absolute; left: 0; top: 0;\";\n var shrinkChildStyle = \"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 getState(element).onExpand && getState(element).onExpand();\n }\n\n function onShrinkScroll() {\n getState(element).onShrink && getState(element).onShrink();\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.width = expandWidth + \"px\";\n expandChild.style.height = expandHeight + \"px\";\n }\n\n function updateDetectorElements(done) {\n var width = element.offsetWidth;\n var height = element.offsetHeight;\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 (!getState(element)) {\n debug(\"Aborting because element has been uninstalled\");\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 if (!getState(element)) {\n debug(\"Aborting because element has been uninstalled\");\n return;\n }\n\n positionScrollbars(element, width, height);\n });\n\n if (done) {\n batchProcessor.add(2, function () {\n if (!getState(element)) {\n debug(\"Aborting because element has been uninstalled\");\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 the 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 var width = element.offsetWidth;\n var height = element.offsetHeight;\n\n if (width !== element.lastWidth || height !== element.lastHeight) {\n debug(\"Element size changed.\");\n updateDetectorElements(notifyListenersIfNeeded);\n } else {\n debug(\"Element size has not changed (\" + width + \"x\" + height + \").\");\n }\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 };\n};\n\n\n/***/ },\n/* 22 */\n/***/ function(module, exports) {\n\n\"use strict\";\n\"use strict\";\n\nmodule.exports = function(options) {\n var getState = options.stateHandler.getState;\n\n /**\n * Tells if the element has been made detectable and ready to be listened for resize events.\n * @public\n * @param {element} The element to check.\n * @returns {boolean} True or false depending on if the element is detectable or not.\n */\n function isDetectable(element) {\n var state = getState(element);\n return state && !!state.isDetectable;\n }\n\n /**\n * Marks the element that it has been made detectable and ready to be listened for resize events.\n * @public\n * @param {element} The element to mark.\n */\n function markAsDetectable(element) {\n getState(element).isDetectable = true;\n }\n\n /**\n * Tells if the element is busy or not.\n * @public\n * @param {element} The element to check.\n * @returns {boolean} True or false depending on if the element is busy or not.\n */\n function isBusy(element) {\n return !!getState(element).busy;\n }\n\n /**\n * Marks the object is busy and should not be made detectable.\n * @public\n * @param {element} element The element to mark.\n * @param {boolean} busy If the element is busy or not.\n */\n function markBusy(element, busy) {\n getState(element).busy = !!busy;\n }\n\n return {\n isDetectable: isDetectable,\n markAsDetectable: markAsDetectable,\n isBusy: isBusy,\n markBusy: markBusy\n };\n};\n\n\n/***/ },\n/* 23 */\n/***/ function(module, exports) {\n\n\"use strict\";\n\"use strict\";\n\nmodule.exports = function() {\n var idCount = 1;\n\n /**\n * Generates a new unique id in the context.\n * @public\n * @returns {number} A unique id in the context.\n */\n function generate() {\n return idCount++;\n }\n\n return {\n generate: generate\n };\n};\n\n\n/***/ },\n/* 24 */\n/***/ function(module, exports) {\n\n\"use strict\";\n\"use strict\";\n\nmodule.exports = function(options) {\n var idGenerator = options.idGenerator;\n var getState = options.stateHandler.getState;\n\n /**\n * Gets the resize detector id of the element.\n * @public\n * @param {element} element The target element to get the id of.\n * @returns {string|number|null} The id of the element. Null if it has no id.\n */\n function getId(element) {\n var state = getState(element);\n\n if (state && state.id !== undefined) {\n return state.id;\n }\n\n return null;\n }\n\n /**\n * Sets the resize detector id of the element. Requires the element to have a resize detector state initialized.\n * @public\n * @param {element} element The target element to set the id of.\n * @returns {string|number|null} The id of the element.\n */\n function setId(element) {\n var state = getState(element);\n\n if (!state) {\n throw new Error(\"setId required the element to have a resize detection state.\");\n }\n\n var id = idGenerator.generate();\n\n state.id = id;\n\n return id;\n }\n\n return {\n get: getId,\n set: setId\n };\n};\n\n\n/***/ },\n/* 25 */\n/***/ function(module, exports) {\n\n\"use strict\";\n\"use strict\";\n\nmodule.exports = function(idHandler) {\n var eventListeners = {};\n\n /**\n * Gets all listeners for the given element.\n * @public\n * @param {element} element The element to get all listeners for.\n * @returns All listeners for the given element.\n */\n function getListeners(element) {\n var id = idHandler.get(element);\n\n if (id === undefined) {\n return [];\n }\n\n return eventListeners[id] || [];\n }\n\n /**\n * Stores the given listener for the given element. Will not actually add the listener to the element.\n * @public\n * @param {element} element The element that should have the listener added.\n * @param {function} listener The callback that the element has added.\n */\n function addListener(element, listener) {\n var id = idHandler.get(element);\n\n if(!eventListeners[id]) {\n eventListeners[id] = [];\n }\n\n eventListeners[id].push(listener);\n }\n\n function removeListener(element, listener) {\n var listeners = getListeners(element);\n for (var i = 0, len = listeners.length; i < len; ++i) {\n if (listeners[i] === listener) {\n listeners.splice(i, 1);\n break;\n }\n }\n }\n\n function removeAllListeners(element) {\n var listeners = getListeners(element);\n if (!listeners) { return; }\n listeners.length = 0;\n }\n\n return {\n get: getListeners,\n add: addListener,\n removeListener: removeListener,\n removeAllListeners: removeAllListeners\n };\n};\n\n\n/***/ },\n/* 26 */\n/***/ function(module, exports) {\n\n\"use strict\";\n\"use strict\";\n\n/* global console: false */\n\n/**\n * Reporter that handles the reporting of logs, warnings and errors.\n * @public\n * @param {boolean} quiet Tells if the reporter should be quiet or not.\n */\nmodule.exports = function(quiet) {\n function noop() {\n //Does nothing.\n }\n\n var reporter = {\n log: noop,\n warn: noop,\n error: noop\n };\n\n if(!quiet && window.console) {\n var attachFunction = function(reporter, name) {\n //The proxy is needed to be able to call the method with the console context,\n //since we cannot use bind.\n reporter[name] = function reporterProxy() {\n var f = console[name];\n if (f.apply) { //IE9 does not support console.log.apply :)\n f.apply(console, arguments);\n } else {\n for (var i = 0; i < arguments.length; i++) {\n f(arguments[i]);\n }\n }\n };\n };\n\n attachFunction(reporter, \"log\");\n attachFunction(reporter, \"warn\");\n attachFunction(reporter, \"error\");\n }\n\n return reporter;\n};\n\n/***/ },\n/* 27 */\n/***/ function(module, exports) {\n\n\"use strict\";\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\n\n/***/ },\n/* 28 */\n/***/ function(module, exports, __webpack_require__) {\n\n/**\n * interact.js v1.2.8\n *\n * Copyright (c) 2012-2015 Taye Adeyemi \n * Open source under the MIT License.\n * https://raw.github.com/taye/interact.js/master/LICENSE\n */\n(function (realWindow) {\n 'use strict';\n\n // return early if there's no window to work with (eg. Node.js)\n if (!realWindow) { return; }\n\n var // get wrapped window if using Shadow DOM polyfill\n window = (function () {\n // create a TextNode\n var el = realWindow.document.createTextNode('');\n\n // check if it's wrapped by a polyfill\n if (el.ownerDocument !== realWindow.document\n && typeof realWindow.wrap === 'function'\n && realWindow.wrap(el) === el) {\n // return wrapped window\n return realWindow.wrap(realWindow);\n }\n\n // no Shadow DOM polyfil or native implementation\n return realWindow;\n }()),\n\n document = window.document,\n DocumentFragment = window.DocumentFragment || blank,\n SVGElement = window.SVGElement || blank,\n SVGSVGElement = window.SVGSVGElement || blank,\n SVGElementInstance = window.SVGElementInstance || blank,\n HTMLElement = window.HTMLElement || window.Element,\n\n PointerEvent = (window.PointerEvent || window.MSPointerEvent),\n pEventTypes,\n\n hypot = Math.hypot || function (x, y) { return Math.sqrt(x * x + y * y); },\n\n tmpXY = {}, // reduce object creation in getXY()\n\n documents = [], // all documents being listened to\n\n interactables = [], // all set interactables\n interactions = [], // all interactions\n\n dynamicDrop = false,\n\n // {\n // type: {\n // selectors: ['selector', ...],\n // contexts : [document, ...],\n // listeners: [[listener, useCapture], ...]\n // }\n // }\n delegatedEvents = {},\n\n defaultOptions = {\n base: {\n accept : null,\n actionChecker : null,\n styleCursor : true,\n preventDefault: 'auto',\n origin : { x: 0, y: 0 },\n deltaSource : 'page',\n allowFrom : null,\n ignoreFrom : null,\n _context : document,\n dropChecker : null\n },\n\n drag: {\n enabled: false,\n manualStart: true,\n max: Infinity,\n maxPerElement: 1,\n\n snap: null,\n restrict: null,\n inertia: null,\n autoScroll: null,\n\n axis: 'xy'\n },\n\n drop: {\n enabled: false,\n accept: null,\n overlap: 'pointer'\n },\n\n resize: {\n enabled: false,\n manualStart: false,\n max: Infinity,\n maxPerElement: 1,\n\n snap: null,\n restrict: null,\n inertia: null,\n autoScroll: null,\n\n square: false,\n preserveAspectRatio: false,\n axis: 'xy',\n\n // use default margin\n margin: NaN,\n\n // object with props left, right, top, bottom which are\n // true/false values to resize when the pointer is over that edge,\n // CSS selectors to match the handles for each direction\n // or the Elements for each handle\n edges: null,\n\n // a value of 'none' will limit the resize rect to a minimum of 0x0\n // 'negate' will alow the rect to have negative width/height\n // 'reposition' will keep the width/height positive by swapping\n // the top and bottom edges and/or swapping the left and right edges\n invert: 'none'\n },\n\n gesture: {\n manualStart: false,\n enabled: false,\n max: Infinity,\n maxPerElement: 1,\n\n restrict: null\n },\n\n perAction: {\n manualStart: false,\n max: Infinity,\n maxPerElement: 1,\n\n snap: {\n enabled : false,\n endOnly : false,\n range : Infinity,\n targets : null,\n offsets : null,\n\n relativePoints: null\n },\n\n restrict: {\n enabled: false,\n endOnly: false\n },\n\n autoScroll: {\n enabled : false,\n container : null, // the item that is scrolled (Window or HTMLElement)\n margin : 60,\n speed : 300 // the scroll speed in pixels per second\n },\n\n inertia: {\n enabled : false,\n resistance : 10, // the lambda in exponential decay\n minSpeed : 100, // target speed must be above this for inertia to start\n endSpeed : 10, // the speed at which inertia is slow enough to stop\n allowResume : true, // allow resuming an action in inertia phase\n zeroResumeDelta : true, // if an action is resumed after launch, set dx/dy to 0\n smoothEndDuration: 300 // animate to snap/restrict endOnly if there's no inertia\n }\n },\n\n _holdDuration: 600\n },\n\n // Things related to autoScroll\n autoScroll = {\n interaction: null,\n i: null, // the handle returned by window.setInterval\n x: 0, y: 0, // Direction each pulse is to scroll in\n\n // scroll the window by the values in scroll.x/y\n scroll: function () {\n var options = autoScroll.interaction.target.options[autoScroll.interaction.prepared.name].autoScroll,\n container = options.container || getWindow(autoScroll.interaction.element),\n now = new Date().getTime(),\n // change in time in seconds\n dtx = (now - autoScroll.prevTimeX) / 1000,\n dty = (now - autoScroll.prevTimeY) / 1000,\n vx, vy, sx, sy;\n\n // displacement\n if (options.velocity) {\n vx = options.velocity.x;\n vy = options.velocity.y;\n }\n else {\n vx = vy = options.speed\n }\n \n sx = vx * dtx;\n sy = vy * dty;\n\n if (sx >= 1 || sy >= 1) {\n if (isWindow(container)) {\n container.scrollBy(autoScroll.x * sx, autoScroll.y * sy);\n }\n else if (container) {\n container.scrollLeft += autoScroll.x * sx;\n container.scrollTop += autoScroll.y * sy;\n }\n\n if (sx >=1) autoScroll.prevTimeX = now;\n if (sy >= 1) autoScroll.prevTimeY = now;\n }\n\n if (autoScroll.isScrolling) {\n cancelFrame(autoScroll.i);\n autoScroll.i = reqFrame(autoScroll.scroll);\n }\n },\n\n isScrolling: false,\n prevTimeX: 0,\n prevTimeY: 0,\n\n start: function (interaction) {\n autoScroll.isScrolling = true;\n cancelFrame(autoScroll.i);\n\n autoScroll.interaction = interaction;\n autoScroll.prevTimeX = new Date().getTime();\n autoScroll.prevTimeY = new Date().getTime();\n autoScroll.i = reqFrame(autoScroll.scroll);\n },\n\n stop: function () {\n autoScroll.isScrolling = false;\n cancelFrame(autoScroll.i);\n }\n },\n\n // Does the browser support touch input?\n supportsTouch = (('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch),\n\n // Does the browser support PointerEvents\n // Avoid PointerEvent bugs introduced in Chrome 55\n supportsPointerEvent = PointerEvent && !/Chrome/.test(navigator.userAgent),\n\n // Less Precision with touch input\n margin = supportsTouch || supportsPointerEvent? 20: 10,\n\n pointerMoveTolerance = 1,\n\n // for ignoring browser's simulated mouse events\n prevTouchTime = 0,\n\n // Allow this many interactions to happen simultaneously\n maxInteractions = Infinity,\n\n // Check if is IE9 or older\n actionCursors = (document.all && !window.atob) ? {\n drag : 'move',\n resizex : 'e-resize',\n resizey : 's-resize',\n resizexy: 'se-resize',\n\n resizetop : 'n-resize',\n resizeleft : 'w-resize',\n resizebottom : 's-resize',\n resizeright : 'e-resize',\n resizetopleft : 'se-resize',\n resizebottomright: 'se-resize',\n resizetopright : 'ne-resize',\n resizebottomleft : 'ne-resize',\n\n gesture : ''\n } : {\n drag : 'move',\n resizex : 'ew-resize',\n resizey : 'ns-resize',\n resizexy: 'nwse-resize',\n\n resizetop : 'ns-resize',\n resizeleft : 'ew-resize',\n resizebottom : 'ns-resize',\n resizeright : 'ew-resize',\n resizetopleft : 'nwse-resize',\n resizebottomright: 'nwse-resize',\n resizetopright : 'nesw-resize',\n resizebottomleft : 'nesw-resize',\n\n gesture : ''\n },\n\n actionIsEnabled = {\n drag : true,\n resize : true,\n gesture: true\n },\n\n // because Webkit and Opera still use 'mousewheel' event type\n wheelEvent = 'onmousewheel' in document? 'mousewheel': 'wheel',\n\n eventTypes = [\n 'dragstart',\n 'dragmove',\n 'draginertiastart',\n 'dragend',\n 'dragenter',\n 'dragleave',\n 'dropactivate',\n 'dropdeactivate',\n 'dropmove',\n 'drop',\n 'resizestart',\n 'resizemove',\n 'resizeinertiastart',\n 'resizeend',\n 'gesturestart',\n 'gesturemove',\n 'gestureinertiastart',\n 'gestureend',\n\n 'down',\n 'move',\n 'up',\n 'cancel',\n 'tap',\n 'doubletap',\n 'hold'\n ],\n\n globalEvents = {},\n\n // Opera Mobile must be handled differently\n isOperaMobile = navigator.appName == 'Opera' &&\n supportsTouch &&\n navigator.userAgent.match('Presto'),\n\n // scrolling doesn't change the result of getClientRects on iOS 7\n isIOS7 = (/iP(hone|od|ad)/.test(navigator.platform)\n && /OS 7[^\\d]/.test(navigator.appVersion)),\n\n // prefix matchesSelector\n prefixedMatchesSelector = 'matches' in Element.prototype?\n 'matches': 'webkitMatchesSelector' in Element.prototype?\n 'webkitMatchesSelector': 'mozMatchesSelector' in Element.prototype?\n 'mozMatchesSelector': 'oMatchesSelector' in Element.prototype?\n 'oMatchesSelector': 'msMatchesSelector',\n\n // will be polyfill function if browser is IE8\n ie8MatchesSelector,\n\n // native requestAnimationFrame or polyfill\n reqFrame = realWindow.requestAnimationFrame,\n cancelFrame = realWindow.cancelAnimationFrame,\n\n // Events wrapper\n events = (function () {\n var useAttachEvent = ('attachEvent' in window) && !('addEventListener' in window),\n addEvent = useAttachEvent? 'attachEvent': 'addEventListener',\n removeEvent = useAttachEvent? 'detachEvent': 'removeEventListener',\n on = useAttachEvent? 'on': '',\n\n elements = [],\n targets = [],\n attachedListeners = [];\n\n function add (element, type, listener, useCapture) {\n var elementIndex = indexOf(elements, element),\n target = targets[elementIndex];\n\n if (!target) {\n target = {\n events: {},\n typeCount: 0\n };\n\n elementIndex = elements.push(element) - 1;\n targets.push(target);\n\n attachedListeners.push((useAttachEvent ? {\n supplied: [],\n wrapped : [],\n useCount: []\n } : null));\n }\n\n if (!target.events[type]) {\n target.events[type] = [];\n target.typeCount++;\n }\n\n if (!contains(target.events[type], listener)) {\n var ret;\n\n if (useAttachEvent) {\n var listeners = attachedListeners[elementIndex],\n listenerIndex = indexOf(listeners.supplied, listener);\n\n var wrapped = listeners.wrapped[listenerIndex] || function (event) {\n if (!event.immediatePropagationStopped) {\n event.target = event.srcElement;\n event.currentTarget = element;\n\n event.preventDefault = event.preventDefault || preventDef;\n event.stopPropagation = event.stopPropagation || stopProp;\n event.stopImmediatePropagation = event.stopImmediatePropagation || stopImmProp;\n\n if (/mouse|click/.test(event.type)) {\n event.pageX = event.clientX + getWindow(element).document.documentElement.scrollLeft;\n event.pageY = event.clientY + getWindow(element).document.documentElement.scrollTop;\n }\n\n listener(event);\n }\n };\n\n ret = element[addEvent](on + type, wrapped, Boolean(useCapture));\n\n if (listenerIndex === -1) {\n listeners.supplied.push(listener);\n listeners.wrapped.push(wrapped);\n listeners.useCount.push(1);\n }\n else {\n listeners.useCount[listenerIndex]++;\n }\n }\n else {\n ret = element[addEvent](type, listener, useCapture || false);\n }\n target.events[type].push(listener);\n\n return ret;\n }\n }\n\n function remove (element, type, listener, useCapture) {\n var i,\n elementIndex = indexOf(elements, element),\n target = targets[elementIndex],\n listeners,\n listenerIndex,\n wrapped = listener;\n\n if (!target || !target.events) {\n return;\n }\n\n if (useAttachEvent) {\n listeners = attachedListeners[elementIndex];\n listenerIndex = indexOf(listeners.supplied, listener);\n wrapped = listeners.wrapped[listenerIndex];\n }\n\n if (type === 'all') {\n for (type in target.events) {\n if (target.events.hasOwnProperty(type)) {\n remove(element, type, 'all');\n }\n }\n return;\n }\n\n if (target.events[type]) {\n var len = target.events[type].length;\n\n if (listener === 'all') {\n for (i = 0; i < len; i++) {\n remove(element, type, target.events[type][i], Boolean(useCapture));\n }\n return;\n } else {\n for (i = 0; i < len; i++) {\n if (target.events[type][i] === listener) {\n element[removeEvent](on + type, wrapped, useCapture || false);\n target.events[type].splice(i, 1);\n\n if (useAttachEvent && listeners) {\n listeners.useCount[listenerIndex]--;\n if (listeners.useCount[listenerIndex] === 0) {\n listeners.supplied.splice(listenerIndex, 1);\n listeners.wrapped.splice(listenerIndex, 1);\n listeners.useCount.splice(listenerIndex, 1);\n }\n }\n\n break;\n }\n }\n }\n\n if (target.events[type] && target.events[type].length === 0) {\n target.events[type] = null;\n target.typeCount--;\n }\n }\n\n if (!target.typeCount) {\n targets.splice(elementIndex, 1);\n elements.splice(elementIndex, 1);\n attachedListeners.splice(elementIndex, 1);\n }\n }\n\n function preventDef () {\n this.returnValue = false;\n }\n\n function stopProp () {\n this.cancelBubble = true;\n }\n\n function stopImmProp () {\n this.cancelBubble = true;\n this.immediatePropagationStopped = true;\n }\n\n return {\n add: add,\n remove: remove,\n useAttachEvent: useAttachEvent,\n\n _elements: elements,\n _targets: targets,\n _attachedListeners: attachedListeners\n };\n }());\n\n function blank () {}\n\n function isElement (o) {\n if (!o || (typeof o !== 'object')) { return false; }\n\n var _window = getWindow(o) || window;\n\n return (/object|function/.test(typeof _window.Element)\n ? o instanceof _window.Element //DOM2\n : o.nodeType === 1 && typeof o.nodeName === \"string\");\n }\n function isWindow (thing) { return thing === window || !!(thing && thing.Window) && (thing instanceof thing.Window); }\n function isDocFrag (thing) { return !!thing && thing instanceof DocumentFragment; }\n function isArray (thing) {\n return isObject(thing)\n && (typeof thing.length !== undefined)\n && isFunction(thing.splice);\n }\n function isObject (thing) { return !!thing && (typeof thing === 'object'); }\n function isFunction (thing) { return typeof thing === 'function'; }\n function isNumber (thing) { return typeof thing === 'number' ; }\n function isBool (thing) { return typeof thing === 'boolean' ; }\n function isString (thing) { return typeof thing === 'string' ; }\n\n function trySelector (value) {\n if (!isString(value)) { return false; }\n\n // an exception will be raised if it is invalid\n document.querySelector(value);\n return true;\n }\n\n function extend (dest, source) {\n for (var prop in source) {\n dest[prop] = source[prop];\n }\n return dest;\n }\n\n var prefixedPropREs = {\n webkit: /(Movement[XY]|Radius[XY]|RotationAngle|Force)$/\n };\n\n function pointerExtend (dest, source) {\n for (var prop in source) {\n var deprecated = false;\n\n // skip deprecated prefixed properties\n for (var vendor in prefixedPropREs) {\n if (prop.indexOf(vendor) === 0 && prefixedPropREs[vendor].test(prop)) {\n deprecated = true;\n break;\n }\n }\n\n if (!deprecated) {\n dest[prop] = source[prop];\n }\n }\n return dest;\n }\n\n function copyCoords (dest, src) {\n dest.page = dest.page || {};\n dest.page.x = src.page.x;\n dest.page.y = src.page.y;\n\n dest.client = dest.client || {};\n dest.client.x = src.client.x;\n dest.client.y = src.client.y;\n\n dest.timeStamp = src.timeStamp;\n }\n\n function setEventXY (targetObj, pointers, interaction) {\n var pointer = (pointers.length > 1\n ? pointerAverage(pointers)\n : pointers[0]);\n\n getPageXY(pointer, tmpXY, interaction);\n targetObj.page.x = tmpXY.x;\n targetObj.page.y = tmpXY.y;\n\n getClientXY(pointer, tmpXY, interaction);\n targetObj.client.x = tmpXY.x;\n targetObj.client.y = tmpXY.y;\n\n targetObj.timeStamp = new Date().getTime();\n }\n\n function setEventDeltas (targetObj, prev, cur) {\n targetObj.page.x = cur.page.x - prev.page.x;\n targetObj.page.y = cur.page.y - prev.page.y;\n targetObj.client.x = cur.client.x - prev.client.x;\n targetObj.client.y = cur.client.y - prev.client.y;\n targetObj.timeStamp = new Date().getTime() - prev.timeStamp;\n\n // set pointer velocity\n var dt = Math.max(targetObj.timeStamp / 1000, 0.001);\n targetObj.page.speed = hypot(targetObj.page.x, targetObj.page.y) / dt;\n targetObj.page.vx = targetObj.page.x / dt;\n targetObj.page.vy = targetObj.page.y / dt;\n\n targetObj.client.speed = hypot(targetObj.client.x, targetObj.page.y) / dt;\n targetObj.client.vx = targetObj.client.x / dt;\n targetObj.client.vy = targetObj.client.y / dt;\n }\n\n function isNativePointer (pointer) {\n return (pointer instanceof window.Event\n || (supportsTouch && window.Touch && pointer instanceof window.Touch));\n }\n\n // Get specified X/Y coords for mouse or event.touches[0]\n function getXY (type, pointer, xy) {\n xy = xy || {};\n type = type || 'page';\n\n xy.x = pointer[type + 'X'];\n xy.y = pointer[type + 'Y'];\n\n return xy;\n }\n\n function getPageXY (pointer, page) {\n page = page || {};\n\n // Opera Mobile handles the viewport and scrolling oddly\n if (isOperaMobile && isNativePointer(pointer)) {\n getXY('screen', pointer, page);\n\n page.x += window.scrollX;\n page.y += window.scrollY;\n }\n else {\n getXY('page', pointer, page);\n }\n\n return page;\n }\n\n function getClientXY (pointer, client) {\n client = client || {};\n\n if (isOperaMobile && isNativePointer(pointer)) {\n // Opera Mobile handles the viewport and scrolling oddly\n getXY('screen', pointer, client);\n }\n else {\n getXY('client', pointer, client);\n }\n\n return client;\n }\n\n function getScrollXY (win) {\n win = win || window;\n return {\n x: win.scrollX || win.document.documentElement.scrollLeft,\n y: win.scrollY || win.document.documentElement.scrollTop\n };\n }\n\n function getPointerId (pointer) {\n return isNumber(pointer.pointerId)? pointer.pointerId : pointer.identifier;\n }\n\n function getActualElement (element) {\n return (element instanceof SVGElementInstance\n ? element.correspondingUseElement\n : element);\n }\n\n function getWindow (node) {\n if (isWindow(node)) {\n return node;\n }\n\n var rootNode = (node.ownerDocument || node);\n\n return rootNode.defaultView || rootNode.parentWindow || window;\n }\n\n function getElementClientRect (element) {\n var clientRect = (element instanceof SVGElement\n ? element.getBoundingClientRect()\n : element.getClientRects()[0]);\n\n return clientRect && {\n left : clientRect.left,\n right : clientRect.right,\n top : clientRect.top,\n bottom: clientRect.bottom,\n width : clientRect.width || clientRect.right - clientRect.left,\n height: clientRect.height || clientRect.bottom - clientRect.top\n };\n }\n\n function getElementRect (element) {\n var clientRect = getElementClientRect(element);\n\n if (!isIOS7 && clientRect) {\n var scroll = getScrollXY(getWindow(element));\n\n clientRect.left += scroll.x;\n clientRect.right += scroll.x;\n clientRect.top += scroll.y;\n clientRect.bottom += scroll.y;\n }\n\n return clientRect;\n }\n\n function getTouchPair (event) {\n var touches = [];\n\n // array of touches is supplied\n if (isArray(event)) {\n touches[0] = event[0];\n touches[1] = event[1];\n }\n // an event\n else {\n if (event.type === 'touchend') {\n if (event.touches.length === 1) {\n touches[0] = event.touches[0];\n touches[1] = event.changedTouches[0];\n }\n else if (event.touches.length === 0) {\n touches[0] = event.changedTouches[0];\n touches[1] = event.changedTouches[1];\n }\n }\n else {\n touches[0] = event.touches[0];\n touches[1] = event.touches[1];\n }\n }\n\n return touches;\n }\n\n function pointerAverage (pointers) {\n var average = {\n pageX : 0,\n pageY : 0,\n clientX: 0,\n clientY: 0,\n screenX: 0,\n screenY: 0\n };\n var prop;\n\n for (var i = 0; i < pointers.length; i++) {\n for (prop in average) {\n average[prop] += pointers[i][prop];\n }\n }\n for (prop in average) {\n average[prop] /= pointers.length;\n }\n\n return average;\n }\n\n function touchBBox (event) {\n if (!event.length && !(event.touches && event.touches.length > 1)) {\n return;\n }\n\n var touches = getTouchPair(event),\n minX = Math.min(touches[0].pageX, touches[1].pageX),\n minY = Math.min(touches[0].pageY, touches[1].pageY),\n maxX = Math.max(touches[0].pageX, touches[1].pageX),\n maxY = Math.max(touches[0].pageY, touches[1].pageY);\n\n return {\n x: minX,\n y: minY,\n left: minX,\n top: minY,\n width: maxX - minX,\n height: maxY - minY\n };\n }\n\n function touchDistance (event, deltaSource) {\n deltaSource = deltaSource || defaultOptions.deltaSource;\n\n var sourceX = deltaSource + 'X',\n sourceY = deltaSource + 'Y',\n touches = getTouchPair(event);\n\n\n var dx = touches[0][sourceX] - touches[1][sourceX],\n dy = touches[0][sourceY] - touches[1][sourceY];\n\n return hypot(dx, dy);\n }\n\n function touchAngle (event, prevAngle, deltaSource) {\n deltaSource = deltaSource || defaultOptions.deltaSource;\n\n var sourceX = deltaSource + 'X',\n sourceY = deltaSource + 'Y',\n touches = getTouchPair(event),\n dx = touches[0][sourceX] - touches[1][sourceX],\n dy = touches[0][sourceY] - touches[1][sourceY],\n angle = 180 * Math.atan(dy / dx) / Math.PI;\n\n if (isNumber(prevAngle)) {\n var dr = angle - prevAngle,\n drClamped = dr % 360;\n\n if (drClamped > 315) {\n angle -= 360 + (angle / 360)|0 * 360;\n }\n else if (drClamped > 135) {\n angle -= 180 + (angle / 360)|0 * 360;\n }\n else if (drClamped < -315) {\n angle += 360 + (angle / 360)|0 * 360;\n }\n else if (drClamped < -135) {\n angle += 180 + (angle / 360)|0 * 360;\n }\n }\n\n return angle;\n }\n\n function getOriginXY (interactable, element) {\n var origin = interactable\n ? interactable.options.origin\n : defaultOptions.origin;\n\n if (origin === 'parent') {\n origin = parentElement(element);\n }\n else if (origin === 'self') {\n origin = interactable.getRect(element);\n }\n else if (trySelector(origin)) {\n origin = closest(element, origin) || { x: 0, y: 0 };\n }\n\n if (isFunction(origin)) {\n origin = origin(interactable && element);\n }\n\n if (isElement(origin)) {\n origin = getElementRect(origin);\n }\n\n origin.x = ('x' in origin)? origin.x : origin.left;\n origin.y = ('y' in origin)? origin.y : origin.top;\n\n return origin;\n }\n\n // http://stackoverflow.com/a/5634528/2280888\n function _getQBezierValue(t, p1, p2, p3) {\n var iT = 1 - t;\n return iT * iT * p1 + 2 * iT * t * p2 + t * t * p3;\n }\n\n function getQuadraticCurvePoint(startX, startY, cpX, cpY, endX, endY, position) {\n return {\n x: _getQBezierValue(position, startX, cpX, endX),\n y: _getQBezierValue(position, startY, cpY, endY)\n };\n }\n\n // http://gizma.com/easing/\n function easeOutQuad (t, b, c, d) {\n t /= d;\n return -c * t*(t-2) + b;\n }\n\n function nodeContains (parent, child) {\n while (child) {\n if (child === parent) {\n return true;\n }\n\n child = child.parentNode;\n }\n\n return false;\n }\n\n function closest (child, selector) {\n var parent = parentElement(child);\n\n while (isElement(parent)) {\n if (matchesSelector(parent, selector)) { return parent; }\n\n parent = parentElement(parent);\n }\n\n return null;\n }\n\n function parentElement (node) {\n var parent = node.parentNode;\n\n if (isDocFrag(parent)) {\n // skip past #shado-root fragments\n while ((parent = parent.host) && isDocFrag(parent)) {}\n\n return parent;\n }\n\n return parent;\n }\n\n function inContext (interactable, element) {\n return interactable._context === element.ownerDocument\n || nodeContains(interactable._context, element);\n }\n\n function testIgnore (interactable, interactableElement, element) {\n var ignoreFrom = interactable.options.ignoreFrom;\n\n if (!ignoreFrom || !isElement(element)) { return false; }\n\n if (isString(ignoreFrom)) {\n return matchesUpTo(element, ignoreFrom, interactableElement);\n }\n else if (isElement(ignoreFrom)) {\n return nodeContains(ignoreFrom, element);\n }\n\n return false;\n }\n\n function testAllow (interactable, interactableElement, element) {\n var allowFrom = interactable.options.allowFrom;\n\n if (!allowFrom) { return true; }\n\n if (!isElement(element)) { return false; }\n\n if (isString(allowFrom)) {\n return matchesUpTo(element, allowFrom, interactableElement);\n }\n else if (isElement(allowFrom)) {\n return nodeContains(allowFrom, element);\n }\n\n return false;\n }\n\n function checkAxis (axis, interactable) {\n if (!interactable) { return false; }\n\n var thisAxis = interactable.options.drag.axis;\n\n return (axis === 'xy' || thisAxis === 'xy' || thisAxis === axis);\n }\n\n function checkSnap (interactable, action) {\n var options = interactable.options;\n\n if (/^resize/.test(action)) {\n action = 'resize';\n }\n\n return options[action].snap && options[action].snap.enabled;\n }\n\n function checkRestrict (interactable, action) {\n var options = interactable.options;\n\n if (/^resize/.test(action)) {\n action = 'resize';\n }\n\n return options[action].restrict && options[action].restrict.enabled;\n }\n\n function checkAutoScroll (interactable, action) {\n var options = interactable.options;\n\n if (/^resize/.test(action)) {\n action = 'resize';\n }\n\n return options[action].autoScroll && options[action].autoScroll.enabled;\n }\n\n function withinInteractionLimit (interactable, element, action) {\n var options = interactable.options,\n maxActions = options[action.name].max,\n maxPerElement = options[action.name].maxPerElement,\n activeInteractions = 0,\n targetCount = 0,\n targetElementCount = 0;\n\n for (var i = 0, len = interactions.length; i < len; i++) {\n var interaction = interactions[i],\n otherAction = interaction.prepared.name,\n active = interaction.interacting();\n\n if (!active) { continue; }\n\n activeInteractions++;\n\n if (activeInteractions >= maxInteractions) {\n return false;\n }\n\n if (interaction.target !== interactable) { continue; }\n\n targetCount += (otherAction === action.name)|0;\n\n if (targetCount >= maxActions) {\n return false;\n }\n\n if (interaction.element === element) {\n targetElementCount++;\n\n if (otherAction !== action.name || targetElementCount >= maxPerElement) {\n return false;\n }\n }\n }\n\n return maxInteractions > 0;\n }\n\n // Test for the element that's \"above\" all other qualifiers\n function indexOfDeepestElement (elements) {\n var dropzone,\n deepestZone = elements[0],\n index = deepestZone? 0: -1,\n parent,\n deepestZoneParents = [],\n dropzoneParents = [],\n child,\n i,\n n;\n\n for (i = 1; i < elements.length; i++) {\n dropzone = elements[i];\n\n // an element might belong to multiple selector dropzones\n if (!dropzone || dropzone === deepestZone) {\n continue;\n }\n\n if (!deepestZone) {\n deepestZone = dropzone;\n index = i;\n continue;\n }\n\n // check if the deepest or current are document.documentElement or document.rootElement\n // - if the current dropzone is, do nothing and continue\n if (dropzone.parentNode === dropzone.ownerDocument) {\n continue;\n }\n // - if deepest is, update with the current dropzone and continue to next\n else if (deepestZone.parentNode === dropzone.ownerDocument) {\n deepestZone = dropzone;\n index = i;\n continue;\n }\n\n if (!deepestZoneParents.length) {\n parent = deepestZone;\n while (parent.parentNode && parent.parentNode !== parent.ownerDocument) {\n deepestZoneParents.unshift(parent);\n parent = parent.parentNode;\n }\n }\n\n // if this element is an svg element and the current deepest is\n // an HTMLElement\n if (deepestZone instanceof HTMLElement\n && dropzone instanceof SVGElement\n && !(dropzone instanceof SVGSVGElement)) {\n\n if (dropzone === deepestZone.parentNode) {\n continue;\n }\n\n parent = dropzone.ownerSVGElement;\n }\n else {\n parent = dropzone;\n }\n\n dropzoneParents = [];\n\n while (parent.parentNode !== parent.ownerDocument) {\n dropzoneParents.unshift(parent);\n parent = parent.parentNode;\n }\n\n n = 0;\n\n // get (position of last common ancestor) + 1\n while (dropzoneParents[n] && dropzoneParents[n] === deepestZoneParents[n]) {\n n++;\n }\n\n var parents = [\n dropzoneParents[n - 1],\n dropzoneParents[n],\n deepestZoneParents[n]\n ];\n\n child = parents[0].lastChild;\n\n while (child) {\n if (child === parents[1]) {\n deepestZone = dropzone;\n index = i;\n deepestZoneParents = [];\n\n break;\n }\n else if (child === parents[2]) {\n break;\n }\n\n child = child.previousSibling;\n }\n }\n\n return index;\n }\n\n function Interaction () {\n this.target = null; // current interactable being interacted with\n this.element = null; // the target element of the interactable\n this.dropTarget = null; // the dropzone a drag target might be dropped into\n this.dropElement = null; // the element at the time of checking\n this.prevDropTarget = null; // the dropzone that was recently dragged away from\n this.prevDropElement = null; // the element at the time of checking\n\n this.prepared = { // action that's ready to be fired on next move event\n name : null,\n axis : null,\n edges: null\n };\n\n this.matches = []; // all selectors that are matched by target element\n this.matchElements = []; // corresponding elements\n\n this.inertiaStatus = {\n active : false,\n smoothEnd : false,\n ending : false,\n\n startEvent: null,\n upCoords: {},\n\n xe: 0, ye: 0,\n sx: 0, sy: 0,\n\n t0: 0,\n vx0: 0, vys: 0,\n duration: 0,\n\n resumeDx: 0,\n resumeDy: 0,\n\n lambda_v0: 0,\n one_ve_v0: 0,\n i : null\n };\n\n if (isFunction(Function.prototype.bind)) {\n this.boundInertiaFrame = this.inertiaFrame.bind(this);\n this.boundSmoothEndFrame = this.smoothEndFrame.bind(this);\n }\n else {\n var that = this;\n\n this.boundInertiaFrame = function () { return that.inertiaFrame(); };\n this.boundSmoothEndFrame = function () { return that.smoothEndFrame(); };\n }\n\n this.activeDrops = {\n dropzones: [], // the dropzones that are mentioned below\n elements : [], // elements of dropzones that accept the target draggable\n rects : [] // the rects of the elements mentioned above\n };\n\n // keep track of added pointers\n this.pointers = [];\n this.pointerIds = [];\n this.downTargets = [];\n this.downTimes = [];\n this.holdTimers = [];\n\n // Previous native pointer move event coordinates\n this.prevCoords = {\n page : { x: 0, y: 0 },\n client : { x: 0, y: 0 },\n timeStamp: 0\n };\n // current native pointer move event coordinates\n this.curCoords = {\n page : { x: 0, y: 0 },\n client : { x: 0, y: 0 },\n timeStamp: 0\n };\n\n // Starting InteractEvent pointer coordinates\n this.startCoords = {\n page : { x: 0, y: 0 },\n client : { x: 0, y: 0 },\n timeStamp: 0\n };\n\n // Change in coordinates and time of the pointer\n this.pointerDelta = {\n page : { x: 0, y: 0, vx: 0, vy: 0, speed: 0 },\n client : { x: 0, y: 0, vx: 0, vy: 0, speed: 0 },\n timeStamp: 0\n };\n\n this.downEvent = null; // pointerdown/mousedown/touchstart event\n this.downPointer = {};\n\n this._eventTarget = null;\n this._curEventTarget = null;\n\n this.prevEvent = null; // previous action event\n this.tapTime = 0; // time of the most recent tap event\n this.prevTap = null;\n\n this.startOffset = { left: 0, right: 0, top: 0, bottom: 0 };\n this.restrictOffset = { left: 0, right: 0, top: 0, bottom: 0 };\n this.snapOffsets = [];\n\n this.gesture = {\n start: { x: 0, y: 0 },\n\n startDistance: 0, // distance between two touches of touchStart\n prevDistance : 0,\n distance : 0,\n\n scale: 1, // gesture.distance / gesture.startDistance\n\n startAngle: 0, // angle of line joining two touches\n prevAngle : 0 // angle of the previous gesture event\n };\n\n this.snapStatus = {\n x : 0, y : 0,\n dx : 0, dy : 0,\n realX : 0, realY : 0,\n snappedX: 0, snappedY: 0,\n targets : [],\n locked : false,\n changed : false\n };\n\n this.restrictStatus = {\n dx : 0, dy : 0,\n restrictedX: 0, restrictedY: 0,\n snap : null,\n restricted : false,\n changed : false\n };\n\n this.restrictStatus.snap = this.snapStatus;\n\n this.pointerIsDown = false;\n this.pointerWasMoved = false;\n this.gesturing = false;\n this.dragging = false;\n this.resizing = false;\n this.resizeAxes = 'xy';\n\n this.mouse = false;\n\n interactions.push(this);\n }\n\n Interaction.prototype = {\n getPageXY : function (pointer, xy) { return getPageXY(pointer, xy, this); },\n getClientXY: function (pointer, xy) { return getClientXY(pointer, xy, this); },\n setEventXY : function (target, ptr) { return setEventXY(target, ptr, this); },\n\n pointerOver: function (pointer, event, eventTarget) {\n if (this.prepared.name || !this.mouse) { return; }\n\n var curMatches = [],\n curMatchElements = [],\n prevTargetElement = this.element;\n\n this.addPointer(pointer);\n\n if (this.target\n && (testIgnore(this.target, this.element, eventTarget)\n || !testAllow(this.target, this.element, eventTarget))) {\n // if the eventTarget should be ignored or shouldn't be allowed\n // clear the previous target\n this.target = null;\n this.element = null;\n this.matches = [];\n this.matchElements = [];\n }\n\n var elementInteractable = interactables.get(eventTarget),\n elementAction = (elementInteractable\n && !testIgnore(elementInteractable, eventTarget, eventTarget)\n && testAllow(elementInteractable, eventTarget, eventTarget)\n && validateAction(\n elementInteractable.getAction(pointer, event, this, eventTarget),\n elementInteractable));\n\n if (elementAction && !withinInteractionLimit(elementInteractable, eventTarget, elementAction)) {\n elementAction = null;\n }\n\n function pushCurMatches (interactable, selector) {\n if (interactable\n && inContext(interactable, eventTarget)\n && !testIgnore(interactable, eventTarget, eventTarget)\n && testAllow(interactable, eventTarget, eventTarget)\n && matchesSelector(eventTarget, selector)) {\n\n curMatches.push(interactable);\n curMatchElements.push(eventTarget);\n }\n }\n\n if (elementAction) {\n this.target = elementInteractable;\n this.element = eventTarget;\n this.matches = [];\n this.matchElements = [];\n }\n else {\n interactables.forEachSelector(pushCurMatches);\n\n if (this.validateSelector(pointer, event, curMatches, curMatchElements)) {\n this.matches = curMatches;\n this.matchElements = curMatchElements;\n\n this.pointerHover(pointer, event, this.matches, this.matchElements);\n events.add(eventTarget,\n supportsPointerEvent? pEventTypes.move : 'mousemove',\n listeners.pointerHover);\n }\n else if (this.target) {\n if (nodeContains(prevTargetElement, eventTarget)) {\n this.pointerHover(pointer, event, this.matches, this.matchElements);\n events.add(this.element,\n supportsPointerEvent? pEventTypes.move : 'mousemove',\n listeners.pointerHover);\n }\n else {\n this.target = null;\n this.element = null;\n this.matches = [];\n this.matchElements = [];\n }\n }\n }\n },\n\n // Check what action would be performed on pointerMove target if a mouse\n // button were pressed and change the cursor accordingly\n pointerHover: function (pointer, event, eventTarget, curEventTarget, matches, matchElements) {\n var target = this.target;\n\n if (!this.prepared.name && this.mouse) {\n\n var action;\n\n // update pointer coords for defaultActionChecker to use\n this.setEventXY(this.curCoords, [pointer]);\n\n if (matches) {\n action = this.validateSelector(pointer, event, matches, matchElements);\n }\n else if (target) {\n action = validateAction(target.getAction(this.pointers[0], event, this, this.element), this.target);\n }\n\n if (target && target.options.styleCursor) {\n if (action) {\n target._doc.documentElement.style.cursor = getActionCursor(action);\n }\n else {\n target._doc.documentElement.style.cursor = '';\n }\n }\n }\n else if (this.prepared.name) {\n this.checkAndPreventDefault(event, target, this.element);\n }\n },\n\n pointerOut: function (pointer, event, eventTarget) {\n if (this.prepared.name) { return; }\n\n // Remove temporary event listeners for selector Interactables\n if (!interactables.get(eventTarget)) {\n events.remove(eventTarget,\n supportsPointerEvent? pEventTypes.move : 'mousemove',\n listeners.pointerHover);\n }\n\n if (this.target && this.target.options.styleCursor && !this.interacting()) {\n this.target._doc.documentElement.style.cursor = '';\n }\n },\n\n selectorDown: function (pointer, event, eventTarget, curEventTarget) {\n var that = this,\n // copy event to be used in timeout for IE8\n eventCopy = events.useAttachEvent? extend({}, event) : event,\n element = eventTarget,\n pointerIndex = this.addPointer(pointer),\n action;\n\n this.holdTimers[pointerIndex] = setTimeout(function () {\n that.pointerHold(events.useAttachEvent? eventCopy : pointer, eventCopy, eventTarget, curEventTarget);\n }, defaultOptions._holdDuration);\n\n this.pointerIsDown = true;\n\n // Check if the down event hits the current inertia target\n if (this.inertiaStatus.active && this.target.selector) {\n // climb up the DOM tree from the event target\n while (isElement(element)) {\n\n // if this element is the current inertia target element\n if (element === this.element\n // and the prospective action is the same as the ongoing one\n && validateAction(this.target.getAction(pointer, event, this, this.element), this.target).name === this.prepared.name) {\n\n // stop inertia so that the next move will be a normal one\n cancelFrame(this.inertiaStatus.i);\n this.inertiaStatus.active = false;\n\n this.collectEventTargets(pointer, event, eventTarget, 'down');\n return;\n }\n element = parentElement(element);\n }\n }\n\n // do nothing if interacting\n if (this.interacting()) {\n this.collectEventTargets(pointer, event, eventTarget, 'down');\n return;\n }\n\n function pushMatches (interactable, selector, context) {\n var elements = ie8MatchesSelector\n ? context.querySelectorAll(selector)\n : undefined;\n\n if (inContext(interactable, element)\n && !testIgnore(interactable, element, eventTarget)\n && testAllow(interactable, element, eventTarget)\n && matchesSelector(element, selector, elements)) {\n\n that.matches.push(interactable);\n that.matchElements.push(element);\n }\n }\n\n // update pointer coords for defaultActionChecker to use\n this.setEventXY(this.curCoords, [pointer]);\n this.downEvent = event;\n\n while (isElement(element) && !action) {\n this.matches = [];\n this.matchElements = [];\n\n interactables.forEachSelector(pushMatches);\n\n action = this.validateSelector(pointer, event, this.matches, this.matchElements);\n element = parentElement(element);\n }\n\n if (action) {\n this.prepared.name = action.name;\n this.prepared.axis = action.axis;\n this.prepared.edges = action.edges;\n\n this.collectEventTargets(pointer, event, eventTarget, 'down');\n\n return this.pointerDown(pointer, event, eventTarget, curEventTarget, action);\n }\n else {\n // do these now since pointerDown isn't being called from here\n this.downTimes[pointerIndex] = new Date().getTime();\n this.downTargets[pointerIndex] = eventTarget;\n pointerExtend(this.downPointer, pointer);\n\n copyCoords(this.prevCoords, this.curCoords);\n this.pointerWasMoved = false;\n }\n\n this.collectEventTargets(pointer, event, eventTarget, 'down');\n },\n\n // Determine action to be performed on next pointerMove and add appropriate\n // style and event Listeners\n pointerDown: function (pointer, event, eventTarget, curEventTarget, forceAction) {\n if (!forceAction && !this.inertiaStatus.active && this.pointerWasMoved && this.prepared.name) {\n this.checkAndPreventDefault(event, this.target, this.element);\n\n return;\n }\n\n this.pointerIsDown = true;\n this.downEvent = event;\n\n var pointerIndex = this.addPointer(pointer),\n action;\n\n // If it is the second touch of a multi-touch gesture, keep the\n // target the same and get a new action if a target was set by the\n // first touch\n if (this.pointerIds.length > 1 && this.target._element === this.element) {\n var newAction = validateAction(forceAction || this.target.getAction(pointer, event, this, this.element), this.target);\n\n if (withinInteractionLimit(this.target, this.element, newAction)) {\n action = newAction;\n }\n\n this.prepared.name = null;\n }\n // Otherwise, set the target if there is no action prepared\n else if (!this.prepared.name) {\n var interactable = interactables.get(curEventTarget);\n\n if (interactable\n && !testIgnore(interactable, curEventTarget, eventTarget)\n && testAllow(interactable, curEventTarget, eventTarget)\n && (action = validateAction(forceAction || interactable.getAction(pointer, event, this, curEventTarget), interactable, eventTarget))\n && withinInteractionLimit(interactable, curEventTarget, action)) {\n this.target = interactable;\n this.element = curEventTarget;\n }\n }\n\n var target = this.target,\n options = target && target.options;\n\n if (target && (forceAction || !this.prepared.name)) {\n action = action || validateAction(forceAction || target.getAction(pointer, event, this, curEventTarget), target, this.element);\n\n this.setEventXY(this.startCoords, this.pointers);\n\n if (!action) { return; }\n\n if (options.styleCursor) {\n target._doc.documentElement.style.cursor = getActionCursor(action);\n }\n\n this.resizeAxes = action.name === 'resize'? action.axis : null;\n\n if (action === 'gesture' && this.pointerIds.length < 2) {\n action = null;\n }\n\n this.prepared.name = action.name;\n this.prepared.axis = action.axis;\n this.prepared.edges = action.edges;\n\n this.snapStatus.snappedX = this.snapStatus.snappedY =\n this.restrictStatus.restrictedX = this.restrictStatus.restrictedY = NaN;\n\n this.downTimes[pointerIndex] = new Date().getTime();\n this.downTargets[pointerIndex] = eventTarget;\n pointerExtend(this.downPointer, pointer);\n\n copyCoords(this.prevCoords, this.startCoords);\n this.pointerWasMoved = false;\n\n this.checkAndPreventDefault(event, target, this.element);\n }\n // if inertia is active try to resume action\n else if (this.inertiaStatus.active\n && curEventTarget === this.element\n && validateAction(target.getAction(pointer, event, this, this.element), target).name === this.prepared.name) {\n\n cancelFrame(this.inertiaStatus.i);\n this.inertiaStatus.active = false;\n\n this.checkAndPreventDefault(event, target, this.element);\n }\n },\n\n setModifications: function (coords, preEnd) {\n var target = this.target,\n shouldMove = true,\n shouldSnap = checkSnap(target, this.prepared.name) && (!target.options[this.prepared.name].snap.endOnly || preEnd),\n shouldRestrict = checkRestrict(target, this.prepared.name) && (!target.options[this.prepared.name].restrict.endOnly || preEnd);\n\n if (shouldSnap ) { this.setSnapping (coords); } else { this.snapStatus .locked = false; }\n if (shouldRestrict) { this.setRestriction(coords); } else { this.restrictStatus.restricted = false; }\n\n if (shouldSnap && this.snapStatus.locked && !this.snapStatus.changed) {\n shouldMove = shouldRestrict && this.restrictStatus.restricted && this.restrictStatus.changed;\n }\n else if (shouldRestrict && this.restrictStatus.restricted && !this.restrictStatus.changed) {\n shouldMove = false;\n }\n\n return shouldMove;\n },\n\n setStartOffsets: function (action, interactable, element) {\n var rect = interactable.getRect(element),\n origin = getOriginXY(interactable, element),\n snap = interactable.options[this.prepared.name].snap,\n restrict = interactable.options[this.prepared.name].restrict,\n width, height;\n\n if (rect) {\n this.startOffset.left = this.startCoords.page.x - rect.left;\n this.startOffset.top = this.startCoords.page.y - rect.top;\n\n this.startOffset.right = rect.right - this.startCoords.page.x;\n this.startOffset.bottom = rect.bottom - this.startCoords.page.y;\n\n if ('width' in rect) { width = rect.width; }\n else { width = rect.right - rect.left; }\n if ('height' in rect) { height = rect.height; }\n else { height = rect.bottom - rect.top; }\n }\n else {\n this.startOffset.left = this.startOffset.top = this.startOffset.right = this.startOffset.bottom = 0;\n }\n\n this.snapOffsets.splice(0);\n\n var snapOffset = snap && snap.offset === 'startCoords'\n ? {\n x: this.startCoords.page.x - origin.x,\n y: this.startCoords.page.y - origin.y\n }\n : snap && snap.offset || { x: 0, y: 0 };\n\n if (rect && snap && snap.relativePoints && snap.relativePoints.length) {\n for (var i = 0; i < snap.relativePoints.length; i++) {\n this.snapOffsets.push({\n x: this.startOffset.left - (width * snap.relativePoints[i].x) + snapOffset.x,\n y: this.startOffset.top - (height * snap.relativePoints[i].y) + snapOffset.y\n });\n }\n }\n else {\n this.snapOffsets.push(snapOffset);\n }\n\n if (rect && restrict.elementRect) {\n this.restrictOffset.left = this.startOffset.left - (width * restrict.elementRect.left);\n this.restrictOffset.top = this.startOffset.top - (height * restrict.elementRect.top);\n\n this.restrictOffset.right = this.startOffset.right - (width * (1 - restrict.elementRect.right));\n this.restrictOffset.bottom = this.startOffset.bottom - (height * (1 - restrict.elementRect.bottom));\n }\n else {\n this.restrictOffset.left = this.restrictOffset.top = this.restrictOffset.right = this.restrictOffset.bottom = 0;\n }\n },\n\n /*\\\n * Interaction.start\n [ method ]\n *\n * Start an action with the given Interactable and Element as tartgets. The\n * action must be enabled for the target Interactable and an appropriate number\n * of pointers must be held down – 1 for drag/resize, 2 for gesture.\n *\n * Use it with `interactable.able({ manualStart: false })` to always\n * [start actions manually](https://github.com/taye/interact.js/issues/114)\n *\n - action (object) The action to be performed - drag, resize, etc.\n - interactable (Interactable) The Interactable to target\n - element (Element) The DOM Element to target\n = (object) interact\n **\n | interact(target)\n | .draggable({\n | // disable the default drag start by down->move\n | manualStart: true\n | })\n | // start dragging after the user holds the pointer down\n | .on('hold', function (event) {\n | var interaction = event.interaction;\n |\n | if (!interaction.interacting()) {\n | interaction.start({ name: 'drag' },\n | event.interactable,\n | event.currentTarget);\n | }\n | });\n \\*/\n start: function (action, interactable, element) {\n if (this.interacting()\n || !this.pointerIsDown\n || this.pointerIds.length < (action.name === 'gesture'? 2 : 1)) {\n return;\n }\n\n // if this interaction had been removed after stopping\n // add it back\n if (indexOf(interactions, this) === -1) {\n interactions.push(this);\n }\n\n // set the startCoords if there was no prepared action\n if (!this.prepared.name) {\n this.setEventXY(this.startCoords, this.pointers);\n }\n\n this.prepared.name = action.name;\n this.prepared.axis = action.axis;\n this.prepared.edges = action.edges;\n this.target = interactable;\n this.element = element;\n\n this.setStartOffsets(action.name, interactable, element);\n this.setModifications(this.startCoords.page);\n\n this.prevEvent = this[this.prepared.name + 'Start'](this.downEvent);\n },\n\n pointerMove: function (pointer, event, eventTarget, curEventTarget, preEnd) {\n if (this.inertiaStatus.active) {\n var pageUp = this.inertiaStatus.upCoords.page;\n var clientUp = this.inertiaStatus.upCoords.client;\n\n var inertiaPosition = {\n pageX : pageUp.x + this.inertiaStatus.sx,\n pageY : pageUp.y + this.inertiaStatus.sy,\n clientX: clientUp.x + this.inertiaStatus.sx,\n clientY: clientUp.y + this.inertiaStatus.sy\n };\n\n this.setEventXY(this.curCoords, [inertiaPosition]);\n }\n else {\n this.recordPointer(pointer);\n this.setEventXY(this.curCoords, this.pointers);\n }\n\n var duplicateMove = (this.curCoords.page.x === this.prevCoords.page.x\n && this.curCoords.page.y === this.prevCoords.page.y\n && this.curCoords.client.x === this.prevCoords.client.x\n && this.curCoords.client.y === this.prevCoords.client.y);\n\n var dx, dy,\n pointerIndex = this.mouse? 0 : indexOf(this.pointerIds, getPointerId(pointer));\n\n // register movement greater than pointerMoveTolerance\n if (this.pointerIsDown && !this.pointerWasMoved) {\n dx = this.curCoords.client.x - this.startCoords.client.x;\n dy = this.curCoords.client.y - this.startCoords.client.y;\n\n this.pointerWasMoved = hypot(dx, dy) > pointerMoveTolerance;\n }\n\n if (!duplicateMove && (!this.pointerIsDown || this.pointerWasMoved)) {\n if (this.pointerIsDown) {\n clearTimeout(this.holdTimers[pointerIndex]);\n }\n\n this.collectEventTargets(pointer, event, eventTarget, 'move');\n }\n\n if (!this.pointerIsDown) { return; }\n\n if (duplicateMove && this.pointerWasMoved && !preEnd) {\n this.checkAndPreventDefault(event, this.target, this.element);\n return;\n }\n\n // set pointer coordinate, time changes and speeds\n setEventDeltas(this.pointerDelta, this.prevCoords, this.curCoords);\n\n if (!this.prepared.name) { return; }\n\n if (this.pointerWasMoved\n // ignore movement while inertia is active\n && (!this.inertiaStatus.active || (pointer instanceof InteractEvent && /inertiastart/.test(pointer.type)))) {\n\n // if just starting an action, calculate the pointer speed now\n if (!this.interacting()) {\n setEventDeltas(this.pointerDelta, this.prevCoords, this.curCoords);\n\n // check if a drag is in the correct axis\n if (this.prepared.name === 'drag') {\n var absX = Math.abs(dx),\n absY = Math.abs(dy),\n targetAxis = this.target.options.drag.axis,\n axis = (absX > absY ? 'x' : absX < absY ? 'y' : 'xy');\n\n // if the movement isn't in the axis of the interactable\n if (axis !== 'xy' && targetAxis !== 'xy' && targetAxis !== axis) {\n // cancel the prepared action\n this.prepared.name = null;\n\n // then try to get a drag from another ineractable\n\n var element = eventTarget;\n\n // check element interactables\n while (isElement(element)) {\n var elementInteractable = interactables.get(element);\n\n if (elementInteractable\n && elementInteractable !== this.target\n && !elementInteractable.options.drag.manualStart\n && elementInteractable.getAction(this.downPointer, this.downEvent, this, element).name === 'drag'\n && checkAxis(axis, elementInteractable)) {\n\n this.prepared.name = 'drag';\n this.target = elementInteractable;\n this.element = element;\n break;\n }\n\n element = parentElement(element);\n }\n\n // if there's no drag from element interactables,\n // check the selector interactables\n if (!this.prepared.name) {\n var thisInteraction = this;\n\n var getDraggable = function (interactable, selector, context) {\n var elements = ie8MatchesSelector\n ? context.querySelectorAll(selector)\n : undefined;\n\n if (interactable === thisInteraction.target) { return; }\n\n if (inContext(interactable, eventTarget)\n && !interactable.options.drag.manualStart\n && !testIgnore(interactable, element, eventTarget)\n && testAllow(interactable, element, eventTarget)\n && matchesSelector(element, selector, elements)\n && interactable.getAction(thisInteraction.downPointer, thisInteraction.downEvent, thisInteraction, element).name === 'drag'\n && checkAxis(axis, interactable)\n && withinInteractionLimit(interactable, element, 'drag')) {\n\n return interactable;\n }\n };\n\n element = eventTarget;\n\n while (isElement(element)) {\n var selectorInteractable = interactables.forEachSelector(getDraggable);\n\n if (selectorInteractable) {\n this.prepared.name = 'drag';\n this.target = selectorInteractable;\n this.element = element;\n break;\n }\n\n element = parentElement(element);\n }\n }\n }\n }\n }\n\n var starting = !!this.prepared.name && !this.interacting();\n\n if (starting\n && (this.target.options[this.prepared.name].manualStart\n || !withinInteractionLimit(this.target, this.element, this.prepared))) {\n this.stop(event);\n return;\n }\n\n if (this.prepared.name && this.target) {\n if (starting) {\n this.start(this.prepared, this.target, this.element);\n }\n\n var shouldMove = this.setModifications(this.curCoords.page, preEnd);\n\n // move if snapping or restriction doesn't prevent it\n if (shouldMove || starting) {\n this.prevEvent = this[this.prepared.name + 'Move'](event);\n }\n\n this.checkAndPreventDefault(event, this.target, this.element);\n }\n }\n\n copyCoords(this.prevCoords, this.curCoords);\n\n if (this.dragging || this.resizing) {\n this.autoScrollMove(pointer);\n }\n },\n\n dragStart: function (event) {\n var dragEvent = new InteractEvent(this, event, 'drag', 'start', this.element);\n\n this.dragging = true;\n this.target.fire(dragEvent);\n\n // reset active dropzones\n this.activeDrops.dropzones = [];\n this.activeDrops.elements = [];\n this.activeDrops.rects = [];\n\n if (!this.dynamicDrop) {\n this.setActiveDrops(this.element);\n }\n\n var dropEvents = this.getDropEvents(event, dragEvent);\n\n if (dropEvents.activate) {\n this.fireActiveDrops(dropEvents.activate);\n }\n\n return dragEvent;\n },\n\n dragMove: function (event) {\n var target = this.target,\n dragEvent = new InteractEvent(this, event, 'drag', 'move', this.element),\n draggableElement = this.element,\n drop = this.getDrop(dragEvent, event, draggableElement);\n\n this.dropTarget = drop.dropzone;\n this.dropElement = drop.element;\n\n var dropEvents = this.getDropEvents(event, dragEvent);\n\n target.fire(dragEvent);\n\n if (dropEvents.leave) { this.prevDropTarget.fire(dropEvents.leave); }\n if (dropEvents.enter) { this.dropTarget.fire(dropEvents.enter); }\n if (dropEvents.move ) { this.dropTarget.fire(dropEvents.move ); }\n\n this.prevDropTarget = this.dropTarget;\n this.prevDropElement = this.dropElement;\n\n return dragEvent;\n },\n\n resizeStart: function (event) {\n var resizeEvent = new InteractEvent(this, event, 'resize', 'start', this.element);\n\n if (this.prepared.edges) {\n var startRect = this.target.getRect(this.element);\n\n /*\n * When using the `resizable.square` or `resizable.preserveAspectRatio` options, resizing from one edge\n * will affect another. E.g. with `resizable.square`, resizing to make the right edge larger will make\n * the bottom edge larger by the same amount. We call these 'linked' edges. Any linked edges will depend\n * on the active edges and the edge being interacted with.\n */\n if (this.target.options.resize.square || this.target.options.resize.preserveAspectRatio) {\n var linkedEdges = extend({}, this.prepared.edges);\n\n linkedEdges.top = linkedEdges.top || (linkedEdges.left && !linkedEdges.bottom);\n linkedEdges.left = linkedEdges.left || (linkedEdges.top && !linkedEdges.right );\n linkedEdges.bottom = linkedEdges.bottom || (linkedEdges.right && !linkedEdges.top );\n linkedEdges.right = linkedEdges.right || (linkedEdges.bottom && !linkedEdges.left );\n\n this.prepared._linkedEdges = linkedEdges;\n }\n else {\n this.prepared._linkedEdges = null;\n }\n\n // if using `resizable.preserveAspectRatio` option, record aspect ratio at the start of the resize\n if (this.target.options.resize.preserveAspectRatio) {\n this.resizeStartAspectRatio = startRect.width / startRect.height;\n }\n\n this.resizeRects = {\n start : startRect,\n current : extend({}, startRect),\n restricted: extend({}, startRect),\n previous : extend({}, startRect),\n delta : {\n left: 0, right : 0, width : 0,\n top : 0, bottom: 0, height: 0\n }\n };\n\n resizeEvent.rect = this.resizeRects.restricted;\n resizeEvent.deltaRect = this.resizeRects.delta;\n }\n\n this.target.fire(resizeEvent);\n\n this.resizing = true;\n\n return resizeEvent;\n },\n\n resizeMove: function (event) {\n var resizeEvent = new InteractEvent(this, event, 'resize', 'move', this.element);\n\n var edges = this.prepared.edges,\n invert = this.target.options.resize.invert,\n invertible = invert === 'reposition' || invert === 'negate';\n\n if (edges) {\n var dx = resizeEvent.dx,\n dy = resizeEvent.dy,\n\n start = this.resizeRects.start,\n current = this.resizeRects.current,\n restricted = this.resizeRects.restricted,\n delta = this.resizeRects.delta,\n previous = extend(this.resizeRects.previous, restricted),\n\n originalEdges = edges;\n\n // `resize.preserveAspectRatio` takes precedence over `resize.square`\n if (this.target.options.resize.preserveAspectRatio) {\n var resizeStartAspectRatio = this.resizeStartAspectRatio;\n\n edges = this.prepared._linkedEdges;\n\n if ((originalEdges.left && originalEdges.bottom)\n || (originalEdges.right && originalEdges.top)) {\n dy = -dx / resizeStartAspectRatio;\n }\n else if (originalEdges.left || originalEdges.right) { dy = dx / resizeStartAspectRatio; }\n else if (originalEdges.top || originalEdges.bottom) { dx = dy * resizeStartAspectRatio; }\n }\n else if (this.target.options.resize.square) {\n edges = this.prepared._linkedEdges;\n\n if ((originalEdges.left && originalEdges.bottom)\n || (originalEdges.right && originalEdges.top)) {\n dy = -dx;\n }\n else if (originalEdges.left || originalEdges.right) { dy = dx; }\n else if (originalEdges.top || originalEdges.bottom) { dx = dy; }\n }\n\n // update the 'current' rect without modifications\n if (edges.top ) { current.top += dy; }\n if (edges.bottom) { current.bottom += dy; }\n if (edges.left ) { current.left += dx; }\n if (edges.right ) { current.right += dx; }\n\n if (invertible) {\n // if invertible, copy the current rect\n extend(restricted, current);\n\n if (invert === 'reposition') {\n // swap edge values if necessary to keep width/height positive\n var swap;\n\n if (restricted.top > restricted.bottom) {\n swap = restricted.top;\n\n restricted.top = restricted.bottom;\n restricted.bottom = swap;\n }\n if (restricted.left > restricted.right) {\n swap = restricted.left;\n\n restricted.left = restricted.right;\n restricted.right = swap;\n }\n }\n }\n else {\n // if not invertible, restrict to minimum of 0x0 rect\n restricted.top = Math.min(current.top, start.bottom);\n restricted.bottom = Math.max(current.bottom, start.top);\n restricted.left = Math.min(current.left, start.right);\n restricted.right = Math.max(current.right, start.left);\n }\n\n restricted.width = restricted.right - restricted.left;\n restricted.height = restricted.bottom - restricted.top ;\n\n for (var edge in restricted) {\n delta[edge] = restricted[edge] - previous[edge];\n }\n\n resizeEvent.edges = this.prepared.edges;\n resizeEvent.rect = restricted;\n resizeEvent.deltaRect = delta;\n }\n\n this.target.fire(resizeEvent);\n\n return resizeEvent;\n },\n\n gestureStart: function (event) {\n var gestureEvent = new InteractEvent(this, event, 'gesture', 'start', this.element);\n\n gestureEvent.ds = 0;\n\n this.gesture.startDistance = this.gesture.prevDistance = gestureEvent.distance;\n this.gesture.startAngle = this.gesture.prevAngle = gestureEvent.angle;\n this.gesture.scale = 1;\n\n this.gesturing = true;\n\n this.target.fire(gestureEvent);\n\n return gestureEvent;\n },\n\n gestureMove: function (event) {\n if (!this.pointerIds.length) {\n return this.prevEvent;\n }\n\n var gestureEvent;\n\n gestureEvent = new InteractEvent(this, event, 'gesture', 'move', this.element);\n gestureEvent.ds = gestureEvent.scale - this.gesture.scale;\n\n this.target.fire(gestureEvent);\n\n this.gesture.prevAngle = gestureEvent.angle;\n this.gesture.prevDistance = gestureEvent.distance;\n\n if (gestureEvent.scale !== Infinity &&\n gestureEvent.scale !== null &&\n gestureEvent.scale !== undefined &&\n !isNaN(gestureEvent.scale)) {\n\n this.gesture.scale = gestureEvent.scale;\n }\n\n return gestureEvent;\n },\n\n pointerHold: function (pointer, event, eventTarget) {\n this.collectEventTargets(pointer, event, eventTarget, 'hold');\n },\n\n pointerUp: function (pointer, event, eventTarget, curEventTarget) {\n var pointerIndex = this.mouse? 0 : indexOf(this.pointerIds, getPointerId(pointer));\n\n clearTimeout(this.holdTimers[pointerIndex]);\n\n this.collectEventTargets(pointer, event, eventTarget, 'up' );\n this.collectEventTargets(pointer, event, eventTarget, 'tap');\n\n this.pointerEnd(pointer, event, eventTarget, curEventTarget);\n\n this.removePointer(pointer);\n },\n\n pointerCancel: function (pointer, event, eventTarget, curEventTarget) {\n var pointerIndex = this.mouse? 0 : indexOf(this.pointerIds, getPointerId(pointer));\n\n clearTimeout(this.holdTimers[pointerIndex]);\n\n this.collectEventTargets(pointer, event, eventTarget, 'cancel');\n this.pointerEnd(pointer, event, eventTarget, curEventTarget);\n\n this.removePointer(pointer);\n },\n\n // http://www.quirksmode.org/dom/events/click.html\n // >Events leading to dblclick\n //\n // IE8 doesn't fire down event before dblclick.\n // This workaround tries to fire a tap and doubletap after dblclick\n ie8Dblclick: function (pointer, event, eventTarget) {\n if (this.prevTap\n && event.clientX === this.prevTap.clientX\n && event.clientY === this.prevTap.clientY\n && eventTarget === this.prevTap.target) {\n\n this.downTargets[0] = eventTarget;\n this.downTimes[0] = new Date().getTime();\n this.collectEventTargets(pointer, event, eventTarget, 'tap');\n }\n },\n\n // End interact move events and stop auto-scroll unless inertia is enabled\n pointerEnd: function (pointer, event, eventTarget, curEventTarget) {\n var endEvent,\n target = this.target,\n options = target && target.options,\n inertiaOptions = options && this.prepared.name && options[this.prepared.name].inertia,\n inertiaStatus = this.inertiaStatus;\n\n if (this.interacting()) {\n\n if (inertiaStatus.active && !inertiaStatus.ending) { return; }\n\n var pointerSpeed,\n now = new Date().getTime(),\n inertiaPossible = false,\n inertia = false,\n smoothEnd = false,\n endSnap = checkSnap(target, this.prepared.name) && options[this.prepared.name].snap.endOnly,\n endRestrict = checkRestrict(target, this.prepared.name) && options[this.prepared.name].restrict.endOnly,\n dx = 0,\n dy = 0,\n startEvent;\n\n if (this.dragging) {\n if (options.drag.axis === 'x' ) { pointerSpeed = Math.abs(this.pointerDelta.client.vx); }\n else if (options.drag.axis === 'y' ) { pointerSpeed = Math.abs(this.pointerDelta.client.vy); }\n else /*options.drag.axis === 'xy'*/{ pointerSpeed = this.pointerDelta.client.speed; }\n }\n else {\n pointerSpeed = this.pointerDelta.client.speed;\n }\n\n // check if inertia should be started\n inertiaPossible = (inertiaOptions && inertiaOptions.enabled\n && this.prepared.name !== 'gesture'\n && event !== inertiaStatus.startEvent);\n\n inertia = (inertiaPossible\n && (now - this.curCoords.timeStamp) < 50\n && pointerSpeed > inertiaOptions.minSpeed\n && pointerSpeed > inertiaOptions.endSpeed);\n\n if (inertiaPossible && !inertia && (endSnap || endRestrict)) {\n\n var snapRestrict = {};\n\n snapRestrict.snap = snapRestrict.restrict = snapRestrict;\n\n if (endSnap) {\n this.setSnapping(this.curCoords.page, snapRestrict);\n if (snapRestrict.locked) {\n dx += snapRestrict.dx;\n dy += snapRestrict.dy;\n }\n }\n\n if (endRestrict) {\n this.setRestriction(this.curCoords.page, snapRestrict);\n if (snapRestrict.restricted) {\n dx += snapRestrict.dx;\n dy += snapRestrict.dy;\n }\n }\n\n if (dx || dy) {\n smoothEnd = true;\n }\n }\n\n if (inertia || smoothEnd) {\n copyCoords(inertiaStatus.upCoords, this.curCoords);\n\n this.pointers[0] = inertiaStatus.startEvent = startEvent =\n new InteractEvent(this, event, this.prepared.name, 'inertiastart', this.element);\n\n inertiaStatus.t0 = now;\n\n target.fire(inertiaStatus.startEvent);\n\n if (inertia) {\n inertiaStatus.vx0 = this.pointerDelta.client.vx;\n inertiaStatus.vy0 = this.pointerDelta.client.vy;\n inertiaStatus.v0 = pointerSpeed;\n\n this.calcInertia(inertiaStatus);\n\n var page = extend({}, this.curCoords.page),\n origin = getOriginXY(target, this.element),\n statusObject;\n\n page.x = page.x + inertiaStatus.xe - origin.x;\n page.y = page.y + inertiaStatus.ye - origin.y;\n\n statusObject = {\n useStatusXY: true,\n x: page.x,\n y: page.y,\n dx: 0,\n dy: 0,\n snap: null\n };\n\n statusObject.snap = statusObject;\n\n dx = dy = 0;\n\n if (endSnap) {\n var snap = this.setSnapping(this.curCoords.page, statusObject);\n\n if (snap.locked) {\n dx += snap.dx;\n dy += snap.dy;\n }\n }\n\n if (endRestrict) {\n var restrict = this.setRestriction(this.curCoords.page, statusObject);\n\n if (restrict.restricted) {\n dx += restrict.dx;\n dy += restrict.dy;\n }\n }\n\n inertiaStatus.modifiedXe += dx;\n inertiaStatus.modifiedYe += dy;\n\n inertiaStatus.i = reqFrame(this.boundInertiaFrame);\n }\n else {\n inertiaStatus.smoothEnd = true;\n inertiaStatus.xe = dx;\n inertiaStatus.ye = dy;\n\n inertiaStatus.sx = inertiaStatus.sy = 0;\n\n inertiaStatus.i = reqFrame(this.boundSmoothEndFrame);\n }\n\n inertiaStatus.active = true;\n return;\n }\n\n if (endSnap || endRestrict) {\n // fire a move event at the snapped coordinates\n this.pointerMove(pointer, event, eventTarget, curEventTarget, true);\n }\n }\n\n if (this.dragging) {\n endEvent = new InteractEvent(this, event, 'drag', 'end', this.element);\n\n var draggableElement = this.element,\n drop = this.getDrop(endEvent, event, draggableElement);\n\n this.dropTarget = drop.dropzone;\n this.dropElement = drop.element;\n\n var dropEvents = this.getDropEvents(event, endEvent);\n\n if (dropEvents.leave) { this.prevDropTarget.fire(dropEvents.leave); }\n if (dropEvents.enter) { this.dropTarget.fire(dropEvents.enter); }\n if (dropEvents.drop ) { this.dropTarget.fire(dropEvents.drop ); }\n if (dropEvents.deactivate) {\n this.fireActiveDrops(dropEvents.deactivate);\n }\n\n target.fire(endEvent);\n }\n else if (this.resizing) {\n endEvent = new InteractEvent(this, event, 'resize', 'end', this.element);\n target.fire(endEvent);\n }\n else if (this.gesturing) {\n endEvent = new InteractEvent(this, event, 'gesture', 'end', this.element);\n target.fire(endEvent);\n }\n\n this.stop(event);\n },\n\n collectDrops: function (element) {\n var drops = [],\n elements = [],\n i;\n\n element = element || this.element;\n\n // collect all dropzones and their elements which qualify for a drop\n for (i = 0; i < interactables.length; i++) {\n if (!interactables[i].options.drop.enabled) { continue; }\n\n var current = interactables[i],\n accept = current.options.drop.accept;\n\n // test the draggable element against the dropzone's accept setting\n if ((isElement(accept) && accept !== element)\n || (isString(accept)\n && !matchesSelector(element, accept))) {\n\n continue;\n }\n\n // query for new elements if necessary\n var dropElements = current.selector? current._context.querySelectorAll(current.selector) : [current._element];\n\n for (var j = 0, len = dropElements.length; j < len; j++) {\n var currentElement = dropElements[j];\n\n if (currentElement === element) {\n continue;\n }\n\n drops.push(current);\n elements.push(currentElement);\n }\n }\n\n return {\n dropzones: drops,\n elements: elements\n };\n },\n\n fireActiveDrops: function (event) {\n var i,\n current,\n currentElement,\n prevElement;\n\n // loop through all active dropzones and trigger event\n for (i = 0; i < this.activeDrops.dropzones.length; i++) {\n current = this.activeDrops.dropzones[i];\n currentElement = this.activeDrops.elements [i];\n\n // prevent trigger of duplicate events on same element\n if (currentElement !== prevElement) {\n // set current element as event target\n event.target = currentElement;\n current.fire(event);\n }\n prevElement = currentElement;\n }\n },\n\n // Collect a new set of possible drops and save them in activeDrops.\n // setActiveDrops should always be called when a drag has just started or a\n // drag event happens while dynamicDrop is true\n setActiveDrops: function (dragElement) {\n // get dropzones and their elements that could receive the draggable\n var possibleDrops = this.collectDrops(dragElement, true);\n\n this.activeDrops.dropzones = possibleDrops.dropzones;\n this.activeDrops.elements = possibleDrops.elements;\n this.activeDrops.rects = [];\n\n for (var i = 0; i < this.activeDrops.dropzones.length; i++) {\n this.activeDrops.rects[i] = this.activeDrops.dropzones[i].getRect(this.activeDrops.elements[i]);\n }\n },\n\n getDrop: function (dragEvent, event, dragElement) {\n var validDrops = [];\n\n if (dynamicDrop) {\n this.setActiveDrops(dragElement);\n }\n\n // collect all dropzones and their elements which qualify for a drop\n for (var j = 0; j < this.activeDrops.dropzones.length; j++) {\n var current = this.activeDrops.dropzones[j],\n currentElement = this.activeDrops.elements [j],\n rect = this.activeDrops.rects [j];\n\n validDrops.push(current.dropCheck(dragEvent, event, this.target, dragElement, currentElement, rect)\n ? currentElement\n : null);\n }\n\n // get the most appropriate dropzone based on DOM depth and order\n var dropIndex = indexOfDeepestElement(validDrops),\n dropzone = this.activeDrops.dropzones[dropIndex] || null,\n element = this.activeDrops.elements [dropIndex] || null;\n\n return {\n dropzone: dropzone,\n element: element\n };\n },\n\n getDropEvents: function (pointerEvent, dragEvent) {\n var dropEvents = {\n enter : null,\n leave : null,\n activate : null,\n deactivate: null,\n move : null,\n drop : null\n };\n\n if (this.dropElement !== this.prevDropElement) {\n // if there was a prevDropTarget, create a dragleave event\n if (this.prevDropTarget) {\n dropEvents.leave = {\n target : this.prevDropElement,\n dropzone : this.prevDropTarget,\n relatedTarget: dragEvent.target,\n draggable : dragEvent.interactable,\n dragEvent : dragEvent,\n interaction : this,\n timeStamp : dragEvent.timeStamp,\n type : 'dragleave'\n };\n\n dragEvent.dragLeave = this.prevDropElement;\n dragEvent.prevDropzone = this.prevDropTarget;\n }\n // if the dropTarget is not null, create a dragenter event\n if (this.dropTarget) {\n dropEvents.enter = {\n target : this.dropElement,\n dropzone : this.dropTarget,\n relatedTarget: dragEvent.target,\n draggable : dragEvent.interactable,\n dragEvent : dragEvent,\n interaction : this,\n timeStamp : dragEvent.timeStamp,\n type : 'dragenter'\n };\n\n dragEvent.dragEnter = this.dropElement;\n dragEvent.dropzone = this.dropTarget;\n }\n }\n\n if (dragEvent.type === 'dragend' && this.dropTarget) {\n dropEvents.drop = {\n target : this.dropElement,\n dropzone : this.dropTarget,\n relatedTarget: dragEvent.target,\n draggable : dragEvent.interactable,\n dragEvent : dragEvent,\n interaction : this,\n timeStamp : dragEvent.timeStamp,\n type : 'drop'\n };\n\n dragEvent.dropzone = this.dropTarget;\n }\n if (dragEvent.type === 'dragstart') {\n dropEvents.activate = {\n target : null,\n dropzone : null,\n relatedTarget: dragEvent.target,\n draggable : dragEvent.interactable,\n dragEvent : dragEvent,\n interaction : this,\n timeStamp : dragEvent.timeStamp,\n type : 'dropactivate'\n };\n }\n if (dragEvent.type === 'dragend') {\n dropEvents.deactivate = {\n target : null,\n dropzone : null,\n relatedTarget: dragEvent.target,\n draggable : dragEvent.interactable,\n dragEvent : dragEvent,\n interaction : this,\n timeStamp : dragEvent.timeStamp,\n type : 'dropdeactivate'\n };\n }\n if (dragEvent.type === 'dragmove' && this.dropTarget) {\n dropEvents.move = {\n target : this.dropElement,\n dropzone : this.dropTarget,\n relatedTarget: dragEvent.target,\n draggable : dragEvent.interactable,\n dragEvent : dragEvent,\n interaction : this,\n dragmove : dragEvent,\n timeStamp : dragEvent.timeStamp,\n type : 'dropmove'\n };\n dragEvent.dropzone = this.dropTarget;\n }\n\n return dropEvents;\n },\n\n currentAction: function () {\n return (this.dragging && 'drag') || (this.resizing && 'resize') || (this.gesturing && 'gesture') || null;\n },\n\n interacting: function () {\n return this.dragging || this.resizing || this.gesturing;\n },\n\n clearTargets: function () {\n this.target = this.element = null;\n\n this.dropTarget = this.dropElement = this.prevDropTarget = this.prevDropElement = null;\n },\n\n stop: function (event) {\n if (this.interacting()) {\n autoScroll.stop();\n this.matches = [];\n this.matchElements = [];\n\n var target = this.target;\n\n if (target.options.styleCursor) {\n target._doc.documentElement.style.cursor = '';\n }\n\n // prevent Default only if were previously interacting\n if (event && isFunction(event.preventDefault)) {\n this.checkAndPreventDefault(event, target, this.element);\n }\n\n if (this.dragging) {\n this.activeDrops.dropzones = this.activeDrops.elements = this.activeDrops.rects = null;\n }\n }\n\n this.clearTargets();\n\n this.pointerIsDown = this.snapStatus.locked = this.dragging = this.resizing = this.gesturing = false;\n this.prepared.name = this.prevEvent = null;\n this.inertiaStatus.resumeDx = this.inertiaStatus.resumeDy = 0;\n\n // remove pointers if their ID isn't in this.pointerIds\n for (var i = 0; i < this.pointers.length; i++) {\n if (indexOf(this.pointerIds, getPointerId(this.pointers[i])) === -1) {\n this.pointers.splice(i, 1);\n }\n }\n },\n\n inertiaFrame: function () {\n var inertiaStatus = this.inertiaStatus,\n options = this.target.options[this.prepared.name].inertia,\n lambda = options.resistance,\n t = new Date().getTime() / 1000 - inertiaStatus.t0;\n\n if (t < inertiaStatus.te) {\n\n var progress = 1 - (Math.exp(-lambda * t) - inertiaStatus.lambda_v0) / inertiaStatus.one_ve_v0;\n\n if (inertiaStatus.modifiedXe === inertiaStatus.xe && inertiaStatus.modifiedYe === inertiaStatus.ye) {\n inertiaStatus.sx = inertiaStatus.xe * progress;\n inertiaStatus.sy = inertiaStatus.ye * progress;\n }\n else {\n var quadPoint = getQuadraticCurvePoint(\n 0, 0,\n inertiaStatus.xe, inertiaStatus.ye,\n inertiaStatus.modifiedXe, inertiaStatus.modifiedYe,\n progress);\n\n inertiaStatus.sx = quadPoint.x;\n inertiaStatus.sy = quadPoint.y;\n }\n\n this.pointerMove(inertiaStatus.startEvent, inertiaStatus.startEvent);\n\n inertiaStatus.i = reqFrame(this.boundInertiaFrame);\n }\n else {\n inertiaStatus.ending = true;\n\n inertiaStatus.sx = inertiaStatus.modifiedXe;\n inertiaStatus.sy = inertiaStatus.modifiedYe;\n\n this.pointerMove(inertiaStatus.startEvent, inertiaStatus.startEvent);\n this.pointerEnd(inertiaStatus.startEvent, inertiaStatus.startEvent);\n\n inertiaStatus.active = inertiaStatus.ending = false;\n }\n },\n\n smoothEndFrame: function () {\n var inertiaStatus = this.inertiaStatus,\n t = new Date().getTime() - inertiaStatus.t0,\n duration = this.target.options[this.prepared.name].inertia.smoothEndDuration;\n\n if (t < duration) {\n inertiaStatus.sx = easeOutQuad(t, 0, inertiaStatus.xe, duration);\n inertiaStatus.sy = easeOutQuad(t, 0, inertiaStatus.ye, duration);\n\n this.pointerMove(inertiaStatus.startEvent, inertiaStatus.startEvent);\n\n inertiaStatus.i = reqFrame(this.boundSmoothEndFrame);\n }\n else {\n inertiaStatus.ending = true;\n\n inertiaStatus.sx = inertiaStatus.xe;\n inertiaStatus.sy = inertiaStatus.ye;\n\n this.pointerMove(inertiaStatus.startEvent, inertiaStatus.startEvent);\n this.pointerEnd(inertiaStatus.startEvent, inertiaStatus.startEvent);\n\n inertiaStatus.smoothEnd =\n inertiaStatus.active = inertiaStatus.ending = false;\n }\n },\n\n addPointer: function (pointer) {\n var id = getPointerId(pointer),\n index = this.mouse? 0 : indexOf(this.pointerIds, id);\n\n if (index === -1) {\n index = this.pointerIds.length;\n }\n\n this.pointerIds[index] = id;\n this.pointers[index] = pointer;\n\n return index;\n },\n\n removePointer: function (pointer) {\n var id = getPointerId(pointer),\n index = this.mouse? 0 : indexOf(this.pointerIds, id);\n\n if (index === -1) { return; }\n\n this.pointers .splice(index, 1);\n this.pointerIds .splice(index, 1);\n this.downTargets.splice(index, 1);\n this.downTimes .splice(index, 1);\n this.holdTimers .splice(index, 1);\n },\n\n recordPointer: function (pointer) {\n var index = this.mouse? 0: indexOf(this.pointerIds, getPointerId(pointer));\n\n if (index === -1) { return; }\n\n this.pointers[index] = pointer;\n },\n\n collectEventTargets: function (pointer, event, eventTarget, eventType) {\n var pointerIndex = this.mouse? 0 : indexOf(this.pointerIds, getPointerId(pointer));\n\n // do not fire a tap event if the pointer was moved before being lifted\n if (eventType === 'tap' && (this.pointerWasMoved\n // or if the pointerup target is different to the pointerdown target\n || !(this.downTargets[pointerIndex] && this.downTargets[pointerIndex] === eventTarget))) {\n return;\n }\n\n var targets = [],\n elements = [],\n element = eventTarget;\n\n function collectSelectors (interactable, selector, context) {\n var els = ie8MatchesSelector\n ? context.querySelectorAll(selector)\n : undefined;\n\n if (interactable._iEvents[eventType]\n && isElement(element)\n && inContext(interactable, element)\n && !testIgnore(interactable, element, eventTarget)\n && testAllow(interactable, element, eventTarget)\n && matchesSelector(element, selector, els)) {\n\n targets.push(interactable);\n elements.push(element);\n }\n }\n\n while (element) {\n if (interact.isSet(element) && interact(element)._iEvents[eventType]) {\n targets.push(interact(element));\n elements.push(element);\n }\n\n interactables.forEachSelector(collectSelectors);\n\n element = parentElement(element);\n }\n\n // create the tap event even if there are no listeners so that\n // doubletap can still be created and fired\n if (targets.length || eventType === 'tap') {\n this.firePointers(pointer, event, eventTarget, targets, elements, eventType);\n }\n },\n\n firePointers: function (pointer, event, eventTarget, targets, elements, eventType) {\n var pointerIndex = this.mouse? 0 : indexOf(this.pointerIds, getPointerId(pointer)),\n pointerEvent = {},\n i,\n // for tap events\n interval, createNewDoubleTap;\n\n // if it's a doubletap then the event properties would have been\n // copied from the tap event and provided as the pointer argument\n if (eventType === 'doubletap') {\n pointerEvent = pointer;\n }\n else {\n pointerExtend(pointerEvent, event);\n if (event !== pointer) {\n pointerExtend(pointerEvent, pointer);\n }\n\n pointerEvent.preventDefault = preventOriginalDefault;\n pointerEvent.stopPropagation = InteractEvent.prototype.stopPropagation;\n pointerEvent.stopImmediatePropagation = InteractEvent.prototype.stopImmediatePropagation;\n pointerEvent.interaction = this;\n\n pointerEvent.timeStamp = new Date().getTime();\n pointerEvent.originalEvent = event;\n pointerEvent.originalPointer = pointer;\n pointerEvent.type = eventType;\n pointerEvent.pointerId = getPointerId(pointer);\n pointerEvent.pointerType = this.mouse? 'mouse' : !supportsPointerEvent? 'touch'\n : isString(pointer.pointerType)\n ? pointer.pointerType\n : [,,'touch', 'pen', 'mouse'][pointer.pointerType];\n }\n\n if (eventType === 'tap') {\n pointerEvent.dt = pointerEvent.timeStamp - this.downTimes[pointerIndex];\n\n interval = pointerEvent.timeStamp - this.tapTime;\n createNewDoubleTap = !!(this.prevTap && this.prevTap.type !== 'doubletap'\n && this.prevTap.target === pointerEvent.target\n && interval < 500);\n\n pointerEvent.double = createNewDoubleTap;\n\n this.tapTime = pointerEvent.timeStamp;\n }\n\n for (i = 0; i < targets.length; i++) {\n pointerEvent.currentTarget = elements[i];\n pointerEvent.interactable = targets[i];\n targets[i].fire(pointerEvent);\n\n if (pointerEvent.immediatePropagationStopped\n ||(pointerEvent.propagationStopped && elements[i + 1] !== pointerEvent.currentTarget)) {\n break;\n }\n }\n\n if (createNewDoubleTap) {\n var doubleTap = {};\n\n extend(doubleTap, pointerEvent);\n\n doubleTap.dt = interval;\n doubleTap.type = 'doubletap';\n\n this.collectEventTargets(doubleTap, event, eventTarget, 'doubletap');\n\n this.prevTap = doubleTap;\n }\n else if (eventType === 'tap') {\n this.prevTap = pointerEvent;\n }\n },\n\n validateSelector: function (pointer, event, matches, matchElements) {\n for (var i = 0, len = matches.length; i < len; i++) {\n var match = matches[i],\n matchElement = matchElements[i],\n action = validateAction(match.getAction(pointer, event, this, matchElement), match);\n\n if (action && withinInteractionLimit(match, matchElement, action)) {\n this.target = match;\n this.element = matchElement;\n\n return action;\n }\n }\n },\n\n setSnapping: function (pageCoords, status) {\n var snap = this.target.options[this.prepared.name].snap,\n targets = [],\n target,\n page,\n i;\n\n status = status || this.snapStatus;\n\n if (status.useStatusXY) {\n page = { x: status.x, y: status.y };\n }\n else {\n var origin = getOriginXY(this.target, this.element);\n\n page = extend({}, pageCoords);\n\n page.x -= origin.x;\n page.y -= origin.y;\n }\n\n status.realX = page.x;\n status.realY = page.y;\n\n page.x = page.x - this.inertiaStatus.resumeDx;\n page.y = page.y - this.inertiaStatus.resumeDy;\n\n var len = snap.targets? snap.targets.length : 0;\n\n for (var relIndex = 0; relIndex < this.snapOffsets.length; relIndex++) {\n var relative = {\n x: page.x - this.snapOffsets[relIndex].x,\n y: page.y - this.snapOffsets[relIndex].y\n };\n\n for (i = 0; i < len; i++) {\n if (isFunction(snap.targets[i])) {\n target = snap.targets[i](relative.x, relative.y, this);\n }\n else {\n target = snap.targets[i];\n }\n\n if (!target) { continue; }\n\n targets.push({\n x: isNumber(target.x) ? (target.x + this.snapOffsets[relIndex].x) : relative.x,\n y: isNumber(target.y) ? (target.y + this.snapOffsets[relIndex].y) : relative.y,\n\n range: isNumber(target.range)? target.range: snap.range\n });\n }\n }\n\n var closest = {\n target: null,\n inRange: false,\n distance: 0,\n range: 0,\n dx: 0,\n dy: 0\n };\n\n for (i = 0, len = targets.length; i < len; i++) {\n target = targets[i];\n\n var range = target.range,\n dx = target.x - page.x,\n dy = target.y - page.y,\n distance = hypot(dx, dy),\n inRange = distance <= range;\n\n // Infinite targets count as being out of range\n // compared to non infinite ones that are in range\n if (range === Infinity && closest.inRange && closest.range !== Infinity) {\n inRange = false;\n }\n\n if (!closest.target || (inRange\n // is the closest target in range?\n ? (closest.inRange && range !== Infinity\n // the pointer is relatively deeper in this target\n ? distance / range < closest.distance / closest.range\n // this target has Infinite range and the closest doesn't\n : (range === Infinity && closest.range !== Infinity)\n // OR this target is closer that the previous closest\n || distance < closest.distance)\n // The other is not in range and the pointer is closer to this target\n : (!closest.inRange && distance < closest.distance))) {\n\n if (range === Infinity) {\n inRange = true;\n }\n\n closest.target = target;\n closest.distance = distance;\n closest.range = range;\n closest.inRange = inRange;\n closest.dx = dx;\n closest.dy = dy;\n\n status.range = range;\n }\n }\n\n var snapChanged;\n\n if (closest.target) {\n snapChanged = (status.snappedX !== closest.target.x || status.snappedY !== closest.target.y);\n\n status.snappedX = closest.target.x;\n status.snappedY = closest.target.y;\n }\n else {\n snapChanged = true;\n\n status.snappedX = NaN;\n status.snappedY = NaN;\n }\n\n status.dx = closest.dx;\n status.dy = closest.dy;\n\n status.changed = (snapChanged || (closest.inRange && !status.locked));\n status.locked = closest.inRange;\n\n return status;\n },\n\n setRestriction: function (pageCoords, status) {\n var target = this.target,\n restrict = target && target.options[this.prepared.name].restrict,\n restriction = restrict && restrict.restriction,\n page;\n\n if (!restriction) {\n return status;\n }\n\n status = status || this.restrictStatus;\n\n page = status.useStatusXY\n ? page = { x: status.x, y: status.y }\n : page = extend({}, pageCoords);\n\n if (status.snap && status.snap.locked) {\n page.x += status.snap.dx || 0;\n page.y += status.snap.dy || 0;\n }\n\n page.x -= this.inertiaStatus.resumeDx;\n page.y -= this.inertiaStatus.resumeDy;\n\n status.dx = 0;\n status.dy = 0;\n status.restricted = false;\n\n var rect, restrictedX, restrictedY;\n\n if (isString(restriction)) {\n if (restriction === 'parent') {\n restriction = parentElement(this.element);\n }\n else if (restriction === 'self') {\n restriction = target.getRect(this.element);\n }\n else {\n restriction = closest(this.element, restriction);\n }\n\n if (!restriction) { return status; }\n }\n\n if (isFunction(restriction)) {\n restriction = restriction(page.x, page.y, this.element);\n }\n\n if (isElement(restriction)) {\n restriction = getElementRect(restriction);\n }\n\n rect = restriction;\n\n if (!restriction) {\n restrictedX = page.x;\n restrictedY = page.y;\n }\n // object is assumed to have\n // x, y, width, height or\n // left, top, right, bottom\n else if ('x' in restriction && 'y' in restriction) {\n restrictedX = Math.max(Math.min(rect.x + rect.width - this.restrictOffset.right , page.x), rect.x + this.restrictOffset.left);\n restrictedY = Math.max(Math.min(rect.y + rect.height - this.restrictOffset.bottom, page.y), rect.y + this.restrictOffset.top );\n }\n else {\n restrictedX = Math.max(Math.min(rect.right - this.restrictOffset.right , page.x), rect.left + this.restrictOffset.left);\n restrictedY = Math.max(Math.min(rect.bottom - this.restrictOffset.bottom, page.y), rect.top + this.restrictOffset.top );\n }\n\n status.dx = restrictedX - page.x;\n status.dy = restrictedY - page.y;\n\n status.changed = status.restrictedX !== restrictedX || status.restrictedY !== restrictedY;\n status.restricted = !!(status.dx || status.dy);\n\n status.restrictedX = restrictedX;\n status.restrictedY = restrictedY;\n\n return status;\n },\n\n checkAndPreventDefault: function (event, interactable, element) {\n if (!(interactable = interactable || this.target)) { return; }\n\n var options = interactable.options,\n prevent = options.preventDefault;\n\n if (prevent === 'auto' && element && !/^(input|select|textarea)$/i.test(event.target.nodeName)) {\n // do not preventDefault on pointerdown if the prepared action is a drag\n // and dragging can only start from a certain direction - this allows\n // a touch to pan the viewport if a drag isn't in the right direction\n if (/down|start/i.test(event.type)\n && this.prepared.name === 'drag' && options.drag.axis !== 'xy') {\n\n return;\n }\n\n // with manualStart, only preventDefault while interacting\n if (options[this.prepared.name] && options[this.prepared.name].manualStart\n && !this.interacting()) {\n return;\n }\n\n event.preventDefault();\n return;\n }\n\n if (prevent === 'always') {\n event.preventDefault();\n return;\n }\n },\n\n calcInertia: function (status) {\n var inertiaOptions = this.target.options[this.prepared.name].inertia,\n lambda = inertiaOptions.resistance,\n inertiaDur = -Math.log(inertiaOptions.endSpeed / status.v0) / lambda;\n\n status.x0 = this.prevEvent.pageX;\n status.y0 = this.prevEvent.pageY;\n status.t0 = status.startEvent.timeStamp / 1000;\n status.sx = status.sy = 0;\n\n status.modifiedXe = status.xe = (status.vx0 - inertiaDur) / lambda;\n status.modifiedYe = status.ye = (status.vy0 - inertiaDur) / lambda;\n status.te = inertiaDur;\n\n status.lambda_v0 = lambda / status.v0;\n status.one_ve_v0 = 1 - inertiaOptions.endSpeed / status.v0;\n },\n\n autoScrollMove: function (pointer) {\n if (!(this.interacting()\n && checkAutoScroll(this.target, this.prepared.name))) {\n return;\n }\n\n if (this.inertiaStatus.active) {\n autoScroll.x = autoScroll.y = 0;\n return;\n }\n\n var top,\n right,\n bottom,\n left,\n options = this.target.options[this.prepared.name].autoScroll,\n container = options.container || getWindow(this.element);\n\n if (isWindow(container)) {\n left = pointer.clientX < autoScroll.margin;\n top = pointer.clientY < autoScroll.margin;\n right = pointer.clientX > container.innerWidth - autoScroll.margin;\n bottom = pointer.clientY > container.innerHeight - autoScroll.margin;\n }\n else {\n var rect = getElementClientRect(container);\n\n left = pointer.clientX < rect.left + autoScroll.margin;\n top = pointer.clientY < rect.top + autoScroll.margin;\n right = pointer.clientX > rect.right - autoScroll.margin;\n bottom = pointer.clientY > rect.bottom - autoScroll.margin;\n }\n\n autoScroll.x = (right ? 1: left? -1: 0);\n autoScroll.y = (bottom? 1: top? -1: 0);\n\n if (!autoScroll.isScrolling) {\n // set the autoScroll properties to those of the target\n autoScroll.margin = options.margin;\n autoScroll.speed = options.speed;\n\n autoScroll.start(this);\n }\n },\n\n _updateEventTargets: function (target, currentTarget) {\n this._eventTarget = target;\n this._curEventTarget = currentTarget;\n }\n\n };\n\n function getInteractionFromPointer (pointer, eventType, eventTarget) {\n var i = 0, len = interactions.length,\n mouseEvent = (/mouse/i.test(pointer.pointerType || eventType)\n // MSPointerEvent.MSPOINTER_TYPE_MOUSE\n || pointer.pointerType === 4),\n interaction;\n\n var id = getPointerId(pointer);\n\n // try to resume inertia with a new pointer\n if (/down|start/i.test(eventType)) {\n for (i = 0; i < len; i++) {\n interaction = interactions[i];\n\n var element = eventTarget;\n\n if (interaction.inertiaStatus.active && interaction.target.options[interaction.prepared.name].inertia.allowResume\n && (interaction.mouse === mouseEvent)) {\n while (element) {\n // if the element is the interaction element\n if (element === interaction.element) {\n return interaction;\n }\n element = parentElement(element);\n }\n }\n }\n }\n\n // if it's a mouse interaction\n if (mouseEvent || !(supportsTouch || supportsPointerEvent)) {\n\n // find a mouse interaction that's not in inertia phase\n for (i = 0; i < len; i++) {\n if (interactions[i].mouse && !interactions[i].inertiaStatus.active) {\n return interactions[i];\n }\n }\n\n // find any interaction specifically for mouse.\n // if the eventType is a mousedown, and inertia is active\n // ignore the interaction\n for (i = 0; i < len; i++) {\n if (interactions[i].mouse && !(/down/.test(eventType) && interactions[i].inertiaStatus.active)) {\n return interaction;\n }\n }\n\n // create a new interaction for mouse\n interaction = new Interaction();\n interaction.mouse = true;\n\n return interaction;\n }\n\n // get interaction that has this pointer\n for (i = 0; i < len; i++) {\n if (contains(interactions[i].pointerIds, id)) {\n return interactions[i];\n }\n }\n\n // at this stage, a pointerUp should not return an interaction\n if (/up|end|out/i.test(eventType)) {\n return null;\n }\n\n // get first idle interaction\n for (i = 0; i < len; i++) {\n interaction = interactions[i];\n\n if ((!interaction.prepared.name || (interaction.target.options.gesture.enabled))\n && !interaction.interacting()\n && !(!mouseEvent && interaction.mouse)) {\n\n return interaction;\n }\n }\n\n return new Interaction();\n }\n\n function doOnInteractions (method) {\n return (function (event) {\n var interaction,\n eventTarget = getActualElement(event.path\n ? event.path[0]\n : event.target),\n curEventTarget = getActualElement(event.currentTarget),\n i;\n\n if (supportsTouch && /touch/.test(event.type)) {\n prevTouchTime = new Date().getTime();\n\n for (i = 0; i < event.changedTouches.length; i++) {\n var pointer = event.changedTouches[i];\n\n interaction = getInteractionFromPointer(pointer, event.type, eventTarget);\n\n if (!interaction) { continue; }\n\n interaction._updateEventTargets(eventTarget, curEventTarget);\n\n interaction[method](pointer, event, eventTarget, curEventTarget);\n }\n }\n else {\n if (!supportsPointerEvent && /mouse/.test(event.type)) {\n // ignore mouse events while touch interactions are active\n for (i = 0; i < interactions.length; i++) {\n if (!interactions[i].mouse && interactions[i].pointerIsDown) {\n return;\n }\n }\n\n // try to ignore mouse events that are simulated by the browser\n // after a touch event\n if (new Date().getTime() - prevTouchTime < 500) {\n return;\n }\n }\n\n interaction = getInteractionFromPointer(event, event.type, eventTarget);\n\n if (!interaction) { return; }\n\n interaction._updateEventTargets(eventTarget, curEventTarget);\n\n interaction[method](event, event, eventTarget, curEventTarget);\n }\n });\n }\n\n function InteractEvent (interaction, event, action, phase, element, related) {\n var client,\n page,\n target = interaction.target,\n snapStatus = interaction.snapStatus,\n restrictStatus = interaction.restrictStatus,\n pointers = interaction.pointers,\n deltaSource = (target && target.options || defaultOptions).deltaSource,\n sourceX = deltaSource + 'X',\n sourceY = deltaSource + 'Y',\n options = target? target.options: defaultOptions,\n origin = getOriginXY(target, element),\n starting = phase === 'start',\n ending = phase === 'end',\n coords = starting? interaction.startCoords : interaction.curCoords;\n\n element = element || interaction.element;\n\n page = extend({}, coords.page);\n client = extend({}, coords.client);\n\n page.x -= origin.x;\n page.y -= origin.y;\n\n client.x -= origin.x;\n client.y -= origin.y;\n\n var relativePoints = options[action].snap && options[action].snap.relativePoints ;\n\n if (checkSnap(target, action) && !(starting && relativePoints && relativePoints.length)) {\n this.snap = {\n range : snapStatus.range,\n locked : snapStatus.locked,\n x : snapStatus.snappedX,\n y : snapStatus.snappedY,\n realX : snapStatus.realX,\n realY : snapStatus.realY,\n dx : snapStatus.dx,\n dy : snapStatus.dy\n };\n\n if (snapStatus.locked) {\n page.x += snapStatus.dx;\n page.y += snapStatus.dy;\n client.x += snapStatus.dx;\n client.y += snapStatus.dy;\n }\n }\n\n if (checkRestrict(target, action) && !(starting && options[action].restrict.elementRect) && restrictStatus.restricted) {\n page.x += restrictStatus.dx;\n page.y += restrictStatus.dy;\n client.x += restrictStatus.dx;\n client.y += restrictStatus.dy;\n\n this.restrict = {\n dx: restrictStatus.dx,\n dy: restrictStatus.dy\n };\n }\n\n this.pageX = page.x;\n this.pageY = page.y;\n this.clientX = client.x;\n this.clientY = client.y;\n\n this.x0 = interaction.startCoords.page.x - origin.x;\n this.y0 = interaction.startCoords.page.y - origin.y;\n this.clientX0 = interaction.startCoords.client.x - origin.x;\n this.clientY0 = interaction.startCoords.client.y - origin.y;\n this.ctrlKey = event.ctrlKey;\n this.altKey = event.altKey;\n this.shiftKey = event.shiftKey;\n this.metaKey = event.metaKey;\n this.button = event.button;\n this.buttons = event.buttons;\n this.target = element;\n this.t0 = interaction.downTimes[0];\n this.type = action + (phase || '');\n\n this.interaction = interaction;\n this.interactable = target;\n\n var inertiaStatus = interaction.inertiaStatus;\n\n if (inertiaStatus.active) {\n this.detail = 'inertia';\n }\n\n if (related) {\n this.relatedTarget = related;\n }\n\n // end event dx, dy is difference between start and end points\n if (ending) {\n if (deltaSource === 'client') {\n this.dx = client.x - interaction.startCoords.client.x;\n this.dy = client.y - interaction.startCoords.client.y;\n }\n else {\n this.dx = page.x - interaction.startCoords.page.x;\n this.dy = page.y - interaction.startCoords.page.y;\n }\n }\n else if (starting) {\n this.dx = 0;\n this.dy = 0;\n }\n // copy properties from previousmove if starting inertia\n else if (phase === 'inertiastart') {\n this.dx = interaction.prevEvent.dx;\n this.dy = interaction.prevEvent.dy;\n }\n else {\n if (deltaSource === 'client') {\n this.dx = client.x - interaction.prevEvent.clientX;\n this.dy = client.y - interaction.prevEvent.clientY;\n }\n else {\n this.dx = page.x - interaction.prevEvent.pageX;\n this.dy = page.y - interaction.prevEvent.pageY;\n }\n }\n if (interaction.prevEvent && interaction.prevEvent.detail === 'inertia'\n && !inertiaStatus.active\n && options[action].inertia && options[action].inertia.zeroResumeDelta) {\n\n inertiaStatus.resumeDx += this.dx;\n inertiaStatus.resumeDy += this.dy;\n\n this.dx = this.dy = 0;\n }\n\n if (action === 'resize' && interaction.resizeAxes) {\n if (options.resize.square) {\n if (interaction.resizeAxes === 'y') {\n this.dx = this.dy;\n }\n else {\n this.dy = this.dx;\n }\n this.axes = 'xy';\n }\n else {\n this.axes = interaction.resizeAxes;\n\n if (interaction.resizeAxes === 'x') {\n this.dy = 0;\n }\n else if (interaction.resizeAxes === 'y') {\n this.dx = 0;\n }\n }\n }\n else if (action === 'gesture') {\n this.touches = [pointers[0], pointers[1]];\n\n if (starting) {\n this.distance = touchDistance(pointers, deltaSource);\n this.box = touchBBox(pointers);\n this.scale = 1;\n this.ds = 0;\n this.angle = touchAngle(pointers, undefined, deltaSource);\n this.da = 0;\n }\n else if (ending || event instanceof InteractEvent) {\n this.distance = interaction.prevEvent.distance;\n this.box = interaction.prevEvent.box;\n this.scale = interaction.prevEvent.scale;\n this.ds = this.scale - 1;\n this.angle = interaction.prevEvent.angle;\n this.da = this.angle - interaction.gesture.startAngle;\n }\n else {\n this.distance = touchDistance(pointers, deltaSource);\n this.box = touchBBox(pointers);\n this.scale = this.distance / interaction.gesture.startDistance;\n this.angle = touchAngle(pointers, interaction.gesture.prevAngle, deltaSource);\n\n this.ds = this.scale - interaction.gesture.prevScale;\n this.da = this.angle - interaction.gesture.prevAngle;\n }\n }\n\n if (starting) {\n this.timeStamp = interaction.downTimes[0];\n this.dt = 0;\n this.duration = 0;\n this.speed = 0;\n this.velocityX = 0;\n this.velocityY = 0;\n }\n else if (phase === 'inertiastart') {\n this.timeStamp = interaction.prevEvent.timeStamp;\n this.dt = interaction.prevEvent.dt;\n this.duration = interaction.prevEvent.duration;\n this.speed = interaction.prevEvent.speed;\n this.velocityX = interaction.prevEvent.velocityX;\n this.velocityY = interaction.prevEvent.velocityY;\n }\n else {\n this.timeStamp = new Date().getTime();\n this.dt = this.timeStamp - interaction.prevEvent.timeStamp;\n this.duration = this.timeStamp - interaction.downTimes[0];\n\n if (event instanceof InteractEvent) {\n var dx = this[sourceX] - interaction.prevEvent[sourceX],\n dy = this[sourceY] - interaction.prevEvent[sourceY],\n dt = this.dt / 1000;\n\n this.speed = hypot(dx, dy) / dt;\n this.velocityX = dx / dt;\n this.velocityY = dy / dt;\n }\n // if normal move or end event, use previous user event coords\n else {\n // speed and velocity in pixels per second\n this.speed = interaction.pointerDelta[deltaSource].speed;\n this.velocityX = interaction.pointerDelta[deltaSource].vx;\n this.velocityY = interaction.pointerDelta[deltaSource].vy;\n }\n }\n\n if ((ending || phase === 'inertiastart')\n && interaction.prevEvent.speed > 600 && this.timeStamp - interaction.prevEvent.timeStamp < 150) {\n\n var angle = 180 * Math.atan2(interaction.prevEvent.velocityY, interaction.prevEvent.velocityX) / Math.PI,\n overlap = 22.5;\n\n if (angle < 0) {\n angle += 360;\n }\n\n var left = 135 - overlap <= angle && angle < 225 + overlap,\n up = 225 - overlap <= angle && angle < 315 + overlap,\n\n right = !left && (315 - overlap <= angle || angle < 45 + overlap),\n down = !up && 45 - overlap <= angle && angle < 135 + overlap;\n\n this.swipe = {\n up : up,\n down : down,\n left : left,\n right: right,\n angle: angle,\n speed: interaction.prevEvent.speed,\n velocity: {\n x: interaction.prevEvent.velocityX,\n y: interaction.prevEvent.velocityY\n }\n };\n }\n }\n\n InteractEvent.prototype = {\n preventDefault: blank,\n stopImmediatePropagation: function () {\n this.immediatePropagationStopped = this.propagationStopped = true;\n },\n stopPropagation: function () {\n this.propagationStopped = true;\n }\n };\n\n function preventOriginalDefault () {\n this.originalEvent.preventDefault();\n }\n\n function getActionCursor (action) {\n var cursor = '';\n\n if (action.name === 'drag') {\n cursor = actionCursors.drag;\n }\n if (action.name === 'resize') {\n if (action.axis) {\n cursor = actionCursors[action.name + action.axis];\n }\n else if (action.edges) {\n var cursorKey = 'resize',\n edgeNames = ['top', 'bottom', 'left', 'right'];\n\n for (var i = 0; i < 4; i++) {\n if (action.edges[edgeNames[i]]) {\n cursorKey += edgeNames[i];\n }\n }\n\n cursor = actionCursors[cursorKey];\n }\n }\n\n return cursor;\n }\n\n function checkResizeEdge (name, value, page, element, interactableElement, rect, margin) {\n // false, '', undefined, null\n if (!value) { return false; }\n\n // true value, use pointer coords and element rect\n if (value === true) {\n // if dimensions are negative, \"switch\" edges\n var width = isNumber(rect.width)? rect.width : rect.right - rect.left,\n height = isNumber(rect.height)? rect.height : rect.bottom - rect.top;\n\n if (width < 0) {\n if (name === 'left' ) { name = 'right'; }\n else if (name === 'right') { name = 'left' ; }\n }\n if (height < 0) {\n if (name === 'top' ) { name = 'bottom'; }\n else if (name === 'bottom') { name = 'top' ; }\n }\n\n if (name === 'left' ) { return page.x < ((width >= 0? rect.left: rect.right ) + margin); }\n if (name === 'top' ) { return page.y < ((height >= 0? rect.top : rect.bottom) + margin); }\n\n if (name === 'right' ) { return page.x > ((width >= 0? rect.right : rect.left) - margin); }\n if (name === 'bottom') { return page.y > ((height >= 0? rect.bottom: rect.top ) - margin); }\n }\n\n // the remaining checks require an element\n if (!isElement(element)) { return false; }\n\n return isElement(value)\n // the value is an element to use as a resize handle\n ? value === element\n // otherwise check if element matches value as selector\n : matchesUpTo(element, value, interactableElement);\n }\n\n function defaultActionChecker (pointer, interaction, element) {\n var rect = this.getRect(element),\n shouldResize = false,\n action = null,\n resizeAxes = null,\n resizeEdges,\n page = extend({}, interaction.curCoords.page),\n options = this.options;\n\n if (!rect) { return null; }\n\n if (actionIsEnabled.resize && options.resize.enabled) {\n var resizeOptions = options.resize;\n\n resizeEdges = {\n left: false, right: false, top: false, bottom: false\n };\n\n // if using resize.edges\n if (isObject(resizeOptions.edges)) {\n for (var edge in resizeEdges) {\n resizeEdges[edge] = checkResizeEdge(edge,\n resizeOptions.edges[edge],\n page,\n interaction._eventTarget,\n element,\n rect,\n resizeOptions.margin || margin);\n }\n\n resizeEdges.left = resizeEdges.left && !resizeEdges.right;\n resizeEdges.top = resizeEdges.top && !resizeEdges.bottom;\n\n shouldResize = resizeEdges.left || resizeEdges.right || resizeEdges.top || resizeEdges.bottom;\n }\n else {\n var right = options.resize.axis !== 'y' && page.x > (rect.right - margin),\n bottom = options.resize.axis !== 'x' && page.y > (rect.bottom - margin);\n\n shouldResize = right || bottom;\n resizeAxes = (right? 'x' : '') + (bottom? 'y' : '');\n }\n }\n\n action = shouldResize\n ? 'resize'\n : actionIsEnabled.drag && options.drag.enabled\n ? 'drag'\n : null;\n\n if (actionIsEnabled.gesture\n && interaction.pointerIds.length >=2\n && !(interaction.dragging || interaction.resizing)) {\n action = 'gesture';\n }\n\n if (action) {\n return {\n name: action,\n axis: resizeAxes,\n edges: resizeEdges\n };\n }\n\n return null;\n }\n\n // Check if action is enabled globally and the current target supports it\n // If so, return the validated action. Otherwise, return null\n function validateAction (action, interactable) {\n if (!isObject(action)) { return null; }\n\n var actionName = action.name,\n options = interactable.options;\n\n if (( (actionName === 'resize' && options.resize.enabled )\n || (actionName === 'drag' && options.drag.enabled )\n || (actionName === 'gesture' && options.gesture.enabled))\n && actionIsEnabled[actionName]) {\n\n if (actionName === 'resize' || actionName === 'resizeyx') {\n actionName = 'resizexy';\n }\n\n return action;\n }\n return null;\n }\n\n var listeners = {},\n interactionListeners = [\n 'dragStart', 'dragMove', 'resizeStart', 'resizeMove', 'gestureStart', 'gestureMove',\n 'pointerOver', 'pointerOut', 'pointerHover', 'selectorDown',\n 'pointerDown', 'pointerMove', 'pointerUp', 'pointerCancel', 'pointerEnd',\n 'addPointer', 'removePointer', 'recordPointer', 'autoScrollMove'\n ];\n\n for (var i = 0, len = interactionListeners.length; i < len; i++) {\n var name = interactionListeners[i];\n\n listeners[name] = doOnInteractions(name);\n }\n\n // bound to the interactable context when a DOM event\n // listener is added to a selector interactable\n function delegateListener (event, useCapture) {\n var fakeEvent = {},\n delegated = delegatedEvents[event.type],\n eventTarget = getActualElement(event.path\n ? event.path[0]\n : event.target),\n element = eventTarget;\n\n useCapture = useCapture? true: false;\n\n // duplicate the event so that currentTarget can be changed\n for (var prop in event) {\n fakeEvent[prop] = event[prop];\n }\n\n fakeEvent.originalEvent = event;\n fakeEvent.preventDefault = preventOriginalDefault;\n\n // climb up document tree looking for selector matches\n while (isElement(element)) {\n for (var i = 0; i < delegated.selectors.length; i++) {\n var selector = delegated.selectors[i],\n context = delegated.contexts[i];\n\n if (matchesSelector(element, selector)\n && nodeContains(context, eventTarget)\n && nodeContains(context, element)) {\n\n var listeners = delegated.listeners[i];\n\n fakeEvent.currentTarget = element;\n\n for (var j = 0; j < listeners.length; j++) {\n if (listeners[j][1] === useCapture) {\n listeners[j][0](fakeEvent);\n }\n }\n }\n }\n\n element = parentElement(element);\n }\n }\n\n function delegateUseCapture (event) {\n return delegateListener.call(this, event, true);\n }\n\n interactables.indexOfElement = function indexOfElement (element, context) {\n context = context || document;\n\n for (var i = 0; i < this.length; i++) {\n var interactable = this[i];\n\n if ((interactable.selector === element\n && (interactable._context === context))\n || (!interactable.selector && interactable._element === element)) {\n\n return i;\n }\n }\n return -1;\n };\n\n interactables.get = function interactableGet (element, options) {\n return this[this.indexOfElement(element, options && options.context)];\n };\n\n interactables.forEachSelector = function (callback) {\n for (var i = 0; i < this.length; i++) {\n var interactable = this[i];\n\n if (!interactable.selector) {\n continue;\n }\n\n var ret = callback(interactable, interactable.selector, interactable._context, i, this);\n\n if (ret !== undefined) {\n return ret;\n }\n }\n };\n\n /*\\\n * interact\n [ method ]\n *\n * The methods of this variable can be used to set elements as\n * interactables and also to change various default settings.\n *\n * Calling it as a function and passing an element or a valid CSS selector\n * string returns an Interactable object which has various methods to\n * configure it.\n *\n - element (Element | string) The HTML or SVG Element to interact with or CSS selector\n = (object) An @Interactable\n *\n > Usage\n | interact(document.getElementById('draggable')).draggable(true);\n |\n | var rectables = interact('rect');\n | rectables\n | .gesturable(true)\n | .on('gesturemove', function (event) {\n | // something cool...\n | })\n | .autoScroll(true);\n \\*/\n function interact (element, options) {\n return interactables.get(element, options) || new Interactable(element, options);\n }\n\n /*\\\n * Interactable\n [ property ]\n **\n * Object type returned by @interact\n \\*/\n function Interactable (element, options) {\n this._element = element;\n this._iEvents = this._iEvents || {};\n\n var _window;\n\n if (trySelector(element)) {\n this.selector = element;\n\n var context = options && options.context;\n\n _window = context? getWindow(context) : window;\n\n if (context && (_window.Node\n ? context instanceof _window.Node\n : (isElement(context) || context === _window.document))) {\n\n this._context = context;\n }\n }\n else {\n _window = getWindow(element);\n\n if (isElement(element, _window)) {\n\n if (supportsPointerEvent) {\n events.add(this._element, pEventTypes.down, listeners.pointerDown );\n events.add(this._element, pEventTypes.move, listeners.pointerHover);\n }\n else {\n events.add(this._element, 'mousedown' , listeners.pointerDown );\n events.add(this._element, 'mousemove' , listeners.pointerHover);\n events.add(this._element, 'touchstart', listeners.pointerDown );\n events.add(this._element, 'touchmove' , listeners.pointerHover);\n }\n }\n }\n\n this._doc = _window.document;\n\n if (!contains(documents, this._doc)) {\n listenToDocument(this._doc);\n }\n\n interactables.push(this);\n\n this.set(options);\n }\n\n Interactable.prototype = {\n setOnEvents: function (action, phases) {\n if (action === 'drop') {\n if (isFunction(phases.ondrop) ) { this.ondrop = phases.ondrop ; }\n if (isFunction(phases.ondropactivate) ) { this.ondropactivate = phases.ondropactivate ; }\n if (isFunction(phases.ondropdeactivate)) { this.ondropdeactivate = phases.ondropdeactivate; }\n if (isFunction(phases.ondragenter) ) { this.ondragenter = phases.ondragenter ; }\n if (isFunction(phases.ondragleave) ) { this.ondragleave = phases.ondragleave ; }\n if (isFunction(phases.ondropmove) ) { this.ondropmove = phases.ondropmove ; }\n }\n else {\n action = 'on' + action;\n\n if (isFunction(phases.onstart) ) { this[action + 'start' ] = phases.onstart ; }\n if (isFunction(phases.onmove) ) { this[action + 'move' ] = phases.onmove ; }\n if (isFunction(phases.onend) ) { this[action + 'end' ] = phases.onend ; }\n if (isFunction(phases.oninertiastart)) { this[action + 'inertiastart' ] = phases.oninertiastart ; }\n }\n\n return this;\n },\n\n /*\\\n * Interactable.draggable\n [ method ]\n *\n * Gets or sets whether drag actions can be performed on the\n * Interactable\n *\n = (boolean) Indicates if this can be the target of drag events\n | var isDraggable = interact('ul li').draggable();\n * or\n - options (boolean | object) #optional true/false or An object with event listeners to be fired on drag events (object makes the Interactable draggable)\n = (object) This Interactable\n | interact(element).draggable({\n | onstart: function (event) {},\n | onmove : function (event) {},\n | onend : function (event) {},\n |\n | // the axis in which the first movement must be\n | // for the drag sequence to start\n | // 'xy' by default - any direction\n | axis: 'x' || 'y' || 'xy',\n |\n | // max number of drags that can happen concurrently\n | // with elements of this Interactable. Infinity by default\n | max: Infinity,\n |\n | // max number of drags that can target the same element+Interactable\n | // 1 by default\n | maxPerElement: 2\n | });\n \\*/\n draggable: function (options) {\n if (isObject(options)) {\n this.options.drag.enabled = options.enabled === false? false: true;\n this.setPerAction('drag', options);\n this.setOnEvents('drag', options);\n\n if (/^x$|^y$|^xy$/.test(options.axis)) {\n this.options.drag.axis = options.axis;\n }\n else if (options.axis === null) {\n delete this.options.drag.axis;\n }\n\n return this;\n }\n\n if (isBool(options)) {\n this.options.drag.enabled = options;\n\n return this;\n }\n\n return this.options.drag;\n },\n\n setPerAction: function (action, options) {\n // for all the default per-action options\n for (var option in options) {\n // if this option exists for this action\n if (option in defaultOptions[action]) {\n // if the option in the options arg is an object value\n if (isObject(options[option])) {\n // duplicate the object\n this.options[action][option] = extend(this.options[action][option] || {}, options[option]);\n\n if (isObject(defaultOptions.perAction[option]) && 'enabled' in defaultOptions.perAction[option]) {\n this.options[action][option].enabled = options[option].enabled === false? false : true;\n }\n }\n else if (isBool(options[option]) && isObject(defaultOptions.perAction[option])) {\n this.options[action][option].enabled = options[option];\n }\n else if (options[option] !== undefined) {\n // or if it's not undefined, do a plain assignment\n this.options[action][option] = options[option];\n }\n }\n }\n },\n\n /*\\\n * Interactable.dropzone\n [ method ]\n *\n * Returns or sets whether elements can be dropped onto this\n * Interactable to trigger drop events\n *\n * Dropzones can receive the following events:\n * - `dropactivate` and `dropdeactivate` when an acceptable drag starts and ends\n * - `dragenter` and `dragleave` when a draggable enters and leaves the dropzone\n * - `dragmove` when a draggable that has entered the dropzone is moved\n * - `drop` when a draggable is dropped into this dropzone\n *\n * Use the `accept` option to allow only elements that match the given CSS selector or element.\n *\n * Use the `overlap` option to set how drops are checked for. The allowed values are:\n * - `'pointer'`, the pointer must be over the dropzone (default)\n * - `'center'`, the draggable element's center must be over the dropzone\n * - a number from 0-1 which is the `(intersection area) / (draggable area)`.\n * e.g. `0.5` for drop to happen when half of the area of the\n * draggable is over the dropzone\n *\n - options (boolean | object | null) #optional The new value to be set.\n | interact('.drop').dropzone({\n | accept: '.can-drop' || document.getElementById('single-drop'),\n | overlap: 'pointer' || 'center' || zeroToOne\n | }\n = (boolean | object) The current setting or this Interactable\n \\*/\n dropzone: function (options) {\n if (isObject(options)) {\n this.options.drop.enabled = options.enabled === false? false: true;\n this.setOnEvents('drop', options);\n\n if (/^(pointer|center)$/.test(options.overlap)) {\n this.options.drop.overlap = options.overlap;\n }\n else if (isNumber(options.overlap)) {\n this.options.drop.overlap = Math.max(Math.min(1, options.overlap), 0);\n }\n if ('accept' in options) {\n this.options.drop.accept = options.accept;\n }\n if ('checker' in options) {\n this.options.drop.checker = options.checker;\n }\n\n return this;\n }\n\n if (isBool(options)) {\n this.options.drop.enabled = options;\n\n return this;\n }\n\n return this.options.drop;\n },\n\n dropCheck: function (dragEvent, event, draggable, draggableElement, dropElement, rect) {\n var dropped = false;\n\n // if the dropzone has no rect (eg. display: none)\n // call the custom dropChecker or just return false\n if (!(rect = rect || this.getRect(dropElement))) {\n return (this.options.drop.checker\n ? this.options.drop.checker(dragEvent, event, dropped, this, dropElement, draggable, draggableElement)\n : false);\n }\n\n var dropOverlap = this.options.drop.overlap;\n\n if (dropOverlap === 'pointer') {\n var page = getPageXY(dragEvent),\n origin = getOriginXY(draggable, draggableElement),\n horizontal,\n vertical;\n\n page.x += origin.x;\n page.y += origin.y;\n\n horizontal = (page.x > rect.left) && (page.x < rect.right);\n vertical = (page.y > rect.top ) && (page.y < rect.bottom);\n\n dropped = horizontal && vertical;\n }\n\n var dragRect = draggable.getRect(draggableElement);\n\n if (dropOverlap === 'center') {\n var cx = dragRect.left + dragRect.width / 2,\n cy = dragRect.top + dragRect.height / 2;\n\n dropped = cx >= rect.left && cx <= rect.right && cy >= rect.top && cy <= rect.bottom;\n }\n\n if (isNumber(dropOverlap)) {\n var overlapArea = (Math.max(0, Math.min(rect.right , dragRect.right ) - Math.max(rect.left, dragRect.left))\n * Math.max(0, Math.min(rect.bottom, dragRect.bottom) - Math.max(rect.top , dragRect.top ))),\n overlapRatio = overlapArea / (dragRect.width * dragRect.height);\n\n dropped = overlapRatio >= dropOverlap;\n }\n\n if (this.options.drop.checker) {\n dropped = this.options.drop.checker(dragEvent, event, dropped, this, dropElement, draggable, draggableElement);\n }\n\n return dropped;\n },\n\n /*\\\n * Interactable.dropChecker\n [ method ]\n *\n * DEPRECATED. Use interactable.dropzone({ checker: function... }) instead.\n *\n * Gets or sets the function used to check if a dragged element is\n * over this Interactable.\n *\n - checker (function) #optional The function that will be called when checking for a drop\n = (Function | Interactable) The checker function or this Interactable\n *\n * The checker function takes the following arguments:\n *\n - dragEvent (InteractEvent) The related dragmove or dragend event\n - event (TouchEvent | PointerEvent | MouseEvent) The user move/up/end Event related to the dragEvent\n - dropped (boolean) The value from the default drop checker\n - dropzone (Interactable) The dropzone interactable\n - dropElement (Element) The dropzone element\n - draggable (Interactable) The Interactable being dragged\n - draggableElement (Element) The actual element that's being dragged\n *\n > Usage:\n | interact(target)\n | .dropChecker(function(dragEvent, // related dragmove or dragend event\n | event, // TouchEvent/PointerEvent/MouseEvent\n | dropped, // bool result of the default checker\n | dropzone, // dropzone Interactable\n | dropElement, // dropzone elemnt\n | draggable, // draggable Interactable\n | draggableElement) {// draggable element\n |\n | return dropped && event.target.hasAttribute('allow-drop');\n | }\n \\*/\n dropChecker: function (checker) {\n if (isFunction(checker)) {\n this.options.drop.checker = checker;\n\n return this;\n }\n if (checker === null) {\n delete this.options.getRect;\n\n return this;\n }\n\n return this.options.drop.checker;\n },\n\n /*\\\n * Interactable.accept\n [ method ]\n *\n * Deprecated. add an `accept` property to the options object passed to\n * @Interactable.dropzone instead.\n *\n * Gets or sets the Element or CSS selector match that this\n * Interactable accepts if it is a dropzone.\n *\n - newValue (Element | string | null) #optional\n * If it is an Element, then only that element can be dropped into this dropzone.\n * If it is a string, the element being dragged must match it as a selector.\n * If it is null, the accept options is cleared - it accepts any element.\n *\n = (string | Element | null | Interactable) The current accept option if given `undefined` or this Interactable\n \\*/\n accept: function (newValue) {\n if (isElement(newValue)) {\n this.options.drop.accept = newValue;\n\n return this;\n }\n\n // test if it is a valid CSS selector\n if (trySelector(newValue)) {\n this.options.drop.accept = newValue;\n\n return this;\n }\n\n if (newValue === null) {\n delete this.options.drop.accept;\n\n return this;\n }\n\n return this.options.drop.accept;\n },\n\n /*\\\n * Interactable.resizable\n [ method ]\n *\n * Gets or sets whether resize actions can be performed on the\n * Interactable\n *\n = (boolean) Indicates if this can be the target of resize elements\n | var isResizeable = interact('input[type=text]').resizable();\n * or\n - options (boolean | object) #optional true/false or An object with event listeners to be fired on resize events (object makes the Interactable resizable)\n = (object) This Interactable\n | interact(element).resizable({\n | onstart: function (event) {},\n | onmove : function (event) {},\n | onend : function (event) {},\n |\n | edges: {\n | top : true, // Use pointer coords to check for resize.\n | left : false, // Disable resizing from left edge.\n | bottom: '.resize-s',// Resize if pointer target matches selector\n | right : handleEl // Resize if pointer target is the given Element\n | },\n |\n | // Width and height can be adjusted independently. When `true`, width and\n | // height are adjusted at a 1:1 ratio.\n | square: false,\n |\n | // Width and height can be adjusted independently. When `true`, width and\n | // height maintain the aspect ratio they had when resizing started.\n | preserveAspectRatio: false,\n |\n | // a value of 'none' will limit the resize rect to a minimum of 0x0\n | // 'negate' will allow the rect to have negative width/height\n | // 'reposition' will keep the width/height positive by swapping\n | // the top and bottom edges and/or swapping the left and right edges\n | invert: 'none' || 'negate' || 'reposition'\n |\n | // limit multiple resizes.\n | // See the explanation in the @Interactable.draggable example\n | max: Infinity,\n | maxPerElement: 1,\n | });\n \\*/\n resizable: function (options) {\n if (isObject(options)) {\n this.options.resize.enabled = options.enabled === false? false: true;\n this.setPerAction('resize', options);\n this.setOnEvents('resize', options);\n\n if (/^x$|^y$|^xy$/.test(options.axis)) {\n this.options.resize.axis = options.axis;\n }\n else if (options.axis === null) {\n this.options.resize.axis = defaultOptions.resize.axis;\n }\n\n if (isBool(options.preserveAspectRatio)) {\n this.options.resize.preserveAspectRatio = options.preserveAspectRatio;\n }\n else if (isBool(options.square)) {\n this.options.resize.square = options.square;\n }\n\n return this;\n }\n if (isBool(options)) {\n this.options.resize.enabled = options;\n\n return this;\n }\n return this.options.resize;\n },\n\n /*\\\n * Interactable.squareResize\n [ method ]\n *\n * Deprecated. Add a `square: true || false` property to @Interactable.resizable instead\n *\n * Gets or sets whether resizing is forced 1:1 aspect\n *\n = (boolean) Current setting\n *\n * or\n *\n - newValue (boolean) #optional\n = (object) this Interactable\n \\*/\n squareResize: function (newValue) {\n if (isBool(newValue)) {\n this.options.resize.square = newValue;\n\n return this;\n }\n\n if (newValue === null) {\n delete this.options.resize.square;\n\n return this;\n }\n\n return this.options.resize.square;\n },\n\n /*\\\n * Interactable.gesturable\n [ method ]\n *\n * Gets or sets whether multitouch gestures can be performed on the\n * Interactable's element\n *\n = (boolean) Indicates if this can be the target of gesture events\n | var isGestureable = interact(element).gesturable();\n * or\n - options (boolean | object) #optional true/false or An object with event listeners to be fired on gesture events (makes the Interactable gesturable)\n = (object) this Interactable\n | interact(element).gesturable({\n | onstart: function (event) {},\n | onmove : function (event) {},\n | onend : function (event) {},\n |\n | // limit multiple gestures.\n | // See the explanation in @Interactable.draggable example\n | max: Infinity,\n | maxPerElement: 1,\n | });\n \\*/\n gesturable: function (options) {\n if (isObject(options)) {\n this.options.gesture.enabled = options.enabled === false? false: true;\n this.setPerAction('gesture', options);\n this.setOnEvents('gesture', options);\n\n return this;\n }\n\n if (isBool(options)) {\n this.options.gesture.enabled = options;\n\n return this;\n }\n\n return this.options.gesture;\n },\n\n /*\\\n * Interactable.autoScroll\n [ method ]\n **\n * Deprecated. Add an `autoscroll` property to the options object\n * passed to @Interactable.draggable or @Interactable.resizable instead.\n *\n * Returns or sets whether dragging and resizing near the edges of the\n * window/container trigger autoScroll for this Interactable\n *\n = (object) Object with autoScroll properties\n *\n * or\n *\n - options (object | boolean) #optional\n * options can be:\n * - an object with margin, distance and interval properties,\n * - true or false to enable or disable autoScroll or\n = (Interactable) this Interactable\n \\*/\n autoScroll: function (options) {\n if (isObject(options)) {\n options = extend({ actions: ['drag', 'resize']}, options);\n }\n else if (isBool(options)) {\n options = { actions: ['drag', 'resize'], enabled: options };\n }\n\n return this.setOptions('autoScroll', options);\n },\n\n /*\\\n * Interactable.snap\n [ method ]\n **\n * Deprecated. Add a `snap` property to the options object passed\n * to @Interactable.draggable or @Interactable.resizable instead.\n *\n * Returns or sets if and how action coordinates are snapped. By\n * default, snapping is relative to the pointer coordinates. You can\n * change this by setting the\n * [`elementOrigin`](https://github.com/taye/interact.js/pull/72).\n **\n = (boolean | object) `false` if snap is disabled; object with snap properties if snap is enabled\n **\n * or\n **\n - options (object | boolean | null) #optional\n = (Interactable) this Interactable\n > Usage\n | interact(document.querySelector('#thing')).snap({\n | targets: [\n | // snap to this specific point\n | {\n | x: 100,\n | y: 100,\n | range: 25\n | },\n | // give this function the x and y page coords and snap to the object returned\n | function (x, y) {\n | return {\n | x: x,\n | y: (75 + 50 * Math.sin(x * 0.04)),\n | range: 40\n | };\n | },\n | // create a function that snaps to a grid\n | interact.createSnapGrid({\n | x: 50,\n | y: 50,\n | range: 10, // optional\n | offset: { x: 5, y: 10 } // optional\n | })\n | ],\n | // do not snap during normal movement.\n | // Instead, trigger only one snapped move event\n | // immediately before the end event.\n | endOnly: true,\n |\n | relativePoints: [\n | { x: 0, y: 0 }, // snap relative to the top left of the element\n | { x: 1, y: 1 }, // and also to the bottom right\n | ], \n |\n | // offset the snap target coordinates\n | // can be an object with x/y or 'startCoords'\n | offset: { x: 50, y: 50 }\n | }\n | });\n \\*/\n snap: function (options) {\n var ret = this.setOptions('snap', options);\n\n if (ret === this) { return this; }\n\n return ret.drag;\n },\n\n setOptions: function (option, options) {\n var actions = options && isArray(options.actions)\n ? options.actions\n : ['drag'];\n\n var i;\n\n if (isObject(options) || isBool(options)) {\n for (i = 0; i < actions.length; i++) {\n var action = /resize/.test(actions[i])? 'resize' : actions[i];\n\n if (!isObject(this.options[action])) { continue; }\n\n var thisOption = this.options[action][option];\n\n if (isObject(options)) {\n extend(thisOption, options);\n thisOption.enabled = options.enabled === false? false: true;\n\n if (option === 'snap') {\n if (thisOption.mode === 'grid') {\n thisOption.targets = [\n interact.createSnapGrid(extend({\n offset: thisOption.gridOffset || { x: 0, y: 0 }\n }, thisOption.grid || {}))\n ];\n }\n else if (thisOption.mode === 'anchor') {\n thisOption.targets = thisOption.anchors;\n }\n else if (thisOption.mode === 'path') {\n thisOption.targets = thisOption.paths;\n }\n\n if ('elementOrigin' in options) {\n thisOption.relativePoints = [options.elementOrigin];\n }\n }\n }\n else if (isBool(options)) {\n thisOption.enabled = options;\n }\n }\n\n return this;\n }\n\n var ret = {},\n allActions = ['drag', 'resize', 'gesture'];\n\n for (i = 0; i < allActions.length; i++) {\n if (option in defaultOptions[allActions[i]]) {\n ret[allActions[i]] = this.options[allActions[i]][option];\n }\n }\n\n return ret;\n },\n\n\n /*\\\n * Interactable.inertia\n [ method ]\n **\n * Deprecated. Add an `inertia` property to the options object passed\n * to @Interactable.draggable or @Interactable.resizable instead.\n *\n * Returns or sets if and how events continue to run after the pointer is released\n **\n = (boolean | object) `false` if inertia is disabled; `object` with inertia properties if inertia is enabled\n **\n * or\n **\n - options (object | boolean | null) #optional\n = (Interactable) this Interactable\n > Usage\n | // enable and use default settings\n | interact(element).inertia(true);\n |\n | // enable and use custom settings\n | interact(element).inertia({\n | // value greater than 0\n | // high values slow the object down more quickly\n | resistance : 16,\n |\n | // the minimum launch speed (pixels per second) that results in inertia start\n | minSpeed : 200,\n |\n | // inertia will stop when the object slows down to this speed\n | endSpeed : 20,\n |\n | // boolean; should actions be resumed when the pointer goes down during inertia\n | allowResume : true,\n |\n | // boolean; should the jump when resuming from inertia be ignored in event.dx/dy\n | zeroResumeDelta: false,\n |\n | // if snap/restrict are set to be endOnly and inertia is enabled, releasing\n | // the pointer without triggering inertia will animate from the release\n | // point to the snaped/restricted point in the given amount of time (ms)\n | smoothEndDuration: 300,\n |\n | // an array of action types that can have inertia (no gesture)\n | actions : ['drag', 'resize']\n | });\n |\n | // reset custom settings and use all defaults\n | interact(element).inertia(null);\n \\*/\n inertia: function (options) {\n var ret = this.setOptions('inertia', options);\n\n if (ret === this) { return this; }\n\n return ret.drag;\n },\n\n getAction: function (pointer, event, interaction, element) {\n var action = this.defaultActionChecker(pointer, interaction, element);\n\n if (this.options.actionChecker) {\n return this.options.actionChecker(pointer, event, action, this, element, interaction);\n }\n\n return action;\n },\n\n defaultActionChecker: defaultActionChecker,\n\n /*\\\n * Interactable.actionChecker\n [ method ]\n *\n * Gets or sets the function used to check action to be performed on\n * pointerDown\n *\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.\n = (Function | Interactable) The checker function or this Interactable\n *\n | interact('.resize-drag')\n | .resizable(true)\n | .draggable(true)\n | .actionChecker(function (pointer, event, action, interactable, element, interaction) {\n |\n | if (interact.matchesSelector(event.target, '.drag-handle') {\n | // force drag with handle target\n | action.name = drag;\n | }\n | else {\n | // resize from the top and right edges\n | action.name = 'resize';\n | action.edges = { top: true, right: true };\n | }\n |\n | return action;\n | });\n \\*/\n actionChecker: function (checker) {\n if (isFunction(checker)) {\n this.options.actionChecker = checker;\n\n return this;\n }\n\n if (checker === null) {\n delete this.options.actionChecker;\n\n return this;\n }\n\n return this.options.actionChecker;\n },\n\n /*\\\n * Interactable.getRect\n [ method ]\n *\n * The default function to get an Interactables bounding rect. Can be\n * overridden using @Interactable.rectChecker.\n *\n - element (Element) #optional The element to measure.\n = (object) The object's bounding rectangle.\n o {\n o top : 0,\n o left : 0,\n o bottom: 0,\n o right : 0,\n o width : 0,\n o height: 0\n o }\n \\*/\n getRect: function rectCheck (element) {\n element = element || this._element;\n\n if (this.selector && !(isElement(element))) {\n element = this._context.querySelector(this.selector);\n }\n\n return getElementRect(element);\n },\n\n /*\\\n * Interactable.rectChecker\n [ method ]\n *\n * Returns or sets the function used to calculate the interactable's\n * element's rectangle\n *\n - checker (function) #optional A function which returns this Interactable's bounding rectangle. See @Interactable.getRect\n = (function | object) The checker function or this Interactable\n \\*/\n rectChecker: function (checker) {\n if (isFunction(checker)) {\n this.getRect = checker;\n\n return this;\n }\n\n if (checker === null) {\n delete this.options.getRect;\n\n return this;\n }\n\n return this.getRect;\n },\n\n /*\\\n * Interactable.styleCursor\n [ method ]\n *\n * Returns or sets whether the action that would be performed when the\n * mouse on the element are checked on `mousemove` so that the cursor\n * may be styled appropriately\n *\n - newValue (boolean) #optional\n = (boolean | Interactable) The current setting or this Interactable\n \\*/\n styleCursor: function (newValue) {\n if (isBool(newValue)) {\n this.options.styleCursor = newValue;\n\n return this;\n }\n\n if (newValue === null) {\n delete this.options.styleCursor;\n\n return this;\n }\n\n return this.options.styleCursor;\n },\n\n /*\\\n * Interactable.preventDefault\n [ method ]\n *\n * Returns or sets whether to prevent the browser's default behaviour\n * in response to pointer events. Can be set to:\n * - `'always'` to always prevent\n * - `'never'` to never prevent\n * - `'auto'` to let interact.js try to determine what would be best\n *\n - newValue (string) #optional `true`, `false` or `'auto'`\n = (string | Interactable) The current setting or this Interactable\n \\*/\n preventDefault: function (newValue) {\n if (/^(always|never|auto)$/.test(newValue)) {\n this.options.preventDefault = newValue;\n return this;\n }\n\n if (isBool(newValue)) {\n this.options.preventDefault = newValue? 'always' : 'never';\n return this;\n }\n\n return this.options.preventDefault;\n },\n\n /*\\\n * Interactable.origin\n [ method ]\n *\n * Gets or sets the origin of the Interactable's element. The x and y\n * of the origin will be subtracted from action event coordinates.\n *\n - origin (object | string) #optional An object eg. { x: 0, y: 0 } or string 'parent', 'self' or any CSS selector\n * OR\n - origin (Element) #optional An HTML or SVG Element whose rect will be used\n **\n = (object) The current origin or this Interactable\n \\*/\n origin: function (newValue) {\n if (trySelector(newValue)) {\n this.options.origin = newValue;\n return this;\n }\n else if (isObject(newValue)) {\n this.options.origin = newValue;\n return this;\n }\n\n return this.options.origin;\n },\n\n /*\\\n * Interactable.deltaSource\n [ method ]\n *\n * Returns or sets the mouse coordinate types used to calculate the\n * movement of the pointer.\n *\n - newValue (string) #optional Use 'client' if you will be scrolling while interacting; Use 'page' if you want autoScroll to work\n = (string | object) The current deltaSource or this Interactable\n \\*/\n deltaSource: function (newValue) {\n if (newValue === 'page' || newValue === 'client') {\n this.options.deltaSource = newValue;\n\n return this;\n }\n\n return this.options.deltaSource;\n },\n\n /*\\\n * Interactable.restrict\n [ method ]\n **\n * Deprecated. Add a `restrict` property to the options object passed to\n * @Interactable.draggable, @Interactable.resizable or @Interactable.gesturable instead.\n *\n * Returns or sets the rectangles within which actions on this\n * interactable (after snap calculations) are restricted. By default,\n * restricting is relative to the pointer coordinates. You can change\n * this by setting the\n * [`elementRect`](https://github.com/taye/interact.js/pull/72).\n **\n - options (object) #optional an object with keys drag, resize, and/or gesture whose values are rects, Elements, CSS selectors, or 'parent' or 'self'\n = (object) The current restrictions object or this Interactable\n **\n | interact(element).restrict({\n | // the rect will be `interact.getElementRect(element.parentNode)`\n | drag: element.parentNode,\n |\n | // x and y are relative to the the interactable's origin\n | resize: { x: 100, y: 100, width: 200, height: 200 }\n | })\n |\n | interact('.draggable').restrict({\n | // the rect will be the selected element's parent\n | drag: 'parent',\n |\n | // do not restrict during normal movement.\n | // Instead, trigger only one restricted move event\n | // immediately before the end event.\n | endOnly: true,\n |\n | // https://github.com/taye/interact.js/pull/72#issue-41813493\n | elementRect: { top: 0, left: 0, bottom: 1, right: 1 }\n | });\n \\*/\n restrict: function (options) {\n if (!isObject(options)) {\n return this.setOptions('restrict', options);\n }\n\n var actions = ['drag', 'resize', 'gesture'],\n ret;\n\n for (var i = 0; i < actions.length; i++) {\n var action = actions[i];\n\n if (action in options) {\n var perAction = extend({\n actions: [action],\n restriction: options[action]\n }, options);\n\n ret = this.setOptions('restrict', perAction);\n }\n }\n\n return ret;\n },\n\n /*\\\n * Interactable.context\n [ method ]\n *\n * Gets the selector context Node of the Interactable. The default is `window.document`.\n *\n = (Node) The context Node of this Interactable\n **\n \\*/\n context: function () {\n return this._context;\n },\n\n _context: document,\n\n /*\\\n * Interactable.ignoreFrom\n [ method ]\n *\n * If the target of the `mousedown`, `pointerdown` or `touchstart`\n * event or any of it's parents match the given CSS selector or\n * Element, no drag/resize/gesture is started.\n *\n - newValue (string | Element | null) #optional a CSS selector string, an Element or `null` to not ignore any elements\n = (string | Element | object) The current ignoreFrom value or this Interactable\n **\n | interact(element, { ignoreFrom: document.getElementById('no-action') });\n | // or\n | interact(element).ignoreFrom('input, textarea, a');\n \\*/\n ignoreFrom: function (newValue) {\n if (trySelector(newValue)) { // CSS selector to match event.target\n this.options.ignoreFrom = newValue;\n return this;\n }\n\n if (isElement(newValue)) { // specific element\n this.options.ignoreFrom = newValue;\n return this;\n }\n\n return this.options.ignoreFrom;\n },\n\n /*\\\n * Interactable.allowFrom\n [ method ]\n *\n * A drag/resize/gesture is started only If the target of the\n * `mousedown`, `pointerdown` or `touchstart` event or any of it's\n * parents match the given CSS selector or Element.\n *\n - newValue (string | Element | null) #optional a CSS selector string, an Element or `null` to allow from any element\n = (string | Element | object) The current allowFrom value or this Interactable\n **\n | interact(element, { allowFrom: document.getElementById('drag-handle') });\n | // or\n | interact(element).allowFrom('.handle');\n \\*/\n allowFrom: function (newValue) {\n if (trySelector(newValue)) { // CSS selector to match event.target\n this.options.allowFrom = newValue;\n return this;\n }\n\n if (isElement(newValue)) { // specific element\n this.options.allowFrom = newValue;\n return this;\n }\n\n return this.options.allowFrom;\n },\n\n /*\\\n * Interactable.element\n [ method ]\n *\n * If this is not a selector Interactable, it returns the element this\n * interactable represents\n *\n = (Element) HTML / SVG Element\n \\*/\n element: function () {\n return this._element;\n },\n\n /*\\\n * Interactable.fire\n [ method ]\n *\n * Calls listeners for the given InteractEvent type bound globally\n * and directly to this Interactable\n *\n - iEvent (InteractEvent) The InteractEvent object to be fired on this Interactable\n = (Interactable) this Interactable\n \\*/\n fire: function (iEvent) {\n if (!(iEvent && iEvent.type) || !contains(eventTypes, iEvent.type)) {\n return this;\n }\n\n var listeners,\n i,\n len,\n onEvent = 'on' + iEvent.type,\n funcName = '';\n\n // Interactable#on() listeners\n if (iEvent.type in this._iEvents) {\n listeners = this._iEvents[iEvent.type];\n\n for (i = 0, len = listeners.length; i < len && !iEvent.immediatePropagationStopped; i++) {\n funcName = listeners[i].name;\n listeners[i](iEvent);\n }\n }\n\n // interactable.onevent listener\n if (isFunction(this[onEvent])) {\n funcName = this[onEvent].name;\n this[onEvent](iEvent);\n }\n\n // interact.on() listeners\n if (iEvent.type in globalEvents && (listeners = globalEvents[iEvent.type])) {\n\n for (i = 0, len = listeners.length; i < len && !iEvent.immediatePropagationStopped; i++) {\n funcName = listeners[i].name;\n listeners[i](iEvent);\n }\n }\n\n return this;\n },\n\n /*\\\n * Interactable.on\n [ method ]\n *\n * Binds a listener for an InteractEvent or DOM event.\n *\n - eventType (string | array | object) The types of events to listen for\n - listener (function) The function to be called on the given event(s)\n - useCapture (boolean) #optional useCapture flag for addEventListener\n = (object) This Interactable\n \\*/\n on: function (eventType, listener, useCapture) {\n var i;\n\n if (isString(eventType) && eventType.search(' ') !== -1) {\n eventType = eventType.trim().split(/ +/);\n }\n\n if (isArray(eventType)) {\n for (i = 0; i < eventType.length; i++) {\n this.on(eventType[i], listener, useCapture);\n }\n\n return this;\n }\n\n if (isObject(eventType)) {\n for (var prop in eventType) {\n this.on(prop, eventType[prop], listener);\n }\n\n return this;\n }\n\n if (eventType === 'wheel') {\n eventType = wheelEvent;\n }\n\n // convert to boolean\n useCapture = useCapture? true: false;\n\n if (contains(eventTypes, eventType)) {\n // if this type of event was never bound to this Interactable\n if (!(eventType in this._iEvents)) {\n this._iEvents[eventType] = [listener];\n }\n else {\n this._iEvents[eventType].push(listener);\n }\n }\n // delegated event for selector\n else if (this.selector) {\n if (!delegatedEvents[eventType]) {\n delegatedEvents[eventType] = {\n selectors: [],\n contexts : [],\n listeners: []\n };\n\n // add delegate listener functions\n for (i = 0; i < documents.length; i++) {\n events.add(documents[i], eventType, delegateListener);\n events.add(documents[i], eventType, delegateUseCapture, true);\n }\n }\n\n var delegated = delegatedEvents[eventType],\n index;\n\n for (index = delegated.selectors.length - 1; index >= 0; index--) {\n if (delegated.selectors[index] === this.selector\n && delegated.contexts[index] === this._context) {\n break;\n }\n }\n\n if (index === -1) {\n index = delegated.selectors.length;\n\n delegated.selectors.push(this.selector);\n delegated.contexts .push(this._context);\n delegated.listeners.push([]);\n }\n\n // keep listener and useCapture flag\n delegated.listeners[index].push([listener, useCapture]);\n }\n else {\n events.add(this._element, eventType, listener, useCapture);\n }\n\n return this;\n },\n\n /*\\\n * Interactable.off\n [ method ]\n *\n * Removes an InteractEvent or DOM event listener\n *\n - eventType (string | array | object) The types of events that were listened for\n - listener (function) The listener function to be removed\n - useCapture (boolean) #optional useCapture flag for removeEventListener\n = (object) This Interactable\n \\*/\n off: function (eventType, listener, useCapture) {\n var i;\n\n if (isString(eventType) && eventType.search(' ') !== -1) {\n eventType = eventType.trim().split(/ +/);\n }\n\n if (isArray(eventType)) {\n for (i = 0; i < eventType.length; i++) {\n this.off(eventType[i], listener, useCapture);\n }\n\n return this;\n }\n\n if (isObject(eventType)) {\n for (var prop in eventType) {\n this.off(prop, eventType[prop], listener);\n }\n\n return this;\n }\n\n var eventList,\n index = -1;\n\n // convert to boolean\n useCapture = useCapture? true: false;\n\n if (eventType === 'wheel') {\n eventType = wheelEvent;\n }\n\n // if it is an action event type\n if (contains(eventTypes, eventType)) {\n eventList = this._iEvents[eventType];\n\n if (eventList && (index = indexOf(eventList, listener)) !== -1) {\n this._iEvents[eventType].splice(index, 1);\n }\n }\n // delegated event\n else if (this.selector) {\n var delegated = delegatedEvents[eventType],\n matchFound = false;\n\n if (!delegated) { return this; }\n\n // count from last index of delegated to 0\n for (index = delegated.selectors.length - 1; index >= 0; index--) {\n // look for matching selector and context Node\n if (delegated.selectors[index] === this.selector\n && delegated.contexts[index] === this._context) {\n\n var listeners = delegated.listeners[index];\n\n // each item of the listeners array is an array: [function, useCaptureFlag]\n for (i = listeners.length - 1; i >= 0; i--) {\n var fn = listeners[i][0],\n useCap = listeners[i][1];\n\n // check if the listener functions and useCapture flags match\n if (fn === listener && useCap === useCapture) {\n // remove the listener from the array of listeners\n listeners.splice(i, 1);\n\n // if all listeners for this interactable have been removed\n // remove the interactable from the delegated arrays\n if (!listeners.length) {\n delegated.selectors.splice(index, 1);\n delegated.contexts .splice(index, 1);\n delegated.listeners.splice(index, 1);\n\n // remove delegate function from context\n events.remove(this._context, eventType, delegateListener);\n events.remove(this._context, eventType, delegateUseCapture, true);\n\n // remove the arrays if they are empty\n if (!delegated.selectors.length) {\n delegatedEvents[eventType] = null;\n }\n }\n\n // only remove one listener\n matchFound = true;\n break;\n }\n }\n\n if (matchFound) { break; }\n }\n }\n }\n // remove listener from this Interatable's element\n else {\n events.remove(this._element, eventType, listener, useCapture);\n }\n\n return this;\n },\n\n /*\\\n * Interactable.set\n [ method ]\n *\n * Reset the options of this Interactable\n - options (object) The new settings to apply\n = (object) This Interactable\n \\*/\n set: function (options) {\n if (!isObject(options)) {\n options = {};\n }\n\n this.options = extend({}, defaultOptions.base);\n\n var i,\n actions = ['drag', 'drop', 'resize', 'gesture'],\n methods = ['draggable', 'dropzone', 'resizable', 'gesturable'],\n perActions = extend(extend({}, defaultOptions.perAction), options[action] || {});\n\n for (i = 0; i < actions.length; i++) {\n var action = actions[i];\n\n this.options[action] = extend({}, defaultOptions[action]);\n\n this.setPerAction(action, perActions);\n\n this[methods[i]](options[action]);\n }\n\n var settings = [\n 'accept', 'actionChecker', 'allowFrom', 'deltaSource',\n 'dropChecker', 'ignoreFrom', 'origin', 'preventDefault',\n 'rectChecker', 'styleCursor'\n ];\n\n for (i = 0, len = settings.length; i < len; i++) {\n var setting = settings[i];\n\n this.options[setting] = defaultOptions.base[setting];\n\n if (setting in options) {\n this[setting](options[setting]);\n }\n }\n\n return this;\n },\n\n /*\\\n * Interactable.unset\n [ method ]\n *\n * Remove this interactable from the list of interactables and remove\n * it's drag, drop, resize and gesture capabilities\n *\n = (object) @interact\n \\*/\n unset: function () {\n events.remove(this._element, 'all');\n\n if (!isString(this.selector)) {\n events.remove(this, 'all');\n if (this.options.styleCursor) {\n this._element.style.cursor = '';\n }\n }\n else {\n // remove delegated events\n for (var type in delegatedEvents) {\n var delegated = delegatedEvents[type];\n\n for (var i = 0; i < delegated.selectors.length; i++) {\n if (delegated.selectors[i] === this.selector\n && delegated.contexts[i] === this._context) {\n\n delegated.selectors.splice(i, 1);\n delegated.contexts .splice(i, 1);\n delegated.listeners.splice(i, 1);\n\n // remove the arrays if they are empty\n if (!delegated.selectors.length) {\n delegatedEvents[type] = null;\n }\n }\n\n events.remove(this._context, type, delegateListener);\n events.remove(this._context, type, delegateUseCapture, true);\n\n break;\n }\n }\n }\n\n this.dropzone(false);\n\n interactables.splice(indexOf(interactables, this), 1);\n\n return interact;\n }\n };\n\n function warnOnce (method, message) {\n var warned = false;\n\n return function () {\n if (!warned) {\n window.console.warn(message);\n warned = true;\n }\n\n return method.apply(this, arguments);\n };\n }\n\n Interactable.prototype.snap = warnOnce(Interactable.prototype.snap,\n 'Interactable#snap is deprecated. See the new documentation for snapping at http://interactjs.io/docs/snapping');\n Interactable.prototype.restrict = warnOnce(Interactable.prototype.restrict,\n 'Interactable#restrict is deprecated. See the new documentation for resticting at http://interactjs.io/docs/restriction');\n Interactable.prototype.inertia = warnOnce(Interactable.prototype.inertia,\n 'Interactable#inertia is deprecated. See the new documentation for inertia at http://interactjs.io/docs/inertia');\n Interactable.prototype.autoScroll = warnOnce(Interactable.prototype.autoScroll,\n 'Interactable#autoScroll is deprecated. See the new documentation for autoScroll at http://interactjs.io/docs/#autoscroll');\n Interactable.prototype.squareResize = warnOnce(Interactable.prototype.squareResize,\n 'Interactable#squareResize is deprecated. See http://interactjs.io/docs/#resize-square');\n\n Interactable.prototype.accept = warnOnce(Interactable.prototype.accept,\n 'Interactable#accept is deprecated. use Interactable#dropzone({ accept: target }) instead');\n Interactable.prototype.dropChecker = warnOnce(Interactable.prototype.dropChecker,\n 'Interactable#dropChecker is deprecated. use Interactable#dropzone({ dropChecker: checkerFunction }) instead');\n Interactable.prototype.context = warnOnce(Interactable.prototype.context,\n 'Interactable#context as a method is deprecated. It will soon be a DOM Node instead');\n\n /*\\\n * interact.isSet\n [ method ]\n *\n * Check if an element has been set\n - element (Element) The Element being searched for\n = (boolean) Indicates if the element or CSS selector was previously passed to interact\n \\*/\n interact.isSet = function(element, options) {\n return interactables.indexOfElement(element, options && options.context) !== -1;\n };\n\n /*\\\n * interact.on\n [ method ]\n *\n * Adds a global listener for an InteractEvent or adds a DOM event to\n * `document`\n *\n - type (string | array | object) The types of events to listen for\n - listener (function) The function to be called on the given event(s)\n - useCapture (boolean) #optional useCapture flag for addEventListener\n = (object) interact\n \\*/\n interact.on = function (type, listener, useCapture) {\n if (isString(type) && type.search(' ') !== -1) {\n type = type.trim().split(/ +/);\n }\n\n if (isArray(type)) {\n for (var i = 0; i < type.length; i++) {\n interact.on(type[i], listener, useCapture);\n }\n\n return interact;\n }\n\n if (isObject(type)) {\n for (var prop in type) {\n interact.on(prop, type[prop], listener);\n }\n\n return interact;\n }\n\n // if it is an InteractEvent type, add listener to globalEvents\n if (contains(eventTypes, type)) {\n // if this type of event was never bound\n if (!globalEvents[type]) {\n globalEvents[type] = [listener];\n }\n else {\n globalEvents[type].push(listener);\n }\n }\n // If non InteractEvent type, addEventListener to document\n else {\n events.add(document, type, listener, useCapture);\n }\n\n return interact;\n };\n\n /*\\\n * interact.off\n [ method ]\n *\n * Removes a global InteractEvent listener or DOM event from `document`\n *\n - type (string | array | object) The types of events that were listened for\n - listener (function) The listener function to be removed\n - useCapture (boolean) #optional useCapture flag for removeEventListener\n = (object) interact\n \\*/\n interact.off = function (type, listener, useCapture) {\n if (isString(type) && type.search(' ') !== -1) {\n type = type.trim().split(/ +/);\n }\n\n if (isArray(type)) {\n for (var i = 0; i < type.length; i++) {\n interact.off(type[i], listener, useCapture);\n }\n\n return interact;\n }\n\n if (isObject(type)) {\n for (var prop in type) {\n interact.off(prop, type[prop], listener);\n }\n\n return interact;\n }\n\n if (!contains(eventTypes, type)) {\n events.remove(document, type, listener, useCapture);\n }\n else {\n var index;\n\n if (type in globalEvents\n && (index = indexOf(globalEvents[type], listener)) !== -1) {\n globalEvents[type].splice(index, 1);\n }\n }\n\n return interact;\n };\n\n /*\\\n * interact.enableDragging\n [ method ]\n *\n * Deprecated.\n *\n * Returns or sets whether dragging is enabled for any Interactables\n *\n - newValue (boolean) #optional `true` to allow the action; `false` to disable action for all Interactables\n = (boolean | object) The current setting or interact\n \\*/\n interact.enableDragging = warnOnce(function (newValue) {\n if (newValue !== null && newValue !== undefined) {\n actionIsEnabled.drag = newValue;\n\n return interact;\n }\n return actionIsEnabled.drag;\n }, 'interact.enableDragging is deprecated and will soon be removed.');\n\n /*\\\n * interact.enableResizing\n [ method ]\n *\n * Deprecated.\n *\n * Returns or sets whether resizing is enabled for any Interactables\n *\n - newValue (boolean) #optional `true` to allow the action; `false` to disable action for all Interactables\n = (boolean | object) The current setting or interact\n \\*/\n interact.enableResizing = warnOnce(function (newValue) {\n if (newValue !== null && newValue !== undefined) {\n actionIsEnabled.resize = newValue;\n\n return interact;\n }\n return actionIsEnabled.resize;\n }, 'interact.enableResizing is deprecated and will soon be removed.');\n\n /*\\\n * interact.enableGesturing\n [ method ]\n *\n * Deprecated.\n *\n * Returns or sets whether gesturing is enabled for any Interactables\n *\n - newValue (boolean) #optional `true` to allow the action; `false` to disable action for all Interactables\n = (boolean | object) The current setting or interact\n \\*/\n interact.enableGesturing = warnOnce(function (newValue) {\n if (newValue !== null && newValue !== undefined) {\n actionIsEnabled.gesture = newValue;\n\n return interact;\n }\n return actionIsEnabled.gesture;\n }, 'interact.enableGesturing is deprecated and will soon be removed.');\n\n interact.eventTypes = eventTypes;\n\n /*\\\n * interact.debug\n [ method ]\n *\n * Returns debugging data\n = (object) An object with properties that outline the current state and expose internal functions and variables\n \\*/\n interact.debug = function () {\n var interaction = interactions[0] || new Interaction();\n\n return {\n interactions : interactions,\n target : interaction.target,\n dragging : interaction.dragging,\n resizing : interaction.resizing,\n gesturing : interaction.gesturing,\n prepared : interaction.prepared,\n matches : interaction.matches,\n matchElements : interaction.matchElements,\n\n prevCoords : interaction.prevCoords,\n startCoords : interaction.startCoords,\n\n pointerIds : interaction.pointerIds,\n pointers : interaction.pointers,\n addPointer : listeners.addPointer,\n removePointer : listeners.removePointer,\n recordPointer : listeners.recordPointer,\n\n snap : interaction.snapStatus,\n restrict : interaction.restrictStatus,\n inertia : interaction.inertiaStatus,\n\n downTime : interaction.downTimes[0],\n downEvent : interaction.downEvent,\n downPointer : interaction.downPointer,\n prevEvent : interaction.prevEvent,\n\n Interactable : Interactable,\n interactables : interactables,\n pointerIsDown : interaction.pointerIsDown,\n defaultOptions : defaultOptions,\n defaultActionChecker : defaultActionChecker,\n\n actionCursors : actionCursors,\n dragMove : listeners.dragMove,\n resizeMove : listeners.resizeMove,\n gestureMove : listeners.gestureMove,\n pointerUp : listeners.pointerUp,\n pointerDown : listeners.pointerDown,\n pointerMove : listeners.pointerMove,\n pointerHover : listeners.pointerHover,\n\n eventTypes : eventTypes,\n\n events : events,\n globalEvents : globalEvents,\n delegatedEvents : delegatedEvents,\n\n prefixedPropREs : prefixedPropREs\n };\n };\n\n // expose the functions used to calculate multi-touch properties\n interact.getPointerAverage = pointerAverage;\n interact.getTouchBBox = touchBBox;\n interact.getTouchDistance = touchDistance;\n interact.getTouchAngle = touchAngle;\n\n interact.getElementRect = getElementRect;\n interact.getElementClientRect = getElementClientRect;\n interact.matchesSelector = matchesSelector;\n interact.closest = closest;\n\n /*\\\n * interact.margin\n [ method ]\n *\n * Deprecated. Use `interact(target).resizable({ margin: number });` instead.\n * Returns or sets the margin for autocheck resizing used in\n * @Interactable.getAction. That is the distance from the bottom and right\n * edges of an element clicking in which will start resizing\n *\n - newValue (number) #optional\n = (number | interact) The current margin value or interact\n \\*/\n interact.margin = warnOnce(function (newvalue) {\n if (isNumber(newvalue)) {\n margin = newvalue;\n\n return interact;\n }\n return margin;\n },\n 'interact.margin is deprecated. Use interact(target).resizable({ margin: number }); instead.') ;\n\n /*\\\n * interact.supportsTouch\n [ method ]\n *\n = (boolean) Whether or not the browser supports touch input\n \\*/\n interact.supportsTouch = function () {\n return supportsTouch;\n };\n\n /*\\\n * interact.supportsPointerEvent\n [ method ]\n *\n = (boolean) Whether or not the browser supports PointerEvents\n \\*/\n interact.supportsPointerEvent = function () {\n return supportsPointerEvent;\n };\n\n /*\\\n * interact.stop\n [ method ]\n *\n * Cancels all interactions (end events are not fired)\n *\n - event (Event) An event on which to call preventDefault()\n = (object) interact\n \\*/\n interact.stop = function (event) {\n for (var i = interactions.length - 1; i >= 0; i--) {\n interactions[i].stop(event);\n }\n\n return interact;\n };\n\n /*\\\n * interact.dynamicDrop\n [ method ]\n *\n * Returns or sets whether the dimensions of dropzone elements are\n * calculated on every dragmove or only on dragstart for the default\n * dropChecker\n *\n - newValue (boolean) #optional True to check on each move. False to check only before start\n = (boolean | interact) The current setting or interact\n \\*/\n interact.dynamicDrop = function (newValue) {\n if (isBool(newValue)) {\n //if (dragging && dynamicDrop !== newValue && !newValue) {\n //calcRects(dropzones);\n //}\n\n dynamicDrop = newValue;\n\n return interact;\n }\n return dynamicDrop;\n };\n\n /*\\\n * interact.pointerMoveTolerance\n [ method ]\n * Returns or sets the distance the pointer must be moved before an action\n * sequence occurs. This also affects tolerance for tap events.\n *\n - newValue (number) #optional The movement from the start position must be greater than this value\n = (number | Interactable) The current setting or interact\n \\*/\n interact.pointerMoveTolerance = function (newValue) {\n if (isNumber(newValue)) {\n pointerMoveTolerance = newValue;\n\n return this;\n }\n\n return pointerMoveTolerance;\n };\n\n /*\\\n * interact.maxInteractions\n [ method ]\n **\n * Returns or sets the maximum number of concurrent interactions allowed.\n * By default only 1 interaction is allowed at a time (for backwards\n * compatibility). To allow multiple interactions on the same Interactables\n * and elements, you need to enable it in the draggable, resizable and\n * gesturable `'max'` and `'maxPerElement'` options.\n **\n - newValue (number) #optional Any number. newValue <= 0 means no interactions.\n \\*/\n interact.maxInteractions = function (newValue) {\n if (isNumber(newValue)) {\n maxInteractions = newValue;\n\n return this;\n }\n\n return maxInteractions;\n };\n\n interact.createSnapGrid = function (grid) {\n return function (x, y) {\n var offsetX = 0,\n offsetY = 0;\n\n if (isObject(grid.offset)) {\n offsetX = grid.offset.x;\n offsetY = grid.offset.y;\n }\n\n var gridx = Math.round((x - offsetX) / grid.x),\n gridy = Math.round((y - offsetY) / grid.y),\n\n newX = gridx * grid.x + offsetX,\n newY = gridy * grid.y + offsetY;\n\n return {\n x: newX,\n y: newY,\n range: grid.range\n };\n };\n };\n\n function endAllInteractions (event) {\n for (var i = 0; i < interactions.length; i++) {\n interactions[i].pointerEnd(event, event);\n }\n }\n\n function listenToDocument (doc) {\n if (contains(documents, doc)) { return; }\n\n var win = doc.defaultView || doc.parentWindow;\n\n // add delegate event listener\n for (var eventType in delegatedEvents) {\n events.add(doc, eventType, delegateListener);\n events.add(doc, eventType, delegateUseCapture, true);\n }\n\n if (supportsPointerEvent) {\n if (PointerEvent === win.MSPointerEvent) {\n pEventTypes = {\n up: 'MSPointerUp', down: 'MSPointerDown', over: 'mouseover',\n out: 'mouseout', move: 'MSPointerMove', cancel: 'MSPointerCancel' };\n }\n else {\n pEventTypes = {\n up: 'pointerup', down: 'pointerdown', over: 'pointerover',\n out: 'pointerout', move: 'pointermove', cancel: 'pointercancel' };\n }\n\n events.add(doc, pEventTypes.down , listeners.selectorDown );\n events.add(doc, pEventTypes.move , listeners.pointerMove );\n events.add(doc, pEventTypes.over , listeners.pointerOver );\n events.add(doc, pEventTypes.out , listeners.pointerOut );\n events.add(doc, pEventTypes.up , listeners.pointerUp );\n events.add(doc, pEventTypes.cancel, listeners.pointerCancel);\n\n // autoscroll\n events.add(doc, pEventTypes.move, listeners.autoScrollMove);\n }\n else {\n events.add(doc, 'mousedown', listeners.selectorDown);\n events.add(doc, 'mousemove', listeners.pointerMove );\n events.add(doc, 'mouseup' , listeners.pointerUp );\n events.add(doc, 'mouseover', listeners.pointerOver );\n events.add(doc, 'mouseout' , listeners.pointerOut );\n\n events.add(doc, 'touchstart' , listeners.selectorDown );\n events.add(doc, 'touchmove' , listeners.pointerMove );\n events.add(doc, 'touchend' , listeners.pointerUp );\n events.add(doc, 'touchcancel', listeners.pointerCancel);\n\n // autoscroll\n events.add(doc, 'mousemove', listeners.autoScrollMove);\n events.add(doc, 'touchmove', listeners.autoScrollMove);\n }\n\n events.add(win, 'blur', endAllInteractions);\n\n try {\n if (win.frameElement) {\n var parentDoc = win.frameElement.ownerDocument,\n parentWindow = parentDoc.defaultView;\n\n events.add(parentDoc , 'mouseup' , listeners.pointerEnd);\n events.add(parentDoc , 'touchend' , listeners.pointerEnd);\n events.add(parentDoc , 'touchcancel' , listeners.pointerEnd);\n events.add(parentDoc , 'pointerup' , listeners.pointerEnd);\n events.add(parentDoc , 'MSPointerUp' , listeners.pointerEnd);\n events.add(parentWindow, 'blur' , endAllInteractions );\n }\n }\n catch (error) {\n interact.windowParentError = error;\n }\n\n // prevent native HTML5 drag on interact.js target elements\n events.add(doc, 'dragstart', function (event) {\n for (var i = 0; i < interactions.length; i++) {\n var interaction = interactions[i];\n\n if (interaction.element\n && (interaction.element === event.target\n || nodeContains(interaction.element, event.target))) {\n\n interaction.checkAndPreventDefault(event, interaction.target, interaction.element);\n return;\n }\n }\n });\n\n if (events.useAttachEvent) {\n // For IE's lack of Event#preventDefault\n events.add(doc, 'selectstart', function (event) {\n var interaction = interactions[0];\n\n if (interaction.currentAction()) {\n interaction.checkAndPreventDefault(event);\n }\n });\n\n // For IE's bad dblclick event sequence\n events.add(doc, 'dblclick', doOnInteractions('ie8Dblclick'));\n }\n\n documents.push(doc);\n }\n\n listenToDocument(document);\n\n function indexOf (array, target) {\n for (var i = 0, len = array.length; i < len; i++) {\n if (array[i] === target) {\n return i;\n }\n }\n\n return -1;\n }\n\n function contains (array, target) {\n return indexOf(array, target) !== -1;\n }\n\n function matchesSelector (element, selector, nodeList) {\n if (ie8MatchesSelector) {\n return ie8MatchesSelector(element, selector, nodeList);\n }\n\n // remove /deep/ from selectors if shadowDOM polyfill is used\n if (window !== realWindow) {\n selector = selector.replace(/\\/deep\\//g, ' ');\n }\n\n return element[prefixedMatchesSelector](selector);\n }\n\n function matchesUpTo (element, selector, limit) {\n while (isElement(element)) {\n if (matchesSelector(element, selector)) {\n return true;\n }\n\n element = parentElement(element);\n\n if (element === limit) {\n return matchesSelector(element, selector);\n }\n }\n\n return false;\n }\n\n // For IE8's lack of an Element#matchesSelector\n // taken from http://tanalin.com/en/blog/2012/12/matches-selector-ie8/ and modified\n if (!(prefixedMatchesSelector in Element.prototype) || !isFunction(Element.prototype[prefixedMatchesSelector])) {\n ie8MatchesSelector = function (element, selector, elems) {\n elems = elems || element.parentNode.querySelectorAll(selector);\n\n for (var i = 0, len = elems.length; i < len; i++) {\n if (elems[i] === element) {\n return true;\n }\n }\n\n return false;\n };\n }\n\n // requestAnimationFrame polyfill\n (function() {\n var lastTime = 0,\n vendors = ['ms', 'moz', 'webkit', 'o'];\n\n for(var x = 0; x < vendors.length && !realWindow.requestAnimationFrame; ++x) {\n reqFrame = realWindow[vendors[x]+'RequestAnimationFrame'];\n cancelFrame = realWindow[vendors[x]+'CancelAnimationFrame'] || realWindow[vendors[x]+'CancelRequestAnimationFrame'];\n }\n\n if (!reqFrame) {\n reqFrame = function(callback) {\n var currTime = new Date().getTime(),\n timeToCall = Math.max(0, 16 - (currTime - lastTime)),\n id = setTimeout(function() { callback(currTime + timeToCall); },\n timeToCall);\n lastTime = currTime + timeToCall;\n return id;\n };\n }\n\n if (!cancelFrame) {\n cancelFrame = function(id) {\n clearTimeout(id);\n };\n }\n }());\n\n /* global exports: true, module, define */\n\n // http://documentcloud.github.io/underscore/docs/underscore.html#section-11\n if (true) {\n if (typeof module !== 'undefined' && module.exports) {\n exports = module.exports = interact;\n }\n exports.interact = interact;\n }\n // AMD\n else if (typeof define === 'function' && define.amd) {\n define('interact', function() {\n return interact;\n });\n }\n else {\n realWindow.interact = interact;\n }\n\n} (typeof window === 'undefined'? undefined : window));\n\n\n/***/ },\n/* 29 */\n/***/ function(module, exports) {\n\nmodule.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-layout\",\n style: (_vm.mergedStyle)\n }, [_vm._t(\"default\"), _vm._v(\" \"), _c('grid-item', {\n directives: [{\n name: \"show\",\n rawName: \"v-show\",\n value: (_vm.isDragging),\n expression: \"isDragging\"\n }],\n staticClass: \"vue-grid-placeholder\",\n attrs: {\n \"x\": _vm.placeholder.x,\n \"y\": _vm.placeholder.y,\n \"w\": _vm.placeholder.w,\n \"h\": _vm.placeholder.h,\n \"i\": _vm.placeholder.i\n }\n })], 2)\n},staticRenderFns: []}\n\n/***/ },\n/* 30 */\n/***/ function(module, exports) {\n\nmodule.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-layout\",\n style: (_vm.mergedStyle)\n }, [_vm._t(\"default\")], 2)\n},staticRenderFns: []}\n\n/***/ },\n/* 31 */\n/***/ function(module, exports) {\n\nmodule.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.isResizable, 'resizing': _vm.isResizing, 'vue-draggable-dragging': _vm.isDragging, 'cssTransforms': _vm.useCssTransforms\n },\n style: (_vm.style)\n }, [_vm._t(\"default\"), _vm._v(\" \"), (_vm.isResizable) ? _c('span', {\n ref: \"handle\",\n class: _vm.resizableHandleClass\n }) : _vm._e()], 2)\n},staticRenderFns: []}\n\n/***/ },\n/* 32 */\n/***/ function(module, exports, __webpack_require__) {\n\n// style-loader: Adds some css to the DOM by adding a \r\n\r\n\n\n\n// WEBPACK FOOTER //\n// GridItem.vue?e2a14cb2","\r\n\r\n\n\n\n// WEBPACK FOOTER //\n// GridLayout.vue?2ecc2c24","\r\n\r\n\n\n\n// WEBPACK FOOTER //\n// ResponsiveGridLayout.vue?bf6e6790","// Get {x, y} positions from event.\r\nexport function getControlPosition(e) {\r\n return offsetXYFromParentOf(e);\r\n}\r\n\r\n\r\n// Get from offsetParent\r\nexport function offsetXYFromParentOf(evt) {\r\n const offsetParent = evt.target.offsetParent || document.body;\r\n const offsetParentRect = evt.offsetParent === document.body ? {left: 0, top: 0} : offsetParent.getBoundingClientRect();\r\n\r\n const x = evt.clientX + offsetParent.scrollLeft - offsetParentRect.left;\r\n const y = evt.clientY + offsetParent.scrollTop - offsetParentRect.top;\r\n\r\n /*const x = Math.round(evt.clientX + offsetParent.scrollLeft - offsetParentRect.left);\r\n const y = Math.round(evt.clientY + offsetParent.scrollTop - offsetParentRect.top);*/\r\n\r\n\r\n return {x, y};\r\n}\r\n\r\n\r\n// Create an data object exposed by 's events\r\nexport function createCoreData(lastX, lastY, x, y) {\r\n // State changes are often (but not always!) async. We want the latest value.\r\n const isStart = !isNum(lastX);\r\n\r\n if (isStart) {\r\n // If this is our first move, use the x and y as last coords.\r\n return {\r\n deltaX: 0, deltaY: 0,\r\n lastX: x, lastY: y,\r\n x: x, y: y\r\n };\r\n } else {\r\n // Otherwise calculate proper values.\r\n return {\r\n deltaX: x - lastX, deltaY: y - lastY,\r\n lastX: lastX, lastY: lastY,\r\n x: x, y: y\r\n };\r\n }\r\n}\r\n\r\n\r\nfunction isNum(num) {\r\n return typeof num === 'number' && !isNaN(num);\r\n}\r\n\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/draggableUtils.js","// @flow\r\n\r\nimport {cloneLayout, compact, correctBounds} from './utils';\r\n\r\nimport type {Layout} from './utils';\r\nexport type ResponsiveLayout = {lg?: Layout, md?: Layout, sm?: Layout, xs?: Layout, xxs?: Layout};\r\ntype Breakpoint = string;\r\ntype Breakpoints = {lg?: number, md?: number, sm?: number, xs?: number, xxs?: number};\r\n\r\n/**\r\n * Given a width, find the highest breakpoint that matches is valid for it (width > breakpoint).\r\n *\r\n * @param {Object} breakpoints Breakpoints object (e.g. {lg: 1200, md: 960, ...})\r\n * @param {Number} width Screen width.\r\n * @return {String} Highest breakpoint that is less than width.\r\n */\r\nexport function getBreakpointFromWidth(breakpoints: Breakpoints, width: number): Breakpoint {\r\n const sorted = sortBreakpoints(breakpoints);\r\n let matching = sorted[0];\r\n for (let i = 1, len = sorted.length; i < len; i++) {\r\n const breakpointName = sorted[i];\r\n if (width > breakpoints[breakpointName]) matching = breakpointName;\r\n }\r\n return matching;\r\n}\r\n\r\n\r\n/**\r\n * Given a breakpoint, get the # of cols set for it.\r\n * @param {String} breakpoint Breakpoint name.\r\n * @param {Object} cols Map of breakpoints to cols.\r\n * @return {Number} Number of cols.\r\n */\r\nexport function getColsFromBreakpoint(breakpoint: Breakpoint, cols: Breakpoints): number {\r\n if (!cols[breakpoint]) {\r\n throw new Error(\"ResponsiveGridLayout: `cols` entry for breakpoint \" + breakpoint + \" is missing!\");\r\n }\r\n return cols[breakpoint];\r\n}\r\n\r\n/**\r\n * Given existing layouts and a new breakpoint, find or generate a new layout.\r\n *\r\n * This finds the layout above the new one and generates from it, if it exists.\r\n *\r\n * @param {Object} layouts Existing layouts.\r\n * @param {Array} breakpoints All breakpoints.\r\n * @param {String} breakpoint New breakpoint.\r\n * @param {String} breakpoint Last breakpoint (for fallback).\r\n * @param {Number} cols Column count at new breakpoint.\r\n * @param {Boolean} verticalCompact Whether or not to compact the layout\r\n * vertically.\r\n * @return {Array} New layout.\r\n */\r\nexport function findOrGenerateResponsiveLayout(layouts: ResponsiveLayout, breakpoints: Breakpoints,\r\n breakpoint: Breakpoint, lastBreakpoint: Breakpoint,\r\n cols: number, verticalCompact: boolean): Layout {\r\n // If it already exists, just return it.\r\n if (layouts[breakpoint]) return cloneLayout(layouts[breakpoint]);\r\n // Find or generate the next layout\r\n let layout = layouts[lastBreakpoint];\r\n const breakpointsSorted = sortBreakpoints(breakpoints);\r\n const breakpointsAbove = breakpointsSorted.slice(breakpointsSorted.indexOf(breakpoint));\r\n for (let i = 0, len = breakpointsAbove.length; i < len; i++) {\r\n const b = breakpointsAbove[i];\r\n if (layouts[b]) {\r\n layout = layouts[b];\r\n break;\r\n }\r\n }\r\n layout = cloneLayout(layout || []); // clone layout so we don't modify existing items\r\n return compact(correctBounds(layout, {cols: cols}), verticalCompact);\r\n}\r\n\r\nexport function generateResponsiveLayout(layout: Layout, breakpoints: Breakpoints,\r\n breakpoint: Breakpoint, lastBreakpoint: Breakpoint,\r\n cols: number, verticalCompact: boolean): Layout {\r\n // If it already exists, just return it.\r\n /*if (layouts[breakpoint]) return cloneLayout(layouts[breakpoint]);\r\n // Find or generate the next layout\r\n let layout = layouts[lastBreakpoint];*/\r\n /*const breakpointsSorted = sortBreakpoints(breakpoints);\r\n const breakpointsAbove = breakpointsSorted.slice(breakpointsSorted.indexOf(breakpoint));\r\n for (let i = 0, len = breakpointsAbove.length; i < len; i++) {\r\n const b = breakpointsAbove[i];\r\n if (layouts[b]) {\r\n layout = layouts[b];\r\n break;\r\n }\r\n }*/\r\n layout = cloneLayout(layout || []); // clone layout so we don't modify existing items\r\n return compact(correctBounds(layout, {cols: cols}), verticalCompact);\r\n}\r\n\r\n/**\r\n * Given breakpoints, return an array of breakpoints sorted by width. This is usually\r\n * e.g. ['xxs', 'xs', 'sm', ...]\r\n *\r\n * @param {Object} breakpoints Key/value pair of breakpoint names to widths.\r\n * @return {Array} Sorted breakpoints.\r\n */\r\nexport function sortBreakpoints(breakpoints: Breakpoints): Array {\r\n const keys: Array = Object.keys(breakpoints);\r\n return keys.sort(function(a, b) {\r\n return breakpoints[a] - breakpoints[b];\r\n });\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/responsiveUtils.js","\"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\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/batch-processor/src/batch-processor.js\n// module id = 15\n// module chunks = 0","\"use strict\";\n\nvar utils = module.exports = {};\n\nutils.getOption = getOption;\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\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/batch-processor/src/utils.js\n// module id = 16\n// module chunks = 0","exports = module.exports = require(\"./../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \".vue-grid-layout{position:relative;transition:height .2s ease}\", \"\"]);\n\n// exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/css-loader!./~/vue-loader/lib/style-rewriter.js?id=data-v-66d6d8cb!./~/vue-loader/lib/selector.js?type=styles&index=0!./src/GridLayout.vue\n// module id = 17\n// module chunks = 0","exports = module.exports = require(\"./../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \".vue-grid-layout{position:relative;transition:height .2s ease}\", \"\"]);\n\n// exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/css-loader!./~/vue-loader/lib/style-rewriter.js?id=data-v-6d0d2fdf!./~/vue-loader/lib/selector.js?type=styles&index=0!./src/ResponsiveGridLayout.vue\n// module id = 18\n// module chunks = 0","exports = module.exports = require(\"./../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \".vue-grid-item{transition:all .2s ease;transition-property:left,top,right}.vue-grid-item.cssTransforms{transition-property:transform}.vue-grid-item.resizing{opacity:.6;z-index:3}.vue-grid-item.vue-draggable-dragging{z-index:3}.vue-grid-item.vue-grid-placeholder{background:red;opacity:.2;transition-duration:.1s;z-index:2;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.vue-grid-item>.vue-resizable-handle{position:absolute;width:20px;height:20px;bottom:0;right:0;background:url(\\\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pg08IS0tIEdlbmVyYXRvcjogQWRvYmUgRmlyZXdvcmtzIENTNiwgRXhwb3J0IFNWRyBFeHRlbnNpb24gYnkgQWFyb24gQmVhbGwgKGh0dHA6Ly9maXJld29ya3MuYWJlYWxsLmNvbSkgLiBWZXJzaW9uOiAwLjYuMSAgLS0+DTwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DTxzdmcgaWQ9IlVudGl0bGVkLVBhZ2UlMjAxIiB2aWV3Qm94PSIwIDAgNiA2IiBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjojZmZmZmZmMDAiIHZlcnNpb249IjEuMSINCXhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbDpzcGFjZT0icHJlc2VydmUiDQl4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjZweCIgaGVpZ2h0PSI2cHgiDT4NCTxnIG9wYWNpdHk9IjAuMzAyIj4NCQk8cGF0aCBkPSJNIDYgNiBMIDAgNiBMIDAgNC4yIEwgNCA0LjIgTCA0LjIgNC4yIEwgNC4yIDAgTCA2IDAgTCA2IDYgTCA2IDYgWiIgZmlsbD0iIzAwMDAwMCIvPg0JPC9nPg08L3N2Zz4=\\\");background-position:100% 100%;padding:0 3px 3px 0;background-repeat:no-repeat;background-origin:content-box;box-sizing:border-box;cursor:se-resize}.vue-grid-item>.vue-rtl-resizable-handle{bottom:0;left:0;background:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAuMDAwMDAwMDAwMDAwMDAyIiBoZWlnaHQ9IjEwLjAwMDAwMDAwMDAwMDAwMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KIDwhLS0gQ3JlYXRlZCB3aXRoIE1ldGhvZCBEcmF3IC0gaHR0cDovL2dpdGh1Yi5jb20vZHVvcGl4ZWwvTWV0aG9kLURyYXcvIC0tPgogPGc+CiAgPHRpdGxlPmJhY2tncm91bmQ8L3RpdGxlPgogIDxyZWN0IGZpbGw9Im5vbmUiIGlkPSJjYW52YXNfYmFja2dyb3VuZCIgaGVpZ2h0PSIxMiIgd2lkdGg9IjEyIiB5PSItMSIgeD0iLTEiLz4KICA8ZyBkaXNwbGF5PSJub25lIiBvdmVyZmxvdz0idmlzaWJsZSIgeT0iMCIgeD0iMCIgaGVpZ2h0PSIxMDAlIiB3aWR0aD0iMTAwJSIgaWQ9ImNhbnZhc0dyaWQiPgogICA8cmVjdCBmaWxsPSJ1cmwoI2dyaWRwYXR0ZXJuKSIgc3Ryb2tlLXdpZHRoPSIwIiB5PSIwIiB4PSIwIiBoZWlnaHQ9IjEwMCUiIHdpZHRoPSIxMDAlIi8+CiAgPC9nPgogPC9nPgogPGc+CiAgPHRpdGxlPkxheWVyIDE8L3RpdGxlPgogIDxsaW5lIGNhbnZhcz0iI2ZmZmZmZiIgY2FudmFzLW9wYWNpdHk9IjEiIHN0cm9rZS1saW5lY2FwPSJ1bmRlZmluZWQiIHN0cm9rZS1saW5lam9pbj0idW5kZWZpbmVkIiBpZD0ic3ZnXzEiIHkyPSItNzAuMTc4NDA3IiB4Mj0iMTI0LjQ2NDE3NSIgeTE9Ii0zOC4zOTI3MzciIHgxPSIxNDQuODIxMjg5IiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlPSIjMDAwIiBmaWxsPSJub25lIi8+CiAgPGxpbmUgc3Ryb2tlPSIjNjY2NjY2IiBzdHJva2UtbGluZWNhcD0idW5kZWZpbmVkIiBzdHJva2UtbGluZWpvaW49InVuZGVmaW5lZCIgaWQ9InN2Z181IiB5Mj0iOS4xMDY5NTciIHgyPSIwLjk0NzI0NyIgeTE9Ii0wLjAxODEyOCIgeDE9IjAuOTQ3MjQ3IiBzdHJva2Utd2lkdGg9IjIiIGZpbGw9Im5vbmUiLz4KICA8bGluZSBzdHJva2UtbGluZWNhcD0idW5kZWZpbmVkIiBzdHJva2UtbGluZWpvaW49InVuZGVmaW5lZCIgaWQ9InN2Z183IiB5Mj0iOSIgeDI9IjEwLjA3MzUyOSIgeTE9IjkiIHgxPSItMC42NTU2NCIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2U9IiM2NjY2NjYiIGZpbGw9Im5vbmUiLz4KIDwvZz4KPC9zdmc+);background-position:0 100%;padding-left:3px;background-repeat:no-repeat;background-origin:content-box;cursor:sw-resize;right:auto}\", \"\"]);\n\n// exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/css-loader!./~/vue-loader/lib/style-rewriter.js?id=data-v-e800ab18!./~/vue-loader/lib/selector.js?type=styles&index=0!./src/GridItem.vue\n// module id = 19\n// module chunks = 0","/**\n * Resize detection strategy that injects objects to elements in order to detect resize events.\n * Heavily inspired by: http://www.backalleycoder.com/2013/03/18/cross-browser-event-based-element-resize-detection/\n */\n\n\"use strict\";\n\nvar browserDetector = require(\"../browser-detector\");\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\n if(!reporter) {\n throw new Error(\"Missing required dependency: reporter.\");\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 if(!getObject(element)) {\n throw new Error(\"Element is not detectable by this strategy.\");\n }\n\n function listenerProxy() {\n listener(element);\n }\n\n if(browserDetector.isIE(8)) {\n //IE 8 does not support object, but supports the resize event directly on elements.\n getState(element).object = {\n proxy: listenerProxy\n };\n element.attachEvent(\"onresize\", listenerProxy);\n } else {\n var object = getObject(element);\n object.contentDocument.defaultView.addEventListener(\"resize\", listenerProxy);\n }\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 var debug = options.debug;\n\n function injectObject(element, callback) {\n var OBJECT_STYLE = \"display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none; padding: 0; margin: 0; opacity: 0; z-index: -1000; pointer-events: none;\";\n\n //The target element needs to be positioned (everything except static) so the absolute positioned object will be positioned relative to the target element.\n\n // Position altering may be performed directly or on object load, depending on if style resolution is possible directly or not.\n var positionCheckPerformed = false;\n\n // The element may not yet be attached to the DOM, and therefore the style object may be empty in some browsers.\n // Since the style object is a reference, it will be updated as soon as the element is attached to the DOM.\n var style = window.getComputedStyle(element);\n var width = element.offsetWidth;\n var height = element.offsetHeight;\n\n getState(element).startSize = {\n width: width,\n height: height\n };\n\n function mutateDom() {\n function alterPositionStyles() {\n if(style.position === \"static\") {\n element.style.position = \"relative\";\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 onObjectLoad() {\n // The object has been loaded, which means that the element now is guaranteed to be attached to the DOM.\n if (!positionCheckPerformed) {\n alterPositionStyles();\n }\n\n /*jshint validthis: true */\n\n function getDocument(element, callback) {\n //Opera 12 seem to call the object.onload before the actual document has been created.\n //So if it is not present, poll it with an timeout until it is present.\n //TODO: Could maybe be handled better with object.onreadystatechange or similar.\n if(!element.contentDocument) {\n setTimeout(function checkForObjectDocument() {\n getDocument(element, callback);\n }, 100);\n\n return;\n }\n\n callback(element.contentDocument);\n }\n\n //Mutating the object element here seems to fire another load event.\n //Mutating the inner document of the object element is fine though.\n var objectElement = this;\n\n //Create the style element to be added to the object.\n getDocument(objectElement, function onObjectDocumentReady(objectDocument) {\n //Notify that the element is ready to be listened to.\n callback(element);\n });\n }\n\n // The element may be detached from the DOM, and some browsers does not support style resolving of detached elements.\n // The alterPositionStyles needs to be delayed until we know the element has been attached to the DOM (which we are sure of when the onObjectLoad has been fired), if style resolution is not possible.\n if (style.position !== \"\") {\n alterPositionStyles(style);\n positionCheckPerformed = true;\n }\n\n //Add an object element as a child to the target element that will be listened to for resize events.\n var object = document.createElement(\"object\");\n object.style.cssText = OBJECT_STYLE;\n object.tabIndex = -1;\n object.type = \"text/html\";\n object.onload = onObjectLoad;\n\n //Safari: This must occur before adding the object to the DOM.\n //IE: Does not like that this happens before, even if it is also added after.\n if(!browserDetector.isIE()) {\n object.data = \"about:blank\";\n }\n\n element.appendChild(object);\n getState(element).object = object;\n\n //IE: This must occur after adding the object to the DOM.\n if(browserDetector.isIE()) {\n object.data = \"about:blank\";\n }\n }\n\n if(batchProcessor) {\n batchProcessor.add(mutateDom);\n } else {\n mutateDom();\n }\n }\n\n if(browserDetector.isIE(8)) {\n //IE 8 does not support objects properly. Luckily they do support the resize event.\n //So do not inject the object and notify that the element is already ready to be listened to.\n //The event handler for the resize event is attached in the utils.addListener instead.\n callback(element);\n } else {\n injectObject(element, callback);\n }\n }\n\n /**\n * Returns the child object of the target element.\n * @private\n * @param {element} element The target element.\n * @returns The object element of the target.\n */\n function getObject(element) {\n return getState(element).object;\n }\n\n function uninstall(element) {\n if(browserDetector.isIE(8)) {\n element.detachEvent(\"onresize\", getState(element).object.proxy);\n } else {\n element.removeChild(getObject(element));\n }\n delete getState(element).object;\n }\n\n return {\n makeDetectable: makeDetectable,\n addListener: addListener,\n uninstall: uninstall\n };\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/element-resize-detector/src/detection-strategy/object.js\n// module id = 20\n// module chunks = 0","/**\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 // 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 var styleId = \"erd_scroll_detection_scrollbar_style\";\n var detectionContainerClass = \"erd_scroll_detection_container\";\n injectScrollStyle(styleId, detectionContainerClass);\n\n function getScrollbarSizes() {\n var width = 500;\n var height = 500;\n\n var child = document.createElement(\"div\");\n child.style.cssText = \"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 = \"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(styleId, containerClass) {\n function injectStyle(style, method) {\n method = method || function (element) {\n document.head.appendChild(element);\n };\n\n var styleElement = document.createElement(\"style\");\n styleElement.innerHTML = style;\n styleElement.id = styleId;\n method(styleElement);\n return styleElement;\n }\n\n if (!document.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 { display: none; }\\n\\n\";\n style += \".\" + containerAnimationActiveClass + \" { -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 return element === element.ownerDocument.body || element.ownerDocument.body.contains(element);\n }\n return !isInDocument(element);\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 return getComputedStyle(container).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 = 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 = \"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.position = \"relative\";\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 = \"position: absolute; flex: none; overflow: hidden; z-index: -1; visibility: hidden; width: 100%; height: 100%; left: 0px; top: 0px;\";\n var containerStyle = \"position: absolute; flex: none; overflow: hidden; z-index: -1; visibility: hidden; \" + getLeftTopBottomRightCssText(-(1 + scrollbarWidth), -(1 + scrollbarHeight), -scrollbarHeight, -scrollbarWidth);\n var expandStyle = \"position: absolute; flex: none; overflow: scroll; z-index: -1; visibility: hidden; width: 100%; height: 100%;\";\n var shrinkStyle = \"position: absolute; flex: none; overflow: scroll; z-index: -1; visibility: hidden; width: 100%; height: 100%;\";\n var expandChildStyle = \"position: absolute; left: 0; top: 0;\";\n var shrinkChildStyle = \"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 getState(element).onExpand && getState(element).onExpand();\n }\n\n function onShrinkScroll() {\n getState(element).onShrink && getState(element).onShrink();\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.width = expandWidth + \"px\";\n expandChild.style.height = expandHeight + \"px\";\n }\n\n function updateDetectorElements(done) {\n var width = element.offsetWidth;\n var height = element.offsetHeight;\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 (!getState(element)) {\n debug(\"Aborting because element has been uninstalled\");\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 if (!getState(element)) {\n debug(\"Aborting because element has been uninstalled\");\n return;\n }\n\n positionScrollbars(element, width, height);\n });\n\n if (done) {\n batchProcessor.add(2, function () {\n if (!getState(element)) {\n debug(\"Aborting because element has been uninstalled\");\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 the 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 var width = element.offsetWidth;\n var height = element.offsetHeight;\n\n if (width !== element.lastWidth || height !== element.lastHeight) {\n debug(\"Element size changed.\");\n updateDetectorElements(notifyListenersIfNeeded);\n } else {\n debug(\"Element size has not changed (\" + width + \"x\" + height + \").\");\n }\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 };\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/element-resize-detector/src/detection-strategy/scroll.js\n// module id = 21\n// module chunks = 0","\"use strict\";\n\nmodule.exports = function(options) {\n var getState = options.stateHandler.getState;\n\n /**\n * Tells if the element has been made detectable and ready to be listened for resize events.\n * @public\n * @param {element} The element to check.\n * @returns {boolean} True or false depending on if the element is detectable or not.\n */\n function isDetectable(element) {\n var state = getState(element);\n return state && !!state.isDetectable;\n }\n\n /**\n * Marks the element that it has been made detectable and ready to be listened for resize events.\n * @public\n * @param {element} The element to mark.\n */\n function markAsDetectable(element) {\n getState(element).isDetectable = true;\n }\n\n /**\n * Tells if the element is busy or not.\n * @public\n * @param {element} The element to check.\n * @returns {boolean} True or false depending on if the element is busy or not.\n */\n function isBusy(element) {\n return !!getState(element).busy;\n }\n\n /**\n * Marks the object is busy and should not be made detectable.\n * @public\n * @param {element} element The element to mark.\n * @param {boolean} busy If the element is busy or not.\n */\n function markBusy(element, busy) {\n getState(element).busy = !!busy;\n }\n\n return {\n isDetectable: isDetectable,\n markAsDetectable: markAsDetectable,\n isBusy: isBusy,\n markBusy: markBusy\n };\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/element-resize-detector/src/element-utils.js\n// module id = 22\n// module chunks = 0","\"use strict\";\n\nmodule.exports = function() {\n var idCount = 1;\n\n /**\n * Generates a new unique id in the context.\n * @public\n * @returns {number} A unique id in the context.\n */\n function generate() {\n return idCount++;\n }\n\n return {\n generate: generate\n };\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/element-resize-detector/src/id-generator.js\n// module id = 23\n// module chunks = 0","\"use strict\";\n\nmodule.exports = function(options) {\n var idGenerator = options.idGenerator;\n var getState = options.stateHandler.getState;\n\n /**\n * Gets the resize detector id of the element.\n * @public\n * @param {element} element The target element to get the id of.\n * @returns {string|number|null} The id of the element. Null if it has no id.\n */\n function getId(element) {\n var state = getState(element);\n\n if (state && state.id !== undefined) {\n return state.id;\n }\n\n return null;\n }\n\n /**\n * Sets the resize detector id of the element. Requires the element to have a resize detector state initialized.\n * @public\n * @param {element} element The target element to set the id of.\n * @returns {string|number|null} The id of the element.\n */\n function setId(element) {\n var state = getState(element);\n\n if (!state) {\n throw new Error(\"setId required the element to have a resize detection state.\");\n }\n\n var id = idGenerator.generate();\n\n state.id = id;\n\n return id;\n }\n\n return {\n get: getId,\n set: setId\n };\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/element-resize-detector/src/id-handler.js\n// module id = 24\n// module chunks = 0","\"use strict\";\n\nmodule.exports = function(idHandler) {\n var eventListeners = {};\n\n /**\n * Gets all listeners for the given element.\n * @public\n * @param {element} element The element to get all listeners for.\n * @returns All listeners for the given element.\n */\n function getListeners(element) {\n var id = idHandler.get(element);\n\n if (id === undefined) {\n return [];\n }\n\n return eventListeners[id] || [];\n }\n\n /**\n * Stores the given listener for the given element. Will not actually add the listener to the element.\n * @public\n * @param {element} element The element that should have the listener added.\n * @param {function} listener The callback that the element has added.\n */\n function addListener(element, listener) {\n var id = idHandler.get(element);\n\n if(!eventListeners[id]) {\n eventListeners[id] = [];\n }\n\n eventListeners[id].push(listener);\n }\n\n function removeListener(element, listener) {\n var listeners = getListeners(element);\n for (var i = 0, len = listeners.length; i < len; ++i) {\n if (listeners[i] === listener) {\n listeners.splice(i, 1);\n break;\n }\n }\n }\n\n function removeAllListeners(element) {\n var listeners = getListeners(element);\n if (!listeners) { return; }\n listeners.length = 0;\n }\n\n return {\n get: getListeners,\n add: addListener,\n removeListener: removeListener,\n removeAllListeners: removeAllListeners\n };\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/element-resize-detector/src/listener-handler.js\n// module id = 25\n// module chunks = 0","\"use strict\";\n\n/* global console: false */\n\n/**\n * Reporter that handles the reporting of logs, warnings and errors.\n * @public\n * @param {boolean} quiet Tells if the reporter should be quiet or not.\n */\nmodule.exports = function(quiet) {\n function noop() {\n //Does nothing.\n }\n\n var reporter = {\n log: noop,\n warn: noop,\n error: noop\n };\n\n if(!quiet && window.console) {\n var attachFunction = function(reporter, name) {\n //The proxy is needed to be able to call the method with the console context,\n //since we cannot use bind.\n reporter[name] = function reporterProxy() {\n var f = console[name];\n if (f.apply) { //IE9 does not support console.log.apply :)\n f.apply(console, arguments);\n } else {\n for (var i = 0; i < arguments.length; i++) {\n f(arguments[i]);\n }\n }\n };\n };\n\n attachFunction(reporter, \"log\");\n attachFunction(reporter, \"warn\");\n attachFunction(reporter, \"error\");\n }\n\n return reporter;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/element-resize-detector/src/reporter.js\n// module id = 26\n// module chunks = 0","\"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\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/element-resize-detector/src/state-handler.js\n// module id = 27\n// module chunks = 0","/**\n * interact.js v1.2.8\n *\n * Copyright (c) 2012-2015 Taye Adeyemi \n * Open source under the MIT License.\n * https://raw.github.com/taye/interact.js/master/LICENSE\n */\n(function (realWindow) {\n 'use strict';\n\n // return early if there's no window to work with (eg. Node.js)\n if (!realWindow) { return; }\n\n var // get wrapped window if using Shadow DOM polyfill\n window = (function () {\n // create a TextNode\n var el = realWindow.document.createTextNode('');\n\n // check if it's wrapped by a polyfill\n if (el.ownerDocument !== realWindow.document\n && typeof realWindow.wrap === 'function'\n && realWindow.wrap(el) === el) {\n // return wrapped window\n return realWindow.wrap(realWindow);\n }\n\n // no Shadow DOM polyfil or native implementation\n return realWindow;\n }()),\n\n document = window.document,\n DocumentFragment = window.DocumentFragment || blank,\n SVGElement = window.SVGElement || blank,\n SVGSVGElement = window.SVGSVGElement || blank,\n SVGElementInstance = window.SVGElementInstance || blank,\n HTMLElement = window.HTMLElement || window.Element,\n\n PointerEvent = (window.PointerEvent || window.MSPointerEvent),\n pEventTypes,\n\n hypot = Math.hypot || function (x, y) { return Math.sqrt(x * x + y * y); },\n\n tmpXY = {}, // reduce object creation in getXY()\n\n documents = [], // all documents being listened to\n\n interactables = [], // all set interactables\n interactions = [], // all interactions\n\n dynamicDrop = false,\n\n // {\n // type: {\n // selectors: ['selector', ...],\n // contexts : [document, ...],\n // listeners: [[listener, useCapture], ...]\n // }\n // }\n delegatedEvents = {},\n\n defaultOptions = {\n base: {\n accept : null,\n actionChecker : null,\n styleCursor : true,\n preventDefault: 'auto',\n origin : { x: 0, y: 0 },\n deltaSource : 'page',\n allowFrom : null,\n ignoreFrom : null,\n _context : document,\n dropChecker : null\n },\n\n drag: {\n enabled: false,\n manualStart: true,\n max: Infinity,\n maxPerElement: 1,\n\n snap: null,\n restrict: null,\n inertia: null,\n autoScroll: null,\n\n axis: 'xy'\n },\n\n drop: {\n enabled: false,\n accept: null,\n overlap: 'pointer'\n },\n\n resize: {\n enabled: false,\n manualStart: false,\n max: Infinity,\n maxPerElement: 1,\n\n snap: null,\n restrict: null,\n inertia: null,\n autoScroll: null,\n\n square: false,\n preserveAspectRatio: false,\n axis: 'xy',\n\n // use default margin\n margin: NaN,\n\n // object with props left, right, top, bottom which are\n // true/false values to resize when the pointer is over that edge,\n // CSS selectors to match the handles for each direction\n // or the Elements for each handle\n edges: null,\n\n // a value of 'none' will limit the resize rect to a minimum of 0x0\n // 'negate' will alow the rect to have negative width/height\n // 'reposition' will keep the width/height positive by swapping\n // the top and bottom edges and/or swapping the left and right edges\n invert: 'none'\n },\n\n gesture: {\n manualStart: false,\n enabled: false,\n max: Infinity,\n maxPerElement: 1,\n\n restrict: null\n },\n\n perAction: {\n manualStart: false,\n max: Infinity,\n maxPerElement: 1,\n\n snap: {\n enabled : false,\n endOnly : false,\n range : Infinity,\n targets : null,\n offsets : null,\n\n relativePoints: null\n },\n\n restrict: {\n enabled: false,\n endOnly: false\n },\n\n autoScroll: {\n enabled : false,\n container : null, // the item that is scrolled (Window or HTMLElement)\n margin : 60,\n speed : 300 // the scroll speed in pixels per second\n },\n\n inertia: {\n enabled : false,\n resistance : 10, // the lambda in exponential decay\n minSpeed : 100, // target speed must be above this for inertia to start\n endSpeed : 10, // the speed at which inertia is slow enough to stop\n allowResume : true, // allow resuming an action in inertia phase\n zeroResumeDelta : true, // if an action is resumed after launch, set dx/dy to 0\n smoothEndDuration: 300 // animate to snap/restrict endOnly if there's no inertia\n }\n },\n\n _holdDuration: 600\n },\n\n // Things related to autoScroll\n autoScroll = {\n interaction: null,\n i: null, // the handle returned by window.setInterval\n x: 0, y: 0, // Direction each pulse is to scroll in\n\n // scroll the window by the values in scroll.x/y\n scroll: function () {\n var options = autoScroll.interaction.target.options[autoScroll.interaction.prepared.name].autoScroll,\n container = options.container || getWindow(autoScroll.interaction.element),\n now = new Date().getTime(),\n // change in time in seconds\n dtx = (now - autoScroll.prevTimeX) / 1000,\n dty = (now - autoScroll.prevTimeY) / 1000,\n vx, vy, sx, sy;\n\n // displacement\n if (options.velocity) {\n vx = options.velocity.x;\n vy = options.velocity.y;\n }\n else {\n vx = vy = options.speed\n }\n \n sx = vx * dtx;\n sy = vy * dty;\n\n if (sx >= 1 || sy >= 1) {\n if (isWindow(container)) {\n container.scrollBy(autoScroll.x * sx, autoScroll.y * sy);\n }\n else if (container) {\n container.scrollLeft += autoScroll.x * sx;\n container.scrollTop += autoScroll.y * sy;\n }\n\n if (sx >=1) autoScroll.prevTimeX = now;\n if (sy >= 1) autoScroll.prevTimeY = now;\n }\n\n if (autoScroll.isScrolling) {\n cancelFrame(autoScroll.i);\n autoScroll.i = reqFrame(autoScroll.scroll);\n }\n },\n\n isScrolling: false,\n prevTimeX: 0,\n prevTimeY: 0,\n\n start: function (interaction) {\n autoScroll.isScrolling = true;\n cancelFrame(autoScroll.i);\n\n autoScroll.interaction = interaction;\n autoScroll.prevTimeX = new Date().getTime();\n autoScroll.prevTimeY = new Date().getTime();\n autoScroll.i = reqFrame(autoScroll.scroll);\n },\n\n stop: function () {\n autoScroll.isScrolling = false;\n cancelFrame(autoScroll.i);\n }\n },\n\n // Does the browser support touch input?\n supportsTouch = (('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch),\n\n // Does the browser support PointerEvents\n // Avoid PointerEvent bugs introduced in Chrome 55\n supportsPointerEvent = PointerEvent && !/Chrome/.test(navigator.userAgent),\n\n // Less Precision with touch input\n margin = supportsTouch || supportsPointerEvent? 20: 10,\n\n pointerMoveTolerance = 1,\n\n // for ignoring browser's simulated mouse events\n prevTouchTime = 0,\n\n // Allow this many interactions to happen simultaneously\n maxInteractions = Infinity,\n\n // Check if is IE9 or older\n actionCursors = (document.all && !window.atob) ? {\n drag : 'move',\n resizex : 'e-resize',\n resizey : 's-resize',\n resizexy: 'se-resize',\n\n resizetop : 'n-resize',\n resizeleft : 'w-resize',\n resizebottom : 's-resize',\n resizeright : 'e-resize',\n resizetopleft : 'se-resize',\n resizebottomright: 'se-resize',\n resizetopright : 'ne-resize',\n resizebottomleft : 'ne-resize',\n\n gesture : ''\n } : {\n drag : 'move',\n resizex : 'ew-resize',\n resizey : 'ns-resize',\n resizexy: 'nwse-resize',\n\n resizetop : 'ns-resize',\n resizeleft : 'ew-resize',\n resizebottom : 'ns-resize',\n resizeright : 'ew-resize',\n resizetopleft : 'nwse-resize',\n resizebottomright: 'nwse-resize',\n resizetopright : 'nesw-resize',\n resizebottomleft : 'nesw-resize',\n\n gesture : ''\n },\n\n actionIsEnabled = {\n drag : true,\n resize : true,\n gesture: true\n },\n\n // because Webkit and Opera still use 'mousewheel' event type\n wheelEvent = 'onmousewheel' in document? 'mousewheel': 'wheel',\n\n eventTypes = [\n 'dragstart',\n 'dragmove',\n 'draginertiastart',\n 'dragend',\n 'dragenter',\n 'dragleave',\n 'dropactivate',\n 'dropdeactivate',\n 'dropmove',\n 'drop',\n 'resizestart',\n 'resizemove',\n 'resizeinertiastart',\n 'resizeend',\n 'gesturestart',\n 'gesturemove',\n 'gestureinertiastart',\n 'gestureend',\n\n 'down',\n 'move',\n 'up',\n 'cancel',\n 'tap',\n 'doubletap',\n 'hold'\n ],\n\n globalEvents = {},\n\n // Opera Mobile must be handled differently\n isOperaMobile = navigator.appName == 'Opera' &&\n supportsTouch &&\n navigator.userAgent.match('Presto'),\n\n // scrolling doesn't change the result of getClientRects on iOS 7\n isIOS7 = (/iP(hone|od|ad)/.test(navigator.platform)\n && /OS 7[^\\d]/.test(navigator.appVersion)),\n\n // prefix matchesSelector\n prefixedMatchesSelector = 'matches' in Element.prototype?\n 'matches': 'webkitMatchesSelector' in Element.prototype?\n 'webkitMatchesSelector': 'mozMatchesSelector' in Element.prototype?\n 'mozMatchesSelector': 'oMatchesSelector' in Element.prototype?\n 'oMatchesSelector': 'msMatchesSelector',\n\n // will be polyfill function if browser is IE8\n ie8MatchesSelector,\n\n // native requestAnimationFrame or polyfill\n reqFrame = realWindow.requestAnimationFrame,\n cancelFrame = realWindow.cancelAnimationFrame,\n\n // Events wrapper\n events = (function () {\n var useAttachEvent = ('attachEvent' in window) && !('addEventListener' in window),\n addEvent = useAttachEvent? 'attachEvent': 'addEventListener',\n removeEvent = useAttachEvent? 'detachEvent': 'removeEventListener',\n on = useAttachEvent? 'on': '',\n\n elements = [],\n targets = [],\n attachedListeners = [];\n\n function add (element, type, listener, useCapture) {\n var elementIndex = indexOf(elements, element),\n target = targets[elementIndex];\n\n if (!target) {\n target = {\n events: {},\n typeCount: 0\n };\n\n elementIndex = elements.push(element) - 1;\n targets.push(target);\n\n attachedListeners.push((useAttachEvent ? {\n supplied: [],\n wrapped : [],\n useCount: []\n } : null));\n }\n\n if (!target.events[type]) {\n target.events[type] = [];\n target.typeCount++;\n }\n\n if (!contains(target.events[type], listener)) {\n var ret;\n\n if (useAttachEvent) {\n var listeners = attachedListeners[elementIndex],\n listenerIndex = indexOf(listeners.supplied, listener);\n\n var wrapped = listeners.wrapped[listenerIndex] || function (event) {\n if (!event.immediatePropagationStopped) {\n event.target = event.srcElement;\n event.currentTarget = element;\n\n event.preventDefault = event.preventDefault || preventDef;\n event.stopPropagation = event.stopPropagation || stopProp;\n event.stopImmediatePropagation = event.stopImmediatePropagation || stopImmProp;\n\n if (/mouse|click/.test(event.type)) {\n event.pageX = event.clientX + getWindow(element).document.documentElement.scrollLeft;\n event.pageY = event.clientY + getWindow(element).document.documentElement.scrollTop;\n }\n\n listener(event);\n }\n };\n\n ret = element[addEvent](on + type, wrapped, Boolean(useCapture));\n\n if (listenerIndex === -1) {\n listeners.supplied.push(listener);\n listeners.wrapped.push(wrapped);\n listeners.useCount.push(1);\n }\n else {\n listeners.useCount[listenerIndex]++;\n }\n }\n else {\n ret = element[addEvent](type, listener, useCapture || false);\n }\n target.events[type].push(listener);\n\n return ret;\n }\n }\n\n function remove (element, type, listener, useCapture) {\n var i,\n elementIndex = indexOf(elements, element),\n target = targets[elementIndex],\n listeners,\n listenerIndex,\n wrapped = listener;\n\n if (!target || !target.events) {\n return;\n }\n\n if (useAttachEvent) {\n listeners = attachedListeners[elementIndex];\n listenerIndex = indexOf(listeners.supplied, listener);\n wrapped = listeners.wrapped[listenerIndex];\n }\n\n if (type === 'all') {\n for (type in target.events) {\n if (target.events.hasOwnProperty(type)) {\n remove(element, type, 'all');\n }\n }\n return;\n }\n\n if (target.events[type]) {\n var len = target.events[type].length;\n\n if (listener === 'all') {\n for (i = 0; i < len; i++) {\n remove(element, type, target.events[type][i], Boolean(useCapture));\n }\n return;\n } else {\n for (i = 0; i < len; i++) {\n if (target.events[type][i] === listener) {\n element[removeEvent](on + type, wrapped, useCapture || false);\n target.events[type].splice(i, 1);\n\n if (useAttachEvent && listeners) {\n listeners.useCount[listenerIndex]--;\n if (listeners.useCount[listenerIndex] === 0) {\n listeners.supplied.splice(listenerIndex, 1);\n listeners.wrapped.splice(listenerIndex, 1);\n listeners.useCount.splice(listenerIndex, 1);\n }\n }\n\n break;\n }\n }\n }\n\n if (target.events[type] && target.events[type].length === 0) {\n target.events[type] = null;\n target.typeCount--;\n }\n }\n\n if (!target.typeCount) {\n targets.splice(elementIndex, 1);\n elements.splice(elementIndex, 1);\n attachedListeners.splice(elementIndex, 1);\n }\n }\n\n function preventDef () {\n this.returnValue = false;\n }\n\n function stopProp () {\n this.cancelBubble = true;\n }\n\n function stopImmProp () {\n this.cancelBubble = true;\n this.immediatePropagationStopped = true;\n }\n\n return {\n add: add,\n remove: remove,\n useAttachEvent: useAttachEvent,\n\n _elements: elements,\n _targets: targets,\n _attachedListeners: attachedListeners\n };\n }());\n\n function blank () {}\n\n function isElement (o) {\n if (!o || (typeof o !== 'object')) { return false; }\n\n var _window = getWindow(o) || window;\n\n return (/object|function/.test(typeof _window.Element)\n ? o instanceof _window.Element //DOM2\n : o.nodeType === 1 && typeof o.nodeName === \"string\");\n }\n function isWindow (thing) { return thing === window || !!(thing && thing.Window) && (thing instanceof thing.Window); }\n function isDocFrag (thing) { return !!thing && thing instanceof DocumentFragment; }\n function isArray (thing) {\n return isObject(thing)\n && (typeof thing.length !== undefined)\n && isFunction(thing.splice);\n }\n function isObject (thing) { return !!thing && (typeof thing === 'object'); }\n function isFunction (thing) { return typeof thing === 'function'; }\n function isNumber (thing) { return typeof thing === 'number' ; }\n function isBool (thing) { return typeof thing === 'boolean' ; }\n function isString (thing) { return typeof thing === 'string' ; }\n\n function trySelector (value) {\n if (!isString(value)) { return false; }\n\n // an exception will be raised if it is invalid\n document.querySelector(value);\n return true;\n }\n\n function extend (dest, source) {\n for (var prop in source) {\n dest[prop] = source[prop];\n }\n return dest;\n }\n\n var prefixedPropREs = {\n webkit: /(Movement[XY]|Radius[XY]|RotationAngle|Force)$/\n };\n\n function pointerExtend (dest, source) {\n for (var prop in source) {\n var deprecated = false;\n\n // skip deprecated prefixed properties\n for (var vendor in prefixedPropREs) {\n if (prop.indexOf(vendor) === 0 && prefixedPropREs[vendor].test(prop)) {\n deprecated = true;\n break;\n }\n }\n\n if (!deprecated) {\n dest[prop] = source[prop];\n }\n }\n return dest;\n }\n\n function copyCoords (dest, src) {\n dest.page = dest.page || {};\n dest.page.x = src.page.x;\n dest.page.y = src.page.y;\n\n dest.client = dest.client || {};\n dest.client.x = src.client.x;\n dest.client.y = src.client.y;\n\n dest.timeStamp = src.timeStamp;\n }\n\n function setEventXY (targetObj, pointers, interaction) {\n var pointer = (pointers.length > 1\n ? pointerAverage(pointers)\n : pointers[0]);\n\n getPageXY(pointer, tmpXY, interaction);\n targetObj.page.x = tmpXY.x;\n targetObj.page.y = tmpXY.y;\n\n getClientXY(pointer, tmpXY, interaction);\n targetObj.client.x = tmpXY.x;\n targetObj.client.y = tmpXY.y;\n\n targetObj.timeStamp = new Date().getTime();\n }\n\n function setEventDeltas (targetObj, prev, cur) {\n targetObj.page.x = cur.page.x - prev.page.x;\n targetObj.page.y = cur.page.y - prev.page.y;\n targetObj.client.x = cur.client.x - prev.client.x;\n targetObj.client.y = cur.client.y - prev.client.y;\n targetObj.timeStamp = new Date().getTime() - prev.timeStamp;\n\n // set pointer velocity\n var dt = Math.max(targetObj.timeStamp / 1000, 0.001);\n targetObj.page.speed = hypot(targetObj.page.x, targetObj.page.y) / dt;\n targetObj.page.vx = targetObj.page.x / dt;\n targetObj.page.vy = targetObj.page.y / dt;\n\n targetObj.client.speed = hypot(targetObj.client.x, targetObj.page.y) / dt;\n targetObj.client.vx = targetObj.client.x / dt;\n targetObj.client.vy = targetObj.client.y / dt;\n }\n\n function isNativePointer (pointer) {\n return (pointer instanceof window.Event\n || (supportsTouch && window.Touch && pointer instanceof window.Touch));\n }\n\n // Get specified X/Y coords for mouse or event.touches[0]\n function getXY (type, pointer, xy) {\n xy = xy || {};\n type = type || 'page';\n\n xy.x = pointer[type + 'X'];\n xy.y = pointer[type + 'Y'];\n\n return xy;\n }\n\n function getPageXY (pointer, page) {\n page = page || {};\n\n // Opera Mobile handles the viewport and scrolling oddly\n if (isOperaMobile && isNativePointer(pointer)) {\n getXY('screen', pointer, page);\n\n page.x += window.scrollX;\n page.y += window.scrollY;\n }\n else {\n getXY('page', pointer, page);\n }\n\n return page;\n }\n\n function getClientXY (pointer, client) {\n client = client || {};\n\n if (isOperaMobile && isNativePointer(pointer)) {\n // Opera Mobile handles the viewport and scrolling oddly\n getXY('screen', pointer, client);\n }\n else {\n getXY('client', pointer, client);\n }\n\n return client;\n }\n\n function getScrollXY (win) {\n win = win || window;\n return {\n x: win.scrollX || win.document.documentElement.scrollLeft,\n y: win.scrollY || win.document.documentElement.scrollTop\n };\n }\n\n function getPointerId (pointer) {\n return isNumber(pointer.pointerId)? pointer.pointerId : pointer.identifier;\n }\n\n function getActualElement (element) {\n return (element instanceof SVGElementInstance\n ? element.correspondingUseElement\n : element);\n }\n\n function getWindow (node) {\n if (isWindow(node)) {\n return node;\n }\n\n var rootNode = (node.ownerDocument || node);\n\n return rootNode.defaultView || rootNode.parentWindow || window;\n }\n\n function getElementClientRect (element) {\n var clientRect = (element instanceof SVGElement\n ? element.getBoundingClientRect()\n : element.getClientRects()[0]);\n\n return clientRect && {\n left : clientRect.left,\n right : clientRect.right,\n top : clientRect.top,\n bottom: clientRect.bottom,\n width : clientRect.width || clientRect.right - clientRect.left,\n height: clientRect.height || clientRect.bottom - clientRect.top\n };\n }\n\n function getElementRect (element) {\n var clientRect = getElementClientRect(element);\n\n if (!isIOS7 && clientRect) {\n var scroll = getScrollXY(getWindow(element));\n\n clientRect.left += scroll.x;\n clientRect.right += scroll.x;\n clientRect.top += scroll.y;\n clientRect.bottom += scroll.y;\n }\n\n return clientRect;\n }\n\n function getTouchPair (event) {\n var touches = [];\n\n // array of touches is supplied\n if (isArray(event)) {\n touches[0] = event[0];\n touches[1] = event[1];\n }\n // an event\n else {\n if (event.type === 'touchend') {\n if (event.touches.length === 1) {\n touches[0] = event.touches[0];\n touches[1] = event.changedTouches[0];\n }\n else if (event.touches.length === 0) {\n touches[0] = event.changedTouches[0];\n touches[1] = event.changedTouches[1];\n }\n }\n else {\n touches[0] = event.touches[0];\n touches[1] = event.touches[1];\n }\n }\n\n return touches;\n }\n\n function pointerAverage (pointers) {\n var average = {\n pageX : 0,\n pageY : 0,\n clientX: 0,\n clientY: 0,\n screenX: 0,\n screenY: 0\n };\n var prop;\n\n for (var i = 0; i < pointers.length; i++) {\n for (prop in average) {\n average[prop] += pointers[i][prop];\n }\n }\n for (prop in average) {\n average[prop] /= pointers.length;\n }\n\n return average;\n }\n\n function touchBBox (event) {\n if (!event.length && !(event.touches && event.touches.length > 1)) {\n return;\n }\n\n var touches = getTouchPair(event),\n minX = Math.min(touches[0].pageX, touches[1].pageX),\n minY = Math.min(touches[0].pageY, touches[1].pageY),\n maxX = Math.max(touches[0].pageX, touches[1].pageX),\n maxY = Math.max(touches[0].pageY, touches[1].pageY);\n\n return {\n x: minX,\n y: minY,\n left: minX,\n top: minY,\n width: maxX - minX,\n height: maxY - minY\n };\n }\n\n function touchDistance (event, deltaSource) {\n deltaSource = deltaSource || defaultOptions.deltaSource;\n\n var sourceX = deltaSource + 'X',\n sourceY = deltaSource + 'Y',\n touches = getTouchPair(event);\n\n\n var dx = touches[0][sourceX] - touches[1][sourceX],\n dy = touches[0][sourceY] - touches[1][sourceY];\n\n return hypot(dx, dy);\n }\n\n function touchAngle (event, prevAngle, deltaSource) {\n deltaSource = deltaSource || defaultOptions.deltaSource;\n\n var sourceX = deltaSource + 'X',\n sourceY = deltaSource + 'Y',\n touches = getTouchPair(event),\n dx = touches[0][sourceX] - touches[1][sourceX],\n dy = touches[0][sourceY] - touches[1][sourceY],\n angle = 180 * Math.atan(dy / dx) / Math.PI;\n\n if (isNumber(prevAngle)) {\n var dr = angle - prevAngle,\n drClamped = dr % 360;\n\n if (drClamped > 315) {\n angle -= 360 + (angle / 360)|0 * 360;\n }\n else if (drClamped > 135) {\n angle -= 180 + (angle / 360)|0 * 360;\n }\n else if (drClamped < -315) {\n angle += 360 + (angle / 360)|0 * 360;\n }\n else if (drClamped < -135) {\n angle += 180 + (angle / 360)|0 * 360;\n }\n }\n\n return angle;\n }\n\n function getOriginXY (interactable, element) {\n var origin = interactable\n ? interactable.options.origin\n : defaultOptions.origin;\n\n if (origin === 'parent') {\n origin = parentElement(element);\n }\n else if (origin === 'self') {\n origin = interactable.getRect(element);\n }\n else if (trySelector(origin)) {\n origin = closest(element, origin) || { x: 0, y: 0 };\n }\n\n if (isFunction(origin)) {\n origin = origin(interactable && element);\n }\n\n if (isElement(origin)) {\n origin = getElementRect(origin);\n }\n\n origin.x = ('x' in origin)? origin.x : origin.left;\n origin.y = ('y' in origin)? origin.y : origin.top;\n\n return origin;\n }\n\n // http://stackoverflow.com/a/5634528/2280888\n function _getQBezierValue(t, p1, p2, p3) {\n var iT = 1 - t;\n return iT * iT * p1 + 2 * iT * t * p2 + t * t * p3;\n }\n\n function getQuadraticCurvePoint(startX, startY, cpX, cpY, endX, endY, position) {\n return {\n x: _getQBezierValue(position, startX, cpX, endX),\n y: _getQBezierValue(position, startY, cpY, endY)\n };\n }\n\n // http://gizma.com/easing/\n function easeOutQuad (t, b, c, d) {\n t /= d;\n return -c * t*(t-2) + b;\n }\n\n function nodeContains (parent, child) {\n while (child) {\n if (child === parent) {\n return true;\n }\n\n child = child.parentNode;\n }\n\n return false;\n }\n\n function closest (child, selector) {\n var parent = parentElement(child);\n\n while (isElement(parent)) {\n if (matchesSelector(parent, selector)) { return parent; }\n\n parent = parentElement(parent);\n }\n\n return null;\n }\n\n function parentElement (node) {\n var parent = node.parentNode;\n\n if (isDocFrag(parent)) {\n // skip past #shado-root fragments\n while ((parent = parent.host) && isDocFrag(parent)) {}\n\n return parent;\n }\n\n return parent;\n }\n\n function inContext (interactable, element) {\n return interactable._context === element.ownerDocument\n || nodeContains(interactable._context, element);\n }\n\n function testIgnore (interactable, interactableElement, element) {\n var ignoreFrom = interactable.options.ignoreFrom;\n\n if (!ignoreFrom || !isElement(element)) { return false; }\n\n if (isString(ignoreFrom)) {\n return matchesUpTo(element, ignoreFrom, interactableElement);\n }\n else if (isElement(ignoreFrom)) {\n return nodeContains(ignoreFrom, element);\n }\n\n return false;\n }\n\n function testAllow (interactable, interactableElement, element) {\n var allowFrom = interactable.options.allowFrom;\n\n if (!allowFrom) { return true; }\n\n if (!isElement(element)) { return false; }\n\n if (isString(allowFrom)) {\n return matchesUpTo(element, allowFrom, interactableElement);\n }\n else if (isElement(allowFrom)) {\n return nodeContains(allowFrom, element);\n }\n\n return false;\n }\n\n function checkAxis (axis, interactable) {\n if (!interactable) { return false; }\n\n var thisAxis = interactable.options.drag.axis;\n\n return (axis === 'xy' || thisAxis === 'xy' || thisAxis === axis);\n }\n\n function checkSnap (interactable, action) {\n var options = interactable.options;\n\n if (/^resize/.test(action)) {\n action = 'resize';\n }\n\n return options[action].snap && options[action].snap.enabled;\n }\n\n function checkRestrict (interactable, action) {\n var options = interactable.options;\n\n if (/^resize/.test(action)) {\n action = 'resize';\n }\n\n return options[action].restrict && options[action].restrict.enabled;\n }\n\n function checkAutoScroll (interactable, action) {\n var options = interactable.options;\n\n if (/^resize/.test(action)) {\n action = 'resize';\n }\n\n return options[action].autoScroll && options[action].autoScroll.enabled;\n }\n\n function withinInteractionLimit (interactable, element, action) {\n var options = interactable.options,\n maxActions = options[action.name].max,\n maxPerElement = options[action.name].maxPerElement,\n activeInteractions = 0,\n targetCount = 0,\n targetElementCount = 0;\n\n for (var i = 0, len = interactions.length; i < len; i++) {\n var interaction = interactions[i],\n otherAction = interaction.prepared.name,\n active = interaction.interacting();\n\n if (!active) { continue; }\n\n activeInteractions++;\n\n if (activeInteractions >= maxInteractions) {\n return false;\n }\n\n if (interaction.target !== interactable) { continue; }\n\n targetCount += (otherAction === action.name)|0;\n\n if (targetCount >= maxActions) {\n return false;\n }\n\n if (interaction.element === element) {\n targetElementCount++;\n\n if (otherAction !== action.name || targetElementCount >= maxPerElement) {\n return false;\n }\n }\n }\n\n return maxInteractions > 0;\n }\n\n // Test for the element that's \"above\" all other qualifiers\n function indexOfDeepestElement (elements) {\n var dropzone,\n deepestZone = elements[0],\n index = deepestZone? 0: -1,\n parent,\n deepestZoneParents = [],\n dropzoneParents = [],\n child,\n i,\n n;\n\n for (i = 1; i < elements.length; i++) {\n dropzone = elements[i];\n\n // an element might belong to multiple selector dropzones\n if (!dropzone || dropzone === deepestZone) {\n continue;\n }\n\n if (!deepestZone) {\n deepestZone = dropzone;\n index = i;\n continue;\n }\n\n // check if the deepest or current are document.documentElement or document.rootElement\n // - if the current dropzone is, do nothing and continue\n if (dropzone.parentNode === dropzone.ownerDocument) {\n continue;\n }\n // - if deepest is, update with the current dropzone and continue to next\n else if (deepestZone.parentNode === dropzone.ownerDocument) {\n deepestZone = dropzone;\n index = i;\n continue;\n }\n\n if (!deepestZoneParents.length) {\n parent = deepestZone;\n while (parent.parentNode && parent.parentNode !== parent.ownerDocument) {\n deepestZoneParents.unshift(parent);\n parent = parent.parentNode;\n }\n }\n\n // if this element is an svg element and the current deepest is\n // an HTMLElement\n if (deepestZone instanceof HTMLElement\n && dropzone instanceof SVGElement\n && !(dropzone instanceof SVGSVGElement)) {\n\n if (dropzone === deepestZone.parentNode) {\n continue;\n }\n\n parent = dropzone.ownerSVGElement;\n }\n else {\n parent = dropzone;\n }\n\n dropzoneParents = [];\n\n while (parent.parentNode !== parent.ownerDocument) {\n dropzoneParents.unshift(parent);\n parent = parent.parentNode;\n }\n\n n = 0;\n\n // get (position of last common ancestor) + 1\n while (dropzoneParents[n] && dropzoneParents[n] === deepestZoneParents[n]) {\n n++;\n }\n\n var parents = [\n dropzoneParents[n - 1],\n dropzoneParents[n],\n deepestZoneParents[n]\n ];\n\n child = parents[0].lastChild;\n\n while (child) {\n if (child === parents[1]) {\n deepestZone = dropzone;\n index = i;\n deepestZoneParents = [];\n\n break;\n }\n else if (child === parents[2]) {\n break;\n }\n\n child = child.previousSibling;\n }\n }\n\n return index;\n }\n\n function Interaction () {\n this.target = null; // current interactable being interacted with\n this.element = null; // the target element of the interactable\n this.dropTarget = null; // the dropzone a drag target might be dropped into\n this.dropElement = null; // the element at the time of checking\n this.prevDropTarget = null; // the dropzone that was recently dragged away from\n this.prevDropElement = null; // the element at the time of checking\n\n this.prepared = { // action that's ready to be fired on next move event\n name : null,\n axis : null,\n edges: null\n };\n\n this.matches = []; // all selectors that are matched by target element\n this.matchElements = []; // corresponding elements\n\n this.inertiaStatus = {\n active : false,\n smoothEnd : false,\n ending : false,\n\n startEvent: null,\n upCoords: {},\n\n xe: 0, ye: 0,\n sx: 0, sy: 0,\n\n t0: 0,\n vx0: 0, vys: 0,\n duration: 0,\n\n resumeDx: 0,\n resumeDy: 0,\n\n lambda_v0: 0,\n one_ve_v0: 0,\n i : null\n };\n\n if (isFunction(Function.prototype.bind)) {\n this.boundInertiaFrame = this.inertiaFrame.bind(this);\n this.boundSmoothEndFrame = this.smoothEndFrame.bind(this);\n }\n else {\n var that = this;\n\n this.boundInertiaFrame = function () { return that.inertiaFrame(); };\n this.boundSmoothEndFrame = function () { return that.smoothEndFrame(); };\n }\n\n this.activeDrops = {\n dropzones: [], // the dropzones that are mentioned below\n elements : [], // elements of dropzones that accept the target draggable\n rects : [] // the rects of the elements mentioned above\n };\n\n // keep track of added pointers\n this.pointers = [];\n this.pointerIds = [];\n this.downTargets = [];\n this.downTimes = [];\n this.holdTimers = [];\n\n // Previous native pointer move event coordinates\n this.prevCoords = {\n page : { x: 0, y: 0 },\n client : { x: 0, y: 0 },\n timeStamp: 0\n };\n // current native pointer move event coordinates\n this.curCoords = {\n page : { x: 0, y: 0 },\n client : { x: 0, y: 0 },\n timeStamp: 0\n };\n\n // Starting InteractEvent pointer coordinates\n this.startCoords = {\n page : { x: 0, y: 0 },\n client : { x: 0, y: 0 },\n timeStamp: 0\n };\n\n // Change in coordinates and time of the pointer\n this.pointerDelta = {\n page : { x: 0, y: 0, vx: 0, vy: 0, speed: 0 },\n client : { x: 0, y: 0, vx: 0, vy: 0, speed: 0 },\n timeStamp: 0\n };\n\n this.downEvent = null; // pointerdown/mousedown/touchstart event\n this.downPointer = {};\n\n this._eventTarget = null;\n this._curEventTarget = null;\n\n this.prevEvent = null; // previous action event\n this.tapTime = 0; // time of the most recent tap event\n this.prevTap = null;\n\n this.startOffset = { left: 0, right: 0, top: 0, bottom: 0 };\n this.restrictOffset = { left: 0, right: 0, top: 0, bottom: 0 };\n this.snapOffsets = [];\n\n this.gesture = {\n start: { x: 0, y: 0 },\n\n startDistance: 0, // distance between two touches of touchStart\n prevDistance : 0,\n distance : 0,\n\n scale: 1, // gesture.distance / gesture.startDistance\n\n startAngle: 0, // angle of line joining two touches\n prevAngle : 0 // angle of the previous gesture event\n };\n\n this.snapStatus = {\n x : 0, y : 0,\n dx : 0, dy : 0,\n realX : 0, realY : 0,\n snappedX: 0, snappedY: 0,\n targets : [],\n locked : false,\n changed : false\n };\n\n this.restrictStatus = {\n dx : 0, dy : 0,\n restrictedX: 0, restrictedY: 0,\n snap : null,\n restricted : false,\n changed : false\n };\n\n this.restrictStatus.snap = this.snapStatus;\n\n this.pointerIsDown = false;\n this.pointerWasMoved = false;\n this.gesturing = false;\n this.dragging = false;\n this.resizing = false;\n this.resizeAxes = 'xy';\n\n this.mouse = false;\n\n interactions.push(this);\n }\n\n Interaction.prototype = {\n getPageXY : function (pointer, xy) { return getPageXY(pointer, xy, this); },\n getClientXY: function (pointer, xy) { return getClientXY(pointer, xy, this); },\n setEventXY : function (target, ptr) { return setEventXY(target, ptr, this); },\n\n pointerOver: function (pointer, event, eventTarget) {\n if (this.prepared.name || !this.mouse) { return; }\n\n var curMatches = [],\n curMatchElements = [],\n prevTargetElement = this.element;\n\n this.addPointer(pointer);\n\n if (this.target\n && (testIgnore(this.target, this.element, eventTarget)\n || !testAllow(this.target, this.element, eventTarget))) {\n // if the eventTarget should be ignored or shouldn't be allowed\n // clear the previous target\n this.target = null;\n this.element = null;\n this.matches = [];\n this.matchElements = [];\n }\n\n var elementInteractable = interactables.get(eventTarget),\n elementAction = (elementInteractable\n && !testIgnore(elementInteractable, eventTarget, eventTarget)\n && testAllow(elementInteractable, eventTarget, eventTarget)\n && validateAction(\n elementInteractable.getAction(pointer, event, this, eventTarget),\n elementInteractable));\n\n if (elementAction && !withinInteractionLimit(elementInteractable, eventTarget, elementAction)) {\n elementAction = null;\n }\n\n function pushCurMatches (interactable, selector) {\n if (interactable\n && inContext(interactable, eventTarget)\n && !testIgnore(interactable, eventTarget, eventTarget)\n && testAllow(interactable, eventTarget, eventTarget)\n && matchesSelector(eventTarget, selector)) {\n\n curMatches.push(interactable);\n curMatchElements.push(eventTarget);\n }\n }\n\n if (elementAction) {\n this.target = elementInteractable;\n this.element = eventTarget;\n this.matches = [];\n this.matchElements = [];\n }\n else {\n interactables.forEachSelector(pushCurMatches);\n\n if (this.validateSelector(pointer, event, curMatches, curMatchElements)) {\n this.matches = curMatches;\n this.matchElements = curMatchElements;\n\n this.pointerHover(pointer, event, this.matches, this.matchElements);\n events.add(eventTarget,\n supportsPointerEvent? pEventTypes.move : 'mousemove',\n listeners.pointerHover);\n }\n else if (this.target) {\n if (nodeContains(prevTargetElement, eventTarget)) {\n this.pointerHover(pointer, event, this.matches, this.matchElements);\n events.add(this.element,\n supportsPointerEvent? pEventTypes.move : 'mousemove',\n listeners.pointerHover);\n }\n else {\n this.target = null;\n this.element = null;\n this.matches = [];\n this.matchElements = [];\n }\n }\n }\n },\n\n // Check what action would be performed on pointerMove target if a mouse\n // button were pressed and change the cursor accordingly\n pointerHover: function (pointer, event, eventTarget, curEventTarget, matches, matchElements) {\n var target = this.target;\n\n if (!this.prepared.name && this.mouse) {\n\n var action;\n\n // update pointer coords for defaultActionChecker to use\n this.setEventXY(this.curCoords, [pointer]);\n\n if (matches) {\n action = this.validateSelector(pointer, event, matches, matchElements);\n }\n else if (target) {\n action = validateAction(target.getAction(this.pointers[0], event, this, this.element), this.target);\n }\n\n if (target && target.options.styleCursor) {\n if (action) {\n target._doc.documentElement.style.cursor = getActionCursor(action);\n }\n else {\n target._doc.documentElement.style.cursor = '';\n }\n }\n }\n else if (this.prepared.name) {\n this.checkAndPreventDefault(event, target, this.element);\n }\n },\n\n pointerOut: function (pointer, event, eventTarget) {\n if (this.prepared.name) { return; }\n\n // Remove temporary event listeners for selector Interactables\n if (!interactables.get(eventTarget)) {\n events.remove(eventTarget,\n supportsPointerEvent? pEventTypes.move : 'mousemove',\n listeners.pointerHover);\n }\n\n if (this.target && this.target.options.styleCursor && !this.interacting()) {\n this.target._doc.documentElement.style.cursor = '';\n }\n },\n\n selectorDown: function (pointer, event, eventTarget, curEventTarget) {\n var that = this,\n // copy event to be used in timeout for IE8\n eventCopy = events.useAttachEvent? extend({}, event) : event,\n element = eventTarget,\n pointerIndex = this.addPointer(pointer),\n action;\n\n this.holdTimers[pointerIndex] = setTimeout(function () {\n that.pointerHold(events.useAttachEvent? eventCopy : pointer, eventCopy, eventTarget, curEventTarget);\n }, defaultOptions._holdDuration);\n\n this.pointerIsDown = true;\n\n // Check if the down event hits the current inertia target\n if (this.inertiaStatus.active && this.target.selector) {\n // climb up the DOM tree from the event target\n while (isElement(element)) {\n\n // if this element is the current inertia target element\n if (element === this.element\n // and the prospective action is the same as the ongoing one\n && validateAction(this.target.getAction(pointer, event, this, this.element), this.target).name === this.prepared.name) {\n\n // stop inertia so that the next move will be a normal one\n cancelFrame(this.inertiaStatus.i);\n this.inertiaStatus.active = false;\n\n this.collectEventTargets(pointer, event, eventTarget, 'down');\n return;\n }\n element = parentElement(element);\n }\n }\n\n // do nothing if interacting\n if (this.interacting()) {\n this.collectEventTargets(pointer, event, eventTarget, 'down');\n return;\n }\n\n function pushMatches (interactable, selector, context) {\n var elements = ie8MatchesSelector\n ? context.querySelectorAll(selector)\n : undefined;\n\n if (inContext(interactable, element)\n && !testIgnore(interactable, element, eventTarget)\n && testAllow(interactable, element, eventTarget)\n && matchesSelector(element, selector, elements)) {\n\n that.matches.push(interactable);\n that.matchElements.push(element);\n }\n }\n\n // update pointer coords for defaultActionChecker to use\n this.setEventXY(this.curCoords, [pointer]);\n this.downEvent = event;\n\n while (isElement(element) && !action) {\n this.matches = [];\n this.matchElements = [];\n\n interactables.forEachSelector(pushMatches);\n\n action = this.validateSelector(pointer, event, this.matches, this.matchElements);\n element = parentElement(element);\n }\n\n if (action) {\n this.prepared.name = action.name;\n this.prepared.axis = action.axis;\n this.prepared.edges = action.edges;\n\n this.collectEventTargets(pointer, event, eventTarget, 'down');\n\n return this.pointerDown(pointer, event, eventTarget, curEventTarget, action);\n }\n else {\n // do these now since pointerDown isn't being called from here\n this.downTimes[pointerIndex] = new Date().getTime();\n this.downTargets[pointerIndex] = eventTarget;\n pointerExtend(this.downPointer, pointer);\n\n copyCoords(this.prevCoords, this.curCoords);\n this.pointerWasMoved = false;\n }\n\n this.collectEventTargets(pointer, event, eventTarget, 'down');\n },\n\n // Determine action to be performed on next pointerMove and add appropriate\n // style and event Listeners\n pointerDown: function (pointer, event, eventTarget, curEventTarget, forceAction) {\n if (!forceAction && !this.inertiaStatus.active && this.pointerWasMoved && this.prepared.name) {\n this.checkAndPreventDefault(event, this.target, this.element);\n\n return;\n }\n\n this.pointerIsDown = true;\n this.downEvent = event;\n\n var pointerIndex = this.addPointer(pointer),\n action;\n\n // If it is the second touch of a multi-touch gesture, keep the\n // target the same and get a new action if a target was set by the\n // first touch\n if (this.pointerIds.length > 1 && this.target._element === this.element) {\n var newAction = validateAction(forceAction || this.target.getAction(pointer, event, this, this.element), this.target);\n\n if (withinInteractionLimit(this.target, this.element, newAction)) {\n action = newAction;\n }\n\n this.prepared.name = null;\n }\n // Otherwise, set the target if there is no action prepared\n else if (!this.prepared.name) {\n var interactable = interactables.get(curEventTarget);\n\n if (interactable\n && !testIgnore(interactable, curEventTarget, eventTarget)\n && testAllow(interactable, curEventTarget, eventTarget)\n && (action = validateAction(forceAction || interactable.getAction(pointer, event, this, curEventTarget), interactable, eventTarget))\n && withinInteractionLimit(interactable, curEventTarget, action)) {\n this.target = interactable;\n this.element = curEventTarget;\n }\n }\n\n var target = this.target,\n options = target && target.options;\n\n if (target && (forceAction || !this.prepared.name)) {\n action = action || validateAction(forceAction || target.getAction(pointer, event, this, curEventTarget), target, this.element);\n\n this.setEventXY(this.startCoords, this.pointers);\n\n if (!action) { return; }\n\n if (options.styleCursor) {\n target._doc.documentElement.style.cursor = getActionCursor(action);\n }\n\n this.resizeAxes = action.name === 'resize'? action.axis : null;\n\n if (action === 'gesture' && this.pointerIds.length < 2) {\n action = null;\n }\n\n this.prepared.name = action.name;\n this.prepared.axis = action.axis;\n this.prepared.edges = action.edges;\n\n this.snapStatus.snappedX = this.snapStatus.snappedY =\n this.restrictStatus.restrictedX = this.restrictStatus.restrictedY = NaN;\n\n this.downTimes[pointerIndex] = new Date().getTime();\n this.downTargets[pointerIndex] = eventTarget;\n pointerExtend(this.downPointer, pointer);\n\n copyCoords(this.prevCoords, this.startCoords);\n this.pointerWasMoved = false;\n\n this.checkAndPreventDefault(event, target, this.element);\n }\n // if inertia is active try to resume action\n else if (this.inertiaStatus.active\n && curEventTarget === this.element\n && validateAction(target.getAction(pointer, event, this, this.element), target).name === this.prepared.name) {\n\n cancelFrame(this.inertiaStatus.i);\n this.inertiaStatus.active = false;\n\n this.checkAndPreventDefault(event, target, this.element);\n }\n },\n\n setModifications: function (coords, preEnd) {\n var target = this.target,\n shouldMove = true,\n shouldSnap = checkSnap(target, this.prepared.name) && (!target.options[this.prepared.name].snap.endOnly || preEnd),\n shouldRestrict = checkRestrict(target, this.prepared.name) && (!target.options[this.prepared.name].restrict.endOnly || preEnd);\n\n if (shouldSnap ) { this.setSnapping (coords); } else { this.snapStatus .locked = false; }\n if (shouldRestrict) { this.setRestriction(coords); } else { this.restrictStatus.restricted = false; }\n\n if (shouldSnap && this.snapStatus.locked && !this.snapStatus.changed) {\n shouldMove = shouldRestrict && this.restrictStatus.restricted && this.restrictStatus.changed;\n }\n else if (shouldRestrict && this.restrictStatus.restricted && !this.restrictStatus.changed) {\n shouldMove = false;\n }\n\n return shouldMove;\n },\n\n setStartOffsets: function (action, interactable, element) {\n var rect = interactable.getRect(element),\n origin = getOriginXY(interactable, element),\n snap = interactable.options[this.prepared.name].snap,\n restrict = interactable.options[this.prepared.name].restrict,\n width, height;\n\n if (rect) {\n this.startOffset.left = this.startCoords.page.x - rect.left;\n this.startOffset.top = this.startCoords.page.y - rect.top;\n\n this.startOffset.right = rect.right - this.startCoords.page.x;\n this.startOffset.bottom = rect.bottom - this.startCoords.page.y;\n\n if ('width' in rect) { width = rect.width; }\n else { width = rect.right - rect.left; }\n if ('height' in rect) { height = rect.height; }\n else { height = rect.bottom - rect.top; }\n }\n else {\n this.startOffset.left = this.startOffset.top = this.startOffset.right = this.startOffset.bottom = 0;\n }\n\n this.snapOffsets.splice(0);\n\n var snapOffset = snap && snap.offset === 'startCoords'\n ? {\n x: this.startCoords.page.x - origin.x,\n y: this.startCoords.page.y - origin.y\n }\n : snap && snap.offset || { x: 0, y: 0 };\n\n if (rect && snap && snap.relativePoints && snap.relativePoints.length) {\n for (var i = 0; i < snap.relativePoints.length; i++) {\n this.snapOffsets.push({\n x: this.startOffset.left - (width * snap.relativePoints[i].x) + snapOffset.x,\n y: this.startOffset.top - (height * snap.relativePoints[i].y) + snapOffset.y\n });\n }\n }\n else {\n this.snapOffsets.push(snapOffset);\n }\n\n if (rect && restrict.elementRect) {\n this.restrictOffset.left = this.startOffset.left - (width * restrict.elementRect.left);\n this.restrictOffset.top = this.startOffset.top - (height * restrict.elementRect.top);\n\n this.restrictOffset.right = this.startOffset.right - (width * (1 - restrict.elementRect.right));\n this.restrictOffset.bottom = this.startOffset.bottom - (height * (1 - restrict.elementRect.bottom));\n }\n else {\n this.restrictOffset.left = this.restrictOffset.top = this.restrictOffset.right = this.restrictOffset.bottom = 0;\n }\n },\n\n /*\\\n * Interaction.start\n [ method ]\n *\n * Start an action with the given Interactable and Element as tartgets. The\n * action must be enabled for the target Interactable and an appropriate number\n * of pointers must be held down – 1 for drag/resize, 2 for gesture.\n *\n * Use it with `interactable.able({ manualStart: false })` to always\n * [start actions manually](https://github.com/taye/interact.js/issues/114)\n *\n - action (object) The action to be performed - drag, resize, etc.\n - interactable (Interactable) The Interactable to target\n - element (Element) The DOM Element to target\n = (object) interact\n **\n | interact(target)\n | .draggable({\n | // disable the default drag start by down->move\n | manualStart: true\n | })\n | // start dragging after the user holds the pointer down\n | .on('hold', function (event) {\n | var interaction = event.interaction;\n |\n | if (!interaction.interacting()) {\n | interaction.start({ name: 'drag' },\n | event.interactable,\n | event.currentTarget);\n | }\n | });\n \\*/\n start: function (action, interactable, element) {\n if (this.interacting()\n || !this.pointerIsDown\n || this.pointerIds.length < (action.name === 'gesture'? 2 : 1)) {\n return;\n }\n\n // if this interaction had been removed after stopping\n // add it back\n if (indexOf(interactions, this) === -1) {\n interactions.push(this);\n }\n\n // set the startCoords if there was no prepared action\n if (!this.prepared.name) {\n this.setEventXY(this.startCoords, this.pointers);\n }\n\n this.prepared.name = action.name;\n this.prepared.axis = action.axis;\n this.prepared.edges = action.edges;\n this.target = interactable;\n this.element = element;\n\n this.setStartOffsets(action.name, interactable, element);\n this.setModifications(this.startCoords.page);\n\n this.prevEvent = this[this.prepared.name + 'Start'](this.downEvent);\n },\n\n pointerMove: function (pointer, event, eventTarget, curEventTarget, preEnd) {\n if (this.inertiaStatus.active) {\n var pageUp = this.inertiaStatus.upCoords.page;\n var clientUp = this.inertiaStatus.upCoords.client;\n\n var inertiaPosition = {\n pageX : pageUp.x + this.inertiaStatus.sx,\n pageY : pageUp.y + this.inertiaStatus.sy,\n clientX: clientUp.x + this.inertiaStatus.sx,\n clientY: clientUp.y + this.inertiaStatus.sy\n };\n\n this.setEventXY(this.curCoords, [inertiaPosition]);\n }\n else {\n this.recordPointer(pointer);\n this.setEventXY(this.curCoords, this.pointers);\n }\n\n var duplicateMove = (this.curCoords.page.x === this.prevCoords.page.x\n && this.curCoords.page.y === this.prevCoords.page.y\n && this.curCoords.client.x === this.prevCoords.client.x\n && this.curCoords.client.y === this.prevCoords.client.y);\n\n var dx, dy,\n pointerIndex = this.mouse? 0 : indexOf(this.pointerIds, getPointerId(pointer));\n\n // register movement greater than pointerMoveTolerance\n if (this.pointerIsDown && !this.pointerWasMoved) {\n dx = this.curCoords.client.x - this.startCoords.client.x;\n dy = this.curCoords.client.y - this.startCoords.client.y;\n\n this.pointerWasMoved = hypot(dx, dy) > pointerMoveTolerance;\n }\n\n if (!duplicateMove && (!this.pointerIsDown || this.pointerWasMoved)) {\n if (this.pointerIsDown) {\n clearTimeout(this.holdTimers[pointerIndex]);\n }\n\n this.collectEventTargets(pointer, event, eventTarget, 'move');\n }\n\n if (!this.pointerIsDown) { return; }\n\n if (duplicateMove && this.pointerWasMoved && !preEnd) {\n this.checkAndPreventDefault(event, this.target, this.element);\n return;\n }\n\n // set pointer coordinate, time changes and speeds\n setEventDeltas(this.pointerDelta, this.prevCoords, this.curCoords);\n\n if (!this.prepared.name) { return; }\n\n if (this.pointerWasMoved\n // ignore movement while inertia is active\n && (!this.inertiaStatus.active || (pointer instanceof InteractEvent && /inertiastart/.test(pointer.type)))) {\n\n // if just starting an action, calculate the pointer speed now\n if (!this.interacting()) {\n setEventDeltas(this.pointerDelta, this.prevCoords, this.curCoords);\n\n // check if a drag is in the correct axis\n if (this.prepared.name === 'drag') {\n var absX = Math.abs(dx),\n absY = Math.abs(dy),\n targetAxis = this.target.options.drag.axis,\n axis = (absX > absY ? 'x' : absX < absY ? 'y' : 'xy');\n\n // if the movement isn't in the axis of the interactable\n if (axis !== 'xy' && targetAxis !== 'xy' && targetAxis !== axis) {\n // cancel the prepared action\n this.prepared.name = null;\n\n // then try to get a drag from another ineractable\n\n var element = eventTarget;\n\n // check element interactables\n while (isElement(element)) {\n var elementInteractable = interactables.get(element);\n\n if (elementInteractable\n && elementInteractable !== this.target\n && !elementInteractable.options.drag.manualStart\n && elementInteractable.getAction(this.downPointer, this.downEvent, this, element).name === 'drag'\n && checkAxis(axis, elementInteractable)) {\n\n this.prepared.name = 'drag';\n this.target = elementInteractable;\n this.element = element;\n break;\n }\n\n element = parentElement(element);\n }\n\n // if there's no drag from element interactables,\n // check the selector interactables\n if (!this.prepared.name) {\n var thisInteraction = this;\n\n var getDraggable = function (interactable, selector, context) {\n var elements = ie8MatchesSelector\n ? context.querySelectorAll(selector)\n : undefined;\n\n if (interactable === thisInteraction.target) { return; }\n\n if (inContext(interactable, eventTarget)\n && !interactable.options.drag.manualStart\n && !testIgnore(interactable, element, eventTarget)\n && testAllow(interactable, element, eventTarget)\n && matchesSelector(element, selector, elements)\n && interactable.getAction(thisInteraction.downPointer, thisInteraction.downEvent, thisInteraction, element).name === 'drag'\n && checkAxis(axis, interactable)\n && withinInteractionLimit(interactable, element, 'drag')) {\n\n return interactable;\n }\n };\n\n element = eventTarget;\n\n while (isElement(element)) {\n var selectorInteractable = interactables.forEachSelector(getDraggable);\n\n if (selectorInteractable) {\n this.prepared.name = 'drag';\n this.target = selectorInteractable;\n this.element = element;\n break;\n }\n\n element = parentElement(element);\n }\n }\n }\n }\n }\n\n var starting = !!this.prepared.name && !this.interacting();\n\n if (starting\n && (this.target.options[this.prepared.name].manualStart\n || !withinInteractionLimit(this.target, this.element, this.prepared))) {\n this.stop(event);\n return;\n }\n\n if (this.prepared.name && this.target) {\n if (starting) {\n this.start(this.prepared, this.target, this.element);\n }\n\n var shouldMove = this.setModifications(this.curCoords.page, preEnd);\n\n // move if snapping or restriction doesn't prevent it\n if (shouldMove || starting) {\n this.prevEvent = this[this.prepared.name + 'Move'](event);\n }\n\n this.checkAndPreventDefault(event, this.target, this.element);\n }\n }\n\n copyCoords(this.prevCoords, this.curCoords);\n\n if (this.dragging || this.resizing) {\n this.autoScrollMove(pointer);\n }\n },\n\n dragStart: function (event) {\n var dragEvent = new InteractEvent(this, event, 'drag', 'start', this.element);\n\n this.dragging = true;\n this.target.fire(dragEvent);\n\n // reset active dropzones\n this.activeDrops.dropzones = [];\n this.activeDrops.elements = [];\n this.activeDrops.rects = [];\n\n if (!this.dynamicDrop) {\n this.setActiveDrops(this.element);\n }\n\n var dropEvents = this.getDropEvents(event, dragEvent);\n\n if (dropEvents.activate) {\n this.fireActiveDrops(dropEvents.activate);\n }\n\n return dragEvent;\n },\n\n dragMove: function (event) {\n var target = this.target,\n dragEvent = new InteractEvent(this, event, 'drag', 'move', this.element),\n draggableElement = this.element,\n drop = this.getDrop(dragEvent, event, draggableElement);\n\n this.dropTarget = drop.dropzone;\n this.dropElement = drop.element;\n\n var dropEvents = this.getDropEvents(event, dragEvent);\n\n target.fire(dragEvent);\n\n if (dropEvents.leave) { this.prevDropTarget.fire(dropEvents.leave); }\n if (dropEvents.enter) { this.dropTarget.fire(dropEvents.enter); }\n if (dropEvents.move ) { this.dropTarget.fire(dropEvents.move ); }\n\n this.prevDropTarget = this.dropTarget;\n this.prevDropElement = this.dropElement;\n\n return dragEvent;\n },\n\n resizeStart: function (event) {\n var resizeEvent = new InteractEvent(this, event, 'resize', 'start', this.element);\n\n if (this.prepared.edges) {\n var startRect = this.target.getRect(this.element);\n\n /*\n * When using the `resizable.square` or `resizable.preserveAspectRatio` options, resizing from one edge\n * will affect another. E.g. with `resizable.square`, resizing to make the right edge larger will make\n * the bottom edge larger by the same amount. We call these 'linked' edges. Any linked edges will depend\n * on the active edges and the edge being interacted with.\n */\n if (this.target.options.resize.square || this.target.options.resize.preserveAspectRatio) {\n var linkedEdges = extend({}, this.prepared.edges);\n\n linkedEdges.top = linkedEdges.top || (linkedEdges.left && !linkedEdges.bottom);\n linkedEdges.left = linkedEdges.left || (linkedEdges.top && !linkedEdges.right );\n linkedEdges.bottom = linkedEdges.bottom || (linkedEdges.right && !linkedEdges.top );\n linkedEdges.right = linkedEdges.right || (linkedEdges.bottom && !linkedEdges.left );\n\n this.prepared._linkedEdges = linkedEdges;\n }\n else {\n this.prepared._linkedEdges = null;\n }\n\n // if using `resizable.preserveAspectRatio` option, record aspect ratio at the start of the resize\n if (this.target.options.resize.preserveAspectRatio) {\n this.resizeStartAspectRatio = startRect.width / startRect.height;\n }\n\n this.resizeRects = {\n start : startRect,\n current : extend({}, startRect),\n restricted: extend({}, startRect),\n previous : extend({}, startRect),\n delta : {\n left: 0, right : 0, width : 0,\n top : 0, bottom: 0, height: 0\n }\n };\n\n resizeEvent.rect = this.resizeRects.restricted;\n resizeEvent.deltaRect = this.resizeRects.delta;\n }\n\n this.target.fire(resizeEvent);\n\n this.resizing = true;\n\n return resizeEvent;\n },\n\n resizeMove: function (event) {\n var resizeEvent = new InteractEvent(this, event, 'resize', 'move', this.element);\n\n var edges = this.prepared.edges,\n invert = this.target.options.resize.invert,\n invertible = invert === 'reposition' || invert === 'negate';\n\n if (edges) {\n var dx = resizeEvent.dx,\n dy = resizeEvent.dy,\n\n start = this.resizeRects.start,\n current = this.resizeRects.current,\n restricted = this.resizeRects.restricted,\n delta = this.resizeRects.delta,\n previous = extend(this.resizeRects.previous, restricted),\n\n originalEdges = edges;\n\n // `resize.preserveAspectRatio` takes precedence over `resize.square`\n if (this.target.options.resize.preserveAspectRatio) {\n var resizeStartAspectRatio = this.resizeStartAspectRatio;\n\n edges = this.prepared._linkedEdges;\n\n if ((originalEdges.left && originalEdges.bottom)\n || (originalEdges.right && originalEdges.top)) {\n dy = -dx / resizeStartAspectRatio;\n }\n else if (originalEdges.left || originalEdges.right) { dy = dx / resizeStartAspectRatio; }\n else if (originalEdges.top || originalEdges.bottom) { dx = dy * resizeStartAspectRatio; }\n }\n else if (this.target.options.resize.square) {\n edges = this.prepared._linkedEdges;\n\n if ((originalEdges.left && originalEdges.bottom)\n || (originalEdges.right && originalEdges.top)) {\n dy = -dx;\n }\n else if (originalEdges.left || originalEdges.right) { dy = dx; }\n else if (originalEdges.top || originalEdges.bottom) { dx = dy; }\n }\n\n // update the 'current' rect without modifications\n if (edges.top ) { current.top += dy; }\n if (edges.bottom) { current.bottom += dy; }\n if (edges.left ) { current.left += dx; }\n if (edges.right ) { current.right += dx; }\n\n if (invertible) {\n // if invertible, copy the current rect\n extend(restricted, current);\n\n if (invert === 'reposition') {\n // swap edge values if necessary to keep width/height positive\n var swap;\n\n if (restricted.top > restricted.bottom) {\n swap = restricted.top;\n\n restricted.top = restricted.bottom;\n restricted.bottom = swap;\n }\n if (restricted.left > restricted.right) {\n swap = restricted.left;\n\n restricted.left = restricted.right;\n restricted.right = swap;\n }\n }\n }\n else {\n // if not invertible, restrict to minimum of 0x0 rect\n restricted.top = Math.min(current.top, start.bottom);\n restricted.bottom = Math.max(current.bottom, start.top);\n restricted.left = Math.min(current.left, start.right);\n restricted.right = Math.max(current.right, start.left);\n }\n\n restricted.width = restricted.right - restricted.left;\n restricted.height = restricted.bottom - restricted.top ;\n\n for (var edge in restricted) {\n delta[edge] = restricted[edge] - previous[edge];\n }\n\n resizeEvent.edges = this.prepared.edges;\n resizeEvent.rect = restricted;\n resizeEvent.deltaRect = delta;\n }\n\n this.target.fire(resizeEvent);\n\n return resizeEvent;\n },\n\n gestureStart: function (event) {\n var gestureEvent = new InteractEvent(this, event, 'gesture', 'start', this.element);\n\n gestureEvent.ds = 0;\n\n this.gesture.startDistance = this.gesture.prevDistance = gestureEvent.distance;\n this.gesture.startAngle = this.gesture.prevAngle = gestureEvent.angle;\n this.gesture.scale = 1;\n\n this.gesturing = true;\n\n this.target.fire(gestureEvent);\n\n return gestureEvent;\n },\n\n gestureMove: function (event) {\n if (!this.pointerIds.length) {\n return this.prevEvent;\n }\n\n var gestureEvent;\n\n gestureEvent = new InteractEvent(this, event, 'gesture', 'move', this.element);\n gestureEvent.ds = gestureEvent.scale - this.gesture.scale;\n\n this.target.fire(gestureEvent);\n\n this.gesture.prevAngle = gestureEvent.angle;\n this.gesture.prevDistance = gestureEvent.distance;\n\n if (gestureEvent.scale !== Infinity &&\n gestureEvent.scale !== null &&\n gestureEvent.scale !== undefined &&\n !isNaN(gestureEvent.scale)) {\n\n this.gesture.scale = gestureEvent.scale;\n }\n\n return gestureEvent;\n },\n\n pointerHold: function (pointer, event, eventTarget) {\n this.collectEventTargets(pointer, event, eventTarget, 'hold');\n },\n\n pointerUp: function (pointer, event, eventTarget, curEventTarget) {\n var pointerIndex = this.mouse? 0 : indexOf(this.pointerIds, getPointerId(pointer));\n\n clearTimeout(this.holdTimers[pointerIndex]);\n\n this.collectEventTargets(pointer, event, eventTarget, 'up' );\n this.collectEventTargets(pointer, event, eventTarget, 'tap');\n\n this.pointerEnd(pointer, event, eventTarget, curEventTarget);\n\n this.removePointer(pointer);\n },\n\n pointerCancel: function (pointer, event, eventTarget, curEventTarget) {\n var pointerIndex = this.mouse? 0 : indexOf(this.pointerIds, getPointerId(pointer));\n\n clearTimeout(this.holdTimers[pointerIndex]);\n\n this.collectEventTargets(pointer, event, eventTarget, 'cancel');\n this.pointerEnd(pointer, event, eventTarget, curEventTarget);\n\n this.removePointer(pointer);\n },\n\n // http://www.quirksmode.org/dom/events/click.html\n // >Events leading to dblclick\n //\n // IE8 doesn't fire down event before dblclick.\n // This workaround tries to fire a tap and doubletap after dblclick\n ie8Dblclick: function (pointer, event, eventTarget) {\n if (this.prevTap\n && event.clientX === this.prevTap.clientX\n && event.clientY === this.prevTap.clientY\n && eventTarget === this.prevTap.target) {\n\n this.downTargets[0] = eventTarget;\n this.downTimes[0] = new Date().getTime();\n this.collectEventTargets(pointer, event, eventTarget, 'tap');\n }\n },\n\n // End interact move events and stop auto-scroll unless inertia is enabled\n pointerEnd: function (pointer, event, eventTarget, curEventTarget) {\n var endEvent,\n target = this.target,\n options = target && target.options,\n inertiaOptions = options && this.prepared.name && options[this.prepared.name].inertia,\n inertiaStatus = this.inertiaStatus;\n\n if (this.interacting()) {\n\n if (inertiaStatus.active && !inertiaStatus.ending) { return; }\n\n var pointerSpeed,\n now = new Date().getTime(),\n inertiaPossible = false,\n inertia = false,\n smoothEnd = false,\n endSnap = checkSnap(target, this.prepared.name) && options[this.prepared.name].snap.endOnly,\n endRestrict = checkRestrict(target, this.prepared.name) && options[this.prepared.name].restrict.endOnly,\n dx = 0,\n dy = 0,\n startEvent;\n\n if (this.dragging) {\n if (options.drag.axis === 'x' ) { pointerSpeed = Math.abs(this.pointerDelta.client.vx); }\n else if (options.drag.axis === 'y' ) { pointerSpeed = Math.abs(this.pointerDelta.client.vy); }\n else /*options.drag.axis === 'xy'*/{ pointerSpeed = this.pointerDelta.client.speed; }\n }\n else {\n pointerSpeed = this.pointerDelta.client.speed;\n }\n\n // check if inertia should be started\n inertiaPossible = (inertiaOptions && inertiaOptions.enabled\n && this.prepared.name !== 'gesture'\n && event !== inertiaStatus.startEvent);\n\n inertia = (inertiaPossible\n && (now - this.curCoords.timeStamp) < 50\n && pointerSpeed > inertiaOptions.minSpeed\n && pointerSpeed > inertiaOptions.endSpeed);\n\n if (inertiaPossible && !inertia && (endSnap || endRestrict)) {\n\n var snapRestrict = {};\n\n snapRestrict.snap = snapRestrict.restrict = snapRestrict;\n\n if (endSnap) {\n this.setSnapping(this.curCoords.page, snapRestrict);\n if (snapRestrict.locked) {\n dx += snapRestrict.dx;\n dy += snapRestrict.dy;\n }\n }\n\n if (endRestrict) {\n this.setRestriction(this.curCoords.page, snapRestrict);\n if (snapRestrict.restricted) {\n dx += snapRestrict.dx;\n dy += snapRestrict.dy;\n }\n }\n\n if (dx || dy) {\n smoothEnd = true;\n }\n }\n\n if (inertia || smoothEnd) {\n copyCoords(inertiaStatus.upCoords, this.curCoords);\n\n this.pointers[0] = inertiaStatus.startEvent = startEvent =\n new InteractEvent(this, event, this.prepared.name, 'inertiastart', this.element);\n\n inertiaStatus.t0 = now;\n\n target.fire(inertiaStatus.startEvent);\n\n if (inertia) {\n inertiaStatus.vx0 = this.pointerDelta.client.vx;\n inertiaStatus.vy0 = this.pointerDelta.client.vy;\n inertiaStatus.v0 = pointerSpeed;\n\n this.calcInertia(inertiaStatus);\n\n var page = extend({}, this.curCoords.page),\n origin = getOriginXY(target, this.element),\n statusObject;\n\n page.x = page.x + inertiaStatus.xe - origin.x;\n page.y = page.y + inertiaStatus.ye - origin.y;\n\n statusObject = {\n useStatusXY: true,\n x: page.x,\n y: page.y,\n dx: 0,\n dy: 0,\n snap: null\n };\n\n statusObject.snap = statusObject;\n\n dx = dy = 0;\n\n if (endSnap) {\n var snap = this.setSnapping(this.curCoords.page, statusObject);\n\n if (snap.locked) {\n dx += snap.dx;\n dy += snap.dy;\n }\n }\n\n if (endRestrict) {\n var restrict = this.setRestriction(this.curCoords.page, statusObject);\n\n if (restrict.restricted) {\n dx += restrict.dx;\n dy += restrict.dy;\n }\n }\n\n inertiaStatus.modifiedXe += dx;\n inertiaStatus.modifiedYe += dy;\n\n inertiaStatus.i = reqFrame(this.boundInertiaFrame);\n }\n else {\n inertiaStatus.smoothEnd = true;\n inertiaStatus.xe = dx;\n inertiaStatus.ye = dy;\n\n inertiaStatus.sx = inertiaStatus.sy = 0;\n\n inertiaStatus.i = reqFrame(this.boundSmoothEndFrame);\n }\n\n inertiaStatus.active = true;\n return;\n }\n\n if (endSnap || endRestrict) {\n // fire a move event at the snapped coordinates\n this.pointerMove(pointer, event, eventTarget, curEventTarget, true);\n }\n }\n\n if (this.dragging) {\n endEvent = new InteractEvent(this, event, 'drag', 'end', this.element);\n\n var draggableElement = this.element,\n drop = this.getDrop(endEvent, event, draggableElement);\n\n this.dropTarget = drop.dropzone;\n this.dropElement = drop.element;\n\n var dropEvents = this.getDropEvents(event, endEvent);\n\n if (dropEvents.leave) { this.prevDropTarget.fire(dropEvents.leave); }\n if (dropEvents.enter) { this.dropTarget.fire(dropEvents.enter); }\n if (dropEvents.drop ) { this.dropTarget.fire(dropEvents.drop ); }\n if (dropEvents.deactivate) {\n this.fireActiveDrops(dropEvents.deactivate);\n }\n\n target.fire(endEvent);\n }\n else if (this.resizing) {\n endEvent = new InteractEvent(this, event, 'resize', 'end', this.element);\n target.fire(endEvent);\n }\n else if (this.gesturing) {\n endEvent = new InteractEvent(this, event, 'gesture', 'end', this.element);\n target.fire(endEvent);\n }\n\n this.stop(event);\n },\n\n collectDrops: function (element) {\n var drops = [],\n elements = [],\n i;\n\n element = element || this.element;\n\n // collect all dropzones and their elements which qualify for a drop\n for (i = 0; i < interactables.length; i++) {\n if (!interactables[i].options.drop.enabled) { continue; }\n\n var current = interactables[i],\n accept = current.options.drop.accept;\n\n // test the draggable element against the dropzone's accept setting\n if ((isElement(accept) && accept !== element)\n || (isString(accept)\n && !matchesSelector(element, accept))) {\n\n continue;\n }\n\n // query for new elements if necessary\n var dropElements = current.selector? current._context.querySelectorAll(current.selector) : [current._element];\n\n for (var j = 0, len = dropElements.length; j < len; j++) {\n var currentElement = dropElements[j];\n\n if (currentElement === element) {\n continue;\n }\n\n drops.push(current);\n elements.push(currentElement);\n }\n }\n\n return {\n dropzones: drops,\n elements: elements\n };\n },\n\n fireActiveDrops: function (event) {\n var i,\n current,\n currentElement,\n prevElement;\n\n // loop through all active dropzones and trigger event\n for (i = 0; i < this.activeDrops.dropzones.length; i++) {\n current = this.activeDrops.dropzones[i];\n currentElement = this.activeDrops.elements [i];\n\n // prevent trigger of duplicate events on same element\n if (currentElement !== prevElement) {\n // set current element as event target\n event.target = currentElement;\n current.fire(event);\n }\n prevElement = currentElement;\n }\n },\n\n // Collect a new set of possible drops and save them in activeDrops.\n // setActiveDrops should always be called when a drag has just started or a\n // drag event happens while dynamicDrop is true\n setActiveDrops: function (dragElement) {\n // get dropzones and their elements that could receive the draggable\n var possibleDrops = this.collectDrops(dragElement, true);\n\n this.activeDrops.dropzones = possibleDrops.dropzones;\n this.activeDrops.elements = possibleDrops.elements;\n this.activeDrops.rects = [];\n\n for (var i = 0; i < this.activeDrops.dropzones.length; i++) {\n this.activeDrops.rects[i] = this.activeDrops.dropzones[i].getRect(this.activeDrops.elements[i]);\n }\n },\n\n getDrop: function (dragEvent, event, dragElement) {\n var validDrops = [];\n\n if (dynamicDrop) {\n this.setActiveDrops(dragElement);\n }\n\n // collect all dropzones and their elements which qualify for a drop\n for (var j = 0; j < this.activeDrops.dropzones.length; j++) {\n var current = this.activeDrops.dropzones[j],\n currentElement = this.activeDrops.elements [j],\n rect = this.activeDrops.rects [j];\n\n validDrops.push(current.dropCheck(dragEvent, event, this.target, dragElement, currentElement, rect)\n ? currentElement\n : null);\n }\n\n // get the most appropriate dropzone based on DOM depth and order\n var dropIndex = indexOfDeepestElement(validDrops),\n dropzone = this.activeDrops.dropzones[dropIndex] || null,\n element = this.activeDrops.elements [dropIndex] || null;\n\n return {\n dropzone: dropzone,\n element: element\n };\n },\n\n getDropEvents: function (pointerEvent, dragEvent) {\n var dropEvents = {\n enter : null,\n leave : null,\n activate : null,\n deactivate: null,\n move : null,\n drop : null\n };\n\n if (this.dropElement !== this.prevDropElement) {\n // if there was a prevDropTarget, create a dragleave event\n if (this.prevDropTarget) {\n dropEvents.leave = {\n target : this.prevDropElement,\n dropzone : this.prevDropTarget,\n relatedTarget: dragEvent.target,\n draggable : dragEvent.interactable,\n dragEvent : dragEvent,\n interaction : this,\n timeStamp : dragEvent.timeStamp,\n type : 'dragleave'\n };\n\n dragEvent.dragLeave = this.prevDropElement;\n dragEvent.prevDropzone = this.prevDropTarget;\n }\n // if the dropTarget is not null, create a dragenter event\n if (this.dropTarget) {\n dropEvents.enter = {\n target : this.dropElement,\n dropzone : this.dropTarget,\n relatedTarget: dragEvent.target,\n draggable : dragEvent.interactable,\n dragEvent : dragEvent,\n interaction : this,\n timeStamp : dragEvent.timeStamp,\n type : 'dragenter'\n };\n\n dragEvent.dragEnter = this.dropElement;\n dragEvent.dropzone = this.dropTarget;\n }\n }\n\n if (dragEvent.type === 'dragend' && this.dropTarget) {\n dropEvents.drop = {\n target : this.dropElement,\n dropzone : this.dropTarget,\n relatedTarget: dragEvent.target,\n draggable : dragEvent.interactable,\n dragEvent : dragEvent,\n interaction : this,\n timeStamp : dragEvent.timeStamp,\n type : 'drop'\n };\n\n dragEvent.dropzone = this.dropTarget;\n }\n if (dragEvent.type === 'dragstart') {\n dropEvents.activate = {\n target : null,\n dropzone : null,\n relatedTarget: dragEvent.target,\n draggable : dragEvent.interactable,\n dragEvent : dragEvent,\n interaction : this,\n timeStamp : dragEvent.timeStamp,\n type : 'dropactivate'\n };\n }\n if (dragEvent.type === 'dragend') {\n dropEvents.deactivate = {\n target : null,\n dropzone : null,\n relatedTarget: dragEvent.target,\n draggable : dragEvent.interactable,\n dragEvent : dragEvent,\n interaction : this,\n timeStamp : dragEvent.timeStamp,\n type : 'dropdeactivate'\n };\n }\n if (dragEvent.type === 'dragmove' && this.dropTarget) {\n dropEvents.move = {\n target : this.dropElement,\n dropzone : this.dropTarget,\n relatedTarget: dragEvent.target,\n draggable : dragEvent.interactable,\n dragEvent : dragEvent,\n interaction : this,\n dragmove : dragEvent,\n timeStamp : dragEvent.timeStamp,\n type : 'dropmove'\n };\n dragEvent.dropzone = this.dropTarget;\n }\n\n return dropEvents;\n },\n\n currentAction: function () {\n return (this.dragging && 'drag') || (this.resizing && 'resize') || (this.gesturing && 'gesture') || null;\n },\n\n interacting: function () {\n return this.dragging || this.resizing || this.gesturing;\n },\n\n clearTargets: function () {\n this.target = this.element = null;\n\n this.dropTarget = this.dropElement = this.prevDropTarget = this.prevDropElement = null;\n },\n\n stop: function (event) {\n if (this.interacting()) {\n autoScroll.stop();\n this.matches = [];\n this.matchElements = [];\n\n var target = this.target;\n\n if (target.options.styleCursor) {\n target._doc.documentElement.style.cursor = '';\n }\n\n // prevent Default only if were previously interacting\n if (event && isFunction(event.preventDefault)) {\n this.checkAndPreventDefault(event, target, this.element);\n }\n\n if (this.dragging) {\n this.activeDrops.dropzones = this.activeDrops.elements = this.activeDrops.rects = null;\n }\n }\n\n this.clearTargets();\n\n this.pointerIsDown = this.snapStatus.locked = this.dragging = this.resizing = this.gesturing = false;\n this.prepared.name = this.prevEvent = null;\n this.inertiaStatus.resumeDx = this.inertiaStatus.resumeDy = 0;\n\n // remove pointers if their ID isn't in this.pointerIds\n for (var i = 0; i < this.pointers.length; i++) {\n if (indexOf(this.pointerIds, getPointerId(this.pointers[i])) === -1) {\n this.pointers.splice(i, 1);\n }\n }\n },\n\n inertiaFrame: function () {\n var inertiaStatus = this.inertiaStatus,\n options = this.target.options[this.prepared.name].inertia,\n lambda = options.resistance,\n t = new Date().getTime() / 1000 - inertiaStatus.t0;\n\n if (t < inertiaStatus.te) {\n\n var progress = 1 - (Math.exp(-lambda * t) - inertiaStatus.lambda_v0) / inertiaStatus.one_ve_v0;\n\n if (inertiaStatus.modifiedXe === inertiaStatus.xe && inertiaStatus.modifiedYe === inertiaStatus.ye) {\n inertiaStatus.sx = inertiaStatus.xe * progress;\n inertiaStatus.sy = inertiaStatus.ye * progress;\n }\n else {\n var quadPoint = getQuadraticCurvePoint(\n 0, 0,\n inertiaStatus.xe, inertiaStatus.ye,\n inertiaStatus.modifiedXe, inertiaStatus.modifiedYe,\n progress);\n\n inertiaStatus.sx = quadPoint.x;\n inertiaStatus.sy = quadPoint.y;\n }\n\n this.pointerMove(inertiaStatus.startEvent, inertiaStatus.startEvent);\n\n inertiaStatus.i = reqFrame(this.boundInertiaFrame);\n }\n else {\n inertiaStatus.ending = true;\n\n inertiaStatus.sx = inertiaStatus.modifiedXe;\n inertiaStatus.sy = inertiaStatus.modifiedYe;\n\n this.pointerMove(inertiaStatus.startEvent, inertiaStatus.startEvent);\n this.pointerEnd(inertiaStatus.startEvent, inertiaStatus.startEvent);\n\n inertiaStatus.active = inertiaStatus.ending = false;\n }\n },\n\n smoothEndFrame: function () {\n var inertiaStatus = this.inertiaStatus,\n t = new Date().getTime() - inertiaStatus.t0,\n duration = this.target.options[this.prepared.name].inertia.smoothEndDuration;\n\n if (t < duration) {\n inertiaStatus.sx = easeOutQuad(t, 0, inertiaStatus.xe, duration);\n inertiaStatus.sy = easeOutQuad(t, 0, inertiaStatus.ye, duration);\n\n this.pointerMove(inertiaStatus.startEvent, inertiaStatus.startEvent);\n\n inertiaStatus.i = reqFrame(this.boundSmoothEndFrame);\n }\n else {\n inertiaStatus.ending = true;\n\n inertiaStatus.sx = inertiaStatus.xe;\n inertiaStatus.sy = inertiaStatus.ye;\n\n this.pointerMove(inertiaStatus.startEvent, inertiaStatus.startEvent);\n this.pointerEnd(inertiaStatus.startEvent, inertiaStatus.startEvent);\n\n inertiaStatus.smoothEnd =\n inertiaStatus.active = inertiaStatus.ending = false;\n }\n },\n\n addPointer: function (pointer) {\n var id = getPointerId(pointer),\n index = this.mouse? 0 : indexOf(this.pointerIds, id);\n\n if (index === -1) {\n index = this.pointerIds.length;\n }\n\n this.pointerIds[index] = id;\n this.pointers[index] = pointer;\n\n return index;\n },\n\n removePointer: function (pointer) {\n var id = getPointerId(pointer),\n index = this.mouse? 0 : indexOf(this.pointerIds, id);\n\n if (index === -1) { return; }\n\n this.pointers .splice(index, 1);\n this.pointerIds .splice(index, 1);\n this.downTargets.splice(index, 1);\n this.downTimes .splice(index, 1);\n this.holdTimers .splice(index, 1);\n },\n\n recordPointer: function (pointer) {\n var index = this.mouse? 0: indexOf(this.pointerIds, getPointerId(pointer));\n\n if (index === -1) { return; }\n\n this.pointers[index] = pointer;\n },\n\n collectEventTargets: function (pointer, event, eventTarget, eventType) {\n var pointerIndex = this.mouse? 0 : indexOf(this.pointerIds, getPointerId(pointer));\n\n // do not fire a tap event if the pointer was moved before being lifted\n if (eventType === 'tap' && (this.pointerWasMoved\n // or if the pointerup target is different to the pointerdown target\n || !(this.downTargets[pointerIndex] && this.downTargets[pointerIndex] === eventTarget))) {\n return;\n }\n\n var targets = [],\n elements = [],\n element = eventTarget;\n\n function collectSelectors (interactable, selector, context) {\n var els = ie8MatchesSelector\n ? context.querySelectorAll(selector)\n : undefined;\n\n if (interactable._iEvents[eventType]\n && isElement(element)\n && inContext(interactable, element)\n && !testIgnore(interactable, element, eventTarget)\n && testAllow(interactable, element, eventTarget)\n && matchesSelector(element, selector, els)) {\n\n targets.push(interactable);\n elements.push(element);\n }\n }\n\n while (element) {\n if (interact.isSet(element) && interact(element)._iEvents[eventType]) {\n targets.push(interact(element));\n elements.push(element);\n }\n\n interactables.forEachSelector(collectSelectors);\n\n element = parentElement(element);\n }\n\n // create the tap event even if there are no listeners so that\n // doubletap can still be created and fired\n if (targets.length || eventType === 'tap') {\n this.firePointers(pointer, event, eventTarget, targets, elements, eventType);\n }\n },\n\n firePointers: function (pointer, event, eventTarget, targets, elements, eventType) {\n var pointerIndex = this.mouse? 0 : indexOf(this.pointerIds, getPointerId(pointer)),\n pointerEvent = {},\n i,\n // for tap events\n interval, createNewDoubleTap;\n\n // if it's a doubletap then the event properties would have been\n // copied from the tap event and provided as the pointer argument\n if (eventType === 'doubletap') {\n pointerEvent = pointer;\n }\n else {\n pointerExtend(pointerEvent, event);\n if (event !== pointer) {\n pointerExtend(pointerEvent, pointer);\n }\n\n pointerEvent.preventDefault = preventOriginalDefault;\n pointerEvent.stopPropagation = InteractEvent.prototype.stopPropagation;\n pointerEvent.stopImmediatePropagation = InteractEvent.prototype.stopImmediatePropagation;\n pointerEvent.interaction = this;\n\n pointerEvent.timeStamp = new Date().getTime();\n pointerEvent.originalEvent = event;\n pointerEvent.originalPointer = pointer;\n pointerEvent.type = eventType;\n pointerEvent.pointerId = getPointerId(pointer);\n pointerEvent.pointerType = this.mouse? 'mouse' : !supportsPointerEvent? 'touch'\n : isString(pointer.pointerType)\n ? pointer.pointerType\n : [,,'touch', 'pen', 'mouse'][pointer.pointerType];\n }\n\n if (eventType === 'tap') {\n pointerEvent.dt = pointerEvent.timeStamp - this.downTimes[pointerIndex];\n\n interval = pointerEvent.timeStamp - this.tapTime;\n createNewDoubleTap = !!(this.prevTap && this.prevTap.type !== 'doubletap'\n && this.prevTap.target === pointerEvent.target\n && interval < 500);\n\n pointerEvent.double = createNewDoubleTap;\n\n this.tapTime = pointerEvent.timeStamp;\n }\n\n for (i = 0; i < targets.length; i++) {\n pointerEvent.currentTarget = elements[i];\n pointerEvent.interactable = targets[i];\n targets[i].fire(pointerEvent);\n\n if (pointerEvent.immediatePropagationStopped\n ||(pointerEvent.propagationStopped && elements[i + 1] !== pointerEvent.currentTarget)) {\n break;\n }\n }\n\n if (createNewDoubleTap) {\n var doubleTap = {};\n\n extend(doubleTap, pointerEvent);\n\n doubleTap.dt = interval;\n doubleTap.type = 'doubletap';\n\n this.collectEventTargets(doubleTap, event, eventTarget, 'doubletap');\n\n this.prevTap = doubleTap;\n }\n else if (eventType === 'tap') {\n this.prevTap = pointerEvent;\n }\n },\n\n validateSelector: function (pointer, event, matches, matchElements) {\n for (var i = 0, len = matches.length; i < len; i++) {\n var match = matches[i],\n matchElement = matchElements[i],\n action = validateAction(match.getAction(pointer, event, this, matchElement), match);\n\n if (action && withinInteractionLimit(match, matchElement, action)) {\n this.target = match;\n this.element = matchElement;\n\n return action;\n }\n }\n },\n\n setSnapping: function (pageCoords, status) {\n var snap = this.target.options[this.prepared.name].snap,\n targets = [],\n target,\n page,\n i;\n\n status = status || this.snapStatus;\n\n if (status.useStatusXY) {\n page = { x: status.x, y: status.y };\n }\n else {\n var origin = getOriginXY(this.target, this.element);\n\n page = extend({}, pageCoords);\n\n page.x -= origin.x;\n page.y -= origin.y;\n }\n\n status.realX = page.x;\n status.realY = page.y;\n\n page.x = page.x - this.inertiaStatus.resumeDx;\n page.y = page.y - this.inertiaStatus.resumeDy;\n\n var len = snap.targets? snap.targets.length : 0;\n\n for (var relIndex = 0; relIndex < this.snapOffsets.length; relIndex++) {\n var relative = {\n x: page.x - this.snapOffsets[relIndex].x,\n y: page.y - this.snapOffsets[relIndex].y\n };\n\n for (i = 0; i < len; i++) {\n if (isFunction(snap.targets[i])) {\n target = snap.targets[i](relative.x, relative.y, this);\n }\n else {\n target = snap.targets[i];\n }\n\n if (!target) { continue; }\n\n targets.push({\n x: isNumber(target.x) ? (target.x + this.snapOffsets[relIndex].x) : relative.x,\n y: isNumber(target.y) ? (target.y + this.snapOffsets[relIndex].y) : relative.y,\n\n range: isNumber(target.range)? target.range: snap.range\n });\n }\n }\n\n var closest = {\n target: null,\n inRange: false,\n distance: 0,\n range: 0,\n dx: 0,\n dy: 0\n };\n\n for (i = 0, len = targets.length; i < len; i++) {\n target = targets[i];\n\n var range = target.range,\n dx = target.x - page.x,\n dy = target.y - page.y,\n distance = hypot(dx, dy),\n inRange = distance <= range;\n\n // Infinite targets count as being out of range\n // compared to non infinite ones that are in range\n if (range === Infinity && closest.inRange && closest.range !== Infinity) {\n inRange = false;\n }\n\n if (!closest.target || (inRange\n // is the closest target in range?\n ? (closest.inRange && range !== Infinity\n // the pointer is relatively deeper in this target\n ? distance / range < closest.distance / closest.range\n // this target has Infinite range and the closest doesn't\n : (range === Infinity && closest.range !== Infinity)\n // OR this target is closer that the previous closest\n || distance < closest.distance)\n // The other is not in range and the pointer is closer to this target\n : (!closest.inRange && distance < closest.distance))) {\n\n if (range === Infinity) {\n inRange = true;\n }\n\n closest.target = target;\n closest.distance = distance;\n closest.range = range;\n closest.inRange = inRange;\n closest.dx = dx;\n closest.dy = dy;\n\n status.range = range;\n }\n }\n\n var snapChanged;\n\n if (closest.target) {\n snapChanged = (status.snappedX !== closest.target.x || status.snappedY !== closest.target.y);\n\n status.snappedX = closest.target.x;\n status.snappedY = closest.target.y;\n }\n else {\n snapChanged = true;\n\n status.snappedX = NaN;\n status.snappedY = NaN;\n }\n\n status.dx = closest.dx;\n status.dy = closest.dy;\n\n status.changed = (snapChanged || (closest.inRange && !status.locked));\n status.locked = closest.inRange;\n\n return status;\n },\n\n setRestriction: function (pageCoords, status) {\n var target = this.target,\n restrict = target && target.options[this.prepared.name].restrict,\n restriction = restrict && restrict.restriction,\n page;\n\n if (!restriction) {\n return status;\n }\n\n status = status || this.restrictStatus;\n\n page = status.useStatusXY\n ? page = { x: status.x, y: status.y }\n : page = extend({}, pageCoords);\n\n if (status.snap && status.snap.locked) {\n page.x += status.snap.dx || 0;\n page.y += status.snap.dy || 0;\n }\n\n page.x -= this.inertiaStatus.resumeDx;\n page.y -= this.inertiaStatus.resumeDy;\n\n status.dx = 0;\n status.dy = 0;\n status.restricted = false;\n\n var rect, restrictedX, restrictedY;\n\n if (isString(restriction)) {\n if (restriction === 'parent') {\n restriction = parentElement(this.element);\n }\n else if (restriction === 'self') {\n restriction = target.getRect(this.element);\n }\n else {\n restriction = closest(this.element, restriction);\n }\n\n if (!restriction) { return status; }\n }\n\n if (isFunction(restriction)) {\n restriction = restriction(page.x, page.y, this.element);\n }\n\n if (isElement(restriction)) {\n restriction = getElementRect(restriction);\n }\n\n rect = restriction;\n\n if (!restriction) {\n restrictedX = page.x;\n restrictedY = page.y;\n }\n // object is assumed to have\n // x, y, width, height or\n // left, top, right, bottom\n else if ('x' in restriction && 'y' in restriction) {\n restrictedX = Math.max(Math.min(rect.x + rect.width - this.restrictOffset.right , page.x), rect.x + this.restrictOffset.left);\n restrictedY = Math.max(Math.min(rect.y + rect.height - this.restrictOffset.bottom, page.y), rect.y + this.restrictOffset.top );\n }\n else {\n restrictedX = Math.max(Math.min(rect.right - this.restrictOffset.right , page.x), rect.left + this.restrictOffset.left);\n restrictedY = Math.max(Math.min(rect.bottom - this.restrictOffset.bottom, page.y), rect.top + this.restrictOffset.top );\n }\n\n status.dx = restrictedX - page.x;\n status.dy = restrictedY - page.y;\n\n status.changed = status.restrictedX !== restrictedX || status.restrictedY !== restrictedY;\n status.restricted = !!(status.dx || status.dy);\n\n status.restrictedX = restrictedX;\n status.restrictedY = restrictedY;\n\n return status;\n },\n\n checkAndPreventDefault: function (event, interactable, element) {\n if (!(interactable = interactable || this.target)) { return; }\n\n var options = interactable.options,\n prevent = options.preventDefault;\n\n if (prevent === 'auto' && element && !/^(input|select|textarea)$/i.test(event.target.nodeName)) {\n // do not preventDefault on pointerdown if the prepared action is a drag\n // and dragging can only start from a certain direction - this allows\n // a touch to pan the viewport if a drag isn't in the right direction\n if (/down|start/i.test(event.type)\n && this.prepared.name === 'drag' && options.drag.axis !== 'xy') {\n\n return;\n }\n\n // with manualStart, only preventDefault while interacting\n if (options[this.prepared.name] && options[this.prepared.name].manualStart\n && !this.interacting()) {\n return;\n }\n\n event.preventDefault();\n return;\n }\n\n if (prevent === 'always') {\n event.preventDefault();\n return;\n }\n },\n\n calcInertia: function (status) {\n var inertiaOptions = this.target.options[this.prepared.name].inertia,\n lambda = inertiaOptions.resistance,\n inertiaDur = -Math.log(inertiaOptions.endSpeed / status.v0) / lambda;\n\n status.x0 = this.prevEvent.pageX;\n status.y0 = this.prevEvent.pageY;\n status.t0 = status.startEvent.timeStamp / 1000;\n status.sx = status.sy = 0;\n\n status.modifiedXe = status.xe = (status.vx0 - inertiaDur) / lambda;\n status.modifiedYe = status.ye = (status.vy0 - inertiaDur) / lambda;\n status.te = inertiaDur;\n\n status.lambda_v0 = lambda / status.v0;\n status.one_ve_v0 = 1 - inertiaOptions.endSpeed / status.v0;\n },\n\n autoScrollMove: function (pointer) {\n if (!(this.interacting()\n && checkAutoScroll(this.target, this.prepared.name))) {\n return;\n }\n\n if (this.inertiaStatus.active) {\n autoScroll.x = autoScroll.y = 0;\n return;\n }\n\n var top,\n right,\n bottom,\n left,\n options = this.target.options[this.prepared.name].autoScroll,\n container = options.container || getWindow(this.element);\n\n if (isWindow(container)) {\n left = pointer.clientX < autoScroll.margin;\n top = pointer.clientY < autoScroll.margin;\n right = pointer.clientX > container.innerWidth - autoScroll.margin;\n bottom = pointer.clientY > container.innerHeight - autoScroll.margin;\n }\n else {\n var rect = getElementClientRect(container);\n\n left = pointer.clientX < rect.left + autoScroll.margin;\n top = pointer.clientY < rect.top + autoScroll.margin;\n right = pointer.clientX > rect.right - autoScroll.margin;\n bottom = pointer.clientY > rect.bottom - autoScroll.margin;\n }\n\n autoScroll.x = (right ? 1: left? -1: 0);\n autoScroll.y = (bottom? 1: top? -1: 0);\n\n if (!autoScroll.isScrolling) {\n // set the autoScroll properties to those of the target\n autoScroll.margin = options.margin;\n autoScroll.speed = options.speed;\n\n autoScroll.start(this);\n }\n },\n\n _updateEventTargets: function (target, currentTarget) {\n this._eventTarget = target;\n this._curEventTarget = currentTarget;\n }\n\n };\n\n function getInteractionFromPointer (pointer, eventType, eventTarget) {\n var i = 0, len = interactions.length,\n mouseEvent = (/mouse/i.test(pointer.pointerType || eventType)\n // MSPointerEvent.MSPOINTER_TYPE_MOUSE\n || pointer.pointerType === 4),\n interaction;\n\n var id = getPointerId(pointer);\n\n // try to resume inertia with a new pointer\n if (/down|start/i.test(eventType)) {\n for (i = 0; i < len; i++) {\n interaction = interactions[i];\n\n var element = eventTarget;\n\n if (interaction.inertiaStatus.active && interaction.target.options[interaction.prepared.name].inertia.allowResume\n && (interaction.mouse === mouseEvent)) {\n while (element) {\n // if the element is the interaction element\n if (element === interaction.element) {\n return interaction;\n }\n element = parentElement(element);\n }\n }\n }\n }\n\n // if it's a mouse interaction\n if (mouseEvent || !(supportsTouch || supportsPointerEvent)) {\n\n // find a mouse interaction that's not in inertia phase\n for (i = 0; i < len; i++) {\n if (interactions[i].mouse && !interactions[i].inertiaStatus.active) {\n return interactions[i];\n }\n }\n\n // find any interaction specifically for mouse.\n // if the eventType is a mousedown, and inertia is active\n // ignore the interaction\n for (i = 0; i < len; i++) {\n if (interactions[i].mouse && !(/down/.test(eventType) && interactions[i].inertiaStatus.active)) {\n return interaction;\n }\n }\n\n // create a new interaction for mouse\n interaction = new Interaction();\n interaction.mouse = true;\n\n return interaction;\n }\n\n // get interaction that has this pointer\n for (i = 0; i < len; i++) {\n if (contains(interactions[i].pointerIds, id)) {\n return interactions[i];\n }\n }\n\n // at this stage, a pointerUp should not return an interaction\n if (/up|end|out/i.test(eventType)) {\n return null;\n }\n\n // get first idle interaction\n for (i = 0; i < len; i++) {\n interaction = interactions[i];\n\n if ((!interaction.prepared.name || (interaction.target.options.gesture.enabled))\n && !interaction.interacting()\n && !(!mouseEvent && interaction.mouse)) {\n\n return interaction;\n }\n }\n\n return new Interaction();\n }\n\n function doOnInteractions (method) {\n return (function (event) {\n var interaction,\n eventTarget = getActualElement(event.path\n ? event.path[0]\n : event.target),\n curEventTarget = getActualElement(event.currentTarget),\n i;\n\n if (supportsTouch && /touch/.test(event.type)) {\n prevTouchTime = new Date().getTime();\n\n for (i = 0; i < event.changedTouches.length; i++) {\n var pointer = event.changedTouches[i];\n\n interaction = getInteractionFromPointer(pointer, event.type, eventTarget);\n\n if (!interaction) { continue; }\n\n interaction._updateEventTargets(eventTarget, curEventTarget);\n\n interaction[method](pointer, event, eventTarget, curEventTarget);\n }\n }\n else {\n if (!supportsPointerEvent && /mouse/.test(event.type)) {\n // ignore mouse events while touch interactions are active\n for (i = 0; i < interactions.length; i++) {\n if (!interactions[i].mouse && interactions[i].pointerIsDown) {\n return;\n }\n }\n\n // try to ignore mouse events that are simulated by the browser\n // after a touch event\n if (new Date().getTime() - prevTouchTime < 500) {\n return;\n }\n }\n\n interaction = getInteractionFromPointer(event, event.type, eventTarget);\n\n if (!interaction) { return; }\n\n interaction._updateEventTargets(eventTarget, curEventTarget);\n\n interaction[method](event, event, eventTarget, curEventTarget);\n }\n });\n }\n\n function InteractEvent (interaction, event, action, phase, element, related) {\n var client,\n page,\n target = interaction.target,\n snapStatus = interaction.snapStatus,\n restrictStatus = interaction.restrictStatus,\n pointers = interaction.pointers,\n deltaSource = (target && target.options || defaultOptions).deltaSource,\n sourceX = deltaSource + 'X',\n sourceY = deltaSource + 'Y',\n options = target? target.options: defaultOptions,\n origin = getOriginXY(target, element),\n starting = phase === 'start',\n ending = phase === 'end',\n coords = starting? interaction.startCoords : interaction.curCoords;\n\n element = element || interaction.element;\n\n page = extend({}, coords.page);\n client = extend({}, coords.client);\n\n page.x -= origin.x;\n page.y -= origin.y;\n\n client.x -= origin.x;\n client.y -= origin.y;\n\n var relativePoints = options[action].snap && options[action].snap.relativePoints ;\n\n if (checkSnap(target, action) && !(starting && relativePoints && relativePoints.length)) {\n this.snap = {\n range : snapStatus.range,\n locked : snapStatus.locked,\n x : snapStatus.snappedX,\n y : snapStatus.snappedY,\n realX : snapStatus.realX,\n realY : snapStatus.realY,\n dx : snapStatus.dx,\n dy : snapStatus.dy\n };\n\n if (snapStatus.locked) {\n page.x += snapStatus.dx;\n page.y += snapStatus.dy;\n client.x += snapStatus.dx;\n client.y += snapStatus.dy;\n }\n }\n\n if (checkRestrict(target, action) && !(starting && options[action].restrict.elementRect) && restrictStatus.restricted) {\n page.x += restrictStatus.dx;\n page.y += restrictStatus.dy;\n client.x += restrictStatus.dx;\n client.y += restrictStatus.dy;\n\n this.restrict = {\n dx: restrictStatus.dx,\n dy: restrictStatus.dy\n };\n }\n\n this.pageX = page.x;\n this.pageY = page.y;\n this.clientX = client.x;\n this.clientY = client.y;\n\n this.x0 = interaction.startCoords.page.x - origin.x;\n this.y0 = interaction.startCoords.page.y - origin.y;\n this.clientX0 = interaction.startCoords.client.x - origin.x;\n this.clientY0 = interaction.startCoords.client.y - origin.y;\n this.ctrlKey = event.ctrlKey;\n this.altKey = event.altKey;\n this.shiftKey = event.shiftKey;\n this.metaKey = event.metaKey;\n this.button = event.button;\n this.buttons = event.buttons;\n this.target = element;\n this.t0 = interaction.downTimes[0];\n this.type = action + (phase || '');\n\n this.interaction = interaction;\n this.interactable = target;\n\n var inertiaStatus = interaction.inertiaStatus;\n\n if (inertiaStatus.active) {\n this.detail = 'inertia';\n }\n\n if (related) {\n this.relatedTarget = related;\n }\n\n // end event dx, dy is difference between start and end points\n if (ending) {\n if (deltaSource === 'client') {\n this.dx = client.x - interaction.startCoords.client.x;\n this.dy = client.y - interaction.startCoords.client.y;\n }\n else {\n this.dx = page.x - interaction.startCoords.page.x;\n this.dy = page.y - interaction.startCoords.page.y;\n }\n }\n else if (starting) {\n this.dx = 0;\n this.dy = 0;\n }\n // copy properties from previousmove if starting inertia\n else if (phase === 'inertiastart') {\n this.dx = interaction.prevEvent.dx;\n this.dy = interaction.prevEvent.dy;\n }\n else {\n if (deltaSource === 'client') {\n this.dx = client.x - interaction.prevEvent.clientX;\n this.dy = client.y - interaction.prevEvent.clientY;\n }\n else {\n this.dx = page.x - interaction.prevEvent.pageX;\n this.dy = page.y - interaction.prevEvent.pageY;\n }\n }\n if (interaction.prevEvent && interaction.prevEvent.detail === 'inertia'\n && !inertiaStatus.active\n && options[action].inertia && options[action].inertia.zeroResumeDelta) {\n\n inertiaStatus.resumeDx += this.dx;\n inertiaStatus.resumeDy += this.dy;\n\n this.dx = this.dy = 0;\n }\n\n if (action === 'resize' && interaction.resizeAxes) {\n if (options.resize.square) {\n if (interaction.resizeAxes === 'y') {\n this.dx = this.dy;\n }\n else {\n this.dy = this.dx;\n }\n this.axes = 'xy';\n }\n else {\n this.axes = interaction.resizeAxes;\n\n if (interaction.resizeAxes === 'x') {\n this.dy = 0;\n }\n else if (interaction.resizeAxes === 'y') {\n this.dx = 0;\n }\n }\n }\n else if (action === 'gesture') {\n this.touches = [pointers[0], pointers[1]];\n\n if (starting) {\n this.distance = touchDistance(pointers, deltaSource);\n this.box = touchBBox(pointers);\n this.scale = 1;\n this.ds = 0;\n this.angle = touchAngle(pointers, undefined, deltaSource);\n this.da = 0;\n }\n else if (ending || event instanceof InteractEvent) {\n this.distance = interaction.prevEvent.distance;\n this.box = interaction.prevEvent.box;\n this.scale = interaction.prevEvent.scale;\n this.ds = this.scale - 1;\n this.angle = interaction.prevEvent.angle;\n this.da = this.angle - interaction.gesture.startAngle;\n }\n else {\n this.distance = touchDistance(pointers, deltaSource);\n this.box = touchBBox(pointers);\n this.scale = this.distance / interaction.gesture.startDistance;\n this.angle = touchAngle(pointers, interaction.gesture.prevAngle, deltaSource);\n\n this.ds = this.scale - interaction.gesture.prevScale;\n this.da = this.angle - interaction.gesture.prevAngle;\n }\n }\n\n if (starting) {\n this.timeStamp = interaction.downTimes[0];\n this.dt = 0;\n this.duration = 0;\n this.speed = 0;\n this.velocityX = 0;\n this.velocityY = 0;\n }\n else if (phase === 'inertiastart') {\n this.timeStamp = interaction.prevEvent.timeStamp;\n this.dt = interaction.prevEvent.dt;\n this.duration = interaction.prevEvent.duration;\n this.speed = interaction.prevEvent.speed;\n this.velocityX = interaction.prevEvent.velocityX;\n this.velocityY = interaction.prevEvent.velocityY;\n }\n else {\n this.timeStamp = new Date().getTime();\n this.dt = this.timeStamp - interaction.prevEvent.timeStamp;\n this.duration = this.timeStamp - interaction.downTimes[0];\n\n if (event instanceof InteractEvent) {\n var dx = this[sourceX] - interaction.prevEvent[sourceX],\n dy = this[sourceY] - interaction.prevEvent[sourceY],\n dt = this.dt / 1000;\n\n this.speed = hypot(dx, dy) / dt;\n this.velocityX = dx / dt;\n this.velocityY = dy / dt;\n }\n // if normal move or end event, use previous user event coords\n else {\n // speed and velocity in pixels per second\n this.speed = interaction.pointerDelta[deltaSource].speed;\n this.velocityX = interaction.pointerDelta[deltaSource].vx;\n this.velocityY = interaction.pointerDelta[deltaSource].vy;\n }\n }\n\n if ((ending || phase === 'inertiastart')\n && interaction.prevEvent.speed > 600 && this.timeStamp - interaction.prevEvent.timeStamp < 150) {\n\n var angle = 180 * Math.atan2(interaction.prevEvent.velocityY, interaction.prevEvent.velocityX) / Math.PI,\n overlap = 22.5;\n\n if (angle < 0) {\n angle += 360;\n }\n\n var left = 135 - overlap <= angle && angle < 225 + overlap,\n up = 225 - overlap <= angle && angle < 315 + overlap,\n\n right = !left && (315 - overlap <= angle || angle < 45 + overlap),\n down = !up && 45 - overlap <= angle && angle < 135 + overlap;\n\n this.swipe = {\n up : up,\n down : down,\n left : left,\n right: right,\n angle: angle,\n speed: interaction.prevEvent.speed,\n velocity: {\n x: interaction.prevEvent.velocityX,\n y: interaction.prevEvent.velocityY\n }\n };\n }\n }\n\n InteractEvent.prototype = {\n preventDefault: blank,\n stopImmediatePropagation: function () {\n this.immediatePropagationStopped = this.propagationStopped = true;\n },\n stopPropagation: function () {\n this.propagationStopped = true;\n }\n };\n\n function preventOriginalDefault () {\n this.originalEvent.preventDefault();\n }\n\n function getActionCursor (action) {\n var cursor = '';\n\n if (action.name === 'drag') {\n cursor = actionCursors.drag;\n }\n if (action.name === 'resize') {\n if (action.axis) {\n cursor = actionCursors[action.name + action.axis];\n }\n else if (action.edges) {\n var cursorKey = 'resize',\n edgeNames = ['top', 'bottom', 'left', 'right'];\n\n for (var i = 0; i < 4; i++) {\n if (action.edges[edgeNames[i]]) {\n cursorKey += edgeNames[i];\n }\n }\n\n cursor = actionCursors[cursorKey];\n }\n }\n\n return cursor;\n }\n\n function checkResizeEdge (name, value, page, element, interactableElement, rect, margin) {\n // false, '', undefined, null\n if (!value) { return false; }\n\n // true value, use pointer coords and element rect\n if (value === true) {\n // if dimensions are negative, \"switch\" edges\n var width = isNumber(rect.width)? rect.width : rect.right - rect.left,\n height = isNumber(rect.height)? rect.height : rect.bottom - rect.top;\n\n if (width < 0) {\n if (name === 'left' ) { name = 'right'; }\n else if (name === 'right') { name = 'left' ; }\n }\n if (height < 0) {\n if (name === 'top' ) { name = 'bottom'; }\n else if (name === 'bottom') { name = 'top' ; }\n }\n\n if (name === 'left' ) { return page.x < ((width >= 0? rect.left: rect.right ) + margin); }\n if (name === 'top' ) { return page.y < ((height >= 0? rect.top : rect.bottom) + margin); }\n\n if (name === 'right' ) { return page.x > ((width >= 0? rect.right : rect.left) - margin); }\n if (name === 'bottom') { return page.y > ((height >= 0? rect.bottom: rect.top ) - margin); }\n }\n\n // the remaining checks require an element\n if (!isElement(element)) { return false; }\n\n return isElement(value)\n // the value is an element to use as a resize handle\n ? value === element\n // otherwise check if element matches value as selector\n : matchesUpTo(element, value, interactableElement);\n }\n\n function defaultActionChecker (pointer, interaction, element) {\n var rect = this.getRect(element),\n shouldResize = false,\n action = null,\n resizeAxes = null,\n resizeEdges,\n page = extend({}, interaction.curCoords.page),\n options = this.options;\n\n if (!rect) { return null; }\n\n if (actionIsEnabled.resize && options.resize.enabled) {\n var resizeOptions = options.resize;\n\n resizeEdges = {\n left: false, right: false, top: false, bottom: false\n };\n\n // if using resize.edges\n if (isObject(resizeOptions.edges)) {\n for (var edge in resizeEdges) {\n resizeEdges[edge] = checkResizeEdge(edge,\n resizeOptions.edges[edge],\n page,\n interaction._eventTarget,\n element,\n rect,\n resizeOptions.margin || margin);\n }\n\n resizeEdges.left = resizeEdges.left && !resizeEdges.right;\n resizeEdges.top = resizeEdges.top && !resizeEdges.bottom;\n\n shouldResize = resizeEdges.left || resizeEdges.right || resizeEdges.top || resizeEdges.bottom;\n }\n else {\n var right = options.resize.axis !== 'y' && page.x > (rect.right - margin),\n bottom = options.resize.axis !== 'x' && page.y > (rect.bottom - margin);\n\n shouldResize = right || bottom;\n resizeAxes = (right? 'x' : '') + (bottom? 'y' : '');\n }\n }\n\n action = shouldResize\n ? 'resize'\n : actionIsEnabled.drag && options.drag.enabled\n ? 'drag'\n : null;\n\n if (actionIsEnabled.gesture\n && interaction.pointerIds.length >=2\n && !(interaction.dragging || interaction.resizing)) {\n action = 'gesture';\n }\n\n if (action) {\n return {\n name: action,\n axis: resizeAxes,\n edges: resizeEdges\n };\n }\n\n return null;\n }\n\n // Check if action is enabled globally and the current target supports it\n // If so, return the validated action. Otherwise, return null\n function validateAction (action, interactable) {\n if (!isObject(action)) { return null; }\n\n var actionName = action.name,\n options = interactable.options;\n\n if (( (actionName === 'resize' && options.resize.enabled )\n || (actionName === 'drag' && options.drag.enabled )\n || (actionName === 'gesture' && options.gesture.enabled))\n && actionIsEnabled[actionName]) {\n\n if (actionName === 'resize' || actionName === 'resizeyx') {\n actionName = 'resizexy';\n }\n\n return action;\n }\n return null;\n }\n\n var listeners = {},\n interactionListeners = [\n 'dragStart', 'dragMove', 'resizeStart', 'resizeMove', 'gestureStart', 'gestureMove',\n 'pointerOver', 'pointerOut', 'pointerHover', 'selectorDown',\n 'pointerDown', 'pointerMove', 'pointerUp', 'pointerCancel', 'pointerEnd',\n 'addPointer', 'removePointer', 'recordPointer', 'autoScrollMove'\n ];\n\n for (var i = 0, len = interactionListeners.length; i < len; i++) {\n var name = interactionListeners[i];\n\n listeners[name] = doOnInteractions(name);\n }\n\n // bound to the interactable context when a DOM event\n // listener is added to a selector interactable\n function delegateListener (event, useCapture) {\n var fakeEvent = {},\n delegated = delegatedEvents[event.type],\n eventTarget = getActualElement(event.path\n ? event.path[0]\n : event.target),\n element = eventTarget;\n\n useCapture = useCapture? true: false;\n\n // duplicate the event so that currentTarget can be changed\n for (var prop in event) {\n fakeEvent[prop] = event[prop];\n }\n\n fakeEvent.originalEvent = event;\n fakeEvent.preventDefault = preventOriginalDefault;\n\n // climb up document tree looking for selector matches\n while (isElement(element)) {\n for (var i = 0; i < delegated.selectors.length; i++) {\n var selector = delegated.selectors[i],\n context = delegated.contexts[i];\n\n if (matchesSelector(element, selector)\n && nodeContains(context, eventTarget)\n && nodeContains(context, element)) {\n\n var listeners = delegated.listeners[i];\n\n fakeEvent.currentTarget = element;\n\n for (var j = 0; j < listeners.length; j++) {\n if (listeners[j][1] === useCapture) {\n listeners[j][0](fakeEvent);\n }\n }\n }\n }\n\n element = parentElement(element);\n }\n }\n\n function delegateUseCapture (event) {\n return delegateListener.call(this, event, true);\n }\n\n interactables.indexOfElement = function indexOfElement (element, context) {\n context = context || document;\n\n for (var i = 0; i < this.length; i++) {\n var interactable = this[i];\n\n if ((interactable.selector === element\n && (interactable._context === context))\n || (!interactable.selector && interactable._element === element)) {\n\n return i;\n }\n }\n return -1;\n };\n\n interactables.get = function interactableGet (element, options) {\n return this[this.indexOfElement(element, options && options.context)];\n };\n\n interactables.forEachSelector = function (callback) {\n for (var i = 0; i < this.length; i++) {\n var interactable = this[i];\n\n if (!interactable.selector) {\n continue;\n }\n\n var ret = callback(interactable, interactable.selector, interactable._context, i, this);\n\n if (ret !== undefined) {\n return ret;\n }\n }\n };\n\n /*\\\n * interact\n [ method ]\n *\n * The methods of this variable can be used to set elements as\n * interactables and also to change various default settings.\n *\n * Calling it as a function and passing an element or a valid CSS selector\n * string returns an Interactable object which has various methods to\n * configure it.\n *\n - element (Element | string) The HTML or SVG Element to interact with or CSS selector\n = (object) An @Interactable\n *\n > Usage\n | interact(document.getElementById('draggable')).draggable(true);\n |\n | var rectables = interact('rect');\n | rectables\n | .gesturable(true)\n | .on('gesturemove', function (event) {\n | // something cool...\n | })\n | .autoScroll(true);\n \\*/\n function interact (element, options) {\n return interactables.get(element, options) || new Interactable(element, options);\n }\n\n /*\\\n * Interactable\n [ property ]\n **\n * Object type returned by @interact\n \\*/\n function Interactable (element, options) {\n this._element = element;\n this._iEvents = this._iEvents || {};\n\n var _window;\n\n if (trySelector(element)) {\n this.selector = element;\n\n var context = options && options.context;\n\n _window = context? getWindow(context) : window;\n\n if (context && (_window.Node\n ? context instanceof _window.Node\n : (isElement(context) || context === _window.document))) {\n\n this._context = context;\n }\n }\n else {\n _window = getWindow(element);\n\n if (isElement(element, _window)) {\n\n if (supportsPointerEvent) {\n events.add(this._element, pEventTypes.down, listeners.pointerDown );\n events.add(this._element, pEventTypes.move, listeners.pointerHover);\n }\n else {\n events.add(this._element, 'mousedown' , listeners.pointerDown );\n events.add(this._element, 'mousemove' , listeners.pointerHover);\n events.add(this._element, 'touchstart', listeners.pointerDown );\n events.add(this._element, 'touchmove' , listeners.pointerHover);\n }\n }\n }\n\n this._doc = _window.document;\n\n if (!contains(documents, this._doc)) {\n listenToDocument(this._doc);\n }\n\n interactables.push(this);\n\n this.set(options);\n }\n\n Interactable.prototype = {\n setOnEvents: function (action, phases) {\n if (action === 'drop') {\n if (isFunction(phases.ondrop) ) { this.ondrop = phases.ondrop ; }\n if (isFunction(phases.ondropactivate) ) { this.ondropactivate = phases.ondropactivate ; }\n if (isFunction(phases.ondropdeactivate)) { this.ondropdeactivate = phases.ondropdeactivate; }\n if (isFunction(phases.ondragenter) ) { this.ondragenter = phases.ondragenter ; }\n if (isFunction(phases.ondragleave) ) { this.ondragleave = phases.ondragleave ; }\n if (isFunction(phases.ondropmove) ) { this.ondropmove = phases.ondropmove ; }\n }\n else {\n action = 'on' + action;\n\n if (isFunction(phases.onstart) ) { this[action + 'start' ] = phases.onstart ; }\n if (isFunction(phases.onmove) ) { this[action + 'move' ] = phases.onmove ; }\n if (isFunction(phases.onend) ) { this[action + 'end' ] = phases.onend ; }\n if (isFunction(phases.oninertiastart)) { this[action + 'inertiastart' ] = phases.oninertiastart ; }\n }\n\n return this;\n },\n\n /*\\\n * Interactable.draggable\n [ method ]\n *\n * Gets or sets whether drag actions can be performed on the\n * Interactable\n *\n = (boolean) Indicates if this can be the target of drag events\n | var isDraggable = interact('ul li').draggable();\n * or\n - options (boolean | object) #optional true/false or An object with event listeners to be fired on drag events (object makes the Interactable draggable)\n = (object) This Interactable\n | interact(element).draggable({\n | onstart: function (event) {},\n | onmove : function (event) {},\n | onend : function (event) {},\n |\n | // the axis in which the first movement must be\n | // for the drag sequence to start\n | // 'xy' by default - any direction\n | axis: 'x' || 'y' || 'xy',\n |\n | // max number of drags that can happen concurrently\n | // with elements of this Interactable. Infinity by default\n | max: Infinity,\n |\n | // max number of drags that can target the same element+Interactable\n | // 1 by default\n | maxPerElement: 2\n | });\n \\*/\n draggable: function (options) {\n if (isObject(options)) {\n this.options.drag.enabled = options.enabled === false? false: true;\n this.setPerAction('drag', options);\n this.setOnEvents('drag', options);\n\n if (/^x$|^y$|^xy$/.test(options.axis)) {\n this.options.drag.axis = options.axis;\n }\n else if (options.axis === null) {\n delete this.options.drag.axis;\n }\n\n return this;\n }\n\n if (isBool(options)) {\n this.options.drag.enabled = options;\n\n return this;\n }\n\n return this.options.drag;\n },\n\n setPerAction: function (action, options) {\n // for all the default per-action options\n for (var option in options) {\n // if this option exists for this action\n if (option in defaultOptions[action]) {\n // if the option in the options arg is an object value\n if (isObject(options[option])) {\n // duplicate the object\n this.options[action][option] = extend(this.options[action][option] || {}, options[option]);\n\n if (isObject(defaultOptions.perAction[option]) && 'enabled' in defaultOptions.perAction[option]) {\n this.options[action][option].enabled = options[option].enabled === false? false : true;\n }\n }\n else if (isBool(options[option]) && isObject(defaultOptions.perAction[option])) {\n this.options[action][option].enabled = options[option];\n }\n else if (options[option] !== undefined) {\n // or if it's not undefined, do a plain assignment\n this.options[action][option] = options[option];\n }\n }\n }\n },\n\n /*\\\n * Interactable.dropzone\n [ method ]\n *\n * Returns or sets whether elements can be dropped onto this\n * Interactable to trigger drop events\n *\n * Dropzones can receive the following events:\n * - `dropactivate` and `dropdeactivate` when an acceptable drag starts and ends\n * - `dragenter` and `dragleave` when a draggable enters and leaves the dropzone\n * - `dragmove` when a draggable that has entered the dropzone is moved\n * - `drop` when a draggable is dropped into this dropzone\n *\n * Use the `accept` option to allow only elements that match the given CSS selector or element.\n *\n * Use the `overlap` option to set how drops are checked for. The allowed values are:\n * - `'pointer'`, the pointer must be over the dropzone (default)\n * - `'center'`, the draggable element's center must be over the dropzone\n * - a number from 0-1 which is the `(intersection area) / (draggable area)`.\n * e.g. `0.5` for drop to happen when half of the area of the\n * draggable is over the dropzone\n *\n - options (boolean | object | null) #optional The new value to be set.\n | interact('.drop').dropzone({\n | accept: '.can-drop' || document.getElementById('single-drop'),\n | overlap: 'pointer' || 'center' || zeroToOne\n | }\n = (boolean | object) The current setting or this Interactable\n \\*/\n dropzone: function (options) {\n if (isObject(options)) {\n this.options.drop.enabled = options.enabled === false? false: true;\n this.setOnEvents('drop', options);\n\n if (/^(pointer|center)$/.test(options.overlap)) {\n this.options.drop.overlap = options.overlap;\n }\n else if (isNumber(options.overlap)) {\n this.options.drop.overlap = Math.max(Math.min(1, options.overlap), 0);\n }\n if ('accept' in options) {\n this.options.drop.accept = options.accept;\n }\n if ('checker' in options) {\n this.options.drop.checker = options.checker;\n }\n\n return this;\n }\n\n if (isBool(options)) {\n this.options.drop.enabled = options;\n\n return this;\n }\n\n return this.options.drop;\n },\n\n dropCheck: function (dragEvent, event, draggable, draggableElement, dropElement, rect) {\n var dropped = false;\n\n // if the dropzone has no rect (eg. display: none)\n // call the custom dropChecker or just return false\n if (!(rect = rect || this.getRect(dropElement))) {\n return (this.options.drop.checker\n ? this.options.drop.checker(dragEvent, event, dropped, this, dropElement, draggable, draggableElement)\n : false);\n }\n\n var dropOverlap = this.options.drop.overlap;\n\n if (dropOverlap === 'pointer') {\n var page = getPageXY(dragEvent),\n origin = getOriginXY(draggable, draggableElement),\n horizontal,\n vertical;\n\n page.x += origin.x;\n page.y += origin.y;\n\n horizontal = (page.x > rect.left) && (page.x < rect.right);\n vertical = (page.y > rect.top ) && (page.y < rect.bottom);\n\n dropped = horizontal && vertical;\n }\n\n var dragRect = draggable.getRect(draggableElement);\n\n if (dropOverlap === 'center') {\n var cx = dragRect.left + dragRect.width / 2,\n cy = dragRect.top + dragRect.height / 2;\n\n dropped = cx >= rect.left && cx <= rect.right && cy >= rect.top && cy <= rect.bottom;\n }\n\n if (isNumber(dropOverlap)) {\n var overlapArea = (Math.max(0, Math.min(rect.right , dragRect.right ) - Math.max(rect.left, dragRect.left))\n * Math.max(0, Math.min(rect.bottom, dragRect.bottom) - Math.max(rect.top , dragRect.top ))),\n overlapRatio = overlapArea / (dragRect.width * dragRect.height);\n\n dropped = overlapRatio >= dropOverlap;\n }\n\n if (this.options.drop.checker) {\n dropped = this.options.drop.checker(dragEvent, event, dropped, this, dropElement, draggable, draggableElement);\n }\n\n return dropped;\n },\n\n /*\\\n * Interactable.dropChecker\n [ method ]\n *\n * DEPRECATED. Use interactable.dropzone({ checker: function... }) instead.\n *\n * Gets or sets the function used to check if a dragged element is\n * over this Interactable.\n *\n - checker (function) #optional The function that will be called when checking for a drop\n = (Function | Interactable) The checker function or this Interactable\n *\n * The checker function takes the following arguments:\n *\n - dragEvent (InteractEvent) The related dragmove or dragend event\n - event (TouchEvent | PointerEvent | MouseEvent) The user move/up/end Event related to the dragEvent\n - dropped (boolean) The value from the default drop checker\n - dropzone (Interactable) The dropzone interactable\n - dropElement (Element) The dropzone element\n - draggable (Interactable) The Interactable being dragged\n - draggableElement (Element) The actual element that's being dragged\n *\n > Usage:\n | interact(target)\n | .dropChecker(function(dragEvent, // related dragmove or dragend event\n | event, // TouchEvent/PointerEvent/MouseEvent\n | dropped, // bool result of the default checker\n | dropzone, // dropzone Interactable\n | dropElement, // dropzone elemnt\n | draggable, // draggable Interactable\n | draggableElement) {// draggable element\n |\n | return dropped && event.target.hasAttribute('allow-drop');\n | }\n \\*/\n dropChecker: function (checker) {\n if (isFunction(checker)) {\n this.options.drop.checker = checker;\n\n return this;\n }\n if (checker === null) {\n delete this.options.getRect;\n\n return this;\n }\n\n return this.options.drop.checker;\n },\n\n /*\\\n * Interactable.accept\n [ method ]\n *\n * Deprecated. add an `accept` property to the options object passed to\n * @Interactable.dropzone instead.\n *\n * Gets or sets the Element or CSS selector match that this\n * Interactable accepts if it is a dropzone.\n *\n - newValue (Element | string | null) #optional\n * If it is an Element, then only that element can be dropped into this dropzone.\n * If it is a string, the element being dragged must match it as a selector.\n * If it is null, the accept options is cleared - it accepts any element.\n *\n = (string | Element | null | Interactable) The current accept option if given `undefined` or this Interactable\n \\*/\n accept: function (newValue) {\n if (isElement(newValue)) {\n this.options.drop.accept = newValue;\n\n return this;\n }\n\n // test if it is a valid CSS selector\n if (trySelector(newValue)) {\n this.options.drop.accept = newValue;\n\n return this;\n }\n\n if (newValue === null) {\n delete this.options.drop.accept;\n\n return this;\n }\n\n return this.options.drop.accept;\n },\n\n /*\\\n * Interactable.resizable\n [ method ]\n *\n * Gets or sets whether resize actions can be performed on the\n * Interactable\n *\n = (boolean) Indicates if this can be the target of resize elements\n | var isResizeable = interact('input[type=text]').resizable();\n * or\n - options (boolean | object) #optional true/false or An object with event listeners to be fired on resize events (object makes the Interactable resizable)\n = (object) This Interactable\n | interact(element).resizable({\n | onstart: function (event) {},\n | onmove : function (event) {},\n | onend : function (event) {},\n |\n | edges: {\n | top : true, // Use pointer coords to check for resize.\n | left : false, // Disable resizing from left edge.\n | bottom: '.resize-s',// Resize if pointer target matches selector\n | right : handleEl // Resize if pointer target is the given Element\n | },\n |\n | // Width and height can be adjusted independently. When `true`, width and\n | // height are adjusted at a 1:1 ratio.\n | square: false,\n |\n | // Width and height can be adjusted independently. When `true`, width and\n | // height maintain the aspect ratio they had when resizing started.\n | preserveAspectRatio: false,\n |\n | // a value of 'none' will limit the resize rect to a minimum of 0x0\n | // 'negate' will allow the rect to have negative width/height\n | // 'reposition' will keep the width/height positive by swapping\n | // the top and bottom edges and/or swapping the left and right edges\n | invert: 'none' || 'negate' || 'reposition'\n |\n | // limit multiple resizes.\n | // See the explanation in the @Interactable.draggable example\n | max: Infinity,\n | maxPerElement: 1,\n | });\n \\*/\n resizable: function (options) {\n if (isObject(options)) {\n this.options.resize.enabled = options.enabled === false? false: true;\n this.setPerAction('resize', options);\n this.setOnEvents('resize', options);\n\n if (/^x$|^y$|^xy$/.test(options.axis)) {\n this.options.resize.axis = options.axis;\n }\n else if (options.axis === null) {\n this.options.resize.axis = defaultOptions.resize.axis;\n }\n\n if (isBool(options.preserveAspectRatio)) {\n this.options.resize.preserveAspectRatio = options.preserveAspectRatio;\n }\n else if (isBool(options.square)) {\n this.options.resize.square = options.square;\n }\n\n return this;\n }\n if (isBool(options)) {\n this.options.resize.enabled = options;\n\n return this;\n }\n return this.options.resize;\n },\n\n /*\\\n * Interactable.squareResize\n [ method ]\n *\n * Deprecated. Add a `square: true || false` property to @Interactable.resizable instead\n *\n * Gets or sets whether resizing is forced 1:1 aspect\n *\n = (boolean) Current setting\n *\n * or\n *\n - newValue (boolean) #optional\n = (object) this Interactable\n \\*/\n squareResize: function (newValue) {\n if (isBool(newValue)) {\n this.options.resize.square = newValue;\n\n return this;\n }\n\n if (newValue === null) {\n delete this.options.resize.square;\n\n return this;\n }\n\n return this.options.resize.square;\n },\n\n /*\\\n * Interactable.gesturable\n [ method ]\n *\n * Gets or sets whether multitouch gestures can be performed on the\n * Interactable's element\n *\n = (boolean) Indicates if this can be the target of gesture events\n | var isGestureable = interact(element).gesturable();\n * or\n - options (boolean | object) #optional true/false or An object with event listeners to be fired on gesture events (makes the Interactable gesturable)\n = (object) this Interactable\n | interact(element).gesturable({\n | onstart: function (event) {},\n | onmove : function (event) {},\n | onend : function (event) {},\n |\n | // limit multiple gestures.\n | // See the explanation in @Interactable.draggable example\n | max: Infinity,\n | maxPerElement: 1,\n | });\n \\*/\n gesturable: function (options) {\n if (isObject(options)) {\n this.options.gesture.enabled = options.enabled === false? false: true;\n this.setPerAction('gesture', options);\n this.setOnEvents('gesture', options);\n\n return this;\n }\n\n if (isBool(options)) {\n this.options.gesture.enabled = options;\n\n return this;\n }\n\n return this.options.gesture;\n },\n\n /*\\\n * Interactable.autoScroll\n [ method ]\n **\n * Deprecated. Add an `autoscroll` property to the options object\n * passed to @Interactable.draggable or @Interactable.resizable instead.\n *\n * Returns or sets whether dragging and resizing near the edges of the\n * window/container trigger autoScroll for this Interactable\n *\n = (object) Object with autoScroll properties\n *\n * or\n *\n - options (object | boolean) #optional\n * options can be:\n * - an object with margin, distance and interval properties,\n * - true or false to enable or disable autoScroll or\n = (Interactable) this Interactable\n \\*/\n autoScroll: function (options) {\n if (isObject(options)) {\n options = extend({ actions: ['drag', 'resize']}, options);\n }\n else if (isBool(options)) {\n options = { actions: ['drag', 'resize'], enabled: options };\n }\n\n return this.setOptions('autoScroll', options);\n },\n\n /*\\\n * Interactable.snap\n [ method ]\n **\n * Deprecated. Add a `snap` property to the options object passed\n * to @Interactable.draggable or @Interactable.resizable instead.\n *\n * Returns or sets if and how action coordinates are snapped. By\n * default, snapping is relative to the pointer coordinates. You can\n * change this by setting the\n * [`elementOrigin`](https://github.com/taye/interact.js/pull/72).\n **\n = (boolean | object) `false` if snap is disabled; object with snap properties if snap is enabled\n **\n * or\n **\n - options (object | boolean | null) #optional\n = (Interactable) this Interactable\n > Usage\n | interact(document.querySelector('#thing')).snap({\n | targets: [\n | // snap to this specific point\n | {\n | x: 100,\n | y: 100,\n | range: 25\n | },\n | // give this function the x and y page coords and snap to the object returned\n | function (x, y) {\n | return {\n | x: x,\n | y: (75 + 50 * Math.sin(x * 0.04)),\n | range: 40\n | };\n | },\n | // create a function that snaps to a grid\n | interact.createSnapGrid({\n | x: 50,\n | y: 50,\n | range: 10, // optional\n | offset: { x: 5, y: 10 } // optional\n | })\n | ],\n | // do not snap during normal movement.\n | // Instead, trigger only one snapped move event\n | // immediately before the end event.\n | endOnly: true,\n |\n | relativePoints: [\n | { x: 0, y: 0 }, // snap relative to the top left of the element\n | { x: 1, y: 1 }, // and also to the bottom right\n | ], \n |\n | // offset the snap target coordinates\n | // can be an object with x/y or 'startCoords'\n | offset: { x: 50, y: 50 }\n | }\n | });\n \\*/\n snap: function (options) {\n var ret = this.setOptions('snap', options);\n\n if (ret === this) { return this; }\n\n return ret.drag;\n },\n\n setOptions: function (option, options) {\n var actions = options && isArray(options.actions)\n ? options.actions\n : ['drag'];\n\n var i;\n\n if (isObject(options) || isBool(options)) {\n for (i = 0; i < actions.length; i++) {\n var action = /resize/.test(actions[i])? 'resize' : actions[i];\n\n if (!isObject(this.options[action])) { continue; }\n\n var thisOption = this.options[action][option];\n\n if (isObject(options)) {\n extend(thisOption, options);\n thisOption.enabled = options.enabled === false? false: true;\n\n if (option === 'snap') {\n if (thisOption.mode === 'grid') {\n thisOption.targets = [\n interact.createSnapGrid(extend({\n offset: thisOption.gridOffset || { x: 0, y: 0 }\n }, thisOption.grid || {}))\n ];\n }\n else if (thisOption.mode === 'anchor') {\n thisOption.targets = thisOption.anchors;\n }\n else if (thisOption.mode === 'path') {\n thisOption.targets = thisOption.paths;\n }\n\n if ('elementOrigin' in options) {\n thisOption.relativePoints = [options.elementOrigin];\n }\n }\n }\n else if (isBool(options)) {\n thisOption.enabled = options;\n }\n }\n\n return this;\n }\n\n var ret = {},\n allActions = ['drag', 'resize', 'gesture'];\n\n for (i = 0; i < allActions.length; i++) {\n if (option in defaultOptions[allActions[i]]) {\n ret[allActions[i]] = this.options[allActions[i]][option];\n }\n }\n\n return ret;\n },\n\n\n /*\\\n * Interactable.inertia\n [ method ]\n **\n * Deprecated. Add an `inertia` property to the options object passed\n * to @Interactable.draggable or @Interactable.resizable instead.\n *\n * Returns or sets if and how events continue to run after the pointer is released\n **\n = (boolean | object) `false` if inertia is disabled; `object` with inertia properties if inertia is enabled\n **\n * or\n **\n - options (object | boolean | null) #optional\n = (Interactable) this Interactable\n > Usage\n | // enable and use default settings\n | interact(element).inertia(true);\n |\n | // enable and use custom settings\n | interact(element).inertia({\n | // value greater than 0\n | // high values slow the object down more quickly\n | resistance : 16,\n |\n | // the minimum launch speed (pixels per second) that results in inertia start\n | minSpeed : 200,\n |\n | // inertia will stop when the object slows down to this speed\n | endSpeed : 20,\n |\n | // boolean; should actions be resumed when the pointer goes down during inertia\n | allowResume : true,\n |\n | // boolean; should the jump when resuming from inertia be ignored in event.dx/dy\n | zeroResumeDelta: false,\n |\n | // if snap/restrict are set to be endOnly and inertia is enabled, releasing\n | // the pointer without triggering inertia will animate from the release\n | // point to the snaped/restricted point in the given amount of time (ms)\n | smoothEndDuration: 300,\n |\n | // an array of action types that can have inertia (no gesture)\n | actions : ['drag', 'resize']\n | });\n |\n | // reset custom settings and use all defaults\n | interact(element).inertia(null);\n \\*/\n inertia: function (options) {\n var ret = this.setOptions('inertia', options);\n\n if (ret === this) { return this; }\n\n return ret.drag;\n },\n\n getAction: function (pointer, event, interaction, element) {\n var action = this.defaultActionChecker(pointer, interaction, element);\n\n if (this.options.actionChecker) {\n return this.options.actionChecker(pointer, event, action, this, element, interaction);\n }\n\n return action;\n },\n\n defaultActionChecker: defaultActionChecker,\n\n /*\\\n * Interactable.actionChecker\n [ method ]\n *\n * Gets or sets the function used to check action to be performed on\n * pointerDown\n *\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.\n = (Function | Interactable) The checker function or this Interactable\n *\n | interact('.resize-drag')\n | .resizable(true)\n | .draggable(true)\n | .actionChecker(function (pointer, event, action, interactable, element, interaction) {\n |\n | if (interact.matchesSelector(event.target, '.drag-handle') {\n | // force drag with handle target\n | action.name = drag;\n | }\n | else {\n | // resize from the top and right edges\n | action.name = 'resize';\n | action.edges = { top: true, right: true };\n | }\n |\n | return action;\n | });\n \\*/\n actionChecker: function (checker) {\n if (isFunction(checker)) {\n this.options.actionChecker = checker;\n\n return this;\n }\n\n if (checker === null) {\n delete this.options.actionChecker;\n\n return this;\n }\n\n return this.options.actionChecker;\n },\n\n /*\\\n * Interactable.getRect\n [ method ]\n *\n * The default function to get an Interactables bounding rect. Can be\n * overridden using @Interactable.rectChecker.\n *\n - element (Element) #optional The element to measure.\n = (object) The object's bounding rectangle.\n o {\n o top : 0,\n o left : 0,\n o bottom: 0,\n o right : 0,\n o width : 0,\n o height: 0\n o }\n \\*/\n getRect: function rectCheck (element) {\n element = element || this._element;\n\n if (this.selector && !(isElement(element))) {\n element = this._context.querySelector(this.selector);\n }\n\n return getElementRect(element);\n },\n\n /*\\\n * Interactable.rectChecker\n [ method ]\n *\n * Returns or sets the function used to calculate the interactable's\n * element's rectangle\n *\n - checker (function) #optional A function which returns this Interactable's bounding rectangle. See @Interactable.getRect\n = (function | object) The checker function or this Interactable\n \\*/\n rectChecker: function (checker) {\n if (isFunction(checker)) {\n this.getRect = checker;\n\n return this;\n }\n\n if (checker === null) {\n delete this.options.getRect;\n\n return this;\n }\n\n return this.getRect;\n },\n\n /*\\\n * Interactable.styleCursor\n [ method ]\n *\n * Returns or sets whether the action that would be performed when the\n * mouse on the element are checked on `mousemove` so that the cursor\n * may be styled appropriately\n *\n - newValue (boolean) #optional\n = (boolean | Interactable) The current setting or this Interactable\n \\*/\n styleCursor: function (newValue) {\n if (isBool(newValue)) {\n this.options.styleCursor = newValue;\n\n return this;\n }\n\n if (newValue === null) {\n delete this.options.styleCursor;\n\n return this;\n }\n\n return this.options.styleCursor;\n },\n\n /*\\\n * Interactable.preventDefault\n [ method ]\n *\n * Returns or sets whether to prevent the browser's default behaviour\n * in response to pointer events. Can be set to:\n * - `'always'` to always prevent\n * - `'never'` to never prevent\n * - `'auto'` to let interact.js try to determine what would be best\n *\n - newValue (string) #optional `true`, `false` or `'auto'`\n = (string | Interactable) The current setting or this Interactable\n \\*/\n preventDefault: function (newValue) {\n if (/^(always|never|auto)$/.test(newValue)) {\n this.options.preventDefault = newValue;\n return this;\n }\n\n if (isBool(newValue)) {\n this.options.preventDefault = newValue? 'always' : 'never';\n return this;\n }\n\n return this.options.preventDefault;\n },\n\n /*\\\n * Interactable.origin\n [ method ]\n *\n * Gets or sets the origin of the Interactable's element. The x and y\n * of the origin will be subtracted from action event coordinates.\n *\n - origin (object | string) #optional An object eg. { x: 0, y: 0 } or string 'parent', 'self' or any CSS selector\n * OR\n - origin (Element) #optional An HTML or SVG Element whose rect will be used\n **\n = (object) The current origin or this Interactable\n \\*/\n origin: function (newValue) {\n if (trySelector(newValue)) {\n this.options.origin = newValue;\n return this;\n }\n else if (isObject(newValue)) {\n this.options.origin = newValue;\n return this;\n }\n\n return this.options.origin;\n },\n\n /*\\\n * Interactable.deltaSource\n [ method ]\n *\n * Returns or sets the mouse coordinate types used to calculate the\n * movement of the pointer.\n *\n - newValue (string) #optional Use 'client' if you will be scrolling while interacting; Use 'page' if you want autoScroll to work\n = (string | object) The current deltaSource or this Interactable\n \\*/\n deltaSource: function (newValue) {\n if (newValue === 'page' || newValue === 'client') {\n this.options.deltaSource = newValue;\n\n return this;\n }\n\n return this.options.deltaSource;\n },\n\n /*\\\n * Interactable.restrict\n [ method ]\n **\n * Deprecated. Add a `restrict` property to the options object passed to\n * @Interactable.draggable, @Interactable.resizable or @Interactable.gesturable instead.\n *\n * Returns or sets the rectangles within which actions on this\n * interactable (after snap calculations) are restricted. By default,\n * restricting is relative to the pointer coordinates. You can change\n * this by setting the\n * [`elementRect`](https://github.com/taye/interact.js/pull/72).\n **\n - options (object) #optional an object with keys drag, resize, and/or gesture whose values are rects, Elements, CSS selectors, or 'parent' or 'self'\n = (object) The current restrictions object or this Interactable\n **\n | interact(element).restrict({\n | // the rect will be `interact.getElementRect(element.parentNode)`\n | drag: element.parentNode,\n |\n | // x and y are relative to the the interactable's origin\n | resize: { x: 100, y: 100, width: 200, height: 200 }\n | })\n |\n | interact('.draggable').restrict({\n | // the rect will be the selected element's parent\n | drag: 'parent',\n |\n | // do not restrict during normal movement.\n | // Instead, trigger only one restricted move event\n | // immediately before the end event.\n | endOnly: true,\n |\n | // https://github.com/taye/interact.js/pull/72#issue-41813493\n | elementRect: { top: 0, left: 0, bottom: 1, right: 1 }\n | });\n \\*/\n restrict: function (options) {\n if (!isObject(options)) {\n return this.setOptions('restrict', options);\n }\n\n var actions = ['drag', 'resize', 'gesture'],\n ret;\n\n for (var i = 0; i < actions.length; i++) {\n var action = actions[i];\n\n if (action in options) {\n var perAction = extend({\n actions: [action],\n restriction: options[action]\n }, options);\n\n ret = this.setOptions('restrict', perAction);\n }\n }\n\n return ret;\n },\n\n /*\\\n * Interactable.context\n [ method ]\n *\n * Gets the selector context Node of the Interactable. The default is `window.document`.\n *\n = (Node) The context Node of this Interactable\n **\n \\*/\n context: function () {\n return this._context;\n },\n\n _context: document,\n\n /*\\\n * Interactable.ignoreFrom\n [ method ]\n *\n * If the target of the `mousedown`, `pointerdown` or `touchstart`\n * event or any of it's parents match the given CSS selector or\n * Element, no drag/resize/gesture is started.\n *\n - newValue (string | Element | null) #optional a CSS selector string, an Element or `null` to not ignore any elements\n = (string | Element | object) The current ignoreFrom value or this Interactable\n **\n | interact(element, { ignoreFrom: document.getElementById('no-action') });\n | // or\n | interact(element).ignoreFrom('input, textarea, a');\n \\*/\n ignoreFrom: function (newValue) {\n if (trySelector(newValue)) { // CSS selector to match event.target\n this.options.ignoreFrom = newValue;\n return this;\n }\n\n if (isElement(newValue)) { // specific element\n this.options.ignoreFrom = newValue;\n return this;\n }\n\n return this.options.ignoreFrom;\n },\n\n /*\\\n * Interactable.allowFrom\n [ method ]\n *\n * A drag/resize/gesture is started only If the target of the\n * `mousedown`, `pointerdown` or `touchstart` event or any of it's\n * parents match the given CSS selector or Element.\n *\n - newValue (string | Element | null) #optional a CSS selector string, an Element or `null` to allow from any element\n = (string | Element | object) The current allowFrom value or this Interactable\n **\n | interact(element, { allowFrom: document.getElementById('drag-handle') });\n | // or\n | interact(element).allowFrom('.handle');\n \\*/\n allowFrom: function (newValue) {\n if (trySelector(newValue)) { // CSS selector to match event.target\n this.options.allowFrom = newValue;\n return this;\n }\n\n if (isElement(newValue)) { // specific element\n this.options.allowFrom = newValue;\n return this;\n }\n\n return this.options.allowFrom;\n },\n\n /*\\\n * Interactable.element\n [ method ]\n *\n * If this is not a selector Interactable, it returns the element this\n * interactable represents\n *\n = (Element) HTML / SVG Element\n \\*/\n element: function () {\n return this._element;\n },\n\n /*\\\n * Interactable.fire\n [ method ]\n *\n * Calls listeners for the given InteractEvent type bound globally\n * and directly to this Interactable\n *\n - iEvent (InteractEvent) The InteractEvent object to be fired on this Interactable\n = (Interactable) this Interactable\n \\*/\n fire: function (iEvent) {\n if (!(iEvent && iEvent.type) || !contains(eventTypes, iEvent.type)) {\n return this;\n }\n\n var listeners,\n i,\n len,\n onEvent = 'on' + iEvent.type,\n funcName = '';\n\n // Interactable#on() listeners\n if (iEvent.type in this._iEvents) {\n listeners = this._iEvents[iEvent.type];\n\n for (i = 0, len = listeners.length; i < len && !iEvent.immediatePropagationStopped; i++) {\n funcName = listeners[i].name;\n listeners[i](iEvent);\n }\n }\n\n // interactable.onevent listener\n if (isFunction(this[onEvent])) {\n funcName = this[onEvent].name;\n this[onEvent](iEvent);\n }\n\n // interact.on() listeners\n if (iEvent.type in globalEvents && (listeners = globalEvents[iEvent.type])) {\n\n for (i = 0, len = listeners.length; i < len && !iEvent.immediatePropagationStopped; i++) {\n funcName = listeners[i].name;\n listeners[i](iEvent);\n }\n }\n\n return this;\n },\n\n /*\\\n * Interactable.on\n [ method ]\n *\n * Binds a listener for an InteractEvent or DOM event.\n *\n - eventType (string | array | object) The types of events to listen for\n - listener (function) The function to be called on the given event(s)\n - useCapture (boolean) #optional useCapture flag for addEventListener\n = (object) This Interactable\n \\*/\n on: function (eventType, listener, useCapture) {\n var i;\n\n if (isString(eventType) && eventType.search(' ') !== -1) {\n eventType = eventType.trim().split(/ +/);\n }\n\n if (isArray(eventType)) {\n for (i = 0; i < eventType.length; i++) {\n this.on(eventType[i], listener, useCapture);\n }\n\n return this;\n }\n\n if (isObject(eventType)) {\n for (var prop in eventType) {\n this.on(prop, eventType[prop], listener);\n }\n\n return this;\n }\n\n if (eventType === 'wheel') {\n eventType = wheelEvent;\n }\n\n // convert to boolean\n useCapture = useCapture? true: false;\n\n if (contains(eventTypes, eventType)) {\n // if this type of event was never bound to this Interactable\n if (!(eventType in this._iEvents)) {\n this._iEvents[eventType] = [listener];\n }\n else {\n this._iEvents[eventType].push(listener);\n }\n }\n // delegated event for selector\n else if (this.selector) {\n if (!delegatedEvents[eventType]) {\n delegatedEvents[eventType] = {\n selectors: [],\n contexts : [],\n listeners: []\n };\n\n // add delegate listener functions\n for (i = 0; i < documents.length; i++) {\n events.add(documents[i], eventType, delegateListener);\n events.add(documents[i], eventType, delegateUseCapture, true);\n }\n }\n\n var delegated = delegatedEvents[eventType],\n index;\n\n for (index = delegated.selectors.length - 1; index >= 0; index--) {\n if (delegated.selectors[index] === this.selector\n && delegated.contexts[index] === this._context) {\n break;\n }\n }\n\n if (index === -1) {\n index = delegated.selectors.length;\n\n delegated.selectors.push(this.selector);\n delegated.contexts .push(this._context);\n delegated.listeners.push([]);\n }\n\n // keep listener and useCapture flag\n delegated.listeners[index].push([listener, useCapture]);\n }\n else {\n events.add(this._element, eventType, listener, useCapture);\n }\n\n return this;\n },\n\n /*\\\n * Interactable.off\n [ method ]\n *\n * Removes an InteractEvent or DOM event listener\n *\n - eventType (string | array | object) The types of events that were listened for\n - listener (function) The listener function to be removed\n - useCapture (boolean) #optional useCapture flag for removeEventListener\n = (object) This Interactable\n \\*/\n off: function (eventType, listener, useCapture) {\n var i;\n\n if (isString(eventType) && eventType.search(' ') !== -1) {\n eventType = eventType.trim().split(/ +/);\n }\n\n if (isArray(eventType)) {\n for (i = 0; i < eventType.length; i++) {\n this.off(eventType[i], listener, useCapture);\n }\n\n return this;\n }\n\n if (isObject(eventType)) {\n for (var prop in eventType) {\n this.off(prop, eventType[prop], listener);\n }\n\n return this;\n }\n\n var eventList,\n index = -1;\n\n // convert to boolean\n useCapture = useCapture? true: false;\n\n if (eventType === 'wheel') {\n eventType = wheelEvent;\n }\n\n // if it is an action event type\n if (contains(eventTypes, eventType)) {\n eventList = this._iEvents[eventType];\n\n if (eventList && (index = indexOf(eventList, listener)) !== -1) {\n this._iEvents[eventType].splice(index, 1);\n }\n }\n // delegated event\n else if (this.selector) {\n var delegated = delegatedEvents[eventType],\n matchFound = false;\n\n if (!delegated) { return this; }\n\n // count from last index of delegated to 0\n for (index = delegated.selectors.length - 1; index >= 0; index--) {\n // look for matching selector and context Node\n if (delegated.selectors[index] === this.selector\n && delegated.contexts[index] === this._context) {\n\n var listeners = delegated.listeners[index];\n\n // each item of the listeners array is an array: [function, useCaptureFlag]\n for (i = listeners.length - 1; i >= 0; i--) {\n var fn = listeners[i][0],\n useCap = listeners[i][1];\n\n // check if the listener functions and useCapture flags match\n if (fn === listener && useCap === useCapture) {\n // remove the listener from the array of listeners\n listeners.splice(i, 1);\n\n // if all listeners for this interactable have been removed\n // remove the interactable from the delegated arrays\n if (!listeners.length) {\n delegated.selectors.splice(index, 1);\n delegated.contexts .splice(index, 1);\n delegated.listeners.splice(index, 1);\n\n // remove delegate function from context\n events.remove(this._context, eventType, delegateListener);\n events.remove(this._context, eventType, delegateUseCapture, true);\n\n // remove the arrays if they are empty\n if (!delegated.selectors.length) {\n delegatedEvents[eventType] = null;\n }\n }\n\n // only remove one listener\n matchFound = true;\n break;\n }\n }\n\n if (matchFound) { break; }\n }\n }\n }\n // remove listener from this Interatable's element\n else {\n events.remove(this._element, eventType, listener, useCapture);\n }\n\n return this;\n },\n\n /*\\\n * Interactable.set\n [ method ]\n *\n * Reset the options of this Interactable\n - options (object) The new settings to apply\n = (object) This Interactable\n \\*/\n set: function (options) {\n if (!isObject(options)) {\n options = {};\n }\n\n this.options = extend({}, defaultOptions.base);\n\n var i,\n actions = ['drag', 'drop', 'resize', 'gesture'],\n methods = ['draggable', 'dropzone', 'resizable', 'gesturable'],\n perActions = extend(extend({}, defaultOptions.perAction), options[action] || {});\n\n for (i = 0; i < actions.length; i++) {\n var action = actions[i];\n\n this.options[action] = extend({}, defaultOptions[action]);\n\n this.setPerAction(action, perActions);\n\n this[methods[i]](options[action]);\n }\n\n var settings = [\n 'accept', 'actionChecker', 'allowFrom', 'deltaSource',\n 'dropChecker', 'ignoreFrom', 'origin', 'preventDefault',\n 'rectChecker', 'styleCursor'\n ];\n\n for (i = 0, len = settings.length; i < len; i++) {\n var setting = settings[i];\n\n this.options[setting] = defaultOptions.base[setting];\n\n if (setting in options) {\n this[setting](options[setting]);\n }\n }\n\n return this;\n },\n\n /*\\\n * Interactable.unset\n [ method ]\n *\n * Remove this interactable from the list of interactables and remove\n * it's drag, drop, resize and gesture capabilities\n *\n = (object) @interact\n \\*/\n unset: function () {\n events.remove(this._element, 'all');\n\n if (!isString(this.selector)) {\n events.remove(this, 'all');\n if (this.options.styleCursor) {\n this._element.style.cursor = '';\n }\n }\n else {\n // remove delegated events\n for (var type in delegatedEvents) {\n var delegated = delegatedEvents[type];\n\n for (var i = 0; i < delegated.selectors.length; i++) {\n if (delegated.selectors[i] === this.selector\n && delegated.contexts[i] === this._context) {\n\n delegated.selectors.splice(i, 1);\n delegated.contexts .splice(i, 1);\n delegated.listeners.splice(i, 1);\n\n // remove the arrays if they are empty\n if (!delegated.selectors.length) {\n delegatedEvents[type] = null;\n }\n }\n\n events.remove(this._context, type, delegateListener);\n events.remove(this._context, type, delegateUseCapture, true);\n\n break;\n }\n }\n }\n\n this.dropzone(false);\n\n interactables.splice(indexOf(interactables, this), 1);\n\n return interact;\n }\n };\n\n function warnOnce (method, message) {\n var warned = false;\n\n return function () {\n if (!warned) {\n window.console.warn(message);\n warned = true;\n }\n\n return method.apply(this, arguments);\n };\n }\n\n Interactable.prototype.snap = warnOnce(Interactable.prototype.snap,\n 'Interactable#snap is deprecated. See the new documentation for snapping at http://interactjs.io/docs/snapping');\n Interactable.prototype.restrict = warnOnce(Interactable.prototype.restrict,\n 'Interactable#restrict is deprecated. See the new documentation for resticting at http://interactjs.io/docs/restriction');\n Interactable.prototype.inertia = warnOnce(Interactable.prototype.inertia,\n 'Interactable#inertia is deprecated. See the new documentation for inertia at http://interactjs.io/docs/inertia');\n Interactable.prototype.autoScroll = warnOnce(Interactable.prototype.autoScroll,\n 'Interactable#autoScroll is deprecated. See the new documentation for autoScroll at http://interactjs.io/docs/#autoscroll');\n Interactable.prototype.squareResize = warnOnce(Interactable.prototype.squareResize,\n 'Interactable#squareResize is deprecated. See http://interactjs.io/docs/#resize-square');\n\n Interactable.prototype.accept = warnOnce(Interactable.prototype.accept,\n 'Interactable#accept is deprecated. use Interactable#dropzone({ accept: target }) instead');\n Interactable.prototype.dropChecker = warnOnce(Interactable.prototype.dropChecker,\n 'Interactable#dropChecker is deprecated. use Interactable#dropzone({ dropChecker: checkerFunction }) instead');\n Interactable.prototype.context = warnOnce(Interactable.prototype.context,\n 'Interactable#context as a method is deprecated. It will soon be a DOM Node instead');\n\n /*\\\n * interact.isSet\n [ method ]\n *\n * Check if an element has been set\n - element (Element) The Element being searched for\n = (boolean) Indicates if the element or CSS selector was previously passed to interact\n \\*/\n interact.isSet = function(element, options) {\n return interactables.indexOfElement(element, options && options.context) !== -1;\n };\n\n /*\\\n * interact.on\n [ method ]\n *\n * Adds a global listener for an InteractEvent or adds a DOM event to\n * `document`\n *\n - type (string | array | object) The types of events to listen for\n - listener (function) The function to be called on the given event(s)\n - useCapture (boolean) #optional useCapture flag for addEventListener\n = (object) interact\n \\*/\n interact.on = function (type, listener, useCapture) {\n if (isString(type) && type.search(' ') !== -1) {\n type = type.trim().split(/ +/);\n }\n\n if (isArray(type)) {\n for (var i = 0; i < type.length; i++) {\n interact.on(type[i], listener, useCapture);\n }\n\n return interact;\n }\n\n if (isObject(type)) {\n for (var prop in type) {\n interact.on(prop, type[prop], listener);\n }\n\n return interact;\n }\n\n // if it is an InteractEvent type, add listener to globalEvents\n if (contains(eventTypes, type)) {\n // if this type of event was never bound\n if (!globalEvents[type]) {\n globalEvents[type] = [listener];\n }\n else {\n globalEvents[type].push(listener);\n }\n }\n // If non InteractEvent type, addEventListener to document\n else {\n events.add(document, type, listener, useCapture);\n }\n\n return interact;\n };\n\n /*\\\n * interact.off\n [ method ]\n *\n * Removes a global InteractEvent listener or DOM event from `document`\n *\n - type (string | array | object) The types of events that were listened for\n - listener (function) The listener function to be removed\n - useCapture (boolean) #optional useCapture flag for removeEventListener\n = (object) interact\n \\*/\n interact.off = function (type, listener, useCapture) {\n if (isString(type) && type.search(' ') !== -1) {\n type = type.trim().split(/ +/);\n }\n\n if (isArray(type)) {\n for (var i = 0; i < type.length; i++) {\n interact.off(type[i], listener, useCapture);\n }\n\n return interact;\n }\n\n if (isObject(type)) {\n for (var prop in type) {\n interact.off(prop, type[prop], listener);\n }\n\n return interact;\n }\n\n if (!contains(eventTypes, type)) {\n events.remove(document, type, listener, useCapture);\n }\n else {\n var index;\n\n if (type in globalEvents\n && (index = indexOf(globalEvents[type], listener)) !== -1) {\n globalEvents[type].splice(index, 1);\n }\n }\n\n return interact;\n };\n\n /*\\\n * interact.enableDragging\n [ method ]\n *\n * Deprecated.\n *\n * Returns or sets whether dragging is enabled for any Interactables\n *\n - newValue (boolean) #optional `true` to allow the action; `false` to disable action for all Interactables\n = (boolean | object) The current setting or interact\n \\*/\n interact.enableDragging = warnOnce(function (newValue) {\n if (newValue !== null && newValue !== undefined) {\n actionIsEnabled.drag = newValue;\n\n return interact;\n }\n return actionIsEnabled.drag;\n }, 'interact.enableDragging is deprecated and will soon be removed.');\n\n /*\\\n * interact.enableResizing\n [ method ]\n *\n * Deprecated.\n *\n * Returns or sets whether resizing is enabled for any Interactables\n *\n - newValue (boolean) #optional `true` to allow the action; `false` to disable action for all Interactables\n = (boolean | object) The current setting or interact\n \\*/\n interact.enableResizing = warnOnce(function (newValue) {\n if (newValue !== null && newValue !== undefined) {\n actionIsEnabled.resize = newValue;\n\n return interact;\n }\n return actionIsEnabled.resize;\n }, 'interact.enableResizing is deprecated and will soon be removed.');\n\n /*\\\n * interact.enableGesturing\n [ method ]\n *\n * Deprecated.\n *\n * Returns or sets whether gesturing is enabled for any Interactables\n *\n - newValue (boolean) #optional `true` to allow the action; `false` to disable action for all Interactables\n = (boolean | object) The current setting or interact\n \\*/\n interact.enableGesturing = warnOnce(function (newValue) {\n if (newValue !== null && newValue !== undefined) {\n actionIsEnabled.gesture = newValue;\n\n return interact;\n }\n return actionIsEnabled.gesture;\n }, 'interact.enableGesturing is deprecated and will soon be removed.');\n\n interact.eventTypes = eventTypes;\n\n /*\\\n * interact.debug\n [ method ]\n *\n * Returns debugging data\n = (object) An object with properties that outline the current state and expose internal functions and variables\n \\*/\n interact.debug = function () {\n var interaction = interactions[0] || new Interaction();\n\n return {\n interactions : interactions,\n target : interaction.target,\n dragging : interaction.dragging,\n resizing : interaction.resizing,\n gesturing : interaction.gesturing,\n prepared : interaction.prepared,\n matches : interaction.matches,\n matchElements : interaction.matchElements,\n\n prevCoords : interaction.prevCoords,\n startCoords : interaction.startCoords,\n\n pointerIds : interaction.pointerIds,\n pointers : interaction.pointers,\n addPointer : listeners.addPointer,\n removePointer : listeners.removePointer,\n recordPointer : listeners.recordPointer,\n\n snap : interaction.snapStatus,\n restrict : interaction.restrictStatus,\n inertia : interaction.inertiaStatus,\n\n downTime : interaction.downTimes[0],\n downEvent : interaction.downEvent,\n downPointer : interaction.downPointer,\n prevEvent : interaction.prevEvent,\n\n Interactable : Interactable,\n interactables : interactables,\n pointerIsDown : interaction.pointerIsDown,\n defaultOptions : defaultOptions,\n defaultActionChecker : defaultActionChecker,\n\n actionCursors : actionCursors,\n dragMove : listeners.dragMove,\n resizeMove : listeners.resizeMove,\n gestureMove : listeners.gestureMove,\n pointerUp : listeners.pointerUp,\n pointerDown : listeners.pointerDown,\n pointerMove : listeners.pointerMove,\n pointerHover : listeners.pointerHover,\n\n eventTypes : eventTypes,\n\n events : events,\n globalEvents : globalEvents,\n delegatedEvents : delegatedEvents,\n\n prefixedPropREs : prefixedPropREs\n };\n };\n\n // expose the functions used to calculate multi-touch properties\n interact.getPointerAverage = pointerAverage;\n interact.getTouchBBox = touchBBox;\n interact.getTouchDistance = touchDistance;\n interact.getTouchAngle = touchAngle;\n\n interact.getElementRect = getElementRect;\n interact.getElementClientRect = getElementClientRect;\n interact.matchesSelector = matchesSelector;\n interact.closest = closest;\n\n /*\\\n * interact.margin\n [ method ]\n *\n * Deprecated. Use `interact(target).resizable({ margin: number });` instead.\n * Returns or sets the margin for autocheck resizing used in\n * @Interactable.getAction. That is the distance from the bottom and right\n * edges of an element clicking in which will start resizing\n *\n - newValue (number) #optional\n = (number | interact) The current margin value or interact\n \\*/\n interact.margin = warnOnce(function (newvalue) {\n if (isNumber(newvalue)) {\n margin = newvalue;\n\n return interact;\n }\n return margin;\n },\n 'interact.margin is deprecated. Use interact(target).resizable({ margin: number }); instead.') ;\n\n /*\\\n * interact.supportsTouch\n [ method ]\n *\n = (boolean) Whether or not the browser supports touch input\n \\*/\n interact.supportsTouch = function () {\n return supportsTouch;\n };\n\n /*\\\n * interact.supportsPointerEvent\n [ method ]\n *\n = (boolean) Whether or not the browser supports PointerEvents\n \\*/\n interact.supportsPointerEvent = function () {\n return supportsPointerEvent;\n };\n\n /*\\\n * interact.stop\n [ method ]\n *\n * Cancels all interactions (end events are not fired)\n *\n - event (Event) An event on which to call preventDefault()\n = (object) interact\n \\*/\n interact.stop = function (event) {\n for (var i = interactions.length - 1; i >= 0; i--) {\n interactions[i].stop(event);\n }\n\n return interact;\n };\n\n /*\\\n * interact.dynamicDrop\n [ method ]\n *\n * Returns or sets whether the dimensions of dropzone elements are\n * calculated on every dragmove or only on dragstart for the default\n * dropChecker\n *\n - newValue (boolean) #optional True to check on each move. False to check only before start\n = (boolean | interact) The current setting or interact\n \\*/\n interact.dynamicDrop = function (newValue) {\n if (isBool(newValue)) {\n //if (dragging && dynamicDrop !== newValue && !newValue) {\n //calcRects(dropzones);\n //}\n\n dynamicDrop = newValue;\n\n return interact;\n }\n return dynamicDrop;\n };\n\n /*\\\n * interact.pointerMoveTolerance\n [ method ]\n * Returns or sets the distance the pointer must be moved before an action\n * sequence occurs. This also affects tolerance for tap events.\n *\n - newValue (number) #optional The movement from the start position must be greater than this value\n = (number | Interactable) The current setting or interact\n \\*/\n interact.pointerMoveTolerance = function (newValue) {\n if (isNumber(newValue)) {\n pointerMoveTolerance = newValue;\n\n return this;\n }\n\n return pointerMoveTolerance;\n };\n\n /*\\\n * interact.maxInteractions\n [ method ]\n **\n * Returns or sets the maximum number of concurrent interactions allowed.\n * By default only 1 interaction is allowed at a time (for backwards\n * compatibility). To allow multiple interactions on the same Interactables\n * and elements, you need to enable it in the draggable, resizable and\n * gesturable `'max'` and `'maxPerElement'` options.\n **\n - newValue (number) #optional Any number. newValue <= 0 means no interactions.\n \\*/\n interact.maxInteractions = function (newValue) {\n if (isNumber(newValue)) {\n maxInteractions = newValue;\n\n return this;\n }\n\n return maxInteractions;\n };\n\n interact.createSnapGrid = function (grid) {\n return function (x, y) {\n var offsetX = 0,\n offsetY = 0;\n\n if (isObject(grid.offset)) {\n offsetX = grid.offset.x;\n offsetY = grid.offset.y;\n }\n\n var gridx = Math.round((x - offsetX) / grid.x),\n gridy = Math.round((y - offsetY) / grid.y),\n\n newX = gridx * grid.x + offsetX,\n newY = gridy * grid.y + offsetY;\n\n return {\n x: newX,\n y: newY,\n range: grid.range\n };\n };\n };\n\n function endAllInteractions (event) {\n for (var i = 0; i < interactions.length; i++) {\n interactions[i].pointerEnd(event, event);\n }\n }\n\n function listenToDocument (doc) {\n if (contains(documents, doc)) { return; }\n\n var win = doc.defaultView || doc.parentWindow;\n\n // add delegate event listener\n for (var eventType in delegatedEvents) {\n events.add(doc, eventType, delegateListener);\n events.add(doc, eventType, delegateUseCapture, true);\n }\n\n if (supportsPointerEvent) {\n if (PointerEvent === win.MSPointerEvent) {\n pEventTypes = {\n up: 'MSPointerUp', down: 'MSPointerDown', over: 'mouseover',\n out: 'mouseout', move: 'MSPointerMove', cancel: 'MSPointerCancel' };\n }\n else {\n pEventTypes = {\n up: 'pointerup', down: 'pointerdown', over: 'pointerover',\n out: 'pointerout', move: 'pointermove', cancel: 'pointercancel' };\n }\n\n events.add(doc, pEventTypes.down , listeners.selectorDown );\n events.add(doc, pEventTypes.move , listeners.pointerMove );\n events.add(doc, pEventTypes.over , listeners.pointerOver );\n events.add(doc, pEventTypes.out , listeners.pointerOut );\n events.add(doc, pEventTypes.up , listeners.pointerUp );\n events.add(doc, pEventTypes.cancel, listeners.pointerCancel);\n\n // autoscroll\n events.add(doc, pEventTypes.move, listeners.autoScrollMove);\n }\n else {\n events.add(doc, 'mousedown', listeners.selectorDown);\n events.add(doc, 'mousemove', listeners.pointerMove );\n events.add(doc, 'mouseup' , listeners.pointerUp );\n events.add(doc, 'mouseover', listeners.pointerOver );\n events.add(doc, 'mouseout' , listeners.pointerOut );\n\n events.add(doc, 'touchstart' , listeners.selectorDown );\n events.add(doc, 'touchmove' , listeners.pointerMove );\n events.add(doc, 'touchend' , listeners.pointerUp );\n events.add(doc, 'touchcancel', listeners.pointerCancel);\n\n // autoscroll\n events.add(doc, 'mousemove', listeners.autoScrollMove);\n events.add(doc, 'touchmove', listeners.autoScrollMove);\n }\n\n events.add(win, 'blur', endAllInteractions);\n\n try {\n if (win.frameElement) {\n var parentDoc = win.frameElement.ownerDocument,\n parentWindow = parentDoc.defaultView;\n\n events.add(parentDoc , 'mouseup' , listeners.pointerEnd);\n events.add(parentDoc , 'touchend' , listeners.pointerEnd);\n events.add(parentDoc , 'touchcancel' , listeners.pointerEnd);\n events.add(parentDoc , 'pointerup' , listeners.pointerEnd);\n events.add(parentDoc , 'MSPointerUp' , listeners.pointerEnd);\n events.add(parentWindow, 'blur' , endAllInteractions );\n }\n }\n catch (error) {\n interact.windowParentError = error;\n }\n\n // prevent native HTML5 drag on interact.js target elements\n events.add(doc, 'dragstart', function (event) {\n for (var i = 0; i < interactions.length; i++) {\n var interaction = interactions[i];\n\n if (interaction.element\n && (interaction.element === event.target\n || nodeContains(interaction.element, event.target))) {\n\n interaction.checkAndPreventDefault(event, interaction.target, interaction.element);\n return;\n }\n }\n });\n\n if (events.useAttachEvent) {\n // For IE's lack of Event#preventDefault\n events.add(doc, 'selectstart', function (event) {\n var interaction = interactions[0];\n\n if (interaction.currentAction()) {\n interaction.checkAndPreventDefault(event);\n }\n });\n\n // For IE's bad dblclick event sequence\n events.add(doc, 'dblclick', doOnInteractions('ie8Dblclick'));\n }\n\n documents.push(doc);\n }\n\n listenToDocument(document);\n\n function indexOf (array, target) {\n for (var i = 0, len = array.length; i < len; i++) {\n if (array[i] === target) {\n return i;\n }\n }\n\n return -1;\n }\n\n function contains (array, target) {\n return indexOf(array, target) !== -1;\n }\n\n function matchesSelector (element, selector, nodeList) {\n if (ie8MatchesSelector) {\n return ie8MatchesSelector(element, selector, nodeList);\n }\n\n // remove /deep/ from selectors if shadowDOM polyfill is used\n if (window !== realWindow) {\n selector = selector.replace(/\\/deep\\//g, ' ');\n }\n\n return element[prefixedMatchesSelector](selector);\n }\n\n function matchesUpTo (element, selector, limit) {\n while (isElement(element)) {\n if (matchesSelector(element, selector)) {\n return true;\n }\n\n element = parentElement(element);\n\n if (element === limit) {\n return matchesSelector(element, selector);\n }\n }\n\n return false;\n }\n\n // For IE8's lack of an Element#matchesSelector\n // taken from http://tanalin.com/en/blog/2012/12/matches-selector-ie8/ and modified\n if (!(prefixedMatchesSelector in Element.prototype) || !isFunction(Element.prototype[prefixedMatchesSelector])) {\n ie8MatchesSelector = function (element, selector, elems) {\n elems = elems || element.parentNode.querySelectorAll(selector);\n\n for (var i = 0, len = elems.length; i < len; i++) {\n if (elems[i] === element) {\n return true;\n }\n }\n\n return false;\n };\n }\n\n // requestAnimationFrame polyfill\n (function() {\n var lastTime = 0,\n vendors = ['ms', 'moz', 'webkit', 'o'];\n\n for(var x = 0; x < vendors.length && !realWindow.requestAnimationFrame; ++x) {\n reqFrame = realWindow[vendors[x]+'RequestAnimationFrame'];\n cancelFrame = realWindow[vendors[x]+'CancelAnimationFrame'] || realWindow[vendors[x]+'CancelRequestAnimationFrame'];\n }\n\n if (!reqFrame) {\n reqFrame = function(callback) {\n var currTime = new Date().getTime(),\n timeToCall = Math.max(0, 16 - (currTime - lastTime)),\n id = setTimeout(function() { callback(currTime + timeToCall); },\n timeToCall);\n lastTime = currTime + timeToCall;\n return id;\n };\n }\n\n if (!cancelFrame) {\n cancelFrame = function(id) {\n clearTimeout(id);\n };\n }\n }());\n\n /* global exports: true, module, define */\n\n // http://documentcloud.github.io/underscore/docs/underscore.html#section-11\n if (typeof exports !== 'undefined') {\n if (typeof module !== 'undefined' && module.exports) {\n exports = module.exports = interact;\n }\n exports.interact = interact;\n }\n // AMD\n else if (typeof define === 'function' && define.amd) {\n define('interact', function() {\n return interact;\n });\n }\n else {\n realWindow.interact = interact;\n }\n\n} (typeof window === 'undefined'? undefined : window));\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/interact.js/interact.js\n// module id = 28\n// module chunks = 0","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-layout\",\n style: (_vm.mergedStyle)\n }, [_vm._t(\"default\"), _vm._v(\" \"), _c('grid-item', {\n directives: [{\n name: \"show\",\n rawName: \"v-show\",\n value: (_vm.isDragging),\n expression: \"isDragging\"\n }],\n staticClass: \"vue-grid-placeholder\",\n attrs: {\n \"x\": _vm.placeholder.x,\n \"y\": _vm.placeholder.y,\n \"w\": _vm.placeholder.w,\n \"h\": _vm.placeholder.h,\n \"i\": _vm.placeholder.i\n }\n })], 2)\n},staticRenderFns: []}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/vue-loader/lib/template-compiler.js?id=data-v-66d6d8cb!./~/vue-loader/lib/selector.js?type=template&index=0!./src/GridLayout.vue\n// module id = 29\n// module chunks = 0","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-layout\",\n style: (_vm.mergedStyle)\n }, [_vm._t(\"default\")], 2)\n},staticRenderFns: []}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/vue-loader/lib/template-compiler.js?id=data-v-6d0d2fdf!./~/vue-loader/lib/selector.js?type=template&index=0!./src/ResponsiveGridLayout.vue\n// module id = 30\n// module chunks = 0","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.isResizable, 'resizing': _vm.isResizing, 'vue-draggable-dragging': _vm.isDragging, 'cssTransforms': _vm.useCssTransforms\n },\n style: (_vm.style)\n }, [_vm._t(\"default\"), _vm._v(\" \"), (_vm.isResizable) ? _c('span', {\n ref: \"handle\",\n class: _vm.resizableHandleClass\n }) : _vm._e()], 2)\n},staticRenderFns: []}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/vue-loader/lib/template-compiler.js?id=data-v-e800ab18!./~/vue-loader/lib/selector.js?type=template&index=0!./src/GridItem.vue\n// module id = 31\n// module chunks = 0","// 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.umd.min.js b/dist/vue-grid-layout.umd.min.js new file mode 100644 index 00000000..5c785db8 --- /dev/null +++ b/dist/vue-grid-layout.umd.min.js @@ -0,0 +1,3 @@ +/*! vue-grid-layout - 2.4.0 | (c) 2015, 2022 Gustavo Santos (JBay Solutions) (http://www.jbaysolutions.com) | https://github.com/jbaysolutions/vue-grid-layout */ +(function(t,e){"object"===typeof exports&&"object"===typeof module?module.exports=e(require("vue")):"function"===typeof define&&define.amd?define([],e):"object"===typeof exports?exports["VueGridLayout"]=e(require("vue")):t["VueGridLayout"]=e(t["Vue"])})("undefined"!==typeof self?self:this,(function(t){return function(t){var e={};function n(i){if(e[i])return e[i].exports;var r=e[i]={i:i,l:!1,exports:{}};return t[i].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=t,n.c=e,n.d=function(t,e,i){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},n.r=function(t){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"===typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var r in t)n.d(i,r,function(e){return t[e]}.bind(null,r));return i},n.n=function(t){var e=t&&t.__esModule?function(){return t["default"]}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s="fb15")}({"01f9":function(t,e,n){"use strict";var i=n("2d00"),r=n("5ca1"),o=n("2aba"),s=n("32e9"),a=n("84f2"),c=n("41a0"),l=n("7f20"),u=n("38fd"),h=n("2b4c")("iterator"),d=!([].keys&&"next"in[].keys()),f="@@iterator",p="keys",g="values",m=function(){return this};t.exports=function(t,e,n,v,b,y,x){c(n,e,v);var w,S,E,O=function(t){if(!d&&t in _)return _[t];switch(t){case p:return function(){return new n(this,t)};case g:return function(){return new n(this,t)}}return function(){return new n(this,t)}},T=e+" Iterator",z=b==g,M=!1,_=t.prototype,P=_[h]||_[f]||b&&_[b],I=P||O(b),j=b?z?O("entries"):I:void 0,D="Array"==e&&_.entries||P;if(D&&(E=u(D.call(new t)),E!==Object.prototype&&E.next&&(l(E,T,!0),i||"function"==typeof E[h]||s(E,h,m))),z&&P&&P.name!==g&&(M=!0,I=function(){return P.call(this)}),i&&!x||!d&&!M&&_[h]||s(_,h,I),a[e]=I,a[T]=m,b)if(w={values:z?I:O(g),keys:y?I:O(p),entries:j},x)for(S in w)S in _||o(_,S,w[S]);else r(r.P+r.F*(d||M),e,w);return w}},"02f4":function(t,e,n){var i=n("4588"),r=n("be13");t.exports=function(t){return function(e,n){var o,s,a=String(r(e)),c=i(n),l=a.length;return c<0||c>=l?t?"":void 0:(o=a.charCodeAt(c),o<55296||o>56319||c+1===l||(s=a.charCodeAt(c+1))<56320||s>57343?t?a.charAt(c):o:t?a.slice(c,c+2):s-56320+(o-55296<<10)+65536)}}},"0390":function(t,e,n){"use strict";var i=n("02f4")(!0);t.exports=function(t,e,n){return e+(n?i(t,e).length:1)}},"0bfb":function(t,e,n){"use strict";var i=n("cb7c");t.exports=function(){var t=i(this),e="";return t.global&&(e+="g"),t.ignoreCase&&(e+="i"),t.multiline&&(e+="m"),t.unicode&&(e+="u"),t.sticky&&(e+="y"),e}},"0d58":function(t,e,n){var i=n("ce10"),r=n("e11e");t.exports=Object.keys||function(t){return i(t,r)}},1156:function(t,e,n){var i=n("ad20");"string"===typeof i&&(i=[[t.i,i,""]]),i.locals&&(t.exports=i.locals);var r=n("499e").default;r("c1ec597e",i,!0,{sourceMap:!1,shadowMode:!1})},"11e9":function(t,e,n){var i=n("52a7"),r=n("4630"),o=n("6821"),s=n("6a99"),a=n("69a8"),c=n("c69a"),l=Object.getOwnPropertyDescriptor;e.f=n("9e1e")?l:function(t,e){if(t=o(t),e=s(e,!0),c)try{return l(t,e)}catch(n){}if(a(t,e))return r(!i.f.call(t,e),t[e])}},1495:function(t,e,n){var i=n("86cc"),r=n("cb7c"),o=n("0d58");t.exports=n("9e1e")?Object.defineProperties:function(t,e){r(t);var n,s=o(e),a=s.length,c=0;while(a>c)i.f(t,n=s[c++],e[n]);return t}},"18d2":function(t,e,n){"use strict";var i=n("18e9");t.exports=function(t){t=t||{};var e=t.reporter,n=t.batchProcessor,r=t.stateHandler.getState;if(!e)throw new Error("Missing required dependency: reporter.");function o(t,e){function n(){e(t)}if(i.isIE(8))r(t).object={proxy:n},t.attachEvent("onresize",n);else{var o=c(t);if(!o)throw new Error("Element is not detectable by this strategy.");o.contentDocument.defaultView.addEventListener("resize",n)}}function s(e){var n=t.important?" !important; ":"; ";return(e.join(n)+n).trim()}function a(t,o,a){a||(a=o,o=t,t=null),t=t||{};t.debug;function c(o,a){var c=s(["display: block","position: absolute","top: 0","left: 0","width: 100%","height: 100%","border: none","padding: 0","margin: 0","opacity: 0","z-index: -1000","pointer-events: none"]),l=!1,u=window.getComputedStyle(o),h=o.offsetWidth,d=o.offsetHeight;function f(){function n(){if("static"===u.position){o.style.setProperty("position","relative",t.important?"important":"");var n=function(e,n,i,r){function o(t){return t.replace(/[^-\d\.]/g,"")}var s=i[r];"auto"!==s&&"0"!==o(s)&&(e.warn("An element that is positioned static has style."+r+"="+s+" which is ignored due to the static positioning. The element will need to be positioned relative, so the style."+r+" will be set to 0. Element: ",n),n.style.setProperty(r,"0",t.important?"important":""))};n(e,o,u,"top"),n(e,o,u,"right"),n(e,o,u,"bottom"),n(e,o,u,"left")}}function s(){function t(e,n){if(!e.contentDocument){var i=r(e);return i.checkForObjectDocumentTimeoutId&&window.clearTimeout(i.checkForObjectDocumentTimeoutId),void(i.checkForObjectDocumentTimeoutId=setTimeout((function(){i.checkForObjectDocumentTimeoutId=0,t(e,n)}),100))}n(e.contentDocument)}l||n();var e=this;t(e,(function(t){a(o)}))}""!==u.position&&(n(u),l=!0);var h=document.createElement("object");h.style.cssText=c,h.tabIndex=-1,h.type="text/html",h.setAttribute("aria-hidden","true"),h.onload=s,i.isIE()||(h.data="about:blank"),r(o)&&(o.appendChild(h),r(o).object=h,i.isIE()&&(h.data="about:blank"))}r(o).startSize={width:h,height:d},n?n.add(f):f()}i.isIE(8)?a(o):c(o,a)}function c(t){return r(t).object}function l(t){if(r(t)){var e=c(t);e&&(i.isIE(8)?t.detachEvent("onresize",e.proxy):t.removeChild(e),r(t).checkForObjectDocumentTimeoutId&&window.clearTimeout(r(t).checkForObjectDocumentTimeoutId),delete r(t).object)}}return{makeDetectable:a,addListener:o,uninstall:l}}},"18e9":function(t,e,n){"use strict";var i=t.exports={};i.isIE=function(t){function e(){var t=navigator.userAgent.toLowerCase();return-1!==t.indexOf("msie")||-1!==t.indexOf("trident")||-1!==t.indexOf(" edge/")}if(!e())return!1;if(!t)return!0;var n=function(){var t,e=3,n=document.createElement("div"),i=n.getElementsByTagName("i");do{n.innerHTML="\x3c!--[if gt IE "+ ++e+"]>4?e:t}();return t===n},i.isLegacyOpera=function(){return!!window.opera}},"1ca7":function(t,e,n){"use strict";n.d(e,"b",(function(){return s})),n.d(e,"a",(function(){return a})),n.d(e,"c",(function(){return c}));var i="auto";function r(){return"undefined"!==typeof document}function o(){return"undefined"!==typeof window}function s(){if(!r())return i;var t="undefined"!==typeof document.dir?document.dir:document.getElementsByTagName("html")[0].getAttribute("dir");return t}function a(t,e){o?window.addEventListener(t,e):e()}function c(t,e){o&&window.removeEventListener(t,e)}},"214f":function(t,e,n){"use strict";n("b0c5");var i=n("2aba"),r=n("32e9"),o=n("79e5"),s=n("be13"),a=n("2b4c"),c=n("520a"),l=a("species"),u=!o((function(){var t=/./;return t.exec=function(){var t=[];return t.groups={a:"7"},t},"7"!=="".replace(t,"$")})),h=function(){var t=/(?:)/,e=t.exec;t.exec=function(){return e.apply(this,arguments)};var n="ab".split(t);return 2===n.length&&"a"===n[0]&&"b"===n[1]}();t.exports=function(t,e,n){var d=a(t),f=!o((function(){var e={};return e[d]=function(){return 7},7!=""[t](e)})),p=f?!o((function(){var e=!1,n=/a/;return n.exec=function(){return e=!0,null},"split"===t&&(n.constructor={},n.constructor[l]=function(){return n}),n[d](""),!e})):void 0;if(!f||!p||"replace"===t&&!u||"split"===t&&!h){var g=/./[d],m=n(s,d,""[t],(function(t,e,n,i,r){return e.exec===c?f&&!r?{done:!0,value:g.call(e,n,i)}:{done:!0,value:t.call(n,e,i)}:{done:!1}})),v=m[0],b=m[1];i(String.prototype,t,v),r(RegExp.prototype,d,2==e?function(t,e){return b.call(t,this,e)}:function(t){return b.call(t,this)})}}},"230e":function(t,e,n){var i=n("d3f4"),r=n("7726").document,o=i(r)&&i(r.createElement);t.exports=function(t){return o?r.createElement(t):{}}},2350:function(t,e){function n(t,e){var n=t[1]||"",r=t[3];if(!r)return n;if(e&&"function"===typeof btoa){var o=i(r),s=r.sources.map((function(t){return"/*# sourceURL="+r.sourceRoot+t+" */"}));return[n].concat(s).concat([o]).join("\n")}return[n].join("\n")}function i(t){var e=btoa(unescape(encodeURIComponent(JSON.stringify(t)))),n="sourceMappingURL=data:application/json;charset=utf-8;base64,"+e;return"/*# "+n+" */"}t.exports=function(t){var e=[];return e.toString=function(){return this.map((function(e){var i=n(e,t);return e[2]?"@media "+e[2]+"{"+i+"}":i})).join("")},e.i=function(t,n){"string"===typeof t&&(t=[[null,t,""]]);for(var i={},r=0;r";e.style.display="none",n("fab2").appendChild(e),e.src="/service/javascript:",t=e.contentWindow.document,t.open(),t.write(r+"script"+s+"document.F=Object"+r+"/script"+s),t.close(),l=t.F;while(i--)delete l[c][o[i]];return l()};t.exports=Object.create||function(t,e){var n;return null!==t?(a[c]=i(t),n=new a,a[c]=null,n[s]=t):n=l(),void 0===e?n:r(n,e)}},"2af9":function(t,e,n){"use strict";(function(t){n.d(e,"d",(function(){return s}));n("7f7f"),n("cadf"),n("456d"),n("ac6a");var i=n("bc21");n.d(e,"a",(function(){return i["a"]}));var r=n("37c8");n.d(e,"b",(function(){return r["a"]}));var o={GridLayout:r["a"],GridItem:i["a"]};function s(t){s.installed||(s.installed=!0,Object.keys(o).forEach((function(e){t.component(e,o[e])})))}var a={install:s},c=null;"undefined"!==typeof window?c=window.Vue:"undefined"!==typeof t&&(c=t.Vue),c&&c.use(a),e["c"]=o}).call(this,n("c8ba"))},"2b4c":function(t,e,n){var i=n("5537")("wks"),r=n("ca5a"),o=n("7726").Symbol,s="function"==typeof o,a=t.exports=function(t){return i[t]||(i[t]=s&&o[t]||(s?o:r)("Symbol."+t))};a.store=i},"2cef":function(t,e,n){"use strict";t.exports=function(){var t=1;function e(){return t++}return{generate:e}}},"2d00":function(t,e){t.exports=!1},"2d95":function(t,e){var n={}.toString;t.exports=function(t){return n.call(t).slice(8,-1)}},"2f21":function(t,e,n){"use strict";var i=n("79e5");t.exports=function(t,e){return!!t&&i((function(){e?t.call(null,(function(){}),1):t.call(null)}))}},"32e9":function(t,e,n){var i=n("86cc"),r=n("4630");t.exports=n("9e1e")?function(t,e,n){return i.f(t,e,r(1,n))}:function(t,e,n){return t[e]=n,t}},"37c8":function(t,e,n){"use strict";var i=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{ref:"item",staticClass:"vue-grid-layout",style:t.mergedStyle},[t._t("default"),n("grid-item",{directives:[{name:"show",rawName:"v-show",value:t.isDragging,expression:"isDragging"}],staticClass:"vue-grid-placeholder",attrs:{x:t.placeholder.x,y:t.placeholder.y,w:t.placeholder.w,h:t.placeholder.h,i:t.placeholder.i}})],2)},r=[],o=(n("8e6e"),n("cadf"),n("456d"),n("f751"),n("fca0"),n("ac6a"),n("ade3")),s=(n("c5f6"),n("8bbf")),a=n.n(s),c=n("a2b6"),l=n("97a7"),u=n("bc21"),h=n("1ca7");function d(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);e&&(i=i.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,i)}return n}function f(t){for(var e=1;e0&&(this.layout.length>this.originalLayout.length?this.originalLayout=this.originalLayout.concat(t):this.originalLayout=this.originalLayout.filter((function(e){return!t.some((function(t){return e.i===t.i}))}))),this.lastLayoutLength=this.layout.length,this.initResponsiveFeatures()}Object(c["c"])(this.layout,this.verticalCompact),this.eventBus.$emit("updateWidth",this.width),this.updateHeight(),this.$emit("layout-updated",this.layout)}},updateHeight:function(){this.mergedStyle={height:this.containerHeight()}},onWindowResize:function(){null!==this.$refs&&null!==this.$refs.item&&void 0!==this.$refs.item&&(this.width=this.$refs.item.offsetWidth),this.eventBus.$emit("resizeEvent")},containerHeight:function(){if(this.autoSize){var t=Object(c["a"])(this.layout)*(this.rowHeight+this.margin[1])+this.margin[1]+"px";return t}},dragEvent:function(t,e,n,i,r,s){var a=Object(c["f"])(this.layout,e);void 0!==a&&null!==a||(a={x:0,y:0}),"dragstart"!==t||this.verticalCompact||(this.positionsBeforeDrag=this.layout.reduce((function(t,e){var n=e.i,i=e.x,r=e.y;return f(f({},t),{},Object(o["a"])({},n,{x:i,y:r}))}),{})),"dragmove"===t||"dragstart"===t?(this.placeholder.i=e,this.placeholder.x=a.x,this.placeholder.y=a.y,this.placeholder.w=s,this.placeholder.h=r,this.$nextTick((function(){this.isDragging=!0})),this.eventBus.$emit("updateWidth",this.width)):this.$nextTick((function(){this.isDragging=!1})),this.layout=Object(c["g"])(this.layout,a,n,i,!0,this.preventCollision),this.restoreOnDrag?(a.static=!0,Object(c["c"])(this.layout,this.verticalCompact,this.positionsBeforeDrag),a.static=!1):Object(c["c"])(this.layout,this.verticalCompact),this.eventBus.$emit("compact"),this.updateHeight(),"dragend"===t&&(delete this.positionsBeforeDrag,this.$emit("layout-updated",this.layout))},resizeEvent:function(t,e,n,i,r,o){var s,a=Object(c["f"])(this.layout,e);if(void 0!==a&&null!==a||(a={h:0,w:0}),this.preventCollision){var l=Object(c["e"])(this.layout,f(f({},a),{},{w:o,h:r})).filter((function(t){return t.i!==a.i}));if(s=l.length>0,s){var u=1/0,h=1/0;l.forEach((function(t){t.x>a.x&&(u=Math.min(u,t.x)),t.y>a.y&&(h=Math.min(h,t.y))})),Number.isFinite(u)&&(a.w=u-a.x),Number.isFinite(h)&&(a.h=h-a.y)}}s||(a.w=o,a.h=r),"resizestart"===t||"resizemove"===t?(this.placeholder.i=e,this.placeholder.x=n,this.placeholder.y=i,this.placeholder.w=a.w,this.placeholder.h=a.h,this.$nextTick((function(){this.isDragging=!0})),this.eventBus.$emit("updateWidth",this.width)):this.$nextTick((function(){this.isDragging=!1})),this.responsive&&this.responsiveGridLayout(),Object(c["c"])(this.layout,this.verticalCompact),this.eventBus.$emit("compact"),this.updateHeight(),"resizeend"===t&&this.$emit("layout-updated",this.layout)},responsiveGridLayout:function(){var t=Object(l["b"])(this.breakpoints,this.width),e=Object(l["c"])(t,this.cols);null==this.lastBreakpoint||this.layouts[this.lastBreakpoint]||(this.layouts[this.lastBreakpoint]=Object(c["b"])(this.layout));var n=Object(l["a"])(this.originalLayout,this.layouts,this.breakpoints,t,this.lastBreakpoint,e,this.verticalCompact);this.layouts[t]=n,this.lastBreakpoint!==t&&this.$emit("breakpoint-changed",t,n),this.$emit("update:layout",n),this.lastBreakpoint=t,this.eventBus.$emit("setColNum",Object(l["c"])(t,this.cols))},initResponsiveFeatures:function(){this.layouts=Object.assign({},this.responsiveLayouts)},findDifference:function(t,e){var n=t.filter((function(t){return!e.some((function(e){return t.i===e.i}))})),i=e.filter((function(e){return!t.some((function(t){return e.i===t.i}))}));return n.concat(i)}}},m=g,v=(n("e279"),n("2877")),b=Object(v["a"])(m,i,r,!1,null,null,null);e["a"]=b.exports},"38fd":function(t,e,n){var i=n("69a8"),r=n("4bf8"),o=n("613b")("IE_PROTO"),s=Object.prototype;t.exports=Object.getPrototypeOf||function(t){return t=r(t),i(t,o)?t[o]:"function"==typeof t.constructor&&t instanceof t.constructor?t.constructor.prototype:t instanceof Object?s:null}},"41a0":function(t,e,n){"use strict";var i=n("2aeb"),r=n("4630"),o=n("7f20"),s={};n("32e9")(s,n("2b4c")("iterator"),(function(){return this})),t.exports=function(t,e,n){t.prototype=i(s,{next:r(1,n)}),o(t,e+" Iterator")}},"456d":function(t,e,n){var i=n("4bf8"),r=n("0d58");n("5eda")("keys",(function(){return function(t){return r(i(t))}}))},4588:function(t,e){var n=Math.ceil,i=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(t>0?i:n)(t)}},4630:function(t,e){t.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},4917:function(t,e,n){"use strict";var i=n("cb7c"),r=n("9def"),o=n("0390"),s=n("5f1b");n("214f")("match",1,(function(t,e,n,a){return[function(n){var i=t(this),r=void 0==n?void 0:n[e];return void 0!==r?r.call(n,i):new RegExp(n)[e](String(i))},function(t){var e=a(n,t,this);if(e.done)return e.value;var c=i(t),l=String(this);if(!c.global)return s(c,l);var u=c.unicode;c.lastIndex=0;var h,d=[],f=0;while(null!==(h=s(c,l))){var p=String(h[0]);d[f]=p,""===p&&(c.lastIndex=o(l,r(c.lastIndex),u)),f++}return 0===f?null:d}]}))},"499e":function(t,e,n){"use strict";function i(t,e){for(var n=[],i={},r=0;rn.parts.length&&(i.parts.length=n.parts.length)}else{var s=[];for(r=0;r1&&o.call(s[0],n,(function(){for(u=1;uu){var f,p=c(arguments[u++]),g=h?r(p).concat(h(p)):r(p),m=g.length,v=0;while(m>v)f=g[v++],i&&!d.call(p,f)||(n[f]=p[f])}return n}:l},7726:function(t,e){var n=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=n)},"77f1":function(t,e,n){var i=n("4588"),r=Math.max,o=Math.min;t.exports=function(t,e){return t=i(t),t<0?r(t+e,0):o(t,e)}},"79e5":function(t,e){t.exports=function(t){try{return!!t()}catch(e){return!0}}},"7f20":function(t,e,n){var i=n("86cc").f,r=n("69a8"),o=n("2b4c")("toStringTag");t.exports=function(t,e,n){t&&!r(t=n?t:t.prototype,o)&&i(t,o,{configurable:!0,value:e})}},"7f7f":function(t,e,n){var i=n("86cc").f,r=Function.prototype,o=/^\s*function ([^ (]*)/,s="name";s in r||n("9e1e")&&i(r,s,{configurable:!0,get:function(){try{return(""+this).match(o)[1]}catch(t){return""}}})},8378:function(t,e){var n=t.exports={version:"2.6.12"};"number"==typeof __e&&(__e=n)},"84f2":function(t,e){t.exports={}},"86cc":function(t,e,n){var i=n("cb7c"),r=n("c69a"),o=n("6a99"),s=Object.defineProperty;e.f=n("9e1e")?Object.defineProperty:function(t,e,n){if(i(t),e=o(e,!0),i(n),r)try{return s(t,e,n)}catch(a){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(t[e]=n.value),t}},"8b97":function(t,e,n){var i=n("d3f4"),r=n("cb7c"),o=function(t,e){if(r(t),!i(e)&&null!==e)throw TypeError(e+": can't set as prototype!")};t.exports={set:Object.setPrototypeOf||("__proto__"in{}?function(t,e,i){try{i=n("9b43")(Function.call,n("11e9").f(Object.prototype,"__proto__").set,2),i(t,[]),e=!(t instanceof Array)}catch(r){e=!0}return function(t,n){return o(t,n),e?t.__proto__=n:i(t,n),t}}({},!1):void 0),check:o}},"8bbf":function(e,n){e.exports=t},"8e6e":function(t,e,n){var i=n("5ca1"),r=n("990b"),o=n("6821"),s=n("11e9"),a=n("f1ae");i(i.S,"Object",{getOwnPropertyDescriptors:function(t){var e,n,i=o(t),c=s.f,l=r(i),u={},h=0;while(l.length>h)n=c(i,e=l[h++]),void 0!==n&&a(u,e,n);return u}})},9093:function(t,e,n){var i=n("ce10"),r=n("e11e").concat("length","prototype");e.f=Object.getOwnPropertyNames||function(t){return i(t,r)}},"97a7":function(t,e,n){"use strict";n.d(e,"b",(function(){return r})),n.d(e,"c",(function(){return o})),n.d(e,"a",(function(){return s}));n("55dd"),n("ac6a"),n("cadf"),n("456d");var i=n("a2b6");function r(t,e){for(var n=a(t),i=n[0],r=1,o=n.length;rt[s]&&(i=s)}return i}function o(t,e){if(!e[t])throw new Error("ResponsiveGridLayout: `cols` entry for breakpoint "+t+" is missing!");return e[t]}function s(t,e,n,r,o,s,c){if(e[r])return Object(i["b"])(e[r]);for(var l=t,u=a(n),h=u.slice(u.indexOf(r)),d=0,f=h.length;d.vue-resizable-handle{position:absolute;width:20px;height:20px;bottom:0;right:0;background:url("data:image/svg+xml;base64,PHN2ZyBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjojZmZmZmZmMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjYiIGhlaWdodD0iNiI+PHBhdGggZD0iTTYgNkgwVjQuMmg0LjJWMEg2djZ6IiBvcGFjaXR5PSIuMzAyIi8+PC9zdmc+");background-position:100% 100%;padding:0 3px 3px 0;background-repeat:no-repeat;background-origin:content-box;-webkit-box-sizing:border-box;box-sizing:border-box;cursor:se-resize}.vue-grid-item>.vue-rtl-resizable-handle{bottom:0;left:0;background:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbD0ibm9uZSIgZD0iTS0xLTFoMTJ2MTJILTF6Ii8+PGc+PHBhdGggc3Ryb2tlLWxpbmVjYXA9InVuZGVmaW5lZCIgc3Ryb2tlLWxpbmVqb2luPSJ1bmRlZmluZWQiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2U9IiMwMDAiIGZpbGw9Im5vbmUiIGQ9Ik0xNDQuODIxLTM4LjM5M2wtMjAuMzU3LTMxLjc4NSIvPjxwYXRoIHN0cm9rZT0iIzY2NiIgc3Ryb2tlLWxpbmVjYXA9InVuZGVmaW5lZCIgc3Ryb2tlLWxpbmVqb2luPSJ1bmRlZmluZWQiIHN0cm9rZS13aWR0aD0iMiIgZmlsbD0ibm9uZSIgZD0iTS45NDctLjAxOHY5LjEyNU0tLjY1NiA5aDEwLjczIi8+PC9nPjwvc3ZnPg==);background-position:0 100%;padding-left:3px;background-repeat:no-repeat;background-origin:content-box;cursor:sw-resize;right:auto}.vue-grid-item.disable-userselect{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}',""])},"9def":function(t,e,n){var i=n("4588"),r=Math.min;t.exports=function(t){return t>0?r(i(t),9007199254740991):0}},"9e1e":function(t,e,n){t.exports=!n("79e5")((function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a}))},a2b6:function(t,e,n){"use strict";n.d(e,"a",(function(){return i})),n.d(e,"b",(function(){return r})),n.d(e,"c",(function(){return a})),n.d(e,"d",(function(){return l})),n.d(e,"f",(function(){return u})),n.d(e,"e",(function(){return d})),n.d(e,"g",(function(){return p})),n.d(e,"j",(function(){return m})),n.d(e,"k",(function(){return v})),n.d(e,"h",(function(){return b})),n.d(e,"i",(function(){return y})),n.d(e,"l",(function(){return w}));n("a481"),n("cadf"),n("456d"),n("ac6a"),n("55dd");function i(t){for(var e,n=0,i=0,r=t.length;in&&(n=e);return n}function r(t){for(var e=Array(t.length),n=0,i=t.length;n=e.x+e.w)&&(!(t.y+t.h<=e.y)&&!(t.y>=e.y+e.h))))}function a(t,e,n){for(var i=f(t),r=x(t),o=Array(t.length),s=0,a=r.length;s0&&!h(t,e))e.y--;else if(i){var r=i[e.i].y;while(e.y>r&&!h(t,e))e.y--}var o;while(o=h(t,e))e.y=o.y+o.h;return e}function l(t,e){for(var n=f(t),i=0,r=t.length;ie.cols&&(o.x=e.cols-o.w),o.x<0&&(o.x=0,o.w=e.cols),o.static)while(h(n,o))o.y++;else n.push(o)}return t}function u(t,e){for(var n=0,i=t.length;ni;"number"===typeof n&&(e.x=n),"number"===typeof i&&(e.y=i),e.moved=!0;var l=x(t);c&&(l=l.reverse());var u=d(l,e);if(o&&u.length)return e.x=s,e.y=a,e.moved=!1,t;for(var h=0,f=u.length;hp.y&&e.y-p.y>p.h/4||(t=p.static?g(t,p,e,r):g(t,e,p,r)))}return t}function g(t,e,n,i){var r=!1;if(i){var o={x:n.x,y:n.y,w:n.w,h:n.h,i:"-1"};if(o.y=Math.max(e.y-n.h,0),!h(t,o))return p(t,n,void 0,o.y,r)}return p(t,n,void 0,n.y+1,r)}function m(t,e,n,i){var r="translate3d("+e+"px,"+t+"px, 0)";return{transform:r,WebkitTransform:r,MozTransform:r,msTransform:r,OTransform:r,width:n+"px",height:i+"px",position:"absolute"}}function v(t,e,n,i){var r="translate3d("+-1*e+"px,"+t+"px, 0)";return{transform:r,WebkitTransform:r,MozTransform:r,msTransform:r,OTransform:r,width:n+"px",height:i+"px",position:"absolute"}}function b(t,e,n,i){return{top:t+"px",left:e+"px",width:n+"px",height:i+"px",position:"absolute"}}function y(t,e,n,i){return{top:t+"px",right:e+"px",width:n+"px",height:i+"px",position:"absolute"}}function x(t){return[].concat(t).sort((function(t,e){return t.y===e.y&&t.x===e.x?0:t.y>e.y||t.y===e.y&&t.x>e.x?1:-1}))}function w(t,e){e=e||"Layout";var n=["x","y","w","h"],i=[];if(!Array.isArray(t))throw new Error(e+" must be an array!");for(var r=0,o=t.length;r=0)throw new Error("VueGridLayout: "+e+"["+r+"].i must be unique!");if(i.push(s.i),void 0!==s.static&&"boolean"!==typeof s.static)throw new Error("VueGridLayout: "+e+"["+r+"].static must be a boolean!")}}},a481:function(t,e,n){"use strict";var i=n("cb7c"),r=n("4bf8"),o=n("9def"),s=n("4588"),a=n("0390"),c=n("5f1b"),l=Math.max,u=Math.min,h=Math.floor,d=/\$([$&`']|\d\d?|<[^>]*>)/g,f=/\$([$&`']|\d\d?)/g,p=function(t){return void 0===t?t:String(t)};n("214f")("replace",2,(function(t,e,n,g){return[function(i,r){var o=t(this),s=void 0==i?void 0:i[e];return void 0!==s?s.call(i,o,r):n.call(String(o),i,r)},function(t,e){var r=g(n,t,this,e);if(r.done)return r.value;var h=i(t),d=String(this),f="function"===typeof e;f||(e=String(e));var v=h.global;if(v){var b=h.unicode;h.lastIndex=0}var y=[];while(1){var x=c(h,d);if(null===x)break;if(y.push(x),!v)break;var w=String(x[0]);""===w&&(h.lastIndex=a(d,o(h.lastIndex),b))}for(var S="",E=0,O=0;O=E&&(S+=d.slice(E,z)+j,E=z+T.length)}return S+d.slice(E)}];function m(t,e,i,o,s,a){var c=i+t.length,l=o.length,u=f;return void 0!==s&&(s=r(s),u=d),n.call(a,u,(function(n,r){var a;switch(r.charAt(0)){case"$":return"$";case"&":return t;case"`":return e.slice(0,i);case"'":return e.slice(c);case"<":a=s[r.slice(1,-1)];break;default:var u=+r;if(0===u)return n;if(u>l){var d=h(u/10);return 0===d?n:d<=l?void 0===o[d-1]?r.charAt(1):o[d-1]+r.charAt(1):n}a=o[u-1]}return void 0===a?"":a}))}}))},aa77:function(t,e,n){var i=n("5ca1"),r=n("be13"),o=n("79e5"),s=n("fdef"),a="["+s+"]",c="​…",l=RegExp("^"+a+a+"*"),u=RegExp(a+a+"*$"),h=function(t,e,n){var r={},a=o((function(){return!!s[t]()||c[t]()!=c})),l=r[t]=a?e(d):s[t];n&&(r[n]=l),i(i.P+i.F*a,"String",r)},d=h.trim=function(t,e){return t=String(r(t)),1&e&&(t=t.replace(l,"")),2&e&&(t=t.replace(u,"")),t};t.exports=h},abb4:function(t,e,n){"use strict";t.exports=function(t){function e(){}var n={log:e,warn:e,error:e};if(!t&&window.console){var i=function(t,e){t[e]=function(){var t=console[e];if(t.apply)t.apply(console,arguments);else for(var n=0;n!(!t||!t.Window)&&t instanceof t.Window;let y=void 0,x=void 0;function w(t){y=t;const e=t.document.createTextNode("");e.ownerDocument!==t.document&&"function"===typeof t.wrap&&t.wrap(e)===e&&(t=t.wrap(t)),x=t}function S(t){if(b(t))return t;const e=t.ownerDocument||t;return e.defaultView||x.window}"undefined"!==typeof window&&window&&w(window);const E=t=>t===x||b(t),O=t=>T(t)&&11===t.nodeType,T=t=>!!t&&"object"===typeof t,z=t=>"function"===typeof t,M=t=>"number"===typeof t,_=t=>"boolean"===typeof t,P=t=>"string"===typeof t,I=t=>{if(!t||"object"!==typeof t)return!1;const e=S(t)||x;return/object|function/.test(typeof e.Element)?t instanceof e.Element:1===t.nodeType&&"string"===typeof t.nodeName},j=t=>T(t)&&!!t.constructor&&/function Object\b/.test(t.constructor.toString()),D=t=>T(t)&&"undefined"!==typeof t.length&&z(t.splice);var R={window:E,docFrag:O,object:T,func:z,number:M,bool:_,string:P,element:I,plainObject:j,array:D};const k={init:A,supportsTouch:null,supportsPointerEvent:null,isIOS7:null,isIOS:null,isIe9:null,isOperaMobile:null,prefixedMatchesSelector:null,pEventTypes:null,wheelEvent:null};function A(t){const e=m.Element,n=x.navigator;k.supportsTouch="ontouchstart"in t||R.func(t.DocumentTouch)&&m.document instanceof t.DocumentTouch,k.supportsPointerEvent=!1!==n.pointerEnabled&&!!m.PointerEvent,k.isIOS=/iP(hone|od|ad)/.test(n.platform),k.isIOS7=/iP(hone|od|ad)/.test(n.platform)&&/OS 7[^\d]/.test(n.appVersion),k.isIe9=/MSIE 9/.test(n.userAgent),k.isOperaMobile="Opera"===n.appName&&k.supportsTouch&&/Presto/.test(n.userAgent),k.prefixedMatchesSelector="matches"in e.prototype?"matches":"webkitMatchesSelector"in e.prototype?"webkitMatchesSelector":"mozMatchesSelector"in e.prototype?"mozMatchesSelector":"oMatchesSelector"in e.prototype?"oMatchesSelector":"msMatchesSelector",k.pEventTypes=k.supportsPointerEvent?m.PointerEvent===t.MSPointerEvent?{up:"MSPointerUp",down:"MSPointerDown",over:"mouseover",out:"mouseout",move:"MSPointerMove",cancel:"MSPointerCancel"}:{up:"pointerup",down:"pointerdown",over:"pointerover",out:"pointerout",move:"pointermove",cancel:"pointercancel"}:null,k.wheelEvent="onmousewheel"in m.document?"mousewheel":"wheel"}var C=k;const H=(t,e)=>-1!==t.indexOf(e),L=(t,e)=>{for(const n of e)t.push(n);return t},B=t=>L([],t),N=(t,e)=>{for(let n=0;nt[N(t,e)];function $(t){const e={};for(const n in t){const i=t[n];R.plainObject(i)?e[n]=$(i):R.array(i)?e[n]=B(i):e[n]=i}return e}function F(t,e){for(const i in e)t[i]=e[i];const n=t;return n}let G,X,Y=0;function q(t){if(G=t.requestAnimationFrame,X=t.cancelAnimationFrame,!G){const e=["ms","moz","webkit","o"];for(const n of e)G=t[n+"RequestAnimationFrame"],X=t[n+"CancelAnimationFrame"]||t[n+"CancelRequestAnimationFrame"]}G=G&&G.bind(t),X=X&&X.bind(t),G||(G=e=>{const n=Date.now(),i=Math.max(0,16-(n-Y)),r=t.setTimeout(()=>{e(n+i)},i);return Y=n+i,r},X=t=>clearTimeout(t))}var V={request:t=>G(t),cancel:t=>X(t),init:q};function U(t,e,n){if(n=n||{},R.string(t)&&-1!==t.search(" ")&&(t=Z(t)),R.array(t))return t.reduce((t,i)=>F(t,U(i,e,n)),n);if(R.object(t)&&(e=t,t=""),R.func(e))n[t]=n[t]||[],n[t].push(e);else if(R.array(e))for(const i of e)U(t,i,n);else if(R.object(e))for(const i in e){const r=Z(i).map(e=>`${t}${e}`);U(r,e[i],n)}return n}function Z(t){return t.trim().split(/ +/)}function K(t,e){for(const n of e){if(t.immediatePropagationStopped)break;n(t)}}class J{constructor(t){this.options=void 0,this.types={},this.propagationStopped=!1,this.immediatePropagationStopped=!1,this.global=void 0,this.options=F({},t||{})}fire(t){let e;const n=this.global;(e=this.types[t.type])&&K(t,e),!t.propagationStopped&&n&&(e=n[t.type])&&K(t,e)}on(t,e){const n=U(t,e);for(t in n)this.types[t]=L(this.types[t]||[],n[t])}off(t,e){const n=U(t,e);for(t in n){const e=this.types[t];if(e&&e.length)for(const i of n[t]){const t=e.indexOf(i);-1!==t&&e.splice(t,1)}}}getRect(t){return null}}function Q(t,e){if(t.contains)return t.contains(e);while(e){if(e===t)return!0;e=e.parentNode}return!1}function tt(t,e){while(R.element(t)){if(nt(t,e))return t;t=et(t)}return null}function et(t){let e=t.parentNode;if(R.docFrag(e)){while((e=e.host)&&R.docFrag(e));return e}return e}function nt(t,e){return x!==y&&(e=e.replace(/\/deep\//g," ")),t[C.prefixedMatchesSelector](e)}function it(t,e,n){while(R.element(t)){if(nt(t,e))return!0;if(t=et(t),t===n)return nt(t,e)}return!1}function rt(t){return t.correspondingUseElement||t}function ot(t){return t=t||x,{x:t.scrollX||t.document.documentElement.scrollLeft,y:t.scrollY||t.document.documentElement.scrollTop}}function st(t){const e=t instanceof m.SVGElement?t.getBoundingClientRect():t.getClientRects()[0];return e&&{left:e.left,right:e.right,top:e.top,bottom:e.bottom,width:e.width||e.right-e.left,height:e.height||e.bottom-e.top}}function at(t){const e=st(t);if(!C.isIOS7&&e){const n=ot(S(t));e.left+=n.x,e.right+=n.x,e.top+=n.y,e.bottom+=n.y}return e}function ct(t){return!!R.string(t)&&(m.document.querySelector(t),!0)}function lt(t,e,n){return"parent"===t?et(n):"self"===t?e.getRect(n):tt(n,t)}function ut(t,e,n,i){let r=t;return R.string(r)?r=lt(r,e,n):R.func(r)&&(r=r(...i)),R.element(r)&&(r=at(r)),r}function ht(t){return t&&{x:"x"in t?t.x:t.left,y:"y"in t?t.y:t.top}}function dt(t){return!t||"left"in t&&"top"in t||(t=F({},t),t.left=t.x||0,t.top=t.y||0,t.right=t.right||t.left+t.width,t.bottom=t.bottom||t.top+t.height),t}function ft(t){return!t||"x"in t&&"y"in t||(t=F({},t),t.x=t.left||0,t.y=t.top||0,t.width=t.width||(t.right||0)-t.x,t.height=t.height||(t.bottom||0)-t.y),t}function pt(t,e,n){t.left&&(e.left+=n.x),t.right&&(e.right+=n.x),t.top&&(e.top+=n.y),t.bottom&&(e.bottom+=n.y),e.width=e.right-e.left,e.height=e.bottom-e.top}var gt=function(t,e,n){const i=t.options[n],r=i&&i.origin,o=r||t.options.origin,s=ut(o,t,e,[t&&e]);return ht(s)||{x:0,y:0}},mt=(t,e)=>Math.sqrt(t*t+e*e);class vt{constructor(t){this.type=void 0,this.target=void 0,this.currentTarget=void 0,this.interactable=void 0,this._interaction=void 0,this.timeStamp=void 0,this.immediatePropagationStopped=!1,this.propagationStopped=!1,this._interaction=t}preventDefault(){}stopPropagation(){this.propagationStopped=!0}stopImmediatePropagation(){this.immediatePropagationStopped=this.propagationStopped=!0}}Object.defineProperty(vt.prototype,"interaction",{get(){return this._interaction._proxy},set(){}});const bt={base:{preventDefault:"auto",deltaSource:"page"},perAction:{enabled:!1,origin:{x:0,y:0}},actions:{}};class yt extends vt{constructor(t,e,n,i,r,o,s){super(t),this.target=void 0,this.currentTarget=void 0,this.relatedTarget=null,this.screenX=void 0,this.screenY=void 0,this.button=void 0,this.buttons=void 0,this.ctrlKey=void 0,this.shiftKey=void 0,this.altKey=void 0,this.metaKey=void 0,this.page=void 0,this.client=void 0,this.delta=void 0,this.rect=void 0,this.x0=void 0,this.y0=void 0,this.t0=void 0,this.dt=void 0,this.duration=void 0,this.clientX0=void 0,this.clientY0=void 0,this.velocity=void 0,this.speed=void 0,this.swipe=void 0,this.timeStamp=void 0,this.axes=void 0,this.preEnd=void 0,r=r||t.element;const a=t.interactable,c=(a&&a.options||bt).deltaSource,l=gt(a,r,n),u="start"===i,h="end"===i,d=u?this:t.prevEvent,f=u?t.coords.start:h?{page:d.page,client:d.client,timeStamp:t.coords.cur.timeStamp}:t.coords.cur;this.page=F({},f.page),this.client=F({},f.client),this.rect=F({},t.rect),this.timeStamp=f.timeStamp,h||(this.page.x-=l.x,this.page.y-=l.y,this.client.x-=l.x,this.client.y-=l.y),this.ctrlKey=e.ctrlKey,this.altKey=e.altKey,this.shiftKey=e.shiftKey,this.metaKey=e.metaKey,this.button=e.button,this.buttons=e.buttons,this.target=r,this.currentTarget=r,this.preEnd=o,this.type=s||n+(i||""),this.interactable=a,this.t0=u?t.pointers[t.pointers.length-1].downTime:d.t0,this.x0=t.coords.start.page.x-l.x,this.y0=t.coords.start.page.y-l.y,this.clientX0=t.coords.start.client.x-l.x,this.clientY0=t.coords.start.client.y-l.y,this.delta=u||h?{x:0,y:0}:{x:this[c].x-d[c].x,y:this[c].y-d[c].y},this.dt=t.coords.delta.timeStamp,this.duration=this.timeStamp-this.t0,this.velocity=F({},t.coords.velocity[c]),this.speed=mt(this.velocity.x,this.velocity.y),this.swipe=h||"inertiastart"===i?this.getSwipe():null}getSwipe(){const t=this._interaction;if(t.prevEvent.speed<600||this.timeStamp-t.prevEvent.timeStamp>150)return null;let e=180*Math.atan2(t.prevEvent.velocityY,t.prevEvent.velocityX)/Math.PI;const n=22.5;e<0&&(e+=360);const i=135-n<=e&&e<225+n,r=225-n<=e&&e<315+n,o=!i&&(315-n<=e||e<45+n),s=!r&&45-n<=e&&e<135+n;return{up:r,down:s,left:i,right:o,angle:e,speed:t.prevEvent.speed,velocity:{x:t.prevEvent.velocityX,y:t.prevEvent.velocityY}}}preventDefault(){}stopImmediatePropagation(){this.immediatePropagationStopped=this.propagationStopped=!0}stopPropagation(){this.propagationStopped=!0}}function xt(t,e){if(e.phaselessTypes[t])return!0;for(const n in e.map)if(0===t.indexOf(n)&&t.substr(n.length)in e.phases)return!0;return!1}Object.defineProperties(yt.prototype,{pageX:{get(){return this.page.x},set(t){this.page.x=t}},pageY:{get(){return this.page.y},set(t){this.page.y=t}},clientX:{get(){return this.client.x},set(t){this.client.x=t}},clientY:{get(){return this.client.y},set(t){this.client.y=t}},dx:{get(){return this.delta.x},set(t){this.delta.x=t}},dy:{get(){return this.delta.y},set(t){this.delta.y=t}},velocityX:{get(){return this.velocity.x},set(t){this.velocity.x=t}},velocityY:{get(){return this.velocity.y},set(t){this.velocity.y=t}}});class wt{get _defaults(){return{base:{},perAction:{},actions:{}}}constructor(t,e,n,i){this.options=void 0,this._actions=void 0,this.target=void 0,this.events=new J,this._context=void 0,this._win=void 0,this._doc=void 0,this._scopeEvents=void 0,this._rectChecker=void 0,this._actions=e.actions,this.target=t,this._context=e.context||n,this._win=S(ct(t)?this._context:t),this._doc=this._win.document,this._scopeEvents=i,this.set(e)}setOnEvents(t,e){return R.func(e.onstart)&&this.on(t+"start",e.onstart),R.func(e.onmove)&&this.on(t+"move",e.onmove),R.func(e.onend)&&this.on(t+"end",e.onend),R.func(e.oninertiastart)&&this.on(t+"inertiastart",e.oninertiastart),this}updatePerActionListeners(t,e,n){(R.array(e)||R.object(e))&&this.off(t,e),(R.array(n)||R.object(n))&&this.on(t,n)}setPerAction(t,e){const n=this._defaults;for(const i in e){const r=i,o=this.options[t],s=e[r];"listeners"===r&&this.updatePerActionListeners(t,o.listeners,s),R.array(s)?o[r]=B(s):R.plainObject(s)?(o[r]=F(o[r]||{},$(s)),R.object(n.perAction[r])&&"enabled"in n.perAction[r]&&(o[r].enabled=!1!==s.enabled)):R.bool(s)&&R.object(n.perAction[r])?o[r].enabled=s:o[r]=s}}getRect(t){return t=t||(R.element(this.target)?this.target:null),R.string(this.target)&&(t=t||this._context.querySelector(this.target)),at(t)}rectChecker(t){return R.func(t)?(this._rectChecker=t,this.getRect=t=>{const e=F({},this._rectChecker(t));return"width"in e||(e.width=e.right-e.left,e.height=e.bottom-e.top),e},this):null===t?(delete this.getRect,delete this._rectChecker,this):this.getRect}_backCompatOption(t,e){if(ct(e)||R.object(e)){this.options[t]=e;for(const n in this._actions.map)this.options[n][t]=e;return this}return this.options[t]}origin(t){return this._backCompatOption("origin",t)}deltaSource(t){return"page"===t||"client"===t?(this.options.deltaSource=t,this):this.options.deltaSource}context(){return this._context}inContext(t){return this._context===t.ownerDocument||Q(this._context,t)}testIgnoreAllow(t,e,n){return!this.testIgnore(t.ignoreFrom,e,n)&&this.testAllow(t.allowFrom,e,n)}testAllow(t,e,n){return!t||!!R.element(n)&&(R.string(t)?it(n,t,e):!!R.element(t)&&Q(t,n))}testIgnore(t,e,n){return!(!t||!R.element(n))&&(R.string(t)?it(n,t,e):!!R.element(t)&&Q(t,n))}fire(t){return this.events.fire(t),this}_onOff(t,e,n,i){R.object(e)&&!R.array(e)&&(i=n,n=null);const r="on"===t?"add":"remove",o=U(e,n);for(let s in o){"wheel"===s&&(s=C.wheelEvent);for(const e of o[s])xt(s,this._actions)?this.events[t](s,e):R.string(this.target)?this._scopeEvents[r+"Delegate"](this.target,this._context,s,e,i):this._scopeEvents[r](this.target,s,e,i)}return this}on(t,e,n){return this._onOff("on",t,e,n)}off(t,e,n){return this._onOff("off",t,e,n)}set(t){const e=this._defaults;R.object(t)||(t={}),this.options=$(e.base);for(const n in this._actions.methodDict){const i=n,r=this._actions.methodDict[i];this.options[i]={},this.setPerAction(i,F(F({},e.perAction),e.actions[i])),this[r](t[i])}for(const n in t)R.func(this[n])&&this[n](t[n]);return this}unset(){if(R.string(this.target))for(const t in this._scopeEvents.delegatedEvents){const e=this._scopeEvents.delegatedEvents[t];for(let n=e.length-1;n>=0;n--){const{selector:i,context:r,listeners:o}=e[n];i===this.target&&r===this._context&&e.splice(n,1);for(let e=o.length-1;e>=0;e--)this._scopeEvents.removeDelegate(this.target,this._context,t,o[e][0],o[e][1])}}else this._scopeEvents.remove(this.target,"all")}}class St{constructor(t){this.list=[],this.selectorMap={},this.scope=void 0,this.scope=t,t.addListeners({"interactable:unset":({interactable:t})=>{const{target:e,_context:n}=t,i=R.string(e)?this.selectorMap[e]:e[this.scope.id],r=N(i,t=>t.context===n);i[r]&&(i[r].context=null,i[r].interactable=null),i.splice(r,1)}})}new(t,e){e=F(e||{},{actions:this.scope.actions});const n=new this.scope.Interactable(t,e,this.scope.document,this.scope.events),i={context:n._context,interactable:n};return this.scope.addDocument(n._doc),this.list.push(n),R.string(t)?(this.selectorMap[t]||(this.selectorMap[t]=[]),this.selectorMap[t].push(i)):(n.target[this.scope.id]||Object.defineProperty(t,this.scope.id,{value:[],configurable:!0}),t[this.scope.id].push(i)),this.scope.fire("interactable:new",{target:t,options:e,interactable:n,win:this.scope._win}),n}get(t,e){const n=e&&e.context||this.scope.document,i=R.string(t),r=i?this.selectorMap[t]:t[this.scope.id];if(!r)return null;const o=W(r,e=>e.context===n&&(i||e.interactable.inContext(t)));return o&&o.interactable}forEachMatch(t,e){for(const n of this.list){let i;if((R.string(n.target)?R.element(t)&&nt(t,n.target):t===n.target)&&n.inContext(t)&&(i=e(n)),void 0!==i)return i}}}function Et(t,e){for(const n in e){const i=Et.prefixedPropREs;let r=!1;for(const t in i)if(0===n.indexOf(t)&&i[t].test(n)){r=!0;break}r||"function"===typeof e[n]||(t[n]=e[n])}return t}Et.prefixedPropREs={webkit:/(Movement[XY]|Radius[XY]|RotationAngle|Force)$/,moz:/(Pressure)$/};var Ot=Et;function Tt(t,e){t.page=t.page||{},t.page.x=e.page.x,t.page.y=e.page.y,t.client=t.client||{},t.client.x=e.client.x,t.client.y=e.client.y,t.timeStamp=e.timeStamp}function zt(t,e,n){t.page.x=n.page.x-e.page.x,t.page.y=n.page.y-e.page.y,t.client.x=n.client.x-e.client.x,t.client.y=n.client.y-e.client.y,t.timeStamp=n.timeStamp-e.timeStamp}function Mt(t,e){const n=Math.max(e.timeStamp/1e3,.001);t.page.x=e.page.x/n,t.page.y=e.page.y/n,t.client.x=e.client.x/n,t.client.y=e.client.y/n,t.timeStamp=n}function _t(t){t.page.x=0,t.page.y=0,t.client.x=0,t.client.y=0}function Pt(t){return t instanceof m.Event||t instanceof m.Touch}function It(t,e,n){return n=n||{},t=t||"page",n.x=e[t+"X"],n.y=e[t+"Y"],n}function jt(t,e){return e=e||{x:0,y:0},C.isOperaMobile&&Pt(t)?(It("screen",t,e),e.x+=window.scrollX,e.y+=window.scrollY):It("page",t,e),e}function Dt(t,e){return e=e||{},C.isOperaMobile&&Pt(t)?It("screen",t,e):It("client",t,e),e}function Rt(t){return R.number(t.pointerId)?t.pointerId:t.identifier}function kt(t,e,n){const i=e.length>1?Ct(e):e[0];jt(i,t.page),Dt(i,t.client),t.timeStamp=n}function At(t){const e=[];return R.array(t)?(e[0]=t[0],e[1]=t[1]):"touchend"===t.type?1===t.touches.length?(e[0]=t.touches[0],e[1]=t.changedTouches[0]):0===t.touches.length&&(e[0]=t.changedTouches[0],e[1]=t.changedTouches[1]):(e[0]=t.touches[0],e[1]=t.touches[1]),e}function Ct(t){const e={pageX:0,pageY:0,clientX:0,clientY:0,screenX:0,screenY:0};for(const n of t)for(const t in e)e[t]+=n[t];for(const n in e)e[n]/=t.length;return e}function Ht(t){if(!t.length)return null;const e=At(t),n=Math.min(e[0].pageX,e[1].pageX),i=Math.min(e[0].pageY,e[1].pageY),r=Math.max(e[0].pageX,e[1].pageX),o=Math.max(e[0].pageY,e[1].pageY);return{x:n,y:i,left:n,top:i,right:r,bottom:o,width:r-n,height:o-i}}function Lt(t,e){const n=e+"X",i=e+"Y",r=At(t),o=r[0][n]-r[1][n],s=r[0][i]-r[1][i];return mt(o,s)}function Bt(t,e){const n=e+"X",i=e+"Y",r=At(t),o=r[1][n]-r[0][n],s=r[1][i]-r[0][i],a=180*Math.atan2(s,o)/Math.PI;return a}function Nt(t){return R.string(t.pointerType)?t.pointerType:R.number(t.pointerType)?[void 0,void 0,"touch","pen","mouse"][t.pointerType]:/touch/.test(t.type)||t instanceof m.Touch?"touch":"mouse"}function Wt(t){const e=R.func(t.composedPath)?t.composedPath():t.path;return[rt(e?e[0]:t.target),rt(t.currentTarget)]}function $t(){return{page:{x:0,y:0},client:{x:0,y:0},timeStamp:0}}function Ft(t){const e=[],n={},i=[],r={add:o,remove:s,addDelegate:a,removeDelegate:c,delegateListener:l,delegateUseCapture:u,delegatedEvents:n,documents:i,targets:e,supportsOptions:!1,supportsPassive:!1};function o(t,n,i,o){const s=Xt(o);let a=W(e,e=>e.eventTarget===t);a||(a={eventTarget:t,events:{}},e.push(a)),a.events[n]||(a.events[n]=[]),t.addEventListener&&!H(a.events[n],i)&&(t.addEventListener(n,i,r.supportsOptions?s:s.capture),a.events[n].push(i))}function s(t,n,i,o){const a=Xt(o),c=N(e,e=>e.eventTarget===t),l=e[c];if(!l||!l.events)return;if("all"===n){for(n in l.events)l.events.hasOwnProperty(n)&&s(t,n,"all");return}let u=!1;const h=l.events[n];if(h){if("all"===i){for(let e=h.length-1;e>=0;e--)s(t,n,h[e],a);return}for(let e=0;en.selector===t&&n.context===e);d||(d={selector:t,context:e,listeners:[]},h.push(d)),d.listeners.push([s,c])}function c(t,e,i,r,o){const a=Xt(o),c=n[i];let h,d=!1;if(c)for(h=c.length-1;h>=0;h--){const n=c[h];if(n.selector===t&&n.context===e){const{listeners:t}=n;for(let n=t.length-1;n>=0;n--){const[o,{capture:f,passive:p}]=t[n];if(o===r&&f===a.capture&&p===a.passive){t.splice(n,1),t.length||(c.splice(h,1),s(e,i,l),s(e,i,u,!0)),d=!0;break}}if(d)break}}}function l(t,e){const i=Xt(e),r=new Gt(t),o=n[t.type],[s]=Wt(t);let a=s;while(R.element(a)){for(let t=0;t{let r=t.interactables.get(n,i);return r||(r=t.interactables.new(n,i),r.events.global=e.globalEvents),r};return e.getPointerAverage=Ct,e.getTouchBBox=Ht,e.getTouchDistance=Lt,e.getTouchAngle=Bt,e.getElementRect=at,e.getElementClientRect=st,e.matchesSelector=nt,e.closest=tt,e.globalEvents={},e.version="1.10.2",e.scope=t,e.use=function(t,e){return this.scope.usePlugin(t,e),this},e.isSet=function(t,e){return!!this.scope.interactables.get(t,e&&e.context)},e.on=qt((function(t,e,n){if(R.string(t)&&-1!==t.search(" ")&&(t=t.trim().split(/ +/)),R.array(t)){for(const i of t)this.on(i,e,n);return this}if(R.object(t)){for(const n in t)this.on(n,t[n],e);return this}return xt(t,this.scope.actions)?this.globalEvents[t]?this.globalEvents[t].push(e):this.globalEvents[t]=[e]:this.scope.events.add(this.scope.document,t,e,{options:n}),this}),"The interact.on() method is being deprecated"),e.off=qt((function(t,e,n){if(R.string(t)&&-1!==t.search(" ")&&(t=t.trim().split(/ +/)),R.array(t)){for(const i of t)this.off(i,e,n);return this}if(R.object(t)){for(const n in t)this.off(n,t[n],e);return this}if(xt(t,this.scope.actions)){let n;t in this.globalEvents&&-1!==(n=this.globalEvents[t].indexOf(e))&&this.globalEvents[t].splice(n,1)}else this.scope.events.remove(this.scope.document,t,e,n);return this}),"The interact.off() method is being deprecated"),e.debug=function(){return this.scope},e.supportsTouch=function(){return C.supportsTouch},e.supportsPointerEvent=function(){return C.supportsPointerEvent},e.stop=function(){for(const t of this.scope.interactions.list)t.stop();return this},e.pointerMoveTolerance=function(t){return R.number(t)?(this.scope.interactions.pointerMoveTolerance=t,this):this.scope.interactions.pointerMoveTolerance},e.addDocument=function(t,e){this.scope.addDocument(t,e)},e.removeDocument=function(t){this.scope.removeDocument(t)},e}class Zt{constructor(t,e,n,i,r){this.id=void 0,this.pointer=void 0,this.event=void 0,this.downTime=void 0,this.downTarget=void 0,this.id=t,this.pointer=e,this.event=n,this.downTime=i,this.downTarget=r}}let Kt,Jt;(function(t){t["interactable"]="",t["element"]="",t["prepared"]="",t["pointerIsDown"]="",t["pointerWasMoved"]="",t["_proxy"]=""})(Kt||(Kt={})),function(t){t["start"]="",t["move"]="",t["end"]="",t["stop"]="",t["interacting"]=""}(Jt||(Jt={}));let Qt=0;class te{get pointerMoveTolerance(){return 1}constructor({pointerType:t,scopeFire:e}){this.interactable=null,this.element=null,this.rect=void 0,this._rects=void 0,this.edges=void 0,this._scopeFire=void 0,this.prepared={name:null,axis:null,edges:null},this.pointerType=void 0,this.pointers=[],this.downEvent=null,this.downPointer={},this._latestPointer={pointer:null,event:null,eventTarget:null},this.prevEvent=null,this.pointerIsDown=!1,this.pointerWasMoved=!1,this._interacting=!1,this._ending=!1,this._stopped=!0,this._proxy=null,this.simulation=null,this.doMove=qt((function(t){this.move(t)}),"The interaction.doMove() method has been renamed to interaction.move()"),this.coords={start:$t(),prev:$t(),cur:$t(),delta:$t(),velocity:$t()},this._id=Qt++,this._scopeFire=e,this.pointerType=t;const n=this;this._proxy={};for(const i in Kt)Object.defineProperty(this._proxy,i,{get(){return n[i]}});for(const i in Jt)Object.defineProperty(this._proxy,i,{value:(...t)=>n[i](...t)});this._scopeFire("interactions:new",{interaction:this})}pointerDown(t,e,n){const i=this.updatePointer(t,e,n,!0),r=this.pointers[i];this._scopeFire("interactions:down",{pointer:t,event:e,eventTarget:n,pointerIndex:i,pointerInfo:r,type:"down",interaction:this})}start(t,e,n){return!(this.interacting()||!this.pointerIsDown||this.pointers.length<("gesture"===t.name?2:1)||!e.options[t.name].enabled)&&(Vt(this.prepared,t),this.interactable=e,this.element=n,this.rect=e.getRect(n),this.edges=this.prepared.edges?F({},this.prepared.edges):{left:!0,right:!0,top:!0,bottom:!0},this._stopped=!1,this._interacting=this._doPhase({interaction:this,event:this.downEvent,phase:"start"})&&!this._stopped,this._interacting)}pointerMove(t,e,n){this.simulation||this.modification&&this.modification.endResult||this.updatePointer(t,e,n,!1);const i=this.coords.cur.page.x===this.coords.prev.page.x&&this.coords.cur.page.y===this.coords.prev.page.y&&this.coords.cur.client.x===this.coords.prev.client.x&&this.coords.cur.client.y===this.coords.prev.client.y;let r,o;this.pointerIsDown&&!this.pointerWasMoved&&(r=this.coords.cur.client.x-this.coords.start.client.x,o=this.coords.cur.client.y-this.coords.start.client.y,this.pointerWasMoved=mt(r,o)>this.pointerMoveTolerance);const s=this.getPointerIndex(t),a={pointer:t,pointerIndex:s,pointerInfo:this.pointers[s],event:e,type:"move",eventTarget:n,dx:r,dy:o,duplicate:i,interaction:this};i||Mt(this.coords.velocity,this.coords.delta),this._scopeFire("interactions:move",a),i||this.simulation||(this.interacting()&&(a.type=null,this.move(a)),this.pointerWasMoved&&Tt(this.coords.prev,this.coords.cur))}move(t){t&&t.event||_t(this.coords.delta),t=F({pointer:this._latestPointer.pointer,event:this._latestPointer.event,eventTarget:this._latestPointer.eventTarget,interaction:this},t||{}),t.phase="move",this._doPhase(t)}pointerUp(t,e,n,i){let r=this.getPointerIndex(t);-1===r&&(r=this.updatePointer(t,e,n,!1));const o=/cancel$/i.test(e.type)?"cancel":"up";this._scopeFire("interactions:"+o,{pointer:t,pointerIndex:r,pointerInfo:this.pointers[r],event:e,eventTarget:n,type:o,curEventTarget:i,interaction:this}),this.simulation||this.end(e),this.removePointer(t,e)}documentBlur(t){this.end(t),this._scopeFire("interactions:blur",{event:t,type:"blur",interaction:this})}end(t){let e;this._ending=!0,t=t||this._latestPointer.event,this.interacting()&&(e=this._doPhase({event:t,interaction:this,phase:"end"})),this._ending=!1,!0===e&&this.stop()}currentAction(){return this._interacting?this.prepared.name:null}interacting(){return this._interacting}stop(){this._scopeFire("interactions:stop",{interaction:this}),this.interactable=this.element=null,this._interacting=!1,this._stopped=!0,this.prepared.name=this.prevEvent=null}getPointerIndex(t){const e=Rt(t);return"mouse"===this.pointerType||"pen"===this.pointerType?this.pointers.length-1:N(this.pointers,t=>t.id===e)}getPointerInfo(t){return this.pointers[this.getPointerIndex(t)]}updatePointer(t,e,n,i){const r=Rt(t);let o=this.getPointerIndex(t),s=this.pointers[o];return i=!1!==i&&(i||/(down|start)$/i.test(e.type)),s?s.pointer=t:(s=new Zt(r,t,e,null,null),o=this.pointers.length,this.pointers.push(s)),kt(this.coords.cur,this.pointers.map(t=>t.pointer),this._now()),zt(this.coords.delta,this.coords.prev,this.coords.cur),i&&(this.pointerIsDown=!0,s.downTime=this.coords.cur.timeStamp,s.downTarget=n,Ot(this.downPointer,t),this.interacting()||(Tt(this.coords.start,this.coords.cur),Tt(this.coords.prev,this.coords.cur),this.downEvent=e,this.pointerWasMoved=!1)),this._updateLatestPointer(t,e,n),this._scopeFire("interactions:update-pointer",{pointer:t,event:e,eventTarget:n,down:i,pointerInfo:s,pointerIndex:o,interaction:this}),o}removePointer(t,e){const n=this.getPointerIndex(t);if(-1===n)return;const i=this.pointers[n];this._scopeFire("interactions:remove-pointer",{pointer:t,event:e,eventTarget:null,pointerIndex:n,pointerInfo:i,interaction:this}),this.pointers.splice(n,1),this.pointerIsDown=!1}_updateLatestPointer(t,e,n){this._latestPointer.pointer=t,this._latestPointer.event=e,this._latestPointer.eventTarget=n}destroy(){this._latestPointer.pointer=null,this._latestPointer.event=null,this._latestPointer.eventTarget=null}_createPreparedEvent(t,e,n,i){return new yt(this,t,this.prepared.name,e,this.element,n,i)}_fireEvent(t){this.interactable.fire(t),(!this.prevEvent||t.timeStamp>=this.prevEvent.timeStamp)&&(this.prevEvent=t)}_doPhase(t){const{event:e,phase:n,preEnd:i,type:r}=t,{rect:o}=this;o&&"move"===n&&(pt(this.edges,o,this.coords.delta[this.interactable.options.deltaSource]),o.width=o.right-o.left,o.height=o.bottom-o.top);const s=this._scopeFire("interactions:before-action-"+n,t);if(!1===s)return!1;const a=t.iEvent=this._createPreparedEvent(e,n,i,r);return this._scopeFire("interactions:action-"+n,t),"start"===n&&(this.prevEvent=a),this._fireEvent(a),this._scopeFire("interactions:after-action-"+n,t),!0}_now(){return Date.now()}}var ee=te;function ne(t){return/^(always|never|auto)$/.test(t)?(this.options.preventDefault=t,this):R.bool(t)?(this.options.preventDefault=t?"always":"never",this):this.options.preventDefault}function ie(t,e,n){const i=t.options.preventDefault;if("never"!==i)if("always"!==i){if(e.events.supportsPassive&&/^touch(start|move)$/.test(n.type)){const t=S(n.target).document,i=e.getDocOptions(t);if(!i||!i.events||!1!==i.events.passive)return}/^(mouse|pointer|touch)*(down|start)/i.test(n.type)||R.element(n.target)&&nt(n.target,"input,select,textarea,[contenteditable=true],[contenteditable=true] *")||n.preventDefault()}else n.preventDefault()}function re({interaction:t,event:e}){t.interactable&&t.interactable.checkAndPreventDefault(e)}function oe(t){const{Interactable:e}=t;e.prototype.preventDefault=ne,e.prototype.checkAndPreventDefault=function(e){return ie(this,t,e)},t.interactions.docEvents.push({type:"dragstart",listener(e){for(const n of t.interactions.list)if(n.element&&(n.element===e.target||Q(n.element,e.target)))return void n.interactable.checkAndPreventDefault(e)}})}var se={id:"core/interactablePreventDefault",install:oe,listeners:["down","move","up","cancel"].reduce((t,e)=>(t["interactions:"+e]=re,t),{})};const ae={methodOrder:["simulationResume","mouseOrPen","hasPointer","idle"],search(t){for(const e of ae.methodOrder){const n=ae[e](t);if(n)return n}return null},simulationResume({pointerType:t,eventType:e,eventTarget:n,scope:i}){if(!/down|start/i.test(e))return null;for(const r of i.interactions.list){let e=n;if(r.simulation&&r.simulation.allowResume&&r.pointerType===t)while(e){if(e===r.element)return r;e=et(e)}}return null},mouseOrPen({pointerId:t,pointerType:e,eventType:n,scope:i}){if("mouse"!==e&&"pen"!==e)return null;let r;for(const o of i.interactions.list)if(o.pointerType===e){if(o.simulation&&!ce(o,t))continue;if(o.interacting())return o;r||(r=o)}if(r)return r;for(const o of i.interactions.list)if(o.pointerType===e&&(!/down/i.test(n)||!o.simulation))return o;return null},hasPointer({pointerId:t,scope:e}){for(const n of e.interactions.list)if(ce(n,t))return n;return null},idle({pointerType:t,scope:e}){for(const n of e.interactions.list){if(1===n.pointers.length){const t=n.interactable;if(t&&(!t.options.gesture||!t.options.gesture.enabled))continue}else if(n.pointers.length>=2)continue;if(!n.interacting()&&t===n.pointerType)return n}return null}};function ce(t,e){return t.pointers.some(({id:t})=>t===e)}var le=ae;const ue=["pointerDown","pointerMove","pointerUp","updatePointer","removePointer","windowBlur"];function he(t){const e={};for(const o of ue)e[o]=de(o,t);const n=C.pEventTypes;let i;function r(){for(const e of t.interactions.list)if(e.pointerIsDown&&"touch"===e.pointerType&&!e._interacting)for(const n of e.pointers)t.documents.some(({doc:t})=>Q(t,n.downTarget))||e.removePointer(n.pointer,n.event)}i=m.PointerEvent?[{type:n.down,listener:r},{type:n.down,listener:e.pointerDown},{type:n.move,listener:e.pointerMove},{type:n.up,listener:e.pointerUp},{type:n.cancel,listener:e.pointerUp}]:[{type:"mousedown",listener:e.pointerDown},{type:"mousemove",listener:e.pointerMove},{type:"mouseup",listener:e.pointerUp},{type:"touchstart",listener:r},{type:"touchstart",listener:e.pointerDown},{type:"touchmove",listener:e.pointerMove},{type:"touchend",listener:e.pointerUp},{type:"touchcancel",listener:e.pointerUp}],i.push({type:"blur",listener(e){for(const n of t.interactions.list)n.documentBlur(e)}}),t.prevTouchTime=0,t.Interaction=class extends ee{get pointerMoveTolerance(){return t.interactions.pointerMoveTolerance}set pointerMoveTolerance(e){t.interactions.pointerMoveTolerance=e}_now(){return t.now()}},t.interactions={list:[],new(e){e.scopeFire=(e,n)=>t.fire(e,n);const n=new t.Interaction(e);return t.interactions.list.push(n),n},listeners:e,docEvents:i,pointerMoveTolerance:1},t.usePlugin(se)}function de(t,e){return function(n){const i=e.interactions.list,r=Nt(n),[o,s]=Wt(n),a=[];if(/^touch/.test(n.type)){e.prevTouchTime=e.now();for(const t of n.changedTouches){const i=t,c=Rt(i),l={pointer:i,pointerId:c,pointerType:r,eventType:n.type,eventTarget:o,curEventTarget:s,scope:e},u=fe(l);a.push([l.pointer,l.eventTarget,l.curEventTarget,u])}}else{let t=!1;if(!C.supportsPointerEvent&&/mouse/.test(n.type)){for(let e=0;epe(t,"add"),"scope:remove-document":t=>pe(t,"remove"),"interactable:unset":({interactable:t},e)=>{for(let n=e.interactions.list.length-1;n>=0;n--){const i=e.interactions.list[n];i.interactable===t&&(i.stop(),e.fire("interactions:destroy",{interaction:i}),i.destroy(),e.interactions.list.length>2&&e.interactions.list.splice(n,1))}}},onDocSignal:pe,doOnInteractions:de,methodNames:ue};var me=ge;class ve{constructor(){this.id="__interact_scope_"+Math.floor(100*Math.random()),this.isInitialized=!1,this.listenerMaps=[],this.browser=C,this.defaults=$(bt),this.Eventable=J,this.actions={map:{},phases:{start:!0,move:!0,end:!0},methodDict:{},phaselessTypes:{}},this.interactStatic=Ut(this),this.InteractEvent=yt,this.Interactable=void 0,this.interactables=new St(this),this._win=void 0,this.document=void 0,this.window=void 0,this.documents=[],this._plugins={list:[],map:{}},this.onWindowUnload=t=>this.removeDocument(t.target);const t=this;this.Interactable=class extends wt{get _defaults(){return t.defaults}set(e){return super.set(e),t.fire("interactable:set",{options:e,interactable:this}),this}unset(){super.unset(),t.interactables.list.splice(t.interactables.list.indexOf(this),1),t.fire("interactable:unset",{interactable:this})}}}addListeners(t,e){this.listenerMaps.push({id:e,map:t})}fire(t,e){for(const{map:{[t]:n}}of this.listenerMaps)if(n&&!1===n(e,this,t))return!1}init(t){return this.isInitialized?this:be(this,t)}pluginIsInstalled(t){return this._plugins.map[t.id]||-1!==this._plugins.list.indexOf(t)}usePlugin(t,e){if(!this.isInitialized)return this;if(this.pluginIsInstalled(t))return this;if(t.id&&(this._plugins.map[t.id]=t),this._plugins.list.push(t),t.install&&t.install(this,e),t.listeners&&t.before){let e=0;const n=this.listenerMaps.length,i=t.before.reduce((t,e)=>(t[e]=!0,t[ye(e)]=!0,t),{});for(;exe.init(t);function Oe(t){const{Interactable:e}=t;e.prototype.getAction=function(e,n,i,r){const o=Te(this,n,i,r,t);return this.options.actionChecker?this.options.actionChecker(e,n,o,this,r,i):o},e.prototype.ignoreFrom=qt((function(t){return this._backCompatOption("ignoreFrom",t)}),"Interactable.ignoreFrom() has been deprecated. Use Interactble.draggable({ignoreFrom: newValue})."),e.prototype.allowFrom=qt((function(t){return this._backCompatOption("allowFrom",t)}),"Interactable.allowFrom() has been deprecated. Use Interactble.draggable({allowFrom: newValue})."),e.prototype.actionChecker=Me,e.prototype.styleCursor=ze}function Te(t,e,n,i,r){const o=t.getRect(i),s=e.buttons||{0:1,1:4,3:8,4:16}[e.button],a={action:null,interactable:t,interaction:n,element:i,rect:o,buttons:s};return r.fire("auto-start:check",a),a.action}function ze(t){return R.bool(t)?(this.options.styleCursor=t,this):null===t?(delete this.options.styleCursor,this):this.options.styleCursor}function Me(t){return R.func(t)?(this.options.actionChecker=t,this):null===t?(delete this.options.actionChecker,this):this.options.actionChecker}"object"===typeof window&&window&&Ee(window);var _e={id:"auto-start/interactableMethods",install:Oe};function Pe(t){const{interactStatic:e,defaults:n}=t;t.usePlugin(_e),n.base.actionChecker=null,n.base.styleCursor=!0,F(n.perAction,{manualStart:!1,max:1/0,maxPerElement:1,allowFrom:null,ignoreFrom:null,mouseButtons:1}),e.maxInteractions=e=>Be(e,t),t.autoStart={maxInteractions:1/0,withinInteractionLimit:Le,cursorElement:null}}function Ie({interaction:t,pointer:e,event:n,eventTarget:i},r){if(t.interacting())return;const o=Ce(t,e,n,i,r);He(t,o,r)}function je({interaction:t,pointer:e,event:n,eventTarget:i},r){if("mouse"!==t.pointerType||t.pointerIsDown||t.interacting())return;const o=Ce(t,e,n,i,r);He(t,o,r)}function De(t,e){const{interaction:n}=t;if(!n.pointerIsDown||n.interacting()||!n.pointerWasMoved||!n.prepared.name)return;e.fire("autoStart:before-start",t);const{interactable:i}=n,r=n.prepared.name;r&&i&&(i.options[r].manualStart||!Le(i,n.element,n.prepared,e)?n.stop():(n.start(n.prepared,i,n.element),We(n,e)))}function Re({interaction:t},e){const{interactable:n}=t;n&&n.options.styleCursor&&Ne(t.element,"",e)}function ke(t,e,n,i,r){return e.testIgnoreAllow(e.options[t.name],n,i)&&e.options[t.name].enabled&&Le(e,n,t,r)?t:null}function Ae(t,e,n,i,r,o,s){for(let a=0,c=i.length;a=a)return!1;if(h.interactable===t){if(l+=i===n.name?1:0,l>=o)return!1;if(h.element===e&&(u++,i===n.name&&u>=s))return!1}}}return a>0}function Be(t,e){return R.number(t)?(e.autoStart.maxInteractions=t,this):e.autoStart.maxInteractions}function Ne(t,e,n){const{cursorElement:i}=n.autoStart;i&&i!==t&&(i.style.cursor=""),t.ownerDocument.documentElement.style.cursor=e,t.style.cursor=e,n.autoStart.cursorElement=e?t:null}function We(t,e){const{interactable:n,element:i,prepared:r}=t;if("mouse"!==t.pointerType||!n||!n.options.styleCursor)return void(e.autoStart.cursorElement&&Ne(e.autoStart.cursorElement,"",e));let o="";if(r.name){const s=n.options[r.name].cursorChecker;o=R.func(s)?s(r,n,i,t._interacting):e.actions.map[r.name].getCursor(r)}Ne(t.element,o||"",e)}const $e={id:"auto-start/base",before:["actions"],install:Pe,listeners:{"interactions:down":Ie,"interactions:move":(t,e)=>{je(t,e),De(t,e)},"interactions:stop":Re},maxInteractions:Be,withinInteractionLimit:Le,validateAction:ke};var Fe=$e;function Ge({interaction:t,eventTarget:e,dx:n,dy:i},r){if("drag"!==t.prepared.name)return;const o=Math.abs(n),s=Math.abs(i),a=t.interactable.options.drag,c=a.startAxis,l=o>s?"x":o{t.autoStartHoldTimer=null},"autoStart:prepared":({interaction:t})=>{const e=Ve(t);e>0&&(t.autoStartHoldTimer=setTimeout(()=>{t.start(t.prepared,t.interactable,t.element)},e))},"interactions:move":({interaction:t,duplicate:e})=>{t.autoStartHoldTimer&&t.pointerWasMoved&&!e&&(clearTimeout(t.autoStartHoldTimer),t.autoStartHoldTimer=null)},"autoStart:before-start":({interaction:t})=>{const e=Ve(t);e>0&&(t.prepared.name=null)}},getHoldDuration:Ve};var Ze=Ue,Ke={id:"auto-start",install(t){t.usePlugin(Fe),t.usePlugin(Ze),t.usePlugin(Ye)}};function Je(t){const{defaults:e,actions:n}=t;t.autoScroll=Qe,Qe.now=()=>t.now(),n.phaselessTypes.autoscroll=!0,e.perAction.autoScroll=Qe.defaults}"object"===typeof window&&window&&Ee(window),Se.use(Ke);const Qe={defaults:{enabled:!1,margin:60,container:null,speed:300},now:Date.now,interaction:null,i:0,x:0,y:0,isScrolling:!1,prevTime:0,margin:0,speed:0,start(t){Qe.isScrolling=!0,V.cancel(Qe.i),t.autoScroll=Qe,Qe.interaction=t,Qe.prevTime=Qe.now(),Qe.i=V.request(Qe.scroll)},stop(){Qe.isScrolling=!1,Qe.interaction&&(Qe.interaction.autoScroll=null),V.cancel(Qe.i)},scroll(){const{interaction:t}=Qe,{interactable:e,element:n}=t,i=t.prepared.name,r=e.options[i].autoScroll,o=tn(r.container,e,n),s=Qe.now(),a=(s-Qe.prevTime)/1e3,c=r.speed*a;if(c>=1){const i={x:Qe.x*c,y:Qe.y*c};if(i.x||i.y){const r=en(o);R.window(o)?o.scrollBy(i.x,i.y):o&&(o.scrollLeft+=i.x,o.scrollTop+=i.y);const s=en(o),a={x:s.x-r.x,y:s.y-r.y};(a.x||a.y)&&e.fire({type:"autoscroll",target:n,interactable:e,delta:a,interaction:t,container:o})}Qe.prevTime=s}Qe.isScrolling&&(V.cancel(Qe.i),Qe.i=V.request(Qe.scroll))},check(t,e){var n;const i=t.options;return null==(n=i[e].autoScroll)?void 0:n.enabled},onInteractionMove({interaction:t,pointer:e}){if(!t.interacting()||!Qe.check(t.interactable,t.prepared.name))return;if(t.simulation)return void(Qe.x=Qe.y=0);let n,i,r,o;const{interactable:s,element:a}=t,c=t.prepared.name,l=s.options[c].autoScroll,u=tn(l.container,s,a);if(R.window(u))o=e.clientXu.innerWidth-Qe.margin,r=e.clientY>u.innerHeight-Qe.margin;else{const t=st(u);o=e.clientXt.right-Qe.margin,r=e.clientY>t.bottom-Qe.margin}Qe.x=i?1:o?-1:0,Qe.y=r?1:n?-1:0,Qe.isScrolling||(Qe.margin=l.margin,Qe.speed=l.speed,Qe.start(t))}};function tn(t,e,n){return(R.string(t)?lt(t,e,n):t)||S(n)}function en(t){return R.window(t)&&(t=window.document.body),{x:t.scrollLeft,y:t.scrollTop}}const nn={id:"auto-scroll",install:Je,listeners:{"interactions:new":({interaction:t})=>{t.autoScroll=null},"interactions:destroy":({interaction:t})=>{t.autoScroll=null,Qe.stop(),Qe.interaction&&(Qe.interaction=null)},"interactions:stop":Qe.stop,"interactions:action-move":t=>Qe.onInteractionMove(t)}};var rn=nn;function on(t){const{actions:e,Interactable:n,defaults:i}=t;n.prototype.draggable=ln.draggable,e.map.drag=ln,e.methodDict.drag="draggable",i.actions.drag=ln.defaults}function sn({interaction:t}){if("drag"!==t.prepared.name)return;const e=t.prepared.axis;"x"===e?(t.coords.cur.page.y=t.coords.start.page.y,t.coords.cur.client.y=t.coords.start.client.y,t.coords.velocity.client.y=0,t.coords.velocity.page.y=0):"y"===e&&(t.coords.cur.page.x=t.coords.start.page.x,t.coords.cur.client.x=t.coords.start.client.x,t.coords.velocity.client.x=0,t.coords.velocity.page.x=0)}function an({iEvent:t,interaction:e}){if("drag"!==e.prepared.name)return;const n=e.prepared.axis;if("x"===n||"y"===n){const i="x"===n?"y":"x";t.page[i]=e.coords.start.page[i],t.client[i]=e.coords.start.client[i],t.delta[i]=0}}"object"===typeof window&&window&&Ee(window),Se.use(rn);const cn=function(t){return R.object(t)?(this.options.drag.enabled=!1!==t.enabled,this.setPerAction("drag",t),this.setOnEvents("drag",t),/^(xy|x|y|start)$/.test(t.lockAxis)&&(this.options.drag.lockAxis=t.lockAxis),/^(xy|x|y)$/.test(t.startAxis)&&(this.options.drag.startAxis=t.startAxis),this):R.bool(t)?(this.options.drag.enabled=t,this):this.options.drag},ln={id:"actions/drag",install:on,listeners:{"interactions:before-action-move":sn,"interactions:action-resume":sn,"interactions:action-move":an,"auto-start:check":t=>{const{interaction:e,interactable:n,buttons:i}=t,r=n.options.drag;if(r&&r.enabled&&(!e.pointerIsDown||!/mouse|pointer/.test(e.pointerType)||0!==(i&n.options.drag.mouseButtons)))return t.action={name:"drag",axis:"start"===r.lockAxis?r.startAxis:r.lockAxis},!1}},draggable:cn,beforeMove:sn,move:an,defaults:{startAxis:"xy",lockAxis:"xy"},getCursor(){return"move"}};var un=ln;function hn(t){const{actions:e,browser:n,Interactable:i,defaults:r}=t;xn.cursors=gn(n),xn.defaultMargin=n.supportsTouch||n.supportsPointerEvent?20:10,i.prototype.resizable=function(e){return fn(this,e,t)},e.map.resize=xn,e.methodDict.resize="resizable",r.actions.resize=xn.defaults}function dn(t){const{interaction:e,interactable:n,element:i,rect:r,buttons:o}=t;if(!r)return;const s=F({},e.coords.cur.page),a=n.options.resize;if(a&&a.enabled&&(!e.pointerIsDown||!/mouse|pointer/.test(e.pointerType)||0!==(o&a.mouseButtons))){if(R.object(a.edges)){const n={left:!1,right:!1,top:!1,bottom:!1};for(const t in n)n[t]=pn(t,a.edges[t],s,e._latestPointer.eventTarget,i,r,a.margin||xn.defaultMargin);n.left=n.left&&!n.right,n.top=n.top&&!n.bottom,(n.left||n.right||n.top||n.bottom)&&(t.action={name:"resize",edges:n})}else{const e="y"!==a.axis&&s.x>r.right-xn.defaultMargin,n="x"!==a.axis&&s.y>r.bottom-xn.defaultMargin;(e||n)&&(t.action={name:"resize",axes:(e?"x":"")+(n?"y":"")})}return!t.action&&void 0}}function fn(t,e,n){return R.object(e)?(t.options.resize.enabled=!1!==e.enabled,t.setPerAction("resize",e),t.setOnEvents("resize",e),R.string(e.axis)&&/^x$|^y$|^xy$/.test(e.axis)?t.options.resize.axis=e.axis:null===e.axis&&(t.options.resize.axis=n.defaults.actions.resize.axis),R.bool(e.preserveAspectRatio)?t.options.resize.preserveAspectRatio=e.preserveAspectRatio:R.bool(e.square)&&(t.options.resize.square=e.square),t):R.bool(e)?(t.options.resize.enabled=e,t):t.options.resize}function pn(t,e,n,i,r,o,s){if(!e)return!1;if(!0===e){const e=R.number(o.width)?o.width:o.right-o.left,i=R.number(o.height)?o.height:o.bottom-o.top;if(s=Math.min(s,Math.abs(("left"===t||"right"===t?e:i)/2)),e<0&&("left"===t?t="right":"right"===t&&(t="left")),i<0&&("top"===t?t="bottom":"bottom"===t&&(t="top")),"left"===t)return n.x<(e>=0?o.left:o.right)+s;if("top"===t)return n.y<(i>=0?o.top:o.bottom)+s;if("right"===t)return n.x>(e>=0?o.right:o.left)-s;if("bottom"===t)return n.y>(i>=0?o.bottom:o.top)-s}return!!R.element(i)&&(R.element(e)?e===i:it(i,e,r))}function gn(t){return t.isIe9?{x:"e-resize",y:"s-resize",xy:"se-resize",top:"n-resize",left:"w-resize",bottom:"s-resize",right:"e-resize",topleft:"se-resize",bottomright:"se-resize",topright:"ne-resize",bottomleft:"ne-resize"}:{x:"ew-resize",y:"ns-resize",xy:"nwse-resize",top:"ns-resize",left:"ew-resize",bottom:"ns-resize",right:"ew-resize",topleft:"nwse-resize",bottomright:"nwse-resize",topright:"nesw-resize",bottomleft:"nesw-resize"}}function mn({iEvent:t,interaction:e}){if("resize"!==e.prepared.name||!e.prepared.edges)return;const n=t,i=e.rect;e._rects={start:F({},i),corrected:F({},i),previous:F({},i),delta:{left:0,right:0,width:0,top:0,bottom:0,height:0}},n.edges=e.prepared.edges,n.rect=e._rects.corrected,n.deltaRect=e._rects.delta}function vn({iEvent:t,interaction:e}){if("resize"!==e.prepared.name||!e.prepared.edges)return;const n=t,i=e.interactable.options.resize,r=i.invert,o="reposition"===r||"negate"===r,s=e.rect,{start:a,corrected:c,delta:l,previous:u}=e._rects;if(F(u,c),o){if(F(c,s),"reposition"===r){if(c.top>c.bottom){const t=c.top;c.top=c.bottom,c.bottom=t}if(c.left>c.right){const t=c.left;c.left=c.right,c.right=t}}}else c.top=Math.min(s.top,a.bottom),c.bottom=Math.max(s.bottom,a.top),c.left=Math.min(s.left,a.right),c.right=Math.max(s.right,a.left);c.width=c.right-c.left,c.height=c.bottom-c.top;for(const h in c)l[h]=c[h]-u[h];n.edges=e.prepared.edges,n.rect=c,n.deltaRect=l}function bn({iEvent:t,interaction:e}){if("resize"!==e.prepared.name||!e.prepared.edges)return;const n=t;n.edges=e.prepared.edges,n.rect=e._rects.corrected,n.deltaRect=e._rects.delta}function yn({iEvent:t,interaction:e}){if("resize"!==e.prepared.name||!e.resizeAxes)return;const n=e.interactable.options,i=t;n.resize.square?("y"===e.resizeAxes?i.delta.x=i.delta.y:i.delta.y=i.delta.x,i.axes="xy"):(i.axes=e.resizeAxes,"x"===e.resizeAxes?i.delta.y=0:"y"===e.resizeAxes&&(i.delta.x=0))}"object"===typeof window&&window&&Ee(window),Se.use(un);const xn={id:"actions/resize",before:["actions/drag"],install:hn,listeners:{"interactions:new":({interaction:t})=>{t.resizeAxes="xy"},"interactions:action-start":t=>{mn(t),yn(t)},"interactions:action-move":t=>{vn(t),yn(t)},"interactions:action-end":bn,"auto-start:check":dn},defaults:{square:!1,preserveAspectRatio:!1,axis:"xy",margin:NaN,edges:null,invert:"none"},cursors:null,getCursor({edges:t,axis:e,name:n}){const i=xn.cursors;let r=null;if(e)r=i[n+e];else if(t){let e="";for(const n of["top","bottom","left","right"])t[n]&&(e+=n);r=i[e]}return r},defaultMargin:null};var wn=xn;"object"===typeof window&&window&&Ee(window),Se.use(wn);var Sn=()=>{},En=()=>{},On=t=>{const e=[["x","y"],["left","top"],["right","bottom"],["width","height"]].filter(([e,n])=>e in t||n in t),n=(n,i)=>{const{range:r,limits:o={left:-1/0,right:1/0,top:-1/0,bottom:1/0},offset:s={x:0,y:0}}=t,a={range:r,grid:t,x:null,y:null};for(const[c,l]of e){const e=Math.round((n-s.x)/t[c]),r=Math.round((i-s.y)/t[l]);a[c]=Math.max(o.left,Math.min(o.right,e*t[c]+s.x)),a[l]=Math.max(o.top,Math.min(o.bottom,r*t[l]+s.y))}return a};return n.grid=t,n.coordFields=e,n};const Tn={id:"snappers",install(t){const{interactStatic:e}=t;e.snappers=F(e.snappers||{},i),e.createSnapGrid=e.snappers.grid}};var zn=Tn;class Mn{constructor(t){this.states=[],this.startOffset={left:0,right:0,top:0,bottom:0},this.startDelta=null,this.result=null,this.endResult=null,this.edges=void 0,this.interaction=void 0,this.interaction=t,this.result=_n()}start({phase:t},e){const{interaction:n}=this,i=Pn(n);this.prepareStates(i),this.edges=F({},n.edges),this.startOffset=In(n.rect,e),this.startDelta={x:0,y:0};const r={phase:t,pageCoords:e,preEnd:!1};this.result=_n(),this.startAll(r);const o=this.result=this.setAll(r);return o}fillArg(t){const{interaction:e}=this;t.interaction=e,t.interactable=e.interactable,t.element=e.element,t.rect=t.rect||e.rect,t.edges=this.edges,t.startOffset=this.startOffset}startAll(t){this.fillArg(t);for(const e of this.states)e.methods.start&&(t.state=e,e.methods.start(t))}setAll(t){this.fillArg(t);const{phase:e,preEnd:n,skipModifiers:i,rect:r}=t;t.coords=F({},t.pageCoords),t.rect=F({},r);const o=i?this.states.slice(i):this.states,s=_n(t.coords,t.rect);for(const l of o){const{options:i}=l,r=F({},t.coords);let o=null;l.methods.set&&this.shouldDo(i,n,e)&&(t.state=l,o=l.methods.set(t),pt(this.interaction.edges,t.rect,{x:t.coords.x-r.x,y:t.coords.y-r.y})),s.eventProps.push(o)}s.delta.x=t.coords.x-t.pageCoords.x,s.delta.y=t.coords.y-t.pageCoords.y,s.rectDelta.left=t.rect.left-r.left,s.rectDelta.right=t.rect.right-r.right,s.rectDelta.top=t.rect.top-r.top,s.rectDelta.bottom=t.rect.bottom-r.bottom;const a=this.result.coords,c=this.result.rect;if(a&&c){const t=s.rect.left!==c.left||s.rect.right!==c.right||s.rect.top!==c.top||s.rect.bottom!==c.bottom;s.changed=t||a.x!==s.coords.x||a.y!==s.coords.y}return s}applyToInteraction(t){const{interaction:e}=this,{phase:n}=t,i=e.coords.cur,r=e.coords.start,{result:o,startDelta:s}=this,a=o.delta;"start"===n&&F(this.startDelta,o.delta);for(const[u,h]of[[r,s],[i,a]])u.page.x+=h.x,u.page.y+=h.y,u.client.x+=h.x,u.client.y+=h.y;const{rectDelta:c}=this.result,l=t.rect||e.rect;l.left+=c.left,l.right+=c.right,l.top+=c.top,l.bottom+=c.bottom,l.width=l.right-l.left,l.height=l.bottom-l.top}setAndApply(t){const{interaction:e}=this,{phase:n,preEnd:i,skipModifiers:r}=t,o=this.setAll({preEnd:i,phase:n,pageCoords:t.modifiedCoords||e.coords.cur.page});if(this.result=o,!o.changed&&(!r||r$(t)),this.result=_n(F({},t.result.coords),F({},t.result.rect))}destroy(){for(const t in this)this[t]=null}}function _n(t,e){return{rect:e,coords:t,delta:{x:0,y:0},rectDelta:{left:0,right:0,top:0,bottom:0},eventProps:[],changed:!0}}function Pn(t){const e=t.interactable.options[t.prepared.name],n=e.modifiers;return n&&n.length?n:["snap","snapSize","snapEdges","restrict","restrictEdges","restrictSize"].map(t=>{const n=e[t];return n&&n.enabled&&{options:n,methods:n._methods}}).filter(t=>!!t)}function In(t,e){return t?{left:e.x-t.left,top:e.y-t.top,right:t.right-e.x,bottom:t.bottom-e.y}:{left:0,top:0,right:0,bottom:0}}function jn(t,e){const{defaults:n}=t,i={start:t.start,set:t.set,beforeEnd:t.beforeEnd,stop:t.stop},r=t=>{const r=t||{};r.enabled=!1!==r.enabled;for(const e in n)e in r||(r[e]=n[e]);const o={options:r,methods:i,name:e,enable:()=>(r.enabled=!0,o),disable:()=>(r.enabled=!1,o)};return o};return e&&"string"===typeof e&&(r._defaults=n,r._methods=i),r}function Dn({iEvent:t,interaction:{modification:{result:e}}}){e&&(t.modifiers=e.eventProps)}const Rn={id:"modifiers/base",before:["actions"],install:t=>{t.defaults.perAction.modifiers=[]},listeners:{"interactions:new":({interaction:t})=>{t.modification=new Mn(t)},"interactions:before-action-start":t=>{const{modification:e}=t.interaction;e.start(t,t.interaction.coords.start.page),t.interaction.edges=e.edges,e.applyToInteraction(t)},"interactions:before-action-move":t=>t.interaction.modification.setAndApply(t),"interactions:before-action-end":t=>t.interaction.modification.beforeEnd(t),"interactions:action-start":Dn,"interactions:action-move":Dn,"interactions:action-end":Dn,"interactions:after-action-start":t=>t.interaction.modification.restoreInteractionCoords(t),"interactions:after-action-move":t=>t.interaction.modification.restoreInteractionCoords(t),"interactions:stop":t=>t.interaction.modification.stop(t)}};var kn=Rn;const An={start(t){const{state:e,rect:n,edges:i,pageCoords:r}=t;let{ratio:o}=e.options;const{equalDelta:s,modifiers:a}=e.options;"preserve"===o&&(o=n.width/n.height),e.startCoords=F({},r),e.startRect=F({},n),e.ratio=o,e.equalDelta=s;const c=e.linkedEdges={top:i.top||i.left&&!i.bottom,left:i.left||i.top&&!i.right,bottom:i.bottom||i.right&&!i.top,right:i.right||i.bottom&&!i.left};if(e.xIsPrimaryAxis=!(!i.left&&!i.right),e.equalDelta)e.edgeSign=(c.left?1:-1)*(c.top?1:-1);else{const t=e.xIsPrimaryAxis?c.top:c.left;e.edgeSign=t?-1:1}if(F(t.edges,c),!a||!a.length)return;const l=new Mn(t.interaction);l.copyFrom(t.interaction.modification),l.prepareStates(a),e.subModification=l,l.startAll({...t})},set(t){const{state:e,rect:n,coords:i}=t,r=F({},i),o=e.equalDelta?Cn:Hn;if(o(e,e.xIsPrimaryAxis,i,n),!e.subModification)return null;const s=F({},n);pt(e.linkedEdges,s,{x:i.x-r.x,y:i.y-r.y});const a=e.subModification.setAll({...t,rect:s,edges:e.linkedEdges,pageCoords:i,prevCoords:i,prevRect:s}),{delta:c}=a;if(a.changed){const t=Math.abs(c.x)>Math.abs(c.y);o(e,t,a.coords,a.rect),F(i,a.coords)}return a.eventProps},defaults:{ratio:"preserve",equalDelta:!1,modifiers:[],enabled:!1}};function Cn({startCoords:t,edgeSign:e},n,i){n?i.y=t.y+(i.x-t.x)*e:i.x=t.x+(i.y-t.y)*e}function Hn({startRect:t,startCoords:e,ratio:n,edgeSign:i},r,o,s){if(r){const r=s.width/n;o.y=e.y+(r-t.height)*i}else{const r=s.height*n;o.x=e.x+(r-t.width)*i}}var Ln=jn(An,"aspectRatio");const Bn=()=>{};Bn._defaults={};var Nn=Bn;function Wn({rect:t,startOffset:e,state:n,interaction:i,pageCoords:r}){const{options:o}=n,{elementRect:s}=o,a=F({left:0,top:0,right:0,bottom:0},o.offset||{});if(t&&s){const n=Fn(o.restriction,i,r);if(n){const e=n.right-n.left-t.width,i=n.bottom-n.top-t.height;e<0&&(a.left+=e,a.right+=e),i<0&&(a.top+=i,a.bottom+=i)}a.left+=e.left-t.width*s.left,a.top+=e.top-t.height*s.top,a.right+=e.right-t.width*(1-s.right),a.bottom+=e.bottom-t.height*(1-s.bottom)}n.offset=a}function $n({coords:t,interaction:e,state:n}){const{options:i,offset:r}=n,o=Fn(i.restriction,e,t);if(!o)return;const s=dt(o);t.x=Math.max(Math.min(s.right-r.right,t.x),s.left+r.left),t.y=Math.max(Math.min(s.bottom-r.bottom,t.y),s.top+r.top)}function Fn(t,e,n){return R.func(t)?ut(t,e.interactable,e.element,[n.x,n.y,e]):ut(t,e.interactable,e.element)}const Gn={restriction:null,elementRect:null,offset:null,endOnly:!1,enabled:!1},Xn={start:Wn,set:$n,defaults:Gn};var Yn=jn(Xn,"restrict");const qn={top:1/0,left:1/0,bottom:-1/0,right:-1/0},Vn={top:-1/0,left:-1/0,bottom:1/0,right:1/0};function Un({interaction:t,startOffset:e,state:n}){const{options:i}=n;let r;if(i){const e=Fn(i.offset,t,t.coords.start.page);r=ht(e)}r=r||{x:0,y:0},n.offset={top:r.y+e.top,left:r.x+e.left,bottom:r.y-e.bottom,right:r.x-e.right}}function Zn({coords:t,edges:e,interaction:n,state:i}){const{offset:r,options:o}=i;if(!e)return;const s=F({},t),a=Fn(o.inner,n,s)||{},c=Fn(o.outer,n,s)||{};Kn(a,qn),Kn(c,Vn),e.top?t.y=Math.min(Math.max(c.top+r.top,s.y),a.top+r.top):e.bottom&&(t.y=Math.max(Math.min(c.bottom+r.bottom,s.y),a.bottom+r.bottom)),e.left?t.x=Math.min(Math.max(c.left+r.left,s.x),a.left+r.left):e.right&&(t.x=Math.max(Math.min(c.right+r.right,s.x),a.right+r.right))}function Kn(t,e){for(const n of["top","left","bottom","right"])n in t||(t[n]=e[n]);return t}const Jn={inner:null,outer:null,offset:null,endOnly:!1,enabled:!1},Qn={noInner:qn,noOuter:Vn,start:Un,set:Zn,defaults:Jn};var ti=jn(Qn,"restrictEdges");const ei=F({get elementRect(){return{top:0,left:0,bottom:1,right:1}},set elementRect(t){}},Xn.defaults),ni={start:Xn.start,set:Xn.set,defaults:ei};var ii=jn(ni,"restrictRect");const ri={width:-1/0,height:-1/0},oi={width:1/0,height:1/0};function si(t){return Qn.start(t)}function ai(t){const{interaction:e,state:n,rect:i,edges:r}=t,{options:o}=n;if(!r)return;const s=ft(Fn(o.min,e,t.coords))||ri,a=ft(Fn(o.max,e,t.coords))||oi;n.options={endOnly:o.endOnly,inner:F({},Qn.noInner),outer:F({},Qn.noOuter)},r.top?(n.options.inner.top=i.bottom-s.height,n.options.outer.top=i.bottom-a.height):r.bottom&&(n.options.inner.bottom=i.top+s.height,n.options.outer.bottom=i.top+a.height),r.left?(n.options.inner.left=i.right-s.width,n.options.outer.left=i.right-a.width):r.right&&(n.options.inner.right=i.left+s.width,n.options.outer.right=i.left+a.width),Qn.set(t),n.options=o}const ci={min:null,max:null,endOnly:!1,enabled:!1},li={start:si,set:ai,defaults:ci};var ui=jn(li,"restrictSize");function hi(t){const{interaction:e,interactable:n,element:i,rect:r,state:o,startOffset:s}=t,{options:a}=o,c=a.offsetWithOrigin?fi(t):{x:0,y:0};let l;if("startCoords"===a.offset)l={x:e.coords.start.page.x,y:e.coords.start.page.y};else{const t=ut(a.offset,n,i,[e]);l=ht(t)||{x:0,y:0},l.x+=c.x,l.y+=c.y}const{relativePoints:u}=a;o.offsets=r&&u&&u.length?u.map((t,e)=>({index:e,relativePoint:t,x:s.left-r.width*t.x+l.x,y:s.top-r.height*t.y+l.y})):[F({index:0,relativePoint:null},l)]}function di(t){const{interaction:e,coords:n,state:i}=t,{options:r,offsets:o}=i,s=gt(e.interactable,e.element,e.prepared.name),a=F({},n),c=[];r.offsetWithOrigin||(a.x-=s.x,a.y-=s.y);for(const u of o){const t=a.x-u.x,n=a.y-u.y;for(let i=0,o=r.targets.length;i{}}:{id:Ci,install:Di,listeners:{"interactions:action-start":({interaction:t},e)=>{for(const n of Ri){const i=t.interactable&&t.interactable.options;i&&i.devTools&&i.devTools.ignore[n.name]||!n.perform(t)||e.logger.warn(Pi+n.text,...n.getInfo(t))}}},checks:Ri,CheckName:Mi,links:Ii,prefix:Pi};var Li=Hi;function Bi(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);e&&(i=i.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,i)}return n}function Ni(t){for(var e=1;ethis.cols?(this.innerX=0,this.innerW=this.w>this.cols?this.cols:this.w):(this.innerX=this.x,this.innerW=this.w);var t,e=this.calcPosition(this.innerX,this.innerY,this.innerW,this.innerH);this.isDragging&&(e.top=this.dragging.top,this.renderRtl?e.right=this.dragging.left:e.left=this.dragging.left),this.isResizing&&(e.width=this.resizing.width,e.height=this.resizing.height),t=this.useCssTransforms?this.renderRtl?Object(a["k"])(e.top,e.right,e.width,e.height):Object(a["j"])(e.top,e.left,e.width,e.height):this.renderRtl?Object(a["i"])(e.top,e.right,e.width,e.height):Object(a["h"])(e.top,e.left,e.width,e.height),this.style=t},emitContainerResized:function(){for(var t={},e=0,n=["width","height"];ethis.maxW&&(n.w=this.maxW),n.hthis.maxH&&(n.h=this.maxH),n.h<1&&(n.h=1),n.w<1&&(n.w=1),this.lastW=i,this.lastH=r,this.innerW===n.w&&this.innerH===n.h||this.$emit("resize",this.i,n.h,n.w,o.height,o.width),"resizeend"!==t.type||this.previousW===this.innerW&&this.previousH===this.innerH||this.$emit("resized",this.i,n.h,n.w,o.height,o.width),this.eventBus.$emit("resizeEvent",t.type,this.i,this.innerX,this.innerY,n.h,n.w)}}},handleDrag:function(t){if(!this.static&&!this.isResizing){var e=c(t);if(null!==e){var n,i=e.x,r=e.y,o={top:0,left:0};switch(t.type){case"dragstart":this.previousX=this.innerX,this.previousY=this.innerY;var s=t.target.offsetParent.getBoundingClientRect(),a=t.target.getBoundingClientRect(),l=a.left/this.transformScale,h=s.left/this.transformScale,d=a.right/this.transformScale,f=s.right/this.transformScale,p=a.top/this.transformScale,g=s.top/this.transformScale;this.renderRtl?o.left=-1*(d-f):o.left=l-h,o.top=p-g,this.dragging=o,this.isDragging=!0;break;case"dragend":if(!this.isDragging)return;var m=t.target.offsetParent.getBoundingClientRect(),v=t.target.getBoundingClientRect(),b=v.left/this.transformScale,y=m.left/this.transformScale,x=v.right/this.transformScale,w=m.right/this.transformScale,S=v.top/this.transformScale,E=m.top/this.transformScale;this.renderRtl?o.left=-1*(x-w):o.left=b-y,o.top=S-E,this.dragging=null,this.isDragging=!1;break;case"dragmove":var O=u(this.lastX,this.lastY,i,r);if(this.renderRtl?o.left=this.dragging.left-O.deltaX/this.transformScale:o.left=this.dragging.left+O.deltaX/this.transformScale,o.top=this.dragging.top+O.deltaY/this.transformScale,this.bounded){var T=t.target.offsetParent.clientHeight-this.calcGridItemWHPx(this.h,this.rowHeight,this.margin[1]);o.top=this.clamp(o.top,0,T);var z=this.calcColWidth(),M=this.containerWidth-this.calcGridItemWHPx(this.w,z,this.margin[0]);o.left=this.clamp(o.left,0,M)}this.dragging=o;break}n=(this.renderRtl,this.calcXY(o.top,o.left)),this.lastX=i,this.lastY=r,this.innerX===n.x&&this.innerY===n.y||this.$emit("move",this.i,n.x,n.y),"dragend"!==t.type||this.previousX===this.innerX&&this.previousY===this.innerY||this.$emit("moved",this.i,n.x,n.y),this.eventBus.$emit("dragEvent",t.type,this.i,n.x,n.y,this.innerH,this.innerW)}}},calcPosition:function(t,e,n,i){var r,o=this.calcColWidth();return r=this.renderRtl?{right:Math.round(o*t+(t+1)*this.margin[0]),top:Math.round(this.rowHeight*e+(e+1)*this.margin[1]),width:n===1/0?n:Math.round(o*n+Math.max(0,n-1)*this.margin[0]),height:i===1/0?i:Math.round(this.rowHeight*i+Math.max(0,i-1)*this.margin[1])}:{left:Math.round(o*t+(t+1)*this.margin[0]),top:Math.round(this.rowHeight*e+(e+1)*this.margin[1]),width:n===1/0?n:Math.round(o*n+Math.max(0,n-1)*this.margin[0]),height:i===1/0?i:Math.round(this.rowHeight*i+Math.max(0,i-1)*this.margin[1])},r},calcXY:function(t,e){var n=this.calcColWidth(),i=Math.round((e-this.margin[0])/(n+this.margin[0])),r=Math.round((t-this.margin[1])/(this.rowHeight+this.margin[1]));return i=Math.max(Math.min(i,this.cols-this.innerW),0),r=Math.max(Math.min(r,this.maxRows-this.innerH),0),{x:i,y:r}},calcColWidth:function(){var t=(this.containerWidth-this.margin[0]*(this.cols+1))/this.cols;return t},calcGridItemWHPx:function(t,e,n){return Number.isFinite(t)?Math.round(e*t+Math.max(0,t-1)*n):t},clamp:function(t,e,n){return Math.max(Math.min(t,n),e)},calcWH:function(t,e){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],i=this.calcColWidth(),r=Math.round((e+this.margin[0])/(i+this.margin[0])),o=0;return o=n?Math.ceil((t+this.margin[1])/(this.rowHeight+this.margin[1])):Math.round((t+this.margin[1])/(this.rowHeight+this.margin[1])),r=Math.max(Math.min(r,this.cols-this.innerX),0),o=Math.max(Math.min(o,this.maxRows-this.innerY),0),{w:r,h:o}},updateWidth:function(t,e){this.containerWidth=t,void 0!==e&&null!==e&&(this.cols=e)},compact:function(){this.createStyle()},tryMakeDraggable:function(){var t=this;if(null!==this.interactObj&&void 0!==this.interactObj||(this.interactObj=Se(this.$refs.item),this.useStyleCursor||this.interactObj.styleCursor(!1)),this.draggable&&!this.static){var e=Ni({ignoreFrom:this.dragIgnoreFrom,allowFrom:this.dragAllowFrom},this.dragOption);this.interactObj.draggable(e),this.dragEventSet||(this.dragEventSet=!0,this.interactObj.on("dragstart dragmove dragend",(function(e){t.handleDrag(e)})))}else this.interactObj.draggable({enabled:!1})},tryMakeResizable:function(){var t=this;if(null!==this.interactObj&&void 0!==this.interactObj||(this.interactObj=Se(this.$refs.item),this.useStyleCursor||this.interactObj.styleCursor(!1)),this.resizable&&!this.static){var e=this.calcPosition(0,0,this.maxW,this.maxH),n=this.calcPosition(0,0,this.minW,this.minH),i=Ni({edges:{left:!1,right:"."+this.resizableHandleClass.trim().replace(" ","."),bottom:"."+this.resizableHandleClass.trim().replace(" ","."),top:!1},ignoreFrom:this.resizeIgnoreFrom,restrictSize:{min:{height:n.height*this.transformScale,width:n.width*this.transformScale},max:{height:e.height*this.transformScale,width:e.width*this.transformScale}}},this.resizeOption);this.preserveAspectRatio&&(i.modifiers=[Se.modifiers.aspectRatio({ratio:"preserve"})]),this.interactObj.resizable(i),this.resizeEventSet||(this.resizeEventSet=!0,this.interactObj.on("resizestart resizemove resizeend",(function(e){t.handleResize(e)})))}else this.interactObj.resizable({enabled:!1})},autoSize:function(){this.previousW=this.innerW,this.previousH=this.innerH;var t=this.$slots.default[0].elm.getBoundingClientRect(),e=this.calcWH(t.height,t.width,!0);e.wthis.maxW&&(e.w=this.maxW),e.hthis.maxH&&(e.h=this.maxH),e.h<1&&(e.h=1),e.w<1&&(e.w=1),this.innerW===e.w&&this.innerH===e.h||this.$emit("resize",this.i,e.h,e.w,t.height,t.width),this.previousW===e.w&&this.previousH===e.h||(this.$emit("resized",this.i,e.h,e.w,t.height,t.width),this.eventBus.$emit("resizeEvent","resizeend",this.i,this.innerX,this.innerY,e.h,e.w))}}},$i=Wi,Fi=(n("5ed4"),n("2877")),Gi=Object(Fi["a"])($i,r,o,!1,null,null,null);e["a"]=Gi.exports},be13:function(t,e){t.exports=function(t){if(void 0==t)throw TypeError("Can't call method on "+t);return t}},c274:function(t,e,n){"use strict";var i=n("50bf");function r(){var t={},e=0,n=0,i=0;function r(r,o){o||(o=r,r=0),r>n?n=r:ru)if(a=c[u++],a!=a)return!0}else for(;l>u;u++)if((t||u in c)&&c[u]===n)return t||u||0;return!t&&-1}}},c5f6:function(t,e,n){"use strict";var i=n("7726"),r=n("69a8"),o=n("2d95"),s=n("5dbc"),a=n("6a99"),c=n("79e5"),l=n("9093").f,u=n("11e9").f,h=n("86cc").f,d=n("aa77").trim,f="Number",p=i[f],g=p,m=p.prototype,v=o(n("2aeb")(m))==f,b="trim"in String.prototype,y=function(t){var e=a(t,!1);if("string"==typeof e&&e.length>2){e=b?e.trim():d(e,3);var n,i,r,o=e.charCodeAt(0);if(43===o||45===o){if(n=e.charCodeAt(2),88===n||120===n)return NaN}else if(48===o){switch(e.charCodeAt(1)){case 66:case 98:i=2,r=49;break;case 79:case 111:i=8,r=55;break;default:return+e}for(var s,c=e.slice(2),l=0,u=c.length;lr)return NaN;return parseInt(c,i)}}return+e};if(!p(" 0o1")||!p("0b1")||p("+0x1")){p=function(t){var e=arguments.length<1?0:t,n=this;return n instanceof p&&(v?c((function(){m.valueOf.call(n)})):o(n)!=f)?s(new g(y(e)),n,p):y(e)};for(var x,w=n("9e1e")?l(g):"MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger".split(","),S=0;w.length>S;S++)r(g,x=w[S])&&!r(p,x)&&h(p,x,u(g,x));p.prototype=m,m.constructor=p,n("2aba")(i,f,p)}},c69a:function(t,e,n){t.exports=!n("9e1e")&&!n("79e5")((function(){return 7!=Object.defineProperty(n("230e")("div"),"a",{get:function(){return 7}}).a}))},c8ba:function(t,e){var n;n=function(){return this}();try{n=n||new Function("return this")()}catch(i){"object"===typeof window&&(n=window)}t.exports=n},c946:function(t,e,n){"use strict";var i=n("b770").forEach;t.exports=function(t){t=t||{};var e=t.reporter,n=t.batchProcessor,r=t.stateHandler.getState,o=(t.stateHandler.hasState,t.idHandler);if(!n)throw new Error("Missing required dependency: batchProcessor");if(!e)throw new Error("Missing required dependency: reporter.");var s=h(),a="erd_scroll_detection_scrollbar_style",c="erd_scroll_detection_container";function l(t){d(t,a,c)}function u(e){var n=t.important?" !important; ":"; ";return(e.join(n)+n).trim()}function h(){var t=500,e=500,n=document.createElement("div");n.style.cssText=u(["position: absolute","width: "+2*t+"px","height: "+2*e+"px","visibility: hidden","margin: 0","padding: 0"]);var i=document.createElement("div");i.style.cssText=u(["position: absolute","width: "+t+"px","height: "+e+"px","overflow: scroll","visibility: none","top: "+3*-t+"px","left: "+3*-e+"px","visibility: hidden","margin: 0","padding: 0"]),i.appendChild(n),document.body.insertBefore(i,document.body.firstChild);var r=t-i.clientWidth,o=e-i.clientHeight;return document.body.removeChild(i),{width:r,height:o}}function d(t,e,n){function i(n,i){i=i||function(e){t.head.appendChild(e)};var r=t.createElement("style");return r.innerHTML=n,r.id=e,i(r),r}if(!t.getElementById(e)){var r=n+"_animation",o=n+"_animation_active",s="/* Created by the element-resize-detector library. */\n";s+="."+n+" > div::-webkit-scrollbar { "+u(["display: none"])+" }\n\n",s+="."+o+" { "+u(["-webkit-animation-duration: 0.1s","animation-duration: 0.1s","-webkit-animation-name: "+r,"animation-name: "+r])+" }\n",s+="@-webkit-keyframes "+r+" { 0% { opacity: 1; } 50% { opacity: 0; } 100% { opacity: 1; } }\n",s+="@keyframes "+r+" { 0% { opacity: 1; } 50% { opacity: 0; } 100% { opacity: 1; } }",i(s)}}function f(t){t.className+=" "+c+"_animation_active"}function p(t,n,i){if(t.addEventListener)t.addEventListener(n,i);else{if(!t.attachEvent)return e.error("[scroll] Don't know how to add event listeners.");t.attachEvent("on"+n,i)}}function g(t,n,i){if(t.removeEventListener)t.removeEventListener(n,i);else{if(!t.detachEvent)return e.error("[scroll] Don't know how to remove event listeners.");t.detachEvent("on"+n,i)}}function m(t){return r(t).container.childNodes[0].childNodes[0].childNodes[0]}function v(t){return r(t).container.childNodes[0].childNodes[0].childNodes[1]}function b(t,e){var n=r(t).listeners;if(!n.push)throw new Error("Cannot add listener to an element that is not detectable.");r(t).listeners.push(e)}function y(t,a,l){function h(){if(t.debug){var n=Array.prototype.slice.call(arguments);if(n.unshift(o.get(a),"Scroll: "),e.log.apply)e.log.apply(null,n);else for(var i=0;i=t.length?(this._t=void 0,r(1)):r(0,"keys"==e?n:"values"==e?t[n]:[n,t[n]])}),"values"),o.Arguments=o.Array,i("keys"),i("values"),i("entries")},cb7c:function(t,e,n){var i=n("d3f4");t.exports=function(t){if(!i(t))throw TypeError(t+" is not an object!");return t}},ce10:function(t,e,n){var i=n("69a8"),r=n("6821"),o=n("c366")(!1),s=n("613b")("IE_PROTO");t.exports=function(t,e){var n,a=r(t),c=0,l=[];for(n in a)n!=s&&i(a,n)&&l.push(n);while(e.length>c)i(a,n=e[c++])&&(~o(l,n)||l.push(n));return l}},d3f4:function(t,e){t.exports=function(t){return"object"===typeof t?null!==t:"function"===typeof t}},d53b:function(t,e){t.exports=function(t,e){return{value:e,done:!!t}}},d6eb:function(t,e,n){"use strict";var i="_erd";function r(t){return t[i]={},o(t)}function o(t){return t[i]}function s(t){delete t[i]}t.exports={initState:r,getState:o,cleanState:s}},d8e8:function(t,e){t.exports=function(t){if("function"!=typeof t)throw TypeError(t+" is not a function!");return t}},e11e:function(t,e){t.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},e279:function(t,e,n){"use strict";n("1156")},eec4:function(t,e,n){"use strict";var i=n("b770").forEach,r=n("5be5"),o=n("49ad"),s=n("2cef"),a=n("5058"),c=n("abb4"),l=n("18e9"),u=n("c274"),h=n("d6eb"),d=n("18d2"),f=n("c946");function p(t){return Array.isArray(t)||void 0!==t.length}function g(t){if(Array.isArray(t))return t;var e=[];return i(t,(function(t){e.push(t)})),e}function m(t){return t&&1===t.nodeType}function v(t,e,n){var i=t[e];return void 0!==i&&null!==i||void 0===n?i:n}t.exports=function(t){var e;if(t=t||{},t.idHandler)e={get:function(e){return t.idHandler.get(e,!0)},set:t.idHandler.set};else{var n=s(),b=a({idGenerator:n,stateHandler:h});e=b}var y=t.reporter;if(!y){var x=!1===y;y=c(x)}var w=v(t,"batchProcessor",u({reporter:y})),S={};S.callOnAdd=!!v(t,"callOnAdd",!0),S.debug=!!v(t,"debug",!1);var E,O=o(e),T=r({stateHandler:h}),z=v(t,"strategy","object"),M=v(t,"important",!1),_={reporter:y,batchProcessor:w,stateHandler:h,idHandler:e,important:M};if("scroll"===z&&(l.isLegacyOpera()?(y.warn("Scroll strategy is not supported on legacy Opera. Changing to object strategy."),z="object"):l.isIE(9)&&(y.warn("Scroll strategy is not supported on IE9. Changing to object strategy."),z="object")),"scroll"===z)E=f(_);else{if("object"!==z)throw new Error("Invalid strategy name: "+z);E=d(_)}var P={};function I(t,n,r){function o(t){var e=O.get(t);i(e,(function(e){e(t)}))}function s(t,e,n){O.add(e,n),t&&n(e)}if(r||(r=n,n=t,t={}),!n)throw new Error("At least one element required.");if(!r)throw new Error("Listener required.");if(m(n))n=[n];else{if(!p(n))return y.error("Invalid arguments. Must be a DOM element or a collection of DOM elements.");n=g(n)}var a=0,c=v(t,"callOnAdd",S.callOnAdd),l=v(t,"onReady",(function(){})),u=v(t,"debug",S.debug);i(n,(function(t){h.getState(t)||(h.initState(t),e.set(t));var d=e.get(t);if(u&&y.log("Attaching listener to element",d,t),!T.isDetectable(t))return u&&y.log(d,"Not detectable."),T.isBusy(t)?(u&&y.log(d,"System busy making it detectable"),s(c,t,r),P[d]=P[d]||[],void P[d].push((function(){a++,a===n.length&&l()}))):(u&&y.log(d,"Making detectable..."),T.markBusy(t,!0),E.makeDetectable({debug:u,important:M},t,(function(t){if(u&&y.log(d,"onElementDetectable"),h.getState(t)){T.markAsDetectable(t),T.markBusy(t,!1),E.addListener(t,o),s(c,t,r);var e=h.getState(t);if(e&&e.startSize){var f=t.offsetWidth,p=t.offsetHeight;e.startSize.width===f&&e.startSize.height===p||o(t)}P[d]&&i(P[d],(function(t){t()}))}else u&&y.log(d,"Element uninstalled before being detectable.");delete P[d],a++,a===n.length&&l()})));u&&y.log(d,"Already detecable, adding listener."),s(c,t,r),a++})),a===n.length&&l()}function j(t){if(!t)return y.error("At least one element is required.");if(m(t))t=[t];else{if(!p(t))return y.error("Invalid arguments. Must be a DOM element or a collection of DOM elements.");t=g(t)}i(t,(function(t){O.removeAllListeners(t),E.uninstall(t),h.cleanState(t)}))}function D(t){E.initDocument&&E.initDocument(t)}return{listenTo:I,removeListener:O.removeListener,removeAllListeners:O.removeAllListeners,uninstall:j,initDocument:D}}},f1ae:function(t,e,n){"use strict";var i=n("86cc"),r=n("4630");t.exports=function(t,e,n){e in t?i.f(t,e,r(0,n)):t[e]=n}},f6fd:function(t,e){(function(t){var e="currentScript",n=t.getElementsByTagName("script");e in t||Object.defineProperty(t,e,{get:function(){try{throw new Error}catch(i){var t,e=(/.*at [^\(]*\((.*):.+:.+\)$/gi.exec(i.stack)||[!1])[1];for(t in n)if(n[t].src==e||"interactive"==n[t].readyState)return n[t];return null}}})})(document)},f751:function(t,e,n){var i=n("5ca1");i(i.S+i.F,"Object",{assign:n("7333")})},fa5b:function(t,e,n){t.exports=n("5537")("native-function-to-string",Function.toString)},fab2:function(t,e,n){var i=n("7726").document;t.exports=i&&i.documentElement},fb15:function(t,e,n){"use strict";var i;(n.r(e),n.d(e,"install",(function(){return r["d"]})),n.d(e,"GridLayout",(function(){return r["b"]})),n.d(e,"GridItem",(function(){return r["a"]})),"undefined"!==typeof window)&&(n("f6fd"),(i=window.document.currentScript)&&(i=i.src.match(/(.+\/)[^/]+\.js(\?.*)?$/))&&(n.p=i[1]));var r=n("2af9");e["default"]=r["c"]},fca0:function(t,e,n){var i=n("5ca1"),r=n("7726").isFinite;i(i.S,"Number",{isFinite:function(t){return"number"==typeof t&&r(t)}})},fdef:function(t,e){t.exports="\t\n\v\f\r   ᠎              \u2028\u2029\ufeff"}})["default"]})); +//# sourceMappingURL=vue-grid-layout.umd.min.js.map \ No newline at end of file diff --git a/dist/vue-grid-layout.umd.min.js.map b/dist/vue-grid-layout.umd.min.js.map new file mode 100644 index 00000000..65b9588d --- /dev/null +++ b/dist/vue-grid-layout.umd.min.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack://VueGridLayout/webpack/universalModuleDefinition","webpack://VueGridLayout/webpack/bootstrap","webpack://VueGridLayout/./node_modules/core-js/modules/_iter-define.js","webpack://VueGridLayout/./node_modules/core-js/modules/_string-at.js","webpack://VueGridLayout/./node_modules/core-js/modules/_advance-string-index.js","webpack://VueGridLayout/./node_modules/core-js/modules/_flags.js","webpack://VueGridLayout/./node_modules/core-js/modules/_object-keys.js","webpack://VueGridLayout/./src/components/GridLayout.vue?43b0","webpack://VueGridLayout/./node_modules/core-js/modules/_object-gopd.js","webpack://VueGridLayout/./node_modules/core-js/modules/_object-dps.js","webpack://VueGridLayout/./node_modules/element-resize-detector/src/detection-strategy/object.js","webpack://VueGridLayout/./node_modules/element-resize-detector/src/browser-detector.js","webpack://VueGridLayout/./src/helpers/DOM.js","webpack://VueGridLayout/./node_modules/core-js/modules/_fix-re-wks.js","webpack://VueGridLayout/./node_modules/core-js/modules/_dom-create.js","webpack://VueGridLayout/./node_modules/css-loader/lib/css-base.js","webpack://VueGridLayout/./node_modules/core-js/modules/_classof.js","webpack://VueGridLayout/./node_modules/core-js/modules/_object-gops.js","webpack://VueGridLayout/./node_modules/vue-loader/lib/runtime/componentNormalizer.js","webpack://VueGridLayout/./node_modules/core-js/modules/_redefine.js","webpack://VueGridLayout/./node_modules/core-js/modules/_object-create.js","webpack://VueGridLayout/./src/components/index.js","webpack://VueGridLayout/./node_modules/core-js/modules/_wks.js","webpack://VueGridLayout/./node_modules/element-resize-detector/src/id-generator.js","webpack://VueGridLayout/./node_modules/core-js/modules/_library.js","webpack://VueGridLayout/./node_modules/core-js/modules/_cof.js","webpack://VueGridLayout/./node_modules/core-js/modules/_strict-method.js","webpack://VueGridLayout/./node_modules/core-js/modules/_hide.js","webpack://VueGridLayout/./src/components/GridLayout.vue?9453","webpack://VueGridLayout/src/components/GridLayout.vue","webpack://VueGridLayout/./src/components/GridLayout.vue?2dea","webpack://VueGridLayout/./src/components/GridLayout.vue","webpack://VueGridLayout/./node_modules/core-js/modules/_object-gpo.js","webpack://VueGridLayout/./node_modules/core-js/modules/_iter-create.js","webpack://VueGridLayout/./node_modules/core-js/modules/es6.object.keys.js","webpack://VueGridLayout/./node_modules/core-js/modules/_to-integer.js","webpack://VueGridLayout/./node_modules/core-js/modules/_property-desc.js","webpack://VueGridLayout/./node_modules/core-js/modules/es6.regexp.match.js","webpack://VueGridLayout/./node_modules/vue-style-loader/lib/listToStyles.js","webpack://VueGridLayout/./node_modules/vue-style-loader/lib/addStylesClient.js","webpack://VueGridLayout/./node_modules/element-resize-detector/src/listener-handler.js","webpack://VueGridLayout/./node_modules/core-js/modules/_to-object.js","webpack://VueGridLayout/./node_modules/element-resize-detector/src/id-handler.js","webpack://VueGridLayout/./node_modules/batch-processor/src/utils.js","webpack://VueGridLayout/./node_modules/core-js/modules/_regexp-exec.js","webpack://VueGridLayout/./node_modules/core-js/modules/_object-pie.js","webpack://VueGridLayout/./node_modules/core-js/modules/_shared.js","webpack://VueGridLayout/./node_modules/core-js/modules/es6.array.sort.js","webpack://VueGridLayout/./node_modules/element-resize-detector/src/element-utils.js","webpack://VueGridLayout/./node_modules/core-js/modules/_export.js","webpack://VueGridLayout/./node_modules/core-js/modules/_inherit-if-required.js","webpack://VueGridLayout/./src/components/GridItem.vue?70f1","webpack://VueGridLayout/./node_modules/core-js/modules/_object-sap.js","webpack://VueGridLayout/./node_modules/core-js/modules/_regexp-exec-abstract.js","webpack://VueGridLayout/./node_modules/core-js/modules/_shared-key.js","webpack://VueGridLayout/./node_modules/core-js/modules/_iobject.js","webpack://VueGridLayout/./node_modules/core-js/modules/_to-iobject.js","webpack://VueGridLayout/./node_modules/core-js/modules/_has.js","webpack://VueGridLayout/./node_modules/core-js/modules/_to-primitive.js","webpack://VueGridLayout/./src/components/GridItem.vue?73c4","webpack://VueGridLayout/./node_modules/core-js/modules/_object-assign.js","webpack://VueGridLayout/./node_modules/core-js/modules/_global.js","webpack://VueGridLayout/./node_modules/core-js/modules/_to-absolute-index.js","webpack://VueGridLayout/./node_modules/core-js/modules/_fails.js","webpack://VueGridLayout/./node_modules/core-js/modules/_set-to-string-tag.js","webpack://VueGridLayout/./node_modules/core-js/modules/es6.function.name.js","webpack://VueGridLayout/./node_modules/core-js/modules/_core.js","webpack://VueGridLayout/./node_modules/core-js/modules/_iterators.js","webpack://VueGridLayout/./node_modules/core-js/modules/_object-dp.js","webpack://VueGridLayout/./node_modules/core-js/modules/_set-proto.js","webpack://VueGridLayout/external {\"commonjs\":\"vue\",\"commonjs2\":\"vue\",\"root\":\"Vue\"}","webpack://VueGridLayout/./node_modules/core-js/modules/es7.object.get-own-property-descriptors.js","webpack://VueGridLayout/./node_modules/core-js/modules/_object-gopn.js","webpack://VueGridLayout/./src/helpers/responsiveUtils.js","webpack://VueGridLayout/./node_modules/core-js/modules/_own-keys.js","webpack://VueGridLayout/./node_modules/core-js/modules/_ctx.js","webpack://VueGridLayout/./node_modules/core-js/modules/_add-to-unscopables.js","webpack://VueGridLayout/./src/components/GridItem.vue?b235","webpack://VueGridLayout/./node_modules/core-js/modules/_to-length.js","webpack://VueGridLayout/./node_modules/core-js/modules/_descriptors.js","webpack://VueGridLayout/./src/helpers/utils.js","webpack://VueGridLayout/./node_modules/core-js/modules/es6.regexp.replace.js","webpack://VueGridLayout/./node_modules/core-js/modules/_string-trim.js","webpack://VueGridLayout/./node_modules/element-resize-detector/src/reporter.js","webpack://VueGridLayout/./node_modules/core-js/modules/web.dom.iterable.js","webpack://VueGridLayout/./src/components/GridLayout.vue?af6b","webpack://VueGridLayout/./node_modules/@babel/runtime/helpers/esm/defineProperty.js","webpack://VueGridLayout/./node_modules/core-js/modules/es6.regexp.exec.js","webpack://VueGridLayout/./node_modules/element-resize-detector/src/collection-utils.js","webpack://VueGridLayout/./src/components/GridItem.vue?f637","webpack://VueGridLayout/./src/helpers/draggableUtils.js","webpack://VueGridLayout/./node_modules/@interactjs/utils/domObjects.js","webpack://VueGridLayout/./node_modules/@interactjs/utils/isWindow.js","webpack://VueGridLayout/./node_modules/@interactjs/utils/window.js","webpack://VueGridLayout/./node_modules/@interactjs/utils/is.js","webpack://VueGridLayout/./node_modules/@interactjs/utils/browser.js","webpack://VueGridLayout/./node_modules/@interactjs/utils/arr.js","webpack://VueGridLayout/./node_modules/@interactjs/utils/clone.js","webpack://VueGridLayout/./node_modules/@interactjs/utils/extend.js","webpack://VueGridLayout/./node_modules/@interactjs/utils/raf.js","webpack://VueGridLayout/./node_modules/@interactjs/utils/normalizeListeners.js","webpack://VueGridLayout/./node_modules/@interactjs/core/Eventable.js","webpack://VueGridLayout/./node_modules/@interactjs/utils/domUtils.js","webpack://VueGridLayout/./node_modules/@interactjs/utils/rect.js","webpack://VueGridLayout/./node_modules/@interactjs/utils/getOriginXY.js","webpack://VueGridLayout/./node_modules/@interactjs/utils/hypot.js","webpack://VueGridLayout/./node_modules/@interactjs/core/BaseEvent.js","webpack://VueGridLayout/./node_modules/@interactjs/core/defaultOptions.js","webpack://VueGridLayout/./node_modules/@interactjs/core/InteractEvent.js","webpack://VueGridLayout/./node_modules/@interactjs/core/isNonNativeEvent.js","webpack://VueGridLayout/./node_modules/@interactjs/core/Interactable.js","webpack://VueGridLayout/./node_modules/@interactjs/core/InteractableSet.js","webpack://VueGridLayout/./node_modules/@interactjs/utils/pointerExtend.js","webpack://VueGridLayout/./node_modules/@interactjs/utils/pointerUtils.js","webpack://VueGridLayout/./node_modules/@interactjs/core/events.js","webpack://VueGridLayout/./node_modules/@interactjs/utils/misc.js","webpack://VueGridLayout/./node_modules/@interactjs/core/interactStatic.js","webpack://VueGridLayout/./node_modules/@interactjs/core/PointerInfo.js","webpack://VueGridLayout/./node_modules/@interactjs/core/Interaction.js","webpack://VueGridLayout/./node_modules/@interactjs/core/interactablePreventDefault.js","webpack://VueGridLayout/./node_modules/@interactjs/core/interactionFinder.js","webpack://VueGridLayout/./node_modules/@interactjs/core/interactions.js","webpack://VueGridLayout/./node_modules/@interactjs/core/scope.js","webpack://VueGridLayout/./node_modules/@interactjs/interact/index.js","webpack://VueGridLayout/./node_modules/@interactjs/auto-start/InteractableMethods.js","webpack://VueGridLayout/./node_modules/@interactjs/auto-start/base.js","webpack://VueGridLayout/./node_modules/@interactjs/auto-start/dragAxis.js","webpack://VueGridLayout/./node_modules/@interactjs/auto-start/hold.js","webpack://VueGridLayout/./node_modules/@interactjs/auto-start/plugin.js","webpack://VueGridLayout/./node_modules/@interactjs/auto-scroll/plugin.js","webpack://VueGridLayout/./node_modules/@interactjs/auto-start/index.js","webpack://VueGridLayout/./node_modules/@interactjs/actions/drag/plugin.js","webpack://VueGridLayout/./node_modules/@interactjs/auto-scroll/index.js","webpack://VueGridLayout/./node_modules/@interactjs/actions/resize/plugin.js","webpack://VueGridLayout/./node_modules/@interactjs/actions/drag/index.js","webpack://VueGridLayout/./node_modules/@interactjs/actions/resize/index.js","webpack://VueGridLayout/./node_modules/@interactjs/snappers/edgeTarget.js","webpack://VueGridLayout/./node_modules/@interactjs/snappers/elements.js","webpack://VueGridLayout/./node_modules/@interactjs/snappers/grid.js","webpack://VueGridLayout/./node_modules/@interactjs/snappers/plugin.js","webpack://VueGridLayout/./node_modules/@interactjs/modifiers/Modification.js","webpack://VueGridLayout/./node_modules/@interactjs/modifiers/base.js","webpack://VueGridLayout/./node_modules/@interactjs/modifiers/aspectRatio.js","webpack://VueGridLayout/./node_modules/@interactjs/modifiers/noop.js","webpack://VueGridLayout/./node_modules/@interactjs/modifiers/restrict/pointer.js","webpack://VueGridLayout/./node_modules/@interactjs/modifiers/restrict/edges.js","webpack://VueGridLayout/./node_modules/@interactjs/modifiers/restrict/rect.js","webpack://VueGridLayout/./node_modules/@interactjs/modifiers/restrict/size.js","webpack://VueGridLayout/./node_modules/@interactjs/modifiers/snap/pointer.js","webpack://VueGridLayout/./node_modules/@interactjs/modifiers/snap/size.js","webpack://VueGridLayout/./node_modules/@interactjs/modifiers/snap/edges.js","webpack://VueGridLayout/./node_modules/@interactjs/modifiers/all.js","webpack://VueGridLayout/./node_modules/@interactjs/modifiers/plugin.js","webpack://VueGridLayout/./node_modules/@interactjs/dev-tools/plugin.js","webpack://VueGridLayout/./node_modules/@interactjs/modifiers/index.js","webpack://VueGridLayout/./node_modules/@interactjs/dev-tools/index.js","webpack://VueGridLayout/src/components/GridItem.vue","webpack://VueGridLayout/./src/components/GridItem.vue?2537","webpack://VueGridLayout/./src/components/GridItem.vue","webpack://VueGridLayout/./node_modules/core-js/modules/_defined.js","webpack://VueGridLayout/./node_modules/batch-processor/src/batch-processor.js","webpack://VueGridLayout/./node_modules/core-js/modules/_array-includes.js","webpack://VueGridLayout/./node_modules/core-js/modules/es6.number.constructor.js","webpack://VueGridLayout/./node_modules/core-js/modules/_ie8-dom-define.js","webpack://VueGridLayout/(webpack)/buildin/global.js","webpack://VueGridLayout/./node_modules/element-resize-detector/src/detection-strategy/scroll.js","webpack://VueGridLayout/./node_modules/core-js/modules/_uid.js","webpack://VueGridLayout/./node_modules/core-js/modules/es6.array.iterator.js","webpack://VueGridLayout/./node_modules/core-js/modules/_an-object.js","webpack://VueGridLayout/./node_modules/core-js/modules/_object-keys-internal.js","webpack://VueGridLayout/./node_modules/core-js/modules/_is-object.js","webpack://VueGridLayout/./node_modules/core-js/modules/_iter-step.js","webpack://VueGridLayout/./node_modules/element-resize-detector/src/state-handler.js","webpack://VueGridLayout/./node_modules/core-js/modules/_a-function.js","webpack://VueGridLayout/./node_modules/core-js/modules/_enum-bug-keys.js","webpack://VueGridLayout/./src/components/GridLayout.vue?2bdf","webpack://VueGridLayout/./node_modules/element-resize-detector/src/element-resize-detector.js","webpack://VueGridLayout/./node_modules/core-js/modules/_create-property.js","webpack://VueGridLayout/./node_modules/current-script-polyfill/currentScript.js","webpack://VueGridLayout/./node_modules/core-js/modules/es6.object.assign.js","webpack://VueGridLayout/./node_modules/core-js/modules/_function-to-string.js","webpack://VueGridLayout/./node_modules/core-js/modules/_html.js","webpack://VueGridLayout/./node_modules/@vue/cli-service/lib/commands/build/setPublicPath.js","webpack://VueGridLayout/./node_modules/@vue/cli-service/lib/commands/build/entry-lib.js","webpack://VueGridLayout/./node_modules/core-js/modules/es6.number.is-finite.js","webpack://VueGridLayout/./node_modules/core-js/modules/_string-ws.js"],"names":["root","factory","exports","module","require","define","amd","self","this","__WEBPACK_EXTERNAL_MODULE__8bbf__","installedModules","__webpack_require__","moduleId","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","LIBRARY","$export","redefine","hide","Iterators","$iterCreate","setToStringTag","getPrototypeOf","ITERATOR","BUGGY","keys","FF_ITERATOR","KEYS","VALUES","returnThis","Base","NAME","Constructor","next","DEFAULT","IS_SET","FORCED","methods","IteratorPrototype","getMethod","kind","proto","TAG","DEF_VALUES","VALUES_BUG","$native","$default","$entries","undefined","$anyNative","entries","values","P","F","toInteger","defined","TO_STRING","that","pos","a","b","String","length","charCodeAt","charAt","slice","at","S","index","unicode","anObject","result","global","ignoreCase","multiline","sticky","$keys","enumBugKeys","O","content","locals","add","default","pIE","createDesc","toIObject","toPrimitive","has","IE8_DOM_DEFINE","gOPD","getOwnPropertyDescriptor","f","e","dP","getKeys","defineProperties","Properties","browserDetector","options","reporter","batchProcessor","getState","stateHandler","Error","addListener","element","listener","listenerProxy","isIE","proxy","attachEvent","getObject","contentDocument","defaultView","addEventListener","buildCssTextString","rules","seperator","important","join","trim","makeDetectable","callback","debug","injectObject","OBJECT_STYLE","positionCheckPerformed","style","window","getComputedStyle","width","offsetWidth","height","offsetHeight","mutateDom","alterPositionStyles","position","setProperty","removeRelativeStyles","getNumericalValue","replace","warn","onObjectLoad","getDocument","state","checkForObjectDocumentTimeoutId","clearTimeout","setTimeout","objectElement","objectDocument","document","createElement","cssText","tabIndex","type","setAttribute","onload","data","appendChild","startSize","uninstall","detachEvent","removeChild","detector","version","isAnyIeVersion","agent","navigator","userAgent","toLowerCase","indexOf","ieVersion","undef","v","div","all","getElementsByTagName","innerHTML","isLegacyOpera","opera","currentDir","hasDocument","hasWindow","getDocumentDir","direction","dir","getAttribute","addWindowEventListener","event","removeWindowEventListener","removeEventListener","fails","wks","regexpExec","SPECIES","REPLACE_SUPPORTS_NAMED_GROUPS","re","exec","groups","SPLIT_WORKS_WITH_OVERWRITTEN_EXEC","originalExec","apply","arguments","split","KEY","SYMBOL","DELEGATES_TO_SYMBOL","DELEGATES_TO_EXEC","execCalled","constructor","nativeRegExpMethod","fns","nativeMethod","regexp","str","arg2","forceStringMethod","done","strfn","rxfn","RegExp","string","arg","isObject","is","it","cssWithMappingToString","item","useSourceMap","cssMapping","btoa","sourceMapping","toComment","sourceURLs","sources","map","source","sourceRoot","concat","sourceMap","base64","unescape","encodeURIComponent","JSON","stringify","list","toString","mediaQuery","alreadyImportedModules","id","push","cof","ARG","tryGet","T","B","callee","getOwnPropertySymbols","normalizeComponent","scriptExports","render","staticRenderFns","functionalTemplate","injectStyles","scopeId","moduleIdentifier","shadowMode","hook","_compiled","functional","_scopeId","context","$vnode","ssrContext","parent","__VUE_SSR_CONTEXT__","_registeredComponents","_ssrRegister","$root","$options","shadowRoot","_injectStyles","originalRender","h","existing","beforeCreate","SRC","$toString","TPL","inspectSource","val","safe","isFunction","Function","dPs","IE_PROTO","Empty","PROTOTYPE","createDict","iframeDocument","iframe","lt","gt","display","src","contentWindow","open","write","close","VueGridLayout","GridLayout","GridItem","install","Vue","installed","forEach","component","plugin","GlobalVue","use","store","uid","USE_SYMBOL","$exports","idCount","generate","method","_vm","_h","$createElement","_c","_self","ref","staticClass","_t","directives","rawName","expression","attrs","placeholder","x","y","w","toObject","ObjectProto","descriptor","ceil","Math","floor","isNaN","bitmap","configurable","writable","toLength","advanceStringIndex","regExpExec","MATCH","$match","maybeCallNative","fn","res","rx","fullUnicode","lastIndex","A","matchStr","listToStyles","parentId","styles","newStyles","css","media","part","parts","DEBUG","stylesInDom","head","singletonElement","singletonCounter","isProduction","noop","ssrIdKey","isOldIE","test","addStylesClient","_isProduction","_options","addStylesToDom","newList","mayRemove","domStyle","refs","j","addStyle","createStyleElement","styleElement","obj","update","remove","querySelector","parentNode","styleIndex","applyToSingletonTag","applyToTag","newObj","replaceText","textStore","replacement","filter","Boolean","styleSheet","cssNode","createTextNode","childNodes","insertBefore","ssrId","firstChild","idHandler","eventListeners","getListeners","removeListener","listeners","len","splice","removeAllListeners","idGenerator","getId","setId","set","utils","getOption","defaultValue","regexpFlags","nativeExec","nativeReplace","patchedExec","LAST_INDEX","UPDATES_LAST_INDEX_WRONG","re1","re2","NPCG_INCLUDED","PATCH","reCopy","match","propertyIsEnumerable","core","SHARED","copyright","aFunction","$sort","sort","comparefn","isDetectable","markAsDetectable","isBusy","busy","markBusy","ctx","own","out","exp","IS_FORCED","IS_GLOBAL","G","IS_STATIC","IS_PROTO","IS_BIND","target","expProto","U","W","R","setPrototypeOf","C","classof","builtinExec","TypeError","shared","IObject","valueOf","DESCRIPTORS","gOPS","$assign","assign","K","k","aLen","getSymbols","isEnum","__g","max","min","def","tag","stat","FProto","nameRE","__e","Attributes","check","buggy","Array","__proto__","ownKeys","createProperty","getOwnPropertyDescriptors","desc","getDesc","hiddenKeys","getOwnPropertyNames","getBreakpointFromWidth","breakpoints","sorted","sortBreakpoints","matching","breakpointName","getColsFromBreakpoint","breakpoint","cols","findOrGenerateResponsiveLayout","orgLayout","layouts","lastBreakpoint","verticalCompact","cloneLayout","layout","breakpointsSorted","breakpointsAbove","compact","correctBounds","gOPN","Reflect","UNSCOPABLES","ArrayProto","bottom","bottomY","newLayout","cloneLayoutItem","layoutItem","parse","collides","l1","l2","minPositions","compareWith","getStatics","sortLayoutItemsByRowCol","static","compactItem","moved","getFirstCollision","minY","bounds","collidesWith","getLayoutItem","getAllCollisions","moveElement","isUserAction","preventCollision","oldX","oldY","movingUp","reverse","collisions","collision","moveElementAwayFromCollision","itemToMove","fakeItem","setTransform","top","left","translate","transform","WebkitTransform","MozTransform","msTransform","OTransform","setTransformRtl","right","setTopLeft","setTopRight","validateLayout","contextName","subProps","keyArr","isArray","SUBSTITUTION_SYMBOLS","SUBSTITUTION_SYMBOLS_NO_NAMED","maybeToString","REPLACE","$replace","searchValue","replaceValue","functionalReplace","results","accumulatedResult","nextSourcePosition","matched","captures","namedCaptures","replacerArgs","getSubstitution","tailPos","symbols","ch","capture","spaces","space","non","ltrim","rtrim","exporter","ALIAS","FORCE","TYPE","quiet","log","error","console","attachFunction","$iterators","TO_STRING_TAG","ArrayValues","DOMIterables","CSSRuleList","CSSStyleDeclaration","CSSValueList","ClientRectList","DOMRectList","DOMStringList","DOMTokenList","DataTransferItemList","FileList","HTMLAllCollection","HTMLCollection","HTMLFormElement","HTMLSelectElement","MediaList","MimeTypeArray","NamedNodeMap","NodeList","PaintRequestList","Plugin","PluginArray","SVGLengthList","SVGNumberList","SVGPathSegList","SVGPointList","SVGStringList","SVGTransformList","SourceBufferList","StyleSheetList","TextTrackCueList","TextTrackList","TouchList","collections","explicit","Collection","_defineProperty","forced","collection","class","classObj","resizableHandleClass","_e","getControlPosition","offsetXYFromParentOf","evt","offsetParent","body","offsetParentRect","getBoundingClientRect","clientX","scrollLeft","clientY","scrollTop","createCoreData","lastX","lastY","isStart","isNum","deltaX","deltaY","num","domObjects","init","DocumentFragment","SVGElement","SVGSVGElement","SVGElementInstance","Element","HTMLElement","Event","Touch","PointerEvent","blank","win","MSPointerEvent","thing","realWindow","el","ownerDocument","wrap","getWindow","node","isWindow","rootNode","docFrag","nodeType","func","number","bool","_window","nodeName","plainObject","array","browser","supportsTouch","supportsPointerEvent","isIOS7","isIOS","isIe9","isOperaMobile","prefixedMatchesSelector","pEventTypes","wheelEvent","DocumentTouch","pointerEnabled","platform","appVersion","appName","up","down","over","move","cancel","contains","merge","from","findIndex","find","clone","dest","prop","extend","ret","request","lastTime","requestAnimationFrame","cancelAnimationFrame","vendors","vendor","currTime","Date","now","timeToCall","token","normalize","search","reduce","acc","prefix","combinedTypes","fireUntilImmediateStopped","immediatePropagationStopped","types","propagationStopped","eventList","subListener","_element","nodeContains","child","selector","matchesSelector","host","matchesUpTo","limit","getActualElement","correspondingUseElement","getScrollXY","relevantWindow","scrollX","documentElement","scrollY","getElementClientRect","clientRect","getClientRects","getElementRect","scroll","trySelector","getStringOptionResult","getRect","resolveRectLike","functionArgs","returnValue","rectToXY","rect","xywhToTlbr","tlbrToXywh","addEdges","edges","delta","actionOptions","actionName","actionOrigin","origin","originRect","BaseEvent","interaction","currentTarget","interactable","_interaction","timeStamp","_proxy","base","preventDefault","deltaSource","perAction","enabled","actions","phase","preEnd","super","relatedTarget","screenX","screenY","button","buttons","ctrlKey","shiftKey","altKey","metaKey","page","client","x0","y0","t0","dt","duration","clientX0","clientY0","velocity","speed","swipe","axes","getOriginXY","starting","ending","prevEvent","coords","start","cur","pointers","downTime","hypot","getSwipe","angle","atan2","velocityY","velocityX","PI","overlap","isNonNativeEvent","phaselessTypes","substr","phases","pageX","pageY","dx","dy","defaultContext","scopeEvents","_actions","events","_context","_win","_doc","_scopeEvents","_rectChecker","onstart","on","onmove","onend","oninertiastart","prev","off","defaults","_defaults","optionName_","optionName","optionValue","updatePerActionListeners","checker","newValue","action","_backCompatOption","targetNode","eventTarget","testIgnore","ignoreFrom","testAllow","allowFrom","iEvent","fire","typeArg","listenerArg","addRemove","_onOff","actionName_","methodDict","methodName","setPerAction","setting","delegatedEvents","delegated","removeDelegate","scope","selectorMap","addListeners","targetMappings","targetIndex","Interactable","mappingInfo","addDocument","isSelector","found","inContext","pointerExtend","prefixedPropREs","deprecated","webkit","moz","copyCoords","setCoordDeltas","targetObj","setCoordVelocity","setZeroCoords","isNativePointer","pointer","getXY","xy","getPageXY","getClientXY","getPointerId","pointerId","identifier","setCoords","pointerAverage","getTouchPair","touches","changedTouches","average","touchBBox","minX","maxX","maxY","touchDistance","sourceX","sourceY","touchAngle","getPointerType","pointerType","getEventTargets","path","composedPath","newCoords","targets","documents","eventsMethods","addDelegate","delegateListener","delegateUseCapture","supportsOptions","supportsPassive","optionalArg","getOptions","typeIsEmpty","typeListeners","doc","delegates","delegate","matchFound","passive","fakeEvent","originalEvent","stopPropagation","stopImmediatePropagation","param","warnOnce","message","warned","copyAction","axis","createInteractStatic","interact","interactables","new","globalEvents","getPointerAverage","getTouchBBox","getTouchDistance","getTouchAngle","closest","usePlugin","isSet","eventType","stop","interactions","pointerMoveTolerance","removeDocument","PointerInfo","downTarget","_ProxyValues","_ProxyMethods","idCounter","scopeFire","_rects","_scopeFire","prepared","downEvent","downPointer","_latestPointer","pointerIsDown","pointerWasMoved","_interacting","_ending","_stopped","simulation","doMove","signalArg","_id","args","pointerIndex","updatePointer","pointerInfo","interacting","_doPhase","modification","endResult","duplicateMove","getPointerIndex","duplicate","curEventTarget","end","removePointer","endPhaseResult","curPointer","_now","_updateLatestPointer","beforeResult","_createPreparedEvent","_fireEvent","checkAndPreventDefault","docOptions","getDocOptions","onInteractionEvent","docEvents","finder","methodOrder","details","allowResume","firstNonActive","hasPointerId","gesture","some","methodNames","doOnInteractions","releasePointersOnRemovedEls","pointerDown","pointerMove","pointerUp","documentBlur","prevTouchTime","Interaction","interactablePreventDefault","matches","changedTouch","searchDetails","getInteraction","invalidPointer","foundInteraction","onDocSignal","eventMethodName","eventMethod","eventOptions","destroy","random","isInitialized","listenerMaps","Eventable","interactStatic","InteractEvent","_plugins","onWindowUnload","unset","initScope","pluginIsInstalled","before","pluginIdRoot","otherId","getDocIndex","docIndex","raf","getAction","defaultActionChecker","actionChecker","styleCursor","0","1","3","4","InteractableMethods","manualStart","Infinity","maxPerElement","mouseButtons","maxInteractions","autoStart","withinInteractionLimit","cursorElement","prepareOnDown","actionInfo","getActionInfo","prepare","prepareOnMove","startOnMove","setInteractionCursor","clearCursorOnStop","setCursor","validateAction","testIgnoreAllow","validateMatches","matchElements","matchElement","matchAction","pushMatches","forEachMatch","maxActions","autoStartMax","activeInteractions","interactableCount","elementCount","otherAction","cursor","prevCursorElement","cursorChecker","getCursor","beforeStart","absX","abs","absY","targetOptions","drag","startAxis","currentAxis","lockAxis","getDraggable","checkStartAxis","thisAxis","hold","delay","getHoldDuration","autoStartHoldTimer","holdDuration","dragAxis","autoScroll","autoscroll","margin","container","isScrolling","prevTime","getContainer","scrollBy","prevScroll","getScroll","curScroll","_options$actionName$a","innerWidth","innerHeight","autoScrollPlugin","onInteractionMove","draggable","beforeMove","opposite","setOnEvents","dragOptions","resize","cursors","initCursors","defaultMargin","resizable","resizeChecker","resizeOptions","resizeEdges","edge","checkResizeEdge","preserveAspectRatio","square","interactableElement","topleft","bottomright","topright","bottomleft","resizeEvent","corrected","previous","deltaRect","invert","invertible","current","startRect","swap","updateEventAxes","resizeAxes","NaN","cursorKey","grid","coordFields","xField","yField","gridFunc","range","limits","offset","gridx","round","gridy","snappersPlugin","snappers","createSnapGrid","states","startOffset","startDelta","createResult","pageCoords","modifierList","getModifierList","prepareStates","getRectOffset","startAll","setAll","fillArg","skipModifiers","unmodifiedRect","newResult","lastModifierCoords","shouldDo","eventProps","rectDelta","prevCoords","prevRect","rectChanged","changed","curCoords","startCoords","curDelta","coordsSet","modifiedCoords","adjustment","applyToInteraction","doPreend","endPosition","beforeEnd","modifierArg","coordsAndDeltas","requireEndOnly","endOnly","setStart","other","actionModifiers","modifiers","_methods","makeModifier","modifier","enable","disable","addEventModifiers","modifiersBase","setAndApply","restoreInteractionCoords","aspectRatio","originalEdges","ratio","equalDelta","linkedEdges","xIsPrimaryAxis","edgeSign","negativeSecondaryEdge","subModification","copyFrom","initialCoords","aspectMethod","setEqualDelta","setRatio","correctedRect","xIsCriticalAxis","newHeight","newWidth","elementRect","restriction","getRestrictionRect","widthDiff","heightDiff","restrict","noInner","noOuter","offsetRect","inner","outer","fixRect","restrictEdges","_","restrictRect","noMin","noMax","minSize","maxSize","restrictSize","offsetWithOrigin","getOrigin","snapOffset","relativePoints","offsets","relativePoint","relativeX","relativeY","snapTarget","inRange","distance","optionsOrigin","snap","targetFields","relative","snapSize","snapEdges","spring","avoid","rubberband","CheckName","links","touchAction","boxSizing","logger","devTools","ignore","checks","parentHasStyle","text","hasStyle","noListeners","moveListeners","styleRe","defaultExport","perform","getInfo","Batch","batch","size","topLevel","bottomLevel","level","process","getSize","asyncProcess","autoProcess","asyncFrameHandler","isProcessing","addFunction","processBatchAsync","processBatch","processingBatch","forceProcessBatch","localAsyncProcess","cancelFrame","requestFrame","force","toAbsoluteIndex","IS_INCLUDES","$this","fromIndex","inheritIfRequired","$trim","NUMBER","$Number","BROKEN_COF","TRIM","toNumber","argument","third","radix","maxCode","first","code","digits","parseInt","g","hasState","scrollbarSizes","getScrollbarSizes","styleId","detectionContainerClass","initDocument","targetDocument","injectScrollStyle","widthSize","clientWidth","heightSize","clientHeight","containerClass","injectStyle","getElementById","containerAnimationClass","containerAnimationActiveClass","addAnimationClass","className","addEvent","cb","removeEvent","getExpandElement","getShrinkElement","unshift","isDetached","isInDocument","isInShadowRoot","getRootNode","isUnrendered","getStyle","elementStyle","widthCSS","heightCSS","storeStartSize","initListeners","storeStyle","storeCurrentSize","lastWidth","lastHeight","getExpandChildElement","getWidthOffset","getHeightOffset","getExpandWidth","getExpandHeight","getShrinkWidth","getShrinkHeight","positionScrollbars","expand","shrink","expandWidth","expandHeight","shrinkWidth","shrinkHeight","injectContainerElement","onAnimationStart","onRendered","injectScrollElements","getLeftTopBottomRightCssText","rootContainer","scrollbarWidth","scrollbarHeight","containerContainerStyle","containerStyle","expandStyle","shrinkStyle","expandChildStyle","shrinkChildStyle","containerContainer","expandChild","shrinkChild","onExpandScroll","onShrinkScroll","onExpand","onShrink","registerListenersAndPositionElements","updateChildSizes","updateDetectorElements","sizeChanged","areElementsInjected","notifyListenersIfNeeded","isFirstNotify","lastNotifiedWidth","lastNotifiedHeight","handleRender","handleScroll","finalizeDomMutation","ready","px","addToUnscopables","step","iterated","_i","_k","Arguments","arrayIndexOf","names","initState","cleanState","elementUtilsMaker","listenerHandlerMaker","idGeneratorMaker","idHandlerMaker","reporterMaker","batchProcessorMaker","objectStrategyMaker","scrollStrategyMaker","isCollection","toArray","isElement","defaultIdHandler","globalOptions","callOnAdd","detectionStrategy","eventListenerHandler","elementUtils","desiredStrategy","importantCssRules","strategyOptions","onReadyCallbacks","listenTo","elements","onResizeCallback","elementsReady","onReadyCallback","$defineProperty","currentScript","scripts","err","stack","readyState","_isFinite","isFinite"],"mappings":"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","file":"vue-grid-layout.umd.min.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"vue\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"VueGridLayout\"] = factory(require(\"vue\"));\n\telse\n\t\troot[\"VueGridLayout\"] = factory(root[\"Vue\"]);\n})((typeof self !== 'undefined' ? self : this), function(__WEBPACK_EXTERNAL_MODULE__8bbf__) {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = \"fb15\");\n","'use strict';\nvar LIBRARY = require('./_library');\nvar $export = require('./_export');\nvar redefine = require('./_redefine');\nvar hide = require('./_hide');\nvar Iterators = require('./_iterators');\nvar $iterCreate = require('./_iter-create');\nvar setToStringTag = require('./_set-to-string-tag');\nvar getPrototypeOf = require('./_object-gpo');\nvar ITERATOR = require('./_wks')('iterator');\nvar BUGGY = !([].keys && 'next' in [].keys()); // Safari has buggy iterators w/o `next`\nvar FF_ITERATOR = '@@iterator';\nvar KEYS = 'keys';\nvar VALUES = 'values';\n\nvar returnThis = function () { return this; };\n\nmodule.exports = function (Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED) {\n $iterCreate(Constructor, NAME, next);\n var getMethod = function (kind) {\n if (!BUGGY && kind in proto) return proto[kind];\n switch (kind) {\n case KEYS: return function keys() { return new Constructor(this, kind); };\n case VALUES: return function values() { return new Constructor(this, kind); };\n } return function entries() { return new Constructor(this, kind); };\n };\n var TAG = NAME + ' Iterator';\n var DEF_VALUES = DEFAULT == VALUES;\n var VALUES_BUG = false;\n var proto = Base.prototype;\n var $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT];\n var $default = $native || getMethod(DEFAULT);\n var $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined;\n var $anyNative = NAME == 'Array' ? proto.entries || $native : $native;\n var methods, key, IteratorPrototype;\n // Fix native\n if ($anyNative) {\n IteratorPrototype = getPrototypeOf($anyNative.call(new Base()));\n if (IteratorPrototype !== Object.prototype && IteratorPrototype.next) {\n // Set @@toStringTag to native iterators\n setToStringTag(IteratorPrototype, TAG, true);\n // fix for some old engines\n if (!LIBRARY && typeof IteratorPrototype[ITERATOR] != 'function') hide(IteratorPrototype, ITERATOR, returnThis);\n }\n }\n // fix Array#{values, @@iterator}.name in V8 / FF\n if (DEF_VALUES && $native && $native.name !== VALUES) {\n VALUES_BUG = true;\n $default = function values() { return $native.call(this); };\n }\n // Define iterator\n if ((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])) {\n hide(proto, ITERATOR, $default);\n }\n // Plug for library\n Iterators[NAME] = $default;\n Iterators[TAG] = returnThis;\n if (DEFAULT) {\n methods = {\n values: DEF_VALUES ? $default : getMethod(VALUES),\n keys: IS_SET ? $default : getMethod(KEYS),\n entries: $entries\n };\n if (FORCED) for (key in methods) {\n if (!(key in proto)) redefine(proto, key, methods[key]);\n } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods);\n }\n return methods;\n};\n","var toInteger = require('./_to-integer');\nvar defined = require('./_defined');\n// true -> String#at\n// false -> String#codePointAt\nmodule.exports = function (TO_STRING) {\n return function (that, pos) {\n var s = String(defined(that));\n var i = toInteger(pos);\n var l = s.length;\n var a, b;\n if (i < 0 || i >= l) return TO_STRING ? '' : undefined;\n a = s.charCodeAt(i);\n return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff\n ? TO_STRING ? s.charAt(i) : a\n : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000;\n };\n};\n","'use strict';\nvar at = require('./_string-at')(true);\n\n // `AdvanceStringIndex` abstract operation\n// https://tc39.github.io/ecma262/#sec-advancestringindex\nmodule.exports = function (S, index, unicode) {\n return index + (unicode ? at(S, index).length : 1);\n};\n","'use strict';\n// 21.2.5.3 get RegExp.prototype.flags\nvar anObject = require('./_an-object');\nmodule.exports = function () {\n var that = anObject(this);\n var result = '';\n if (that.global) result += 'g';\n if (that.ignoreCase) result += 'i';\n if (that.multiline) result += 'm';\n if (that.unicode) result += 'u';\n if (that.sticky) result += 'y';\n return result;\n};\n","// 19.1.2.14 / 15.2.3.14 Object.keys(O)\nvar $keys = require('./_object-keys-internal');\nvar enumBugKeys = require('./_enum-bug-keys');\n\nmodule.exports = Object.keys || function keys(O) {\n return $keys(O, enumBugKeys);\n};\n","// 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/examples/02-events.js b/examples/02-events.js deleted file mode 100644 index 711153fb..00000000 --- a/examples/02-events.js +++ /dev/null @@ -1,74 +0,0 @@ -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 Vue = require('vue'); - -Vue.config.debug = true; -Vue.config.devtools = true; - -var GridLayout = VueGridLayout.GridLayout; -var GridItem = VueGridLayout.GridItem; - -new Vue({ - el: '#app', - components: { - "GridLayout": GridLayout, - "GridItem": GridItem - }, - data: { - layout: testLayout, - index: 0, - eventLog: [] - }, - watch: { - eventLog: function() { - var eventsDiv = this.$refs.eventsDiv; - eventsDiv.scrollTop = eventsDiv.scrollHeight; - } - }, - methods: { - moveEvent: function(i, newX, newY){ - var msg = "MOVE i=" + i + ", X=" + newX + ", Y=" + newY; - this.eventLog.push(msg); - console.log(msg); - - }, - resizeEvent: function(i, newH, newW){ - var msg = "RESIZE i=" + i + ", H=" + newH + ", W=" + newW; - this.eventLog.push(msg); - console.log(msg); - }, - movedEvent: function(i, newX, newY){ - var msg = "MOVED i=" + i + ", X=" + newX + ", Y=" + newY; - this.eventLog.push(msg); - console.log(msg); - - }, - resizedEvent: function(i, newH, newW){ - var msg = "RESIZED i=" + i + ", H=" + newH + ", W=" + newW; - this.eventLog.push(msg); - console.log(msg); - }, - } -}); - diff --git a/examples/vue.js b/examples/vue.js deleted file mode 100644 index bf468499..00000000 --- a/examples/vue.js +++ /dev/null @@ -1,8515 +0,0 @@ -/*! - * Vue.js v2.1.8 - * (c) 2014-2016 Evan You - * Released under the MIT License. - */ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - (global.Vue = factory()); -}(this, (function () { 'use strict'; - -/* */ - -/** - * Convert a value to a string that is actually rendered. - */ -function _toString (val) { - return val == null - ? '' - : typeof val === 'object' - ? JSON.stringify(val, null, 2) - : String(val) -} - -/** - * Convert a input value to a number for persistence. - * If the conversion fails, return original string. - */ -function toNumber (val) { - var n = parseFloat(val, 10); - return (n || n === 0) ? n : val -} - -/** - * Make a map and return a function for checking if a key - * is in that map. - */ -function makeMap ( - str, - expectsLowerCase -) { - var map = Object.create(null); - var list = str.split(','); - for (var i = 0; i < list.length; i++) { - map[list[i]] = true; - } - return expectsLowerCase - ? function (val) { return map[val.toLowerCase()]; } - : function (val) { return map[val]; } -} - -/** - * Check if a tag is a built-in tag. - */ -var isBuiltInTag = makeMap('slot,component', true); - -/** - * Remove an item from an array - */ -function remove$1 (arr, item) { - if (arr.length) { - var index = arr.indexOf(item); - if (index > -1) { - return arr.splice(index, 1) - } - } -} - -/** - * Check whether the object has the property. - */ -var hasOwnProperty = Object.prototype.hasOwnProperty; -function hasOwn (obj, key) { - return hasOwnProperty.call(obj, key) -} - -/** - * Check if value is primitive - */ -function isPrimitive (value) { - return typeof value === 'string' || typeof value === 'number' -} - -/** - * Create a cached version of a pure function. - */ -function cached (fn) { - var cache = Object.create(null); - return (function cachedFn (str) { - var hit = cache[str]; - return hit || (cache[str] = fn(str)) - }) -} - -/** - * Camelize a hyphen-delmited string. - */ -var camelizeRE = /-(\w)/g; -var camelize = cached(function (str) { - return str.replace(camelizeRE, function (_, c) { return c ? c.toUpperCase() : ''; }) -}); - -/** - * Capitalize a string. - */ -var capitalize = cached(function (str) { - return str.charAt(0).toUpperCase() + str.slice(1) -}); - -/** - * Hyphenate a camelCase string. - */ -var hyphenateRE = /([^-])([A-Z])/g; -var hyphenate = cached(function (str) { - return str - .replace(hyphenateRE, '$1-$2') - .replace(hyphenateRE, '$1-$2') - .toLowerCase() -}); - -/** - * Simple bind, faster than native - */ -function bind$1 (fn, ctx) { - function boundFn (a) { - var l = arguments.length; - return l - ? l > 1 - ? fn.apply(ctx, arguments) - : fn.call(ctx, a) - : fn.call(ctx) - } - // record original fn length - boundFn._length = fn.length; - return boundFn -} - -/** - * Convert an Array-like object to a real Array. - */ -function toArray (list, start) { - start = start || 0; - var i = list.length - start; - var ret = new Array(i); - while (i--) { - ret[i] = list[i + start]; - } - return ret -} - -/** - * Mix properties into target object. - */ -function extend (to, _from) { - for (var key in _from) { - to[key] = _from[key]; - } - return to -} - -/** - * Quick object check - this is primarily used to tell - * Objects from primitive values when we know the value - * is a JSON-compliant type. - */ -function isObject (obj) { - return obj !== null && typeof obj === 'object' -} - -/** - * Strict object type check. Only returns true - * for plain JavaScript objects. - */ -var toString = Object.prototype.toString; -var OBJECT_STRING = '[object Object]'; -function isPlainObject (obj) { - return toString.call(obj) === OBJECT_STRING -} - -/** - * Merge an Array of Objects into a single Object. - */ -function toObject (arr) { - var res = {}; - for (var i = 0; i < arr.length; i++) { - if (arr[i]) { - extend(res, arr[i]); - } - } - return res -} - -/** - * Perform no operation. - */ -function noop () {} - -/** - * Always return false. - */ -var no = function () { return false; }; - -/** - * Return same value - */ -var identity = function (_) { return _; }; - -/** - * Generate a static keys string from compiler modules. - */ -function genStaticKeys (modules) { - return modules.reduce(function (keys, m) { - return keys.concat(m.staticKeys || []) - }, []).join(',') -} - -/** - * Check if two values are loosely equal - that is, - * if they are plain objects, do they have the same shape? - */ -function looseEqual (a, b) { - var isObjectA = isObject(a); - var isObjectB = isObject(b); - if (isObjectA && isObjectB) { - return JSON.stringify(a) === JSON.stringify(b) - } else if (!isObjectA && !isObjectB) { - return String(a) === String(b) - } else { - return false - } -} - -function looseIndexOf (arr, val) { - for (var i = 0; i < arr.length; i++) { - if (looseEqual(arr[i], val)) { return i } - } - return -1 -} - -/* */ - -var config = { - /** - * Option merge strategies (used in core/util/options) - */ - optionMergeStrategies: Object.create(null), - - /** - * Whether to suppress warnings. - */ - silent: false, - - /** - * Whether to enable devtools - */ - devtools: "development" !== 'production', - - /** - * Error handler for watcher errors - */ - errorHandler: null, - - /** - * Ignore certain custom elements - */ - ignoredElements: [], - - /** - * Custom user key aliases for v-on - */ - keyCodes: Object.create(null), - - /** - * Check if a tag is reserved so that it cannot be registered as a - * component. This is platform-dependent and may be overwritten. - */ - isReservedTag: no, - - /** - * Check if a tag is an unknown element. - * Platform-dependent. - */ - isUnknownElement: no, - - /** - * Get the namespace of an element - */ - getTagNamespace: noop, - - /** - * Parse the real tag name for the specific platform. - */ - parsePlatformTagName: identity, - - /** - * Check if an attribute must be bound using property, e.g. value - * Platform-dependent. - */ - mustUseProp: no, - - /** - * List of asset types that a component can own. - */ - _assetTypes: [ - 'component', - 'directive', - 'filter' - ], - - /** - * List of lifecycle hooks. - */ - _lifecycleHooks: [ - 'beforeCreate', - 'created', - 'beforeMount', - 'mounted', - 'beforeUpdate', - 'updated', - 'beforeDestroy', - 'destroyed', - 'activated', - 'deactivated' - ], - - /** - * Max circular updates allowed in a scheduler flush cycle. - */ - _maxUpdateCount: 100 -}; - -/* */ - -/** - * Check if a string starts with $ or _ - */ -function isReserved (str) { - var c = (str + '').charCodeAt(0); - return c === 0x24 || c === 0x5F -} - -/** - * Define a property. - */ -function def (obj, key, val, enumerable) { - Object.defineProperty(obj, key, { - value: val, - enumerable: !!enumerable, - writable: true, - configurable: true - }); -} - -/** - * Parse simple path. - */ -var bailRE = /[^\w.$]/; -function parsePath (path) { - if (bailRE.test(path)) { - return - } else { - var segments = path.split('.'); - return function (obj) { - for (var i = 0; i < segments.length; i++) { - if (!obj) { return } - obj = obj[segments[i]]; - } - return obj - } - } -} - -/* */ -/* globals MutationObserver */ - -// can we use __proto__? -var hasProto = '__proto__' in {}; - -// Browser environment sniffing -var inBrowser = typeof window !== 'undefined'; -var UA = inBrowser && window.navigator.userAgent.toLowerCase(); -var isIE = UA && /msie|trident/.test(UA); -var isIE9 = UA && UA.indexOf('msie 9.0') > 0; -var isEdge = UA && UA.indexOf('edge/') > 0; -var isAndroid = UA && UA.indexOf('android') > 0; -var isIOS = UA && /iphone|ipad|ipod|ios/.test(UA); - -// this needs to be lazy-evaled because vue may be required before -// vue-server-renderer can set VUE_ENV -var _isServer; -var isServerRendering = function () { - if (_isServer === undefined) { - /* istanbul ignore if */ - if (!inBrowser && typeof global !== 'undefined') { - // detect presence of vue-server-renderer and avoid - // Webpack shimming the process - _isServer = global['process'].env.VUE_ENV === 'server'; - } else { - _isServer = false; - } - } - return _isServer -}; - -// detect devtools -var devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__; - -/* istanbul ignore next */ -function isNative (Ctor) { - return /native code/.test(Ctor.toString()) -} - -/** - * Defer a task to execute it asynchronously. - */ -var nextTick = (function () { - var callbacks = []; - var pending = false; - var timerFunc; - - function nextTickHandler () { - pending = false; - var copies = callbacks.slice(0); - callbacks.length = 0; - for (var i = 0; i < copies.length; i++) { - copies[i](); - } - } - - // the nextTick behavior leverages the microtask queue, which can be accessed - // via either native Promise.then or MutationObserver. - // MutationObserver has wider support, however it is seriously bugged in - // UIWebView in iOS >= 9.3.3 when triggered in touch event handlers. It - // completely stops working after triggering a few times... so, if native - // Promise is available, we will use it: - /* istanbul ignore if */ - if (typeof Promise !== 'undefined' && isNative(Promise)) { - var p = Promise.resolve(); - var logError = function (err) { console.error(err); }; - timerFunc = function () { - p.then(nextTickHandler).catch(logError); - // in problematic UIWebViews, Promise.then doesn't completely break, but - // it can get stuck in a weird state where callbacks are pushed into the - // microtask queue but the queue isn't being flushed, until the browser - // needs to do some other work, e.g. handle a timer. Therefore we can - // "force" the microtask queue to be flushed by adding an empty timer. - if (isIOS) { setTimeout(noop); } - }; - } else if (typeof MutationObserver !== 'undefined' && ( - isNative(MutationObserver) || - // PhantomJS and iOS 7.x - MutationObserver.toString() === '[object MutationObserverConstructor]' - )) { - // use MutationObserver where native Promise is not available, - // e.g. PhantomJS IE11, iOS7, Android 4.4 - var counter = 1; - var observer = new MutationObserver(nextTickHandler); - var textNode = document.createTextNode(String(counter)); - observer.observe(textNode, { - characterData: true - }); - timerFunc = function () { - counter = (counter + 1) % 2; - textNode.data = String(counter); - }; - } else { - // fallback to setTimeout - /* istanbul ignore next */ - timerFunc = function () { - setTimeout(nextTickHandler, 0); - }; - } - - return function queueNextTick (cb, ctx) { - var _resolve; - callbacks.push(function () { - if (cb) { cb.call(ctx); } - if (_resolve) { _resolve(ctx); } - }); - if (!pending) { - pending = true; - timerFunc(); - } - if (!cb && typeof Promise !== 'undefined') { - return new Promise(function (resolve) { - _resolve = resolve; - }) - } - } -})(); - -var _Set; -/* istanbul ignore if */ -if (typeof Set !== 'undefined' && isNative(Set)) { - // use native Set when available. - _Set = Set; -} else { - // a non-standard Set polyfill that only works with primitive keys. - _Set = (function () { - function Set () { - this.set = Object.create(null); - } - Set.prototype.has = function has (key) { - return this.set[key] === true - }; - Set.prototype.add = function add (key) { - this.set[key] = true; - }; - Set.prototype.clear = function clear () { - this.set = Object.create(null); - }; - - return Set; - }()); -} - -var warn = noop; -var formatComponentName; - -{ - var hasConsole = typeof console !== 'undefined'; - - warn = function (msg, vm) { - if (hasConsole && (!config.silent)) { - console.error("[Vue warn]: " + msg + " " + ( - vm ? formatLocation(formatComponentName(vm)) : '' - )); - } - }; - - formatComponentName = function (vm) { - if (vm.$root === vm) { - return 'root instance' - } - var name = vm._isVue - ? vm.$options.name || vm.$options._componentTag - : vm.name; - return ( - (name ? ("component <" + name + ">") : "anonymous component") + - (vm._isVue && vm.$options.__file ? (" at " + (vm.$options.__file)) : '') - ) - }; - - var formatLocation = function (str) { - if (str === 'anonymous component') { - str += " - use the \"name\" option for better debugging messages."; - } - return ("\n(found in " + str + ")") - }; -} - -/* */ - - -var uid$1 = 0; - -/** - * A dep is an observable that can have multiple - * directives subscribing to it. - */ -var Dep = function Dep () { - this.id = uid$1++; - this.subs = []; -}; - -Dep.prototype.addSub = function addSub (sub) { - this.subs.push(sub); -}; - -Dep.prototype.removeSub = function removeSub (sub) { - remove$1(this.subs, sub); -}; - -Dep.prototype.depend = function depend () { - if (Dep.target) { - Dep.target.addDep(this); - } -}; - -Dep.prototype.notify = function notify () { - // stablize the subscriber list first - var subs = this.subs.slice(); - for (var i = 0, l = subs.length; i < l; i++) { - subs[i].update(); - } -}; - -// the current target watcher being evaluated. -// this is globally unique because there could be only one -// watcher being evaluated at any time. -Dep.target = null; -var targetStack = []; - -function pushTarget (_target) { - if (Dep.target) { targetStack.push(Dep.target); } - Dep.target = _target; -} - -function popTarget () { - Dep.target = targetStack.pop(); -} - -/* - * not type checking this file because flow doesn't play well with - * dynamically accessing methods on Array prototype - */ - -var arrayProto = Array.prototype; -var arrayMethods = Object.create(arrayProto);[ - 'push', - 'pop', - 'shift', - 'unshift', - 'splice', - 'sort', - 'reverse' -] -.forEach(function (method) { - // cache original method - var original = arrayProto[method]; - def(arrayMethods, method, function mutator () { - var arguments$1 = arguments; - - // avoid leaking arguments: - // http://jsperf.com/closure-with-arguments - var i = arguments.length; - var args = new Array(i); - while (i--) { - args[i] = arguments$1[i]; - } - var result = original.apply(this, args); - var ob = this.__ob__; - var inserted; - switch (method) { - case 'push': - inserted = args; - break - case 'unshift': - inserted = args; - break - case 'splice': - inserted = args.slice(2); - break - } - if (inserted) { ob.observeArray(inserted); } - // notify change - ob.dep.notify(); - return result - }); -}); - -/* */ - -var arrayKeys = Object.getOwnPropertyNames(arrayMethods); - -/** - * By default, when a reactive property is set, the new value is - * also converted to become reactive. However when passing down props, - * we don't want to force conversion because the value may be a nested value - * under a frozen data structure. Converting it would defeat the optimization. - */ -var observerState = { - shouldConvert: true, - isSettingProps: false -}; - -/** - * Observer class that are attached to each observed - * object. Once attached, the observer converts target - * object's property keys into getter/setters that - * collect dependencies and dispatches updates. - */ -var Observer = function Observer (value) { - this.value = value; - this.dep = new Dep(); - this.vmCount = 0; - def(value, '__ob__', this); - if (Array.isArray(value)) { - var augment = hasProto - ? protoAugment - : copyAugment; - augment(value, arrayMethods, arrayKeys); - this.observeArray(value); - } else { - this.walk(value); - } -}; - -/** - * Walk through each property and convert them into - * getter/setters. This method should only be called when - * value type is Object. - */ -Observer.prototype.walk = function walk (obj) { - var keys = Object.keys(obj); - for (var i = 0; i < keys.length; i++) { - defineReactive$$1(obj, keys[i], obj[keys[i]]); - } -}; - -/** - * Observe a list of Array items. - */ -Observer.prototype.observeArray = function observeArray (items) { - for (var i = 0, l = items.length; i < l; i++) { - observe(items[i]); - } -}; - -// helpers - -/** - * Augment an target Object or Array by intercepting - * the prototype chain using __proto__ - */ -function protoAugment (target, src) { - /* eslint-disable no-proto */ - target.__proto__ = src; - /* eslint-enable no-proto */ -} - -/** - * Augment an target Object or Array by defining - * hidden properties. - */ -/* istanbul ignore next */ -function copyAugment (target, src, keys) { - for (var i = 0, l = keys.length; i < l; i++) { - var key = keys[i]; - def(target, key, src[key]); - } -} - -/** - * Attempt to create an observer instance for a value, - * returns the new observer if successfully observed, - * or the existing observer if the value already has one. - */ -function observe (value, asRootData) { - if (!isObject(value)) { - return - } - var ob; - if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) { - ob = value.__ob__; - } else if ( - observerState.shouldConvert && - !isServerRendering() && - (Array.isArray(value) || isPlainObject(value)) && - Object.isExtensible(value) && - !value._isVue - ) { - ob = new Observer(value); - } - if (asRootData && ob) { - ob.vmCount++; - } - return ob -} - -/** - * Define a reactive property on an Object. - */ -function defineReactive$$1 ( - obj, - key, - val, - customSetter -) { - var dep = new Dep(); - - var property = Object.getOwnPropertyDescriptor(obj, key); - if (property && property.configurable === false) { - return - } - - // cater for pre-defined getter/setters - var getter = property && property.get; - var setter = property && property.set; - - var childOb = observe(val); - Object.defineProperty(obj, key, { - enumerable: true, - configurable: true, - get: function reactiveGetter () { - var value = getter ? getter.call(obj) : val; - if (Dep.target) { - dep.depend(); - if (childOb) { - childOb.dep.depend(); - } - if (Array.isArray(value)) { - dependArray(value); - } - } - return value - }, - set: function reactiveSetter (newVal) { - var value = getter ? getter.call(obj) : val; - /* eslint-disable no-self-compare */ - if (newVal === value || (newVal !== newVal && value !== value)) { - return - } - /* eslint-enable no-self-compare */ - if ("development" !== 'production' && customSetter) { - customSetter(); - } - if (setter) { - setter.call(obj, newVal); - } else { - val = newVal; - } - childOb = observe(newVal); - dep.notify(); - } - }); -} - -/** - * Set a property on an object. Adds the new property and - * triggers change notification if the property doesn't - * already exist. - */ -function set$1 (obj, key, val) { - if (Array.isArray(obj)) { - obj.length = Math.max(obj.length, key); - obj.splice(key, 1, val); - return val - } - if (hasOwn(obj, key)) { - obj[key] = val; - return - } - var ob = obj.__ob__; - if (obj._isVue || (ob && ob.vmCount)) { - "development" !== 'production' && warn( - 'Avoid adding reactive properties to a Vue instance or its root $data ' + - 'at runtime - declare it upfront in the data option.' - ); - return - } - if (!ob) { - obj[key] = val; - return - } - defineReactive$$1(ob.value, key, val); - ob.dep.notify(); - return val -} - -/** - * Delete a property and trigger change if necessary. - */ -function del (obj, key) { - var ob = obj.__ob__; - if (obj._isVue || (ob && ob.vmCount)) { - "development" !== 'production' && warn( - 'Avoid deleting properties on a Vue instance or its root $data ' + - '- just set it to null.' - ); - return - } - if (!hasOwn(obj, key)) { - return - } - delete obj[key]; - if (!ob) { - return - } - ob.dep.notify(); -} - -/** - * Collect dependencies on array elements when the array is touched, since - * we cannot intercept array element access like property getters. - */ -function dependArray (value) { - for (var e = (void 0), i = 0, l = value.length; i < l; i++) { - e = value[i]; - e && e.__ob__ && e.__ob__.dep.depend(); - if (Array.isArray(e)) { - dependArray(e); - } - } -} - -/* */ - -/** - * Option overwriting strategies are functions that handle - * how to merge a parent option value and a child option - * value into the final value. - */ -var strats = config.optionMergeStrategies; - -/** - * Options with restrictions - */ -{ - strats.el = strats.propsData = function (parent, child, vm, key) { - if (!vm) { - warn( - "option \"" + key + "\" can only be used during instance " + - 'creation with the `new` keyword.' - ); - } - return defaultStrat(parent, child) - }; -} - -/** - * Helper that recursively merges two data objects together. - */ -function mergeData (to, from) { - if (!from) { return to } - var key, toVal, fromVal; - var keys = Object.keys(from); - for (var i = 0; i < keys.length; i++) { - key = keys[i]; - toVal = to[key]; - fromVal = from[key]; - if (!hasOwn(to, key)) { - set$1(to, key, fromVal); - } else if (isPlainObject(toVal) && isPlainObject(fromVal)) { - mergeData(toVal, fromVal); - } - } - return to -} - -/** - * Data - */ -strats.data = function ( - parentVal, - childVal, - vm -) { - if (!vm) { - // in a Vue.extend merge, both should be functions - if (!childVal) { - return parentVal - } - if (typeof childVal !== 'function') { - "development" !== 'production' && warn( - 'The "data" option should be a function ' + - 'that returns a per-instance value in component ' + - 'definitions.', - vm - ); - return parentVal - } - if (!parentVal) { - return childVal - } - // when parentVal & childVal are both present, - // we need to return a function that returns the - // merged result of both functions... no need to - // check if parentVal is a function here because - // it has to be a function to pass previous merges. - return function mergedDataFn () { - return mergeData( - childVal.call(this), - parentVal.call(this) - ) - } - } else if (parentVal || childVal) { - return function mergedInstanceDataFn () { - // instance merge - var instanceData = typeof childVal === 'function' - ? childVal.call(vm) - : childVal; - var defaultData = typeof parentVal === 'function' - ? parentVal.call(vm) - : undefined; - if (instanceData) { - return mergeData(instanceData, defaultData) - } else { - return defaultData - } - } - } -}; - -/** - * Hooks and param attributes are merged as arrays. - */ -function mergeHook ( - parentVal, - childVal -) { - return childVal - ? parentVal - ? parentVal.concat(childVal) - : Array.isArray(childVal) - ? childVal - : [childVal] - : parentVal -} - -config._lifecycleHooks.forEach(function (hook) { - strats[hook] = mergeHook; -}); - -/** - * Assets - * - * When a vm is present (instance creation), we need to do - * a three-way merge between constructor options, instance - * options and parent options. - */ -function mergeAssets (parentVal, childVal) { - var res = Object.create(parentVal || null); - return childVal - ? extend(res, childVal) - : res -} - -config._assetTypes.forEach(function (type) { - strats[type + 's'] = mergeAssets; -}); - -/** - * Watchers. - * - * Watchers hashes should not overwrite one - * another, so we merge them as arrays. - */ -strats.watch = function (parentVal, childVal) { - /* istanbul ignore if */ - if (!childVal) { return parentVal } - if (!parentVal) { return childVal } - var ret = {}; - extend(ret, parentVal); - for (var key in childVal) { - var parent = ret[key]; - var child = childVal[key]; - if (parent && !Array.isArray(parent)) { - parent = [parent]; - } - ret[key] = parent - ? parent.concat(child) - : [child]; - } - return ret -}; - -/** - * Other object hashes. - */ -strats.props = -strats.methods = -strats.computed = function (parentVal, childVal) { - if (!childVal) { return parentVal } - if (!parentVal) { return childVal } - var ret = Object.create(null); - extend(ret, parentVal); - extend(ret, childVal); - return ret -}; - -/** - * Default strategy. - */ -var defaultStrat = function (parentVal, childVal) { - return childVal === undefined - ? parentVal - : childVal -}; - -/** - * Validate component names - */ -function checkComponents (options) { - for (var key in options.components) { - var lower = key.toLowerCase(); - if (isBuiltInTag(lower) || config.isReservedTag(lower)) { - warn( - 'Do not use built-in or reserved HTML elements as component ' + - 'id: ' + key - ); - } - } -} - -/** - * Ensure all props option syntax are normalized into the - * Object-based format. - */ -function normalizeProps (options) { - var props = options.props; - if (!props) { return } - var res = {}; - var i, val, name; - if (Array.isArray(props)) { - i = props.length; - while (i--) { - val = props[i]; - if (typeof val === 'string') { - name = camelize(val); - res[name] = { type: null }; - } else { - warn('props must be strings when using array syntax.'); - } - } - } else if (isPlainObject(props)) { - for (var key in props) { - val = props[key]; - name = camelize(key); - res[name] = isPlainObject(val) - ? val - : { type: val }; - } - } - options.props = res; -} - -/** - * Normalize raw function directives into object format. - */ -function normalizeDirectives (options) { - var dirs = options.directives; - if (dirs) { - for (var key in dirs) { - var def = dirs[key]; - if (typeof def === 'function') { - dirs[key] = { bind: def, update: def }; - } - } - } -} - -/** - * Merge two option objects into a new one. - * Core utility used in both instantiation and inheritance. - */ -function mergeOptions ( - parent, - child, - vm -) { - { - checkComponents(child); - } - normalizeProps(child); - normalizeDirectives(child); - var extendsFrom = child.extends; - if (extendsFrom) { - parent = typeof extendsFrom === 'function' - ? mergeOptions(parent, extendsFrom.options, vm) - : mergeOptions(parent, extendsFrom, vm); - } - if (child.mixins) { - for (var i = 0, l = child.mixins.length; i < l; i++) { - var mixin = child.mixins[i]; - if (mixin.prototype instanceof Vue$3) { - mixin = mixin.options; - } - parent = mergeOptions(parent, mixin, vm); - } - } - var options = {}; - var key; - for (key in parent) { - mergeField(key); - } - for (key in child) { - if (!hasOwn(parent, key)) { - mergeField(key); - } - } - function mergeField (key) { - var strat = strats[key] || defaultStrat; - options[key] = strat(parent[key], child[key], vm, key); - } - return options -} - -/** - * Resolve an asset. - * This function is used because child instances need access - * to assets defined in its ancestor chain. - */ -function resolveAsset ( - options, - type, - id, - warnMissing -) { - /* istanbul ignore if */ - if (typeof id !== 'string') { - return - } - var assets = options[type]; - // check local registration variations first - if (hasOwn(assets, id)) { return assets[id] } - var camelizedId = camelize(id); - if (hasOwn(assets, camelizedId)) { return assets[camelizedId] } - var PascalCaseId = capitalize(camelizedId); - if (hasOwn(assets, PascalCaseId)) { return assets[PascalCaseId] } - // fallback to prototype chain - var res = assets[id] || assets[camelizedId] || assets[PascalCaseId]; - if ("development" !== 'production' && warnMissing && !res) { - warn( - 'Failed to resolve ' + type.slice(0, -1) + ': ' + id, - options - ); - } - return res -} - -/* */ - -function validateProp ( - key, - propOptions, - propsData, - vm -) { - var prop = propOptions[key]; - var absent = !hasOwn(propsData, key); - var value = propsData[key]; - // handle boolean props - if (isType(Boolean, prop.type)) { - if (absent && !hasOwn(prop, 'default')) { - value = false; - } else if (!isType(String, prop.type) && (value === '' || value === hyphenate(key))) { - value = true; - } - } - // check default value - if (value === undefined) { - value = getPropDefaultValue(vm, prop, key); - // since the default value is a fresh copy, - // make sure to observe it. - var prevShouldConvert = observerState.shouldConvert; - observerState.shouldConvert = true; - observe(value); - observerState.shouldConvert = prevShouldConvert; - } - { - assertProp(prop, key, value, vm, absent); - } - return value -} - -/** - * Get the default value of a prop. - */ -function getPropDefaultValue (vm, prop, key) { - // no default, return undefined - if (!hasOwn(prop, 'default')) { - return undefined - } - var def = prop.default; - // warn against non-factory defaults for Object & Array - if (isObject(def)) { - "development" !== 'production' && warn( - 'Invalid default value for prop "' + key + '": ' + - 'Props with type Object/Array must use a factory function ' + - 'to return the default value.', - vm - ); - } - // the raw prop value was also undefined from previous render, - // return previous default value to avoid unnecessary watcher trigger - if (vm && vm.$options.propsData && - vm.$options.propsData[key] === undefined && - vm[key] !== undefined) { - return vm[key] - } - // call factory function for non-Function types - return typeof def === 'function' && prop.type !== Function - ? def.call(vm) - : def -} - -/** - * Assert whether a prop is valid. - */ -function assertProp ( - prop, - name, - value, - vm, - absent -) { - if (prop.required && absent) { - warn( - 'Missing required prop: "' + name + '"', - vm - ); - return - } - if (value == null && !prop.required) { - return - } - var type = prop.type; - var valid = !type || type === true; - var expectedTypes = []; - if (type) { - if (!Array.isArray(type)) { - type = [type]; - } - for (var i = 0; i < type.length && !valid; i++) { - var assertedType = assertType(value, type[i]); - expectedTypes.push(assertedType.expectedType || ''); - valid = assertedType.valid; - } - } - if (!valid) { - warn( - 'Invalid prop: type check failed for prop "' + name + '".' + - ' Expected ' + expectedTypes.map(capitalize).join(', ') + - ', got ' + Object.prototype.toString.call(value).slice(8, -1) + '.', - vm - ); - return - } - var validator = prop.validator; - if (validator) { - if (!validator(value)) { - warn( - 'Invalid prop: custom validator check failed for prop "' + name + '".', - vm - ); - } - } -} - -/** - * Assert the type of a value - */ -function assertType (value, type) { - var valid; - var expectedType = getType(type); - if (expectedType === 'String') { - valid = typeof value === (expectedType = 'string'); - } else if (expectedType === 'Number') { - valid = typeof value === (expectedType = 'number'); - } else if (expectedType === 'Boolean') { - valid = typeof value === (expectedType = 'boolean'); - } else if (expectedType === 'Function') { - valid = typeof value === (expectedType = 'function'); - } else if (expectedType === 'Object') { - valid = isPlainObject(value); - } else if (expectedType === 'Array') { - valid = Array.isArray(value); - } else { - valid = value instanceof type; - } - return { - valid: valid, - expectedType: expectedType - } -} - -/** - * Use function string name to check built-in types, - * because a simple equality check will fail when running - * across different vms / iframes. - */ -function getType (fn) { - var match = fn && fn.toString().match(/^\s*function (\w+)/); - return match && match[1] -} - -function isType (type, fn) { - if (!Array.isArray(fn)) { - return getType(fn) === getType(type) - } - for (var i = 0, len = fn.length; i < len; i++) { - if (getType(fn[i]) === getType(type)) { - return true - } - } - /* istanbul ignore next */ - return false -} - - - -var util = Object.freeze({ - defineReactive: defineReactive$$1, - _toString: _toString, - toNumber: toNumber, - makeMap: makeMap, - isBuiltInTag: isBuiltInTag, - remove: remove$1, - hasOwn: hasOwn, - isPrimitive: isPrimitive, - cached: cached, - camelize: camelize, - capitalize: capitalize, - hyphenate: hyphenate, - bind: bind$1, - toArray: toArray, - extend: extend, - isObject: isObject, - isPlainObject: isPlainObject, - toObject: toObject, - noop: noop, - no: no, - identity: identity, - genStaticKeys: genStaticKeys, - looseEqual: looseEqual, - looseIndexOf: looseIndexOf, - isReserved: isReserved, - def: def, - parsePath: parsePath, - hasProto: hasProto, - inBrowser: inBrowser, - UA: UA, - isIE: isIE, - isIE9: isIE9, - isEdge: isEdge, - isAndroid: isAndroid, - isIOS: isIOS, - isServerRendering: isServerRendering, - devtools: devtools, - nextTick: nextTick, - get _Set () { return _Set; }, - mergeOptions: mergeOptions, - resolveAsset: resolveAsset, - get warn () { return warn; }, - get formatComponentName () { return formatComponentName; }, - validateProp: validateProp -}); - -/* not type checking this file because flow doesn't play well with Proxy */ - -var initProxy; - -{ - var allowedGlobals = makeMap( - 'Infinity,undefined,NaN,isFinite,isNaN,' + - 'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' + - 'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,' + - 'require' // for Webpack/Browserify - ); - - var warnNonPresent = function (target, key) { - warn( - "Property or method \"" + key + "\" is not defined on the instance but " + - "referenced during render. Make sure to declare reactive data " + - "properties in the data option.", - target - ); - }; - - var hasProxy = - typeof Proxy !== 'undefined' && - Proxy.toString().match(/native code/); - - if (hasProxy) { - var isBuiltInModifier = makeMap('stop,prevent,self,ctrl,shift,alt,meta'); - config.keyCodes = new Proxy(config.keyCodes, { - set: function set (target, key, value) { - if (isBuiltInModifier(key)) { - warn(("Avoid overwriting built-in modifier in config.keyCodes: ." + key)); - return false - } else { - target[key] = value; - return true - } - } - }); - } - - var hasHandler = { - has: function has (target, key) { - var has = key in target; - var isAllowed = allowedGlobals(key) || key.charAt(0) === '_'; - if (!has && !isAllowed) { - warnNonPresent(target, key); - } - return has || !isAllowed - } - }; - - var getHandler = { - get: function get (target, key) { - if (typeof key === 'string' && !(key in target)) { - warnNonPresent(target, key); - } - return target[key] - } - }; - - initProxy = function initProxy (vm) { - if (hasProxy) { - // determine which proxy handler to use - var options = vm.$options; - var handlers = options.render && options.render._withStripped - ? getHandler - : hasHandler; - vm._renderProxy = new Proxy(vm, handlers); - } else { - vm._renderProxy = vm; - } - }; -} - -/* */ - - -var queue = []; -var has$1 = {}; -var circular = {}; -var waiting = false; -var flushing = false; -var index = 0; - -/** - * Reset the scheduler's state. - */ -function resetSchedulerState () { - queue.length = 0; - has$1 = {}; - { - circular = {}; - } - waiting = flushing = false; -} - -/** - * Flush both queues and run the watchers. - */ -function flushSchedulerQueue () { - flushing = true; - - // Sort queue before flush. - // This ensures that: - // 1. Components are updated from parent to child. (because parent is always - // created before the child) - // 2. A component's user watchers are run before its render watcher (because - // user watchers are created before the render watcher) - // 3. If a component is destroyed during a parent component's watcher run, - // its watchers can be skipped. - queue.sort(function (a, b) { return a.id - b.id; }); - - // do not cache length because more watchers might be pushed - // as we run existing watchers - for (index = 0; index < queue.length; index++) { - var watcher = queue[index]; - var id = watcher.id; - has$1[id] = null; - watcher.run(); - // in dev build, check and stop circular updates. - if ("development" !== 'production' && has$1[id] != null) { - circular[id] = (circular[id] || 0) + 1; - if (circular[id] > config._maxUpdateCount) { - warn( - 'You may have an infinite update loop ' + ( - watcher.user - ? ("in watcher with expression \"" + (watcher.expression) + "\"") - : "in a component render function." - ), - watcher.vm - ); - break - } - } - } - - // devtool hook - /* istanbul ignore if */ - if (devtools && config.devtools) { - devtools.emit('flush'); - } - - resetSchedulerState(); -} - -/** - * Push a watcher into the watcher queue. - * Jobs with duplicate IDs will be skipped unless it's - * pushed when the queue is being flushed. - */ -function queueWatcher (watcher) { - var id = watcher.id; - if (has$1[id] == null) { - has$1[id] = true; - if (!flushing) { - queue.push(watcher); - } else { - // if already flushing, splice the watcher based on its id - // if already past its id, it will be run next immediately. - var i = queue.length - 1; - while (i >= 0 && queue[i].id > watcher.id) { - i--; - } - queue.splice(Math.max(i, index) + 1, 0, watcher); - } - // queue the flush - if (!waiting) { - waiting = true; - nextTick(flushSchedulerQueue); - } - } -} - -/* */ - -var uid$2 = 0; - -/** - * A watcher parses an expression, collects dependencies, - * and fires callback when the expression value changes. - * This is used for both the $watch() api and directives. - */ -var Watcher = function Watcher ( - vm, - expOrFn, - cb, - options -) { - this.vm = vm; - vm._watchers.push(this); - // options - if (options) { - this.deep = !!options.deep; - this.user = !!options.user; - this.lazy = !!options.lazy; - this.sync = !!options.sync; - } else { - this.deep = this.user = this.lazy = this.sync = false; - } - this.cb = cb; - this.id = ++uid$2; // uid for batching - this.active = true; - this.dirty = this.lazy; // for lazy watchers - this.deps = []; - this.newDeps = []; - this.depIds = new _Set(); - this.newDepIds = new _Set(); - this.expression = expOrFn.toString(); - // parse expression for getter - if (typeof expOrFn === 'function') { - this.getter = expOrFn; - } else { - this.getter = parsePath(expOrFn); - if (!this.getter) { - this.getter = function () {}; - "development" !== 'production' && warn( - "Failed watching path: \"" + expOrFn + "\" " + - 'Watcher only accepts simple dot-delimited paths. ' + - 'For full control, use a function instead.', - vm - ); - } - } - this.value = this.lazy - ? undefined - : this.get(); -}; - -/** - * Evaluate the getter, and re-collect dependencies. - */ -Watcher.prototype.get = function get () { - pushTarget(this); - var value = this.getter.call(this.vm, this.vm); - // "touch" every property so they are all tracked as - // dependencies for deep watching - if (this.deep) { - traverse(value); - } - popTarget(); - this.cleanupDeps(); - return value -}; - -/** - * Add a dependency to this directive. - */ -Watcher.prototype.addDep = function addDep (dep) { - var id = dep.id; - if (!this.newDepIds.has(id)) { - this.newDepIds.add(id); - this.newDeps.push(dep); - if (!this.depIds.has(id)) { - dep.addSub(this); - } - } -}; - -/** - * Clean up for dependency collection. - */ -Watcher.prototype.cleanupDeps = function cleanupDeps () { - var this$1 = this; - - var i = this.deps.length; - while (i--) { - var dep = this$1.deps[i]; - if (!this$1.newDepIds.has(dep.id)) { - dep.removeSub(this$1); - } - } - var tmp = this.depIds; - this.depIds = this.newDepIds; - this.newDepIds = tmp; - this.newDepIds.clear(); - tmp = this.deps; - this.deps = this.newDeps; - this.newDeps = tmp; - this.newDeps.length = 0; -}; - -/** - * Subscriber interface. - * Will be called when a dependency changes. - */ -Watcher.prototype.update = function update () { - /* istanbul ignore else */ - if (this.lazy) { - this.dirty = true; - } else if (this.sync) { - this.run(); - } else { - queueWatcher(this); - } -}; - -/** - * Scheduler job interface. - * Will be called by the scheduler. - */ -Watcher.prototype.run = function run () { - if (this.active) { - var value = this.get(); - if ( - value !== this.value || - // Deep watchers and watchers on Object/Arrays should fire even - // when the value is the same, because the value may - // have mutated. - isObject(value) || - this.deep - ) { - // set new value - var oldValue = this.value; - this.value = value; - if (this.user) { - try { - this.cb.call(this.vm, value, oldValue); - } catch (e) { - /* istanbul ignore else */ - if (config.errorHandler) { - config.errorHandler.call(null, e, this.vm); - } else { - "development" !== 'production' && warn( - ("Error in watcher \"" + (this.expression) + "\""), - this.vm - ); - throw e - } - } - } else { - this.cb.call(this.vm, value, oldValue); - } - } - } -}; - -/** - * Evaluate the value of the watcher. - * This only gets called for lazy watchers. - */ -Watcher.prototype.evaluate = function evaluate () { - this.value = this.get(); - this.dirty = false; -}; - -/** - * Depend on all deps collected by this watcher. - */ -Watcher.prototype.depend = function depend () { - var this$1 = this; - - var i = this.deps.length; - while (i--) { - this$1.deps[i].depend(); - } -}; - -/** - * Remove self from all dependencies' subscriber list. - */ -Watcher.prototype.teardown = function teardown () { - var this$1 = this; - - if (this.active) { - // remove self from vm's watcher list - // this is a somewhat expensive operation so we skip it - // if the vm is being destroyed. - if (!this.vm._isBeingDestroyed) { - remove$1(this.vm._watchers, this); - } - var i = this.deps.length; - while (i--) { - this$1.deps[i].removeSub(this$1); - } - this.active = false; - } -}; - -/** - * Recursively traverse an object to evoke all converted - * getters, so that every nested property inside the object - * is collected as a "deep" dependency. - */ -var seenObjects = new _Set(); -function traverse (val) { - seenObjects.clear(); - _traverse(val, seenObjects); -} - -function _traverse (val, seen) { - var i, keys; - var isA = Array.isArray(val); - if ((!isA && !isObject(val)) || !Object.isExtensible(val)) { - return - } - if (val.__ob__) { - var depId = val.__ob__.dep.id; - if (seen.has(depId)) { - return - } - seen.add(depId); - } - if (isA) { - i = val.length; - while (i--) { _traverse(val[i], seen); } - } else { - keys = Object.keys(val); - i = keys.length; - while (i--) { _traverse(val[keys[i]], seen); } - } -} - -/* */ - -function initState (vm) { - vm._watchers = []; - var opts = vm.$options; - if (opts.props) { initProps(vm, opts.props); } - if (opts.methods) { initMethods(vm, opts.methods); } - if (opts.data) { - initData(vm); - } else { - observe(vm._data = {}, true /* asRootData */); - } - if (opts.computed) { initComputed(vm, opts.computed); } - if (opts.watch) { initWatch(vm, opts.watch); } -} - -var isReservedProp = { key: 1, ref: 1, slot: 1 }; - -function initProps (vm, props) { - var propsData = vm.$options.propsData || {}; - var keys = vm.$options._propKeys = Object.keys(props); - var isRoot = !vm.$parent; - // root instance props should be converted - observerState.shouldConvert = isRoot; - var loop = function ( i ) { - var key = keys[i]; - /* istanbul ignore else */ - { - if (isReservedProp[key]) { - warn( - ("\"" + key + "\" is a reserved attribute and cannot be used as component prop."), - vm - ); - } - defineReactive$$1(vm, key, validateProp(key, props, propsData, vm), function () { - if (vm.$parent && !observerState.isSettingProps) { - warn( - "Avoid mutating a prop directly since the value will be " + - "overwritten whenever the parent component re-renders. " + - "Instead, use a data or computed property based on the prop's " + - "value. Prop being mutated: \"" + key + "\"", - vm - ); - } - }); - } - }; - - for (var i = 0; i < keys.length; i++) loop( i ); - observerState.shouldConvert = true; -} - -function initData (vm) { - var data = vm.$options.data; - data = vm._data = typeof data === 'function' - ? data.call(vm) - : data || {}; - if (!isPlainObject(data)) { - data = {}; - "development" !== 'production' && warn( - 'data functions should return an object:\n' + - 'https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function', - vm - ); - } - // proxy data on instance - var keys = Object.keys(data); - var props = vm.$options.props; - var i = keys.length; - while (i--) { - if (props && hasOwn(props, keys[i])) { - "development" !== 'production' && warn( - "The data property \"" + (keys[i]) + "\" is already declared as a prop. " + - "Use prop default value instead.", - vm - ); - } else { - proxy(vm, keys[i]); - } - } - // observe data - observe(data, true /* asRootData */); -} - -var computedSharedDefinition = { - enumerable: true, - configurable: true, - get: noop, - set: noop -}; - -function initComputed (vm, computed) { - for (var key in computed) { - /* istanbul ignore if */ - if ("development" !== 'production' && key in vm) { - warn( - "existing instance property \"" + key + "\" will be " + - "overwritten by a computed property with the same name.", - vm - ); - } - var userDef = computed[key]; - if (typeof userDef === 'function') { - computedSharedDefinition.get = makeComputedGetter(userDef, vm); - computedSharedDefinition.set = noop; - } else { - computedSharedDefinition.get = userDef.get - ? userDef.cache !== false - ? makeComputedGetter(userDef.get, vm) - : bind$1(userDef.get, vm) - : noop; - computedSharedDefinition.set = userDef.set - ? bind$1(userDef.set, vm) - : noop; - } - Object.defineProperty(vm, key, computedSharedDefinition); - } -} - -function makeComputedGetter (getter, owner) { - var watcher = new Watcher(owner, getter, noop, { - lazy: true - }); - return function computedGetter () { - if (watcher.dirty) { - watcher.evaluate(); - } - if (Dep.target) { - watcher.depend(); - } - return watcher.value - } -} - -function initMethods (vm, methods) { - for (var key in methods) { - vm[key] = methods[key] == null ? noop : bind$1(methods[key], vm); - if ("development" !== 'production' && methods[key] == null) { - warn( - "method \"" + key + "\" has an undefined value in the component definition. " + - "Did you reference the function correctly?", - vm - ); - } - } -} - -function initWatch (vm, watch) { - for (var key in watch) { - var handler = watch[key]; - if (Array.isArray(handler)) { - for (var i = 0; i < handler.length; i++) { - createWatcher(vm, key, handler[i]); - } - } else { - createWatcher(vm, key, handler); - } - } -} - -function createWatcher (vm, key, handler) { - var options; - if (isPlainObject(handler)) { - options = handler; - handler = handler.handler; - } - if (typeof handler === 'string') { - handler = vm[handler]; - } - vm.$watch(key, handler, options); -} - -function stateMixin (Vue) { - // flow somehow has problems with directly declared definition object - // when using Object.defineProperty, so we have to procedurally build up - // the object here. - var dataDef = {}; - dataDef.get = function () { - return this._data - }; - { - dataDef.set = function (newData) { - warn( - 'Avoid replacing instance root $data. ' + - 'Use nested data properties instead.', - this - ); - }; - } - Object.defineProperty(Vue.prototype, '$data', dataDef); - - Vue.prototype.$set = set$1; - Vue.prototype.$delete = del; - - Vue.prototype.$watch = function ( - expOrFn, - cb, - options - ) { - var vm = this; - options = options || {}; - options.user = true; - var watcher = new Watcher(vm, expOrFn, cb, options); - if (options.immediate) { - cb.call(vm, watcher.value); - } - return function unwatchFn () { - watcher.teardown(); - } - }; -} - -function proxy (vm, key) { - if (!isReserved(key)) { - Object.defineProperty(vm, key, { - configurable: true, - enumerable: true, - get: function proxyGetter () { - return vm._data[key] - }, - set: function proxySetter (val) { - vm._data[key] = val; - } - }); - } -} - -/* */ - -var VNode = function VNode ( - tag, - data, - children, - text, - elm, - context, - componentOptions -) { - this.tag = tag; - this.data = data; - this.children = children; - this.text = text; - this.elm = elm; - this.ns = undefined; - this.context = context; - this.functionalContext = undefined; - this.key = data && data.key; - this.componentOptions = componentOptions; - this.child = undefined; - this.parent = undefined; - this.raw = false; - this.isStatic = false; - this.isRootInsert = true; - this.isComment = false; - this.isCloned = false; - this.isOnce = false; -}; - -var createEmptyVNode = function () { - var node = new VNode(); - node.text = ''; - node.isComment = true; - return node -}; - -function createTextVNode (val) { - return new VNode(undefined, undefined, undefined, String(val)) -} - -// optimized shallow clone -// used for static nodes and slot nodes because they may be reused across -// multiple renders, cloning them avoids errors when DOM manipulations rely -// on their elm reference. -function cloneVNode (vnode) { - var cloned = new VNode( - vnode.tag, - vnode.data, - vnode.children, - vnode.text, - vnode.elm, - vnode.context, - vnode.componentOptions - ); - cloned.ns = vnode.ns; - cloned.isStatic = vnode.isStatic; - cloned.key = vnode.key; - cloned.isCloned = true; - return cloned -} - -function cloneVNodes (vnodes) { - var res = new Array(vnodes.length); - for (var i = 0; i < vnodes.length; i++) { - res[i] = cloneVNode(vnodes[i]); - } - return res -} - -/* */ - -function mergeVNodeHook (def, hookKey, hook, key) { - key = key + hookKey; - var injectedHash = def.__injected || (def.__injected = {}); - if (!injectedHash[key]) { - injectedHash[key] = true; - var oldHook = def[hookKey]; - if (oldHook) { - def[hookKey] = function () { - oldHook.apply(this, arguments); - hook.apply(this, arguments); - }; - } else { - def[hookKey] = hook; - } - } -} - -/* */ - -function updateListeners ( - on, - oldOn, - add, - remove$$1, - vm -) { - var name, cur, old, fn, event, capture, once; - for (name in on) { - cur = on[name]; - old = oldOn[name]; - if (!cur) { - "development" !== 'production' && warn( - "Invalid handler for event \"" + name + "\": got " + String(cur), - vm - ); - } else if (!old) { - once = name.charAt(0) === '~'; // Prefixed last, checked first - event = once ? name.slice(1) : name; - capture = event.charAt(0) === '!'; - event = capture ? event.slice(1) : event; - if (Array.isArray(cur)) { - add(event, (cur.invoker = arrInvoker(cur)), once, capture); - } else { - if (!cur.invoker) { - fn = cur; - cur = on[name] = {}; - cur.fn = fn; - cur.invoker = fnInvoker(cur); - } - add(event, cur.invoker, once, capture); - } - } else if (cur !== old) { - if (Array.isArray(old)) { - old.length = cur.length; - for (var i = 0; i < old.length; i++) { old[i] = cur[i]; } - on[name] = old; - } else { - old.fn = cur; - on[name] = old; - } - } - } - for (name in oldOn) { - if (!on[name]) { - once = name.charAt(0) === '~'; // Prefixed last, checked first - event = once ? name.slice(1) : name; - capture = event.charAt(0) === '!'; - event = capture ? event.slice(1) : event; - remove$$1(event, oldOn[name].invoker, capture); - } - } -} - -function arrInvoker (arr) { - return function (ev) { - var arguments$1 = arguments; - - var single = arguments.length === 1; - for (var i = 0; i < arr.length; i++) { - single ? arr[i](ev) : arr[i].apply(null, arguments$1); - } - } -} - -function fnInvoker (o) { - return function (ev) { - var single = arguments.length === 1; - single ? o.fn(ev) : o.fn.apply(null, arguments); - } -} - -/* */ - -// The template compiler attempts to minimize the need for normalization by -// statically analyzing the template at compile time. -// -// For plain HTML markup, normalization can be completely skipped because the -// generated render function is guaranteed to return Array. There are -// two cases where extra normalization is needed: - -// 1. When the children contains components - because a functional component -// may return an Array instead of a single root. In this case, just a simple -// nomralization is needed - if any child is an Array, we flatten the whole -// thing with Array.prototype.concat. It is guaranteed to be only 1-level deep -// because functional components already normalize their own children. -function simpleNormalizeChildren (children) { - for (var i = 0; i < children.length; i++) { - if (Array.isArray(children[i])) { - return Array.prototype.concat.apply([], children) - } - } - return children -} - -// 2. When the children contains constrcuts that always generated nested Arrays, -// e.g.