Merge pull request #6 from weexteam/feature-refactoring

Feature refactoring
diff --git a/.gitignore b/.gitignore
index a76bb72..a9f497d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,5 @@
 node_modules
 lib
-
-test/actual
-test/expect/*.js
+test/actual/*.js
+test/actual/*.map
+*.log
\ No newline at end of file
diff --git a/README.md b/README.md
index 073d86a..c30a50a 100644
--- a/README.md
+++ b/README.md
@@ -5,16 +5,16 @@
 ## Install
 
 ```
-npm install weex-loader --save
+npm install weex-loader@0.3.0-alpha babel-loader babel-preset-es2015 babel-runtime babel-plugin-transform-runtime --save
 ```
 
-## Feature
+## Features
 
 0. Can load `.we` file.
-1. Can load parted files(`.js/.css/.tpl`) instead of one `.we` file.
-2. Can chain any loader you want when write parted files.
-3. Can require a CommonJS module.
-4. Can specify the name of a component.
+0. Can load parted files(`.js/.css/.html`) via `src` attribute.
+0. Can specify a custom language to chain any loader.
+0. Can specify name when require `.we` file.
+0. Can write es2015 in script.
 
 ## Usage
 
@@ -22,14 +22,10 @@
 
 **make a webpack config**
 ```javascript
-var path = require('path');
-var webpack = require('webpack');
-var loader = require('weex-loader');
-
 module.exports = {
-  entry: './test/main.we?entry=true',
+  entry: './main.we?entry',
   output: {
-    path: './test/actual',
+    path: './dist',
     filename: 'main.js'
   },
   module: {
@@ -45,107 +41,71 @@
 
 ### How to write parted files
 
-#### write .js/.css/.tpl anywhere
-
-**main.js as script**
-```javascript
-module.exports = {
-    data: {
-        text: 'Hello World'
-    }
-}
-
-module.exports.style = require('./main.css');
-module.exports.template = require('./main.tpl');
-```
-
-**main.css as style**
-```css
-.h1 {
-    font-size: 60px;
-    color: red;
-    padding-top: 20px;
-    padding-bottom: 20px;
-    padding-left: 20px;
-    padding-right: 20px;
-}
-```
-
-**main.tpl as template**
+**specify `src` attribute**
 ```html
-<container>
-    <text class="h1">{{text}}</text>
-</container>
+<template src="./main.html"></template>
+<style src="./main.css"></style>
+<script src="./main.js"></script>
 ```
 
-Then change the entry to `main.js` in `webpack.config.js`
+### add some custom language for loaders
 
-#### add some loader in webpack config
-
-**loader for script**
+**append a weex config in webpack config**
 ```javascript
-  {
-    test: /\.js(\?[^?]+)?$/,
-    loader: 'weex?type=script'
+  weex: {
+    lang: {
+      jade: ['jade-html'] // a jade langauge will chain "jade-html-loader"
+    }
   }
 ```
 
-**loader for style**
-```javascript
-  {
-    test: /\.css(\?[^?]+)?$/, 
-    loader: 'weex?type=style'
-  }
+**main.we**
+```
+<template lang="jade">
+div
+  text Hello Weex
+</template>
 ```
 
-**loader for template**
-```javascript
-  {
-    test: /\.tpl(\?[^?]+)?$/, 
-    loader: 'weex?type=tpl'
-  }
+### How to require `.we` file as component element
+
+0. first, require a `path/to/component.we` in `script` like `require('./foo.we')` or write inline element like `<element name="foo" src="./foo.we"></element>`.
+1. second, use it in `template` like `<foo></foo>`.
+
 ```
+<element name="foo" src="./foo.we"></element>
 
-### How to require a CommonJS module
+<template>
+  <div>
+    <foo></foo>
+    <bar></bar>
+  </div>
+</template>
 
-0. first, require a `path/to/module.js` in `script` like `var _ = require('lodash')`. 
-1. then use it in `script`.
-
-### How to embed a composed component
-
-0. first, require a `path/to/component.js` in `script` like `require('./sub.js')`.
-1. second, use it in `template` like `<sub></sub>`.
+<script>
+  require('./bar.we')
+</script>
+```
 
 ### How to specify the name of a component
 
 0. By default, the name is the basename without extname of component path.
-1. Give a name query in require request, like `require('./sub.js?name="goto"')`
-2. use the name in `template` like `<goto></goto>`.
+1. Give a name query in require request, like `require('./foo.we?name="fooo"')`. Or specify a name attribute in element, like `<element name="fooo" src="./foo.we" ></element>`
+2. use the name in `template` like `<fooo></fooo>`.
 
-## Chain your favorite loader
-
-For examples:
-
-### write ES2015
-
-Only your need is chain babel-loader before weex-loader.
-
-```javascript
-  {
-    test: /\.js(\?[^?]+)?$/,
-    loader: 'weex?type=script!babel?presets[]=es2015'
-  }
 ```
+<element name="fooo" src="./foo.we"></element>
 
-### write SCSS
+<template>
+  <div>
+    <fooo></fooo>
+    <baar></baar>
+  </div>
+</template>
 
-Only your need is chain scss loader before weex-loader.
-
-```javascript
-  {
-    test: /\.scss(\?[^?]+)?$/, 
-    loader: 'weex?type=style!scss'
-  }
+<script>
+  require('./bar.we?name=baar')
+</script>
 ```
 
 ## Test
@@ -153,9 +113,33 @@
 ```bash
 npm run test
 ```
-will run mocha testing
+will run mocha testing.
 
-```bash
-npm run serve
-```
-then open `localhost:12581` on chrome, will run web testing
+And you can check the specs in `test/spec` folder.
+
+## Specs
+
+- [Build with single template tag](test/spec/a.we)
+- [Build with template and style tags](test/spec/b.we)
+- [Build with template/style/script tags](test/spec/c.we)
+- [Build with single element tag](test/spec/d.we)
+- [Build with multiple element tag](test/spec/e.we)
+- [Build from parted files specifed in `src` attr](test/spec/f.we)
+- [Manually Require component and specifies an alias name](test/spec/g.we)
+- [Automaticely require component under some folder](test/spec/h.we)
+- [Build with config/data tag](test/spec/i.we)
+- [Require weex module](test/spec/j.we)
+- [Build by using custom language](test/spec/k.we)
+- [Require commonjs module](test/spec/l.we)
+- [Require weex module in commonjs module](test/spec/m.we)
+- [Build with sourcemap(no test)](test/spec/n.we)
+
+## Knew Issues
+
+- [`Bug` Source Map Offset](https://github.com/webpack/webpack/issues/2145). Encoding to this problem, please use `devtool:"eval-source-map"` instead of `devtool:"source-map"`.
+- [`Bug` Can't set debugger breakpoint](#). I still don't know the reason, but you can debug with `debugger` keyword.
+
+
+
+
+
diff --git a/circle.yml b/circle.yml
index 1bd54b3..fe46540 100644
--- a/circle.yml
+++ b/circle.yml
@@ -1,3 +1,3 @@
 machine:
   node:
-    version: 4.2.1
+    version: 4
diff --git a/index.js b/index.js
index 9615572..18abae3 100644
--- a/index.js
+++ b/index.js
@@ -1 +1 @@
-module.exports = require('./lib/')
+module.exports = require('./lib/loader')
diff --git a/package.json b/package.json
index 1c99ba4..d7d304c 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "weex-loader",
-  "version": "0.2.3",
+  "version": "0.3.0-alpha",
   "description": "a webpack loader for weex",
   "main": "index.js",
   "author": "terrykingcha <terrykingcha@gmail.com>",
@@ -16,30 +16,40 @@
     "transformer"
   ],
   "scripts": {
-    "prepublish": "node_modules/babel-cli/bin/babel.js src --out-dir lib",
-    "test:lint": "eslint src",
+    "clear": "rm -f lib/* && rm -f test/actual/*",
+    "lint": "eslint --fix src",
+    "build": "node_modules/babel-cli/bin/babel.js src --out-dir lib",
     "test:build": "webpack --config test/webpack.config.js",
-    "test:transform": "transformer test/expect/*.we -o test/expect",
     "test:mocha": "mocha test/test.js",
-    "test": "npm run prepublish && npm run test:lint && npm run test:build && npm run test:transform && npm run test:mocha",
-    "serve": "serve ./test -p 12581"
+    "pretest": "npm run clear && npm run lint && npm run build",
+    "test": "npm run test:build && npm run test:mocha",
+    "ci": "npm run test",
+    "prepublish": "npm run clear && npm run lint && npm run build"
   },
   "devDependencies": {
     "babel-cli": "^6.10.1",
     "babel-core": "^6.10.4",
     "babel-loader": "^6.2.4",
+    "babel-plugin-transform-runtime": "^6.9.0",
     "babel-preset-es2015": "^6.9.0",
+    "babel-runtime": "^6.9.2",
     "chai": "^3.5.0",
+    "coffee-loader": "^0.7.2",
+    "coffee-script": "^1.10.0",
     "eslint": "^2.13.1",
-    "less": "^2.6.1",
-    "less-loader": "^2.2.3",
+    "jade": "^1.11.0",
+    "jade-html-loader": "0.0.3",
+    "js-base64": "^2.1.9",
     "mocha": "^2.4.5",
-    "serve": "^1.4.0",
+    "parse5": "^2.1.5",
+    "postcss-cssnext": "^2.7.0",
+    "postcss-loader": "^0.9.1",
     "sinon": "^1.17.3",
     "sinon-chai": "^2.8.0",
     "webpack": "~1.13.0"
   },
   "dependencies": {
+    "hash-sum": "^1.0.2",
     "loader-utils": "~0.2.14",
     "md5": "^2.1.0",
     "source-map": "^0.5.6",
diff --git a/src/config.js b/src/config.js
index c1e9e30..ded0c99 100644
--- a/src/config.js
+++ b/src/config.js
@@ -1,3 +1 @@
-import pkg from '../package.json'
-export const transformerVersion = pkg.dependencies['weex-transformer'].match(/\d+(?:\.\d+){0,2}/)[0]
 export const logLevel = false
diff --git a/src/element.js b/src/element.js
new file mode 100644
index 0000000..378a261
--- /dev/null
+++ b/src/element.js
@@ -0,0 +1,34 @@
+import loaderUtils from 'loader-utils'
+
+import {
+  extractBlocks
+} from './parser'
+
+module.exports = function (source) {
+  this.cacheable && this.cacheable()
+
+  const callback = this.async()
+  const loaderQuery = loaderUtils.parseQuery(this.query)
+  const resourceQuery = loaderUtils.parseQuery(this.resourceQuery)
+  const name = resourceQuery.name
+
+  let contentPromise
+
+  if (loaderQuery.extract) {
+    contentPromise =
+      extractBlocks(source, 'elements')
+  }
+  else {
+    contentPromise = Promise.resolve({ content: source })
+  }
+
+  contentPromise.then(elements => {
+    if (loaderQuery.raw) {
+      return elements[name].content
+    }
+  }).then(result => {
+    callback(null, result)
+  }).catch(e => {
+    callback(e, '')
+  })
+}
diff --git a/src/extract.js b/src/extract.js
new file mode 100644
index 0000000..d103e3f
--- /dev/null
+++ b/src/extract.js
@@ -0,0 +1,96 @@
+import loaderUtils from 'loader-utils'
+
+import {
+  extractBlocks
+} from './parser'
+import {
+  splitSourceLine,
+  generateMap,
+  consumeMap
+  // printSourceWithLine
+} from './util'
+
+module.exports = function (source, inputSourceMap) {
+  this.cacheable && this.cacheable()
+
+  const callback = this.async()
+  const loaderQuery = loaderUtils.parseQuery(this.query)
+  const type = loaderQuery.type
+  let index = loaderQuery.index
+
+  if (index != null && index.match(/^\d+$/)) {
+    index = parseInt(index)
+  }
+
+  extractBlocks(source, type)
+    .then(result => {
+      if (index != null) {
+        result = result[index]
+      }
+      const content = result.content.trim()
+
+      let map
+      if (this.sourceMap &&
+        (type === 'scripts' || type === 'elements')) {
+        const contentLineStart = result.line
+        let contentLineCount = 0
+
+        let cmap
+        if (inputSourceMap) {
+          cmap = consumeMap(this, source, inputSourceMap)
+          source = cmap.sourcesContent.join('')
+            // printSourceWithLine(source)
+        }
+
+        const iterator = splitSourceLine(content)
+          .map((input, line) => {
+            contentLineCount++
+            line = line + 1
+            let originalLine = line + contentLineStart
+            const generatedLine = line
+            if (cmap) {
+              // mapping to the original of input source
+              originalLine = cmap.mapping[`line-${originalLine}-column-0`].line
+                // console.log(originalLine + ':', input)
+            }
+            return {
+              original: {
+                line: originalLine,
+                column: 0
+              },
+              generated: {
+                line: generatedLine,
+                column: 0
+              }
+            }
+          })
+
+        // if (type === 'scripts') {
+        //   let lineStart = contentLineStart
+        //   if (cmap) {
+        //     // mapping to the original of input source
+        //     lineStart = cmap.mapping[`line-${lineStart}-column-0`].line
+        //   }
+        //   source = splitSourceLine(source)
+        //     .map((input, line) => {
+        //       line = line + 1
+        //       // console.log(line + ':', input)
+        //       if (line === lineStart
+        //           || line === lineStart + contentLineCount + 1) {
+        //         return input + ' /* generated by weex-loader */'
+        //       } else {
+        //         return input
+        //       }
+        //     }).join('\n')
+        // }
+
+        map = generateMap(this, source, iterator)
+      }
+
+      return [content, map]
+    }).then(([content, map]) => {
+      callback(null, content, map && map.toJSON() || inputSourceMap)
+    }).catch(e => {
+      callback(e, '')
+    })
+}
diff --git a/src/index.js b/src/index.js
deleted file mode 100644
index b3d4145..0000000
--- a/src/index.js
+++ /dev/null
@@ -1,81 +0,0 @@
-import loaderUtils from 'loader-utils'
-
-import {
-  parseScript,
-  parseStyle,
-  parseTemplate,
-  parseWeex
-} from './parser'
-import { getFilenameByPath } from './util'
-import * as config from './config'
-import * as legacy from './legacy'
-import { ScriptMap } from './map'
-
-function partedLoader (type, loader, params, source, map) {
-  let promise
-  switch (type) {
-    case 'js':
-    case 'script':
-      const transformerVersion = config.transformerVersion
-      promise = parseScript(loader, params, source,
-        { config: JSON.stringify({ transformerVersion }) })
-      break
-    case 'css':
-    case 'style':
-      promise = parseStyle(loader, params, source)
-      break
-    case 'html':
-    case 'tpl':
-    case 'template':
-      promise = parseTemplate(loader, params, source)
-      break
-    case 'we':
-    default:
-      map.enable()
-      promise = parseWeex(loader, params, source, map)
-      break
-  }
-  return promise
-}
-
-function loader (source) {
-  this.cacheable && this.cacheable()
-
-  const callback = this.async()
-  const params = {
-    loaderQuery: loaderUtils.parseQuery(this.query),
-    resourceQuery: loaderUtils.parseQuery(this.resourceQuery),
-    resourcePath: this.resourcePath
-  }
-  const type = params.loaderQuery.type || 'we'
-  const { resourcePath } = params
-  const filename = getFilenameByPath(resourcePath)
-  const map = new ScriptMap(filename, source)
-
-  const promise = partedLoader(type, this, params, source, map)
-
-  promise.then(result => {
-    if (map.enabled) {
-      map.parse()
-    }
-    if (type === 'style' || type === 'css' ||
-      type === 'html' || type === 'tpl' || type === 'template') {
-      result = 'module.exports=' + result
-    }
-    callback(null, result, map.toJSON())
-  }).catch(err => {
-    // console.error(err.stack)
-    this.emitError(err.toString())
-    callback(err.toString(), '')
-  })
-}
-
-loader.setLogLevel = level => {
-  config.logLevel = level
-}
-
-for (const key in legacy) {
-  loader[key] = legacy[key]
-}
-
-module.exports = loader
diff --git a/src/json.js b/src/json.js
new file mode 100644
index 0000000..59c2977
--- /dev/null
+++ b/src/json.js
@@ -0,0 +1,5 @@
+module.exports = function (source) {
+  this.cacheable && this.cacheable()
+
+  return `module.exports = ${source}`
+}
diff --git a/src/loader.js b/src/loader.js
new file mode 100644
index 0000000..0fc97fe
--- /dev/null
+++ b/src/loader.js
@@ -0,0 +1,387 @@
+import loaderUtils from 'loader-utils'
+import path from 'path'
+import fs from 'fs'
+import md5 from 'md5'
+
+import * as config from './config'
+import * as legacy from './legacy'
+
+import {
+  parseFragment
+} from './parser'
+import {
+  getNameByPath,
+  getRequireString,
+  stringifyLoaders
+} from './util'
+
+const loaderPath = __dirname
+const defaultLoaders = {
+  main: path.resolve(loaderPath, 'loader.js'),
+  extract: path.resolve(loaderPath, 'extract.js'),
+  template: path.resolve(loaderPath, 'template.js'),
+  style: path.resolve(loaderPath, 'style.js'),
+  script: path.resolve(loaderPath, 'script.js'),
+  json: path.resolve(loaderPath, 'json.js'),
+  babel: 'babel-loader'
+}
+
+function getLoaderString (type, config) {
+  config = config || {}
+  let customLoader
+  let loaders
+
+  if (config.lang && config.customLang[config.lang]) {
+    customLoader = config.customLang[config.lang]
+  }
+
+  if (type === 'main') {
+    loaders = [{
+      name: defaultLoaders.main
+    }]
+    return stringifyLoaders(loaders)
+  }
+
+  if (type === 'element') {
+    loaders = [{
+      name: defaultLoaders.main,
+      query: {
+        element: config.source ? undefined : true
+      }
+    }]
+    if (!config.source) {
+      loaders.push({
+        name: defaultLoaders.extract,
+        query: {
+          index: config.name,
+          type: 'elements'
+        }
+      })
+    }
+    return stringifyLoaders(loaders)
+  }
+
+  if (type === 'template') {
+    loaders = [{
+      name: defaultLoaders.json
+    }, {
+      name: defaultLoaders.template
+    }]
+    if (customLoader) {
+      loaders = loaders.concat(customLoader)
+    }
+    if (!config.source) {
+      loaders.push({
+        name: defaultLoaders.extract,
+        query: {
+          type: 'template'
+        }
+      })
+    }
+    if (config.element) {
+      loaders.push({
+        name: defaultLoaders.extract,
+        query: {
+          index: config.elementName,
+          type: 'elements'
+        }
+      })
+    }
+    return stringifyLoaders(loaders)
+  }
+
+  if (type === 'style') {
+    loaders = [{
+      name: defaultLoaders.json
+    }, {
+      name: defaultLoaders.style
+    }]
+    if (customLoader) {
+      loaders = loaders.concat(customLoader)
+    }
+    if (!config.source) {
+      loaders.push({
+        name: defaultLoaders.extract,
+        query: {
+          index: 0,
+          type: 'styles'
+        }
+      })
+    }
+    if (config.element) {
+      loaders.push({
+        name: defaultLoaders.extract,
+        query: {
+          index: config.elementName,
+          type: 'elements'
+        }
+      })
+    }
+    return stringifyLoaders(loaders)
+  }
+
+  if (type === 'script') {
+    loaders = [{
+      name: defaultLoaders.script
+    }]
+    if (customLoader) {
+      loaders = loaders.concat(customLoader)
+    }
+    else {
+      loaders.push({
+        name: defaultLoaders.babel,
+        query: {
+          presets: ['es2015'],
+          plugins: ['transform-runtime'],
+          comments: 'false'
+        }
+      })
+    }
+    if (!config.source) {
+      loaders.push({
+        name: defaultLoaders.extract,
+        query: {
+          index: 0,
+          type: 'scripts'
+        }
+      })
+    }
+    if (config.element) {
+      loaders.push({
+        name: defaultLoaders.extract,
+        query: {
+          index: config.elementName,
+          type: 'elements'
+        }
+      })
+    }
+    return stringifyLoaders(loaders)
+  }
+
+  if (type === 'config') {
+    loaders = [{
+      name: defaultLoaders.json
+    }]
+    if (!config.source) {
+      loaders.push({
+        name: defaultLoaders.extract,
+        query: {
+          type: 'config'
+        }
+      })
+    }
+    return stringifyLoaders(loaders)
+  }
+
+  if (type === 'data') {
+    loaders = [{
+      name: defaultLoaders.json
+    }]
+    if (!config.source) {
+      loaders.push({
+        name: defaultLoaders.extract,
+        query: {
+          type: 'data'
+        }
+      })
+    }
+    return stringifyLoaders(loaders)
+  }
+}
+
+function loader (source) {
+  this.cacheable && this.cacheable()
+
+  const options = this.options.weex || {}
+  const customLang = options.lang || {}
+
+  const loaderQuery = loaderUtils.parseQuery(this.query)
+  const resourceQuery = loaderUtils.parseQuery(this.resourceQuery)
+  const resourcePath = this.resourcePath
+  const isElement = loaderQuery.element
+  const isEntry = resourceQuery.entry
+  const filename = path.relative('.', resourcePath)
+  const name = isEntry ? md5(filename) :
+                          (resourceQuery.name ||
+                            getNameByPath(resourcePath))
+
+  let output = ''
+
+  const frag = parseFragment(source)
+
+  const elementNames = []
+  if (frag.element.length) {
+    for (let i = 0; i < frag.element.length; i++) {
+      const element = frag.element[i]
+      if (!element.name) {
+        this.emitError('Element block need a name attribute')
+        return ''
+      }
+      elementNames.push(element.name)
+
+      let src = resourcePath
+      if (element.src) {
+        src = element.src
+      }
+
+      output += getRequireString(
+                  this,
+                  getLoaderString('element', {
+                    customLang,
+                    name: element.name,
+                    source: element.src
+                  }),
+                  `${src}?name=${element.name}`
+                )
+    }
+  }
+
+  if (frag.deps.length) {
+    for (const dep of frag.deps) {
+      const filepath = path.resolve(path.dirname(resourcePath), `${dep}.we`)
+      if (elementNames.indexOf(dep) < 0
+            && fs.existsSync(filepath)) {
+        output += getRequireString(
+                    this,
+                    getLoaderString('main'),
+                    `./${dep}.we`
+                  )
+      }
+    }
+  }
+
+  if (!frag.template.length) {
+    this.emitError('Template block is required')
+    return ''
+  }
+  else {
+    const template = frag.template[0]
+    let src = resourcePath
+    if (template.src) {
+      src = template.src
+    }
+    output += 'var __weex_template__ = ' +
+                getRequireString(
+                  this,
+                  getLoaderString('template', {
+                    customLang,
+                    lang: template.lang,
+                    element: isElement,
+                    elementName: isElement ? name : undefined,
+                    source: template.src
+                  }),
+                  src
+                )
+  }
+
+  if (frag.style.length) {
+    const style = frag.style[0]
+    let src = resourcePath
+    if (style.src) {
+      src = style.src
+    }
+    output += 'var __weex_style__ = ' +
+                getRequireString(
+                  this,
+                  getLoaderString('style', {
+                    customLang,
+                    lang: style.lang,
+                    element: isElement,
+                    elementName: isElement ? name : undefined,
+                    source: style.src
+                  }),
+                  src
+                )
+  }
+
+  if (frag.script.length) {
+    const script = frag.script[0]
+    let src = resourcePath
+    if (script.src) {
+      src = script.src
+    }
+    output += 'var __weex_script__ = ' +
+                getRequireString(
+                  this,
+                  getLoaderString('script', {
+                    customLang,
+                    lang: script.lang,
+                    element: isElement,
+                    elementName: isElement ? name : undefined,
+                    source: script.src
+                  }),
+                  src
+                )
+  }
+
+  if (isEntry && frag.data.length) {
+    const data = frag.data[0]
+    let src = resourcePath
+    if (data.src) {
+      src = data.src
+    }
+    output += 'var __weex_data__ = ' +
+                getRequireString(
+                  this,
+                  getLoaderString('data', {
+                    source: data.src
+                  }),
+                  src
+                )
+  }
+
+  if (isEntry && frag.config.length) {
+    const config = frag.config[0]
+    let src = resourcePath
+    if (config.src) {
+      src = config.src
+    }
+    output += 'var __weex_config__ = ' +
+                getRequireString(
+                  this,
+                  getLoaderString('config', {
+                    source: config.src
+                  }),
+                  src
+                )
+  }
+
+  output += `
+__weex_define__('@weex-component/${name}', [], function(__weex_require__, __weex_exports__, __weex_module__) {
+` + (
+  frag.script.length > 0 ? `
+    __weex_script__(__weex_module__, __weex_exports__, __weex_require__)
+    if (__weex_exports__.__esModule && __weex_exports__.default) {
+      __weex_module__.exports = __weex_exports__.default
+    }
+` : ''
+) +
+`
+    __weex_module__.exports.template = __weex_template__
+` + (
+  frag.style.length > 0 ? `
+    __weex_module__.exports.style = __weex_style__
+` : ''
+) + `
+})
+`
+  if (isEntry) {
+    output += `
+__weex_bootstrap__('@weex-component/${name}'`
+  + (frag.config.length > 0 ? `,__weex_config__` : ',undefined')
+  + (frag.data.length > 0 ? `,__weex_data__` : ',undefined')
++ `)`
+  }
+
+  return output
+}
+
+loader.setLogLevel = level => {
+  config.logLevel = level
+}
+
+for (const key in legacy) {
+  loader[key] = legacy[key]
+}
+
+module.exports = loader
diff --git a/src/map.js b/src/map.js
deleted file mode 100644
index b859690..0000000
--- a/src/map.js
+++ /dev/null
@@ -1,109 +0,0 @@
-import { SourceMapGenerator } from 'source-map'
-
-export class ScriptMap {
-  constructor (filename, content) {
-    this.filename = filename
-    this.content = content
-    const generator = new SourceMapGenerator()
-    generator.setSourceContent(filename, content)
-    this.generator = generator
-    this.history = []
-    this.elements = {}
-    this.enabled = false
-  }
-
-  enable () {
-    this.enabled = true
-  }
-
-  start () {
-    if (!this.enabled) { return }
-    this.current = { elements: [], scripts: [] }
-  }
-
-  end () {
-    if (!this.enabled) { return }
-    const current = this.current
-    this.current = {}
-
-    // re-order the elements and scripts into history
-    const length = current.elements.length
-    if (length > 0) {
-      const children = this.history.splice(-length, length)
-      current.children = children
-    }
-
-    current.elements.concat(current.scripts).forEach(item => {
-      current.name = item.name
-      delete item.name
-    })
-
-    current.elements.forEach((info, index) => {
-      current.children[index].length = info.length
-      current.children[index].line = info.line
-    })
-
-    delete current.elements
-    this.history.push(current)
-  }
-
-  addElement (name, index, line, length) {
-    if (!this.enabled) { return }
-    this.current.elements.push({ name, index, line, length })
-  }
-
-  addScript (name, info, externalOffset) {
-    if (!this.enabled) { return }
-    this.current.scripts.push({ name, info, externalOffset })
-  }
-
-  setElementPosition (name, line, column) {
-    if (!this.enabled) { return }
-    this.elements[name] = { line, column }
-  }
-
-  parse (target, startLine) {
-    if (!this.enabled) { return }
-    target = target || this.history[0]
-    if (!target) { return }
-    startLine = startLine || 0
-
-    const { name, line, scripts, children } = target
-    const elInfo = this.elements[name] || {};
-
-    (scripts || []).forEach(script => {
-      const { info, externalOffset } = script
-      const { original, generated } = info
-      const scriptLength = info.length
-      this.add(
-        original.line + (elInfo.line || 1) - 1,
-        scriptLength,
-        generated.line + startLine + (line || 1) - 1 + externalOffset
-      )
-    });
-
-    (children || []).forEach(child => {
-      this.parse(child, startLine + (line || 1) - 1)
-    })
-
-    this.json = true
-  }
-
-  add (originalLine, length, generatedLine) {
-    if (!this.enabled) { return }
-    const option = {
-      source: this.filename,
-      original: { line: originalLine, column: 1 },
-      generated: { line: generatedLine, column: 1 }
-    }
-    for (let i = 0; i < length; i++) {
-      option.original.line = originalLine + i
-      option.generated.line = generatedLine + i
-      this.generator.addMapping(option)
-    }
-  }
-
-  toJSON () {
-    return this.json ? this.generator.toJSON() : null
-  }
-}
diff --git a/src/parser.js b/src/parser.js
index cb16ad0..3b8ad50 100644
--- a/src/parser.js
+++ b/src/parser.js
@@ -1,265 +1,141 @@
+import parse5 from 'parse5'
 import blocker from 'weex-transformer/lib/blocker'
 import templater from 'weex-templater'
 import styler from 'weex-styler'
 import scripter from 'weex-scripter'
+import { checkTagName } from 'weex-templater/lib/validator'
 
-import md5 from 'md5'
-
-import { transformerVersion } from './config'
 import {
-  MODULE_EXPORTS_REG,
-  REQUIRE_REG,
   FUNC_START_REG,
   FUNC_END_REG,
-  getNameByPath,
-  checkFileExist,
-  depHasRequired,
-  parseElementNameByPath,
-  stringifyFunction,
-  appendToWarn
+  stringifyFunction
 } from './util'
 
-export function parseWeex (loader, params, source, map, deps, elementName) {
-  return new Promise(
-    // separate source into <element>s, <template>, <style>s and <script>s
-    separateBlocks(source, deps || []))
-    // pre-parse non-javascript parts
-    .then(preParseBlocks(loader, params, map))
-    // join blocks together and parse as javascript finally
-    .then(parseBlocks(loader, params, map, elementName))
+function getAttribute (node, name) {
+  if (node.attrs) {
+    let i = node.attrs.length
+    let attr
+    while (i--) {
+      attr = node.attrs[i]
+      if (attr.name === name) {
+        return attr.value
+      }
+    }
+  }
 }
 
-function separateBlocks (source, deps) {
-  return (resolve, reject) => {
+function extractDependencies (node, deps) {
+  if (node.childNodes) {
+    node.childNodes.forEach(child => {
+      checkTagName(child, {
+        result: {},
+        deps,
+        log: []
+      })
+      extractDependencies(child, deps)
+    })
+  }
+}
+
+export function parseFragment (source) {
+  const fragment = parse5.parseFragment(source, {
+    locationInfo: true
+  })
+
+  const output = {
+    deps: [],
+    element: [],
+    template: [],
+    style: [],
+    script: [],
+    data: [],
+    config: []
+  }
+
+  fragment.childNodes.forEach(node => {
+    let type
+
+    if (node.tagName === 'script') {
+      type = getAttribute(node, 'type')
+      if (type !== 'data' && type !== 'config') {
+        type = 'script'
+      }
+    }
+    else {
+      type = node.tagName
+    }
+
+    if (!output[type]) {
+      return
+    }
+
+    const name = getAttribute(node, 'name')
+    const src = getAttribute(node, 'src')
+    const lang = getAttribute(node, 'lang')
+
+    output[type].push({
+      name,
+      src,
+      lang,
+      node
+    })
+
+    if (type === 'template') {
+      const deps = []
+      extractDependencies(node.content, deps)
+      output.deps = deps
+    }
+  })
+
+  return output
+}
+
+export function extractBlocks (source, type) {
+  return new Promise((resolve, reject) => {
     blocker.format(source, (err, ret) => {
       if (err) {
         reject(err)
       }
       else {
-        ret.deps = deps
-        resolve(ret)
+        resolve(ret[type])
       }
     })
-  }
+  })
 }
 
-function preParseBlocks (loader, params, map) {
-  return (blocks) => {
-    const { deps, elements, template, styles, scripts, config, data } = blocks
-    const promises = [
-      Promise.resolve(),
-      Promise.resolve(),
-      Promise.resolve(),
-      Promise.resolve(scripts),
-      Promise.resolve(deps),
-      Promise.resolve(config),
-      Promise.resolve(data)
-    ]
-    let content
-    // pre-parse sub elements
-    if (elements) {
-      const elPromises = []
-      Object.keys(elements).forEach(key => {
-        const el = elements[key]
-        // record original positions of each <element>
-        map.setElementPosition(el.name, el.line, el.column)
-        elPromises.push(parseWeex(loader, params, el.content, map, deps, el.name))
-      })
-      promises[0] = Promise.all(elPromises)
-    }
-    // pre-parse template
-    if (template) {
-      content = template.content
-      promises[1] = parseTemplate(loader, params, content, deps)
-    }
-    // pre-parse styles
-    if (styles) {
-      content = styles.reduce((pre, cur) => {
-        return pre + '\n' + cur.content
-      }, '')
-      promises[2] = parseStyle(loader, params, content)
-    }
-    return Promise.all(promises)
-  }
-}
-
-function parseBlocks (loader, params, map, elementName) {
-  return (results) => {
-    const elements = results[0] || []
-    const template = results[1]
-    const style = results[2]
-    const scripts = results[3]
-    const deps = results[4] || []
-    const configResult = results[5]
-    const dataResult = results[6]
-
-    let content = ''
-    let config = {}
-    let data
-
-    const mapOffset = { basic: 0, subs: [] }
-
-    if (scripts) {
-      // record original and generated position of each <script>
-      // the generated content is begin with empty string
-      // so later the template, styles and elements will be appended/prepended
-      // and mapOffset.basic will record lines of prepended *required* content
-      content += scripts.reduce((prev, next, i) => {
-        // length of previous content
-        const line = prev.split(/\r?\n/g).length + 1
-        const column = 1
-        const oriLine = next.line
-        const oriColumn = next.column
-        mapOffset.subs.push({
-          original: { line: oriLine, column: oriColumn },
-          generated: { line, column },
-          // length of next content
-          length: next.content.split(/\r?\n/g).length
-        })
-        return prev + '\n;' + next.content
-      }, '')
-    }
-
-    let requireContent = ''
-    if (deps.length) {
-      const entryElementName = parseElementNameByPath(params.resourcePath)
-      requireContent += deps.filter(dep => {
-        if (parseElementNameByPath(dep) === entryElementName) {
-          console.warn(`[Warn]: "${dep}" cannot include <${entryElementName}> itself.`)
-          return false
-        }
-        return true
-      }).map(dep =>
-        depHasRequired(content, dep) ? 'require("' + dep + '");' : ''
-      ).join('\n')
-      if (requireContent) {
-        // length of implicitly requires
-        mapOffset.basic = requireContent.split(/\r?\n/g).length
-        content = requireContent + '\n' + content
-      }
-    }
-
-    if (template) {
-      // append template content, not impact sourcemap
-      content += '\n;module.exports.template = module.exports.template || {}' +
-        '\n;Object.assign(module.exports.template, ' + template + ')'
-    }
-
-    if (style) {
-      // append style content, not impact sourcemap
-      content += '\n;module.exports.style = module.exports.style || {}' +
-        '\n;Object.assign(module.exports.style, ' + style + ')'
-    }
-
-    // prepare entry config
-    if (configResult) {
-      config = new Function('return ' + configResult.content.replace(/\n/g, ''))()
-    }
-    config.transformerVersion = transformerVersion
-    config = JSON.stringify(config, null, 2)
-
-    // prepare entry data
-    if (dataResult) {
-      data = new Function('return ' + dataResult.content.replace(/\n/g, ''))()
-      data = JSON.stringify(data, null, 2)
-    }
-
-    return parseScript(loader, params, content, { config, data, elementName, elements, map, mapOffset })
-  }
-}
-
-export function parseTemplate (loader, params, source, deps) {
+export function parseTemplate (source) {
   return new Promise((resolve, reject) => {
     templater.parse(source, (err, obj) => {
       if (err) {
         reject(err)
       }
       else {
-        appendToWarn(loader, obj.log)
-        // push valid obj.deps to deps
-        if (deps && obj.deps) {
-          obj.deps.map(
-            dep => checkFileExist(dep, params.resourcePath)
-          ).forEach(dep => {
-            if (dep) {
-              deps.push(dep)
-            }
-          })
-        }
         // parse json to string and treat function specially
-        let target = JSON.stringify(obj.jsonTemplate, stringifyFunction, '  ')
-        target = target.replace(FUNC_START_REG, '').replace(FUNC_END_REG, '')
-        resolve(target)
+        let parsed = JSON.stringify(obj.jsonTemplate, stringifyFunction, '  ')
+        parsed = parsed.replace(FUNC_START_REG, '').replace(FUNC_END_REG, '')
+        resolve({ parsed, log: obj.log })
       }
     })
   })
 }
 
-export function parseStyle (loader, params, source) {
+export function parseStyle (source) {
   return new Promise((resolve, reject) => {
     styler.parse(source, (err, obj) => {
       if (err) {
         reject(err)
       }
       else {
-        appendToWarn(loader, obj.log)
-        resolve(JSON.stringify(obj.jsonStyle, null, 2))
+        const parsed = JSON.stringify(obj.jsonStyle, null, 2)
+        resolve({ parsed, log: obj.log })
       }
     })
   })
 }
 
-export function parseScript (loader, params, source, env) {
-  const { config, data, elementName, elements, map, mapOffset } = env
-
-  // the entry component has a special resource query and not a sub element tag
-  const isEntry = params.resourceQuery.entry === true && !elementName
-
-  // resolve component name
-  const name = isEntry
-    ? md5(source)
-    : (elementName || params.resourceQuery.name || getNameByPath(params.resourcePath))
-
-  // join with elements deps
-  // 2 more lines between each element and the end
-  map && map.start()
-  const prefix = (elements || []).reduce((prev, next, index) => {
-    const prevLength = prev.split(/\r?\n/g).length
-    const nextLength = next.split(/\r?\n/g).length
-    // record generated positions of each <element>
-    map && map.addElement(name, index, prevLength, nextLength)
-    return prev + next + ';\n\n'
-  }, '')
-
-  // fix data option from an object to a function
-  let target = scripter.fix(source)
-
-  // wrap with __weex_define__(name, [], (r, e, m) {...})
-  // 1 more line at start, 1 more line at end
-  target = target
-      .replace(MODULE_EXPORTS_REG, '__weex_module__.exports')
-      .replace(REQUIRE_REG, '__weex_require__($1$2$1)')
-  target = ';__weex_define__("@weex-component/' + name + '", [], ' +
-      'function(__weex_require__, exports, __weex_module__)' +
-      '{\n' + target + '\n})'
-
-  // record mapOffset into sourcemap
-  if (mapOffset) {
-    // length of generated prefix (elements) and basic (implicitly requires)
-    const preLines = prefix.split(/\r?\n/g).length + mapOffset.basic
-    mapOffset.subs.forEach(info => {
-      map.addScript(elementName || name, info, preLines)
-    })
-  }
-  map && map.end()
-
-  // append __weex_bootstrap__ for entry component
-  // not impact sourcemap
-  if (isEntry) {
-    target += '\n;__weex_bootstrap__("@weex-component/' + name + '", ' +
-        String(config) + ',' +
-        String(data) + ')'
-  }
-
-  return Promise.resolve(prefix + target)
+export function parseScript (source) {
+  return new Promise((resolve, reject) => {
+    const parsed = scripter.fix(source)
+    resolve({ parsed })
+  })
 }
diff --git a/src/script.js b/src/script.js
new file mode 100644
index 0000000..23b1eae
--- /dev/null
+++ b/src/script.js
@@ -0,0 +1,32 @@
+import {
+  parseScript
+} from './parser'
+
+module.exports = function (source, map) {
+  this.cacheable && this.cacheable()
+
+  const callback = this.async()
+
+  parseScript(source)
+    .then(({
+      parsed
+    }) => {
+      let requireList = parsed.match(/require\([^()]+?\)/g)
+
+      if (requireList && requireList.length > 0) {
+        requireList = requireList.filter(str => {
+          if (str.indexOf('@weex-module') > 0) {
+            parsed = parsed.replace(str, str.replace('require', '__weex_require__'))
+            return true
+          }
+          return false
+        }).join('\n')
+      }
+
+      let result = `module.exports = function(module, exports, __weex_require__){${parsed}}`
+      result += '\n/* generated by weex-loader */\n'
+      callback(null, result, map)
+    }).catch(e => {
+      callback(e, '')
+    })
+}
diff --git a/src/style.js b/src/style.js
new file mode 100644
index 0000000..3ddbe0a
--- /dev/null
+++ b/src/style.js
@@ -0,0 +1,23 @@
+import {
+  logWarn
+} from './util'
+
+import {
+  parseStyle
+} from './parser'
+
+module.exports = function (source) {
+  this.cacheable && this.cacheable()
+
+  const callback = this.async()
+
+  parseStyle(source)
+    .then(({ parsed, log }) => {
+      if (log && log.length) {
+        logWarn(this, log)
+      }
+      callback(null, parsed)
+    }).catch(e => {
+      callback(e, '')
+    })
+}
diff --git a/src/template.js b/src/template.js
new file mode 100644
index 0000000..aec4fb5
--- /dev/null
+++ b/src/template.js
@@ -0,0 +1,23 @@
+import {
+  logWarn
+} from './util'
+
+import {
+  parseTemplate
+} from './parser'
+
+module.exports = function (source) {
+  this.cacheable && this.cacheable()
+
+  const callback = this.async()
+
+  parseTemplate(source)
+    .then(({ parsed, log }) => {
+      if (log && log.length) {
+        logWarn(this, log)
+      }
+      callback(null, parsed)
+    }).catch(e => {
+      callback(e, '')
+    })
+}
diff --git a/src/util.js b/src/util.js
index 629f1e3..8d479c7 100644
--- a/src/util.js
+++ b/src/util.js
@@ -1,13 +1,21 @@
-import fs from 'fs'
 import path from 'path'
+import loaderUtils from 'loader-utils'
+import hash from 'hash-sum'
+import {
+  SourceMapGenerator,
+  SourceMapConsumer
+} from 'source-map'
 
 import * as config from './config'
 
-export const MODULE_EXPORTS_REG = /module\.exports/g
-export const REQUIRE_REG = /require\((["'])(@weex\-module\/[^\)\1]+)\1\)/g
+export function getNameByPath (resourcePath) {
+  return path.basename(resourcePath).replace(/\..*$/, '')
+}
 
-export function getNameByPath (filepath) {
-  return path.basename(filepath).replace(/\..*$/, '')
+export function getFileNameWithHash (resourcePath, content) {
+  const filename = path.relative('.', resourcePath)
+  const cacheKey = hash(filename + content)
+  return `./${filename}?${cacheKey}`
 }
 
 export function getFilenameByPath (filepath) {
@@ -21,12 +29,12 @@
 
 export function stringifyFunction (key, value) {
   if (typeof value === 'function') {
-    return FUNC_START + value.toString() + '#####FUN_E#####'
+    return FUNC_START + value.toString() + FUNC_END
   }
   return value
 }
 
-export function appendToWarn (loader, logs) {
+export function logWarn (loader, logs) {
   if (config.logLevel && logs && logs.length) {
     logs.forEach(log => {
       loader.emitWarning(log.reason + '\t@' + log.line + ':' + log.column)
@@ -34,17 +42,120 @@
   }
 }
 
-export function checkFileExist (name, resourcePath) {
-  const context = path.dirname(resourcePath)
-  const filename = './' + name + '.we'
-  const filepath = path.resolve(context, filename)
-  return fs.existsSync(filepath) ? filename : null
+export function getRequireString (loaderContext, loader, filepath) {
+  return 'require(' +
+                loaderUtils.stringifyRequest(
+                    loaderContext,
+                    `!!${loader}!${filepath}`
+                ) +
+           ')\n'
 }
 
-export function depHasRequired (content, dep) {
-  return !content.match(new RegExp('require\\(["\']./' + path.basename(dep) + '(.we)?["\']\\)', 'g'))
+export function stringifyLoaders (loaders) {
+  return loaders.map(loader => {
+    if (typeof loader === 'string') {
+      return loader
+    }
+    else {
+      const name = loader.name
+      const query = []
+      if (loader.query) {
+        for (const k in loader.query) {
+          const v = loader.query[k]
+          if (v != null) {
+            if (v === true) {
+              query.push(k)
+            }
+            else {
+              if (v instanceof Array) {
+                query.push(`${k}[]=${v.join(',')}`)
+              }
+              query.push(`${k}=${v}`)
+            }
+          }
+        }
+      }
+      return `${name}${query.length ? ('?' + query.join('&')) : ''}`
+    }
+  }).join('!')
 }
 
-export function parseElementNameByPath (filepath) {
-  return path.parse(filepath).name
+export function generateMap (loader, source, iterator) {
+  const filePath = loader.resourcePath
+
+  const fileNameWithHash = getFileNameWithHash(filePath)
+  const sourceRoot = path.resolve('.')
+
+  const map = new SourceMapGenerator({
+    sourceRoot,
+    skipValidation: true
+  })
+  map.setSourceContent(fileNameWithHash, source)
+
+  for (const { original, generated } of iterator) {
+    map.addMapping({
+      source: fileNameWithHash,
+      original,
+      generated
+    })
+  }
+
+  return map
+}
+
+export function consumeMap (loader, target, map) {
+  const smc = new SourceMapConsumer(map)
+  let source
+  const original = []
+  const generated = []
+  const mapping = {}
+
+  splitSourceLine(target)
+    .forEach((input, line) => {
+      const column = 0
+      line = line + 1
+
+      const pos = smc.originalPositionFor({
+        line,
+        column
+      })
+
+      if (pos.source) {
+        source = pos.source
+        original.push({
+          line: pos.line,
+          column: pos.column
+        })
+        generated.push({
+          line,
+          column
+        })
+        mapping[`line-${line}-column-${column}`] = {
+          line: pos.line,
+          column: pos.column
+        }
+      }
+    })
+
+  return {
+    source,
+    original,
+    generated,
+    mapping,
+    sourcesContent: smc.sourcesContent
+  }
+}
+
+const LINE_REG = /\r?\n/g
+export function splitSourceLine (source) {
+  return source.split(LINE_REG)
+}
+
+export function printSourceWithLine (source) {
+  console.log('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
+  source = splitSourceLine(source)
+              .map((input, line) => {
+                console.log(line + 1 + ':', input)
+              })
+  console.log('<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<')
 }
diff --git a/test/a.js b/test/a.js
deleted file mode 100644
index 574e715..0000000
--- a/test/a.js
+++ /dev/null
@@ -1,13 +0,0 @@
-require('./b?name=goto');
-require('./copyright.we?name=copyright');
-
-var c = require('./lib/c');
-
-module.exports = {
-    data: {
-        text: 'Hello ' + c.name
-    }
-}
-
-module.exports.style = require('./a.less');
-module.exports.template = require('./a.tpl');
diff --git a/test/a.less b/test/a.less
deleted file mode 100644
index 331de73..0000000
--- a/test/a.less
+++ /dev/null
@@ -1,10 +0,0 @@
-@padding: 20px;
-
-.h1 {
-    font-size: 60px;
-    color: red;
-    padding-top: @padding;
-    padding-bottom: @padding;
-    padding-left: @padding;
-    padding-right: @padding;
-}
\ No newline at end of file
diff --git a/test/a.tpl b/test/a.tpl
deleted file mode 100644
index 52d1a04..0000000
--- a/test/a.tpl
+++ /dev/null
@@ -1,5 +0,0 @@
-<container>
-    <text class="h1">{{text}}</text>
-    <goto></goto>
-    <copyright></copyright>
-</container>
\ No newline at end of file
diff --git a/test/actual/.gitkeeper b/test/actual/.gitkeeper
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/actual/.gitkeeper
diff --git a/test/b.js b/test/b.js
deleted file mode 100644
index ab5c28e..0000000
--- a/test/b.js
+++ /dev/null
@@ -1,18 +0,0 @@
-import template from './b.tpl';
-import * as event from '@weex-module/event';
-
-module.exports = {
-    data: {
-        text: '',
-        paddingLeft: 20
-    },
-    template,
-    created() {
-        this.text = 'Yes It is! Go Weex >>>';
-    },
-    methods: {
-        clicked: function() {
-            event.openURL('https://github.com/alibaba/weex_toolchain');
-        }
-    }
-};
\ No newline at end of file
diff --git a/test/b.tpl b/test/b.tpl
deleted file mode 100644
index 3fb7d9b..0000000
--- a/test/b.tpl
+++ /dev/null
@@ -1,3 +0,0 @@
-<container>
-    <text onclick="clicked" style="text-decoration: underline; padding-left: {{paddingLeft}}">{{text}}</text>
-</container>
\ No newline at end of file
diff --git a/test/copyright.we b/test/copyright.we
deleted file mode 100644
index 0930225..0000000
--- a/test/copyright.we
+++ /dev/null
@@ -1,29 +0,0 @@
-<template>
-    <container>
-        <text class="{{className}} highlight">Copy right @ 2016 Weex</text>
-        <company></company>
-    </container>
-</template>
-
-<style>
-    .copyright {
-        text-align: center;
-        padding-top: 20;
-        padding-bottom: 20;
-    }
-</style>
-
-<script>
-    require('./expect/company.we');
-
-    module.exports = {
-        data: {
-            className: ''
-        },
-        created: function (argument) {
-            this.className = 'copyright';
-        }
-    }
-
-    module.exports.style = require('./highlight.css')
-</script>
\ No newline at end of file
diff --git a/test/expect/a.js b/test/expect/a.js
new file mode 100644
index 0000000..b9dc846
--- /dev/null
+++ b/test/expect/a.js
@@ -0,0 +1,15 @@
+{
+  "@weex-component/f7f03a1f8fba3f0ef22eb87969da4ac2": {
+    "template": {
+      "type": "div",
+      "children": [
+        {
+          "type": "text",
+          "attr": {
+            "value": "Hello Weex"
+          }
+        }
+      ]
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/expect/a.we b/test/expect/a.we
deleted file mode 100644
index 2565076..0000000
--- a/test/expect/a.we
+++ /dev/null
@@ -1,27 +0,0 @@
-<template>
-    <container>
-        <text class="h1">{{text}}</text>
-        <goto></goto>
-        <copyright></copyright>
-    </container>
-</template>
-
-<style>
-.h1 {
-    font-size: 60px;
-    color: red;
-    padding-top: 20px;
-    padding-bottom: 20px;
-    padding-left: 20px;
-    padding-right: 20px;
-}
-</style>
-
-<script>
-var c = require('../lib/c')
-module.exports = {
-    data: {
-        text: 'Hello ' + c.name
-    }
-}
-</script>
diff --git a/test/expect/b.js b/test/expect/b.js
new file mode 100644
index 0000000..c0b229f
--- /dev/null
+++ b/test/expect/b.js
@@ -0,0 +1,24 @@
+{
+  "@weex-component/efeeed2d981d974f413e0eb80df99deb": {
+    "template": {
+      "type": "div",
+      "children": [
+        {
+          "type": "text",
+          "classList": [
+            "hi"
+          ],
+          "attr": {
+            "value": "Hello Weex"
+          }
+        }
+      ]
+    },
+    "style": {
+      "hi": {
+        "fontSize": 26,
+        "color": "#FF0000"
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/expect/b.we b/test/expect/b.we
deleted file mode 100644
index 0c1855b..0000000
--- a/test/expect/b.we
+++ /dev/null
@@ -1,19 +0,0 @@
-<element name="y">
-  <template>
-    <div>
-      <item></item>
-      <text>y</text>
-    </div>
-  </template>
-</element>
-
-<template>
-  <div>
-    <text>Hello</text>
-    <y></y>
-  </div>
-</template>
-
-<script>
-  require('../lib/3rd.js')
-</script>
diff --git a/test/expect/c.js b/test/expect/c.js
new file mode 100644
index 0000000..05aeac1
--- /dev/null
+++ b/test/expect/c.js
@@ -0,0 +1,25 @@
+{
+  "@weex-component/192c464938a57dbd89308b3f2aaa0b18": {
+    "data": "function data() {\n\t    return {\n\t        name: 'Weex'\n\t    };\n\t}",
+    "template": {
+      "type": "div",
+      "children": [
+        {
+          "type": "text",
+          "classList": [
+            "hello"
+          ],
+          "attr": {
+            "value": "function () {return 'Hello ' + (this.name)}"
+          }
+        }
+      ]
+    },
+    "style": {
+      "hello": {
+        "fontSize": 26,
+        "color": "#FF0000"
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/expect/company.we b/test/expect/company.we
deleted file mode 100644
index 743920c..0000000
--- a/test/expect/company.we
+++ /dev/null
@@ -1,14 +0,0 @@
-<template>
-    <container>
-        <text style="text-align: center; font-size: 18; color: #CCCCCC;">{{name}}</text>
-    </container>
-</template>
-
-<script>
-var d = require('../lib/d');
-module.exports = {
-    data: {
-        name: d.name
-    }
-}
-</script>
\ No newline at end of file
diff --git a/test/expect/copyright.we b/test/expect/copyright.we
deleted file mode 100644
index 2525348..0000000
--- a/test/expect/copyright.we
+++ /dev/null
@@ -1,27 +0,0 @@
-<template>
-    <container>
-        <text class="{{className}}">Copy right @ 2016 Weex</text>
-        <company></company>
-    </container>
-</template>
-
-<style>
-    .copyright {
-        text-align: center;
-        padding-top: 20;
-        padding-bottom: 20;
-        color: #666;
-        font-size: 26;
-    }
-</style>
-
-<script>
-    module.exports = {
-        data: {
-            className: ''
-        },
-        created: function (argument) {
-            this.className = 'copyright';
-        }
-    }
-</script>
\ No newline at end of file
diff --git a/test/expect/d.js b/test/expect/d.js
new file mode 100644
index 0000000..beb89fe
--- /dev/null
+++ b/test/expect/d.js
@@ -0,0 +1,57 @@
+{
+  "@weex-component/name": {
+    "data": "function data() {\n\t        return {\n\t            name: ''\n\t        };\n\t    }",
+    "template": {
+      "type": "div",
+      "children": [
+        {
+          "type": "text",
+          "classList": [
+            "name"
+          ],
+          "attr": {
+            "value": "function () {return this.name}"
+          }
+        }
+      ]
+    },
+    "style": {
+      "name": {
+        "fontSize": 26,
+        "color": "#FF0000"
+      }
+    }
+  },
+  "@weex-component/efd01076a5d363118b9fa68bbab98216": {
+    "data": "function data() {\n\t    return {\n\t        name: 'Weex'\n\t    };\n\t}",
+    "template": {
+      "type": "div",
+      "style": {
+        "flexDirection": "row"
+      },
+      "children": [
+        {
+          "type": "text",
+          "classList": [
+            "hello"
+          ],
+          "attr": {
+            "value": "Hello"
+          }
+        },
+        {
+          "type": "name",
+          "attr": {
+            "name": "function () {return this.name}"
+          }
+        }
+      ]
+    },
+    "style": {
+      "hello": {
+        "fontSize": 26,
+        "color": "#008000"
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/expect/e.js b/test/expect/e.js
new file mode 100644
index 0000000..12a0ae9
--- /dev/null
+++ b/test/expect/e.js
@@ -0,0 +1,71 @@
+{
+  "@weex-component/hi": {
+    "data": "function data() {\n\t        return {\n\t            hi: ''\n\t        };\n\t    }",
+    "template": {
+      "type": "div",
+      "children": [
+        {
+          "type": "text",
+          "classList": [
+            "hi"
+          ],
+          "attr": {
+            "value": "function () {return this.hi}"
+          }
+        }
+      ]
+    },
+    "style": {
+      "hi": {
+        "fontSize": 26,
+        "color": "#008000"
+      }
+    }
+  },
+  "@weex-component/name": {
+    "data": "function data() {\n\t        return {\n\t            name: ''\n\t        };\n\t    }",
+    "template": {
+      "type": "div",
+      "children": [
+        {
+          "type": "text",
+          "classList": [
+            "name"
+          ],
+          "attr": {
+            "value": "function () {return this.name}"
+          }
+        }
+      ]
+    },
+    "style": {
+      "name": {
+        "fontSize": 26,
+        "color": "#FF0000"
+      }
+    }
+  },
+  "@weex-component/3f7bb5c2b95329dedd5cb4556f4df361": {
+    "data": "function data() {\n\t    return {\n\t        hi: 'Hello',\n\t        name: 'Weex'\n\t    };\n\t}",
+    "template": {
+      "type": "div",
+      "style": {
+        "flexDirection": "row"
+      },
+      "children": [
+        {
+          "type": "hi",
+          "attr": {
+            "hi": "function () {return this.hi}"
+          }
+        },
+        {
+          "type": "name",
+          "attr": {
+            "name": "function () {return this.name}"
+          }
+        }
+      ]
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/expect/exports.we b/test/expect/exports.we
deleted file mode 100644
index 731b20a..0000000
--- a/test/expect/exports.we
+++ /dev/null
@@ -1,11 +0,0 @@
-<template>
-  <div>
-    <text>{{foo}}</text>
-  </div>
-</template>
-
-<script>
-  exports.data = {
-    foo: 'Hello'
-  }
-</script>
diff --git a/test/expect/f.js b/test/expect/f.js
new file mode 100644
index 0000000..b662d15
--- /dev/null
+++ b/test/expect/f.js
@@ -0,0 +1,76 @@
+{
+  "@weex-component/hi": {
+    "data": "function data() {\n\t        return {\n\t            hi: ''\n\t        };\n\t    }",
+    "template": {
+      "type": "div",
+      "children": [
+        {
+          "type": "text",
+          "classList": [
+            "hi"
+          ],
+          "attr": {
+            "value": "function () {return this.hi}"
+          }
+        }
+      ]
+    },
+    "style": {
+      "hi": {
+        "fontSize": 26,
+        "color": "#008000"
+      }
+    }
+  },
+  "@weex-component/name": {
+    "data": "function data() {\n\t        console.log('Name Component Comment');\n\t        return {\n\t            name: ''\n\t        };\n\t    }",
+    "template": {
+      "type": "div",
+      "children": [
+        {
+          "type": "text",
+          "classList": [
+            "name"
+          ],
+          "attr": {
+            "value": "function () {return this.name}"
+          }
+        }
+      ]
+    },
+    "style": {
+      "name": {
+        "fontSize": 26,
+        "color": "#FF0000"
+      }
+    }
+  },
+  "@weex-component/ce75098d1d76e52a00b0d2b2613d990c": {
+    "data": "function data() {\n\t    return {\n\t        hi: 'Hello',\n\t        name: 'Weex'\n\t    };\n\t}",
+    "template": {
+      "type": "div",
+      "classList": [
+        "wrap"
+      ],
+      "children": [
+        {
+          "type": "hi",
+          "attr": {
+            "hi": "function () {return this.hi}"
+          }
+        },
+        {
+          "type": "name",
+          "attr": {
+            "name": "function () {return this.name}"
+          }
+        }
+      ]
+    },
+    "style": {
+      "wrap": {
+        "flexDirection": "row"
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/expect/g.js b/test/expect/g.js
new file mode 100644
index 0000000..5446409
--- /dev/null
+++ b/test/expect/g.js
@@ -0,0 +1,76 @@
+{
+  "@weex-component/name1": {
+    "data": "function data() {\n\t        console.log('Name Component Comment');\n\t        return {\n\t            name: ''\n\t        };\n\t    }",
+    "template": {
+      "type": "div",
+      "children": [
+        {
+          "type": "text",
+          "classList": [
+            "name"
+          ],
+          "attr": {
+            "value": "function () {return this.name}"
+          }
+        }
+      ]
+    },
+    "style": {
+      "name": {
+        "fontSize": 26,
+        "color": "#FF0000"
+      }
+    }
+  },
+  "@weex-component/hi1": {
+    "data": "function data() {\n\t        return {\n\t            hi: ''\n\t        };\n\t    }",
+    "template": {
+      "type": "div",
+      "children": [
+        {
+          "type": "text",
+          "classList": [
+            "hi"
+          ],
+          "attr": {
+            "value": "function () {return this.hi}"
+          }
+        }
+      ]
+    },
+    "style": {
+      "hi": {
+        "fontSize": 26,
+        "color": "#008000"
+      }
+    }
+  },
+  "@weex-component/ce13b953688b3be076ebafcfb5807052": {
+    "data": "function data() {\n\t        return {\n\t            hi: 'Hello',\n\t            name: 'Weex'\n\t        };\n\t    }",
+    "template": {
+      "type": "div",
+      "classList": [
+        "wrap"
+      ],
+      "children": [
+        {
+          "type": "hi1",
+          "attr": {
+            "hi": "function () {return this.hi}"
+          }
+        },
+        {
+          "type": "name1",
+          "attr": {
+            "name": "function () {return this.name}"
+          }
+        }
+      ]
+    },
+    "style": {
+      "wrap": {
+        "flexDirection": "row"
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/expect/goto.we b/test/expect/goto.we
deleted file mode 100644
index b4c2b52..0000000
--- a/test/expect/goto.we
+++ /dev/null
@@ -1,22 +0,0 @@
-<template>
-    <container>
-        <text onclick="clicked" style="text-decoration: underline; padding-left: {{paddingLeft}}">{{text}}</text>
-    </container>
-</template>
-
-<script>
-    module.exports = {
-        data: {
-            text: '',
-            paddingLeft: 20
-        },
-        created: function() {
-            this.text = 'Yes It is! Go Weex >>>';
-        },
-        methods: {
-            clicked: function() {
-                this.$openURL('http://github.com/alibaba/weex');
-            }
-        }
-    }
-</script>
\ No newline at end of file
diff --git a/test/expect/h.js b/test/expect/h.js
new file mode 100644
index 0000000..bb0753b
--- /dev/null
+++ b/test/expect/h.js
@@ -0,0 +1,76 @@
+{
+  "@weex-component/hi": {
+    "data": "function data() {\n\t        return {\n\t            hi: ''\n\t        };\n\t    }",
+    "template": {
+      "type": "div",
+      "children": [
+        {
+          "type": "text",
+          "classList": [
+            "hi"
+          ],
+          "attr": {
+            "value": "function () {return this.hi}"
+          }
+        }
+      ]
+    },
+    "style": {
+      "hi": {
+        "fontSize": 26,
+        "color": "#008000"
+      }
+    }
+  },
+  "@weex-component/name": {
+    "data": "function data() {\n\t        console.log('Name Component Comment');\n\t        return {\n\t            name: ''\n\t        };\n\t    }",
+    "template": {
+      "type": "div",
+      "children": [
+        {
+          "type": "text",
+          "classList": [
+            "name"
+          ],
+          "attr": {
+            "value": "function () {return this.name}"
+          }
+        }
+      ]
+    },
+    "style": {
+      "name": {
+        "fontSize": 26,
+        "color": "#FF0000"
+      }
+    }
+  },
+  "@weex-component/a3294f0702f2a9d0b48c66c00c4429af": {
+    "data": "function data() {\n\t        return {\n\t            hi: 'Hello',\n\t            name: 'Weex'\n\t        };\n\t    }",
+    "template": {
+      "type": "div",
+      "classList": [
+        "wrap"
+      ],
+      "children": [
+        {
+          "type": "hi",
+          "attr": {
+            "hi": "function () {return this.hi}"
+          }
+        },
+        {
+          "type": "name",
+          "attr": {
+            "name": "function () {return this.name}"
+          }
+        }
+      ]
+    },
+    "style": {
+      "wrap": {
+        "flexDirection": "row"
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/expect/i.js b/test/expect/i.js
new file mode 100644
index 0000000..33c90d2
--- /dev/null
+++ b/test/expect/i.js
@@ -0,0 +1,24 @@
+{
+  "@weex-component/a0ca0f35aa865d928da5cb31115674de": {
+    "template": {
+      "type": "div",
+      "children": [
+        {
+          "type": "text",
+          "classList": [
+            "hello"
+          ],
+          "attr": {
+            "value": "function () {return 'Hello ' + (this.name)}"
+          }
+        }
+      ]
+    },
+    "style": {
+      "hello": {
+        "fontSize": 26,
+        "color": "#FF0000"
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/expect/item.we b/test/expect/item.we
deleted file mode 100644
index 6edada6..0000000
--- a/test/expect/item.we
+++ /dev/null
@@ -1,5 +0,0 @@
-<template>
-  <div>
-    <text>ITEM</text>
-  </div>
-</template>
diff --git a/test/expect/j.js b/test/expect/j.js
new file mode 100644
index 0000000..1a1152a
--- /dev/null
+++ b/test/expect/j.js
@@ -0,0 +1,31 @@
+{
+  "@weex-component/75ade3685ace094b4dd3622093f2ac3e": {
+    "ready": "function ready() {\n\t        _modal2.default.toast({ 'message': 'ready' });\n\t    }",
+    "data": "function data() {\n\t        return {\n\t            hi: 'Hello',\n\t            name: 'Weex'\n\t        };\n\t    }",
+    "template": {
+      "type": "div",
+      "classList": [
+        "wrap"
+      ],
+      "children": [
+        {
+          "type": "text",
+          "attr": {
+            "value": "function () {return this.hi}"
+          }
+        },
+        {
+          "type": "text",
+          "attr": {
+            "value": "function () {return this.name}"
+          }
+        }
+      ]
+    },
+    "style": {
+      "wrap": {
+        "flexDirection": "row"
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/expect/k.js b/test/expect/k.js
new file mode 100644
index 0000000..7401d48
--- /dev/null
+++ b/test/expect/k.js
@@ -0,0 +1,45 @@
+{
+  "@weex-component/6461408a6e72015716c3e75aedb3f4f8": {
+    "ready": "function () {\n\t    return modal.toast({\n\t      'message': 'ready'\n\t    });\n\t  }",
+    "data": "function () {\n\t    return {\n\t      hi: 'Hello',\n\t      name: 'Weex'\n\t    };\n\t  }",
+    "template": {
+      "type": "div",
+      "classList": [
+        "wrap"
+      ],
+      "children": [
+        {
+          "type": "text",
+          "classList": [
+            "text-hi"
+          ],
+          "attr": {
+            "value": "function () {return this.hi}"
+          }
+        },
+        {
+          "type": "text",
+          "classList": [
+            "text-name"
+          ],
+          "attr": {
+            "value": "function () {return this.name}"
+          }
+        }
+      ]
+    },
+    "style": {
+      "wrap": {
+        "flexDirection": "row"
+      },
+      "text-hi": {
+        "color": "#FF0000",
+        "fontSize": 26
+      },
+      "text-name": {
+        "color": "#008000",
+        "fontSize": 26
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/expect/l.js b/test/expect/l.js
new file mode 100644
index 0000000..48739e0
--- /dev/null
+++ b/test/expect/l.js
@@ -0,0 +1,26 @@
+{
+  "@weex-component/b88790ebbe39cc44c23e81e6ef2a07e2": {
+    "ready": "function ready() {\n\t    _modal2.default.toast({ message: this.name });\n\t}",
+    "data": "function data() {\n\t    return {\n\t        name: (0, _getName2.default)()\n\t    };\n\t}",
+    "template": {
+      "type": "div",
+      "children": [
+        {
+          "type": "text",
+          "classList": [
+            "hello"
+          ],
+          "attr": {
+            "value": "function () {return 'Hello ' + (this.name)}"
+          }
+        }
+      ]
+    },
+    "style": {
+      "hello": {
+        "fontSize": 26,
+        "color": "#FF0000"
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/expect/m.js b/test/expect/m.js
new file mode 100644
index 0000000..8522912
--- /dev/null
+++ b/test/expect/m.js
@@ -0,0 +1,27 @@
+{
+  "@weex-component/toast": {},
+  "@weex-component/27bd9f030aa3c2c01f3168b3f623e61e": {
+    "ready": "function ready() {\n\t        (0, _toast2.default)(this.name);\n\t    }",
+    "data": "function data() {\n\t        return {\n\t            name: 'Weex'\n\t        };\n\t    }",
+    "template": {
+      "type": "div",
+      "children": [
+        {
+          "type": "text",
+          "classList": [
+            "hello"
+          ],
+          "attr": {
+            "value": "function () {return 'Hello ' + (this.name)}"
+          }
+        }
+      ]
+    },
+    "style": {
+      "hello": {
+        "fontSize": 26,
+        "color": "#FF0000"
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/expect/n.js b/test/expect/n.js
new file mode 100644
index 0000000..af965a5
--- /dev/null
+++ b/test/expect/n.js
@@ -0,0 +1,76 @@
+{
+  "@weex-component/hi": {
+    "data": "function data() {\n\t        console.log('Hi Component Comment');\n\t        return {\n\t            hi: ''\n\t        };\n\t    }",
+    "template": {
+      "type": "div",
+      "children": [
+        {
+          "type": "text",
+          "classList": [
+            "hi"
+          ],
+          "attr": {
+            "value": "function () {return this.hi}"
+          }
+        }
+      ]
+    },
+    "style": {
+      "hi": {
+        "fontSize": 26,
+        "color": "#008000"
+      }
+    }
+  },
+  "@weex-component/name": {
+    "data": "function data() {\n\t        console.log('Name Component Comment');\n\t        return {\n\t            name: ''\n\t        };\n\t    }",
+    "template": {
+      "type": "div",
+      "children": [
+        {
+          "type": "text",
+          "classList": [
+            "name"
+          ],
+          "attr": {
+            "value": "function () {return this.name}"
+          }
+        }
+      ]
+    },
+    "style": {
+      "name": {
+        "fontSize": 26,
+        "color": "#FF0000"
+      }
+    }
+  },
+  "@weex-component/57a447a57bba51ef8a7697040ca71e75": {
+    "data": "function data() {\n\t    console.log('N comment');\n\t    return {\n\t        hi: 'Hello',\n\t        name: 'Weex'\n\t    };\n\t}",
+    "template": {
+      "type": "div",
+      "classList": [
+        "wrap"
+      ],
+      "children": [
+        {
+          "type": "hi",
+          "attr": {
+            "hi": "function () {return this.hi}"
+          }
+        },
+        {
+          "type": "name",
+          "attr": {
+            "name": "function () {return this.name}"
+          }
+        }
+      ]
+    },
+    "style": {
+      "wrap": {
+        "flexDirection": "row"
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/expect/samename.we b/test/expect/samename.we
deleted file mode 100644
index 9020bf9..0000000
--- a/test/expect/samename.we
+++ /dev/null
@@ -1,3 +0,0 @@
-<template>
-  <samename></samename>
-</template>
diff --git a/test/expect/sourcemap.we b/test/expect/sourcemap.we
deleted file mode 100644
index f798f7f..0000000
--- a/test/expect/sourcemap.we
+++ /dev/null
@@ -1,26 +0,0 @@
-<element name="foo">
-  <template>
-    <text>Hello</text>
-  </template>
-  <script>
-    console.log(6)
-    console.log(7)
-    console.log(8)
-    console.log(9)
-    console.log(0)
-  </script>
-</element>
-
-<template>
-  <div>
-    <foo></foo>
-  </div>
-</template>
-
-<script>
-  console.log(1)
-  console.log(2)
-  require('../lib/3rd.js')
-  console.log(4)
-  console.log(5)
-</script>
diff --git a/test/expect/z.we b/test/expect/z.we
deleted file mode 100644
index b5b35d9..0000000
--- a/test/expect/z.we
+++ /dev/null
@@ -1,23 +0,0 @@
-<template>
-    <div></div>
-</template>
-
-<script type="data">
-{
-    a: 1,
-    b: 2
-}
-</script>
-
-<script type="config">
-{
-    downgrade:{
-        ios: {
-            appVersion: '>=13.0.0'
-        },
-        android: {
-            appVersion: '<=0.0.0'
-        }
-    }
-}
-</script>
\ No newline at end of file
diff --git a/test/highlight.css b/test/highlight.css
deleted file mode 100644
index 4662927..0000000
--- a/test/highlight.css
+++ /dev/null
@@ -1,4 +0,0 @@
-.highlight {
-    color: #666;
-    font-size: 26;
-}
\ No newline at end of file
diff --git a/test/index.html b/test/index.html
deleted file mode 100644
index 3faf460..0000000
--- a/test/index.html
+++ /dev/null
@@ -1,67 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="utf-8">
-<title>Weex Loader Demo</title>
-<meta name="apple-mobile-web-app-capable" content="yes" />
-<meta name="apple-mobile-web-app-status-bar-style" content="black" />
-<meta name="apple-touch-fullscreen" content="yes" />
-<meta name="format-detection" content="telephone=no, email=no" />
-<!--flexible-->
-<script>
-!function(a,b){function c(){var b=f.getBoundingClientRect().width;b/i>540&&(b=540*i);var c=b/10;f.style.fontSize=c+"px",k.rem=a.rem=c}var d,e=a.document,f=e.documentElement,g=e.querySelector('meta[name="viewport"]'),h=e.querySelector('meta[name="flexible"]'),i=0,j=0,k=b.flexible||(b.flexible={});if(g){console.warn("The page size will be adapted by the <meta> info.");var l=g.getAttribute("content").match(/initial\-scale=([\d\.]+)/);l&&(j=parseFloat(l[1]),i=parseInt(1/j))}else if(h){var m=h.getAttribute("content");if(m){var n=m.match(/initial\-dpr=([\d\.]+)/),o=m.match(/maximum\-dpr=([\d\.]+)/);n&&(i=parseFloat(n[1]),j=parseFloat((1/i).toFixed(2))),o&&(i=parseFloat(o[1]),j=parseFloat((1/i).toFixed(2)))}}if(!i&&!j){var p=(a.navigator.appVersion.match(/android/gi),a.navigator.appVersion.match(/iphone/gi)),q=a.devicePixelRatio;i=p?q>=3&&(!i||i>=3)?3:q>=2&&(!i||i>=2)?2:1:1,j=1/i}if(f.setAttribute("data-dpr",i),!g)if(g=e.createElement("meta"),g.setAttribute("name","viewport"),g.setAttribute("content","initial-scale="+j+", maximum-scale="+j+", minimum-scale="+j+", user-scalable=no"),f.firstElementChild)f.firstElementChild.appendChild(g);else{var r=e.createElement("div");r.appendChild(g),e.write(r.innerHTML)}a.addEventListener("resize",function(){clearTimeout(d),d=setTimeout(c,300)},!1),a.addEventListener("pageshow",function(a){a.persisted&&(clearTimeout(d),d=setTimeout(c,300))},!1),"complete"===e.readyState?e.body.style.fontSize=12*i+"px":e.addEventListener("DOMContentLoaded",function(){e.body.style.fontSize=12*i+"px"},!1),c(),k.dpr=a.dpr=i,k.refreshRem=c,k.rem2px=function(a){var b=parseFloat(a)*this.rem;return"string"==typeof a&&a.match(/rem$/)&&(b+="px"),b},k.px2rem=function(a){var b=parseFloat(a)/this.rem;return"string"==typeof a&&a.match(/px$/)&&(b+="rem"),b}}(window,window.lib||(window.lib={}));
-</script>
-<style>
-  body > h1 {
-    background-color: #666;
-    color: #EFEFEF;
-    padding: 10px;
-  }
-</style>
-</head>
-<body>
-<h1>[Test Case Actual]</h1>
-<div id="test_actual"></div>
-<br /><br /><br /><br /><br /><br />
-<h1>[Test Case Expect]</h1>
-<div id="test_expect"></div>
-<!-- jsframework -->
-<script src="./lib/jsfm.js"></script>
-<!-- h5render -->
-<script src="./lib/h5render.js"></script>
-<!-- entry -->
-<script>
-/**
- * init weex instance depending on the url params.
- * There are three ways to load weex bundles, depends on the
- * parameter 'loader' in the url:
- *
- *   + xhr:   use XMLHttpRequest. Parameter 'page' should be
- *   the bundle's url.
- *   + jsonp: use jsonp. Parameter 'page' should be the request
- *   url and jsonpCallback should be specified during calling
- *   weex.init.
- *   + source: use the transformed code itself. 'page' should
- *   be the transformed weex bundle.
- *
- * @param {String}  bundle  It has different meaning depends on
- *   the type of loader.
- */
-(function () {
-  window.weex.init({
-    appId: 'actual/a.js',
-    loader: 'xhr',
-    source: './actual/a.js',
-    rootId: 'test_actual'
-  });
-
-  window.weex.init({
-    appId: 'expect/a.js',
-    loader: 'xhr',
-    source: './expect/a.js',
-    rootId: 'test_expect'
-  });
-})();
-</script>
-</body>
-</html>
\ No newline at end of file
diff --git a/test/lib/3rd.js b/test/lib/3rd.js
deleted file mode 100644
index cc00e41..0000000
--- a/test/lib/3rd.js
+++ /dev/null
@@ -1,4 +0,0 @@
-'Hello 3rd-party JavaScript'
-'Hello 3rd-party JavaScript 2'
-'Hello 3rd-party JavaScript 3'
-'Hello 3rd-party JavaScript 4'
diff --git a/test/lib/c.js b/test/lib/c.js
deleted file mode 100644
index 1bdb562..0000000
--- a/test/lib/c.js
+++ /dev/null
@@ -1 +0,0 @@
-exports.name = 'Weex-Loader';
\ No newline at end of file
diff --git a/test/lib/d.js b/test/lib/d.js
deleted file mode 100644
index a0a2f94..0000000
--- a/test/lib/d.js
+++ /dev/null
@@ -1 +0,0 @@
-exports.name = 'Alibaba Group';
\ No newline at end of file
diff --git a/test/lib/h5render.js b/test/lib/h5render.js
deleted file mode 100644
index 90cac01..0000000
--- a/test/lib/h5render.js
+++ /dev/null
@@ -1,6965 +0,0 @@
-(this.nativeLog || function(s) {console.log(s)})('START WEEX HTML5: 0.2.6');
-/******/ (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] = {
-/******/      exports: {},
-/******/      id: moduleId,
-/******/      loaded: false
-/******/    };
-/******/
-/******/    // Execute the module function
-/******/    modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
-/******/
-/******/    // Flag the module as loaded
-/******/    module.loaded = 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;
-/******/
-/******/  // __webpack_public_path__
-/******/  __webpack_require__.p = "";
-/******/
-/******/  // Load entry module and return exports
-/******/  return __webpack_require__(0);
-/******/ })
-/************************************************************************/
-/******/ ([
-/* 0 */
-/***/ function(module, exports, __webpack_require__) {
-
-  /* WEBPACK VAR INJECTION */(function(global) {'use strict'
-  
-  __webpack_require__(1)
-  
-  var config = __webpack_require__(5)
-  var Loader = __webpack_require__(6)
-  var utils = __webpack_require__(7)
-  var protocol = __webpack_require__(8)
-  var ComponentManager = __webpack_require__(9)
-  var Component = __webpack_require__(16)
-  var Sender = __webpack_require__(19)
-  var receiver = __webpack_require__(20)
-  
-  // Components and apis.
-  var components = __webpack_require__(21)
-  var api = __webpack_require__(66)
-  __webpack_require__(96)
-  
-  var WEAPP_STYLE_ID = 'weapp-style'
-  
-  var DEFAULT_DESIGN_WIDTH = 750
-  var DEFAULT_ROOT_ID = 'weex'
-  var DEFAULT_JSON_CALLBACK_NAME = 'weexJsonpCallback'
-  
-  // config.scale = window.innerWidth / DEFAULT_DESIGN_WIDTH
-  
-  window.WXEnvironment = {
-    weexVersion: config.weexVersion,
-    appName: lib.env.aliapp ? lib.env.aliapp.appname : null,
-    appVersion: lib.env.aliapp ? lib.env.aliapp.version.val : null,
-    platform: lib.env.os ? lib.env.os.name : null,
-    osVersion: lib.env.os ? lib.env.os.version.val : null,
-    deviceHeight: window.innerHeight / config.scale
-  }
-  
-  var _instanceMap = {}
-  
-  function Weex(options) {
-  
-    if (!(this instanceof Weex)) {
-      return new Weex(options)
-    }
-  
-    // Width of the root container. Default is window.innerWidth.
-    this.width = options.width || window.innerWidth
-    this.bundleUrl = options.bundleUrl || location.href
-    this.instanceId = options.appId
-    this.rootId = options.rootId || (DEFAULT_ROOT_ID + utils.getRandom(10))
-    this.designWidth = options.designWidth || DEFAULT_DESIGN_WIDTH
-    this.jsonpCallback = options.jsonpCallback || DEFAULT_JSON_CALLBACK_NAME
-    this.source = options.source
-    this.loader = options.loader
-  
-    this.data = options.data
-  
-    this.initScale()
-    this.initComponentManager()
-    this.initBridge()
-    Weex.addInstance(this)
-  
-    protocol.injectWeexInstance(this)
-  
-    this.loadBundle(function (err, appCode) {
-      if (!err) {
-        this.createApp(config, appCode)
-      } else {
-        console.error('load bundle err:', err)
-      }
-    }.bind(this))
-  
-  }
-  
-  Weex.init = function (options) {
-    if (utils.isArray(options)) {
-      options.forEach(function (config) {
-        new Weex(config)
-      })
-    } else if (
-        Object.prototype.toString.call(options).slice(8, -1) === 'Object'
-      ) {
-      new Weex(options)
-    }
-  }
-  
-  Weex.addInstance = function (instance) {
-    _instanceMap[instance.instanceId] = instance
-  }
-  
-  Weex.getInstance = function (instanceId) {
-    return _instanceMap[instanceId]
-  }
-  
-  Weex.prototype = {
-  
-    initBridge: function () {
-      receiver.init(this)
-      this.sender = new Sender(this)
-    },
-  
-    loadBundle: function (cb) {
-      Loader.load({
-        jsonpCallback: this.jsonpCallback,
-        source: this.source,
-        loader: this.loader
-      }, cb)
-    },
-  
-    createApp: function (config, appCode) {
-      var root = document.querySelector('#' + this.rootId)
-      if (!root) {
-        root = document.createElement('div')
-        root.id = this.rootId
-        document.body.appendChild(root)
-      }
-  
-      var promise = window.createInstance(
-        this.instanceId
-        , appCode
-        , {
-          bundleUrl: this.bundleUrl,
-          debug: config.debug
-        }
-        , this.data
-      )
-  
-      if (Promise && promise instanceof Promise) {
-        promise.then(function () {
-          // Weex._instances[this.instanceId] = this.root
-        }.bind(this)).catch(function (err) {
-          if (err && config.debug) {
-            console.error(err)
-          }
-        })
-      }
-  
-      // Do not destroy instance here, because in most browser
-      // press back button to back to this page will not refresh
-      // the window and the instance will not be recreated then.
-      // window.addEventListener('beforeunload', function (e) {
-      // })
-  
-    },
-  
-    initScale: function () {
-      this.scale = this.width / this.designWidth
-    },
-  
-    initComponentManager: function () {
-      this._componentManager = new ComponentManager(this)
-    },
-  
-    getComponentManager: function () {
-      return this._componentManager
-    }
-  }
-  
-  Weex.appendStyle = function (css) {
-    utils.appendStyle(css, WEAPP_STYLE_ID)
-  },
-  
-  // Register a new component with the specified name.
-  Weex.registerComponent = function (name, comp) {
-    ComponentManager.registerComponent(name, comp)
-  },
-  
-  // Register a new api module.
-  // If the module already exists, just add methods from the
-  // new module to the old one.
-  Weex.registerApiModule = function (name, module, meta) {
-    if (!protocol.apiModule[name]) {
-      protocol.apiModule[name] = module
-    } else {
-      for (var key in module) {
-        if (module.hasOwnProperty(key)) {
-          protocol.apiModule[name][key] = module[key]
-        }
-      }
-    }
-    // register API module's meta info to jsframework
-    if (meta) {
-      protocol.setApiModuleMeta(meta)
-      window.registerModules(protocol.getApiModuleMeta(name), true)
-    }
-  },
-  
-  // Register a new api method for the specified module.
-  // opts:
-  //  - args: type of arguments the API method takes such
-  //    as ['string', 'function']
-  Weex.registerApi = function (moduleName, name, method, args) {
-    if (typeof method !== 'function') {
-      return
-    }
-    if (!protocol.apiModule[moduleName]) {
-      protocol.apiModule[moduleName] = {}
-      protocol._meta[moduleName] = []
-    }
-    protocol.apiModule[moduleName][name] = method
-    if (!args) {
-      return
-    }
-    // register API meta info to jsframework
-    protocol.setApiMeta(moduleName, {
-      name: name,
-      args: args
-    })
-    window.registerModules(protocol.getApiModuleMeta(moduleName, meta), true)
-  },
-  
-  // Register a new weex-bundle-loader.
-  Weex.registerLoader = function (name, loaderFunc) {
-    Loader.registerLoader(name, loaderFunc)
-  }
-  
-  // To install components and plugins.
-  Weex.install = function (mod) {
-    mod.init(Weex)
-  }
-  
-  Weex.stopTheWorld = function () {
-    for (var instanceId in _instanceMap) {
-      if (_instanceMap.hasOwnProperty(instanceId)) {
-        window.destroyInstance(instanceId)
-      }
-    }
-  }
-  
-  (function startRefreshController() {
-    if (location.search.indexOf('hot-reload_controller') === -1)  {
-      return
-    }
-    if (!window.WebSocket) {
-      console.info('auto refresh need WebSocket support')
-      return
-    }
-    var host = location.hostname
-    var port = 8082
-    var client = new WebSocket('ws://' + host + ':' + port + '/',
-      'echo-protocol'
-    )
-    client.onerror = function () {
-      console.log('refresh controller websocket connection error')
-    }
-    client.onmessage = function (e) {
-      console.log('Received: \'' + e.data + '\'')
-      if (e.data  === 'refresh') {
-        location.reload()
-      }
-    }
-  }())
-  
-  // Weex.install(require('weex-components'))
-  Weex.install(components)
-  Weex.install(api)
-  
-  Weex.Component = Component
-  Weex.ComponentManager = ComponentManager
-  Weex.utils = utils
-  Weex.config = config
-  
-  global.weex = Weex
-  module.exports = Weex
-  
-  /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
-
-/***/ },
-/* 1 */
-/***/ function(module, exports, __webpack_require__) {
-
-  // style-loader: Adds some css to the DOM by adding a <style> tag
-  
-  // load the styles
-  var content = __webpack_require__(2);
-  if(typeof content === 'string') content = [[module.id, content, '']];
-  // add the styles to the DOM
-  var update = __webpack_require__(4)(content, {});
-  if(content.locals) module.exports = content.locals;
-  // Hot Module Replacement
-  if(false) {
-    // When the styles change, update the <style> tags
-    if(!content.locals) {
-      module.hot.accept("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./base.scss", function() {
-        var newContent = require("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./base.scss");
-        if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
-        update(newContent);
-      });
-    }
-    // When the module is disposed, remove the <style> tags
-    module.hot.dispose(function() { update(); });
-  }
-
-/***/ },
-/* 2 */
-/***/ function(module, exports, __webpack_require__) {
-
-  exports = module.exports = __webpack_require__(3)();
-  // imports
-  
-  
-  // module
-  exports.push([module.id, "* {\n  margin: 0;\n  padding: 0;\n  text-size-adjust: none; }\n\nul, ol {\n  list-style: none; }\n", "", {"version":3,"sources":["/./src/src/styles/base.scss"],"names":[],"mappings":"AAAA;EACE,UAAS;EACT,WAAU;EACV,uBACD,EAAC;;AACF;EACE,iBACD,EAAC","file":"base.scss","sourcesContent":["* {\n  margin:0;\n  padding:0;\n  text-size-adjust:none\n}\nul,ol {\n  list-style:none\n}"],"sourceRoot":"webpack://"}]);
-  
-  // exports
-
-
-/***/ },
-/* 3 */
-/***/ function(module, exports) {
-
-  /*
-    MIT License http://www.opensource.org/licenses/mit-license.php
-    Author Tobias Koppers @sokra
-  */
-  // css base code, injected by the css-loader
-  module.exports = function() {
-    var list = [];
-  
-    // return the list of modules as css string
-    list.toString = function toString() {
-      var result = [];
-      for(var i = 0; i < this.length; i++) {
-        var item = this[i];
-        if(item[2]) {
-          result.push("@media " + item[2] + "{" + item[1] + "}");
-        } else {
-          result.push(item[1]);
-        }
-      }
-      return result.join("");
-    };
-  
-    // import a list of modules into the list
-    list.i = function(modules, mediaQuery) {
-      if(typeof modules === "string")
-        modules = [[null, modules, ""]];
-      var alreadyImportedModules = {};
-      for(var i = 0; i < this.length; i++) {
-        var id = this[i][0];
-        if(typeof id === "number")
-          alreadyImportedModules[id] = true;
-      }
-      for(i = 0; i < modules.length; i++) {
-        var item = modules[i];
-        // skip already imported module
-        // this implementation is not 100% perfect for weird media query combinations
-        //  when a module is imported multiple times with different media queries.
-        //  I hope this will never occur (Hey this way we have smaller bundles)
-        if(typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) {
-          if(mediaQuery && !item[2]) {
-            item[2] = mediaQuery;
-          } else if(mediaQuery) {
-            item[2] = "(" + item[2] + ") and (" + mediaQuery + ")";
-          }
-          list.push(item);
-        }
-      }
-    };
-    return list;
-  };
-
-
-/***/ },
-/* 4 */
-/***/ function(module, exports, __webpack_require__) {
-
-  /*
-    MIT License http://www.opensource.org/licenses/mit-license.php
-    Author Tobias Koppers @sokra
-  */
-  var stylesInDom = {},
-    memoize = function(fn) {
-      var memo;
-      return function () {
-        if (typeof memo === "undefined") memo = fn.apply(this, arguments);
-        return memo;
-      };
-    },
-    isOldIE = memoize(function() {
-      return /msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase());
-    }),
-    getHeadElement = memoize(function () {
-      return document.head || document.getElementsByTagName("head")[0];
-    }),
-    singletonElement = null,
-    singletonCounter = 0,
-    styleElementsInsertedAtTop = [];
-  
-  module.exports = function(list, options) {
-    if(false) {
-      if(typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment");
-    }
-  
-    options = options || {};
-    // Force single-tag solution on IE6-9, which has a hard limit on the # of <style>
-    // tags it will allow on a page
-    if (typeof options.singleton === "undefined") options.singleton = isOldIE();
-  
-    // By default, add <style> tags to the bottom of <head>.
-    if (typeof options.insertAt === "undefined") options.insertAt = "bottom";
-  
-    var styles = listToStyles(list);
-    addStylesToDom(styles, options);
-  
-    return function update(newList) {
-      var mayRemove = [];
-      for(var i = 0; i < styles.length; i++) {
-        var item = styles[i];
-        var domStyle = stylesInDom[item.id];
-        domStyle.refs--;
-        mayRemove.push(domStyle);
-      }
-      if(newList) {
-        var newStyles = listToStyles(newList);
-        addStylesToDom(newStyles, options);
-      }
-      for(var i = 0; i < mayRemove.length; i++) {
-        var domStyle = mayRemove[i];
-        if(domStyle.refs === 0) {
-          for(var j = 0; j < domStyle.parts.length; j++)
-            domStyle.parts[j]();
-          delete stylesInDom[domStyle.id];
-        }
-      }
-    };
-  }
-  
-  function addStylesToDom(styles, options) {
-    for(var i = 0; i < styles.length; i++) {
-      var item = styles[i];
-      var domStyle = stylesInDom[item.id];
-      if(domStyle) {
-        domStyle.refs++;
-        for(var j = 0; j < domStyle.parts.length; j++) {
-          domStyle.parts[j](item.parts[j]);
-        }
-        for(; j < item.parts.length; j++) {
-          domStyle.parts.push(addStyle(item.parts[j], options));
-        }
-      } else {
-        var parts = [];
-        for(var j = 0; j < item.parts.length; j++) {
-          parts.push(addStyle(item.parts[j], options));
-        }
-        stylesInDom[item.id] = {id: item.id, refs: 1, parts: parts};
-      }
-    }
-  }
-  
-  function listToStyles(list) {
-    var styles = [];
-    var newStyles = {};
-    for(var i = 0; i < list.length; i++) {
-      var item = list[i];
-      var id = item[0];
-      var css = item[1];
-      var media = item[2];
-      var sourceMap = item[3];
-      var part = {css: css, media: media, sourceMap: sourceMap};
-      if(!newStyles[id])
-        styles.push(newStyles[id] = {id: id, parts: [part]});
-      else
-        newStyles[id].parts.push(part);
-    }
-    return styles;
-  }
-  
-  function insertStyleElement(options, styleElement) {
-    var head = getHeadElement();
-    var lastStyleElementInsertedAtTop = styleElementsInsertedAtTop[styleElementsInsertedAtTop.length - 1];
-    if (options.insertAt === "top") {
-      if(!lastStyleElementInsertedAtTop) {
-        head.insertBefore(styleElement, head.firstChild);
-      } else if(lastStyleElementInsertedAtTop.nextSibling) {
-        head.insertBefore(styleElement, lastStyleElementInsertedAtTop.nextSibling);
-      } else {
-        head.appendChild(styleElement);
-      }
-      styleElementsInsertedAtTop.push(styleElement);
-    } else if (options.insertAt === "bottom") {
-      head.appendChild(styleElement);
-    } else {
-      throw new Error("Invalid value for parameter 'insertAt'. Must be 'top' or 'bottom'.");
-    }
-  }
-  
-  function removeStyleElement(styleElement) {
-    styleElement.parentNode.removeChild(styleElement);
-    var idx = styleElementsInsertedAtTop.indexOf(styleElement);
-    if(idx >= 0) {
-      styleElementsInsertedAtTop.splice(idx, 1);
-    }
-  }
-  
-  function createStyleElement(options) {
-    var styleElement = document.createElement("style");
-    styleElement.type = "text/css";
-    insertStyleElement(options, styleElement);
-    return styleElement;
-  }
-  
-  function createLinkElement(options) {
-    var linkElement = document.createElement("link");
-    linkElement.rel = "stylesheet";
-    insertStyleElement(options, linkElement);
-    return linkElement;
-  }
-  
-  function addStyle(obj, options) {
-    var styleElement, update, remove;
-  
-    if (options.singleton) {
-      var styleIndex = singletonCounter++;
-      styleElement = singletonElement || (singletonElement = createStyleElement(options));
-      update = applyToSingletonTag.bind(null, styleElement, styleIndex, false);
-      remove = applyToSingletonTag.bind(null, styleElement, styleIndex, true);
-    } else if(obj.sourceMap &&
-      typeof URL === "function" &&
-      typeof URL.createObjectURL === "function" &&
-      typeof URL.revokeObjectURL === "function" &&
-      typeof Blob === "function" &&
-      typeof btoa === "function") {
-      styleElement = createLinkElement(options);
-      update = updateLink.bind(null, styleElement);
-      remove = function() {
-        removeStyleElement(styleElement);
-        if(styleElement.href)
-          URL.revokeObjectURL(styleElement.href);
-      };
-    } else {
-      styleElement = createStyleElement(options);
-      update = applyToTag.bind(null, styleElement);
-      remove = function() {
-        removeStyleElement(styleElement);
-      };
-    }
-  
-    update(obj);
-  
-    return function updateStyle(newObj) {
-      if(newObj) {
-        if(newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap)
-          return;
-        update(obj = newObj);
-      } else {
-        remove();
-      }
-    };
-  }
-  
-  var replaceText = (function () {
-    var textStore = [];
-  
-    return function (index, replacement) {
-      textStore[index] = replacement;
-      return textStore.filter(Boolean).join('\n');
-    };
-  })();
-  
-  function applyToSingletonTag(styleElement, index, remove, obj) {
-    var css = remove ? "" : obj.css;
-  
-    if (styleElement.styleSheet) {
-      styleElement.styleSheet.cssText = replaceText(index, css);
-    } else {
-      var cssNode = document.createTextNode(css);
-      var childNodes = styleElement.childNodes;
-      if (childNodes[index]) styleElement.removeChild(childNodes[index]);
-      if (childNodes.length) {
-        styleElement.insertBefore(cssNode, childNodes[index]);
-      } else {
-        styleElement.appendChild(cssNode);
-      }
-    }
-  }
-  
-  function applyToTag(styleElement, obj) {
-    var css = obj.css;
-    var media = obj.media;
-  
-    if(media) {
-      styleElement.setAttribute("media", media)
-    }
-  
-    if(styleElement.styleSheet) {
-      styleElement.styleSheet.cssText = css;
-    } else {
-      while(styleElement.firstChild) {
-        styleElement.removeChild(styleElement.firstChild);
-      }
-      styleElement.appendChild(document.createTextNode(css));
-    }
-  }
-  
-  function updateLink(linkElement, obj) {
-    var css = obj.css;
-    var sourceMap = obj.sourceMap;
-  
-    if(sourceMap) {
-      // http://stackoverflow.com/a/26603875
-      css += "\n/*# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + " */";
-    }
-  
-    var blob = new Blob([css], { type: "text/css" });
-  
-    var oldSrc = linkElement.href;
-  
-    linkElement.href = URL.createObjectURL(blob);
-  
-    if(oldSrc)
-      URL.revokeObjectURL(oldSrc);
-  }
-
-
-/***/ },
-/* 5 */
-/***/ function(module, exports) {
-
-  'use strict'
-  
-  var config = {
-  
-    weexVersion: '1.4.0',
-  
-    debug: true
-  
-  }
-  
-  module.exports = config
-
-/***/ },
-/* 6 */
-/***/ function(module, exports) {
-
-  'use strict'
-  
-  function loadByXHR(config, callback) {
-    if (!config.source) {
-      callback(new Error('xhr loader: missing config.source.'))
-    }
-    var xhr = new XMLHttpRequest()
-    xhr.open('GET', config.source)
-    xhr.onload = function () {
-      callback(null, this.responseText)
-    }
-    xhr.onerror = function (error) {
-      callback(error)
-    }
-    xhr.send()
-  }
-  
-  function loadByJsonp(config, callback) {
-    if (!config.source) {
-      callback(new Error('jsonp loader: missing config.source.'))
-    }
-    var callbackName = config.jsonpCallback || 'weexJsonpCallback'
-    window[callbackName] = function (code) {
-      if (code) {
-        callback(null, code)
-      } else {
-        callback(new Error('load by jsonp error'))
-      }
-    }
-    var script = document.createElement('script')
-    script.src = decodeURIComponent(config.source)
-    script.type = 'text/javascript'
-    document.body.appendChild(script)
-  }
-  
-  function loadBySourceCode(config, callback) {
-    // src is the jsbundle.
-    // no need to fetch from anywhere.
-    if (config.source) {
-      callback(null, config.source)
-    } else {
-      callback(new Error('source code laoder: missing config.source.'))
-    }
-  }
-  
-  var callbackMap = {
-    xhr: loadByXHR,
-    jsonp: loadByJsonp,
-    source: loadBySourceCode
-  }
-  
-  function load(options, callback) {
-    var loadFn = callbackMap[options.loader]
-    loadFn(options, callback)
-  }
-  
-  function registerLoader(name, loaderFunc) {
-    if (typeof loaderFunc === 'function') {
-      callbackMap[name] = loaderFunc
-    }
-  }
-  
-  module.exports = {
-    load: load,
-    registerLoader: registerLoader
-  }
-
-
-/***/ },
-/* 7 */
-/***/ function(module, exports) {
-
-  'use strict'
-  
-  var WEAPP_STYLE_ID = 'weapp-style'
-  
-  var _isWebpSupported = false
-  
-  ; (function isSupportWebp() {
-    try {
-      var webP = new Image()
-      webP.src = 'data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdA'
-                + 'SoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA'
-      webP.onload = function () {
-        if (webP.height === 2) {
-          _isWebpSupported = true
-        }
-      }
-    } catch (e) {
-      // do nothing.
-    }
-  })()
-  
-  function extend(to, from) {
-    for (var key in from) {
-      to[key] = from[key]
-    }
-    return to
-  }
-  
-  function isArray(arr) {
-    return Array.isArray
-      ? Array.isArray(arr)
-      : (Object.prototype.toString.call(arr) === '[object Array]')
-  }
-  
-  function appendStyle(css, styleId, replace) {
-    var style = document.getElementById(styleId)
-    if (style && replace) {
-      style.parentNode.removeChild(style)
-      style = null
-    }
-    if (!style) {
-      style = document.createElement('style')
-      style.type = 'text/css'
-      styleId && (style.id = styleId)
-      document.getElementsByTagName('head')[0].appendChild(style)
-    }
-    style.appendChild(document.createTextNode(css))
-  }
-  
-  function getUniqueFromArray(arr) {
-    if (!isArray(arr)) {
-      return []
-    }
-    var res = []
-    var unique = {}
-    var val
-    for (var i = 0, l = arr.length; i < l; i++) {
-      val = arr[i]
-      if (unique[val]) {
-        continue
-      }
-      unique[val] = true
-      res.push(val)
-    }
-    return res
-  }
-  
-  function transitionize(element, props) {
-    var transitions = []
-    for (var key in props) {
-      transitions.push(key + ' ' + props[key])
-    }
-    element.style.transition = transitions.join(', ')
-    element.style.webkitTransition = transitions.join(', ')
-  }
-  
-  function detectWebp() {
-    return _isWebpSupported
-  }
-  
-  function getRandom(num) {
-    var _defaultNum = 10
-    if (typeof num !== 'number' || num <= 0) {
-      num = _defaultNum
-    }
-    var _max = Math.pow(10, num)
-    return Math.floor(Date.now() + Math.random() * _max) % _max
-  }
-  
-  module.exports = {
-    extend: extend,
-    isArray: isArray,
-    appendStyle: appendStyle,
-    getUniqueFromArray: getUniqueFromArray,
-    transitionize: transitionize,
-    detectWebp: detectWebp,
-    getRandom: getRandom
-  }
-
-/***/ },
-/* 8 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  var extend = __webpack_require__(7).extend
-  var isArray = __webpack_require__(7).isArray
-  var ComponentManager = __webpack_require__(9)
-  
-  // for jsframework to register modules.
-  var _registerModules = function (config) {
-    if (isArray(config)) {
-      for (var i = 0, l = config.length; i < l; i++) {
-        window.registerModules(config[i])
-      }
-    } else {
-      window.registerModules(config)
-    }
-  }
-  
-  var protocol = {
-  
-    // weex instances
-    _instances: [],
-  
-    // api meta info
-    _meta: [],
-  
-    apiModule: {},
-  
-    injectWeexInstance: function (instance) {
-      this._instances[instance.instanceId] = instance
-    },
-  
-    getWeexInstance: function (instanceId) {
-      return this._instances[instanceId]
-    },
-  
-    // get the api method meta info array for the module.
-    getApiModuleMeta: function (moduleName) {
-      var metaObj = {}
-      metaObj[moduleName] = this._meta[moduleName]
-      return metaObj
-    },
-  
-    // Set meta info for a api module.
-    // If there is a same named api, just replace it.
-    // opts:
-    // - metaObj: meta object like
-    // {
-    //    dom: [{
-    //      name: 'addElement',
-    //      args: ['string', 'object']
-    //    }]
-    // }
-    setApiModuleMeta: function (metaObj) {
-      var moduleName
-      for (var k in metaObj) {
-        if (metaObj.hasOwnProperty(k)) {
-          moduleName = k
-        }
-      }
-      var metaArray = this._meta[moduleName]
-      if (!metaArray) {
-        this._meta[moduleName] = metaObj[moduleName]
-      } else {
-        var nameObj = {}
-        metaObj[moduleName].forEach(function (api) {
-          nameObj[api.name] = api
-        })
-        metaArray.forEach(function (api, i) {
-          if (nameObj[api.name]) {
-            metaArray[i] = nameObj[api.name]
-            delete nameObj[api.name]
-          }
-        })
-        for (var k in metaObj) {
-          if (metaObj.hasOwnProperty(k)) {
-            metaArray.push(metaObj[k])
-          }
-        }
-      }
-      this._meta[moduleName] = metaObj[moduleName]
-    },
-  
-    // Set meta info for a single api.
-    // opts:
-    //  - moduleName: api module name.
-    //  - meta: a meta object like:
-    //  {
-    //    name: 'addElement',
-    //    args: ['string', 'object']
-    //  }
-    setApiMeta: function (moduleName, meta) {
-      var metaArray = this._meta[moduleName]
-      if (!metaArray) {
-        this._meta[moduleName] = [meta]
-      } else {
-        var metaIdx = -1
-        metaArray.forEach(function (api, i) {
-          if (meta.name === name) {
-            metaIdx = i
-          }
-        })
-        if (metaIdx !== -1) {
-          metaArray[metaIdx] = meta
-        } else {
-          metaArray.push(meta)
-        }
-      }
-    }
-  }
-  
-  _registerModules([{
-    modal: [{
-      name: 'toast',
-      args: ['object', 'function']
-    }, {
-      name: 'alert',
-      args: ['object', 'function']
-    }, {
-      name: 'confirm',
-      args: ['object', 'function']
-    }, {
-      name: 'prompt',
-      args: ['object', 'function']
-    }]
-  }, {
-    animation: [{
-      name: 'transition',
-      args: ['string', 'object', 'function']
-    }]
-  }])
-  
-  module.exports = protocol
-
-
-/***/ },
-/* 9 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  var config = __webpack_require__(5)
-  var FrameUpdater = __webpack_require__(10)
-  var AppearWatcher = __webpack_require__(11)
-  var utils = __webpack_require__(7)
-  var LazyLoad = __webpack_require__(12)
-  var animation = __webpack_require__(15)
-  
-  var RENDERING_INDENT = 800
-  
-  var _instanceMap = {}
-  var typeMap = {}
-  var scrollableTypes = ['scroller', 'list']
-  
-  function ComponentManager(instance) {
-    this.instanceId = instance.instanceId
-    this.weexInstance = instance
-    this.componentMap = {}
-    _instanceMap[this.instanceId] = this
-  }
-  
-  ComponentManager.getInstance = function (instanceId) {
-    return _instanceMap[instanceId]
-  }
-  
-  ComponentManager.getWeexInstance = function (instanceId) {
-    return _instanceMap[instanceId].weexInstance
-  }
-  
-  ComponentManager.registerComponent = function (type, definition) {
-    typeMap[type] = definition
-  }
-  
-  ComponentManager.getScrollableTypes = function () {
-    return scrollableTypes
-  }
-  
-  ComponentManager.prototype = {
-  
-    // Fire a event 'renderbegin'/'renderend' on body element.
-    rendering: function () {
-      function _renderingEnd() {
-        // get weex instance root
-        window.dispatchEvent(new Event('renderend'))
-        this._renderingTimer = null
-      }
-      if (this._renderingTimer) {
-        clearTimeout(this._renderingTimer)
-        this._renderingTimer = setTimeout(
-          _renderingEnd.bind(this),
-          RENDERING_INDENT
-        )
-      } else {
-        window.dispatchEvent(new Event('renderbegin'))
-        this._renderingTimer = setTimeout(
-          _renderingEnd.bind(this),
-          RENDERING_INDENT
-        )
-      }
-    },
-  
-    getElementByRef: function (ref) {
-      return this.componentMap[ref]
-    },
-  
-    removeElementByRef: function (ref) {
-      var cmp
-      var self = this
-      if (!ref || !(cmp = this.componentMap[ref])) {
-        return
-      }
-      // remove from this.componentMap cursively
-      (function _removeCursively(_ref) {
-        var child = self.componentMap[_ref]
-        var listeners = child._listeners
-        var children = child.data.children
-        if (children && children.length) {
-          for (var i = 0, l = children.length; i < l; i++) {
-            _removeCursively(children[i].ref)
-          }
-        }
-        // remove events from _ref component
-        if (listeners) {
-          for (var type in listeners) {
-            child.node.removeEventListener(type, listeners[type])
-          }
-        }
-        delete child._listeners
-        delete child.node._listeners
-        // remove _ref component
-        delete self.componentMap[_ref]
-      })(ref)
-  
-    },
-  
-    createElement: function (data, nodeType) {
-      var ComponentType = typeMap[data.type]
-      if (!ComponentType) {
-        ComponentType = typeMap['container']
-      }
-  
-      var ref = data.ref
-      var component = new ComponentType(data, nodeType)
-  
-      this.componentMap[ref] = component
-      component.node.setAttribute('data-ref', ref)
-  
-      return component
-    },
-  
-    /**
-     * createBody: generate root component
-     * @param  {object} element
-     */
-    createBody: function (element) {
-  
-      // TODO: creatbody on document.body
-      // no need to create a extra div
-      var root, body, nodeType
-      if (this.componentMap['_root']) {
-        return
-      }
-  
-      nodeType = element.type
-      element.type = 'root'
-      element.rootId = this.weexInstance.rootId
-      element.ref = '_root'
-  
-      var root = this.createElement(element, nodeType)
-      body = document.querySelector('#' + this.weexInstance.rootId)
-            || document.body
-      body.appendChild(root.node)
-      root._appended = true
-    },
-  
-    appendChild: function (parentRef, data) {
-      var parent = this.componentMap[parentRef]
-  
-      if (this.componentMap[data.ref] || !parent) {
-        return
-      }
-  
-      if (parentRef === '_root' && !parent) {
-        parent = this.createElement({
-          type: 'root',
-          rootId: this.weexInstance.rootId,
-          ref: '_root'
-        })
-        parent._appended = true
-      }
-  
-      var child = parent.appendChild(data)
-  
-      // In some parent component the implementation of method
-      // appendChild didn't return the component at all, therefor
-      // child maybe a undefined object.
-      if (child) {
-        child.parentRef = parentRef
-      }
-  
-      if (child && parent._appended) {
-        this.handleAppend(child)
-      }
-    },
-  
-    appendChildren: function (ref, elements) {
-      for (var i = 0; i < elements.length; i++) {
-        this.appendChild(ref, elements[i])
-      }
-    },
-  
-    removeElement: function (ref) {
-      var component = this.componentMap[ref]
-  
-      // fire event for rendering dom on body elment.
-      this.rendering()
-  
-      if (component && component.parentRef) {
-        var parent = this.componentMap[component.parentRef]
-        component.onRemove && component.onRemove()
-        parent.removeChild(component)
-      } else {
-        console.warn('ref: ', ref)
-      }
-    },
-  
-    moveElement: function (ref, parentRef, index) {
-      var component = this.componentMap[ref]
-      var newParent = this.componentMap[parentRef]
-      var oldParentRef = component.parentRef
-      var children, before, i, l
-      if (!component || !newParent) {
-        console.warn('ref: ', ref)
-        return
-      }
-  
-      // fire event for rendering dom on body elment.
-      this.rendering()
-  
-      // remove from oldParent.data.children
-      if (oldParentRef && this.componentMap[oldParentRef]) {
-        children = this.componentMap[oldParentRef].data.children
-        if (children && children.length) {
-          for (i = 0, l = children.length; i < l; i++) {
-            if (children[i].ref === ref) {
-              break
-            }
-          }
-          if (l > i) {
-            children.splice(i, 1)
-          }
-        }
-      }
-  
-      if (index < -1) {
-        index = -1
-        console.warn('index cannot be less than -1.')
-      }
-  
-      children = newParent.data.children
-      if (children
-          && children.length
-          && index !== -1
-          && index < children.length) {
-        before = this.componentMap[newParent.data.children[index].ref]
-        newParent.insertBefore(component, before)
-      } else {  // append
-        newParent.insertBefore(component)
-      }
-  
-      component.onMove && component.onMove(parentRef, index)
-  
-    },
-  
-    insertBefore: function (ref, data) {
-      var child, before, parent
-      before = this.componentMap[ref]
-      child = this.componentMap[data.ref]
-      before && (parent = this.componentMap[before.parentRef])
-      if (child || !parent || !before) {
-        return
-      }
-  
-      child = this.createElement(data)
-      if (child) {
-        child.parentRef = before.parentRef
-        parent.insertBefore(child, before)
-      } else {
-        return
-      }
-  
-      if (this.componentMap[before.parentRef]._appended) {
-        this.handleAppend(child)
-      }
-    },
-  
-    /**
-     * addElement
-     * If index is larget than any child's index, the
-     * element will be appended behind.
-     * @param {string} parentRef
-     * @param {obj} element (data of the component)
-     * @param {number} index
-     */
-    addElement: function (parentRef, element, index) {
-      var parent, children, before
-  
-      // fire event for rendering dom on body elment.
-      this.rendering()
-  
-      parent = this.componentMap[parentRef]
-      if (!parent) {
-        return
-      }
-      children = parent.data.children
-      // -1 means append as the last.
-      if (index < -1) {
-        index = -1
-        console.warn('index cannot be less than -1.')
-      }
-      if (children && children.length
-          && children.length > index
-          && index !== -1) {
-        this.insertBefore(children[index].ref, element)
-      } else {
-        this.appendChild(parentRef, element)
-      }
-    },
-  
-    clearChildren: function (ref) {
-      var component = this.componentMap[ref]
-      if (component) {
-        component.node.innerHTML = ''
-        if (component.data) {
-          component.data.children = null
-        }
-      }
-    },
-  
-    addEvent: function (ref, type) {
-      var component
-      if (typeof ref === 'string' || typeof ref === 'number') {
-        component = this.componentMap[ref]
-      } else if (Object.prototype.toString.call(ref).slice(8, -1) === 'Object') {
-        component = ref
-        ref = component.data.ref
-      }
-      if (component && component.node) {
-        var sender = this.weexInstance.sender
-        var listener = sender.fireEvent.bind(sender, ref, type)
-        var listeners = component._listeners
-        component.node.addEventListener(type, listener, false, false)
-        if (!listeners) {
-          listeners = component._listeners = {}
-          component.node._listeners = {}
-        }
-        listeners[type] = listener
-        component.node._listeners[type] = listener
-      }
-    },
-  
-    removeEvent: function (ref, type) {
-      var component = this.componentMap[ref]
-      var listener = component._listeners[type]
-      if (component && listener) {
-        component.node.removeEventListener(type, listener)
-        component._listeners[type] = null
-        component.node._listeners[type] = null
-      }
-    },
-  
-    updateAttrs: function (ref, attr) {
-      var component = this.componentMap[ref]
-      if (component) {
-        component.updateAttrs(attr)
-        if (component.data.type === 'image' && attr.src) {
-          LazyLoad.startIfNeeded(component)
-        }
-      }
-    },
-  
-    updateStyle: function (ref, style) {
-      var component = this.componentMap[ref]
-      if (component) {
-        component.updateStyle(style)
-      }
-    },
-  
-    updateFullAttrs: function (ref, attr) {
-      var component = this.componentMap[ref]
-      if (component) {
-        component.clearAttr()
-        component.updateAttrs(attr)
-        if (component.data.type === 'image' && attr.src) {
-          LazyLoad.startIfNeeded(component)
-        }
-      }
-    },
-  
-    updateFullStyle: function (ref, style) {
-      var component = this.componentMap[ref]
-      if (component) {
-        component.clearStyle()
-        component.updateStyle(style)
-      }
-    },
-  
-    handleAppend: function (component) {
-      component._appended = true
-      component.onAppend && component.onAppend()
-  
-      // invoke onAppend on children recursively
-      var children = component.data.children
-      if (children) {
-        for (var i = 0; i < children.length; i++) {
-          var child = this.componentMap[children[i].ref]
-          if (child) {
-            this.handleAppend(child)
-          }
-        }
-      }
-  
-      // watch appear/disappear of the component if needed
-      AppearWatcher.watchIfNeeded(component)
-  
-      // do lazyload if needed
-      LazyLoad.startIfNeeded(component)
-    },
-  
-    transition: function (ref, config, callback) {
-      var component = this.componentMap[ref]
-      animation.transitionOnce(component, config, callback)
-    },
-  
-    renderFinish: function () {
-      FrameUpdater.pause()
-    }
-  }
-  
-  module.exports = ComponentManager
-
-
-/***/ },
-/* 10 */
-/***/ function(module, exports) {
-
-  'use strict'
-  
-  var raf = window.requestAnimationFrame ||
-            window.webkitRequestAnimationFrame ||
-            function (calllback) {
-              setTimeout(calllback, 16)
-            }
-  
-  var rafId
-  var observers = []
-  var paused = false
-  
-  var FrameUpdater = {
-    start: function () {
-      if (rafId) {
-        return
-      }
-  
-      rafId = raf(function runLoop() {
-        if (!paused) {
-          for (var i = 0; i < observers.length; i++) {
-            observers[i]()
-          }
-          raf(runLoop)
-        }
-      })
-    },
-  
-    isActive: function () {
-      return !paused
-    },
-  
-    pause: function () {
-      paused = true
-      rafId = undefined
-    },
-  
-    resume: function () {
-      paused = false
-      this.start()
-    },
-  
-    addUpdateObserver: function (observeMethod) {
-      observers.push(observeMethod)
-    }
-  }
-  
-  module.exports = FrameUpdater
-
-
-/***/ },
-/* 11 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  var utils = __webpack_require__(7)
-  
-  var componentsInScroller = []
-  var componentsOutOfScroller = []
-  var listened = false
-  var direction = 'up'
-  var scrollY = 0
-  
-  var AppearWatcher = {
-    watchIfNeeded: function (component) {
-      if (needWatch(component)) {
-        if (component.isInScrollable()) {
-          componentsInScroller.push(component)
-        } else {
-          componentsOutOfScroller.push(component)
-        }
-        if (!listened) {
-          listened = true
-          // var handler = throttle(onScroll, 25)
-          var handler = throttle(onScroll, 100)
-          window.addEventListener('scroll', handler, false)
-        }
-      }
-    }
-  }
-  
-  function needWatch(component) {
-    var events = component.data.event
-    if (events
-        && (events.indexOf('appear') != -1
-          || events.indexOf('disappear') != -1)) {
-      return true
-    }
-    return false
-  }
-  
-  function onScroll(e) {
-    // If the scroll event is dispatched from a scrollable component
-    // implemented through scrollerjs, then the appear/disappear events
-    // should be treated specially by handleScrollerScroll.
-    if (e.originalType === 'scrolling') {
-      handleScrollerScroll()
-    } else {
-      handleWindowScroll()
-    }
-  }
-  
-  function handleScrollerScroll() {
-    var cmps = componentsInScroller
-    var len = cmps.length
-    for (var i = 0; i < len; i++) {
-      var component = cmps[i]
-      var appear = isComponentInScrollerAppear(component)
-      if (appear && !component._appear) {
-        component._appear = true
-        fireEvent(component, 'appear')
-      } else if (!appear && component._appear) {
-        component._appear = false
-        fireEvent(component, 'disappear')
-      }
-    }
-  }
-  
-  function handleWindowScroll() {
-    var y = window.scrollY
-    direction = y >= scrollY ? 'up' : 'down'
-    scrollY = y
-  
-    var len = componentsOutOfScroller.length
-    if (len === 0) {
-      return
-    }
-    for (var i = 0; i < len; i++) {
-      var component = componentsOutOfScroller[i]
-      var appear = isComponentInWindow(component)
-      if (appear && !component._appear) {
-        component._appear = true
-        fireEvent(component, 'appear')
-      } else if (!appear && component._appear) {
-        component._appear = false
-        fireEvent(component, 'disappear')
-      }
-    }
-  }
-  
-  function isComponentInScrollerAppear(component) {
-    var parentScroller = component._parentScroller
-    var cmpRect = component.node.getBoundingClientRect()
-    if (!isComponentInWindow(component)) {
-      return false
-    }
-    while (parentScroller) {
-      var parentRect = parentScroller.node.getBoundingClientRect()
-      if (!(cmpRect.right > parentRect.left
-          && cmpRect.left < parentRect.right
-          && cmpRect.bottom > parentRect.top
-          && cmpRect.top < parentRect.bottom)) {
-        return false
-      }
-      parentScroller = parentScroller._parentScroller
-    }
-    return true
-  }
-  
-  function isComponentInWindow(component) {
-    var rect = component.node.getBoundingClientRect()
-    return rect.right > 0 && rect.left < window.innerWidth &&
-           rect.bottom > 0 && rect.top < window.innerHeight
-  }
-  
-  function fireEvent(component, type) {
-    var evt = document.createEvent('HTMLEvents')
-    var data = { direction: direction }
-    evt.initEvent(type, false, false)
-    evt.data = data
-    utils.extend(evt, data)
-    component.node.dispatchEvent(evt)
-  }
-  
-  function throttle(func, wait) {
-    var context, args, result
-    var timeout = null
-    var previous = 0
-    var later = function () {
-      previous = Date.now()
-      timeout = null
-      result = func.apply(context, args)
-    }
-    return function () {
-      var now = Date.now()
-      var remaining = wait - (now - previous)
-      context = this
-      args = arguments
-      if (remaining <= 0) {
-        clearTimeout(timeout)
-        timeout = null
-        previous = now
-        result = func.apply(context, args)
-      } else if (!timeout) {
-        timeout = setTimeout(later, remaining)
-      }
-      return result
-    }
-  }
-  
-  module.exports = AppearWatcher
-
-/***/ },
-/* 12 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  __webpack_require__(13)
-  
-  var lazyloadTimer
-  
-  var LazyLoad = {
-    makeImageLazy: function (image, src) {
-      image.removeAttribute('img-src')
-      image.removeAttribute('i-lazy-src')
-      image.removeAttribute('src')
-      image.setAttribute('img-src', src)
-      // should replace 'src' with 'img-src'. but for now lib.img.fire is
-      // not working for the situation that the appear event has been
-      // already triggered.
-      // image.setAttribute('src', src)
-      // image.setAttribute('img-src', src)
-      this.fire()
-    },
-  
-    // we don't know when all image are appended
-    // just use setTimeout to do delay lazyload
-    //
-    // -- actually everytime we add a element or update styles,
-    // the component manager will call startIfNeed to fire
-    // lazyload once again in the handleAppend function. so there
-    // is no way that any image element can miss it. See source
-    // code in componentMangager.js.
-    startIfNeeded: function (component) {
-      var that = this
-      if (component.data.type === 'image') {
-        if (!lazyloadTimer) {
-          lazyloadTimer = setTimeout(function () {
-            that.fire()
-            clearTimeout(lazyloadTimer)
-            lazyloadTimer = null
-          }, 16)
-        }
-      }
-    },
-  
-    loadIfNeeded: function (elementScope) {
-      var notPreProcessed = elementScope.querySelectorAll('[img-src]')
-      var that = this
-      // image elements which have attribute 'i-lazy-src' were elements
-      // that had been preprocessed by lib-img-core, but not loaded yet, and
-      // must be loaded when 'appear' events were fired. It turns out the
-      // 'appear' event was not fired correctly in the css-translate-transition
-      // situation, so 'i-lazy-src' must be checked and lazyload must be
-      // fired manually.
-      var preProcessed = elementScope.querySelectorAll('[i-lazy-src]')
-      if (notPreProcessed.length > 0 || preProcessed.length > 0) {
-        that.fire()
-      }
-    },
-  
-    // fire lazyload.
-    fire: function () {
-      lib.img.fire()
-    }
-  
-  }
-  
-  module.exports = LazyLoad
-
-
-/***/ },
-/* 13 */
-/***/ function(module, exports, __webpack_require__) {
-
-  "undefined"==typeof window&&(window={ctrl:{},lib:{}}),!window.ctrl&&(window.ctrl={}),!window.lib&&(window.lib={}),function(t,i){function e(t,i){i&&("IMG"==t.nodeName.toUpperCase()?t.setAttribute("src",i):t.style.backgroundImage='url("'+i+'")')}function a(){r=i.appear.init({cls:"imgtmp",once:!0,x:o.lazyWidth,y:o.lazyHeight,onAppear:function(t){var i=this;e(i,i.getAttribute("i-lazy-src")),i.removeAttribute("i-lazy-src")}})}__webpack_require__(14);var r,A={},o={dataSrc:"img-src",lazyHeight:0,lazyWidth:0};A.logConfig=function(){console.log("lib-img Config\n",o)},A.fire=function(){r||a();var t="i_"+Date.now()%1e5,i=document.querySelectorAll("["+o.dataSrc+"]");[].forEach.call(i,function(i){"false"==i.dataset.lazy&&"true"!=i.dataset.lazy?e(i,processSrc(i,i.getAttribute(o.dataSrc))):(i.classList.add(t),i.setAttribute("i-lazy-src",i.getAttribute(o.dataSrc))),i.removeAttribute(o.dataSrc)}),r.bind("."+t),r.fire()},A.defaultSrc="data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==",i.img=A,module.exports=A}(window,window.lib||(window.lib={}));
-
-/***/ },
-/* 14 */
-/***/ function(module, exports) {
-
-  "undefined"==typeof window&&(window={ctrl:{},lib:{}}),!window.ctrl&&(window.ctrl={}),!window.lib&&(window.lib={}),function(n,e){function i(){d=w.createEvent("HTMLEvents"),v=w.createEvent("HTMLEvents"),d.initEvent("_appear",!1,!0),v.initEvent("_disappear",!1,!0)}function a(t,n){var e,i,a,s=(Date.now(),0),o=null,r=function(){s=Date.now(),o=null,t.apply(e,i)};return function(){var l=Date.now();e=this,i=arguments;var c=n-(l-s);return 0>=c||c>=n?(clearTimeout(o),o=null,a=t.apply(e,i)):null==o&&(o=setTimeout(r,c)),a}}function s(n,e){var n,i,a,s;if(n)return e||(e={x:0,y:0}),n!=window?(n=n.getBoundingClientRect(),i=n.left,t=n.top,a=n.right,s=n.bottom):(i=0,t=0,a=i+n.innerWidth,s=t+n.innerHeight),{left:i,top:t,right:a+e.x,bottom:s+e.y}}function o(t,n){var e=n.right>t.left&&n.left<t.right,i=n.bottom>t.top&&n.top<t.bottom;return e&&i}function r(t,n){var e="none",i=t.left-n.left,a=t.top-n.top;return 0==a&&(e=0!=i?i>0?"left":"right":"none"),0==i&&(e=0!=a?a>0?"up":"down":"none"),e}function l(t,n){for(var e in n)n.hasOwnProperty(e)&&(t[e]=n[e]);return t}function c(){var t=this,n=a(function(){f.apply(t,arguments)},this.options.wait);this.__handle&&(this.container.removeEventListener("scroll",this.__handle),this.__handle=null),this.__handle=n,this.container.addEventListener("scroll",n,!1),this.container.addEventListener("resize",function(n){f.apply(t,arguments)},!1),this.container.addEventListener("animationEnd",function(){f.apply(t,arguments)},!1),this.container.addEventListener("webkitAnimationEnd",function(){f.apply(t,arguments)},!1),this.container.addEventListener("transitionend",function(){f.apply(t,arguments)},!1)}function p(t){var n=this,e=this.options.container;if("string"==typeof e?this.container=w.querySelector(e):this.container=e,this.container==window)var i=w.querySelectorAll(t);else var i=this.container.querySelectorAll(t);var i=[].slice.call(i,null);return i=i.filter(function(t){return"1"==t.dataset.bind?(delete t._hasAppear,delete t._hasDisAppear,delete t._appear,t.classList.remove(n.options.cls),!1):!0})}function h(t){var n=this;t&&t.length>0&&[].forEach.call(t,function(t){t._eleOffset=s(t),t.classList.remove(n.options.cls),t.dataset.bind=1})}function f(){var t=this.container,n=this.appearWatchElements,e=this.options.onAppear,i=this.options.onDisappear,a=s(t,{x:this.options.x,y:this.options.y}),l=this.options.once,c=arguments[0]||{};n&&n.length>0&&[].forEach.call(n,function(t,n){var p=s(t),h=r(t._eleOffset,p);t._eleOffset=p;var f=o(a,p),u=t._appear,w=t._hasAppear,E=t._hasDisAppear;d.data={direction:h},v.data={direction:h},f&&!u?(l&&!w||!l)&&(e&&e.call(t,c),t.dispatchEvent(d),t._hasAppear=!0,t._appear=!0):!f&&u&&(l&&!E||!l)&&(i&&i.call(t,c),t.dispatchEvent(v),t._hasDisAppear=!0,t._appear=!1)})}function u(t){l(this.options,t||(t={})),this.appearWatchElements=this.appearWatchElements||p.call(this,"."+this.options.cls),h.call(this,this.appearWatchElements),c.call(this)}var d,v,w=document,E=function(){u.apply(this,arguments)},_={instances:[],init:function(t){var n={options:{container:window,wait:100,x:0,y:0,cls:"lib-appear",once:!1,onReset:function(){},onAppear:function(){},onDisappear:function(){}},container:null,appearWatchElements:null,bind:function(t){var n=this.options.cls;if("string"==typeof t){var e=p.call(this,t);[].forEach.call(e,function(t,e){t.classList.contains(n)||t.classList.add(n)})}else{if(1!=t.nodeType||!this.container.contains(t))return this;t.classList.contains(n)||t.classList.add(n)}var i=p.call(this,"."+this.options.cls);return this.appearWatchElements=this.appearWatchElements.concat(i),h.call(this,i),this},reset:function(t){return u.call(this,t),this.appearWatchElements.forEach(function(t){delete t._hasAppear,delete t._hasDisAppear,delete t._appear}),this},fire:function(){this.appearWatchElements||(this.appearWatchElements=[]);var t=p.call(this,"."+this.options.cls);return this.appearWatchElements=this.appearWatchElements.concat(t),h.call(this,t),f.call(this),this}};E.prototype=n;var e=new E(t);return this.instances.push(e),e},fireAll:function(){var t=this.instances;t.forEach(function(t){t.fire()})}};i(),e.appear=_}(window,window.lib||(window.lib={}));
-
-/***/ },
-/* 15 */
-/***/ function(module, exports) {
-
-  'use strict'
-  
-  module.exports = {
-  
-    /**
-     * config:
-     *   - styles
-     *   - duration [Number] milliseconds(ms)
-     *   - timingFunction [string]
-     *   - dealy [Number] milliseconds(ms)
-     */
-    transitionOnce: function (comp, config, callback) {
-      var styles = config.styles || {}
-      var duration = config.duration || 1000 // ms
-      var timingFunction = config.timingFunction || 'ease'
-      var delay = config.delay || 0  // ms
-      var transitionValue = 'all ' + duration + 'ms '
-          + timingFunction + ' ' + delay + 'ms'
-      var dom = comp.node
-      var transitionEndHandler = function (e) {
-        e.stopPropagation()
-        dom.removeEventListener('webkitTransitionEnd', transitionEndHandler)
-        dom.removeEventListener('transitionend', transitionEndHandler)
-        dom.style.transition = ''
-        dom.style.webkitTransition = ''
-        callback()
-      }
-      dom.style.transition = transitionValue
-      dom.style.webkitTransition = transitionValue
-      dom.addEventListener('webkitTransitionEnd', transitionEndHandler)
-      dom.addEventListener('transitionend', transitionEndHandler)
-      comp.updateStyle(styles)
-    }
-  
-  }
-
-/***/ },
-/* 16 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  var config = __webpack_require__(5)
-  var utils = __webpack_require__(7)
-  var ComponentManager = __webpack_require__(9)
-  var flexbox = __webpack_require__(17)
-  __webpack_require__(18)
-  
-  function Component(data, nodeType) {
-    this.data = data
-    this.node = this.create(nodeType)
-  
-    this.createChildren()
-    this.updateAttrs(this.data.attr)
-    // issue: when add element to a list in lifetime hook 'ready', the
-    // styles is set to the classStyle, not style. This is a issue
-    // that jsframework should do something about.
-    var classStyle = this.data.classStyle
-    classStyle && this.updateStyle(this.data.classStyle)
-    this.updateStyle(this.data.style)
-    this.bindEvents(this.data.event)
-  }
-  
-  Component.prototype = {
-  
-    create: function (nodeType) {
-      var node = document.createElement(nodeType || 'div')
-      return node
-    },
-  
-    getComponentManager: function () {
-      return ComponentManager.getInstance(this.data.instanceId)
-    },
-  
-    getParent: function () {
-      return this.getComponentManager().componentMap[this.parentRef]
-    },
-  
-    isScrollable: function () {
-      var t = this.data.type
-      return ComponentManager.getScrollableTypes().indexOf(t) !== -1
-    },
-  
-    isInScrollable: function () {
-      if (typeof this._isInScrollable === 'boolean') {
-        return this._isInScrollable
-      }
-      var parent = this.getParent()
-      if (parent
-          && (typeof parent._isInScrollable !== 'boolean')
-          && !parent.isScrollable()) {
-        if (parent.data.type === 'root') {
-          this._isInScrollable = false
-          return false
-        }
-        this._isInScrollable = parent.isInScrollable()
-        this._parentScroller = parent._parentScroller
-        return this._isInScrollable
-      }
-      if (typeof parent._isInScrollable === 'boolean') {
-        this._isInScrollable = parent._isInScrollable
-        this._parentScroller = parent._parentScroller
-        return this._isInScrollable
-      }
-      if (parent.isScrollable()) {
-        this._isInScrollable = true
-        this._parentScroller = parent
-        return true
-      }
-      if (!parent) {
-        console && console.error('isInScrollable - parent not exist.')
-      }
-    },
-  
-    createChildren: function () {
-      var children = this.data.children
-      var parentRef = this.data.ref
-      var componentManager = this.getComponentManager()
-      if (children && children.length) {
-        var fragment = document.createDocumentFragment()
-        var isFlex = false
-        for (var i = 0; i < children.length; i++) {
-          children[i].instanceId = this.data.instanceId
-          children[i].scale = this.data.scale
-          var child = componentManager.createElement(children[i])
-          fragment.appendChild(child.node)
-          child.parentRef = parentRef
-          if (!isFlex
-              && child.data.style
-              && child.data.style.hasOwnProperty('flex')
-            ) {
-            isFlex = true
-          }
-        }
-        this.node.appendChild(fragment)
-      }
-    },
-  
-    // @todo: changed param data to child
-    appendChild: function (data) {
-      var children = this.data.children
-      var componentManager = this.getComponentManager()
-      var child = componentManager.createElement(data)
-      this.node.appendChild(child.node)
-      // update this.data.children
-      if (!children || !children.length) {
-        this.data.children = [data]
-      } else {
-        children.push(data)
-      }
-  
-      return child
-    },
-  
-    insertBefore: function (child, before) {
-      var children = this.data.children
-      var i = 0
-      var l
-      var isAppend = false
-  
-      // update this.data.children
-      if (!children || !children.length || !before) {
-        isAppend = true
-      } else {
-        for (l = children.length; i < l; i++) {
-          if (children[i].ref === before.data.ref) {
-            break
-          }
-        }
-        if (i === l) {
-          isAppend = true
-        }
-      }
-  
-  
-      if (isAppend) {
-        this.node.appendChild(child.node)
-        children.push(child.data)
-      } else {
-        this.node.insertBefore(child.node, before.node)
-        children.splice(i, 0, child.data)
-      }
-  
-    },
-  
-    removeChild: function (child) {
-      var children = this.data.children
-      // remove from this.data.children
-      var i = 0
-      var componentManager = this.getComponentManager()
-      if (children && children.length) {
-        for (var l = children.length; i < l; i++) {
-          if (children[i].ref === child.data.ref) {
-            break
-          }
-        }
-        if (i < l) {
-          children.splice(i, 1)
-        }
-      }
-      // remove from componentMap recursively
-      componentManager.removeElementByRef(child.data.ref)
-      this.node.removeChild(child.node)
-    },
-  
-    updateAttrs: function (attrs) {
-      // Note:attr must be injected into the dom element because
-      // it will be accessed from the outside developer by event.target.attr.
-      if (!this.node.attr) {
-        this.node.attr = {}
-      }
-      for (var key in attrs) {
-        var value = attrs[key]
-        var attrSetter = this.attr[key]
-        if (typeof attrSetter === 'function') {
-          attrSetter.call(this, value)
-        } else {
-          if (typeof value === 'boolean') {
-            this.node[key] = value
-          } else {
-            this.node.setAttribute(key, value)
-          }
-          this.node.attr[key] = value
-        }
-      }
-    },
-  
-    updateStyle: function (style) {
-      for (var key in style) {
-        var value = style[key]
-        var styleSetter = this.style[key]
-  
-        if (typeof styleSetter === 'function') {
-          styleSetter.call(this, value)
-        } else {
-          if (typeof value === 'number'
-              && (key !== 'flex' && key !== 'opacity' && key !== 'zIndex')
-            ) {
-            value = value * this.data.scale + 'px'
-          }
-          this.node.style[key] = value
-        }
-      }
-    },
-  
-    bindEvents: function (evts) {
-      var componentManager = this.getComponentManager()
-      if (evts
-          && Object.prototype.toString.call(evts).slice(8, -1) === 'Array'
-        ) {
-        for (var i = 0, l = evts.length; i < l; i++) {
-          componentManager.addEvent(this, evts[i])
-        }
-      }
-    },
-  
-    // dispatch a specified event on this.node
-    //  - type: event type
-    //  - data: event data
-    //  - config: event config object
-    //     - bubbles
-    //     - cancelable
-    dispatchEvent: function (type, data, config) {
-      var event = document.createEvent('HTMLEvents')
-      config = config || {}
-      event.initEvent(type, config.bubbles || false, config.cancelable || false)
-      !data && (data = {})
-      event.data = utils.extend({}, data)
-      utils.extend(event, data)
-      if (type === 'appear') {
-        console.log('appear', data)
-      }
-      this.node.dispatchEvent(event)
-    },
-  
-    updateRecursiveAttr: function (data) {
-      this.updateAttrs(data.attr)
-      var componentManager = this.getComponentManager()
-      var children = this.data.children
-      if (children) {
-        for (var i = 0; i < children.length; i++) {
-          var child = componentManager.getElementByRef(children[i].ref)
-          if (child) {
-            child.updateRecursiveAttr(data.children[i])
-          }
-        }
-      }
-    },
-  
-    updateRecursiveStyle: function (data) {
-      this.updateStyle(data.style)
-      var componentManager = this.getComponentManager()
-      var children = this.data.children
-      if (children) {
-        for (var i = 0; i < children.length; i++) {
-          var child = componentManager.getElementByRef(children[i].ref)
-          if (child) {
-            child.updateRecursiveStyle(data.children[i])
-          }
-        }
-      }
-    },
-  
-    updateRecursiveAll: function (data) {
-      this.updateAttrs(data.attr)
-      this.updateStyle(data.style)
-      var componentManager = this.getComponentManager()
-  
-      // var oldRef = this.data.ref
-      // if (componentMap[oldRef]) {
-      //   delete componentMap[oldRef]
-      // }
-      // this.data.ref = data.ref
-      // componentMap[data.ref] = this
-  
-      var children = this.data.children
-      if (children) {
-        for (var i = 0; i < children.length; i++) {
-          var child = componentManager.getElementByRef(children[i].ref)
-          if (child) {
-            child.updateRecursiveAll(data.children[i])
-          }
-        }
-      }
-    },
-  
-    attr: {}, // attr setters
-  
-    style: Object.create(flexbox), // style setters
-  
-    clearAttr: function () {
-    },
-  
-    clearStyle: function () {
-      this.node.cssText = ''
-    }
-  }
-  
-  Component.prototype.style.position = function (value) {
-    // TODO: make it in a decent implementation
-    if (value === 'sticky') {
-      this.node.style.zIndex = 100
-      setTimeout(function () {
-        this.sticky = new lib.sticky(this.node, {
-          top: 0
-        })
-      }.bind(this), 0)
-    } else {
-      this.node.style.position = value
-    }
-  }
-  
-  module.exports = Component
-
-
-/***/ },
-/* 17 */
-/***/ function(module, exports) {
-
-  'use strict'
-  
-  // Flexbox polyfill
-  var flexboxSetters = (function () {
-    var BOX_ALIGN = {
-      stretch: 'stretch',
-      'flex-start': 'start',
-      'flex-end': 'end',
-      center: 'center'
-    }
-    var BOX_ORIENT = {
-      row: 'horizontal',
-      column: 'vertical'
-    }
-    var BOX_PACK = {
-      'flex-start': 'start',
-      'flex-end': 'end',
-      center: 'center',
-      'space-between': 'justify',
-      'space-around': 'justify' // Just same as `space-between`
-    }
-    return {
-      flex: function (value) {
-        this.node.style.webkitBoxFlex = value
-        this.node.style.webkitFlex = value
-        this.node.style.flex = value
-      },
-      alignItems: function (value) {
-        this.node.style.webkitBoxAlign = BOX_ALIGN[value]
-        this.node.style.webkitAlignItems = value
-        this.node.style.alignItems = value
-      },
-      alignSelf: function (value) {
-        this.node.style.webkitAlignSelf = value
-        this.node.style.alignSelf = value
-      },
-      flexDirection: function (value) {
-        this.node.style.webkitBoxOrient = BOX_ORIENT[value]
-        this.node.style.webkitFlexDirection = value
-        this.node.style.flexDirection = value
-      },
-      justifyContent: function (value) {
-        this.node.style.webkitBoxPack = BOX_PACK[value]
-        this.node.style.webkitJustifyContent = value
-        this.node.style.justifyContent = value
-      }
-    }
-  })()
-  
-  module.exports = flexboxSetters
-
-
-/***/ },
-/* 18 */
-/***/ function(module, exports) {
-
-  (typeof window === 'undefined') && (window = {ctrl: {}, lib: {}});!window.ctrl && (window.ctrl = {});!window.lib && (window.lib = {});!function(a,b,c){function d(a){return null!=a&&"object"==typeof a&&Object.getPrototypeOf(a)==Object.prototype}function e(a,b){var c,d,e,f=null,g=0,h=function(){g=Date.now(),f=null,e=a.apply(c,d)};return function(){var i=Date.now(),j=b-(i-g);return c=this,d=arguments,0>=j?(clearTimeout(f),f=null,g=i,e=a.apply(c,d)):f||(f=setTimeout(h,j)),e}}function f(a){var b="";return Object.keys(a).forEach(function(c){b+=c+":"+a[c]+";"}),b}function g(a,c){!c&&d(a)&&(c=a,a=c.element),c=c||{},a.nodeType!=b.ELEMENT_NODE&&"string"==typeof a&&(a=b.querySelector(a));var e=this;e.element=a,e.top=c.top||0,e.withinParent=void 0==c.withinParent?!1:c.withinParent,e.init()}var h=a.parseInt,i=navigator.userAgent,j=!!i.match(/Firefox/i),k=!!i.match(/IEMobile/i),l=j?"-moz-":k?"-ms-":"-webkit-",m=j?"Moz":k?"ms":"webkit",n=function(){var a=b.createElement("div"),c=a.style;return c.cssText="position:"+l+"sticky;position:sticky;",-1!=c.position.indexOf("sticky")}();g.prototype={constructor:g,init:function(){var a=this,b=a.element,c=b.style;c[m+"Transform"]="translateZ(0)",c.transform="translateZ(0)",a._originCssText=c.cssText,n?(c.position=l+"sticky",c.position="sticky",c.top=a.top+"px"):(a._simulateSticky(),a._bindResize())},_bindResize:function(){var b=this,c=/android/gi.test(navigator.appVersion),d=b._resizeEvent="onorientationchange"in a?"orientationchange":"resize",e=b._resizeHandler=function(){setTimeout(function(){b.refresh()},c?200:0)};a.addEventListener(d,e,!1)},refresh:function(){var a=this;n||(a._detach(),a._simulateSticky())},_addPlaceholder:function(a){var c,d=this,e=d.element,g=a.position;if(-1!=["static","relative"].indexOf(g)){c=d._placeholderElement=b.createElement("div");var i=h(a.width)+h(a.marginLeft)+h(a.marginRight),j=h(a.height);"border-box"!=a.boxSizing&&(i+=h(a.borderLeftWidth)+h(a.borderRightWidth)+h(a.paddingLeft)+h(a.paddingRight),j+=h(a.borderTopWidth)+h(a.borderBottomWidth)+h(a.paddingTop)+h(a.paddingBottom)),c.style.cssText=f({display:"none",visibility:"hidden",width:i+"px",height:j+"px",margin:0,"margin-top":a.marginTop,"margin-bottom":a.marginBottom,border:0,padding:0,"float":a["float"]||a.cssFloat}),e.parentNode.insertBefore(c,e)}return c},_simulateSticky:function(){var c=this,d=c.element,g=c.top,i=d.style,j=d.getBoundingClientRect(),k=getComputedStyle(d,""),l=d.parentNode,m=getComputedStyle(l,""),n=c._addPlaceholder(k),o=c.withinParent,p=c._originCssText,q=j.top-g+a.pageYOffset,r=l.getBoundingClientRect().bottom-h(m.paddingBottom)-h(m.borderBottomWidth)-h(k.marginBottom)-j.height-g+a.pageYOffset,s=p+f({position:"fixed",top:g+"px",width:k.width,"margin-top":0}),t=p+f({position:"absolute",top:r+"px",width:k.width}),u=1,v=c._scrollHandler=e(function(){var b=a.pageYOffset;q>b?1!=u&&(i.cssText=p,n&&(n.style.display="none"),u=1):!o&&b>=q||o&&b>=q&&r>b?2!=u&&(i.cssText=s,n&&3!=u&&(n.style.display="block"),u=2):o&&3!=u&&(i.cssText=t,n&&2!=u&&(n.style.display="block"),u=3)},100);if(a.addEventListener("scroll",v,!1),a.pageYOffset>=q){var w=b.createEvent("HTMLEvents");w.initEvent("scroll",!0,!0),a.dispatchEvent(w)}},_detach:function(){var b=this,c=b.element;if(c.style.cssText=b._originCssText,!n){var d=b._placeholderElement;d&&c.parentNode.removeChild(d),a.removeEventListener("scroll",b._scrollHandler,!1)}},destroy:function(){var b=this;b._detach();var c=b.element.style;c.removeProperty(l+"transform"),c.removeProperty("transform"),n||a.removeEventListener(b._resizeEvent,b._resizeHandler,!1)}},c.sticky=g}(window,document,window.lib||(window.lib={}));;module.exports = window.lib['sticky'];
-
-/***/ },
-/* 19 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  var utils = __webpack_require__(7)
-  
-  var _senderMap = {}
-  
-  function Sender(instance) {
-    if (!(this instanceof Sender)) {
-      return new Sender(instance)
-    }
-    this.instanceId = instance.instanceId
-    this.weexInstance = instance
-    _senderMap[this.instanceId] = this
-  }
-  
-  function _send(instanceId, msg) {
-    callJS(instanceId, [msg])
-  }
-  
-  Sender.getSender = function (instanceId) {
-    return _senderMap[instanceId]
-  }
-  
-  Sender.prototype = {
-  
-    // perform a callback to jsframework.
-    performCallback: function (callbackId, data) {
-      var args = [callbackId]
-      data && args.push(data)
-      _send(this.instanceId, {
-        method: 'callback',
-        args: args
-      })
-    },
-  
-    fireEvent: function (ref, type, event) {
-      // Note that the event.target must be the standard event's
-      // currentTarget. Therefor a process for replacing target must
-      // be done when a event is fired.
-      var evt = utils.extend({}, event)
-      evt.target = evt.currentTarget
-      evt.value = event.target.value
-      evt.timestamp = Date.now()
-      _send(this.instanceId, {
-        method: 'fireEvent',
-        args: [ref, type, evt]
-      })
-    }
-  
-  }
-  
-  module.exports = Sender
-
-/***/ },
-/* 20 */
-/***/ function(module, exports, __webpack_require__) {
-
-  /* WEBPACK VAR INJECTION */(function(global) {'use strict'
-  
-  var config = __webpack_require__(5)
-  var protocol = __webpack_require__(8)
-  var utils = __webpack_require__(7)
-  var FrameUpdater = __webpack_require__(10)
-  var Sender = __webpack_require__(19)
-  
-  var callQueue = []
-  // Need a task counter?
-  // When FrameUpdater is not activated, tasks will not be push
-  // into callQueue and there will be no trace for situation of
-  // execution of tasks.
-  
-  // give 10ms for call handling, and rest 6ms for others
-  var MAX_TIME_FOR_EACH_FRAME = 10
-  
-  // callNative: jsFramework will call this method to talk to
-  // this renderer.
-  // params:
-  //  - instanceId: string.
-  //  - tasks: array of object.
-  //  - callbackId: number.
-  function callNative(instanceId, tasks, callbackId) {
-    var calls = []
-    if (typeof tasks === 'string') {
-      try {
-        calls = JSON.parse(tasks)
-      } catch (e) {
-        console.error('invalid tasks:', tasks)
-      }
-    } else if (Object.prototype.toString.call(tasks).slice(8, -1) === 'Array') {
-      calls = tasks
-    }
-    var len = calls.length
-    calls[len - 1].callbackId = (!callbackId && callbackId !== 0)
-                                ? -1
-                                : callbackId
-    // To solve the problem of callapp, the two-way time loop rule must
-    // be replaced by calling directly except the situation of page loading.
-    // 2015-11-03
-    for (var i = 0; i < len; i++) {
-      if (FrameUpdater.isActive()) {
-        callQueue.push({
-          instanceId: instanceId,
-          call: calls[i]
-        })
-      }
-      else {
-        processCall(instanceId, calls[i])
-      }
-    }
-  
-  }
-  
-  function processCallQueue() {
-    var len = callQueue.length
-    if (len === 0) {
-      return
-    }
-    var start = Date.now()
-    var elapsed = 0
-  
-    while (--len >= 0 && elapsed < MAX_TIME_FOR_EACH_FRAME) {
-      var callObj = callQueue.shift()
-      processCall(callObj.instanceId, callObj.call)
-      elapsed = Date.now() - start
-    }
-  }
-  
-  function processCall(instanceId, call) {
-    var moduleName = call.module
-    var methodName = call.method
-    var module, method
-    var args = call.args || call.arguments || []
-  
-    if (!(module = protocol.apiModule[moduleName])) {
-      return
-    }
-    if (!(method = module[methodName])) {
-      return
-    }
-  
-    method.apply(protocol.getWeexInstance(instanceId), args)
-  
-    var callbackId = call.callbackId
-    if ((callbackId
-      || callbackId === 0
-      || callbackId === '0')
-      && callbackId !== '-1'
-      && callbackId !== -1) {
-      performNextTick(instanceId, callbackId)
-    }
-  }
-  
-  function performNextTick(instanceId, callbackId) {
-    Sender.getSender(instanceId).performCallback(callbackId)
-  }
-  
-  function nativeLog() {
-    if (config.debug) {
-      if (arguments[0].match(/^perf/)) {
-        console.info.apply(console, arguments)
-        return
-      }
-      console.debug.apply(console, arguments)
-    }
-  }
-  
-  function exportsBridgeMethodsToGlobal() {
-    global.callNative = callNative
-    global.nativeLog = nativeLog
-  }
-  
-  module.exports = {
-  
-    init: function () {
-  
-      // process callQueue every 16 milliseconds.
-      FrameUpdater.addUpdateObserver(processCallQueue)
-      FrameUpdater.start()
-  
-      // exports methods to global(window).
-      exportsBridgeMethodsToGlobal()
-    }
-  
-  }
-  
-  /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
-
-/***/ },
-/* 21 */
-/***/ function(module, exports, __webpack_require__) {
-
-  var RootComponent = __webpack_require__(22)
-  var Container = __webpack_require__(23)
-  var Image = __webpack_require__(26)
-  var Text = __webpack_require__(28)
-  var List = __webpack_require__(29)
-  var Countdown = __webpack_require__(37)
-  var Marquee = __webpack_require__(39)
-  var Slider = __webpack_require__(40)
-  var Indicator = __webpack_require__(44)
-  var Tabheader = __webpack_require__(47)
-  var Scroller = __webpack_require__(51)
-  var Input = __webpack_require__(54)
-  var Select = __webpack_require__(55)
-  var Datepicker = __webpack_require__(56)
-  var Timepicker = __webpack_require__(57)
-  var Video = __webpack_require__(58)
-  var Switch = __webpack_require__(61)
-  var A = __webpack_require__(64)
-  var Embed = __webpack_require__(65)
-  
-  var components = {
-    init: function (Weex) {
-      Weex.registerComponent('root', RootComponent)
-      Weex.registerComponent('root', RootComponent)
-      Weex.registerComponent('container', Container)
-      Weex.registerComponent('image', Image)
-      Weex.registerComponent('text', Text)
-      Weex.registerComponent('list', List)
-      Weex.registerComponent('countdown', Countdown)
-      Weex.registerComponent('marquee', Marquee)
-      Weex.registerComponent('slider', Slider)
-      Weex.registerComponent('indicator', Indicator)
-      Weex.registerComponent('tabheader', Tabheader)
-      Weex.registerComponent('scroller', Scroller)
-      Weex.registerComponent('input', Input)
-      Weex.registerComponent('select', Select)
-      Weex.registerComponent('datepicker', Datepicker)
-      Weex.registerComponent('timepicker', Timepicker)
-      Weex.registerComponent('video', Video)
-      Weex.registerComponent('switch', Switch)
-      Weex.registerComponent('a', A)
-      Weex.registerComponent('embed', Embed)
-    }
-  }
-  
-  module.exports = components
-
-/***/ },
-/* 22 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  var ComponentManager = __webpack_require__(9)
-  var Component = __webpack_require__(16)
-  
-  // If nodeType is in this WHITE_LIST, just ignore it and
-  // replace it with a div element.
-  var WHITE_LIST = []
-  
-  function RootComponent(data, nodeType) {
-    var id = data.rootId + '-root'
-    var componentManager = ComponentManager.getInstance(data.instanceId)
-  
-    // Return a NodeType instance.
-    if (nodeType && nodeType !== 'div' && WHITE_LIST.indexOf(nodeType) === -1) {
-      data.type = nodeType
-      var cmp = componentManager.createElement(data)
-      cmp.node.id = id
-      return cmp
-    }
-  
-    // Otherwise return a common weex-container component,
-    // whose node is a div element.
-    var node = document.createElement('div')
-    this.data = data
-    this.node = node
-  
-    this.createChildren()
-    this.updateAttrs(this.data.attr)
-    // issue: when add element to a list in lifetime hook 'ready', the
-    // styles is set to the classStyle, not style. This is a issue
-    // that jsframework should do something about.
-    var classStyle = this.data.classStyle
-    classStyle && this.updateStyle(this.data.classStyle)
-    this.updateStyle(this.data.style)
-    this.bindEvents(this.data.event)
-  }
-  
-  RootComponent.prototype = Object.create(Component.prototype)
-  
-  module.exports = RootComponent
-
-
-/***/ },
-/* 23 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  __webpack_require__(24)
-  
-  var Component = __webpack_require__(16)
-  
-  function Container (data, nodeType) {
-    Component.call(this, data, nodeType)
-    this.node.classList.add('weex-container')
-  }
-  
-  Container.prototype = Object.create(Component.prototype)
-  
-  module.exports = Container
-
-
-/***/ },
-/* 24 */
-/***/ function(module, exports, __webpack_require__) {
-
-  // style-loader: Adds some css to the DOM by adding a <style> tag
-  
-  // load the styles
-  var content = __webpack_require__(25);
-  if(typeof content === 'string') content = [[module.id, content, '']];
-  // add the styles to the DOM
-  var update = __webpack_require__(4)(content, {});
-  if(content.locals) module.exports = content.locals;
-  // Hot Module Replacement
-  if(false) {
-    // When the styles change, update the <style> tags
-    if(!content.locals) {
-      module.hot.accept("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./container.scss", function() {
-        var newContent = require("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./container.scss");
-        if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
-        update(newContent);
-      });
-    }
-    // When the module is disposed, remove the <style> tags
-    module.hot.dispose(function() { update(); });
-  }
-
-/***/ },
-/* 25 */
-/***/ function(module, exports, __webpack_require__) {
-
-  exports = module.exports = __webpack_require__(3)();
-  // imports
-  
-  
-  // module
-  exports.push([module.id, ".weex-container {\n  box-sizing: border-box;\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: flex;\n  -webkit-box-orient: vertical;\n  -webkit-flex-direction: column;\n  flex-direction: column;\n  position: relative;\n  border: 0 solid black;\n  margin: 0;\n  padding: 0; }\n\n.weex-element {\n  box-sizing: border-box;\n  position: relative; }\n", "", {"version":3,"sources":["/./src/src/styles/container.scss"],"names":[],"mappings":"AAAA;EACE,uBAAsB;EACtB,qBAAoB;EACpB,sBAAqB;EACrB,cAAa;EACb,6BAA4B;EAC5B,+BAA8B;EAC9B,uBAAsB;EACtB,mBAAkB;EAClB,sBAAqB;EACrB,UAAS;EACT,WACD,EAAC;;AAEF;EACE,uBAAuB;EACvB,mBAAmB,EACpB","file":"container.scss","sourcesContent":[".weex-container {\n  box-sizing:border-box;\n  display:-webkit-box;\n  display:-webkit-flex;\n  display:flex;\n  -webkit-box-orient:vertical;\n  -webkit-flex-direction:column;\n  flex-direction:column;\n  position:relative;\n  border:0 solid black;\n  margin:0;\n  padding:0\n}\n\n.weex-element {\n  box-sizing: border-box;\n  position: relative;\n}"],"sourceRoot":"webpack://"}]);
-  
-  // exports
-
-
-/***/ },
-/* 26 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  var Atomic = __webpack_require__(27)
-  var LazyLoad = __webpack_require__(12)
-  var config = __webpack_require__(5)
-  
-  var DEFAULT_SIZE = 200
-  var RESIZE_MODES = ['cover', 'contain'] // not temporarily supported
-  
-  /**
-   * resize=cover|contain|stretch v1.4 temporarily not supported
-   * src=url
-   */
-  
-  function Image (data) {
-    this.width = data.style && data.style.width
-                 ? (data.style.width + '').replace(/[^\d]/g, '')
-                 : DEFAULT_SIZE
-    this.height = data.style && data.style.height
-                 ? (data.style.height + '').replace(/[^\d]/g, '')
-                 : DEFAULT_SIZE
-    this.width *= data.scale
-    this.height *= data.scale
-    var mode
-    var attr = data.attr
-    attr && (mode = attr.resize || attr.resizeMode)
-    if (RESIZE_MODES.indexOf(mode) !== -1) {
-      this.mode = mode
-      // TODO: resize-mode is not temporarily supported.
-    }
-    Atomic.call(this, data)
-  }
-  
-  Image.prototype = Object.create(Atomic.prototype)
-  
-  Image.prototype.create = function () {
-    var node = document.createElement('img')
-    node.classList.add('weex-element')
-    node.style.display = 'block'
-    node.style.outline = 'none'
-    return node
-  }
-  
-  Image.prototype.attr = {
-    src: function (value) {
-      if (!this.node.src) {
-        this.node.src = lib.img.defaultSrc
-      }
-      LazyLoad.makeImageLazy(this.node, value)
-    }
-  }
-  
-  Image.prototype.clearAttr = function () {
-    this.node.src = ''
-  }
-  
-  module.exports = Image
-
-
-/***/ },
-/* 27 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  var Component = __webpack_require__(16)
-  
-  // Component which can have no subcomponents.
-  // This component should not be instantiated directly, since
-  // it is designed to be used as a base class to extend from.
-  function Atomic (data) {
-    Component.call(this, data)
-  }
-  
-  Atomic.prototype = Object.create(Component.prototype)
-  
-  Atomic.prototype.appendChild = function (data) {
-    // do nothing
-    return
-  }
-  
-  Atomic.prototype.insertBefore = function (child, before) {
-    // do nothing
-    return
-  }
-  
-  Atomic.prototype.removeChild = function (child) {
-    // do nothing
-    return
-  }
-  
-  module.exports = Atomic
-
-
-/***/ },
-/* 28 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  var Atomic = __webpack_require__(16)
-  var utils = __webpack_require__(7)
-  
-  var DEFAULT_FONT_SIZE = 32
-  
-  // attr
-  //  - value: text content.
-  //  - lines: maximum lines of the text.
-  function Text (data) {
-    Atomic.call(this, data)
-  }
-  
-  Text.prototype = Object.create(Atomic.prototype)
-  
-  Text.prototype.create = function () {
-    var node = document.createElement('div')
-    node.classList.add('weex-container')
-    node.style.fontSize = DEFAULT_FONT_SIZE * this.data.scale + 'px'
-    this.textNode = document.createElement('span')
-    // Give the developers the ability to control space
-    // and line-breakers.
-    this.textNode.style.whiteSpace = 'pre-wrap'
-    this.textNode.style.display = '-webkit-box'
-    this.textNode.style.webkitBoxOrient = 'vertical'
-    this.style.lines.call(this, this.data.style.lines)
-    node.appendChild(this.textNode)
-    return node
-  }
-  
-  Text.prototype.attr = {
-    value: function (value) {
-      var span = this.node.firstChild
-      span.innerHTML = ''
-      if (!value) {
-        return
-      }
-      span.textContent = value
-      /**
-       * Developers are supposed to have the ability to break text
-       * lines manually. Using ``&nbsp;`` to replace text space is
-       * not compatible with the ``-webkit-line-clamp``. Therefor
-       * we use ``white-space: no-wrap`` instead (instead of the
-       * code bellow).
-  
-        var frag = document.createDocumentFragment()
-          text.split(' ').forEach(function(str) {
-            var textNode = document.createTextNode(str)
-            var space = document.createElement('i')
-            space.innerHTML = '&nbsp;'
-            frag.appendChild(space)
-            frag.appendChild(textNode)
-          })
-          frag.removeChild(frag.firstChild)
-          span.appendChild(document.createElement('br'))
-          span.appendChild(frag)
-        })
-        span.removeChild(span.firstChild)
-       */
-    }
-  }
-  
-  Text.prototype.clearAttr = function () {
-    this.node.firstChild.textContent = ''
-  }
-  
-  Text.prototype.style = utils.extend(Object.create(Atomic.prototype.style), {
-  
-    lines: function (val) {
-      val = parseInt(val)
-      if (val !== val) { // NaN
-        return
-      }
-      if (val <= 0) {
-        this.textNode.style.textOverflow = ''
-        this.textNode.style.overflow = 'visible'
-        this.textNode.style.webkitLineClamp = ''
-      } else {
-        this.textNode.style.overflow = 'hidden'
-        this.textNode.style.textOverflow = 'ellipsis'
-        this.textNode.style.webkitLineClamp = lines
-      }
-    }
-  
-  })
-  
-  module.exports = Text
-
-
-/***/ },
-/* 29 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  __webpack_require__(30)
-  __webpack_require__(32)
-  
-  var Component = __webpack_require__(16)
-  var LazyLoad = __webpack_require__(12)
-  
-  var DEFAULT_LOAD_MORE_OFFSET = 500
-  
-  function List(data, nodeType) {
-    // this.loadmoreOffset = Number(data.attr.loadmoreoffset)
-    // this.isAvailableToFireloadmore = true
-    Component.call(this, data, nodeType)
-  }
-  
-  List.prototype = Object.create(Component.prototype)
-  
-  List.prototype.create = function (nodeType) {
-    var Scroll = lib.scroll
-    var node = Component.prototype.create.call(this, nodeType)
-    node.classList.add('weex-container', 'list-wrap')
-    this.listElement = document.createElement('div')
-    this.listElement.classList.add(
-      'weex-container'
-      , 'list-element'
-    )
-    node.appendChild(this.listElement)
-    this.scroller = new Scroll({
-      scrollElement: this.listElement
-      , direction: 'y'
-    })
-    this.scroller.init()
-    return node
-  }
-  
-  List.prototype.bindEvents = function (evts) {
-    Component.prototype.bindEvents.call(this, evts)
-    // to enable lazyload for Images.
-    this.scroller.addEventListener('scrolling', function (e) {
-      var so = e.scrollObj
-      this.dispatchEvent('scroll', {
-        originalType: 'scrolling',
-        scrollTop: so.getScrollTop(),
-        scrollLeft: so.getScrollLeft()
-      }, {
-        bubbles: true
-      })
-    }.bind(this))
-  
-    this.scroller.addEventListener('pullupend', function (e) {
-      this.dispatchEvent('loadmore')
-    }.bind(this))
-  }
-  
-  List.prototype.appendChild = function (data) {
-    var children = this.data.children
-    var componentManager = this.getComponentManager()
-    var child = componentManager.createElement(data)
-    this.listElement.appendChild(child.node)
-  
-    // update this.data.children
-    if (!children || !children.length) {
-      this.data.children = [data]
-    } else {
-      children.push(data)
-    }
-  
-    return child
-  }
-  
-  List.prototype.insertBefore = function (child, before) {
-    var children = this.data.children
-    var i = 0
-    var isAppend = false
-  
-    // update this.data.children
-    if (!children || !children.length || !before) {
-      isAppend = true
-    } else {
-      for (var l = children.length; i < l; i++) {
-        if (children[i].ref === child.data.ref) {
-          break
-        }
-      }
-      if (i === l) {
-        isAppend = true
-      }
-    }
-  
-    if (isAppend) {
-      this.listElement.appendChild(child.node)
-      children.push(child.data)
-    } else {
-      this.listElement.insertBefore(child.node, before.node)
-      children.splice(i, 0, child.data)
-    }
-  }
-  
-  List.prototype.removeChild = function (child) {
-    var children = this.data.children
-    // remove from this.data.children
-    var i = 0
-    var componentManager = this.getComponentManager()
-    if (children && children.length) {
-      for (var l = children.length; i < l; i++) {
-        if (children[i].ref === child.data.ref) {
-          break
-        }
-      }
-      if (i < l) {
-        children.splice(i, 1)
-      }
-    }
-    // remove from componentMap recursively
-    componentManager.removeElementByRef(child.data.ref)
-    this.listElement.removeChild(child.node)
-  }
-  
-  module.exports = List
-
-
-/***/ },
-/* 30 */
-/***/ function(module, exports, __webpack_require__) {
-
-  // style-loader: Adds some css to the DOM by adding a <style> tag
-  
-  // load the styles
-  var content = __webpack_require__(31);
-  if(typeof content === 'string') content = [[module.id, content, '']];
-  // add the styles to the DOM
-  var update = __webpack_require__(4)(content, {});
-  if(content.locals) module.exports = content.locals;
-  // Hot Module Replacement
-  if(false) {
-    // When the styles change, update the <style> tags
-    if(!content.locals) {
-      module.hot.accept("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./list.scss", function() {
-        var newContent = require("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./list.scss");
-        if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
-        update(newContent);
-      });
-    }
-    // When the module is disposed, remove the <style> tags
-    module.hot.dispose(function() { update(); });
-  }
-
-/***/ },
-/* 31 */
-/***/ function(module, exports, __webpack_require__) {
-
-  exports = module.exports = __webpack_require__(3)();
-  // imports
-  
-  
-  // module
-  exports.push([module.id, ".list-wrap {\n  display: block;\n  overflow: hidden; }\n\n.list-element {\n  -webkit-box-orient: vertical;\n  -webkit-flex-direction: column;\n  flex-direction: column; }\n", "", {"version":3,"sources":["/./src/src/styles/list.scss"],"names":[],"mappings":"AAAA;EACC,eAAe;EACf,iBAAiB,EACjB;;AAED;EACE,6BAA6B;EAC7B,+BAA+B;EAC/B,uBAAuB,EACxB","file":"list.scss","sourcesContent":[".list-wrap {\n\tdisplay: block;\n\toverflow: hidden;\n}\n\n.list-element {\n  -webkit-box-orient: vertical;\n  -webkit-flex-direction: column;\n  flex-direction: column;\n}"],"sourceRoot":"webpack://"}]);
-  
-  // exports
-
-
-/***/ },
-/* 32 */
-/***/ function(module, exports, __webpack_require__) {
-
-  (typeof window === 'undefined') && (window = {ctrl: {}, lib: {}});!window.ctrl && (window.ctrl = {});!window.lib && (window.lib = {});__webpack_require__(33);__webpack_require__(34);__webpack_require__(35);__webpack_require__(36);!function(a,b,c){function d(){b.scroll.outputDebugLog&&console.debug.apply(console,arguments)}function e(a){var b=a.getBoundingClientRect();if(!b){b={},b.width=a.offsetWidth,b.height=a.offsetHeight,b.left=a.offsetLeft,b.top=a.offsetTop;for(var c=a.offsetParent;c;)b.left+=c.offsetLeft,b.top+=c.offsetTop,c=c.offsetParent;b.right=b.left+b.width,b.bottom=b.top+b.height}return b}function f(a){return 0-a.options[a.axis+"PaddingTop"]}function g(a){var b=e(a.element),c=e(a.viewport),d=f(a);if("y"===a.axis)var g=0-b.height+c.height;else var g=0-b.width+c.width;return Math.min(g+a.options[a.axis+"PaddingBottom"],d)}function h(a,b){return b>a.minScrollOffset?b-a.minScrollOffset:b<a.maxScrollOffset?b-a.maxScrollOffset:void 0}function i(a,b){return b>a.minScrollOffset?b=a.minScrollOffset:b<a.maxScrollOffset&&(b=a.maxScrollOffset),b}function j(a,b,c){d(a.element.scrollId,b,c);var e=p.createEvent("HTMLEvents");if(e.initEvent(b,!1,!0),e.scrollObj=a,c)for(var f in c)e[f]=c[f];a.element.dispatchEvent(e),a.viewport.dispatchEvent(e)}function k(a){var b,c={x:0,y:0},d=getComputedStyle(a.element)[y+"Transform"];return"none"!==d&&(b=d.match(/^matrix3d\((?:[-\d.]+,\s*){12}([-\d.]+),\s*([-\d.]+)(?:,\s*[-\d.]+){2}\)/)||d.match(/^matrix\((?:[-\d.]+,\s*){4}([-\d.]+),\s*([-\d.]+)\)$/))&&(c.x=parseFloat(b[1])||0,c.y=parseFloat(b[2])||0),c}function l(a,b){return a=parseFloat(a),b=parseFloat(b),0!=a&&(a+="px"),0!=b&&(b+="px"),A?"translate3d("+a+", "+b+", 0)":"translate("+a+", "+b+")"}function m(a,b,c){""===b&&""===c?a.element.style[y+"Transition"]="":a.element.style[y+"Transition"]=x+"transform "+b+" "+c+" 0s"}function n(a,b){var c=0,d=0;"object"==typeof b?(c=b.x,d=b.y):"y"===a.axis?d=b:c=b,a.element.style[y+"Transform"]=l(c,d)}function o(a,c){function l(a){return F||L?(a.preventDefault(),a.stopPropagation(),!1):!0}function o(a){F||L||setTimeout(function(){var b=document.createEvent("HTMLEvents");b.initEvent("niceclick",!0,!0),a.target.dispatchEvent(b)},300)}function p(a,c){I=null,clearTimeout(J),J=setTimeout(function(){I&&(I=null,b.animation.requestFrame(a))},c||400),I=a}function q(a){if(!E.enabled)return!1;if("undefined"!=typeof a.isVertical){if(!("y"===E.axis&&a.isVertical||"x"===E.axis&&!a.isVertical))return!1;a.stopPropagation()}return!0}function t(a){if(q(a))if(L&&D(),c.useFrameAnimation)H&&H.stop(),H=null;else{var b=k(E);n(E,b),m(E,"",""),I=null,clearTimeout(J)}}function w(a){if(q(a)){var d=k(E)[E.axis],e=h(E,d);if(e){var f=i(E,d);if(c.useFrameAnimation){var g=f-d;H=new b.animation(400,b.cubicbezier.ease,0,function(a,b){var c=(d+g*b).toFixed(2);n(E,c),j(E,"scrolling")}),H.onend(D),H.play()}else{var l=f.toFixed(0);m(E,"0.4s","ease"),n(E,l),p(D,400),b.animation.requestFrame(function(){L&&E.enabled&&(j(E,"scrolling"),b.animation.requestFrame(arguments.callee))})}e>0?j(E,"y"===E.axis?"pulldownend":"pullrightend"):0>e&&j(E,"y"===E.axis?"pullupend":"pullleftend")}else L&&D()}}function x(a){q(a)&&(E.transformOffset=k(E),E.minScrollOffset=f(E),E.maxScrollOffset=g(E),K=2.5,N=!0,L=!0,M=!1,j(E,"scrollstart"),O=a["displacement"+E.axis.toUpperCase()])}function z(a){if(q(a)){var b=a["displacement"+E.axis.toUpperCase()];if(Math.abs(b-O)<5)return void a.stopPropagation();O=b;var c=E.transformOffset[E.axis]+b;c>E.minScrollOffset?(c=E.minScrollOffset+(c-E.minScrollOffset)/K,K*=1.003):c<E.maxScrollOffset&&(c=E.maxScrollOffset-(E.maxScrollOffset-c)/K,K*=1.003),K>4&&(K=4);var d=h(E,c);d&&(j(E,d>0?"y"===E.axis?"pulldown":"pullright":"y"===E.axis?"pullup":"pullleft",{boundaryOffset:Math.abs(d)}),E.options.noBounce&&(c=i(E,c))),n(E,c.toFixed(2)),j(E,"scrolling")}}function A(a){q(a)&&a.isflick&&C(a)}function C(a){N=!0;var e,f,g,i,l,o,q,r,s,t,v,w,x,y,z,A,B;i=k(E)[E.axis];var C=h(E,i);if(!C){e=a["velocity"+E.axis.toUpperCase()];var F=2,G=.0015;c.inertia&&u[c.inertia]&&(F=u[c.inertia][0],G=u[c.inertia][1]),e>F&&(e=F),-F>e&&(e=-F),f=G*(e/Math.abs(e)),o=new b.motion({v:e,a:-f}),g=o.t,l=i+o.s;var I=h(E,l);if(I){d("惯性计算超出了边缘",I),q=e,r=f,I>0?(t=E.minScrollOffset,w=1):(t=E.maxScrollOffset,w=-1),v=new b.motion({v:w*q,a:-w*r,s:Math.abs(t-i)}),s=v.t;var J=v.generateCubicBezier();x=q-r*s,y=.03*(x/Math.abs(x)),B=new b.motion({v:x,a:-y}),z=B.t,A=t+B.s;B.generateCubicBezier();if(c.noBounce)if(d("没有回弹效果"),i!==t)if(c.useFrameAnimation){var K=t-i,O=b.cubicbezier(J[0][0],J[0][1],J[1][0],J[1][1]);H=new b.animation(s.toFixed(0),O,0,function(a,b){var c=i+K*b;k(E,c.toFixed(2)),j(E,"scrolling",{afterFlick:!0})}),H.onend(D),H.play()}else{var P=t.toFixed(0);m(E,(s/1e3).toFixed(2)+"s","cubic-bezier("+J+")"),n(E,P),p(D,1e3*(s/1e3).toFixed(2))}else D();else if(i!==A)if(d("惯性滚动","s="+A.toFixed(0),"t="+((s+z)/1e3).toFixed(2)),c.useFrameAnimation){var K=A-i,O=b.cubicbezier.easeOut;H=new b.animation((s+z).toFixed(0),O,0,function(a,b){var c=i+K*b;n(E,c.toFixed(2)),j(E,"scrolling",{afterFlick:!0})}),H.onend(function(){if(E.enabled){var a=t-A,c=b.cubicbezier.ease;H=new b.animation(400,c,0,function(b,c){var d=A+a*c;n(E,d.toFixed(2)),j(E,"scrolling",{afterFlick:!0})}),H.onend(D),H.play()}}),H.play()}else{var P=A.toFixed(0);m(E,((s+z)/1e3).toFixed(2)+"s","ease-out"),n(E,P),p(function(a){if(E.enabled)if(d("惯性回弹","s="+t.toFixed(0),"t=400"),A!==t){var b=t.toFixed(0);m(E,"0.4s","ease"),n(E,b),p(D,400)}else D()},1e3*((s+z)/1e3).toFixed(2))}else D()}else{d("惯性计算没有超出边缘");var Q=o.generateCubicBezier();if(c.useFrameAnimation){var K=l-i,O=b.cubicbezier(Q[0][0],Q[0][1],Q[1][0],Q[1][1]);H=new b.animation(g.toFixed(0),O,0,function(a,b){var c=(i+K*b).toFixed(2);n(E,c),j(E,"scrolling",{afterFlick:!0})}),H.onend(D),H.play()}else{var P=l.toFixed(0);m(E,(g/1e3).toFixed(2)+"s","cubic-bezier("+Q+")"),n(E,P),p(D,1e3*(g/1e3).toFixed(2))}}M=!0,c.useFrameAnimation||b.animation.requestFrame(function(){L&&M&&E.enabled&&(j(E,"scrolling",{afterFlick:!0}),b.animation.requestFrame(arguments.callee))})}}function D(){E.enabled&&(N=!1,setTimeout(function(){!N&&L&&(L=!1,M=!1,c.useFrameAnimation?(H&&H.stop(),H=null):m(E,"",""),j(E,"scrollend"))},50))}var E=this;if(c=c||{},c.noBounce=!!c.noBounce,c.padding=c.padding||{},null==c.isPrevent?c.isPrevent=!0:c.isPrevent=!!c.isPrevent,null==c.isFixScrollendClick?c.isFixScrollendClick=!0:c.isFixScrollendClick=!!c.isFixScrollendClick,c.padding?(c.yPaddingTop=-c.padding.top||0,c.yPaddingBottom=-c.padding.bottom||0,c.xPaddingTop=-c.padding.left||0,c.xPaddingBottom=-c.padding.right||0):(c.yPaddingTop=0,c.yPaddingBottom=0,c.xPaddingTop=0,c.xPaddingBottom=0),c.direction=c.direction||"y",c.inertia=c.inertia||"normal",this.options=c,E.axis=c.direction,this.element=a,this.viewport=a.parentNode,this.plugins={},this.element.scrollId=setTimeout(function(){r[E.element.scrollId+""]=E},1),this.viewport.addEventListener("touchstart",t,!1),this.viewport.addEventListener("touchend",w,!1),this.viewport.addEventListener("touchcancel",w,!1),this.viewport.addEventListener("panstart",x,!1),this.viewport.addEventListener("panmove",z,!1),this.viewport.addEventListener("panend",A,!1),c.isPrevent&&(this.viewport.addEventListener("touchstart",function(a){B=!0},!1),E.viewport.addEventListener("touchend",function(a){B=!1},!1)),c.isFixScrollendClick){var F,G;this.viewport.addEventListener("scrolling",function(){F=!0,G&&clearTimeout(G),G=setTimeout(function(a){F=!1},400)},!1),this.viewport.addEventListener("click",l,!1),this.viewport.addEventListener("tap",o,!1)}if(c.useFrameAnimation){var H;Object.defineProperty(this,"animation",{get:function(){return H}})}else{var I,J=0;a.addEventListener(v?"transitionend":y+"TransitionEnd",function(a){if(I){var c=I;I=null,clearTimeout(J),b.animation.requestFrame(function(){c(a)})}},!1)}var K,L,M,N;Object.defineProperty(this,"isScrolling",{get:function(){return!!L}});var O,P={init:function(){return this.enable(),this.refresh(),this.scrollTo(0),this},enable:function(){return this.enabled=!0,this},disable:function(){var a=this.element;return this.enabled=!1,this.options.useFrameAnimation?H&&H.stop():b.animation.requestFrame(function(){a.style[y+"Transform"]=getComputedStyle(a)[y+"Transform"]}),this},getScrollWidth:function(){return e(this.element).width},getScrollHeight:function(){return e(this.element).height},getScrollLeft:function(){return-k(this).x-this.options.xPaddingTop},getScrollTop:function(){return-k(this).y-this.options.yPaddingTop},getMaxScrollLeft:function(){return-E.maxScrollOffset-this.options.xPaddingTop},getMaxScrollTop:function(){return-E.maxScrollOffset-this.options.yPaddingTop},getBoundaryOffset:function(){return Math.abs(h(this,k(this)[this.axis])||0)},refresh:function(){var a=this.element,b="y"===this.axis,c=b?"height":"width";if(null!=this.options[c])a.style[c]=this.options[c]+"px";else if(this.options.useElementRect)a.style[c]="auto",a.style[c]=e(a)[c]+"px";else if(a.childElementCount>0){var d,h,i=a.firstElementChild,l=a.lastElementChild;if(document.createRange&&!this.options.ignoreOverflow&&(d=document.createRange(),d.selectNodeContents(a),h=e(d)),h)a.style[c]=h[c]+"px";else{for(;i&&0===e(i)[c]&&i.nextElementSibling;)i=i.nextElementSibling;for(;l&&l!==i&&0===e(l)[c]&&l.previousElementSibling;)l=l.previousElementSibling;a.style[c]=e(l)[b?"bottom":"right"]-e(i)[b?"top":"left"]+"px"}}return this.transformOffset=k(this),this.minScrollOffset=f(this),this.maxScrollOffset=g(this),this.scrollTo(-this.transformOffset[this.axis]-this.options[this.axis+"PaddingTop"]),j(this,"contentrefresh"),this},offset:function(a){var b=e(this.element),c=e(a);if("y"===this.axis){var d={top:c.top-b.top-this.options.yPaddingTop,left:c.left-b.left,right:b.right-c.right,width:c.width,height:c.height};d.bottom=d.top+d.height}else{var d={top:c.top-b.top,bottom:b.bottom-c.bottom,left:c.left-b.left-this.options.xPaddingTop,width:c.width,height:c.height};d.right=d.left+d.width}return d},getRect:function(a){var b=e(this.viewport),c=e(a);if("y"===this.axis){var d={top:c.top-b.top,left:c.left-b.left,right:b.right-c.right,width:c.width,height:c.height};d.bottom=d.top+d.height}else{var d={top:c.top-b.top,bottom:b.bottom-c.bottom,left:c.left-b.left,width:c.width,height:c.height};d.right=d.left+d.width}return d},isInView:function(a){var b=this.getRect(this.viewport),c=this.getRect(a);return"y"===this.axis?b.top<c.bottom&&b.bottom>c.top:b.left<c.right&&b.right>c.left},scrollTo:function(a,c){var d=this;this.element;if(a=-a-this.options[this.axis+"PaddingTop"],a=i(this,a),L=!0,c===!0)if(this.options.useFrameAnimation){var e=k(d)[this.axis],f=a-e;H=new b.animation(400,b.cubicbezier.ease,0,function(a,b){var c=(e+f*b).toFixed(2);n(d,c),j(d,"scrolling")}),H.onend(D),H.play()}else m(d,"0.4s","ease"),n(d,a),p(D,400),b.animation.requestFrame(function(){L&&d.enabled&&(j(d,"scrolling"),b.animation.requestFrame(arguments.callee))});else this.options.useFrameAnimation||m(d,"",""),n(d,a),D();return this},scrollToElement:function(a,b){var c=this.offset(a);return c=c["y"===this.axis?"top":"left"],this.scrollTo(c,b)},getViewWidth:function(){return e(this.viewport).width},getViewHeight:function(){return e(this.viewport).height},addPulldownHandler:function(a){var b=this;return this.element.addEventListener("pulldownend",function(c){b.disable(),a.call(b,c,function(){b.scrollTo(0,!0),b.refresh(),b.enable()})},!1),this},addPullupHandler:function(a){var b=this;return this.element.addEventListener("pullupend",function(c){b.disable(),a.call(b,c,function(){b.scrollTo(b.getScrollHeight(),!0),b.refresh(),b.enable()})},!1),this},addScrollstartHandler:function(a){var b=this;return this.element.addEventListener("scrollstart",function(c){a.call(b,c)},!1),this},addScrollingHandler:function(a){var b=this;return this.element.addEventListener("scrolling",function(c){a.call(b,c)},!1),this},addScrollendHandler:function(a){var b=this;return this.element.addEventListener("scrollend",function(c){a.call(b,c)},!1),this},addContentrenfreshHandler:function(a){var b=this;this.element.addEventListener("contentrefresh",function(c){a.call(b,c)},!1)},addEventListener:function(a,b,c){var d=this;this.element.addEventListener(a,function(a){b.call(d,a)},!!c)},removeEventListener:function(a,b){var c=this;this.element.removeEventListener(a,function(a){b.call(c,a)})},enablePlugin:function(a,b){var c=s[a];return c&&!this.plugins[a]&&(this.plugins[a]=!0,b=b||{},c.call(this,a,b)),this}};for(var Q in P)this[Q]=P[Q];delete P}var p=a.document,q=a.navigator.userAgent,r={},s={},t=a.dpr||(a.navigator.userAgent.match(/iPhone|iPad|iPod/)?document.documentElement.clientWidth/a.screen.availWidth:1),u={normal:[2*t,.0015*t],slow:[1.5*t,.003*t],veryslow:[1.5*t,.005*t]},v=!!q.match(/Firefox/i),w=!!q.match(/IEMobile/i),x=v?"-moz-":w?"-ms-":"-webkit-",y=v?"Moz":w?"ms":"webkit",z=w?"MSCSSMatrix":"WebKitCSSMatrix",A=!!v||z in a&&"m11"in new a[z],B=!1;p.addEventListener("touchmove",function(a){return B?(a.preventDefault(),!1):!0},!1),b.scroll=function(a,c){if(1===arguments.length&&!(arguments[0]instanceof HTMLElement))if(c=arguments[0],c.scrollElement)a=c.scrollElement;else{if(!c.scrollWrap)throw new Error("no scroll element");a=c.scrollWrap.firstElementChild}if(!a.parentNode)throw new Error("wrong dom tree");if(c&&c.direction&&["x","y"].indexOf(c.direction)<0)throw new Error("wrong direction");var d;return d=c.downgrade===!0&&b.scroll.downgrade?b.scroll.downgrade(a,c):a.scrollId?r[a.scrollId]:new o(a,c)},b.scroll.plugin=function(a,b){return b?(a=a.split(","),void a.forEach(function(a){s[a]=b})):s[a]}}(window,window.lib||(window.lib={}));;module.exports = window.lib['scroll'];
-
-/***/ },
-/* 33 */
-/***/ function(module, exports) {
-
-  (typeof window === 'undefined') && (window = {ctrl: {}, lib: {}});!window.ctrl && (window.ctrl = {});!window.lib && (window.lib = {});!function(a,b){function c(a){return setTimeout(a,l)}function d(a){clearTimeout(a)}function e(){var a={},b=new m(function(b,c){a.resolve=b,a.reject=c});return a.promise=b,a}function f(a,b){return["then","catch"].forEach(function(c){b[c]=function(){return a[c].apply(a,arguments)}}),b}function g(b){var c,d,h=!1;this.request=function(){h=!1;var g=arguments;return c=e(),f(c.promise,this),d=n(function(){h||c&&c.resolve(b.apply(a,g))}),this},this.cancel=function(){return d&&(h=!0,o(d),c&&c.reject("CANCEL")),this},this.clone=function(){return new g(b)}}function h(a,b){"function"==typeof b&&(b={0:b});for(var c=a/l,d=1/c,e=[],f=Object.keys(b).map(function(a){return parseInt(a)}),h=0;c>h;h++){var i=f[0],j=d*h;if(null!=i&&100*j>=i){var k=b[""+i];k instanceof g||(k=new g(k)),e.push(k),f.shift()}else e.length&&e.push(e[e.length-1].clone())}return e}function i(a){var c;return"string"==typeof a||a instanceof Array?b.cubicbezier?"string"==typeof a?b.cubicbezier[a]&&(c=b.cubicbezier[a]):a instanceof Array&&4===a.length&&(c=b.cubicbezier.apply(b.cubicbezier,a)):console.error("require lib.cubicbezier"):"function"==typeof a&&(c=a),c}function j(a,b,c){var d,g=h(a,c),j=1/(a/l),k=0,m=i(b);if(!m)throw new Error("unexcept timing function");var n=!1;this.play=function(){function a(){var c=j*(k+1).toFixed(10),e=g[k];e.request(c.toFixed(10),b(c).toFixed(10)).then(function(){n&&(k===g.length-1?(n=!1,d&&d.resolve("FINISH"),d=null):(k++,a()))},function(){})}if(!n)return n=!0,d||(d=e(),f(d.promise,this)),a(),this},this.stop=function(){return n?(n=!1,g[k]&&g[k].cancel(),this):void 0}}var k=60,l=1e3/k,m=a.Promise||b.promise&&b.promise.ES6Promise,n=window.requestAnimationFrame||window.msRequestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||c,o=window.cancelAnimationFrame||window.msCancelAnimationFrame||window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||d;(n===c||o===d)&&(n=c,o=d),b.animation=function(a,b,c){return new j(a,b,c)},b.animation.frame=function(a){return new g(a)},b.animation.requestFrame=function(a){var b=new g(a);return b.request()}}(window,window.lib||(window.lib={}));;module.exports = window.lib['animation'];
-
-/***/ },
-/* 34 */
-/***/ function(module, exports) {
-
-  (typeof window === 'undefined') && (window = {ctrl: {}, lib: {}});!window.ctrl && (window.ctrl = {});!window.lib && (window.lib = {});!function(a,b){function c(a,b,c,d){function e(a){return(3*k*a+2*l)*a+m}function f(a){return((k*a+l)*a+m)*a}function g(a){return((n*a+o)*a+p)*a}function h(a){for(var b,c,d=a,g=0;8>g;g++){if(c=f(d)-a,Math.abs(c)<j)return d;if(b=e(d),Math.abs(b)<j)break;d-=c/b}var h=1,i=0;for(d=a;h>i;){if(c=f(d)-a,Math.abs(c)<j)return d;c>0?h=d:i=d,d=(h+i)/2}return d}function i(a){return g(h(a))}var j=1e-6,k=3*a-3*c+1,l=3*c-6*a,m=3*a,n=3*b-3*d+1,o=3*d-6*b,p=3*b;return i}b.cubicbezier=c,b.cubicbezier.linear=c(0,0,1,1),b.cubicbezier.ease=c(.25,.1,.25,1),b.cubicbezier.easeIn=c(.42,0,1,1),b.cubicbezier.easeOut=c(0,0,.58,1),b.cubicbezier.easeInOut=c(.42,0,.58,1)}(window,window.lib||(window.lib={}));;module.exports = window.lib['cubicbezier'];
-
-/***/ },
-/* 35 */
-/***/ function(module, exports) {
-
-  (typeof window === 'undefined') && (window = {ctrl: {}, lib: {}});!window.ctrl && (window.ctrl = {});!window.lib && (window.lib = {});!function(a){"use strict";function b(a,b){for(var c=a;c;){if(c.contains(b)||c==b)return c;c=c.parentNode}return null}function c(a,b,c){var d=i.createEvent("HTMLEvents");if(d.initEvent(b,!0,!0),"object"==typeof c)for(var e in c)d[e]=c[e];a.dispatchEvent(d)}function d(a,b,c,d,e,f,g,h){var i=Math.atan2(h-f,g-e)-Math.atan2(d-b,c-a),j=Math.sqrt((Math.pow(h-f,2)+Math.pow(g-e,2))/(Math.pow(d-b,2)+Math.pow(c-a,2))),k=[e-j*a*Math.cos(i)+j*b*Math.sin(i),f-j*b*Math.cos(i)-j*a*Math.sin(i)];return{rotate:i,scale:j,translate:k,matrix:[[j*Math.cos(i),-j*Math.sin(i),k[0]],[j*Math.sin(i),j*Math.cos(i),k[1]],[0,0,1]]}}function e(a){0===Object.keys(l).length&&(j.addEventListener("touchmove",f,!1),j.addEventListener("touchend",g,!1),j.addEventListener("touchcancel",h,!1));for(var d=0;d<a.changedTouches.length;d++){var e=a.changedTouches[d],i={};for(var m in e)i[m]=e[m];var n={startTouch:i,startTime:Date.now(),status:"tapping",element:a.srcElement||a.target,pressingHandler:setTimeout(function(b,d){return function(){"tapping"===n.status&&(n.status="pressing",c(b,"longpress",{touch:d,touches:a.touches,changedTouches:a.changedTouches,touchEvent:a})),clearTimeout(n.pressingHandler),n.pressingHandler=null}}(a.srcElement||a.target,a.changedTouches[d]),500)};l[e.identifier]=n}if(2==Object.keys(l).length){var o=[];for(var m in l)o.push(l[m].element);c(b(o[0],o[1]),"dualtouchstart",{touches:k.call(a.touches),touchEvent:a})}}function f(a){for(var e=0;e<a.changedTouches.length;e++){var f=a.changedTouches[e],g=l[f.identifier];if(!g)return;g.lastTouch||(g.lastTouch=g.startTouch),g.lastTime||(g.lastTime=g.startTime),g.velocityX||(g.velocityX=0),g.velocityY||(g.velocityY=0),g.duration||(g.duration=0);var h=Date.now()-g.lastTime,i=(f.clientX-g.lastTouch.clientX)/h,j=(f.clientY-g.lastTouch.clientY)/h,k=70;h>k&&(h=k),g.duration+h>k&&(g.duration=k-h),g.velocityX=(g.velocityX*g.duration+i*h)/(g.duration+h),g.velocityY=(g.velocityY*g.duration+j*h)/(g.duration+h),g.duration+=h,g.lastTouch={};for(var m in f)g.lastTouch[m]=f[m];g.lastTime=Date.now();var n=f.clientX-g.startTouch.clientX,o=f.clientY-g.startTouch.clientY,p=Math.sqrt(Math.pow(n,2)+Math.pow(o,2));("tapping"===g.status||"pressing"===g.status)&&p>10&&(g.status="panning",g.isVertical=!(Math.abs(n)>Math.abs(o)),c(g.element,"panstart",{touch:f,touches:a.touches,changedTouches:a.changedTouches,touchEvent:a,isVertical:g.isVertical}),c(g.element,(g.isVertical?"vertical":"horizontal")+"panstart",{touch:f,touchEvent:a})),"panning"===g.status&&(g.panTime=Date.now(),c(g.element,"panmove",{displacementX:n,displacementY:o,touch:f,touches:a.touches,changedTouches:a.changedTouches,touchEvent:a,isVertical:g.isVertical}),g.isVertical?c(g.element,"verticalpanmove",{displacementY:o,touch:f,touchEvent:a}):c(g.element,"horizontalpanmove",{displacementX:n,touch:f,touchEvent:a}))}if(2==Object.keys(l).length){for(var q,r=[],s=[],t=[],e=0;e<a.touches.length;e++){var f=a.touches[e],g=l[f.identifier];r.push([g.startTouch.clientX,g.startTouch.clientY]),s.push([f.clientX,f.clientY])}for(var m in l)t.push(l[m].element);q=d(r[0][0],r[0][1],r[1][0],r[1][1],s[0][0],s[0][1],s[1][0],s[1][1]),c(b(t[0],t[1]),"dualtouch",{transform:q,touches:a.touches,touchEvent:a})}}function g(a){if(2==Object.keys(l).length){var d=[];for(var e in l)d.push(l[e].element);c(b(d[0],d[1]),"dualtouchend",{touches:k.call(a.touches),touchEvent:a})}for(var i=0;i<a.changedTouches.length;i++){var n=a.changedTouches[i],o=n.identifier,p=l[o];if(p){if(p.pressingHandler&&(clearTimeout(p.pressingHandler),p.pressingHandler=null),"tapping"===p.status&&(p.timestamp=Date.now(),c(p.element,"tap",{touch:n,touchEvent:a}),m&&p.timestamp-m.timestamp<300&&c(p.element,"doubletap",{touch:n,touchEvent:a}),m=p),"panning"===p.status){var q=Date.now(),r=q-p.startTime,s=((n.clientX-p.startTouch.clientX)/r,(n.clientY-p.startTouch.clientY)/r,n.clientX-p.startTouch.clientX),t=n.clientY-p.startTouch.clientY,u=Math.sqrt(p.velocityY*p.velocityY+p.velocityX*p.velocityX),v=u>.5&&q-p.lastTime<100,w={duration:r,isflick:v,velocityX:p.velocityX,velocityY:p.velocityY,displacementX:s,displacementY:t,touch:n,touches:a.touches,changedTouches:a.changedTouches,touchEvent:a,isVertical:p.isVertical};c(p.element,"panend",w),v&&(c(p.element,"swipe",w),p.isVertical?c(p.element,"verticalswipe",w):c(p.element,"horizontalswipe",w))}"pressing"===p.status&&c(p.element,"pressend",{touch:n,touchEvent:a}),delete l[o]}}0===Object.keys(l).length&&(j.removeEventListener("touchmove",f,!1),j.removeEventListener("touchend",g,!1),j.removeEventListener("touchcancel",h,!1))}function h(a){if(2==Object.keys(l).length){var d=[];for(var e in l)d.push(l[e].element);c(b(d[0],d[1]),"dualtouchend",{touches:k.call(a.touches),touchEvent:a})}for(var i=0;i<a.changedTouches.length;i++){var m=a.changedTouches[i],n=m.identifier,o=l[n];o&&(o.pressingHandler&&(clearTimeout(o.pressingHandler),o.pressingHandler=null),"panning"===o.status&&c(o.element,"panend",{touch:m,touches:a.touches,changedTouches:a.changedTouches,touchEvent:a}),"pressing"===o.status&&c(o.element,"pressend",{touch:m,touchEvent:a}),delete l[n])}0===Object.keys(l).length&&(j.removeEventListener("touchmove",f,!1),j.removeEventListener("touchend",g,!1),j.removeEventListener("touchcancel",h,!1))}var i=a.document,j=i.documentElement,k=Array.prototype.slice,l={},m=null;j.addEventListener("touchstart",e,!1)}(window);;module.exports = window.lib['gesturejs'];
-
-/***/ },
-/* 36 */
-/***/ function(module, exports) {
-
-  (typeof window === 'undefined') && (window = {ctrl: {}, lib: {}});!window.ctrl && (window.ctrl = {});!window.lib && (window.lib = {});!function(a,b){function c(a,b){return[[(a/3+(a+b)/3-a)/(b-a),(a*a/3+a*b*2/3-a*a)/(b*b-a*a)],[(b/3+(a+b)/3-a)/(b-a),(b*b/3+a*b*2/3-a*a)/(b*b-a*a)]]}function d(a){if(this.v=a.v||0,this.a=a.a||0,"undefined"!=typeof a.t&&(this.t=a.t),"undefined"!=typeof a.s&&(this.s=a.s),"undefined"==typeof this.t)if("undefined"==typeof this.s)this.t=-this.v/this.a;else{var b=(Math.sqrt(this.v*this.v+2*this.a*this.s)-this.v)/this.a,c=(-Math.sqrt(this.v*this.v+2*this.a*this.s)-this.v)/this.a;this.t=Math.min(b,c)}"undefined"==typeof this.s&&(this.s=this.a*this.t*this.t/2+this.v*this.t)}d.prototype.generateCubicBezier=function(){return c(this.v/this.a,this.t+this.v/this.a)},b.motion=d}(window,window.lib||(window.lib={}));;module.exports = window.lib['motion'];
-
-/***/ },
-/* 37 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  var Atomic = __webpack_require__(27)
-  __webpack_require__(38)
-  
-  var FORMATTER_REGEXP = /(\\)?(dd*|hh?|mm?|ss?)/gi
-  
-  function formatDateTime(data, formatter, timeColor) {
-    return formatter.replace(FORMATTER_REGEXP, function (m) {
-      var len = m.length
-      var firstChar = m.charAt(0)
-      // escape character
-      if (firstChar === '\\') {
-        return m.replace('\\', '')
-      }
-      var value = (firstChar === 'd' ? data.days :
-                  firstChar === 'h' ? data.hours :
-                  firstChar === 'm' ? data.minutes :
-                  firstChar === 's' ? data.seconds : 0) + ''
-  
-      // 5 zero should be enough
-      return '<span style="margin:4px;color:'
-        + timeColor + '" >'
-        + ('00000' + value).substr(-Math.max(value.length, len))
-        + '</span>'
-    })
-  }
-  
-  function Countdown (data) {
-    Atomic.call(this, data)
-  }
-  
-  Countdown.prototype = Object.create(Atomic.prototype)
-  
-  Countdown.prototype.create = function () {
-    var node = document.createElement('div')
-    node.classList.add('weex-element')
-    var data = this.data
-    var time = Number(data.attr.countdownTime) || 0
-    var endTime = Date.now() / 1000 + time
-    var cd = lib.countdown({
-      endDate: endTime,
-      onUpdate: function (time) {
-        var timeColor = data.style.timeColor || '#000'
-        var result = formatDateTime(time, data.attr.formatterValue, timeColor)
-        node.innerHTML = result
-      },
-      onEnd: function () {
-      }
-    }).start()
-  
-    return node
-  }
-  
-  Countdown.prototype.style = {
-    textColor: function (value) {
-      this.node.style.color = value
-    }
-  }
-  
-  module.exports = Countdown
-
-
-/***/ },
-/* 38 */
-/***/ function(module, exports) {
-
-  !function(a,b){function c(a){var b;if("number"==typeof a)b=new Date(1e3*a);else if("string"==typeof a){var c=a.charAt(0),d="+"===c,h="-"===c;if(d||h){for(var i,j=a.substr(1),k=j.split(":"),l=[0,0,0,0],m=4;k.length&&--m>=0;)l[m]=parseInt(k.pop())||0;i=e*l[0]+f*l[1]+g*l[2]+l[3],b=new Date,b.setSeconds(b.getSeconds()+i*(h?-1:1)),b.setMilliseconds(0)}}return b||(b=new Date(a)),b}function d(a,b){return b.replace(FORMATTER_REGEXP,function(b){var c=b.length,d=b.charAt(0);if("\\"===d)return b.replace("\\","");var e=("d"===d?a.days:"h"===d?a.hours:"m"===d?a.minutes:"s"===d?a.seconds:0)+"";return("00000"+e).substr(-Math.max(e.length,c))})}var e=86400,f=3600,g=60,h="d天hh时mm分ss秒";FORMATTER_REGEXP=/(\\)?(dd*|hh?|mm?|ss?)/gi;var i=function(a){a=a||{};var b=this,d=c(a.endDate);if(!d||!d.getTime())throw new Error("Invalid endDate");b.endDate=d,b.onUpdate=a.onUpdate,b.onEnd=a.onEnd,b.interval=a.interval||1e3,b.stringFormatter=a.stringFormatter||h,b.correctDateOffset=a.correctDateOffset||0,b.updateElement=a.updateElement,b._data={days:0,hours:0,minutes:0,seconds:0}};i.prototype={start:function(){var a=this;return a.stop(),a._update()&&(a._intervalId=setInterval(function(){a._update()},a.interval)),a},_update:function(){var a,b=this,c=b._data,h=b.updateElement,i=+new Date+1e3*b.correctDateOffset,j=Math.max(0,Math.round((b.endDate.getTime()-i)/1e3)),k=0>=j;return c.totalSeconds=j,j-=(c.days=Math.floor(j/e))*e,j-=(c.hours=Math.floor(j/f))*f,j-=(c.minutes=Math.floor(j/g))*g,c.seconds=j,c.stringValue=d(c,b.stringFormatter),h&&(h.innerHTML=c.stringValue),(a=b.onUpdate)&&a.call(b,c),k?(b.stop(),(a=b.onEnd)&&a.call(b),!1):!0},stop:function(){var a=this;return a._intervalId&&(clearInterval(a._intervalId),a._intervalId=null),a},setEndDate:function(a){var b=this;return b.endDate=c(a),b}},b.countdown=function(a){return new i(a)}}(window,window.lib||(window.lib={}));
-
-/***/ },
-/* 39 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  var config = __webpack_require__(5)
-  var Component = __webpack_require__(16)
-  var ComponentManager = __webpack_require__(9)
-  var LazyLoad = __webpack_require__(12)
-  
-  function Marquee (data) {
-    this.interval = Number(data.attr.interval) || 5 * 1000
-    this.transitionDuration = Number(data.attr.transitionDuration) || 500
-    this.delay = Number(data.attr.delay) || 0
-    Component.call(this, data)
-  }
-  
-  Marquee.prototype = Object.create(Component.prototype)
-  
-  Marquee.prototype.create = function () {
-    var node = document.createElement('div')
-    node.classList.add('weex-container')
-    node.style.overflow = 'hidden'
-    // fix page shaking during slider's playing
-    node.style.webkitTransform = 'translate3D(0,0,0)'
-    node.addEventListener('webkitTransitionEnd', this.end.bind(this), false)
-    return node
-  }
-  
-  Marquee.prototype.createChildren = function () {
-    // first run:
-    // - create each child
-    // - append to parentNode
-    // - find current and next
-    // - set current and next shown and others hidden
-    var children = this.data.children
-    var parentRef = this.data.ref
-    var instanceId = this.data.instanceId
-    var items = []
-    var componentManager = this.getComponentManager()
-  
-    var fragment, isFlex, child, node, i
-  
-    if (children && children.length) {
-      fragment = document.createDocumentFragment()
-      isFlex = false
-      for (i = 0; i < children.length; i++) {
-        children[i].scale = this.data.scale
-        children[i].instanceId = instanceId
-        child = componentManager.createElement(children[i])
-        child.parentRef = parentRef
-        this.initChild(child)
-        // append and push
-        items.push(child)
-        fragment.appendChild(child.node)
-        if (!isFlex && child.data.style.hasOwnProperty('flex')) {
-          isFlex = true
-        }
-      }
-      this.node.appendChild(fragment)
-    }
-  
-    // set items
-    this.items = items
-  
-    // reset the clock for first transition
-    this.reset()
-  }
-  
-  Marquee.prototype.initChild = function (child) {
-    var node = child.node
-    node.style.position = 'absolute'
-    node.style.top = '0'
-    node.style.left = '0'
-  }
-  
-  Marquee.prototype.appendChild = function (data) {
-    // dom + items
-    var componentManager = ComponentManager.getInstance(this.data.instanceId)
-    var child = componentManager.createElement(data)
-    this.initChild(child)
-    this.node.appendChild(child.node)
-    this.items.push(child)
-    this.reset()
-    return child // @todo redesign Component#appendChild(component)
-  }
-  
-  Marquee.prototype.insertBefore = function (child, before) {
-    // dom + items
-    var index = this.items.indexOf(before)
-    this.items.splice(index, 0, child)
-    this.initChild(child)
-    this.node.insertBefore(child.node, before.node)
-    this.reset()
-  }
-  
-  Marquee.prototype.removeChild = function (child) {
-    // dom + items
-    var index = this.items.indexOf(child)
-    this.items.splice(index, 1)
-    this.node.removeChild(child.node)
-    this.reset()
-  }
-  
-  /**
-   * status: {
-   *   current: {translateY: 0, shown: true},
-   *   next: {translateY: height, shown: true},
-   *   others[]: {shown: false}
-   *   index: index
-   * }
-   */
-  Marquee.prototype.reset = function () {
-    var interval = this.interval - 0
-    var delay = this.delay - 0
-    var items = this.items
-    var self = this
-  
-    var loop = function () {
-      self.next()
-      self.timerId = setTimeout(loop, self.interval)
-    }
-  
-    // reset display and transform
-    items.forEach(function (item, index) {
-      var node = item.node
-      // set non-current(0)|next(1) item hidden
-      node.style.display = index > 1 ? 'none' : ''
-      // set next(1) item translateY
-      // TODO: it supposed to use item.data.style
-      // but somehow the style object is empty.
-      // This problem relies on jsframework's bugfix.
-  
-      // node.style.transform = index === 1
-      //     ? 'translate3D(0,' + config.scale * item.data.style.height + 'px,0)'
-      //     : ''
-      // node.style.webkitTransform = index === 1
-      //     ? 'translate3D(0,' + config.scale * item.data.style.height + 'px,0)'
-      //     : ''
-      node.style.transform = index === 1
-          ? 'translate3D(0,' + self.data.scale * self.data.style.height + 'px,0)'
-          : ''
-      node.style.webkitTransform = index === 1
-          ? 'translate3D(0,' + self.data.scale * self.data.style.height + 'px,0)'
-          : ''
-    })
-  
-    setTimeout(function () {
-      // reset current, next, index
-      self.currentItem = items[0]
-      self.nextItem = items[1]
-      self.currentIndex = 0
-  
-      items.forEach(function (item, index) {
-        var node = item.node
-        // set transition
-        node.style.transition = 'transform '
-            + self.transitionDuration
-            + 'ms ease'
-        node.style.webkitTransition = '-webkit-transform '
-            + self.transitionDuration
-            + 'ms ease'
-      })
-  
-      clearTimeout(self.timerId)
-  
-      if (items.length > 1) {
-        self.timerId = setTimeout(loop, delay + interval)
-      }
-    }, 13)
-  
-  }
-  
-  /**
-   * next:
-   * - current: {translateY: -height}
-   * - next: {translateY: 0}
-   */
-  Marquee.prototype.next = function () {
-    // - update state
-    //   - set current and next transition
-    //   - hide current when transition end
-    //   - set next to current
-    //   - find new next
-    var next = this.nextItem.node
-    var current = this.currentItem.node
-    this.transitionIndex = this.currentIndex
-  
-    // Use setTimeout to fix the problem that when the
-    // page recover from backstage, the slider will
-    // not work any longer.
-    setTimeout(function () {
-      next.style.transform = 'translate3D(0,0,0)'
-      next.style.webkitTransform = 'translate3D(0,0,0)'
-      current.style.transform = 'translate3D(0,-'
-          + this.data.scale * this.data.style.height
-          + 'px,0)'
-      current.style.webkitTransform = 'translate3D(0,-'
-          + this.data.scale * this.data.style.height
-          + 'px,0)'
-      this.fireEvent('change')
-    }.bind(this), 300)
-  }
-  
-  Marquee.prototype.fireEvent = function (type) {
-    var length = this.items.length
-    var nextIndex = (this.currentIndex + 1) % length
-    var evt = document.createEvent('HTMLEvents')
-    evt.initEvent(type, false, false)
-    evt.data = {
-      prevIndex: this.currentIndex,
-      index: nextIndex
-    }
-    this.node.dispatchEvent(evt)
-  }
-  
-  /**
-   * end:
-   * - old current: {shown: false}
-   * - old current: {translateY: 0}
-   * - index++ % length
-   * - new current = old next
-   * - new next = items[index+1 % length]
-   * - new next: {translateY: height}
-   * - new next: {shown: true}
-   */
-  Marquee.prototype.end = function (e) {
-    var target = e.target
-    var items = this.items
-    var length = items.length
-    var current, next
-    var currentIndex, nextIndex
-  
-    currentIndex = this.transitionIndex
-  
-    if (isNaN(currentIndex)) {
-      return
-    }
-    delete this.transitionIndex
-  
-    current = this.currentItem.node
-    current.style.display = 'none'
-    current.style.webkitTransform = ''
-  
-    currentIndex = (currentIndex + 1) % length
-    nextIndex = (currentIndex + 1) % length
-  
-    this.currentIndex = currentIndex
-    this.currentItem = this.nextItem
-    this.nextItem = items[nextIndex]
-  
-    setTimeout(function () {
-      next = this.nextItem.node
-      // TODO: it supposed to use this.nextItem.data.style
-      // but somehow the style object is empty.
-      // This problem relies on jsframework's bugfix.
-  
-      next.style.webkitTransform = 'translate3D(0,'
-          + this.data.scale * this.data.style.height
-          + 'px,0)'
-      next.style.display = ''
-      LazyLoad.loadIfNeeded(next)
-    }.bind(this))
-  }
-  
-  Marquee.prototype.attr = {
-    interval: function (value) {
-      this.interval = value
-    },
-    transitionDuration: function (value) {
-      this.transitionDuration = value
-    },
-    delay: function (value) {
-      this.delay = value
-    }
-  }
-  
-  Marquee.prototype.clearAttr = function () {
-    this.interval = 5 * 1000
-    this.transitionDuration = 500
-    this.delay = 0
-  }
-  
-  module.exports = Marquee
-
-
-/***/ },
-/* 40 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  var extend = __webpack_require__(7).extend
-  var config = __webpack_require__(5)
-  var Component = __webpack_require__(16)
-  var ComponentManager = __webpack_require__(9)
-  var LazyLoad = __webpack_require__(12)
-  __webpack_require__(41)
-  __webpack_require__(42)
-  
-  function Slider (data) {
-    this.autoPlay = true  // always true for autoplay
-    this.direction = 'row' // 'column' is not temporarily supported.
-    this.children = []
-    this.isPageShow = true
-    this.isDomRendering = true
-  
-    // bind event 'pageshow' and 'pagehide' on window.
-    this._idleWhenPageDisappear()
-    // bind event 'renderBegin' and 'renderEnd' on window.
-    this._idleWhenDomRendering()
-  
-    Component.call(this, data)
-  }
-  
-  Slider.prototype = Object.create(Component.prototype)
-  
-  Slider.prototype._idleWhenPageDisappear = function () {
-    var _this = this
-    window.addEventListener('pageshow', function () {
-      _this.isPageShow = true
-      _this.autoPlay && !_this.isDomRendering && _this.play()
-    })
-    window.addEventListener('pagehide', function () {
-      _this.isPageShow = false
-      _this.stop()
-    })
-  }
-  
-  Slider.prototype._idleWhenDomRendering = function () {
-    var _this = this
-    window.addEventListener('renderend', function () {
-      _this.isDomRendering = false
-      _this.autoPlay && _this.isPageShow && _this.play()
-    })
-    window.addEventListener('renderbegin', function () {
-      _this.isDomRendering = true
-      _this.stop()
-    })
-  }
-  
-  Slider.prototype.attr = {
-    interval: function (val) {
-      this.interval = parseInt(val) || 3000
-      if (this.carrousel) {
-        this.carrousel.playInterval = this.interval
-      }
-    },
-  
-    playstatus: function (val) {
-      this.playstatus = val && val !== 'false' ? true : false
-      this.autoPlay = this.playstatus
-      if (this.carrousel) {
-        if (this.playstatus) {
-          this.play()
-        } else {
-          this.stop()
-        }
-      }
-    },
-  
-    // support playstatus' alias auto-play for compatibility
-    autoPlay: function (val) {
-      this.attr.playstatus.call(this, val)
-    }
-  }
-  
-  Slider.prototype.create = function () {
-    var node = document.createElement('div')
-    node.classList.add('slider')
-    node.style.position = 'relative'
-    node.style.overflow = 'hidden'
-    return node
-  }
-  
-  Slider.prototype._doRender = function () {
-    var _this = this
-    _this.createChildren()
-    _this.onAppend()
-  }
-  
-  Slider.prototype.removeChild = function (child) {
-    var children = this.data.children
-    if (children) {
-      for (var i = 0; i < children.length; i++) {
-        if (child.data.ref === children[i].ref) {
-          children.splice(i, 1)
-          break
-        }
-      }
-    }
-  
-    this._doRender()
-  }
-  
-  Slider.prototype.insertBefore = function (child, before) {
-    var children = this.data.children
-    // var childIndex = this.children.indexOf(before.data)
-    var childIndex = -1
-    for (var i = 0, l = children.length; i < l; i++) {
-      if (children[i].ref === before.data.ref) {
-        childIndex = i
-        break
-      }
-    }
-    children.splice(childIndex, 0, child.data)
-  
-    this._doRender()
-    if (this.children.length > 0) {
-      return this.children[this.children.length - 1]
-    }
-  }
-  
-  Slider.prototype.appendChild = function (data) {
-    var children = this.data.children || (this.data.children = [])
-    children.push(data)
-    this._doRender()
-    if (this.children.length > 0) {
-      return this.children[this.children.length - 1]
-    }
-  }
-  
-  Slider.prototype.createChildren = function () {
-  
-    var componentManager = this.getComponentManager()
-  
-    // recreate slider container.
-    if (this.sliderContainer) {
-      this.node.removeChild(this.sliderContainer)
-    }
-    if (this.indicator) {
-      this.indicator.node.parentNode.removeChild(this.indicator.node)
-    }
-    this.children = []
-  
-    var sliderContainer = document.createElement('ul')
-    sliderContainer.style.listStyle = 'none'
-    this.node.appendChild(sliderContainer)
-    this.sliderContainer = sliderContainer
-  
-    var children = this.data.children
-    var scale = this.data.scale
-    var fragment = document.createDocumentFragment()
-    var indicatorData, width, height
-    var childWidth = 0
-    var childHeight = 0
-  
-    if (children && children.length) {
-      for (var i = 0; i < children.length; i++) {
-        var child
-        children[i].scale = this.data.scale
-        children[i].instanceId = this.data.instanceId
-        if (children[i].type === 'indicator') {
-          indicatorData = extend(children[i], {
-            extra: {
-              amount: children.length - 1,
-              index: 0
-            }
-          })
-        } else {
-          child = componentManager.createElement(children[i], 'li')
-          this.children.push(child)
-          fragment.appendChild(child.node)
-          width = child.data.style.width || 0
-          height = child.data.style.height || 0
-          width > childWidth && (childWidth = width)
-          height > childHeight && (childHeight = height)
-          child.parentRef = this.data.ref
-        }
-      }
-      // append indicator
-      if (indicatorData) {
-        indicatorData.extra.width = this.data.style.width || childWidth
-        indicatorData.extra.height = this.data.style.height || childHeight
-        this.indicator = componentManager.createElement(indicatorData)
-        this.indicator.parentRef = this.data.ref
-        this.indicator.slider = this
-        this.node.appendChild(this.indicator.node)
-      }
-  
-      sliderContainer.style.height = scale * this.data.style.height + 'px'
-      sliderContainer.appendChild(fragment)
-    }
-  }
-  
-  Slider.prototype.onAppend = function () {
-    if (this.carrousel) {
-      this.carrousel.removeEventListener('change', this._getSliderChangeHandler())
-      this.carrousel.stop()
-      this.carrousel = null
-    }
-    this.carrousel = new lib.carrousel(this.sliderContainer, {
-      autoplay: this.autoPlay,
-      useGesture: true
-    })
-  
-    this.carrousel.playInterval = this.interval
-    this.carrousel.addEventListener('change', this._getSliderChangeHandler())
-    this.currentIndex = 0
-  
-    // preload all images for slider
-    // because:
-    // 1. lib-img doesn't listen to event transitionend
-    // 2. even if we fire lazy load in slider's change event handler,
-    //    the next image still won't be preloaded utill the moment it
-    //    slides into the view, which is too late.
-    if (this.preloadImgsTimer) {
-      clearTimeout(this.preloadImgsTimer)
-    }
-    // The time just before the second slide appear and enough
-    // for all child elements to append is ok.
-    var preloadTime = 0.8
-    this.preloadImgsTimer = setTimeout(function () {
-      var imgs = this.carrousel.element.querySelectorAll('img')
-      for (var i = 0, l = imgs.length; i < l; i++) {
-        var img = imgs[i]
-        var iLazySrc = img.getAttribute('i-lazy-src')
-        var imgSrc = img.getAttribute('img-src')
-        if (iLazySrc) {
-          img.setAttribute('src', iLazySrc)
-        } else if (imgSrc) {
-          img.setAttribute('src', imgSrc)
-        }
-        img.removeAttribute('i-lazy-src')
-        img.removeAttribute('img-src')
-      }
-    }.bind(this), preloadTime * 1000)
-  
-    // avoid page scroll when panning
-    var panning = false
-    this.carrousel.element.addEventListener('panstart', function (e) {
-      if (!e.isVertical) {
-        panning = true
-      }
-    })
-    this.carrousel.element.addEventListener('panend', function (e) {
-      if (!e.isVertical) {
-        panning = false
-      }
-    })
-  
-    document.addEventListener('touchmove', function (e) {
-      if (panning) {
-        e.preventDefault()
-        return false
-      }
-      return true
-    }.bind(this))
-  
-  }
-  
-  Slider.prototype._updateIndicators = function () {
-    this.indicator && this.indicator.setIndex(this.currentIndex)
-  }
-  
-  Slider.prototype._getSliderChangeHandler = function (e) {
-    if (!this.sliderChangeHandler) {
-      this.sliderChangeHandler = (function (e) {
-        var index = this.carrousel.items.index
-        this.currentIndex = index
-  
-        // updateIndicators
-        this._updateIndicators()
-  
-        this.dispatchEvent('change', { index: index })
-      }).bind(this)
-    }
-    return this.sliderChangeHandler
-  }
-  
-  Slider.prototype.play = function () {
-    this.carrousel.play()
-  }
-  
-  Slider.prototype.stop = function () {
-    this.carrousel.stop()
-  }
-  
-  Slider.prototype.slideTo = function (index) {
-    var offset = index - this.currentIndex
-    this.carrousel.items.slide(offset)
-  }
-  
-  module.exports = Slider
-
-
-/***/ },
-/* 41 */
-/***/ function(module, exports, __webpack_require__) {
-
-  (typeof window === 'undefined') && (window = {ctrl: {}, lib: {}});!window.ctrl && (window.ctrl = {});!window.lib && (window.lib = {});__webpack_require__(33);__webpack_require__(34);__webpack_require__(35);!function(){var a="[data-ctrl-name=carrousel]{position:relative;-webkit-transform:translateZ(1px);-ms-transform:translateZ(1px);transform:translateZ(1px)}",b=document.createElement("style");if(document.getElementsByTagName("head")[0].appendChild(b),b.styleSheet)b.styleSheet.disabled||(b.styleSheet.cssText=a);else try{b.innerHTML=a}catch(c){b.innerText=a}}();!function(a,b,c){function d(a){var b,c={x:0,y:0},d=getComputedStyle(a)[l+"Transform"];return"none"!==d&&(b=d.match(/^matrix3d\((?:[-\d.]+,\s*){12}([-\d.]+),\s*([-\d.]+)(?:,\s*[-\d.]+){2}\)/)||d.match(/^matrix\((?:[-\d.]+,\s*){4}([-\d.]+),\s*([-\d.]+)\)$/))&&(c.x=parseFloat(b[1])||0,c.y=parseFloat(b[2])||0),c}function e(a,b){return a=parseFloat(a),b=parseFloat(b),0!=a&&(a+="px"),0!=b&&(b+="px"),n?"translate3d("+a+", "+b+", 0)":"translate("+a+", "+b+")"}function f(a){return o.call(a)}function g(a,c){function g(a,b){var c=h.createEvent("HTMLEvents");if(c.initEvent(a,!1,!1),b)for(var d in b)c[d]=b[d];n.dispatchEvent(c)}function i(a){for(;0>a;)a+=r;for(;a>=r;)a-=r;return a}function j(a){if(0!==r){var b,c,d=q.get(a);r>1&&(b=q.get(a-1),c=2===r?q.getCloned(a+1):q.get(a+1),d.style.left=-o+"px",b.style.left=-o-s+"px",c.style.left=-o+s+"px"),t=d.index,g("change",{prevItem:b,curItem:d,nextItem:c})}}var k=this,m=Date.now()+"-"+ ++p,n=document.createDocumentFragment();1!==arguments.length||arguments[0]instanceof HTMLElement||(c=arguments[0],a=null),a||(a=document.createElement("ul"),n.appendChild(a)),c=c||{},a.setAttribute("data-ctrl-name","carrousel"),a.setAttribute("data-ctrl-id",m),a.style.position="relative",a.style[l+"Transform"]=e(0,0);var o=0,q={},r=0,s=c.step||a.getBoundingClientRect().width,t=0;q.add=function(b){var c=document.createElement("li");return c.style.display="none",c.style["float"]="left",c.index=r,"string"==typeof b?c.innerHTML=b:b instanceof HTMLElement&&c.appendChild(b),a.appendChild(c),Object.defineProperty(q,r+"",{get:function(){return c}}),r++,c},q.get=function(a){return q[i(a)]},q.getCloned=function(b){function c(a,b,d){var e=a._listeners;if(e){b._listeners=e;for(var f in e)b.addEventListener(f,e[f])}if(d&&a.children&&a.children.length)for(var g=0,h=a.children.length;h>g;g++)c(a.children[g],b.children[g],d)}var b=i(b),d=a.querySelector('[cloned="cloned-'+b+'"]'),e=q[b];return d||(d=e.cloneNode(!0),c(e,d,!0),a.appendChild(d),d.setAttribute("cloned","cloned-"+b),d.index=b),d},q.slide=function(c){if(0!==r){1===r&&(c=0);var f=d(a).x,g=o+s*-c,h=g-f;if(0!==h){new b.animation(400,b.cubicbezier.ease,function(b,c){a.style[l+"Transform"]=e(f+h*c,0)}).play().then(function(){o=g,a.style[l+"Transform"]=e(g,0),c&&j(t+c)})}}},q.next=function(){q.slide(1)},q.prev=function(){q.slide(-1)},f(a.querySelectorAll("li")).forEach(function(a){a.style.position="absolute",a.style.top="0",a.style.left=r*s+"px",a.style["float"]="left",a.index=r,Object.defineProperty(q,r+"",{get:function(){return a}}),r++}),Object.defineProperty(this,"items",{get:function(){return q}}),Object.defineProperty(q,"length",{get:function(){return r}}),Object.defineProperty(q,"index",{get:function(){return t}}),Object.defineProperty(q,"step",{get:function(){return s},set:function(a){s=a}});var u=!1,v=!1,w=!1;this.play=function(){return u?void(v||(v=setTimeout(function(){w=!0,q.next(),setTimeout(function(){w=!1},500),v=setTimeout(arguments.callee,400+z)},400+z))):(u=!0,j(0))},this.stop=function(){v&&(clearTimeout(v),setTimeout(function(){v=!1},500))};var x=!1,y=!1;Object.defineProperty(this,"autoplay",{get:function(){return x},set:function(a){x=!!a,y&&(clearTimeout(y),y=!1),x?y=setTimeout(function(){k.play()},2e3):k.stop()}}),this.autoplay=!!c.autoplay;var z=1500;if(Object.defineProperty(this,"playInterval",{get:function(){return z},set:function(a){z=a}}),this.playInterval=!!c.playInterval||1500,c.useGesture){var A,B=!1;a.addEventListener("panstart",function(a){a.isVertical||B&&w||(a.preventDefault(),a.stopPropagation(),x&&k.stop(),A=0,B=!0)}),a.addEventListener("panmove",function(b){!b.isVertical&&B&&(b.preventDefault(),b.stopPropagation(),A=b.displacementX,a.style[l+"Transform"]=e(o+A,0))}),a.addEventListener("panend",function(a){!a.isVertical&&B&&(a.preventDefault(),a.stopPropagation(),B=!1,a.isflick?0>A?q.next():q.prev():Math.abs(A)<s/2?q.slide(0):q.slide(0>A?1:-1),x&&setTimeout(function(){k.play()},2e3))},!1),a.addEventListener("swipe",function(a){a.isVertical||(a.preventDefault(),a.stopPropagation())})}this.addEventListener=function(a,b){this.root.addEventListener(a,b,!1)},this.removeEventListener=function(a,b){this.root.removeEventListener(a,b,!1)},this.root=n,this.element=a}var h=a.document,i=a.navigator.userAgent,j=!!i.match(/Firefox/i),k=!!i.match(/IEMobile/i),l=j?"Moz":k?"ms":"webkit",m=k?"MSCSSMatrix":"WebKitCSSMatrix",n=!!j||m in a&&"m11"in new a[m],o=Array.prototype.slice,p=0;b.carrousel=g}(window,window.lib,window.ctrl||(window.ctrl={}));;module.exports = window.lib['carrousel'];
-
-/***/ },
-/* 42 */
-/***/ function(module, exports, __webpack_require__) {
-
-  // style-loader: Adds some css to the DOM by adding a <style> tag
-  
-  // load the styles
-  var content = __webpack_require__(43);
-  if(typeof content === 'string') content = [[module.id, content, '']];
-  // add the styles to the DOM
-  var update = __webpack_require__(4)(content, {});
-  if(content.locals) module.exports = content.locals;
-  // Hot Module Replacement
-  if(false) {
-    // When the styles change, update the <style> tags
-    if(!content.locals) {
-      module.hot.accept("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./slider.scss", function() {
-        var newContent = require("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./slider.scss");
-        if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
-        update(newContent);
-      });
-    }
-    // When the module is disposed, remove the <style> tags
-    module.hot.dispose(function() { update(); });
-  }
-
-/***/ },
-/* 43 */
-/***/ function(module, exports, __webpack_require__) {
-
-  exports = module.exports = __webpack_require__(3)();
-  // imports
-  
-  
-  // module
-  exports.push([module.id, ".slider {\n  position: relative; }\n\n.slider .indicator-container {\n  position: absolute;\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: flex;\n  -webkit-box-align: center;\n  box-align: center;\n  -webkit-align-items: center;\n  align-items: center;\n  -webkit-box-pack: center;\n  box-pack: center;\n  -webkit-justify-content: center;\n  justify-content: center;\n  font-size: 0; }\n  .slider .indicator-container .indicator {\n    border-radius: 50%; }\n  .slider .indicator-container.row {\n    -webkit-box-orient: horizontal;\n    box-orient: horizontal;\n    -webkit-flex-direction: row;\n    flex-direction: row; }\n  .slider .indicator-container.column {\n    -webkit-box-orient: vertical;\n    box-orient: vertical;\n    -webkit-flex-direction: column;\n    flex-direction: column; }\n", "", {"version":3,"sources":["/./src/src/styles/slider.scss"],"names":[],"mappings":"AAAA;EACE,mBAAmB,EACpB;;AACD;EACE,mBAAmB;EACnB,qBAAqB;EACrB,sBAAsB;EACtB,cAAc;EACd,0BAA0B;EAC1B,kBAAkB;EAClB,4BAA4B;EAC5B,oBAAoB;EACpB,yBAAyB;EACzB,iBAAiB;EACjB,gCAAgC;EAChC,wBAAwB;EACxB,aAAa,EAoBd;EAjCD;IAgBI,mBAAmB,EACpB;EAjBH;IAoBI,+BAA+B;IAC/B,uBAAuB;IACvB,4BAA4B;IAC5B,oBAAoB,EACrB;EAxBH;IA2BI,6BAA6B;IAC7B,qBAAqB;IACrB,+BAA+B;IAC/B,uBAAuB,EACxB","file":"slider.scss","sourcesContent":[".slider {\n  position: relative;\n}\n.slider .indicator-container {\n  position: absolute;\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: flex;\n  -webkit-box-align: center;\n  box-align: center;\n  -webkit-align-items: center;\n  align-items: center;\n  -webkit-box-pack: center;\n  box-pack: center;\n  -webkit-justify-content: center;\n  justify-content: center;\n  font-size: 0;\n\n  .indicator {\n    border-radius: 50%;\n  }\n\n  &.row {\n    -webkit-box-orient: horizontal;\n    box-orient: horizontal;\n    -webkit-flex-direction: row;\n    flex-direction: row;\n  }\n\n  &.column {\n    -webkit-box-orient: vertical;\n    box-orient: vertical;\n    -webkit-flex-direction: column;\n    flex-direction: column;\n  }\n\n}"],"sourceRoot":"webpack://"}]);
-  
-  // exports
-
-
-/***/ },
-/* 44 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  var extend = __webpack_require__(7).extend
-  var config = __webpack_require__(5)
-  var Atomic = __webpack_require__(27)
-  var Component = __webpack_require__(16)
-  
-  __webpack_require__(45)
-  
-  var DEFAULT_ITEM_COLOR = '#999'
-  var DEFAULT_ITEM_SELECTED_COLOR = '#0000ff'
-  var DEFAULT_ITEM_SIZE = 20
-  var DEFAULT_MARGIN_SIZE = 10
-  
-  // Style supported:
-  //   position: (default - absolute)
-  //   itemColor: color of indicator dots
-  //   itemSelectedColor: color of the selected indicator dot
-  //   itemSize: size of indicators
-  //   other layout styles
-  function Indicator (data) {
-    this.direction = 'row' // 'column' is not temporarily supported.
-    this.amount = data.extra.amount
-    this.index = data.extra.index
-    this.sliderWidth = data.extra.width
-    this.sliderHeight = data.extra.height
-    var styles = data.style || {}
-    this.data = data
-    this.style.width.call(this, styles.width)
-    this.style.height.call(this, styles.height)
-    this.items = []
-    Atomic.call(this, data)
-  }
-  
-  Indicator.prototype = Object.create(Atomic.prototype)
-  
-  Indicator.prototype.create = function () {
-    var node = document.createElement('div')
-    node.classList.add('weex-indicators')
-    node.classList.add('weex-element')
-    node.style.position = 'absolute'
-    this.node = node
-    this.style.itemSize.call(this, 0)
-    this.itemColor = DEFAULT_ITEM_COLOR
-    this.itemSelectedColor = DEFAULT_ITEM_SELECTED_COLOR
-    this.updateStyle({
-      left: 0,
-      top: 0,
-      itemSize: 0
-    })
-    return node
-  }
-  
-  Indicator.prototype.createChildren = function () {
-    var root = document.createDocumentFragment()
-    for (var i = 0; i < this.amount; i++) {
-      var indicator = document.createElement('div')
-      indicator.classList.add('weex-indicator')
-      indicator.style.boxSizing = 'border-box'
-      indicator.style.margin = '0 '
-                              + (DEFAULT_MARGIN_SIZE * this.data.scale)
-                              + 'px'
-      indicator.style.width = this.itemSize + 'px'
-      indicator.style.height = this.itemSize + 'px'
-      indicator.setAttribute('index', i)
-      if (this.index === i) {
-        indicator.style.backgroundColor = this.itemSelectedColor
-      } else {
-        indicator.style.backgroundColor = this.itemColor
-      }
-      indicator.addEventListener('click', this._clickHandler.bind(this, i))
-      this.items[i] = indicator
-      root.appendChild(indicator)
-    }
-    this.node.appendChild(root)
-  }
-  
-  Indicator.prototype.style
-      = extend(Object.create(Atomic.prototype.style), {
-    itemColor: function (val) {
-      this.itemColor = val || DEFAULT_ITEM_COLOR
-      for (var i = 0, l = this.items.length; i < l; i++) {
-        this.items[i].style.backgroundColor = this.itemColor
-      }
-    },
-  
-    itemSelectedColor: function (val) {
-      this.itemSelectedColor = val || DEFAULT_ITEM_SELECTED_COLOR
-      if (typeof this.index !== 'undefined'
-          && this.items.length > this.index) {
-        this.items[this.index].style.backgroundColor
-            = this.itemSelectedColor
-      }
-    },
-  
-    itemSize: function (val) {
-      val = parseInt(val) * this.data.scale
-            || DEFAULT_ITEM_SIZE * this.data.scale
-      this.itemSize = val
-      this.node.style.height = val + 'px'
-      for (var i = 0, l = this.items.length; i < l; i++) {
-        this.items[i].style.width = val + 'px'
-        this.items[i].style.height = val + 'px'
-      }
-    },
-  
-    width: function (val) {
-      val = parseInt(val) * this.data.scale || parseInt(this.sliderWidth)
-      this.virtualWrapperWidth = val
-    },
-  
-    height: function (val) {
-      val = parseInt(val) * this.data.scale || parseInt(this.sliderHeight)
-      this.virtualWrapperHeight = val
-    },
-  
-    top: function (val) {
-      val = this.virtualWrapperHeight / 2 - this.itemSize / 2
-          + val * this.data.scale
-      this.node.style.bottom = ''
-      this.node.style.top = val + 'px'
-    },
-  
-    bottom: function (val) {
-      val = this.virtualWrapperHeight / 2 - this.itemSize / 2
-          + val * this.data.scale
-      this.node.style.top = ''
-      this.node.style.bottom = val + 'px'
-    },
-  
-    left: function (val) {
-      val = this.virtualWrapperWidth / 2
-            - (this.itemSize + 2 * DEFAULT_MARGIN_SIZE * this.data.scale)
-                * this.amount / 2
-            + val * this.data.scale
-      this.node.style.right = ''
-      this.node.style.left = val + 'px'
-    },
-  
-    right: function (val) {
-      val = this.virtualWrapperWidth / 2
-            - (this.itemSize + 2 * DEFAULT_MARGIN_SIZE * this.data.scale)
-                * this.amount / 2
-            + val * this.data.scale
-      this.node.style.left = ''
-      this.node.style.right = val + 'px'
-    }
-  })
-  
-  Indicator.prototype.setIndex = function (idx) {
-    if (idx >= this.amount) {
-      return
-    }
-    var prev = this.items[this.index]
-    var cur = this.items[idx]
-    prev.classList.remove('active')
-    prev.style.backgroundColor = this.itemColor
-    cur.classList.add('active')
-    cur.style.backgroundColor = this.itemSelectedColor
-    this.index = idx
-  }
-  
-  Indicator.prototype._clickHandler = function (idx) {
-    this.slider.slideTo(idx)
-  }
-  
-  module.exports = Indicator
-
-
-/***/ },
-/* 45 */
-/***/ function(module, exports, __webpack_require__) {
-
-  // style-loader: Adds some css to the DOM by adding a <style> tag
-  
-  // load the styles
-  var content = __webpack_require__(46);
-  if(typeof content === 'string') content = [[module.id, content, '']];
-  // add the styles to the DOM
-  var update = __webpack_require__(4)(content, {});
-  if(content.locals) module.exports = content.locals;
-  // Hot Module Replacement
-  if(false) {
-    // When the styles change, update the <style> tags
-    if(!content.locals) {
-      module.hot.accept("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./indicator.scss", function() {
-        var newContent = require("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./indicator.scss");
-        if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
-        update(newContent);
-      });
-    }
-    // When the module is disposed, remove the <style> tags
-    module.hot.dispose(function() { update(); });
-  }
-
-/***/ },
-/* 46 */
-/***/ function(module, exports, __webpack_require__) {
-
-  exports = module.exports = __webpack_require__(3)();
-  // imports
-  
-  
-  // module
-  exports.push([module.id, ".weex-indicators {\n  position: absolute;\n  white-space: nowrap; }\n  .weex-indicators .weex-indicator {\n    float: left;\n    border-radius: 50%; }\n", "", {"version":3,"sources":["/./src/src/styles/indicator.scss"],"names":[],"mappings":"AAAA;EACE,mBAAmB;EACnB,oBAAoB,EAOrB;EATD;IAKI,YAAY;IACZ,mBAAmB,EACpB","file":"indicator.scss","sourcesContent":[".weex-indicators {\n  position: absolute;\n  white-space: nowrap;\n\n  .weex-indicator {\n    float: left;\n    border-radius: 50%;\n  }\n\n}"],"sourceRoot":"webpack://"}]);
-  
-  // exports
-
-
-/***/ },
-/* 47 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  var Atomic = __webpack_require__(27)
-  var msgQueue = __webpack_require__(48)
-  var config = __webpack_require__(5)
-  var utils = __webpack_require__(7)
-  
-  // TODO: refactor this scss code since this is strongly
-  // dependent on lib.flexible other than the value of
-  // scale.
-  __webpack_require__(49)
-  
-  function TabHeader(data) {
-    Atomic.call(this, data)
-  }
-  
-  var proto = TabHeader.prototype = Object.create(Atomic.prototype)
-  
-  proto.create = function () {
-    // outside container.
-    var node = document.createElement('div')
-    node.className = 'tab-header'
-    // tip on the top.
-    var bar = document.createElement('div')
-    bar.className = 'header-bar'
-    bar.textContent = 'CHANGE FLOOR'
-    // middle layer.
-    var body = document.createElement('div')
-    body.className = 'header-body'
-    var box = document.createElement('ul')
-    box.className = 'tabheader'
-  
-    body.appendChild(box)
-    node.appendChild(bar)
-    node.appendChild(body)
-    this._bar = bar
-    this._body = body
-    this.box = box
-    this.node = node
-    // init events.
-    this._initFoldBtn()
-    this._initEvent()
-    return node
-  }
-  
-  proto._initFoldBtn = function () {
-    var _this = this
-    var node = this.node
-    var btn = document.createElement('span')
-    btn.className = 'fold-toggle iconfont'
-    btn.innerHTML = '&#xe661;'
-    node.appendChild(btn)
-  
-    btn.addEventListener('click', function () {
-      if (_this.unfolding) {
-        _this._folding()
-      } else {
-        _this._unfolding()
-      }
-    })
-  }
-  
-  proto._initMask = function () {
-    var mask = document.createElement('div')
-    mask.className = 'tabheader-mask'
-    this.mask = mask
-    // stop default behavior: page moving.
-    mask.addEventListener('touchmove', function (evt) {
-      evt.preventDefault()
-    })
-    // click to unfold.
-    var _this = this
-    mask.addEventListener('click', function () {
-      _this._folding()
-    })
-  
-    document.body.appendChild(mask)
-  }
-  
-  proto._unfolding = function () {
-    // mark the initial posiiton of tabheader
-    if (!this.flag) {
-      var flag = document.createComment('tabheader')
-      this.flag = flag
-      this.node.parentNode.insertBefore(flag, this.node)
-    }
-    if (!this.mask) {
-      this._initMask()
-    }
-  
-    // record the scroll position.
-    this._scrollVal = this._body.scrollLeft
-    // record the position in document.
-    this._topVal = this.node.getBoundingClientRect().top
-    this._styleTop = this.node.style.top
-  
-    document.body.appendChild(this.node)
-    this.node.classList.add('unfold-header')
-    this.node.style.height = 'auto'
-    // recalc the position when it is unfolded.
-    var thHeight = this.node.getBoundingClientRect().height
-    if (thHeight + this._topVal > window.innerHeight) {
-      this._topVal = this._topVal
-          + (window.innerHeight - thHeight - this._topVal)
-    }
-  
-    this.node.style.top = this._topVal + 'px'
-    // process mask style
-    this.mask.classList.add('unfold-header')
-    this.mask.style.height = window.innerHeight + 'px'
-    this.unfolding = true
-  }
-  
-  proto._folding = function () {
-    if (this.unfolding !== true) {
-      return
-    }
-  
-    this.mask.classList.remove('unfold-header')
-    this.node.classList.remove('unfold-header')
-  
-    this.node.style.height = ''
-    this.node.style.top = this._styleTop
-  
-    // recover the position of tabheader.
-    this.flag.parentNode.insertBefore(this.node, this.flag)
-    // recover the position of scoller.
-    this._body.scrollLeft = this._scrollVal
-  
-    this._scrollToView()
-    this.unfolding = false
-  }
-  
-  proto._initEvent = function () {
-    this._initClickEvent()
-    this._initSelectEvent()
-  }
-  
-  // init events.
-  proto._initClickEvent = function () {
-    var box = this.box
-    var _this = this
-  
-    box.addEventListener('click', function (evt) {
-      var target = evt.target
-      if (target.nodeName === 'UL') {
-        return
-      }
-  
-      if (target.parentNode.nodeName === 'LI') {
-        target = target.parentNode
-      }
-  
-      var floor = target.getAttribute('data-floor')
-  
-      if (_this.data.attr.selectedIndex == floor) {
-        // Duplicated clicking, not to trigger select event.
-        return
-      }
-  
-      fireEvent(target, 'select', {index:  floor})
-    })
-  }
-  
-  proto._initSelectEvent = function () {
-    var node = this.node
-    var _this = this
-    node.addEventListener('select', function (evt) {
-      var index
-      if (evt.index !== undefined) {
-        index = evt.index
-      } else if (evt.data && evt.data.index !== undefined) {
-        index = evt.data.index
-      }
-  
-      if (index === undefined) {
-        return
-      }
-  
-      _this.attr.selectedIndex.call(_this, index)
-    })
-  }
-  
-  proto.attr = {
-    highlightIcon: function () {
-      return createHighlightIcon()
-    },
-    data: function () {
-      var attr = this.data.attr
-      // Ensure there is a default selected value.
-      if (attr.selectedIndex === undefined) {
-        attr.selectedIndex = 0
-      }
-  
-      var list = attr.data || []
-      var curItem = attr.selectedIndex
-  
-      var ret = []
-      var itemTmpl = '<li class="th-item" data-floor="{{floor}}">'
-          + '{{hlIcon}}{{floorName}}</li>'
-  
-      list.forEach(function (item, idx) {
-        var html = itemTmpl.replace('{{floor}}', idx)
-        if (curItem == idx) {
-          html = html.replace('{{hlIcon}}', createHighlightIcon())
-        } else {
-          html = html.replace('{{hlIcon}}', '')
-        }
-  
-        html = html.replace('{{floorName}}', item)
-  
-        ret.push(html)
-      }, this)
-  
-      this.box.innerHTML = ret.join('')
-    },
-    selectedIndex: function (val) {
-      var attr = this.data.attr
-  
-      if (val === undefined) {
-        val = 0
-      }
-  
-      // if (val == attr.selectedIndex) {
-      //   return
-      // }
-  
-      attr.selectedIndex = val
-  
-      this.attr.data.call(this)
-  
-      this._folding()
-      this.style.textHighlightColor.call(this, this.textHighlightColor)
-    }
-  }
-  
-  proto.style = Object.create(Atomic.prototype.style)
-  
-  proto.style.opacity = function (val) {
-    if (val === undefined || val < 0 || val > 1) {
-      val = 1
-    }
-  
-    this.node.style.opacity = val
-  }
-  
-  proto.style.textColor = function (val) {
-    if (!isValidColor(val)) {
-      return
-    }
-  
-    this.node.style.color = val
-  }
-  
-  proto.style.textHighlightColor = function (val) {
-    if (!isValidColor(val)) {
-      return
-    }
-    this.textHighlightColor = val
-    var attr = this.data.attr
-  
-    var node = this.node.querySelector('[data-floor="'
-        + attr.selectedIndex + '"]')
-    if (node) {
-      node.style.color = val
-      this._scrollToView(node)
-    }
-  }
-  
-  proto._scrollToView = function (node) {
-    if (!node) {
-      var attr = this.data.attr
-      node = this.node.querySelector('[data-floor="' + attr.selectedIndex + '"]')
-    }
-    if (!node) {
-      return
-    }
-  
-    var defaultVal = this._body.scrollLeft
-    var leftVal = defaultVal  - node.offsetLeft + 300
-  
-    var scrollVal = getScrollVal(this._body.getBoundingClientRect(), node)
-    doScroll(this._body, scrollVal)
-  }
-  
-  // scroll the tabheader.
-  // positive val means to scroll right.
-  // negative val means to scroll left.
-  function doScroll(node, val, finish) {
-    if (!val) {
-      return
-    }
-    if (finish === undefined) {
-      finish = Math.abs(val)
-    }
-  
-    if (finish <= 0) {
-      return
-    }
-  
-    setTimeout(function () {
-      if (val > 0) {
-        node.scrollLeft += 2
-      } else {
-        node.scrollLeft -= 2
-      }
-      finish -= 2
-  
-      doScroll(node, val, finish)
-    })
-  }
-  
-  // get scroll distance.
-  function getScrollVal(rect, node) {
-    var left = node.previousSibling
-    var right = node.nextSibling
-    var scrollVal
-  
-    // process left-side element first.
-    if (left) {
-      var leftRect = left.getBoundingClientRect()
-      // only need to compare the value of left.
-      if (leftRect.left < rect.left) {
-        scrollVal = leftRect.left
-        return scrollVal
-      }
-    }
-  
-    if (right) {
-      var rightRect = right.getBoundingClientRect()
-      // compare the value of right.
-      if (rightRect.right > rect.right) {
-        scrollVal = rightRect.right - rect.right
-        return scrollVal
-      }
-    }
-  
-    // process current node, from left to right.
-    var nodeRect = node.getBoundingClientRect()
-    if (nodeRect.left < rect.left) {
-      scrollVal = nodeRect.left
-    } else if (nodeRect.right > rect.right) {
-      scrollVal = nodeRect.right - rect.right
-    }
-  
-    return scrollVal
-  }
-  
-  // trigger and broadcast events.
-  function fireEvent(element, type, data) {
-    var evt = document.createEvent('Event')
-    evt.data = data
-    utils.extend(evt, data)
-    // need bubble.
-    evt.initEvent(type, true, true)
-  
-    element.dispatchEvent(evt)
-  }
-  
-  function createHighlightIcon(code) {
-    var html = '<i class="hl-icon iconfont">' + '&#xe650' + '</i>'
-    return html
-  }
-  
-  function isValidColor(color) {
-    if (!color) {
-      return false
-    }
-  
-    if (color.charAt(0) !== '#') {
-      return false
-    }
-  
-    if (color.length !== 7) {
-      return false
-    }
-  
-    return true
-  }
-  
-  module.exports = TabHeader
-
-
-/***/ },
-/* 48 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  var config = __webpack_require__(5)
-  var messageQueue = []
-  
-  function flushMessage() {
-    if (typeof callJS === 'function' && messageQueue.length > 0) {
-      callJS(config.instanceId, JSON.stringify(messageQueue))
-      messageQueue.length = 0
-    }
-  }
-  
-  function push(msg) {
-    messageQueue.push(msg)
-  }
-  
-  /**
-   * To fix the problem of callapp, the two-way time loop mechanism must
-   * be replaced by directly procedure call except the situation of
-   * page loading.
-   * 2015-11-03
-   */
-  function pushDirectly(msg) {
-    callJS(config.instanceId, [msg])
-  }
-  
-  module.exports = {
-    push: pushDirectly
-  }
-
-
-/***/ },
-/* 49 */
-/***/ function(module, exports, __webpack_require__) {
-
-  // style-loader: Adds some css to the DOM by adding a <style> tag
-  
-  // load the styles
-  var content = __webpack_require__(50);
-  if(typeof content === 'string') content = [[module.id, content, '']];
-  // add the styles to the DOM
-  var update = __webpack_require__(4)(content, {});
-  if(content.locals) module.exports = content.locals;
-  // Hot Module Replacement
-  if(false) {
-    // When the styles change, update the <style> tags
-    if(!content.locals) {
-      module.hot.accept("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./tabheader.scss", function() {
-        var newContent = require("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./tabheader.scss");
-        if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
-        update(newContent);
-      });
-    }
-    // When the module is disposed, remove the <style> tags
-    module.hot.dispose(function() { update(); });
-  }
-
-/***/ },
-/* 50 */
-/***/ function(module, exports, __webpack_require__) {
-
-  exports = module.exports = __webpack_require__(3)();
-  // imports
-  
-  
-  // module
-  exports.push([module.id, ".tab-header {\n  position: relative;\n  width: 10rem;\n  font-size: 14px;\n  color: #333; }\n  .tab-header .header-bar {\n    height: 1.17rem;\n    line-height: 1.17rem;\n    display: none;\n    color: #999;\n    padding-left: 0.4rem; }\n  .tab-header .header-body {\n    margin-right: 1.07rem;\n    overflow-x: auto;\n    overflow-y: hidden; }\n    .tab-header .header-body::-webkit-scrollbar {\n      width: 0;\n      height: 0;\n      overflow: hidden; }\n  .tab-header .fold-toggle {\n    position: absolute;\n    top: 0.59rem;\n    -webkit-transform: translateY(-50%);\n    right: 0.29rem;\n    width: 0.48rem;\n    height: 0.48rem;\n    line-height: 0.48rem;\n    text-align: center;\n    z-index: 99;\n    font-size: 14px; }\n  .tab-header.unfold-header {\n    position: fixed !important;\n    top: 0;\n    left: 0;\n    overflow: hidden; }\n\n.tabheader {\n  list-style: none;\n  white-space: nowrap;\n  height: 1.17rem;\n  line-height: 1.17rem; }\n  .tabheader .th-item {\n    padding-left: 0.72rem;\n    position: relative;\n    display: inline-block; }\n  .tabheader .hl-icon {\n    width: 0.4rem;\n    height: 0.4rem;\n    line-height: 0.4rem;\n    text-align: center;\n    position: absolute;\n    top: 50%;\n    -webkit-transform: translateY(-50%);\n    left: 0.24rem;\n    font-size: 14px; }\n\n.unfold-header .header-bar {\n  display: block; }\n\n.unfold-header .fold-toggle {\n  -webkit-transform: translateY(-50%) rotate(180deg); }\n\n.unfold-header .header-body {\n  margin-right: 0;\n  padding: 0.24rem; }\n\n.unfold-header .tabheader {\n  display: block;\n  height: auto; }\n\n.unfold-header .th-item {\n  box-sizing: border-box;\n  float: left;\n  width: 33.3333%;\n  height: 1.01rem;\n  line-height: 1.01rem; }\n\n.unfold-header .hl-icon {\n  margin-right: 0;\n  position: absolute; }\n\n.unfold-header.tabheader-mask {\n  display: block;\n  width: 100%;\n  height: 100%;\n  background-color: rgba(0, 0, 0, 0.6); }\n\n.tabheader-mask {\n  display: none;\n  position: fixed;\n  left: 0;\n  top: 0; }\n\n@font-face {\n  font-family: \"iconfont\";\n  src: url(\"data:application/x-font-ttf;charset=utf-8;base64,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R7AEQ7CAYmAgsAArIIqKYSCwAkNgZCOwA0NhZFBYsAJDYRuwA0NgWbADJbCAYmGwAiVGYTgjIDwjOBshICBGI0ewACsjYTghWbEkARQrLbA7LLAuKy6xJAEUKy2wPCywLyshIyAgPLAEI0IjOLEkARQrsARDLrAkKy2wPSywABUgR7AAI0KyAAEBFRQTLrAqKi2wPiywABUgR7AAI0KyAAEBFRQTLrAqKi2wPyyxAAEUE7ArKi2wQCywLSotsEEssAAWRSMgLiBGiiNhOLEkARQrLbBCLLAJI0KwQSstsEMssgAAOistsEQssgABOistsEUssgEAOistsEYssgEBOistsEcssgAAOystsEgssgABOystsEkssgEAOystsEossgEBOystsEsssgAANystsEwssgABNystsE0ssgEANystsE4ssgEBNystsE8ssgAAOSstsFAssgABOSstsFEssgEAOSstsFIssgEBOSstsFMssgAAPCstsFQssgABPCstsFUssgEAPCstsFYssgEBPCstsFcssgAAOCstsFgssgABOCstsFkssgEAOCstsFossgEBOCstsFsssDArLrEkARQrLbBcLLAwK7A0Ky2wXSywMCuwNSstsF4ssAAWsDArsDYrLbBfLLAxKy6xJAEUKy2wYCywMSuwNCstsGEssDErsDUrLbBiLLAxK7A2Ky2wYyywMisusSQBFCstsGQssDIrsDQrLbBlLLAyK7A1Ky2wZiywMiuwNistsGcssDMrLrEkARQrLbBoLLAzK7A0Ky2waSywMyuwNSstsGossDMrsDYrLbBrLCuwCGWwAyRQeLABFTAtAABLuADIUlixAQGOWbkIAAgAYyCwASNEILADI3CwDkUgIEu4AA5RS7AGU1pYsDQbsChZYGYgilVYsAIlYbABRWMjYrACI0SzCgkFBCuzCgsFBCuzDg8FBCtZsgQoCUVSRLMKDQYEK7EGAUSxJAGIUViwQIhYsQYDRLEmAYhRWLgEAIhYsQYBRFlZWVm4Af+FsASNsQUARAAAAA==\") format(\"truetype\"); }\n\n.iconfont {\n  font-family: iconfont !important;\n  font-size: 16px;\n  font-style: normal;\n  -webkit-font-smoothing: antialiased;\n  -webkit-text-stroke-width: 0.2px;\n  -moz-osx-font-smoothing: grayscale; }\n\n[data-dpr=\"2\"] .tab-header {\n  font-size: 28px; }\n\n[data-dpr=\"3\"] .tab-header {\n  font-size: 42px; }\n\n[data-dpr=\"2\"] .tabheader .hl-icon {\n  font-size: 28px; }\n\n[data-dpr=\"3\"] .tabheader .hl-icon {\n  font-size: 42px; }\n\n[data-dpr=\"2\"] .tab-header .fold-toggle {\n  font-size: 28px; }\n\n[data-dpr=\"3\"] .tab-header .fold-toggle {\n  font-size: 42px; }\n", "", {"version":3,"sources":["/./src/src/styles/tabheader.scss","/./src/styles/tabheader.scss"],"names":[],"mappings":"AAGA;EACE,mBAAmB;EACnB,aAAa;EACb,gBAAgB;EAChB,YAAY,EA0Cb;EA9CD;IAOI,gBAAgB;IAChB,qBAAqB;IACrB,cAAc;IACd,YAAY;IACZ,qBAAqB,EACtB;EAZH;IAeI,sBAAsB;IACtB,iBAAiB;IACjB,mBAAmB,EAOpB;IAxBH;MAoBM,SAAS;MACT,UAAU;MACV,iBAAiB,EAClB;EAvBL;IA2BI,mBAAmB;IACnB,aAAa;IACb,oCAA6B;IAC7B,eAAe;IACf,eAAe;IACf,gBAAgB;IAChB,qBAAqB;IACrB,mBAAmB;IACnB,YAAY;IACZ,gBAAgB,EACjB;EArCH;IAwCI,2BAA2B;IAC3B,OAAO;IACP,QAAQ;IACR,iBAAiB,EAClB;;AAIH;EACE,iBAAiB;EACjB,oBAAoB;EACpB,gBAAgB;EAChB,qBAAqB,EAoBtB;EAxBD;IAOI,sBAAsB;IACtB,mBAAmB;IACnB,sBAAsB,EACvB;EAVH;IAaI,cAAc;IACd,eAAe;IACf,oBAAoB;IACpB,mBAAmB;IACnB,mBAAmB;IACnB,SAAS;IACT,oCAA6B;IAC7B,cAAc;IACd,gBAAgB,EACjB;;AAIH;EAGI,eAAe,EAChB;;AAJH;EAOI,mDAA0C,EAC3C;;AARH;EAWI,gBAAgB;EAChB,iBAAiB,EAClB;;AAbH;EAgBI,eAAe;EACf,aAAa,EACd;;AAlBH;EAqBI,uBAAuB;EACvB,YAAY;EACZ,gBAAgB;EAChB,gBAAgB;EAChB,qBAAqB,EACtB;;AA1BH;EA6BI,gBAAgB;EAChB,mBAAmB,EACpB;;AA/BH;EAkCI,eAAe;EACf,YAAY;EACZ,aAAa;EACb,qCAAsB,EACvB;;AAGH;EACE,cAAc;EACd,gBAAgB;EAChB,QAAQ;EACR,OAAO,EACR;;AAED;EACE,wBAAwB;EACxB,y9NAA48N,EAAA;;AAG98N;EACE,iCAAiC;EACjC,gBAAgB;EAChB,mBAAmB;EACnB,oCAAoC;EACpC,iCAAiC;EACjC,mCAAmC,EACpC;;AChCD;EDmCE,gBAAgB,EACjB;;ACjCD;EDoCE,gBAAgB,EACjB;;AClCD;EDqCE,gBAAgB,EACjB;;ACnCD;EDsCE,gBAAgB,EACjB;;ACpCD;EDuCE,gBAAgB,EACjB;;ACrCD;EDwCE,gBAAgB,EACjB","file":"tabheader.scss","sourcesContent":["// Heads up! Rem is not a good way for\n// weex HTML5 renderer.\n\n.tab-header {\n  position: relative;\n  width: 10rem;\n  font-size: 14px;\n  color: #333;\n\n  .header-bar {\n    height: 1.17rem;\n    line-height: 1.17rem;\n    display: none;\n    color: #999;\n    padding-left: 0.4rem;\n  }\n  \n  .header-body {\n    margin-right: 1.07rem;\n    overflow-x: auto;\n    overflow-y: hidden;\n\n    &::-webkit-scrollbar {\n      width: 0;\n      height: 0;\n      overflow: hidden;\n    }\n  }\n\n  .fold-toggle {\n    position: absolute;\n    top: 0.59rem;\n    -webkit-transform: translateY(-50%);\n    right: 0.29rem;\n    width: 0.48rem;\n    height: 0.48rem;\n    line-height: 0.48rem;\n    text-align: center;\n    z-index: 99;\n    font-size: 14px;\n  }\n\n  &.unfold-header {\n    position: fixed !important;\n    top: 0;\n    left: 0;\n    overflow: hidden;\n  }\n\n}\n\n.tabheader {\n  list-style: none;\n  white-space: nowrap;\n  height: 1.17rem;\n  line-height: 1.17rem;\n\n  .th-item {\n    padding-left: 0.72rem;\n    position: relative;\n    display: inline-block;\n  }\n\n  .hl-icon {\n    width: 0.4rem;\n    height: 0.4rem;\n    line-height: 0.4rem;\n    text-align: center;\n    position: absolute;\n    top: 50%;\n    -webkit-transform: translateY(-50%);\n    left: 0.24rem;\n    font-size: 14px;\n  }\n\n}\n\n.unfold-header {\n\n  .header-bar {\n    display: block;\n  }\n\n  .fold-toggle {\n    -webkit-transform: translateY(-50%) rotate(180deg);\n  }\n\n  .header-body {\n    margin-right: 0;\n    padding: 0.24rem;\n  }\n\n  .tabheader {\n    display: block;\n    height: auto;\n  }\n\n  .th-item {\n    box-sizing: border-box;\n    float: left;\n    width: 33.3333%;\n    height: 1.01rem;\n    line-height: 1.01rem;\n  }\n\n  .hl-icon {\n    margin-right: 0;\n    position: absolute;\n  }\n\n  &.tabheader-mask {\n    display: block;\n    width: 100%;\n    height: 100%;\n    background-color: rgba(0, 0, 0, 0.6);\n  }\n}\n\n.tabheader-mask {\n  display: none;\n  position: fixed;\n  left: 0;\n  top: 0;\n}\n\n@font-face {\n  font-family: \"iconfont\";\n  src: url(\"data:application/x-font-ttf;charset=utf-8;base64,AAEAAAAPAIAAAwBwRkZUTXBD98UAAAD8AAAAHE9TLzJXL1zIAAABGAAAAGBjbWFws6IHbgAAAXgAAAFaY3Z0IAyV/swAAApQAAAAJGZwZ20w956VAAAKdAAACZZnYXNwAAAAEAAACkgAAAAIZ2x5ZuxoPFIAAALUAAAEWGhlYWQHA5h3AAAHLAAAADZoaGVhBzIDcgAAB2QAAAAkaG10eAs2AW0AAAeIAAAAGGxvY2EDcAQeAAAHoAAAABBtYXhwASkKKwAAB7AAAAAgbmFtZQl/3hgAAAfQAAACLnBvc3Tm7f0bAAAKAAAAAEhwcmVwpbm+ZgAAFAwAAACVAAAAAQAAAADMPaLPAAAAANIDKnoAAAAA0gMqewAEA/oB9AAFAAACmQLMAAAAjwKZAswAAAHrADMBCQAAAgAGAwAAAAAAAAAAAAEQAAAAAAAAAAAAAABQZkVkAMAAeObeAyz/LABcAxgAlAAAAAEAAAAAAxgAAAAAACAAAQAAAAMAAAADAAAAHAABAAAAAABUAAMAAQAAABwABAA4AAAACgAIAAIAAgB45lDmYebe//8AAAB45lDmYebe////ixm0GaQZKAABAAAAAAAAAAAAAAAAAQYAAAEAAAAAAAAAAQIAAAACAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACACIAAAEyAqoAAwAHAClAJgAAAAMCAANXAAIBAQJLAAICAU8EAQECAUMAAAcGBQQAAwADEQUPKzMRIREnMxEjIgEQ7szMAqr9ViICZgAAAAUALP/hA7wDGAAWADAAOgBSAF4Bd0uwE1BYQEoCAQANDg0ADmYAAw4BDgNeAAEICAFcEAEJCAoGCV4RAQwGBAYMXgALBAtpDwEIAAYMCAZYAAoHBQIECwoEWRIBDg4NUQANDQoOQhtLsBdQWEBLAgEADQ4NAA5mAAMOAQ4DXgABCAgBXBABCQgKCAkKZhEBDAYEBgxeAAsEC2kPAQgABgwIBlgACgcFAgQLCgRZEgEODg1RAA0NCg5CG0uwGFBYQEwCAQANDg0ADmYAAw4BDgNeAAEICAFcEAEJCAoICQpmEQEMBgQGDARmAAsEC2kPAQgABgwIBlgACgcFAgQLCgRZEgEODg1RAA0NCg5CG0BOAgEADQ4NAA5mAAMOAQ4DAWYAAQgOAQhkEAEJCAoICQpmEQEMBgQGDARmAAsEC2kPAQgABgwIBlgACgcFAgQLCgRZEgEODg1RAA0NCg5CWVlZQChTUzs7MjEXF1NeU15bWDtSO1JLQzc1MToyOhcwFzBRETEYESgVQBMWKwEGKwEiDgIdASE1NCY1NC4CKwEVIQUVFBYUDgIjBiYrASchBysBIiciLgI9ARciBhQWMzI2NCYXBgcOAx4BOwYyNicuAScmJwE1ND4COwEyFh0BARkbGlMSJRwSA5ABChgnHoX+SgKiARUfIw4OHw4gLf5JLB0iFBkZIBMIdwwSEgwNEhKMCAYFCwQCBA8OJUNRUEAkFxYJBQkFBQb+pAUPGhW8HykCHwEMGScaTCkQHAQNIBsSYYg0Fzo6JRcJAQGAgAETGyAOpz8RGhERGhF8GhYTJA4QDQgYGg0jERMUAXfkCxgTDB0m4wAAAgCg/2wDYALsABIAGgAhQB4AAAADAgADWQACAQECTQACAgFRAAECAUUTFjkQBBIrACAGFRQeAxcWOwEyPwESNTQAIiY0NjIWFAKS/tzORFVvMRAJDgEOCW3b/uKEXl6EXgLszpI1lXyJNhEKC30BDIyS/s5ehF5ehAAAAAEAggBJA4QB6AAdABtAGBIRAgEAAUAFAQA+AAABAGgAAQFfEx8CECsBJgcGBwkBLgEGBwYUFwEwMxcVFjI3AT4DLgIDehEWAwP+uP60BhEQBgoKAWEBAQoaCQFeAwQCAQECBAHhEg0DAv61AUkHBAUGCRsJ/qIBAQkJAWICBwYHCAYGAAEAfwCLA4ECJwAhAB1AGhYPAgEAAUAFAQA+AAABAGgCAQEBXyQuEwMRKyUBMCcjNSYHBgcBDgEUFhceAjMyNwkBFjMyNjc+Ai4BA3f+nwEBEhUEAv6iBQUFBQMHCAQOCQFIAUwKDQYMBQMFAQEFwwFeAQERDQID/p8FDAwMBAMEAgkBS/62CQUFAwoJCgkAAAEAAAABAAALIynoXw889QALBAAAAAAA0gMqewAAAADSAyp7ACL/bAO8AxgAAAAIAAIAAAAAAAAAAQAAAxj/bABcBAAAAAAAA7wAAQAAAAAAAAAAAAAAAAAAAAUBdgAiAAAAAAFVAAAD6QAsBAAAoACCAH8AAAAoACgAKAFkAaIB5AIsAAEAAAAHAF8ABQAAAAAAAgAmADQAbAAAAIoJlgAAAAAAAAAMAJYAAQAAAAAAAQAIAAAAAQAAAAAAAgAGAAgAAQAAAAAAAwAkAA4AAQAAAAAABAAIADIAAQAAAAAABQBGADoAAQAAAAAABgAIAIAAAwABBAkAAQAQAIgAAwABBAkAAgAMAJgAAwABBAkAAwBIAKQAAwABBAkABAAQAOwAAwABBAkABQCMAPwAAwABBAkABgAQAYhpY29uZm9udE1lZGl1bUZvbnRGb3JnZSAyLjAgOiBpY29uZm9udCA6IDI2LTgtMjAxNWljb25mb250VmVyc2lvbiAxLjAgOyB0dGZhdXRvaGludCAodjAuOTQpIC1sIDggLXIgNTAgLUcgMjAwIC14IDE0IC13ICJHIiAtZiAtc2ljb25mb250AGkAYwBvAG4AZgBvAG4AdABNAGUAZABpAHUAbQBGAG8AbgB0AEYAbwByAGcAZQAgADIALgAwACAAOgAgAGkAYwBvAG4AZgBvAG4AdAAgADoAIAAyADYALQA4AC0AMgAwADEANQBpAGMAbwBuAGYAbwBuAHQAVgBlAHIAcwBpAG8AbgAgADEALgAwACAAOwAgAHQAdABmAGEAdQB0AG8AaABpAG4AdAAgACgAdgAwAC4AOQA0ACkAIAAtAGwAIAA4ACAALQByACAANQAwACAALQBHACAAMgAwADAAIAAtAHgAIAAxADQAIAAtAHcAIAAiAEcAIgAgAC0AZgAgAC0AcwBpAGMAbwBuAGYAbwBuAHQAAAACAAAAAAAA/4MAMgAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAABAAIAWwECAQMBBAd1bmlFNjUwB3VuaUU2NjEHdW5pRTZERQABAAH//wAPAAAAAAAAAAAAAAAAAAAAAAAyADIDGP/hAxj/bAMY/+EDGP9ssAAssCBgZi2wASwgZCCwwFCwBCZasARFW1ghIyEbilggsFBQWCGwQFkbILA4UFghsDhZWSCwCkVhZLAoUFghsApFILAwUFghsDBZGyCwwFBYIGYgiophILAKUFhgGyCwIFBYIbAKYBsgsDZQWCGwNmAbYFlZWRuwACtZWSOwAFBYZVlZLbACLCBFILAEJWFkILAFQ1BYsAUjQrAGI0IbISFZsAFgLbADLCMhIyEgZLEFYkIgsAYjQrIKAAIqISCwBkMgiiCKsAArsTAFJYpRWGBQG2FSWVgjWSEgsEBTWLAAKxshsEBZI7AAUFhlWS2wBCywCCNCsAcjQrAAI0KwAEOwB0NRWLAIQyuyAAEAQ2BCsBZlHFktsAUssABDIEUgsAJFY7ABRWJgRC2wBiywAEMgRSCwACsjsQQEJWAgRYojYSBkILAgUFghsAAbsDBQWLAgG7BAWVkjsABQWGVZsAMlI2FERC2wByyxBQVFsAFhRC2wCCywAWAgILAKQ0qwAFBYILAKI0JZsAtDSrAAUlggsAsjQlktsAksILgEAGIguAQAY4ojYbAMQ2AgimAgsAwjQiMtsAosS1RYsQcBRFkksA1lI3gtsAssS1FYS1NYsQcBRFkbIVkksBNlI3gtsAwssQANQ1VYsQ0NQ7ABYUKwCStZsABDsAIlQrIAAQBDYEKxCgIlQrELAiVCsAEWIyCwAyVQWLAAQ7AEJUKKiiCKI2GwCCohI7ABYSCKI2GwCCohG7AAQ7ACJUKwAiVhsAgqIVmwCkNHsAtDR2CwgGIgsAJFY7ABRWJgsQAAEyNEsAFDsAA+sgEBAUNgQi2wDSyxAAVFVFgAsA0jQiBgsAFhtQ4OAQAMAEJCimCxDAQrsGsrGyJZLbAOLLEADSstsA8ssQENKy2wECyxAg0rLbARLLEDDSstsBIssQQNKy2wEyyxBQ0rLbAULLEGDSstsBUssQcNKy2wFiyxCA0rLbAXLLEJDSstsBgssAcrsQAFRVRYALANI0IgYLABYbUODgEADABCQopgsQwEK7BrKxsiWS2wGSyxABgrLbAaLLEBGCstsBsssQIYKy2wHCyxAxgrLbAdLLEEGCstsB4ssQUYKy2wHyyxBhgrLbAgLLEHGCstsCEssQgYKy2wIiyxCRgrLbAjLCBgsA5gIEMjsAFgQ7ACJbACJVFYIyA8sAFgI7ASZRwbISFZLbAkLLAjK7AjKi2wJSwgIEcgILACRWOwAUViYCNhOCMgilVYIEcgILACRWOwAUViYCNhOBshWS2wJiyxAAVFVFgAsAEWsCUqsAEVMBsiWS2wJyywByuxAAVFVFgAsAEWsCUqsAEVMBsiWS2wKCwgNbABYC2wKSwAsANFY7ABRWKwACuwAkVjsAFFYrAAK7AAFrQAAAAAAEQ+IzixKAEVKi2wKiwgPCBHILACRWOwAUViYLAAQ2E4LbArLC4XPC2wLCwgPCBHILACRWOwAUViYLAAQ2GwAUNjOC2wLSyxAgAWJSAuIEewACNCsAIlSYqKRyNHI2EgWGIbIVmwASNCsiwBARUUKi2wLiywABawBCWwBCVHI0cjYbAGRStlii4jICA8ijgtsC8ssAAWsAQlsAQlIC5HI0cjYSCwBCNCsAZFKyCwYFBYILBAUVizAiADIBuzAiYDGllCQiMgsAlDIIojRyNHI2EjRmCwBEOwgGJgILAAKyCKimEgsAJDYGQjsANDYWRQWLACQ2EbsANDYFmwAyWwgGJhIyAgsAQmI0ZhOBsjsAlDRrACJbAJQ0cjRyNhYCCwBEOwgGJgIyCwACsjsARDYLAAK7AFJWGwBSWwgGKwBCZhILAEJWBkI7ADJWBkUFghGyMhWSMgILAEJiNGYThZLbAwLLAAFiAgILAFJiAuRyNHI2EjPDgtsDEssAAWILAJI0IgICBGI0ewACsjYTgtsDIssAAWsAMlsAIlRyNHI2GwAFRYLiA8IyEbsAIlsAIlRyNHI2EgsAUlsAQlRyNHI2GwBiWwBSVJsAIlYbABRWMjIFhiGyFZY7ABRWJgIy4jICA8ijgjIVktsDMssAAWILAJQyAuRyNHI2EgYLAgYGawgGIjICA8ijgtsDQsIyAuRrACJUZSWCA8WS6xJAEUKy2wNSwjIC5GsAIlRlBYIDxZLrEkARQrLbA2LCMgLkawAiVGUlggPFkjIC5GsAIlRlBYIDxZLrEkARQrLbA3LLAuKyMgLkawAiVGUlggPFkusSQBFCstsDgssC8riiAgPLAEI0KKOCMgLkawAiVGUlggPFkusSQBFCuwBEMusCQrLbA5LLAAFrAEJbAEJiAuRyNHI2GwBkUrIyA8IC4jOLEkARQrLbA6LLEJBCVCsAAWsAQlsAQlIC5HI0cjYSCwBCNCsAZFKyCwYFBYILBAUVizAiADIBuzAiYDGllCQiMgR7AEQ7CAYmAgsAArIIqKYSCwAkNgZCOwA0NhZFBYsAJDYRuwA0NgWbADJbCAYmGwAiVGYTgjIDwjOBshICBGI0ewACsjYTghWbEkARQrLbA7LLAuKy6xJAEUKy2wPCywLyshIyAgPLAEI0IjOLEkARQrsARDLrAkKy2wPSywABUgR7AAI0KyAAEBFRQTLrAqKi2wPiywABUgR7AAI0KyAAEBFRQTLrAqKi2wPyyxAAEUE7ArKi2wQCywLSotsEEssAAWRSMgLiBGiiNhOLEkARQrLbBCLLAJI0KwQSstsEMssgAAOistsEQssgABOistsEUssgEAOistsEYssgEBOistsEcssgAAOystsEgssgABOystsEkssgEAOystsEossgEBOystsEsssgAANystsEwssgABNystsE0ssgEANystsE4ssgEBNystsE8ssgAAOSstsFAssgABOSstsFEssgEAOSstsFIssgEBOSstsFMssgAAPCstsFQssgABPCstsFUssgEAPCstsFYssgEBPCstsFcssgAAOCstsFgssgABOCstsFkssgEAOCstsFossgEBOCstsFsssDArLrEkARQrLbBcLLAwK7A0Ky2wXSywMCuwNSstsF4ssAAWsDArsDYrLbBfLLAxKy6xJAEUKy2wYCywMSuwNCstsGEssDErsDUrLbBiLLAxK7A2Ky2wYyywMisusSQBFCstsGQssDIrsDQrLbBlLLAyK7A1Ky2wZiywMiuwNistsGcssDMrLrEkARQrLbBoLLAzK7A0Ky2waSywMyuwNSstsGossDMrsDYrLbBrLCuwCGWwAyRQeLABFTAtAABLuADIUlixAQGOWbkIAAgAYyCwASNEILADI3CwDkUgIEu4AA5RS7AGU1pYsDQbsChZYGYgilVYsAIlYbABRWMjYrACI0SzCgkFBCuzCgsFBCuzDg8FBCtZsgQoCUVSRLMKDQYEK7EGAUSxJAGIUViwQIhYsQYDRLEmAYhRWLgEAIhYsQYBRFlZWVm4Af+FsASNsQUARAAAAA==\") format(\"truetype\");\n}\n\n.iconfont {\n  font-family: iconfont !important;\n  font-size: 16px;\n  font-style: normal;\n  -webkit-font-smoothing: antialiased;\n  -webkit-text-stroke-width: 0.2px;\n  -moz-osx-font-smoothing: grayscale;\n}\n\n[data-dpr=\"2\"] .tab-header {\n  font-size: 28px;\n}\n\n[data-dpr=\"3\"] .tab-header {\n  font-size: 42px;\n}\n\n[data-dpr=\"2\"] .tabheader .hl-icon {\n  font-size: 28px;\n}\n\n[data-dpr=\"3\"] .tabheader .hl-icon {\n  font-size: 42px;\n}\n\n[data-dpr=\"2\"] .tab-header .fold-toggle {\n  font-size: 28px;\n}\n\n[data-dpr=\"3\"] .tab-header .fold-toggle {\n  font-size: 42px;\n}",".tab-header {\n  position: relative;\n  width: 10rem;\n  font-size: 14px;\n  color: #333; }\n  .tab-header .header-bar {\n    height: 1.17rem;\n    line-height: 1.17rem;\n    display: none;\n    color: #999;\n    padding-left: 0.4rem; }\n  .tab-header .header-body {\n    margin-right: 1.07rem;\n    overflow-x: auto;\n    overflow-y: hidden; }\n    .tab-header .header-body::-webkit-scrollbar {\n      width: 0;\n      height: 0;\n      overflow: hidden; }\n  .tab-header .fold-toggle {\n    position: absolute;\n    top: 0.59rem;\n    -webkit-transform: translateY(-50%);\n    right: 0.29rem;\n    width: 0.48rem;\n    height: 0.48rem;\n    line-height: 0.48rem;\n    text-align: center;\n    z-index: 99;\n    font-size: 14px; }\n  .tab-header.unfold-header {\n    position: fixed !important;\n    top: 0;\n    left: 0;\n    overflow: hidden; }\n\n.tabheader {\n  list-style: none;\n  white-space: nowrap;\n  height: 1.17rem;\n  line-height: 1.17rem; }\n  .tabheader .th-item {\n    padding-left: 0.72rem;\n    position: relative;\n    display: inline-block; }\n  .tabheader .hl-icon {\n    width: 0.4rem;\n    height: 0.4rem;\n    line-height: 0.4rem;\n    text-align: center;\n    position: absolute;\n    top: 50%;\n    -webkit-transform: translateY(-50%);\n    left: 0.24rem;\n    font-size: 14px; }\n\n.unfold-header .header-bar {\n  display: block; }\n\n.unfold-header .fold-toggle {\n  -webkit-transform: translateY(-50%) rotate(180deg); }\n\n.unfold-header .header-body {\n  margin-right: 0;\n  padding: 0.24rem; }\n\n.unfold-header .tabheader {\n  display: block;\n  height: auto; }\n\n.unfold-header .th-item {\n  box-sizing: border-box;\n  float: left;\n  width: 33.3333%;\n  height: 1.01rem;\n  line-height: 1.01rem; }\n\n.unfold-header .hl-icon {\n  margin-right: 0;\n  position: absolute; }\n\n.unfold-header.tabheader-mask {\n  display: block;\n  width: 100%;\n  height: 100%;\n  background-color: rgba(0, 0, 0, 0.6); }\n\n.tabheader-mask {\n  display: none;\n  position: fixed;\n  left: 0;\n  top: 0; }\n\n@font-face {\n  font-family: \"iconfont\";\n  src: url(\"data:application/x-font-ttf;charset=utf-8;base64,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R7AEQ7CAYmAgsAArIIqKYSCwAkNgZCOwA0NhZFBYsAJDYRuwA0NgWbADJbCAYmGwAiVGYTgjIDwjOBshICBGI0ewACsjYTghWbEkARQrLbA7LLAuKy6xJAEUKy2wPCywLyshIyAgPLAEI0IjOLEkARQrsARDLrAkKy2wPSywABUgR7AAI0KyAAEBFRQTLrAqKi2wPiywABUgR7AAI0KyAAEBFRQTLrAqKi2wPyyxAAEUE7ArKi2wQCywLSotsEEssAAWRSMgLiBGiiNhOLEkARQrLbBCLLAJI0KwQSstsEMssgAAOistsEQssgABOistsEUssgEAOistsEYssgEBOistsEcssgAAOystsEgssgABOystsEkssgEAOystsEossgEBOystsEsssgAANystsEwssgABNystsE0ssgEANystsE4ssgEBNystsE8ssgAAOSstsFAssgABOSstsFEssgEAOSstsFIssgEBOSstsFMssgAAPCstsFQssgABPCstsFUssgEAPCstsFYssgEBPCstsFcssgAAOCstsFgssgABOCstsFkssgEAOCstsFossgEBOCstsFsssDArLrEkARQrLbBcLLAwK7A0Ky2wXSywMCuwNSstsF4ssAAWsDArsDYrLbBfLLAxKy6xJAEUKy2wYCywMSuwNCstsGEssDErsDUrLbBiLLAxK7A2Ky2wYyywMisusSQBFCstsGQssDIrsDQrLbBlLLAyK7A1Ky2wZiywMiuwNistsGcssDMrLrEkARQrLbBoLLAzK7A0Ky2waSywMyuwNSstsGossDMrsDYrLbBrLCuwCGWwAyRQeLABFTAtAABLuADIUlixAQGOWbkIAAgAYyCwASNEILADI3CwDkUgIEu4AA5RS7AGU1pYsDQbsChZYGYgilVYsAIlYbABRWMjYrACI0SzCgkFBCuzCgsFBCuzDg8FBCtZsgQoCUVSRLMKDQYEK7EGAUSxJAGIUViwQIhYsQYDRLEmAYhRWLgEAIhYsQYBRFlZWVm4Af+FsASNsQUARAAAAA==\") format(\"truetype\"); }\n\n.iconfont {\n  font-family: iconfont !important;\n  font-size: 16px;\n  font-style: normal;\n  -webkit-font-smoothing: antialiased;\n  -webkit-text-stroke-width: 0.2px;\n  -moz-osx-font-smoothing: grayscale; }\n\n[data-dpr=\"2\"] .tab-header {\n  font-size: 28px; }\n\n[data-dpr=\"3\"] .tab-header {\n  font-size: 42px; }\n\n[data-dpr=\"2\"] .tabheader .hl-icon {\n  font-size: 28px; }\n\n[data-dpr=\"3\"] .tabheader .hl-icon {\n  font-size: 42px; }\n\n[data-dpr=\"2\"] .tab-header .fold-toggle {\n  font-size: 28px; }\n\n[data-dpr=\"3\"] .tab-header .fold-toggle {\n  font-size: 42px; }\n"],"sourceRoot":"webpack://"}]);
-  
-  // exports
-
-
-/***/ },
-/* 51 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  __webpack_require__(52)
-  __webpack_require__(32)
-  
-  // lib.scroll events:
-  //  - scrollstart
-  //  - scrolling
-  //  - pulldownend
-  //  - pullupend
-  //  - pullleftend
-  //  - pullrightend
-  //  - pulldown
-  //  - pullup
-  //  - pullleft
-  //  - pullright
-  //  - contentrefresh
-  
-  var Component = __webpack_require__(16)
-  var utils = __webpack_require__(7)
-  
-  // attrs:
-  //  - scroll-direciton: none|vertical|horizontal (default is vertical)
-  //  - show-scrollbar: true|false (default is true)
-  function Scroller (data, nodeType) {
-    var attrs = data.attr || {}
-    this.items = []
-    this.totalWidth = 0
-    this.scrollDirection = attrs.scrollDirection === 'horizontal'
-                            ? 'horizontal'
-                            : 'vertical'
-    this.showScrollbar = attrs.showScrollbar || true
-    Component.call(this, data, nodeType)
-  }
-  
-  Scroller.prototype = Object.create(Component.prototype)
-  
-  Scroller.prototype.create = function (nodeType) {
-    var Scroll = lib.scroll
-    var node = Component.prototype.create.call(this, nodeType)
-    node.classList.add('weex-container', 'scroll-wrap')
-    this.scrollElement = document.createElement('div')
-    this.scrollElement.classList.add(
-      'weex-container',
-      'scroll-element',
-      this.scrollDirection
-    )
-    node.appendChild(this.scrollElement)
-    this.scroller = new Scroll({
-      scrollElement: this.scrollElement,
-      direction: this.scrollDirection === 'vertical' ? 'y' : 'x'
-    })
-    this.scroller.init()
-    return node
-  }
-  
-  Scroller.prototype.bindEvents = function (evts) {
-    Component.prototype.bindEvents.call(this, evts)
-    // to enable lazyload for Images
-    this.scroller.addEventListener('scrolling', function (e) {
-      var so = e.scrollObj
-      this.dispatchEvent('scroll', {
-        originalType: 'scrolling',
-        scrollTop: so.getScrollTop(),
-        scrollLeft: so.getScrollLeft()
-      }, {
-        bubbles: true
-      })
-    }.bind(this))
-  }
-  
-  Scroller.prototype.appendChild = function (data) {
-    var children = this.data.children
-    var componentManager = this.getComponentManager()
-    var child = componentManager.createElement(data)
-    this.scrollElement.appendChild(child.node)
-  
-    var childWidth = child.node.getBoundingClientRect().width
-    this.totalWidth += childWidth
-    // if direction is horizontal then the width of scrollElement
-    // should be set manually due to flexbox's rule (child elements
-    // will not exceed box's width but to shrink to adapt).
-    if (this.scrollDirection === 'horizontal') {
-      this.scrollElement.style.width = this.totalWidth + 'px'
-    }
-  
-    // update this.data.children
-    if (!children || !children.length) {
-      this.data.children = [data]
-    } else {
-      children.push(data)
-    }
-  
-    this.items.push(child)
-    return child
-  }
-  
-  Scroller.prototype.insertBefore = function (child, before) {
-    var children = this.data.children
-    var i = 0
-    var isAppend = false
-  
-    // update this.data.children
-    if (!children || !children.length || !before) {
-      isAppend = true
-    } else {
-      for (var l = children.length; i < l; i++) {
-        if (children[i].ref === child.data.ref) {
-          break
-        }
-      }
-      if (i === l) {
-        isAppend = true
-      }
-    }
-  
-    if (isAppend) {
-      this.scrollElement.appendChild(child.node)
-      children.push(child.data)
-      this.items.push(child)
-    } else {
-      this.scrollElement.insertBefore(child.node, before.node)
-      children.splice(i, 0, child.data)
-      this.items.splice(i, 0, child)
-    }
-  }
-  
-  Scroller.prototype.removeChild = function () {
-    var children = this.data.children
-    // remove from this.data.children
-    var i = 0
-    var componentManager = this.getComponentManager()
-    if (children && children.length) {
-      for (var l = children.length; i < l; i++) {
-        if (children[i].ref === child.data.ref) {
-          break
-        }
-      }
-      if (i < l) {
-        children.splice(i, 1)
-        this.items.splice(i, 1)
-      }
-    }
-    // remove from componentMap recursively
-    componentManager.removeElementByRef(child.data.ref)
-    this.scrollElement.removeChild(child.node)
-  }
-  
-  module.exports = Scroller
-
-
-/***/ },
-/* 52 */
-/***/ function(module, exports, __webpack_require__) {
-
-  // style-loader: Adds some css to the DOM by adding a <style> tag
-  
-  // load the styles
-  var content = __webpack_require__(53);
-  if(typeof content === 'string') content = [[module.id, content, '']];
-  // add the styles to the DOM
-  var update = __webpack_require__(4)(content, {});
-  if(content.locals) module.exports = content.locals;
-  // Hot Module Replacement
-  if(false) {
-    // When the styles change, update the <style> tags
-    if(!content.locals) {
-      module.hot.accept("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./scroller.scss", function() {
-        var newContent = require("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./scroller.scss");
-        if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
-        update(newContent);
-      });
-    }
-    // When the module is disposed, remove the <style> tags
-    module.hot.dispose(function() { update(); });
-  }
-
-/***/ },
-/* 53 */
-/***/ function(module, exports, __webpack_require__) {
-
-  exports = module.exports = __webpack_require__(3)();
-  // imports
-  
-  
-  // module
-  exports.push([module.id, ".scroll-wrap {\n  display: block;\n  overflow: hidden; }\n\n.scroll-element.horizontal {\n  -webkit-box-orient: horizontal;\n  -webkit-flex-direction: row;\n  flex-direction: row; }\n\n.scroll-element.vertical {\n  -webkit-box-orient: vertical;\n  -webkit-flex-direction: column;\n  flex-direction: column; }\n", "", {"version":3,"sources":["/./src/src/styles/scroller.scss"],"names":[],"mappings":"AAAA;EACC,eAAe;EACf,iBAAiB,EACjB;;AAED;EAEI,+BAA+B;EAC/B,4BAA4B;EAC5B,oBAAoB,EACrB;;AALH;EAOI,6BAA6B;EAC7B,+BAA+B;EAC/B,uBAAuB,EACxB","file":"scroller.scss","sourcesContent":[".scroll-wrap {\n\tdisplay: block;\n\toverflow: hidden;\n}\n\n.scroll-element {\n  &.horizontal {\n    -webkit-box-orient: horizontal;\n    -webkit-flex-direction: row;\n    flex-direction: row;\n  }\n  &.vertical {\n    -webkit-box-orient: vertical;\n    -webkit-flex-direction: column;\n    flex-direction: column;\n  }\n}"],"sourceRoot":"webpack://"}]);
-  
-  // exports
-
-
-/***/ },
-/* 54 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  var Atomic = __webpack_require__(27)
-  var utils = __webpack_require__(7)
-  
-  // attrs:
-  //   - type: text|password|tel|email|url
-  //   - value
-  //   - placeholder
-  //   - disabled
-  //   - autofocus
-  function Input (data) {
-    var attrs = data.attr || {}
-    this.type = attrs.type || 'text'
-    this.value = attrs.value
-    this.placeholder = attrs.placeholder
-    this.autofocus = attrs.autofocus && (attrs.autofocus !== 'false')
-                      ? true
-                      : false
-    Atomic.call(this, data)
-  }
-  
-  Input.prototype = Object.create(Atomic.prototype)
-  
-  Input.prototype.create = function () {
-    var node = document.createElement('input')
-    var uuid = Math.floor(10000000000000 * Math.random()) + Date.now()
-    this.className = 'weex-ipt-' + uuid
-    this.styleId = 'weex-style-' + uuid
-    node.classList.add(this.className)
-    node.setAttribute('type', this.type)
-    node.type = this.type
-    // For the consistency of input component's width.
-    // The date and time type of input will have a bigger width
-    // when the 'box-sizing' is not set to 'border-box'
-    node.classList.add('weex-element')
-    this.value && (node.value = this.value)
-    this.placeholder && (node.placeholder = this.placeholder)
-    return node
-  }
-  
-  Input.prototype.updateStyle = function (style) {
-    Atomic.prototype.updateStyle.call(this, style)
-    if (style && style.placeholderColor) {
-      this.placeholderColor = style.placeholderColor
-      this.setPlaceholderColor()
-    }
-  }
-  
-  Input.prototype.attr = {
-    disabled: function (val) {
-      this.node.disabled = val && val !== 'false'
-                      ? true
-                      : false
-    }
-  }
-  
-  Input.prototype.setPlaceholderColor = function () {
-    if (!this.placeholderColor) {
-      return
-    }
-    var vendors = [
-      '::-webkit-input-placeholder',
-      ':-moz-placeholder',
-      '::-moz-placeholder',
-      ':-ms-input-placeholder',
-      ':placeholder-shown'
-    ]
-    var css = ''
-    var cssRule = 'color: ' + this.placeholderColor + ';'
-    for (var i = 0, l = vendors.length; i < l; i++) {
-      css += '.' + this.className + vendors[i] + '{'
-             + cssRule + '}'
-    }
-    utils.appendStyle(css, this.styleId, true)
-  }
-  
-  module.exports = Input
-
-
-/***/ },
-/* 55 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  var Atomic = __webpack_require__(16)
-  var sender = __webpack_require__(19)
-  
-  // attrs:
-  //   - options: the options to be listed, as a array of strings.
-  //   - selectedIndex: the selected options' index number.
-  //   - disabled
-  function Select (data) {
-    var attrs = data.attr || {}
-    this.options = []
-    this.selectedIndex = 0
-    Atomic.call(this, data)
-  }
-  
-  Select.prototype = Object.create(Atomic.prototype)
-  
-  Select.prototype.create = function () {
-    var node = document.createElement('select')
-    var uuid = Math.floor(10000000000000 * Math.random()) + Date.now()
-    this.className = 'weex-slct-' + uuid
-    this.styleId = 'weex-style-' + uuid
-    node.classList.add(this.className)
-    // For the consistency of input component's width.
-    // The date and time type of input will have a bigger width
-    // when the 'box-sizing' is not set to 'border-box'
-    node.style['box-sizing'] = 'border-box'
-    return node
-  }
-  
-  Select.prototype.attr = {
-    disabled: function (val) {
-      this.node.disabled = val && val !== 'false'
-                      ? true
-                      : false
-    },
-    options: function (val) {
-      if (Object.prototype.toString.call(val) !== '[object Array]') {
-        return
-      }
-      this.options = val
-      this.node.innerHTML = ''
-      this.createOptions(val)
-    },
-    selectedIndex: function (val) {
-      val = parseInt(val)
-      if (typeof val !== 'number' || val !== val || val >= this.options.length) {
-        return
-      }
-      this.node.value = this.options[val]
-    }
-  }
-  
-  Select.prototype.bindEvents = function (evts) {
-    var isListenToChange = false
-    Atomic.prototype.bindEvents.call(
-        this,
-        evts.filter(function (val) {
-          var pass = val !== 'change'
-          !pass && (isListenToChange = true)
-          return pass
-        }))
-    if (isListenToChange) {
-      this.node.addEventListener('change', function (e) {
-        e.index = this.options.indexOf(this.node.value)
-        sender.fireEvent(this.data.ref, 'change', e)
-      }.bind(this))
-    }
-  }
-  
-  Select.prototype.createOptions = function (opts) {
-    var optDoc = document.createDocumentFragment()
-    var opt
-    for (var i = 0, l = opts.length; i < l; i++) {
-      opt = document.createElement('option')
-      opt.appendChild(document.createTextNode(opts[i]))
-      optDoc.appendChild(opt)
-    }
-    this.node.appendChild(optDoc)
-  }
-  
-  module.exports = Select
-
-
-/***/ },
-/* 56 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  var Atomic = __webpack_require__(27)
-  
-  // attrs:
-  //   - value
-  //   - disabled
-  function Datepicker (data) {
-    Atomic.call(this, data)
-  }
-  
-  Datepicker.prototype = Object.create(Atomic.prototype)
-  
-  Datepicker.prototype.create = function () {
-    var node = document.createElement('input')
-    var uuid = Math.floor(10000000000000 * Math.random()) + Date.now()
-    this.className = 'weex-ipt-' + uuid
-    this.styleId = 'weex-style-' + uuid
-    node.classList.add(this.className)
-    node.setAttribute('type', 'date')
-    node.type = 'date'
-    // For the consistency of input component's width.
-    // The date and time type of input will have a bigger width
-    // when the 'box-sizing' is not set to 'border-box'
-    node.classList.add('weex-element')
-    return node
-  }
-  
-  Datepicker.prototype.attr = {
-    disabled: function (val) {
-      this.node.disabled = val && val !== 'false'
-                      ? true
-                      : false
-    }
-  }
-  
-  module.exports = Datepicker
-
-
-/***/ },
-/* 57 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  var Atomic = __webpack_require__(27)
-  
-  // attrs:
-  //   - value
-  //   - disabled
-  function Timepicker (data) {
-    Atomic.call(this, data)
-  }
-  
-  Timepicker.prototype = Object.create(Atomic.prototype)
-  
-  Timepicker.prototype.create = function () {
-    var node = document.createElement('input')
-    var uuid = Math.floor(10000000000000 * Math.random()) + Date.now()
-    this.className = 'weex-ipt-' + uuid
-    this.styleId = 'weex-style-' + uuid
-    node.classList.add(this.className)
-    node.setAttribute('type', 'time')
-    node.type = 'time'
-    // For the consistency of input component's width.
-    // The date and time type of input will have a bigger width
-    // when the 'box-sizing' is not set to 'border-box'
-    node.classList.add('weex-element')
-    return node
-  }
-  
-  Timepicker.prototype.attr = {
-    disabled: function (val) {
-      this.node.disabled = val && val !== 'false'
-                      ? true
-                      : false
-    }
-  }
-  
-  module.exports = Timepicker
-
-
-/***/ },
-/* 58 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  var Atomic = __webpack_require__(27)
-  var utils = __webpack_require__(7)
-  __webpack_require__(59)
-  
-  // attrs:
-  //   - autoPlay: true | false (default: false)
-  //   - playStatus: play | pause | stop
-  //   - src: {string}
-  //   - poster: {string}
-  //   - loop: true | false (default: false)
-  //   - muted: true | false (default: false)
-  // events:
-  //   - start
-  //   - pause
-  //   - finish
-  //   - fail
-  function Video (data) {
-    var autoPlay = data.attr.autoPlay
-    var playStatus = data.attr.playStatus
-    this.autoPlay = autoPlay === true || autoPlay === 'true'
-    if (playStatus !== 'play'
-        && playStatus !== 'stop'
-        && playStatus !== 'pause') {
-      this.playStatus = 'pause'
-    } else {
-      this.playStatus = playStatus
-    }
-    Atomic.call(this, data)
-  }
-  
-  Video.prototype = Object.create(Atomic.prototype)
-  
-  Video.prototype.attr = {
-    playStatus: function (val) {
-      if (val !== 'play' && val !== 'stop' && val !== 'pause') {
-        val = 'pause'
-      }
-      if (this.playStatus === val) {
-        return
-      }
-      this.playStatus = val
-      this.node.setAttribute('play-status', val)
-      this[this.playStatus]()
-    },
-    autoPlay: function (val) {
-      // DO NOTHING
-    }
-  }
-  
-  Video.prototype.create = function () {
-    var node = document.createElement('video')
-    node.classList.add('weex-video', 'weex-element')
-    node.controls = true
-    node.autoplay = this.autoPlay
-    node.setAttribute('play-status', this.playStatus)
-    this.node = node
-    if (this.autoPlay && this.playStatus === 'play') {
-      this.play()
-    }
-    return node
-  }
-  
-  Video.prototype.bindEvents = function (evts) {
-    Atomic.prototype.bindEvents.call(this, evts)
-  
-    // convert w3c-video events to weex-video events.
-    var evtsMap = {
-      start: 'play',
-      finish: 'ended',
-      fail: 'error'
-    }
-    for (var evtName in evtsMap) {
-      this.node.addEventListener(evtsMap[evtName], function (type, e) {
-        this.dispatchEvent(type, e.data)
-      }.bind(this, evtName))
-    }
-  }
-  
-  Video.prototype.play = function () {
-    var src = this.node.getAttribute('src')
-    if (!src) {
-      src = this.node.getAttribute('data-src')
-      src && this.node.setAttribute('src', src)
-    }
-    this.node.play()
-  }
-  
-  Video.prototype.pause = function () {
-    this.node.pause()
-  }
-  
-  Video.prototype.stop = function () {
-    this.node.pause()
-    this.node.autoplay = false
-    this.node.setAttribute('data-src', this.node.src)
-    this.node.src = ''
-  }
-  
-  module.exports = Video
-
-
-/***/ },
-/* 59 */
-/***/ function(module, exports, __webpack_require__) {
-
-  // style-loader: Adds some css to the DOM by adding a <style> tag
-  
-  // load the styles
-  var content = __webpack_require__(60);
-  if(typeof content === 'string') content = [[module.id, content, '']];
-  // add the styles to the DOM
-  var update = __webpack_require__(4)(content, {});
-  if(content.locals) module.exports = content.locals;
-  // Hot Module Replacement
-  if(false) {
-    // When the styles change, update the <style> tags
-    if(!content.locals) {
-      module.hot.accept("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./video.scss", function() {
-        var newContent = require("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./video.scss");
-        if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
-        update(newContent);
-      });
-    }
-    // When the module is disposed, remove the <style> tags
-    module.hot.dispose(function() { update(); });
-  }
-
-/***/ },
-/* 60 */
-/***/ function(module, exports, __webpack_require__) {
-
-  exports = module.exports = __webpack_require__(3)();
-  // imports
-  
-  
-  // module
-  exports.push([module.id, ".weex-video {\n  background-color: #000; }\n", "", {"version":3,"sources":["/./src/src/styles/video.scss"],"names":[],"mappings":"AAAA;EACC,uBAAuB,EACvB","file":"video.scss","sourcesContent":[".weex-video {\n\tbackground-color: #000;\n}"],"sourceRoot":"webpack://"}]);
-  
-  // exports
-
-
-/***/ },
-/* 61 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  var Atomic = __webpack_require__(27)
-  var utils = __webpack_require__(7)
-  __webpack_require__(62)
-  
-  var defaults = {
-    color: '#64bd63'
-    , secondaryColor: '#dfdfdf'
-    , jackColor: '#fff'
-    , jackSecondaryColor: null
-    , className: 'weex-switch'
-    , disabledOpacity: 0.5
-    , speed: '0.4s'
-    , width: 100
-    , height: 60
-    // is width and height scalable ?
-    , scalable: false
-  }
-  
-  // attrs:
-  //   - checked: if is checked.
-  //   - disabled: if true, this component is not available for interaction.
-  function Switch (data) {
-    this.options = utils.extend({}, defaults)
-    this.checked = data.attr.checked
-        && data.attr.checked !== 'false' ? true : false
-    this.data = data
-    this.width = this.options.width * data.scale
-    this.height = this.options.height * data.scale
-    Atomic.call(this, data)
-  }
-  
-  Switch.prototype = Object.create(Atomic.prototype)
-  
-  Switch.prototype.create = function () {
-    var node = document.createElement('span')
-    this.jack = document.createElement('small')
-    node.appendChild(this.jack)
-    node.className = this.options.className
-    this.node = node
-    this.attr.disabled.call(this, this.data.attr.disabled)
-    return node
-  }
-  
-  Switch.prototype.onAppend = function () {
-    this.setSize()
-    this.setPosition()
-  }
-  
-  Switch.prototype.attr = {
-    disabled: function (val) {
-      this.disabled = val && val !== 'false'
-                      ? true
-                      : false
-      this.disabled ? this.disable() : this.enable()
-    }
-  }
-  
-  Switch.prototype.setSize = function () {
-    var min = Math.min(this.width, this.height)
-    var max = Math.max(this.width, this.height)
-    this.node.style.width = max + 'px'
-    this.node.style.height = min + 'px'
-    this.node.style.borderRadius = min / 2 + 'px'
-    this.jack.style.width
-        = this.jack.style.height
-        = min + 'px'
-  }
-  
-  Switch.prototype.setPosition = function (clicked) {
-    var checked = this.checked
-    var node = this.node
-    var jack = this.jack
-  
-    if (clicked && checked) {
-      checked = false
-    } else if (clicked && !checked) {
-      checked = true
-    }
-  
-    if (checked === true) {
-      this.checked = true
-  
-      if (window.getComputedStyle) {
-        jack.style.left = parseInt(window.getComputedStyle(node).width)
-                          - parseInt(window.getComputedStyle(jack).width) + 'px'
-      } else {
-        jack.style.left = parseInt(node.currentStyle['width'])
-                          - parseInt(jack.currentStyle['width']) + 'px'
-      }
-  
-      this.options.color && this.colorize()
-      this.setSpeed()
-    } else {
-      this.checked = false
-      jack.style.left = 0
-      node.style.boxShadow = 'inset 0 0 0 0 ' + this.options.secondaryColor
-      node.style.borderColor = this.options.secondaryColor
-      node.style.backgroundColor
-          = (this.options.secondaryColor !== defaults.secondaryColor)
-            ? this.options.secondaryColor
-            : '#fff'
-      jack.style.backgroundColor
-          = (this.options.jackSecondaryColor !== this.options.jackColor)
-            ? this.options.jackSecondaryColor
-            : this.options.jackColor
-      this.setSpeed()
-    }
-  }
-  
-  Switch.prototype.colorize = function () {
-    var nodeHeight = this.node.offsetHeight / 2
-  
-    this.node.style.backgroundColor = this.options.color
-    this.node.style.borderColor = this.options.color
-    this.node.style.boxShadow = 'inset 0 0 0 '
-                                + nodeHeight
-                                + 'px '
-                                + this.options.color
-    this.jack.style.backgroundColor = this.options.jackColor
-  }
-  
-  Switch.prototype.setSpeed = function () {
-    var switcherProp = {}
-    var jackProp = {
-        'background-color': this.options.speed
-        , left: this.options.speed.replace(/[a-z]/, '') / 2 + 's'
-      }
-  
-    if (this.checked) {
-      switcherProp = {
-        border: this.options.speed
-        , 'box-shadow': this.options.speed
-        , 'background-color': this.options.speed.replace(/[a-z]/, '') * 3 + 's'
-      }
-    } else {
-      switcherProp = {
-        border: this.options.speed
-        , 'box-shadow': this.options.speed
-      }
-    }
-  
-    utils.transitionize(this.node, switcherProp)
-    utils.transitionize(this.jack, jackProp)
-  }
-  
-  Switch.prototype.disable = function () {
-    !this.disabled && (this.disabled = true)
-    this.node.style.opacity = defaults.disabledOpacity
-    this.node.removeEventListener('click', this.getClickHandler())
-  }
-  
-  Switch.prototype.enable = function () {
-    this.disabled && (this.disabled = false)
-    this.node.style.opacity = 1
-    this.node.addEventListener('click', this.getClickHandler())
-  }
-  
-  Switch.prototype.getClickHandler = function () {
-    if (!this._clickHandler) {
-      this._clickHandler = function () {
-        // var parent = this.node.parentNode.tagName.toLowerCase()
-        // var labelParent = (parent === 'label') ? false : true
-        this.setPosition(true)
-        this.dispatchEvent('change', {
-          checked: this.checked
-        })
-      }.bind(this)
-    }
-    return this._clickHandler
-  }
-  
-  Switch.prototype.style
-      = utils.extend(Object.create(Atomic.prototype.style), {
-  
-        width: function (val) {
-          if (!this.options.scalable) {
-            return
-          }
-          val = parseFloat(val)
-          if (val !== val || val < 0) { // NaN
-            val = this.options.width
-          }
-          this.width = val * this.data.scale
-          this.setSize()
-        },
-  
-        height: function (val) {
-          if (!this.options.scalable) {
-            return
-          }
-          val = parseFloat(val)
-          if (val !== val || val < 0) { // NaN
-            val = this.options.height
-          }
-          this.height = val * this.data.scale
-          this.setSize()
-        }
-  
-      })
-  
-  module.exports = Switch
-
-
-/***/ },
-/* 62 */
-/***/ function(module, exports, __webpack_require__) {
-
-  // style-loader: Adds some css to the DOM by adding a <style> tag
-  
-  // load the styles
-  var content = __webpack_require__(63);
-  if(typeof content === 'string') content = [[module.id, content, '']];
-  // add the styles to the DOM
-  var update = __webpack_require__(4)(content, {});
-  if(content.locals) module.exports = content.locals;
-  // Hot Module Replacement
-  if(false) {
-    // When the styles change, update the <style> tags
-    if(!content.locals) {
-      module.hot.accept("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./switch.scss", function() {
-        var newContent = require("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./switch.scss");
-        if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
-        update(newContent);
-      });
-    }
-    // When the module is disposed, remove the <style> tags
-    module.hot.dispose(function() { update(); });
-  }
-
-/***/ },
-/* 63 */
-/***/ function(module, exports, __webpack_require__) {
-
-  exports = module.exports = __webpack_require__(3)();
-  // imports
-  
-  
-  // module
-  exports.push([module.id, "/* switch defaults. */\n.weex-switch {\n  background-color: #fff;\n  border: 1px solid #dfdfdf;\n  cursor: pointer;\n  display: inline-block;\n  position: relative;\n  vertical-align: middle;\n  -moz-user-select: none;\n  -khtml-user-select: none;\n  -webkit-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n  box-sizing: content-box;\n  background-clip: content-box; }\n\n.weex-switch > small {\n  background: #fff;\n  border-radius: 100%;\n  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);\n  position: absolute;\n  top: 0; }\n", "", {"version":3,"sources":["/./src/src/styles/switch.scss"],"names":[],"mappings":"AAAA,sBAAsB;AAEtB;EACE,uBAAuB;EACvB,0BAA0B;EAC1B,gBAAgB;EAChB,sBAAsB;EACtB,mBAAmB;EACnB,uBAAuB;EAEvB,uBAAuB;EACvB,yBAAyB;EACzB,0BAA0B;EAC1B,sBAAsB;EACtB,kBAAkB;EAClB,wBAAwB;EACxB,6BAA6B,EAC9B;;AAED;EACE,iBAAiB;EACjB,oBAAoB;EACpB,yCAA0B;EAC1B,mBAAmB;EACnB,OAAO,EACR","file":"switch.scss","sourcesContent":["/* switch defaults. */\n\n.weex-switch {\n  background-color: #fff;\n  border: 1px solid #dfdfdf;\n  cursor: pointer;\n  display: inline-block;\n  position: relative;\n  vertical-align: middle;\n\n  -moz-user-select: none;\n  -khtml-user-select: none;\n  -webkit-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n  box-sizing: content-box;\n  background-clip: content-box;\n}\n\n.weex-switch > small {\n  background: #fff;\n  border-radius: 100%;\n  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);\n  position: absolute;\n  top: 0;\n}\n"],"sourceRoot":"webpack://"}]);
-  
-  // exports
-
-
-/***/ },
-/* 64 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  var Component = __webpack_require__(16)
-  
-  // attrs:
-  //   - href
-  function A (data) {
-    Component.call(this, data)
-  }
-  
-  A.prototype = Object.create(Component.prototype)
-  
-  A.prototype.create = function () {
-    var node = document.createElement('a')
-    node.classList.add('weex-container')
-    this.node = node
-    this.style.alignItems.call(this, 'center')
-    this.style.justifyContent.call(this, 'center')
-    this.node.style.textDecoration = 'none'
-    return node
-  }
-  
-  module.exports = A
-
-
-/***/ },
-/* 65 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  var Component = __webpack_require__(16)
-  var utils = __webpack_require__(7)
-  
-  var ID_PREFIX = 'weex_embed_'
-  
-  function _generateId() {
-    return ID_PREFIX + utils.getRandom(10)
-  }
-  
-  function Embed (data, nodeType) {
-    var attr = data.attr
-    if (attr) {
-      this.source = attr.src
-      this.loader = attr.loade || 'xhr'
-    }
-    Component.call(this, data, nodeType)
-    this.initWeex()
-  }
-  
-  Embed.prototype = Object.create(Component.prototype)
-  
-  Embed.prototype.create = function () {
-  
-    var node = document.createElement('div')
-    node.id = this.id
-    node.style.overflow = 'scroll'
-    // node.classList.add('weex-container')
-    return node
-  }
-  
-  Embed.prototype.initWeex = function () {
-    this.id = _generateId()
-    this.node.id = this.id
-    var config = {
-      appId: this.id,
-      source: this.source,
-      loader: this.loader,
-      width: this.node.getBoundingClientRect().width,
-      rootId: this.id
-    }
-    window.weex.init(config)
-  }
-  
-  Embed.prototype.destroyWeex = function () {
-    this.id && window.destroyInstance(this.id)
-    // TODO: unbind events and clear doms.
-    this.node.innerHTML = ''
-  }
-  
-  Embed.prototype.reloadWeex = function () {
-    this.destroyWeex()
-    this.initWeex()
-  }
-  
-  // src is not updatable temporarily
-  // Embed.prototype.attr = {
-  //   src: function (value) {
-  //     this.src = value
-  //     this.reloadWeex()
-  //   }
-  // }
-  
-  module.exports = Embed
-
-
-/***/ },
-/* 66 */
-/***/ function(module, exports, __webpack_require__) {
-
-  var dom = __webpack_require__(67)
-  var event = __webpack_require__(75)
-  var pageInfo = __webpack_require__(76)
-  var stream = __webpack_require__(77)
-  var modal = __webpack_require__(78)
-  var animation = __webpack_require__(95)
-  
-  var api = {
-    init: function (Weex) {
-      Weex.registerApiModule('dom', dom, dom._meta)
-      Weex.registerApiModule('event', event, event._meta)
-      Weex.registerApiModule('pageInfo', pageInfo, pageInfo._meta)
-      Weex.registerApiModule('stream', stream, stream._meta)
-      Weex.registerApiModule('modal', modal, modal._meta)
-      Weex.registerApiModule('animation', animation, animation._meta)
-    }
-  }
-  
-  module.exports = api
-
-/***/ },
-/* 67 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  var messageQueue = __webpack_require__(48)
-  var FrameUpdater = __webpack_require__(10)
-  var Component = __webpack_require__(16)
-  var scroll = __webpack_require__(68)
-  var config = __webpack_require__(5)
-  // var Weex = require('../weex')
-  
-  var dom = {
-  
-    /**
-     * createBody: create root component
-     * @param  {object} element
-     *    container|listview|scrollview
-     * @return {[type]}      [description]
-     */
-    createBody: function (element) {
-      var componentManager = this.getComponentManager()
-      element.scale = this.scale
-      element.instanceId = componentManager.instanceId
-      return componentManager.createBody(element)
-    },
-  
-    addElement: function (parentRef, element, index) {
-      var componentManager = this.getComponentManager()
-      element.scale = this.scale
-      element.instanceId = componentManager.instanceId
-      return componentManager.addElement(parentRef, element, index)
-    },
-  
-    removeElement: function (ref) {
-      var componentManager = this.getComponentManager()
-      return componentManager.removeElement(ref)
-    },
-  
-    moveElement: function (ref, parentRef, index) {
-      var componentManager = this.getComponentManager()
-      return componentManager.moveElement(ref, parentRef, index)
-    },
-  
-    addEvent: function (ref, type) {
-      var componentManager = this.getComponentManager()
-      return componentManager.addEvent(ref, type)
-    },
-  
-    removeEvent: function (ref, type) {
-      var componentManager = this.getComponentManager()
-      return componentManager.removeEvent(ref, type)
-    },
-  
-    /**
-     * updateAttrs: update attributes of component
-     * @param  {string} ref
-     * @param  {obj} attr
-     */
-    updateAttrs: function (ref, attr) {
-      var componentManager = this.getComponentManager()
-      return componentManager.updateAttrs(ref, attr)
-    },
-  
-    /**
-     * updateStyle: udpate style of component
-     * @param {string} ref
-     * @param {obj} style
-     */
-    updateStyle: function (ref, style) {
-      var componentManager = this.getComponentManager()
-      return componentManager.updateStyle(ref, style)
-    },
-  
-    createFinish: function () {
-      // TODO
-      // FrameUpdater.pause()
-    },
-  
-    refreshFinish: function () {
-      // TODO
-    },
-  
-    /**
-     * scrollToElement
-     * @param  {string} ref
-     * @param  {obj} options {offset:Number}
-     *   ps: scroll-to has 'ease' and 'duration'(ms) as options.
-     */
-    scrollToElement: function (ref, options) {
-      !options && (options = {})
-      var componentManager = this.getComponentManager()
-      var elem = componentManager.getElementByRef(ref)
-      if (elem) {
-        var offsetTop = elem.node.getBoundingClientRect().top
-            + document.body.scrollTop
-        var offset = (Number(options.offset) || 0) * this.scale
-        var tween = scroll(0, offsetTop + offset, options)
-        // tween.on('end', function () {
-        // })
-      }
-    }
-  
-  }
-  
-  dom._meta = {
-    dom: [{
-      name: 'createBody',
-      args: ['object']
-    }, {
-      name: 'addElement',
-      args: ['string', 'object', 'number']
-    }, {
-      name: 'removeElement',
-      args: ['string']
-    }, {
-      name: 'moveElement',
-      args: ['string', 'string', 'number']
-    }, {
-      name: 'addEvent',
-      args: ['string', 'string']
-    }, {
-      name: 'removeEvent',
-      args: ['string', 'string']
-    }, {
-      name: 'updateAttrs',
-      args: ['string', 'object']
-    }, {
-      name: 'updateStyle',
-      args: ['string', 'object']
-    }, {
-      name: 'createFinish',
-      args: []
-    }, {
-      name: 'refreshFinish',
-      args: []
-    }, {
-      name: 'scrollToElement',
-      args: ['string', 'object']
-    }]
-  }
-  
-  module.exports = dom
-
-
-/***/ },
-/* 68 */
-/***/ function(module, exports, __webpack_require__) {
-
-  /**
-   * Module dependencies.
-   */
-  
-  var Tween = __webpack_require__(69);
-  var raf = __webpack_require__(74);
-  
-  /**
-   * Expose `scrollTo`.
-   */
-  
-  module.exports = scrollTo;
-  
-  /**
-   * Scroll to `(x, y)`.
-   *
-   * @param {Number} x
-   * @param {Number} y
-   * @api public
-   */
-  
-  function scrollTo(x, y, options) {
-    options = options || {};
-  
-    // start position
-    var start = scroll();
-  
-    // setup tween
-    var tween = Tween(start)
-      .ease(options.ease || 'out-circ')
-      .to({ top: y, left: x })
-      .duration(options.duration || 1000);
-  
-    // scroll
-    tween.update(function(o){
-      window.scrollTo(o.left | 0, o.top | 0);
-    });
-  
-    // handle end
-    tween.on('end', function(){
-      animate = function(){};
-    });
-  
-    // animate
-    function animate() {
-      raf(animate);
-      tween.update();
-    }
-  
-    animate();
-    
-    return tween;
-  }
-  
-  /**
-   * Return scroll position.
-   *
-   * @return {Object}
-   * @api private
-   */
-  
-  function scroll() {
-    var y = window.pageYOffset || document.documentElement.scrollTop;
-    var x = window.pageXOffset || document.documentElement.scrollLeft;
-    return { top: y, left: x };
-  }
-
-
-/***/ },
-/* 69 */
-/***/ function(module, exports, __webpack_require__) {
-
-  
-  /**
-   * Module dependencies.
-   */
-  
-  var Emitter = __webpack_require__(70);
-  var clone = __webpack_require__(71);
-  var type = __webpack_require__(72);
-  var ease = __webpack_require__(73);
-  
-  /**
-   * Expose `Tween`.
-   */
-  
-  module.exports = Tween;
-  
-  /**
-   * Initialize a new `Tween` with `obj`.
-   *
-   * @param {Object|Array} obj
-   * @api public
-   */
-  
-  function Tween(obj) {
-    if (!(this instanceof Tween)) return new Tween(obj);
-    this._from = obj;
-    this.ease('linear');
-    this.duration(500);
-  }
-  
-  /**
-   * Mixin emitter.
-   */
-  
-  Emitter(Tween.prototype);
-  
-  /**
-   * Reset the tween.
-   *
-   * @api public
-   */
-  
-  Tween.prototype.reset = function(){
-    this.isArray = 'array' === type(this._from);
-    this._curr = clone(this._from);
-    this._done = false;
-    this._start = Date.now();
-    return this;
-  };
-  
-  /**
-   * Tween to `obj` and reset internal state.
-   *
-   *    tween.to({ x: 50, y: 100 })
-   *
-   * @param {Object|Array} obj
-   * @return {Tween} self
-   * @api public
-   */
-  
-  Tween.prototype.to = function(obj){
-    this.reset();
-    this._to = obj;
-    return this;
-  };
-  
-  /**
-   * Set duration to `ms` [500].
-   *
-   * @param {Number} ms
-   * @return {Tween} self
-   * @api public
-   */
-  
-  Tween.prototype.duration = function(ms){
-    this._duration = ms;
-    return this;
-  };
-  
-  /**
-   * Set easing function to `fn`.
-   *
-   *    tween.ease('in-out-sine')
-   *
-   * @param {String|Function} fn
-   * @return {Tween}
-   * @api public
-   */
-  
-  Tween.prototype.ease = function(fn){
-    fn = 'function' == typeof fn ? fn : ease[fn];
-    if (!fn) throw new TypeError('invalid easing function');
-    this._ease = fn;
-    return this;
-  };
-  
-  /**
-   * Stop the tween and immediately emit "stop" and "end".
-   *
-   * @return {Tween}
-   * @api public
-   */
-  
-  Tween.prototype.stop = function(){
-    this.stopped = true;
-    this._done = true;
-    this.emit('stop');
-    this.emit('end');
-    return this;
-  };
-  
-  /**
-   * Perform a step.
-   *
-   * @return {Tween} self
-   * @api private
-   */
-  
-  Tween.prototype.step = function(){
-    if (this._done) return;
-  
-    // duration
-    var duration = this._duration;
-    var now = Date.now();
-    var delta = now - this._start;
-    var done = delta >= duration;
-  
-    // complete
-    if (done) {
-      this._from = this._to;
-      this._update(this._to);
-      this._done = true;
-      this.emit('end');
-      return this;
-    }
-  
-    // tween
-    var from = this._from;
-    var to = this._to;
-    var curr = this._curr;
-    var fn = this._ease;
-    var p = (now - this._start) / duration;
-    var n = fn(p);
-  
-    // array
-    if (this.isArray) {
-      for (var i = 0; i < from.length; ++i) {
-        curr[i] = from[i] + (to[i] - from[i]) * n;
-      }
-  
-      this._update(curr);
-      return this;
-    }
-  
-    // objech
-    for (var k in from) {
-      curr[k] = from[k] + (to[k] - from[k]) * n;
-    }
-  
-    this._update(curr);
-    return this;
-  };
-  
-  /**
-   * Set update function to `fn` or
-   * when no argument is given this performs
-   * a "step".
-   *
-   * @param {Function} fn
-   * @return {Tween} self
-   * @api public
-   */
-  
-  Tween.prototype.update = function(fn){
-    if (0 == arguments.length) return this.step();
-    this._update = fn;
-    return this;
-  };
-
-/***/ },
-/* 70 */
-/***/ function(module, exports) {
-
-  
-  /**
-   * Expose `Emitter`.
-   */
-  
-  module.exports = Emitter;
-  
-  /**
-   * Initialize a new `Emitter`.
-   *
-   * @api public
-   */
-  
-  function Emitter(obj) {
-    if (obj) return mixin(obj);
-  };
-  
-  /**
-   * Mixin the emitter properties.
-   *
-   * @param {Object} obj
-   * @return {Object}
-   * @api private
-   */
-  
-  function mixin(obj) {
-    for (var key in Emitter.prototype) {
-      obj[key] = Emitter.prototype[key];
-    }
-    return obj;
-  }
-  
-  /**
-   * Listen on the given `event` with `fn`.
-   *
-   * @param {String} event
-   * @param {Function} fn
-   * @return {Emitter}
-   * @api public
-   */
-  
-  Emitter.prototype.on =
-  Emitter.prototype.addEventListener = function(event, fn){
-    this._callbacks = this._callbacks || {};
-    (this._callbacks['$' + event] = this._callbacks['$' + event] || [])
-      .push(fn);
-    return this;
-  };
-  
-  /**
-   * Adds an `event` listener that will be invoked a single
-   * time then automatically removed.
-   *
-   * @param {String} event
-   * @param {Function} fn
-   * @return {Emitter}
-   * @api public
-   */
-  
-  Emitter.prototype.once = function(event, fn){
-    function on() {
-      this.off(event, on);
-      fn.apply(this, arguments);
-    }
-  
-    on.fn = fn;
-    this.on(event, on);
-    return this;
-  };
-  
-  /**
-   * Remove the given callback for `event` or all
-   * registered callbacks.
-   *
-   * @param {String} event
-   * @param {Function} fn
-   * @return {Emitter}
-   * @api public
-   */
-  
-  Emitter.prototype.off =
-  Emitter.prototype.removeListener =
-  Emitter.prototype.removeAllListeners =
-  Emitter.prototype.removeEventListener = function(event, fn){
-    this._callbacks = this._callbacks || {};
-  
-    // all
-    if (0 == arguments.length) {
-      this._callbacks = {};
-      return this;
-    }
-  
-    // specific event
-    var callbacks = this._callbacks['$' + event];
-    if (!callbacks) return this;
-  
-    // remove all handlers
-    if (1 == arguments.length) {
-      delete this._callbacks['$' + event];
-      return this;
-    }
-  
-    // remove specific handler
-    var cb;
-    for (var i = 0; i < callbacks.length; i++) {
-      cb = callbacks[i];
-      if (cb === fn || cb.fn === fn) {
-        callbacks.splice(i, 1);
-        break;
-      }
-    }
-    return this;
-  };
-  
-  /**
-   * Emit `event` with the given args.
-   *
-   * @param {String} event
-   * @param {Mixed} ...
-   * @return {Emitter}
-   */
-  
-  Emitter.prototype.emit = function(event){
-    this._callbacks = this._callbacks || {};
-    var args = [].slice.call(arguments, 1)
-      , callbacks = this._callbacks['$' + event];
-  
-    if (callbacks) {
-      callbacks = callbacks.slice(0);
-      for (var i = 0, len = callbacks.length; i < len; ++i) {
-        callbacks[i].apply(this, args);
-      }
-    }
-  
-    return this;
-  };
-  
-  /**
-   * Return array of callbacks for `event`.
-   *
-   * @param {String} event
-   * @return {Array}
-   * @api public
-   */
-  
-  Emitter.prototype.listeners = function(event){
-    this._callbacks = this._callbacks || {};
-    return this._callbacks['$' + event] || [];
-  };
-  
-  /**
-   * Check if this emitter has `event` handlers.
-   *
-   * @param {String} event
-   * @return {Boolean}
-   * @api public
-   */
-  
-  Emitter.prototype.hasListeners = function(event){
-    return !! this.listeners(event).length;
-  };
-
-
-/***/ },
-/* 71 */
-/***/ function(module, exports, __webpack_require__) {
-
-  /**
-   * Module dependencies.
-   */
-  
-  var type;
-  try {
-    type = __webpack_require__(72);
-  } catch (_) {
-    type = __webpack_require__(72);
-  }
-  
-  /**
-   * Module exports.
-   */
-  
-  module.exports = clone;
-  
-  /**
-   * Clones objects.
-   *
-   * @param {Mixed} any object
-   * @api public
-   */
-  
-  function clone(obj){
-    switch (type(obj)) {
-      case 'object':
-        var copy = {};
-        for (var key in obj) {
-          if (obj.hasOwnProperty(key)) {
-            copy[key] = clone(obj[key]);
-          }
-        }
-        return copy;
-  
-      case 'array':
-        var copy = new Array(obj.length);
-        for (var i = 0, l = obj.length; i < l; i++) {
-          copy[i] = clone(obj[i]);
-        }
-        return copy;
-  
-      case 'regexp':
-        // from millermedeiros/amd-utils - MIT
-        var flags = '';
-        flags += obj.multiline ? 'm' : '';
-        flags += obj.global ? 'g' : '';
-        flags += obj.ignoreCase ? 'i' : '';
-        return new RegExp(obj.source, flags);
-  
-      case 'date':
-        return new Date(obj.getTime());
-  
-      default: // string, number, boolean, …
-        return obj;
-    }
-  }
-
-
-/***/ },
-/* 72 */
-/***/ function(module, exports) {
-
-  /**
-   * toString ref.
-   */
-  
-  var toString = Object.prototype.toString;
-  
-  /**
-   * Return the type of `val`.
-   *
-   * @param {Mixed} val
-   * @return {String}
-   * @api public
-   */
-  
-  module.exports = function(val){
-    switch (toString.call(val)) {
-      case '[object Date]': return 'date';
-      case '[object RegExp]': return 'regexp';
-      case '[object Arguments]': return 'arguments';
-      case '[object Array]': return 'array';
-      case '[object Error]': return 'error';
-    }
-  
-    if (val === null) return 'null';
-    if (val === undefined) return 'undefined';
-    if (val !== val) return 'nan';
-    if (val && val.nodeType === 1) return 'element';
-  
-    val = val.valueOf
-      ? val.valueOf()
-      : Object.prototype.valueOf.apply(val)
-  
-    return typeof val;
-  };
-
-
-/***/ },
-/* 73 */
-/***/ function(module, exports) {
-
-  
-  // easing functions from "Tween.js"
-  
-  exports.linear = function(n){
-    return n;
-  };
-  
-  exports.inQuad = function(n){
-    return n * n;
-  };
-  
-  exports.outQuad = function(n){
-    return n * (2 - n);
-  };
-  
-  exports.inOutQuad = function(n){
-    n *= 2;
-    if (n < 1) return 0.5 * n * n;
-    return - 0.5 * (--n * (n - 2) - 1);
-  };
-  
-  exports.inCube = function(n){
-    return n * n * n;
-  };
-  
-  exports.outCube = function(n){
-    return --n * n * n + 1;
-  };
-  
-  exports.inOutCube = function(n){
-    n *= 2;
-    if (n < 1) return 0.5 * n * n * n;
-    return 0.5 * ((n -= 2 ) * n * n + 2);
-  };
-  
-  exports.inQuart = function(n){
-    return n * n * n * n;
-  };
-  
-  exports.outQuart = function(n){
-    return 1 - (--n * n * n * n);
-  };
-  
-  exports.inOutQuart = function(n){
-    n *= 2;
-    if (n < 1) return 0.5 * n * n * n * n;
-    return -0.5 * ((n -= 2) * n * n * n - 2);
-  };
-  
-  exports.inQuint = function(n){
-    return n * n * n * n * n;
-  }
-  
-  exports.outQuint = function(n){
-    return --n * n * n * n * n + 1;
-  }
-  
-  exports.inOutQuint = function(n){
-    n *= 2;
-    if (n < 1) return 0.5 * n * n * n * n * n;
-    return 0.5 * ((n -= 2) * n * n * n * n + 2);
-  };
-  
-  exports.inSine = function(n){
-    return 1 - Math.cos(n * Math.PI / 2 );
-  };
-  
-  exports.outSine = function(n){
-    return Math.sin(n * Math.PI / 2);
-  };
-  
-  exports.inOutSine = function(n){
-    return .5 * (1 - Math.cos(Math.PI * n));
-  };
-  
-  exports.inExpo = function(n){
-    return 0 == n ? 0 : Math.pow(1024, n - 1);
-  };
-  
-  exports.outExpo = function(n){
-    return 1 == n ? n : 1 - Math.pow(2, -10 * n);
-  };
-  
-  exports.inOutExpo = function(n){
-    if (0 == n) return 0;
-    if (1 == n) return 1;
-    if ((n *= 2) < 1) return .5 * Math.pow(1024, n - 1);
-    return .5 * (-Math.pow(2, -10 * (n - 1)) + 2);
-  };
-  
-  exports.inCirc = function(n){
-    return 1 - Math.sqrt(1 - n * n);
-  };
-  
-  exports.outCirc = function(n){
-    return Math.sqrt(1 - (--n * n));
-  };
-  
-  exports.inOutCirc = function(n){
-    n *= 2
-    if (n < 1) return -0.5 * (Math.sqrt(1 - n * n) - 1);
-    return 0.5 * (Math.sqrt(1 - (n -= 2) * n) + 1);
-  };
-  
-  exports.inBack = function(n){
-    var s = 1.70158;
-    return n * n * (( s + 1 ) * n - s);
-  };
-  
-  exports.outBack = function(n){
-    var s = 1.70158;
-    return --n * n * ((s + 1) * n + s) + 1;
-  };
-  
-  exports.inOutBack = function(n){
-    var s = 1.70158 * 1.525;
-    if ( ( n *= 2 ) < 1 ) return 0.5 * ( n * n * ( ( s + 1 ) * n - s ) );
-    return 0.5 * ( ( n -= 2 ) * n * ( ( s + 1 ) * n + s ) + 2 );
-  };
-  
-  exports.inBounce = function(n){
-    return 1 - exports.outBounce(1 - n);
-  };
-  
-  exports.outBounce = function(n){
-    if ( n < ( 1 / 2.75 ) ) {
-      return 7.5625 * n * n;
-    } else if ( n < ( 2 / 2.75 ) ) {
-      return 7.5625 * ( n -= ( 1.5 / 2.75 ) ) * n + 0.75;
-    } else if ( n < ( 2.5 / 2.75 ) ) {
-      return 7.5625 * ( n -= ( 2.25 / 2.75 ) ) * n + 0.9375;
-    } else {
-      return 7.5625 * ( n -= ( 2.625 / 2.75 ) ) * n + 0.984375;
-    }
-  };
-  
-  exports.inOutBounce = function(n){
-    if (n < .5) return exports.inBounce(n * 2) * .5;
-    return exports.outBounce(n * 2 - 1) * .5 + .5;
-  };
-  
-  // aliases
-  
-  exports['in-quad'] = exports.inQuad;
-  exports['out-quad'] = exports.outQuad;
-  exports['in-out-quad'] = exports.inOutQuad;
-  exports['in-cube'] = exports.inCube;
-  exports['out-cube'] = exports.outCube;
-  exports['in-out-cube'] = exports.inOutCube;
-  exports['in-quart'] = exports.inQuart;
-  exports['out-quart'] = exports.outQuart;
-  exports['in-out-quart'] = exports.inOutQuart;
-  exports['in-quint'] = exports.inQuint;
-  exports['out-quint'] = exports.outQuint;
-  exports['in-out-quint'] = exports.inOutQuint;
-  exports['in-sine'] = exports.inSine;
-  exports['out-sine'] = exports.outSine;
-  exports['in-out-sine'] = exports.inOutSine;
-  exports['in-expo'] = exports.inExpo;
-  exports['out-expo'] = exports.outExpo;
-  exports['in-out-expo'] = exports.inOutExpo;
-  exports['in-circ'] = exports.inCirc;
-  exports['out-circ'] = exports.outCirc;
-  exports['in-out-circ'] = exports.inOutCirc;
-  exports['in-back'] = exports.inBack;
-  exports['out-back'] = exports.outBack;
-  exports['in-out-back'] = exports.inOutBack;
-  exports['in-bounce'] = exports.inBounce;
-  exports['out-bounce'] = exports.outBounce;
-  exports['in-out-bounce'] = exports.inOutBounce;
-
-
-/***/ },
-/* 74 */
-/***/ function(module, exports) {
-
-  /**
-   * Expose `requestAnimationFrame()`.
-   */
-  
-  exports = module.exports = window.requestAnimationFrame
-    || window.webkitRequestAnimationFrame
-    || window.mozRequestAnimationFrame
-    || fallback;
-  
-  /**
-   * Fallback implementation.
-   */
-  
-  var prev = new Date().getTime();
-  function fallback(fn) {
-    var curr = new Date().getTime();
-    var ms = Math.max(0, 16 - (curr - prev));
-    var req = setTimeout(fn, ms);
-    prev = curr;
-    return req;
-  }
-  
-  /**
-   * Cancel.
-   */
-  
-  var cancel = window.cancelAnimationFrame
-    || window.webkitCancelAnimationFrame
-    || window.mozCancelAnimationFrame
-    || window.clearTimeout;
-  
-  exports.cancel = function(id){
-    cancel.call(window, id);
-  };
-
-
-/***/ },
-/* 75 */
-/***/ function(module, exports) {
-
-  'use strict'
-  
-  var event = {
-    /**
-     * openUrl
-     * @param  {string} url
-     */
-    openURL: function (url) {
-      location.href = url
-    }
-  
-  }
-  
-  event._meta = {
-    event: [{
-      name: 'openURL',
-      args: ['string']
-    }]
-  }
-  
-  module.exports = event
-
-/***/ },
-/* 76 */
-/***/ function(module, exports) {
-
-  'use strict'
-  
-  var pageInfo = {
-  
-    setTitle: function (title) {
-      title = title || 'Weex HTML5'
-      try {
-        title = decodeURIComponent(title)
-      } catch (e) {}
-      document.title = title
-    }
-  }
-  
-  pageInfo._meta = {
-    pageInfo: [{
-      name: 'setTitle',
-      args: ['string']
-    }]
-  }
-  
-  module.exports = pageInfo
-
-/***/ },
-/* 77 */
-/***/ function(module, exports) {
-
-  'use strict'
-  
-  // require('httpurl')
-  
-  // var jsonpCnt = 0
-  
-  // function _sendJsonp(config, callbackId) {
-  //   var cbName = '_callback_' + (++jsonpCnt)
-  //   var script, url, head
-  //   global[cbName] = (function (cb) {
-  //     return function (response) {
-  //       this.sender.performCallback(callbackId, response)
-  //       delete global[cb]
-  //     }
-  //   })(cbName)
-  //   script = document.createElement('script')
-  //   url = lib.httpurl(config.url)
-  //   url.params.callback = cbName
-  //   script.type = 'text/javascript'
-  //   script.src = url.toString()
-  //   // script.onerror is not working on IE or safari.
-  //   // but they are not considered here.
-  //   script.onerror = (function (cb) {
-  //     return function (err) {
-  //       this.sender.performCallback(callbackId, err)
-  //       delete global[cb]
-  //     }
-  //   })(cbName)
-  //   head = document.getElementsByTagName('head')[0]
-  //   head.insertBefore(script, null)
-  // }
-  
-  var stream = {
-  
-    /**
-     * sendHttp
-     * @param  {obj} params
-     *  - method: 'GET' | 'POST',
-     *  - url: url requested
-     * @param  {string} callbackId
-     */
-    sendHttp: function (param, callbackId) {
-      if (typeof param === 'string') {
-        try {
-          param = JSON.parse(param)
-        } catch (e) {
-          return
-        }
-      }
-      if (typeof param !== 'object' || !param.url) {
-        return
-      }
-  
-      // Not to use jsonp to send http request since it requires the server
-      // to support jsonp callback at the first place.
-      // _sendJsonp.call(this, param, callbackId)
-  
-      var self = this
-      var method = param.method || 'GET'
-      var xhr = new XMLHttpRequest()
-      xhr.open(method, param.url, true)
-      xhr.onload = function () {
-        self.sender.performCallback(callbackId, this.responseText)
-      }
-      xhr.onerror = function (error) {
-        self.sender.performCallback(callbackId, error)
-      }
-      xhr.send()
-    }
-  
-  }
-  
-  stream._meta = {
-    stream: [{
-      name: 'sendHttp',
-      args: ['object', 'string']
-    }]
-  }
-  
-  module.exports = stream
-
-/***/ },
-/* 78 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  var sender = __webpack_require__(19)
-  var modal = __webpack_require__(79)
-  
-  var msg = {
-  
-    // duration: default is 0.8 seconds.
-    toast: function (config) {
-      modal.toast(config.message, config.duration)
-    },
-  
-    // config:
-    //  - message: string
-    //  - okTitle: title of ok button
-    //  - callback
-    alert: function (config, callbackId) {
-      var sender =  this.sender
-      config.callback = function () {
-        sender.performCallback(callbackId)
-      }
-      modal.alert(config)
-    },
-  
-    // config:
-    //  - message: string
-    //  - okTitle: title of ok button
-    //  - cancelTitle: title of cancel button
-    //  - callback
-    confirm: function (config, callbackId) {
-      var sender =  this.sender
-      config.callback = function (val) {
-        sender.performCallback(callbackId, val)
-      }
-      modal.confirm(config)
-    },
-  
-    // config:
-    //  - message: string
-    //  - okTitle: title of ok button
-    //  - cancelTitle: title of cancel button
-    //  - callback
-    prompt: function (config, callbackId) {
-      var sender =  this.sender
-      config.callback = function (val) {
-        sender.performCallback(callbackId, val)
-      }
-      modal.prompt(config)
-    }
-  
-  }
-  
-  msg._meta = {
-    modal: [{
-      name: 'toast',
-      args: ['object']
-    }, {
-      name: 'alert',
-      args: ['object', 'string']
-    }, {
-      name: 'confirm',
-      args: ['object', 'string']
-    }, {
-      name: 'prompt',
-      args: ['object', 'string']
-    }]
-  }
-  
-  module.exports = msg
-
-
-/***/ },
-/* 79 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  var Alert = __webpack_require__(80)
-  var Confirm = __webpack_require__(86)
-  var Prompt = __webpack_require__(89)
-  var toast = __webpack_require__(92)
-  
-  var modal = {
-  
-    toast: function (msg, duration) {
-      toast.push(msg, duration)
-    },
-  
-    alert: function (config) {
-      new Alert(config).show()
-    },
-  
-    prompt: function (config) {
-      new Prompt(config).show()
-    },
-  
-    confirm: function (config) {
-      new Confirm(config).show()
-    }
-  
-  }
-  
-  !window.lib && (window.lib = {})
-  window.lib.modal = modal
-  
-  module.exports = modal
-
-/***/ },
-/* 80 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  var Modal = __webpack_require__(81)
-  __webpack_require__(84)
-  
-  var CONTENT_CLASS = 'content'
-  var MSG_CLASS = 'content-msg'
-  var BUTTON_GROUP_CLASS = 'btn-group'
-  var BUTTON_CLASS = 'btn'
-  
-  function Alert(config) {
-    this.msg = config.message || ''
-    this.callback = config.callback
-    this.okTitle = config.okTitle || 'OK'
-    Modal.call(this)
-    this.node.classList.add('amfe-alert')
-  }
-  
-  Alert.prototype = Object.create(Modal.prototype)
-  
-  Alert.prototype.createNodeContent = function () {
-    var content = document.createElement('div')
-    content.classList.add(CONTENT_CLASS)
-    this.node.appendChild(content)
-  
-    var msg = document.createElement('div')
-    msg.classList.add(MSG_CLASS)
-    msg.appendChild(document.createTextNode(this.msg))
-    content.appendChild(msg)
-  
-    var buttonGroup = document.createElement('div')
-    buttonGroup.classList.add(BUTTON_GROUP_CLASS)
-    this.node.appendChild(buttonGroup)
-    var button = document.createElement('div')
-    button.classList.add(BUTTON_CLASS, 'alert-ok')
-    button.appendChild(document.createTextNode(this.okTitle))
-    buttonGroup.appendChild(button)
-  }
-  
-  Alert.prototype.bindEvents = function () {
-    Modal.prototype.bindEvents.call(this)
-    var button = this.node.querySelector('.' + BUTTON_CLASS)
-    button.addEventListener('click', function () {
-      this.destroy()
-      this.callback && this.callback()
-    }.bind(this))
-  }
-  
-  module.exports = Alert
-
-
-/***/ },
-/* 81 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  __webpack_require__(82)
-  
-  // there will be only one instance of modal.
-  var MODAL_WRAP_CLASS = 'amfe-modal-wrap'
-  var MODAL_NODE_CLASS = 'amfe-modal-node'
-  
-  function Modal() {
-    this.wrap = document.querySelector(MODAL_WRAP_CLASS)
-    this.node = document.querySelector(MODAL_NODE_CLASS)
-    if (!this.wrap) {
-      this.createWrap()
-    }
-    if (!this.node) {
-      this.createNode()
-    }
-    this.clearNode()
-    this.createNodeContent()
-    this.bindEvents()
-  }
-  
-  Modal.prototype = {
-  
-    show: function () {
-      this.wrap.style.display = 'block'
-      this.node.classList.remove('hide')
-    },
-  
-    destroy: function () {
-      document.body.removeChild(this.wrap)
-      document.body.removeChild(this.node)
-      this.wrap = null
-      this.node = null
-    },
-  
-    createWrap: function () {
-      this.wrap = document.createElement('div')
-      this.wrap.className = MODAL_WRAP_CLASS
-      document.body.appendChild(this.wrap)
-    },
-  
-    createNode: function () {
-      this.node = document.createElement('div')
-      this.node.classList.add(MODAL_NODE_CLASS, 'hide')
-      document.body.appendChild(this.node)
-    },
-  
-    clearNode: function () {
-      this.node.innerHTML = ''
-    },
-  
-    createNodeContent: function () {
-  
-      // do nothing.
-      // child classes can override this method.
-    },
-  
-    bindEvents: function () {
-      this.wrap.addEventListener('click', function (e) {
-        e.preventDefault()
-        e.stopPropagation()
-      })
-    }
-  }
-  
-  module.exports = Modal
-
-
-/***/ },
-/* 82 */
-/***/ function(module, exports, __webpack_require__) {
-
-  // style-loader: Adds some css to the DOM by adding a <style> tag
-  
-  // load the styles
-  var content = __webpack_require__(83);
-  if(typeof content === 'string') content = [[module.id, content, '']];
-  // add the styles to the DOM
-  var update = __webpack_require__(4)(content, {});
-  if(content.locals) module.exports = content.locals;
-  // Hot Module Replacement
-  if(false) {
-    // When the styles change, update the <style> tags
-    if(!content.locals) {
-      module.hot.accept("!!./../../css-loader/index.js?sourceMap!./../../sass-loader/index.js?sourceMap!./modal.scss", function() {
-        var newContent = require("!!./../../css-loader/index.js?sourceMap!./../../sass-loader/index.js?sourceMap!./modal.scss");
-        if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
-        update(newContent);
-      });
-    }
-    // When the module is disposed, remove the <style> tags
-    module.hot.dispose(function() { update(); });
-  }
-
-/***/ },
-/* 83 */
-/***/ function(module, exports, __webpack_require__) {
-
-  exports = module.exports = __webpack_require__(3)();
-  // imports
-  
-  
-  // module
-  exports.push([module.id, ".amfe-modal-wrap {\n  display: none;\n  position: fixed;\n  z-index: 999999999;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  background-color: #000;\n  opacity: 0.5; }\n\n.amfe-modal-node {\n  position: fixed;\n  z-index: 9999999999;\n  top: 50%;\n  left: 50%;\n  width: 6.666667rem;\n  min-height: 2.666667rem;\n  border-radius: 0.066667rem;\n  -webkit-transform: translate(-50%, -50%);\n  transform: translate(-50%, -50%);\n  background-color: #fff; }\n  .amfe-modal-node.hide {\n    display: none; }\n  .amfe-modal-node .content {\n    width: 100%;\n    min-height: 1.866667rem;\n    box-sizing: border-box;\n    font-size: 0.32rem;\n    line-height: 0.426667rem;\n    padding: 0.213333rem;\n    border-bottom: 1px solid #ddd; }\n  .amfe-modal-node .btn-group {\n    width: 100%;\n    height: 0.8rem;\n    font-size: 0.373333rem;\n    text-align: center; }\n    .amfe-modal-node .btn-group .btn {\n      box-sizing: border-box;\n      height: 0.8rem;\n      line-height: 0.8rem; }\n", "", {"version":3,"sources":["/./node_modules/modals/node_modules/modals/styles/modal.scss"],"names":[],"mappings":"AAAA;EACE,cAAc;EACd,gBAAgB;EAChB,mBAAmB;EACnB,OAAO;EACP,QAAQ;EACR,YAAY;EACZ,aAAa;EACb,uBAAuB;EACvB,aAAa,EAEd;;AAED;EACE,gBAAgB;EAChB,oBAAoB;EACpB,SAAS;EACT,UAAU;EACV,mBAAmB;EACnB,wBAAwB;EACxB,2BAA2B;EAC3B,yCAA4B;EAC5B,iCAAoB;EACpB,uBAAuB,EA4BxB;EAtCD;IAaI,cACD,EAAC;EAdJ;IAiBI,YAAY;IACZ,wBAAwB;IACxB,uBAAuB;IACvB,mBAAmB;IACnB,yBAAyB;IACzB,qBAAqB;IACrB,8BAA8B,EAC/B;EAxBH;IA2BI,YAAY;IACZ,eAAe;IACf,uBAAuB;IACvB,mBAAmB,EAOpB;IArCH;MAiCM,uBAAuB;MACvB,eAAe;MACf,oBAAoB,EACrB","file":"modal.scss","sourcesContent":[".amfe-modal-wrap {\n  display: none;\n  position: fixed;\n  z-index: 999999999;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  background-color: #000;\n  opacity: 0.5;\n\n}\n\n.amfe-modal-node {\n  position: fixed;\n  z-index: 9999999999;\n  top: 50%;\n  left: 50%;\n  width: 6.666667rem; // 500px\n  min-height: 2.666667rem; // 200px\n  border-radius: 0.066667rem; // 5px\n  -webkit-transform: translate(-50%, -50%);\n  transform: translate(-50%, -50%);\n  background-color: #fff;\n\n  &.hide {\n    display: none\n  }\n\n  .content {\n    width: 100%;\n    min-height: 1.866667rem; // 140px\n    box-sizing: border-box;\n    font-size: 0.32rem; // 24px\n    line-height: 0.426667rem; // 32px\n    padding: 0.213333rem; // 16px\n    border-bottom: 1px solid #ddd;\n  }\n\n  .btn-group {\n    width: 100%;\n    height: 0.8rem; // 60px\n    font-size: 0.373333rem; // 28px\n    text-align: center;\n\n    .btn {\n      box-sizing: border-box;\n      height: 0.8rem; // 60px\n      line-height: 0.8rem; // 60px\n    }\n  }\n}\n"],"sourceRoot":"webpack://"}]);
-  
-  // exports
-
-
-/***/ },
-/* 84 */
-/***/ function(module, exports, __webpack_require__) {
-
-  // style-loader: Adds some css to the DOM by adding a <style> tag
-  
-  // load the styles
-  var content = __webpack_require__(85);
-  if(typeof content === 'string') content = [[module.id, content, '']];
-  // add the styles to the DOM
-  var update = __webpack_require__(4)(content, {});
-  if(content.locals) module.exports = content.locals;
-  // Hot Module Replacement
-  if(false) {
-    // When the styles change, update the <style> tags
-    if(!content.locals) {
-      module.hot.accept("!!./../../css-loader/index.js?sourceMap!./../../sass-loader/index.js?sourceMap!./alert.scss", function() {
-        var newContent = require("!!./../../css-loader/index.js?sourceMap!./../../sass-loader/index.js?sourceMap!./alert.scss");
-        if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
-        update(newContent);
-      });
-    }
-    // When the module is disposed, remove the <style> tags
-    module.hot.dispose(function() { update(); });
-  }
-
-/***/ },
-/* 85 */
-/***/ function(module, exports, __webpack_require__) {
-
-  exports = module.exports = __webpack_require__(3)();
-  // imports
-  
-  
-  // module
-  exports.push([module.id, ".amfe-alert .amfe-alert-ok {\n  width: 100%; }\n", "", {"version":3,"sources":["/./node_modules/modals/node_modules/modals/styles/alert.scss"],"names":[],"mappings":"AAAA;EAGI,YAAY,EACb","file":"alert.scss","sourcesContent":[".amfe-alert {\n\n  .amfe-alert-ok {\n    width: 100%;\n  }\n}\n"],"sourceRoot":"webpack://"}]);
-  
-  // exports
-
-
-/***/ },
-/* 86 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  var Modal = __webpack_require__(81)
-  __webpack_require__(87)
-  
-  var CONTENT_CLASS = 'content'
-  var MSG_CLASS = 'content-msg'
-  var BUTTON_GROUP_CLASS = 'btn-group'
-  var BUTTON_CLASS = 'btn'
-  
-  function Confirm(config) {
-    this.msg = config.message || ''
-    this.callback = config.callback
-    this.okTitle = config.okTitle || 'OK'
-    this.cancelTitle = config.cancelTitle || 'Cancel'
-    Modal.call(this)
-    this.node.classList.add('amfe-confirm')
-  }
-  
-  Confirm.prototype = Object.create(Modal.prototype)
-  
-  Confirm.prototype.createNodeContent = function () {
-    var content = document.createElement('div')
-    content.classList.add(CONTENT_CLASS)
-    this.node.appendChild(content)
-  
-    var msg = document.createElement('div')
-    msg.classList.add(MSG_CLASS)
-    msg.appendChild(document.createTextNode(this.msg))
-    content.appendChild(msg)
-  
-    var buttonGroup = document.createElement('div')
-    buttonGroup.classList.add(BUTTON_GROUP_CLASS)
-    this.node.appendChild(buttonGroup)
-    var btnOk = document.createElement('div')
-    btnOk.appendChild(document.createTextNode(this.okTitle))
-    btnOk.classList.add('btn-ok', BUTTON_CLASS)
-    var btnCancel = document.createElement('div')
-    btnCancel.appendChild(document.createTextNode(this.cancelTitle))
-    btnCancel.classList.add('btn-cancel', BUTTON_CLASS)
-    buttonGroup.appendChild(btnOk)
-    buttonGroup.appendChild(btnCancel)
-    this.node.appendChild(buttonGroup)
-  }
-  
-  Confirm.prototype.bindEvents = function () {
-    Modal.prototype.bindEvents.call(this)
-    var btnOk = this.node.querySelector('.' + BUTTON_CLASS + '.btn-ok')
-    var btnCancel = this.node.querySelector('.' + BUTTON_CLASS + '.btn-cancel')
-    btnOk.addEventListener('click', function () {
-      this.destroy()
-      this.callback && this.callback(this.okTitle)
-    }.bind(this))
-    btnCancel.addEventListener('click', function () {
-      this.destroy()
-      this.callback && this.callback(this.cancelTitle)
-    }.bind(this))
-  }
-  
-  module.exports = Confirm
-
-
-/***/ },
-/* 87 */
-/***/ function(module, exports, __webpack_require__) {
-
-  // style-loader: Adds some css to the DOM by adding a <style> tag
-  
-  // load the styles
-  var content = __webpack_require__(88);
-  if(typeof content === 'string') content = [[module.id, content, '']];
-  // add the styles to the DOM
-  var update = __webpack_require__(4)(content, {});
-  if(content.locals) module.exports = content.locals;
-  // Hot Module Replacement
-  if(false) {
-    // When the styles change, update the <style> tags
-    if(!content.locals) {
-      module.hot.accept("!!./../../css-loader/index.js?sourceMap!./../../sass-loader/index.js?sourceMap!./confirm.scss", function() {
-        var newContent = require("!!./../../css-loader/index.js?sourceMap!./../../sass-loader/index.js?sourceMap!./confirm.scss");
-        if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
-        update(newContent);
-      });
-    }
-    // When the module is disposed, remove the <style> tags
-    module.hot.dispose(function() { update(); });
-  }
-
-/***/ },
-/* 88 */
-/***/ function(module, exports, __webpack_require__) {
-
-  exports = module.exports = __webpack_require__(3)();
-  // imports
-  
-  
-  // module
-  exports.push([module.id, ".amfe-confirm .btn-group .btn {\n  float: left;\n  width: 50%; }\n  .amfe-confirm .btn-group .btn.btn-ok {\n    border-right: 1px solid #ddd; }\n", "", {"version":3,"sources":["/./node_modules/modals/node_modules/modals/styles/confirm.scss"],"names":[],"mappings":"AAAA;EAKM,YAAY;EACZ,WAAW,EAKZ;EAXL;IASO,6BAA6B,EAC7B","file":"confirm.scss","sourcesContent":[".amfe-confirm {\n\n  .btn-group {\n\n    .btn {\n      float: left;\n      width: 50%;\n\n      &.btn-ok {\n      \tborder-right: 1px solid #ddd;\n      }\n    }\n  }\n}"],"sourceRoot":"webpack://"}]);
-  
-  // exports
-
-
-/***/ },
-/* 89 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  var Modal = __webpack_require__(81)
-  __webpack_require__(90)
-  
-  var CONTENT_CLASS = 'content'
-  var MSG_CLASS = 'content-msg'
-  var BUTTON_GROUP_CLASS = 'btn-group'
-  var BUTTON_CLASS = 'btn'
-  var INPUT_WRAP_CLASS = 'input-wrap'
-  var INPUT_CLASS = 'input'
-  
-  function Prompt(config) {
-    this.msg = config.message || ''
-    this.defaultMsg = config.default || ''
-    this.callback = config.callback
-    this.okTitle = config.okTitle || 'OK'
-    this.cancelTitle = config.cancelTitle || 'Cancel'
-    Modal.call(this)
-    this.node.classList.add('amfe-prompt')
-  }
-  
-  Prompt.prototype = Object.create(Modal.prototype)
-  
-  Prompt.prototype.createNodeContent = function () {
-  
-    var content = document.createElement('div')
-    content.classList.add(CONTENT_CLASS)
-    this.node.appendChild(content)
-  
-    var msg = document.createElement('div')
-    msg.classList.add(MSG_CLASS)
-    msg.appendChild(document.createTextNode(this.msg))
-    content.appendChild(msg)
-  
-    var inputWrap = document.createElement('div')
-    inputWrap.classList.add(INPUT_WRAP_CLASS)
-    content.appendChild(inputWrap)
-    var input = document.createElement('input')
-    input.classList.add(INPUT_CLASS)
-    input.type = 'text'
-    input.autofocus = true
-    input.placeholder = this.defaultMsg
-    inputWrap.appendChild(input)
-  
-    var buttonGroup = document.createElement('div')
-    buttonGroup.classList.add(BUTTON_GROUP_CLASS)
-    var btnOk = document.createElement('div')
-    btnOk.appendChild(document.createTextNode(this.okTitle))
-    btnOk.classList.add('btn-ok', BUTTON_CLASS)
-    var btnCancel = document.createElement('div')
-    btnCancel.appendChild(document.createTextNode(this.cancelTitle))
-    btnCancel.classList.add('btn-cancel', BUTTON_CLASS)
-    buttonGroup.appendChild(btnOk)
-    buttonGroup.appendChild(btnCancel)
-    this.node.appendChild(buttonGroup)
-  }
-  
-  Prompt.prototype.bindEvents = function () {
-    Modal.prototype.bindEvents.call(this)
-    var btnOk = this.node.querySelector('.' + BUTTON_CLASS + '.btn-ok')
-    var btnCancel = this.node.querySelector('.' + BUTTON_CLASS + '.btn-cancel')
-    var that = this
-    btnOk.addEventListener('click', function () {
-      var val = document.querySelector('input').value
-      this.destroy()
-      this.callback && this.callback({
-        result: that.okTitle,
-        data: val
-      })
-    }.bind(this))
-    btnCancel.addEventListener('click', function () {
-      var val = document.querySelector('input').value
-      this.destroy()
-      this.callback && this.callback({
-        result: that.cancelTitle
-      })
-    }.bind(this))
-  }
-  
-  module.exports = Prompt
-
-
-/***/ },
-/* 90 */
-/***/ function(module, exports, __webpack_require__) {
-
-  // style-loader: Adds some css to the DOM by adding a <style> tag
-  
-  // load the styles
-  var content = __webpack_require__(91);
-  if(typeof content === 'string') content = [[module.id, content, '']];
-  // add the styles to the DOM
-  var update = __webpack_require__(4)(content, {});
-  if(content.locals) module.exports = content.locals;
-  // Hot Module Replacement
-  if(false) {
-    // When the styles change, update the <style> tags
-    if(!content.locals) {
-      module.hot.accept("!!./../../css-loader/index.js?sourceMap!./../../sass-loader/index.js?sourceMap!./prompt.scss", function() {
-        var newContent = require("!!./../../css-loader/index.js?sourceMap!./../../sass-loader/index.js?sourceMap!./prompt.scss");
-        if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
-        update(newContent);
-      });
-    }
-    // When the module is disposed, remove the <style> tags
-    module.hot.dispose(function() { update(); });
-  }
-
-/***/ },
-/* 91 */
-/***/ function(module, exports, __webpack_require__) {
-
-  exports = module.exports = __webpack_require__(3)();
-  // imports
-  
-  
-  // module
-  exports.push([module.id, ".amfe-prompt .input-wrap {\n  box-sizing: border-box;\n  width: 100%;\n  padding: 0.24rem 0.213333rem 0.213333rem;\n  height: 0.96rem; }\n  .amfe-prompt .input-wrap .input {\n    box-sizing: border-box;\n    width: 100%;\n    height: 0.56rem;\n    line-height: 0.56rem;\n    font-size: 0.32rem; }\n\n.amfe-prompt .btn-group .btn {\n  float: left;\n  width: 50%; }\n  .amfe-prompt .btn-group .btn.btn-ok {\n    border-right: 1px solid #ddd; }\n", "", {"version":3,"sources":["/./node_modules/modals/node_modules/modals/styles/prompt.scss"],"names":[],"mappings":"AAAA;EAGI,uBAAuB;EACvB,YAAY;EACZ,yCAAyC;EACzC,gBAAgB,EASjB;EAfH;IASM,uBAAuB;IACvB,YAAY;IACZ,gBAAgB;IAChB,qBAAqB;IACrB,mBAAmB,EACpB;;AAdL;EAoBM,YAAY;EACZ,WAAW,EAKZ;EA1BL;IAwBQ,6BAA6B,EAC9B","file":"prompt.scss","sourcesContent":[".amfe-prompt {\n\n  .input-wrap {\n    box-sizing: border-box;\n    width: 100%;\n    padding: 0.24rem 0.213333rem 0.213333rem; // 18px 16px 16px\n    height: 0.96rem; // 74px\n\n    .input {\n      box-sizing: border-box;\n      width: 100%;\n      height: 0.56rem; // 42px\n      line-height: 0.56rem; // 42px\n      font-size: 0.32rem; // 24px\n    }\n  }\n\n  .btn-group {\n\n    .btn {\n      float: left;\n      width: 50%;\n\n      &.btn-ok {\n        border-right: 1px solid #ddd;\n      }\n    }\n  }\n}"],"sourceRoot":"webpack://"}]);
-  
-  // exports
-
-
-/***/ },
-/* 92 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  __webpack_require__(93)
-  
-  var queue = []
-  var timer
-  var isProcessing = false
-  var toastWin
-  var TOAST_WIN_CLASS_NAME = 'amfe-toast'
-  
-  var DEFAULT_DURATION = 0.8
-  
-  function showToastWindow(msg, callback) {
-    var handleTransitionEnd = function () {
-      toastWin.removeEventListener('transitionend', handleTransitionEnd)
-      callback && callback()
-    }
-    if (!toastWin) {
-      toastWin = document.createElement('div')
-      toastWin.classList.add(TOAST_WIN_CLASS_NAME, 'hide')
-      document.body.appendChild(toastWin)
-    }
-    toastWin.innerHTML = msg
-    toastWin.addEventListener('transitionend', handleTransitionEnd)
-    setTimeout(function () {
-      toastWin.classList.remove('hide')
-    }, 0)
-  }
-  
-  function hideToastWindow(callback) {
-    var handleTransitionEnd = function () {
-      toastWin.removeEventListener('transitionend', handleTransitionEnd)
-      callback && callback()
-    }
-    if (!toastWin) {
-      return
-    }
-    toastWin.addEventListener('transitionend', handleTransitionEnd)
-    toastWin.classList.add('hide')
-  }
-  
-  var toast = {
-  
-    push: function (msg, duration) {
-      queue.push({
-        msg: msg,
-        duration: duration || DEFAULT_DURATION
-      })
-      this.show()
-    },
-  
-    show: function () {
-      var that = this
-  
-      // All messages had been toasted already, so remove the toast window,
-      if (!queue.length) {
-        toastWin && toastWin.parentNode.removeChild(toastWin)
-        toastWin = null
-        return
-      }
-  
-      // the previous toast is not ended yet.
-      if (isProcessing) {
-        return
-      }
-      isProcessing = true
-  
-      var toastInfo = queue.shift()
-      showToastWindow(toastInfo.msg, function () {
-        timer = setTimeout(function () {
-          timer = null
-          hideToastWindow(function () {
-            isProcessing = false
-            that.show()
-          })
-        }, toastInfo.duration * 1000)
-      })
-    }
-  
-  }
-  
-  module.exports = {
-    push: toast.push.bind(toast)
-  }
-
-
-/***/ },
-/* 93 */
-/***/ function(module, exports, __webpack_require__) {
-
-  // style-loader: Adds some css to the DOM by adding a <style> tag
-  
-  // load the styles
-  var content = __webpack_require__(94);
-  if(typeof content === 'string') content = [[module.id, content, '']];
-  // add the styles to the DOM
-  var update = __webpack_require__(4)(content, {});
-  if(content.locals) module.exports = content.locals;
-  // Hot Module Replacement
-  if(false) {
-    // When the styles change, update the <style> tags
-    if(!content.locals) {
-      module.hot.accept("!!./../../css-loader/index.js?sourceMap!./../../sass-loader/index.js?sourceMap!./toast.scss", function() {
-        var newContent = require("!!./../../css-loader/index.js?sourceMap!./../../sass-loader/index.js?sourceMap!./toast.scss");
-        if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
-        update(newContent);
-      });
-    }
-    // When the module is disposed, remove the <style> tags
-    module.hot.dispose(function() { update(); });
-  }
-
-/***/ },
-/* 94 */
-/***/ function(module, exports, __webpack_require__) {
-
-  exports = module.exports = __webpack_require__(3)();
-  // imports
-  
-  
-  // module
-  exports.push([module.id, ".amfe-toast {\n  font-size: 0.32rem;\n  line-height: 0.426667rem;\n  position: fixed;\n  box-sizing: border-box;\n  max-width: 80%;\n  bottom: 2.666667rem;\n  left: 50%;\n  padding: 0.213333rem;\n  background-color: #000;\n  color: #fff;\n  text-align: center;\n  opacity: 0.6;\n  transition: all 0.4s ease-in-out;\n  border-radius: 0.066667rem;\n  -webkit-transform: translateX(-50%);\n  transform: translateX(-50%); }\n\n.amfe-toast.hide {\n  opacity: 0; }\n", "", {"version":3,"sources":["/./node_modules/modals/node_modules/modals/styles/toast.scss"],"names":[],"mappings":"AAAA;EACC,mBAAmB;EACnB,yBAAyB;EACzB,gBAAgB;EAChB,uBAAuB;EACvB,eAAe;EACf,oBAAoB;EACpB,UAAU;EACV,qBAAqB;EACrB,uBAAuB;EACvB,YAAY;EACZ,mBAAmB;EACnB,aAAa;EACb,iCAAiC;EACjC,2BAA2B;EAC3B,oCAA6B;EAC5B,4BAAqB,EACtB;;AAED;EACC,WAAW,EACX","file":"toast.scss","sourcesContent":[".amfe-toast {\n\tfont-size: 0.32rem; // 24px\n\tline-height: 0.426667rem; // 32px\n\tposition: fixed;\n\tbox-sizing: border-box;\n\tmax-width: 80%;\n\tbottom: 2.666667rem; // 200px\n\tleft: 50%;\n\tpadding: 0.213333rem; // 16px\n\tbackground-color: #000;\n\tcolor: #fff;\n\ttext-align: center;\n\topacity: 0.6;\n\ttransition: all 0.4s ease-in-out;\n\tborder-radius: 0.066667rem; // 5px\n\t-webkit-transform: translateX(-50%);\n  transform: translateX(-50%);\n}\n\n.amfe-toast.hide {\n\topacity: 0;\n}"],"sourceRoot":"webpack://"}]);
-  
-  // exports
-
-
-/***/ },
-/* 95 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict'
-  
-  var Sender = __webpack_require__(19)
-  
-  var _data = {}
-  
-  var animation = {
-  
-    /**
-     * transition
-     * @param  {string} ref        [description]
-     * @param  {obj} config     [description]
-     * @param  {string} callbackId [description]
-     */
-    transition: function (ref, config, callbackId) {
-      var refData = _data[ref]
-      var stylesKey = JSON.stringify(config.styles)
-      var weexInstance = this
-      // If the same component perform a animation with exactly the same
-      // styles in a sequence with so short interval that the prev animation
-      // is still in playing, then the next animation should be ignored.
-      if (refData && refData[stylesKey]) {
-        return
-      }
-      if (!refData) {
-        refData = _data[ref] = {}
-      }
-      refData[stylesKey] = true
-      return this.getComponentManager().transition(ref, config, function () {
-        // Remove the stylesKey in refData so that the same animation
-        // can be played again after current animation is already finished.
-        delete refData[stylesKey]
-        weexInstance.sender.performCallback(callbackId)
-      })
-    }
-  
-  }
-  
-  animation._meta = {
-    animation: [{
-      name: 'transition',
-      args: ['string', 'object', 'string']
-    }]
-  }
-  
-  module.exports = animation
-
-
-/***/ },
-/* 96 */
-/***/ function(module, exports) {
-
-  (typeof window === 'undefined') && (window = {ctrl: {}, lib: {}});!window.ctrl && (window.ctrl = {});!window.lib && (window.lib = {});!function(a,b){function c(a){Object.defineProperty(this,"val",{value:a.toString(),enumerable:!0}),this.gt=function(a){return c.compare(this,a)>0},this.gte=function(a){return c.compare(this,a)>=0},this.lt=function(a){return c.compare(this,a)<0},this.lte=function(a){return c.compare(this,a)<=0},this.eq=function(a){return 0===c.compare(this,a)}}b.env=b.env||{},c.prototype.toString=function(){return this.val},c.prototype.valueOf=function(){for(var a=this.val.split("."),b=[],c=0;c<a.length;c++){var d=parseInt(a[c],10);isNaN(d)&&(d=0);var e=d.toString();e.length<5&&(e=Array(6-e.length).join("0")+e),b.push(e),1===b.length&&b.push(".")}return parseFloat(b.join(""))},c.compare=function(a,b){a=a.toString().split("."),b=b.toString().split(".");for(var c=0;c<a.length||c<b.length;c++){var d=parseInt(a[c],10),e=parseInt(b[c],10);if(window.isNaN(d)&&(d=0),window.isNaN(e)&&(e=0),e>d)return-1;if(d>e)return 1}return 0},b.version=function(a){return new c(a)}}(window,window.lib||(window.lib={})),function(a,b){b.env=b.env||{};var c=a.location.search.replace(/^\?/,"");if(b.env.params={},c)for(var d=c.split("&"),e=0;e<d.length;e++){d[e]=d[e].split("=");try{b.env.params[d[e][0]]=decodeURIComponent(d[e][1])}catch(f){b.env.params[d[e][0]]=d[e][1]}}}(window,window.lib||(window.lib={})),function(a,b){b.env=b.env||{};var c,d=a.navigator.userAgent;if(c=d.match(/Windows\sPhone\s(?:OS\s)?([\d\.]+)/))b.env.os={name:"Windows Phone",isWindowsPhone:!0,version:c[1]};else if(d.match(/Safari/)&&(c=d.match(/Android[\s\/]([\d\.]+)/)))b.env.os={version:c[1]},d.match(/Mobile\s+Safari/)?(b.env.os.name="Android",b.env.os.isAndroid=!0):(b.env.os.name="AndroidPad",b.env.os.isAndroidPad=!0);else if(c=d.match(/(iPhone|iPad|iPod)/)){var e=c[1];c=d.match(/OS ([\d_\.]+) like Mac OS X/),b.env.os={name:e,isIPhone:"iPhone"===e||"iPod"===e,isIPad:"iPad"===e,isIOS:!0,version:c[1].split("_").join(".")}}else b.env.os={name:"unknown",version:"0.0.0"};b.version&&(b.env.os.version=b.version(b.env.os.version))}(window,window.lib||(window.lib={})),function(a,b){b.env=b.env||{};var c,d=a.navigator.userAgent;(c=d.match(/(?:UCWEB|UCBrowser\/)([\d\.]+)/))?b.env.browser={name:"UC",isUC:!0,version:c[1]}:(c=d.match(/MQQBrowser\/([\d\.]+)/))?b.env.browser={name:"QQ",isQQ:!0,version:c[1]}:(c=d.match(/Firefox\/([\d\.]+)/))?b.env.browser={name:"Firefox",isFirefox:!0,version:c[1]}:(c=d.match(/MSIE\s([\d\.]+)/))||(c=d.match(/IEMobile\/([\d\.]+)/))?(b.env.browser={version:c[1]},d.match(/IEMobile/)?(b.env.browser.name="IEMobile",b.env.browser.isIEMobile=!0):(b.env.browser.name="IE",b.env.browser.isIE=!0),d.match(/Android|iPhone/)&&(b.env.browser.isIELikeWebkit=!0)):(c=d.match(/(?:Chrome|CriOS)\/([\d\.]+)/))?(b.env.browser={name:"Chrome",isChrome:!0,version:c[1]},d.match(/Version\/[\d+\.]+\s*Chrome/)&&(b.env.browser.name="Chrome Webview",b.env.browser.isWebview=!0)):d.match(/Safari/)&&(c=d.match(/Android[\s\/]([\d\.]+)/))?b.env.browser={name:"Android",isAndroid:!0,version:c[1]}:d.match(/iPhone|iPad|iPod/)?d.match(/Safari/)?(c=d.match(/Version\/([\d\.]+)/),b.env.browser={name:"Safari",isSafari:!0,version:c[1]}):(c=d.match(/OS ([\d_\.]+) like Mac OS X/),b.env.browser={name:"iOS Webview",isWebview:!0,version:c[1].replace(/\_/g,".")}):b.env.browser={name:"unknown",version:"0.0.0"},b.version&&(b.env.browser.version=b.version(b.env.browser.version))}(window,window.lib||(window.lib={})),function(a,b){b.env=b.env||{};var c=a.navigator.userAgent;c.match(/Weibo/i)?b.env.thirdapp={appname:"Weibo",isWeibo:!0}:c.match(/MicroMessenger/i)?b.env.thirdapp={appname:"Weixin",isWeixin:!0}:b.env.thirdapp=!1}(window,window.lib||(window.lib={})),function(a,b){b.env=b.env||{};var c,d,e=a.navigator.userAgent;(d=e.match(/WindVane[\/\s]([\d\.\_]+)/))&&(c=d[1]);var f=!1,g="",h="",i="";(d=e.match(/AliApp\(([A-Z\-]+)\/([\d\.]+)\)/i))&&(f=!0,g=d[1],i=d[2],h=g.indexOf("-PD")>0?b.env.os.isIOS?"iPad":b.env.os.isAndroid?"AndroidPad":b.env.os.name:b.env.os.name),!g&&e.indexOf("TBIOS")>0&&(g="TB"),f?b.env.aliapp={windvane:b.version(c||"0.0.0"),appname:g||"unkown",version:b.version(i||"0.0.0"),platform:h||b.env.os.name}:b.env.aliapp=!1,b.env.taobaoApp=b.env.aliapp}(window,window.lib||(window.lib={}));;module.exports = window.lib['env'];
-
-/***/ }
-/******/ ]);
-//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgOTZlMGFmY2M2NTc2OTAzNzZlNTQiLCJ3ZWJwYWNrOi8vLy4vc3JjL3dlZXguanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3N0eWxlcy9iYXNlLnNjc3M/YzJlZSIsIndlYnBhY2s6Ly8vLi9zcmMvc3R5bGVzL2Jhc2Uuc2NzcyIsIndlYnBhY2s6Ly8vLi9+L2Nzcy1sb2FkZXIvbGliL2Nzcy1iYXNlLmpzIiwid2VicGFjazovLy8uL34vc3R5bGUtbG9hZGVyL2FkZFN0eWxlcy5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvY29uZmlnLmpzIiwid2VicGFjazovLy8uL3NyYy9sb2FkZXIuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3V0aWxzLmpzIiwid2VicGFjazovLy8uL3NyYy9wcm90b2NvbC5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50TWFuYWdlci5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvZnJhbWVVcGRhdGVyLmpzIiwid2VicGFjazovLy8uL3NyYy9hcHBlYXJXYXRjaGVyLmpzIiwid2VicGFjazovLy8uL3NyYy9sYXp5TG9hZC5qcyIsIndlYnBhY2s6Ly8vLi9+L2xhenlpbWcvYnVpbGQvaW1nLmNvbW1vbi5qcyIsIndlYnBhY2s6Ly8vLi9+L2FwcGVhcmpzL2J1aWxkL2FwcGVhci5jb21tb24uanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2FuaW1hdGlvbi5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy9jb21wb25lbnQuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2ZsZXhib3guanMiLCJ3ZWJwYWNrOi8vLy4vfi9maXhlZHN0aWNreS9idWlsZC9zdGlja3kuY29tbW9uLmpzIiwid2VicGFjazovLy8uL3NyYy9icmlkZ2Uvc2VuZGVyLmpzIiwid2VicGFjazovLy8uL3NyYy9icmlkZ2UvcmVjZWl2ZXIuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvbXBvbmVudHMvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvbXBvbmVudHMvcm9vdC5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy9jb250YWluZXIuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3N0eWxlcy9jb250YWluZXIuc2Nzcz9kNmI0Iiwid2VicGFjazovLy8uL3NyYy9zdHlsZXMvY29udGFpbmVyLnNjc3MiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvbXBvbmVudHMvaW1hZ2UuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvbXBvbmVudHMvYXRvbWljLmpzIiwid2VicGFjazovLy8uL3NyYy9jb21wb25lbnRzL3RleHQuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvbXBvbmVudHMvbGlzdC5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvc3R5bGVzL2xpc3Quc2Nzcz9iZDk2Iiwid2VicGFjazovLy8uL3NyYy9zdHlsZXMvbGlzdC5zY3NzIiwid2VicGFjazovLy8uL34vc2Nyb2xsanMvYnVpbGQvc2Nyb2xsLmNvbW1vbi5qcyIsIndlYnBhY2s6Ly8vLi9+L2FuaW1hdGlvbmpzL2J1aWxkL2FuaW1hdGlvbi5jb21tb24uanMiLCJ3ZWJwYWNrOi8vLy4vfi9jdWJpY2Jlemllci9idWlsZC9jdWJpY2Jlemllci5jb21tb24uanMiLCJ3ZWJwYWNrOi8vLy4vfi9nZXN0dXJlanMvYnVpbGQvZ2VzdHVyZWpzLmNvbW1vbi5qcyIsIndlYnBhY2s6Ly8vLi9+L21vdGlvbmpzL2J1aWxkL21vdGlvbi5jb21tb24uanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvbXBvbmVudHMvY291bnRkb3duLmpzIiwid2VicGFjazovLy8uL34va291bnRkb3duL2J1aWxkL2NvdW50ZG93bi5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy9tYXJxdWVlLmpzIiwid2VicGFjazovLy8uL3NyYy9jb21wb25lbnRzL3NsaWRlci5qcyIsIndlYnBhY2s6Ly8vLi9+L2NhcnJvdXNlbC9idWlsZC9jYXJyb3VzZWwuY29tbW9uLmpzIiwid2VicGFjazovLy8uL3NyYy9zdHlsZXMvc2xpZGVyLnNjc3M/NDM0YSIsIndlYnBhY2s6Ly8vLi9zcmMvc3R5bGVzL3NsaWRlci5zY3NzIiwid2VicGFjazovLy8uL3NyYy9jb21wb25lbnRzL2luZGljYXRvci5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvc3R5bGVzL2luZGljYXRvci5zY3NzPzQ0NmYiLCJ3ZWJwYWNrOi8vLy4vc3JjL3N0eWxlcy9pbmRpY2F0b3Iuc2NzcyIsIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy90YWJoZWFkZXIuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL21lc3NhZ2VRdWV1ZS5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvc3R5bGVzL3RhYmhlYWRlci5zY3NzP2Y1YTgiLCJ3ZWJwYWNrOi8vLy4vc3JjL3N0eWxlcy90YWJoZWFkZXIuc2NzcyIsIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy9zY3JvbGxlci5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvc3R5bGVzL3Njcm9sbGVyLnNjc3M/NjYzZCIsIndlYnBhY2s6Ly8vLi9zcmMvc3R5bGVzL3Njcm9sbGVyLnNjc3MiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvbXBvbmVudHMvaW5wdXQuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvbXBvbmVudHMvc2VsZWN0LmpzIiwid2VicGFjazovLy8uL3NyYy9jb21wb25lbnRzL2RhdGVwaWNrZXIuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvbXBvbmVudHMvdGltZXBpY2tlci5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy92aWRlby5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvc3R5bGVzL3ZpZGVvLnNjc3M/YjFmYSIsIndlYnBhY2s6Ly8vLi9zcmMvc3R5bGVzL3ZpZGVvLnNjc3MiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvbXBvbmVudHMvc3dpdGNoLmpzIiwid2VicGFjazovLy8uL3NyYy9zdHlsZXMvc3dpdGNoLnNjc3M/ZjY5OCIsIndlYnBhY2s6Ly8vLi9zcmMvc3R5bGVzL3N3aXRjaC5zY3NzIiwid2VicGFjazovLy8uL3NyYy9jb21wb25lbnRzL2EuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvbXBvbmVudHMvZW1iZWQuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2FwaS9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvYXBpL2RvbS5qcyIsIndlYnBhY2s6Ly8vLi9+L3Njcm9sbC10by9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvbXBvbmVudC10d2Vlbi9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvbXBvbmVudC1lbWl0dGVyL2luZGV4LmpzIiwid2VicGFjazovLy8uL34vY29tcG9uZW50LWNsb25lL2luZGV4LmpzIiwid2VicGFjazovLy8uL34vY29tcG9uZW50LXR5cGUvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vfi9lYXNlLWNvbXBvbmVudC9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvbXBvbmVudC1yYWYvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2FwaS9ldmVudC5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvYXBpL3BhZ2VJbmZvLmpzIiwid2VicGFjazovLy8uL3NyYy9hcGkvc3RyZWFtLmpzIiwid2VicGFjazovLy8uL3NyYy9hcGkvbW9kYWwuanMiLCJ3ZWJwYWNrOi8vLy4vfi9tb2RhbHMvc3JjL2luZGV4LmpzIiwid2VicGFjazovLy8uL34vbW9kYWxzL3NyYy9hbGVydC5qcyIsIndlYnBhY2s6Ly8vLi9+L21vZGFscy9zcmMvbW9kYWwuanMiLCJ3ZWJwYWNrOi8vLy4vfi9tb2RhbHMvc3R5bGVzL21vZGFsLnNjc3M/ZGE0OCIsIndlYnBhY2s6Ly8vLi9+L21vZGFscy9zdHlsZXMvbW9kYWwuc2NzcyIsIndlYnBhY2s6Ly8vLi9+L21vZGFscy9zdHlsZXMvYWxlcnQuc2Nzcz81NzgyIiwid2VicGFjazovLy8uL34vbW9kYWxzL3N0eWxlcy9hbGVydC5zY3NzIiwid2VicGFjazovLy8uL34vbW9kYWxzL3NyYy9jb25maXJtLmpzIiwid2VicGFjazovLy8uL34vbW9kYWxzL3N0eWxlcy9jb25maXJtLnNjc3M/ZDY0YSIsIndlYnBhY2s6Ly8vLi9+L21vZGFscy9zdHlsZXMvY29uZmlybS5zY3NzIiwid2VicGFjazovLy8uL34vbW9kYWxzL3NyYy9wcm9tcHQuanMiLCJ3ZWJwYWNrOi8vLy4vfi9tb2RhbHMvc3R5bGVzL3Byb21wdC5zY3NzPzdlMWMiLCJ3ZWJwYWNrOi8vLy4vfi9tb2RhbHMvc3R5bGVzL3Byb21wdC5zY3NzIiwid2VicGFjazovLy8uL34vbW9kYWxzL3NyYy90b2FzdC5qcyIsIndlYnBhY2s6Ly8vLi9+L21vZGFscy9zdHlsZXMvdG9hc3Quc2Nzcz9hNjBmIiwid2VicGFjazovLy8uL34vbW9kYWxzL3N0eWxlcy90b2FzdC5zY3NzIiwid2VicGFjazovLy8uL3NyYy9hcGkvYW5pbWF0aW9uLmpzIiwid2VicGFjazovLy8uL34vZW52ZC9idWlsZC9lbnZkLmNvbW1vbi5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHVCQUFlO0FBQ2Y7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7Ozs7Ozs7QUN0Q0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDtBQUNBO0FBQ0EsSUFBRzs7QUFFSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTCxJQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLElBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTCxJQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxRQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsUUFBTztBQUNQOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUTs7QUFFUixJQUFHOztBQUVIO0FBQ0E7QUFDQSxJQUFHOztBQUVIO0FBQ0E7QUFDQSxJQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxFQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBLEVBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFHO0FBQ0g7QUFDQSxFQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBQzs7QUFFRDtBQUNBO0FBQ0E7O0FB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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRTs7Ozs7O0FDakdBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSx1Q0FBc0MsT0FBTztBQUM3QztBQUNBO0FBQ0EsSUFBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsZ0JBQWU7O0FBRWY7QUFDQTtBQUNBLElBQUc7O0FBRUg7QUFDQTtBQUNBLElBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLFFBQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQU87QUFDUDtBQUNBO0FBQ0EsUUFBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFHO0FBQ0g7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0EsSUFBRztBQUNIO0FBQ0E7QUFDQSxJQUFHO0FBQ0gsRUFBQztBQUNEO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSCxFQUFDOztBQUVE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Q0E7QUFDQTtBQUNBLElBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBRzs7QUFFSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esc0JBQXFCLHFCQUFxQjtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsSUFBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQSxJQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBOztBQUVBOzs7Ozs7O0FDaFpBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHdCQUF1QixzQkFBc0I7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0wsSUFBRzs7QUFFSDtBQUNBO0FBQ0EsSUFBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQSxJQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBLElBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7Ozs7Ozs7QUMvQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esa0JBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1B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Q0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxJQUFHOztBQUVIO0FBQ0E7QUFDQSxJQUFHOztBQUVIO0FBQ0E7QUFDQSxJQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBLElBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBcUIscUJBQXFCO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0EsSUFBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTCxnQ0FBK0IsT0FBTztBQUN0QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBLElBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0NBQW1DLE9BQU87QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQU87QUFDUDtBQUNBO0FBQ0EsVUFBUztBQUNU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d0I7Ozs7OztBQ25EQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7QUFDQSxJQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7Ozs7Ozs7QUM5SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDRCOzs7Ozs7QUM3Q0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7Ozs7Ozs7QUN4Q0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7Ozs7Ozs7QUNiQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdEQUFtRjtBQUNuRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFHO0FBQ0g7QUFDQTtBQUNBLGlDQUFnQyxVQUFVLEVBQUU7QUFDNUMsRTs7Ozs7O0FDcEJBO0FBQ0E7OztBQUdBO0FBQ0EsNENBQTJDLDJCQUEyQix5QkFBeUIsMEJBQTBCLGtCQUFrQixpQ0FBaUMsbUNBQW1DLDJCQUEyQix1QkFBdUIsMEJBQTBCLGNBQWMsZUFBZSxFQUFFLG1CQUFtQiwyQkFBMkIsdUJBQXVCLEVBQUUsVUFBVSx1RkFBdUYsWUFBWSxhQUFhLGFBQWEsV0FBVyxZQUFZLGFBQWEsYUFBYSxhQUFhLGFBQWEsV0FBVyxnQkFBZ0IsS0FBSyxZQUFZLGdGQUFnRiwwQkFBMEIsd0JBQXdCLHlCQUF5QixpQkFBaUIsZ0NBQWdDLGtDQUFrQywwQkFBMEIsc0JBQXNCLHlCQUF5QixhQUFhLGdCQUFnQixtQkFBbUIsMkJBQTJCLHVCQUF1QixHQUFHLDZCQUE2Qjs7QUFFeGpDOzs7Ozs7O0FDUEE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOzs7Ozs7O0FDeERBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7Ozs7OztBQzVCQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0NBQXFDO0FBQ3JDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DQUFtQztBQUNuQztBQUNBO0FBQ0EsVUFBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLFFBQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLHVCQUFzQjtBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxFQUFDOztBQUVEOzs7Ozs7O0FDdkZBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQSxNQUFLO0FBQ0wsSUFBRzs7QUFFSDtBQUNBO0FBQ0EsSUFBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsSUFBRztBQUNIO0FBQ0E7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QTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsSUFBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQU87QUFDUCxNQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDQUFxQztBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDQUFxQztBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLE1BQUs7O0FBRUw7Ozs7Ozs7QUMxTUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnREFBbUY7QUFDbkY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBRztBQUNIO0FBQ0E7QUFDQSxpQ0FBZ0MsVUFB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QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBLElBQUc7QUFDSDtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDektBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7Ozs7O0FDakNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGVBQWMsT0FBTztBQUNyQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtB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LGlCQUFpQixnQkFBZ0IsZ0NBQWdDLG1EQUFtRCx3QkFBd0IsZ09BQWdPLDJHQUEyRyw4Q0FBOEMsa0NBQWtDLElBQUksbUMiLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VzQ29udGVudCI6WyIgXHQvLyBUaGUgbW9kdWxlIGNhY2hlXG4gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuXG4gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXG4gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSlcbiBcdFx0XHRyZXR1cm4gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0uZXhwb3J0cztcblxuIFx0XHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuIFx0XHR2YXIgbW9kdWxlID0gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0gPSB7XG4gXHRcdFx0ZXhwb3J0czoge30sXG4gXHRcdFx0aWQ6IG1vZHVsZUlkLFxuIFx0XHRcdGxvYWRlZDogZmFsc2VcbiBcdFx0fTtcblxuIFx0XHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cbiBcdFx0bW9kdWxlc1ttb2R1bGVJZF0uY2FsbChtb2R1bGUuZXhwb3J0cywgbW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cbiBcdFx0Ly8gRmxhZyB0aGUgbW9kdWxlIGFzIGxvYWRlZFxuIFx0XHRtb2R1bGUubG9hZGVkID0gdHJ1ZTtcblxuIFx0XHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG4gXHR9XG5cblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBpbnN0YWxsZWRNb2R1bGVzO1xuXG4gXHQvLyBfX3dlYnBhY2tfcHVibGljX3BhdGhfX1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCJcIjtcblxuIFx0Ly8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzXG4gXHRyZXR1cm4gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIHdlYnBhY2svYm9vdHN0cmFwIDk2ZTBhZmNjNjU3NjkwMzc2ZTU0XG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnJlcXVpcmUoJy4vc3R5bGVzL2Jhc2Uuc2NzcycpXG5cbnZhciBjb25maWcgPSByZXF1aXJlKCcuL2NvbmZpZycpXG52YXIgTG9hZGVyID0gcmVxdWlyZSgnLi9sb2FkZXInKVxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpXG52YXIgcHJvdG9jb2wgPSByZXF1aXJlKCcuL3Byb3RvY29sJylcbnZhciBDb21wb25lbnRNYW5hZ2VyID0gcmVxdWlyZSgnLi9jb21wb25lbnRNYW5hZ2VyJylcbnZhciBDb21wb25lbnQgPSByZXF1aXJlKCcuL2NvbXBvbmVudHMvY29tcG9uZW50JylcbnZhciBTZW5kZXIgPSByZXF1aXJlKCcuL2JyaWRnZS9zZW5kZXInKVxudmFyIHJlY2VpdmVyID0gcmVxdWlyZSgnLi9icmlkZ2UvcmVjZWl2ZXInKVxuXG4vLyBDb21wb25lbnRzIGFuZCBhcGlzLlxudmFyIGNvbXBvbmVudHMgPSByZXF1aXJlKCcuL2NvbXBvbmVudHMnKVxudmFyIGFwaSA9IHJlcXVpcmUoJy4vYXBpJylcbnJlcXVpcmUoJ2VudmQnKVxuXG52YXIgV0VBUFBfU1RZTEVfSUQgPSAnd2VhcHAtc3R5bGUnXG5cbnZhciBERUZBVUxUX0RFU0lHTl9XSURUSCA9IDc1MFxudmFyIERFRkFVTFRfUk9PVF9JRCA9ICd3ZWV4J1xudmFyIERFRkFVTFRfSlNPTl9DQUxMQkFDS19OQU1FID0gJ3dlZXhKc29ucENhbGxiYWNrJ1xuXG4vLyBjb25maWcuc2NhbGUgPSB3aW5kb3cuaW5uZXJXaWR0aCAvIERFRkFVTFRfREVTSUdOX1dJRFRIXG5cbndpbmRvdy5XWEVudmlyb25tZW50ID0ge1xuICB3ZWV4VmVyc2lvbjogY29uZmlnLndlZXhWZXJzaW9uLFxuICBhcHBOYW1lOiBsaWIuZW52LmFsaWFwcCA/IGxpYi5lbnYuYWxpYXBwLmFwcG5hbWUgOiBudWxsLFxuICBhcHBWZXJzaW9uOiBsaWIuZW52LmFsaWFwcCA/IGxpYi5lbnYuYWxpYXBwLnZlcnNpb24udmFsIDogbnVsbCxcbiAgcGxhdGZvcm06IGxpYi5lbnYub3MgPyBsaWIuZW52Lm9zLm5hbWUgOiBudWxsLFxuICBvc1ZlcnNpb246IGxpYi5lbnYub3MgPyBsaWIuZW52Lm9zLnZlcnNpb24udmFsIDogbnVsbCxcbiAgZGV2aWNlSGVpZ2h0OiB3aW5kb3cuaW5uZXJIZWlnaHQgLyBjb25maWcuc2NhbGVcbn1cblxudmFyIF9pbnN0YW5jZU1hcCA9IHt9XG5cbmZ1bmN0aW9uIFdlZXgob3B0aW9ucykge1xuXG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBXZWV4KSkge1xuICAgIHJldHVybiBuZXcgV2VleChvcHRpb25zKVxuICB9XG5cbiAgLy8gV2lkdGggb2YgdGhlIHJvb3QgY29udGFpbmVyLiBEZWZhdWx0IGlzIHdpbmRvdy5pbm5lcldpZHRoLlxuICB0aGlzLndpZHRoID0gb3B0aW9ucy53aWR0aCB8fCB3aW5kb3cuaW5uZXJXaWR0aFxuICB0aGlzLmJ1bmRsZVVybCA9IG9wdGlvbnMuYnVuZGxlVXJsIHx8IGxvY2F0aW9uLmhyZWZcbiAgdGhpcy5pbnN0YW5jZUlkID0gb3B0aW9ucy5hcHBJZFxuICB0aGlzLnJvb3RJZCA9IG9wdGlvbnMucm9vdElkIHx8IChERUZBVUxUX1JPT1RfSUQgKyB1dGlscy5nZXRSYW5kb20oMTApKVxuICB0aGlzLmRlc2lnbldpZHRoID0gb3B0aW9ucy5kZXNpZ25XaWR0aCB8fCBERUZBVUxUX0RFU0lHTl9XSURUSFxuICB0aGlzLmpzb25wQ2FsbGJhY2sgPSBvcHRpb25zLmpzb25wQ2FsbGJhY2sgfHwgREVGQVVMVF9KU09OX0NBTExCQUNLX05BTUVcbiAgdGhpcy5zb3VyY2UgPSBvcHRpb25zLnNvdXJjZVxuICB0aGlzLmxvYWRlciA9IG9wdGlvbnMubG9hZGVyXG5cbiAgdGhpcy5kYXRhID0gb3B0aW9ucy5kYXRhXG5cbiAgdGhpcy5pbml0U2NhbGUoKVxuICB0aGlzLmluaXRDb21wb25lbnRNYW5hZ2VyKClcbiAgdGhpcy5pbml0QnJpZGdlKClcbiAgV2VleC5hZGRJbnN0YW5jZSh0aGlzKVxuXG4gIHByb3RvY29sLmluamVjdFdlZXhJbnN0YW5jZSh0aGlzKVxuXG4gIHRoaXMubG9hZEJ1bmRsZShmdW5jdGlvbiAoZXJyLCBhcHBDb2RlKSB7XG4gICAgaWYgKCFlcnIpIHtcbiAgICAgIHRoaXMuY3JlYXRlQXBwKGNvbmZpZywgYXBwQ29kZSlcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc29sZS5lcnJvcignbG9hZCBidW5kbGUgZXJyOicsIGVycilcbiAgICB9XG4gIH0uYmluZCh0aGlzKSlcblxufVxuXG5XZWV4LmluaXQgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICBpZiAodXRpbHMuaXNBcnJheShvcHRpb25zKSkge1xuICAgIG9wdGlvbnMuZm9yRWFjaChmdW5jdGlvbiAoY29uZmlnKSB7XG4gICAgICBuZXcgV2VleChjb25maWcpXG4gICAgfSlcbiAgfSBlbHNlIGlmIChcbiAgICAgIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvcHRpb25zKS5zbGljZSg4LCAtMSkgPT09ICdPYmplY3QnXG4gICAgKSB7XG4gICAgbmV3IFdlZXgob3B0aW9ucylcbiAgfVxufVxuXG5XZWV4LmFkZEluc3RhbmNlID0gZnVuY3Rpb24gKGluc3RhbmNlKSB7XG4gIF9pbnN0YW5jZU1hcFtpbnN0YW5jZS5pbnN0YW5jZUlkXSA9IGluc3RhbmNlXG59XG5cbldlZXguZ2V0SW5zdGFuY2UgPSBmdW5jdGlvbiAoaW5zdGFuY2VJZCkge1xuICByZXR1cm4gX2luc3RhbmNlTWFwW2luc3RhbmNlSWRdXG59XG5cbldlZXgucHJvdG90eXBlID0ge1xuXG4gIGluaXRCcmlkZ2U6IGZ1bmN0aW9uICgpIHtcbiAgICByZWNlaXZlci5pbml0KHRoaXMpXG4gICAgdGhpcy5zZW5kZXIgPSBuZXcgU2VuZGVyKHRoaXMpXG4gIH0sXG5cbiAgbG9hZEJ1bmRsZTogZnVuY3Rpb24gKGNiKSB7XG4gICAgTG9hZGVyLmxvYWQoe1xuICAgICAganNvbnBDYWxsYmFjazogdGhpcy5qc29ucENhbGxiYWNrLFxuICAgICAgc291cmNlOiB0aGlzLnNvdXJjZSxcbiAgICAgIGxvYWRlcjogdGhpcy5sb2FkZXJcbiAgICB9LCBjYilcbiAgfSxcblxuICBjcmVhdGVBcHA6IGZ1bmN0aW9uIChjb25maWcsIGFwcENvZGUpIHtcbiAgICB2YXIgcm9vdCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyMnICsgdGhpcy5yb290SWQpXG4gICAgaWYgKCFyb290KSB7XG4gICAgICByb290ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgICAgIHJvb3QuaWQgPSB0aGlzLnJvb3RJZFxuICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChyb290KVxuICAgIH1cblxuICAgIHZhciBwcm9taXNlID0gd2luZG93LmNyZWF0ZUluc3RhbmNlKFxuICAgICAgdGhpcy5pbnN0YW5jZUlkXG4gICAgICAsIGFwcENvZGVcbiAgICAgICwge1xuICAgICAgICBidW5kbGVVcmw6IHRoaXMuYnVuZGxlVXJsLFxuICAgICAgICBkZWJ1ZzogY29uZmlnLmRlYnVnXG4gICAgICB9XG4gICAgICAsIHRoaXMuZGF0YVxuICAgIClcblxuICAgIGlmIChQcm9taXNlICYmIHByb21pc2UgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICBwcm9taXNlLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBXZWV4Ll9pbnN0YW5jZXNbdGhpcy5pbnN0YW5jZUlkXSA9IHRoaXMucm9vdFxuICAgICAgfS5iaW5kKHRoaXMpKS5jYXRjaChmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgIGlmIChlcnIgJiYgY29uZmlnLmRlYnVnKSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihlcnIpXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuXG4gICAgLy8gRG8gbm90IGRlc3Ryb3kgaW5zdGFuY2UgaGVyZSwgYmVjYXVzZSBpbiBtb3N0IGJyb3dzZXJcbiAgICAvLyBwcmVzcyBiYWNrIGJ1dHRvbiB0byBiYWNrIHRvIHRoaXMgcGFnZSB3aWxsIG5vdCByZWZyZXNoXG4gICAgLy8gdGhlIHdpbmRvdyBhbmQgdGhlIGluc3RhbmNlIHdpbGwgbm90IGJlIHJlY3JlYXRlZCB0aGVuLlxuICAgIC8vIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdiZWZvcmV1bmxvYWQnLCBmdW5jdGlvbiAoZSkge1xuICAgIC8vIH0pXG5cbiAgfSxcblxuICBpbml0U2NhbGU6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnNjYWxlID0gdGhpcy53aWR0aCAvIHRoaXMuZGVzaWduV2lkdGhcbiAgfSxcblxuICBpbml0Q29tcG9uZW50TWFuYWdlcjogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuX2NvbXBvbmVudE1hbmFnZXIgPSBuZXcgQ29tcG9uZW50TWFuYWdlcih0aGlzKVxuICB9LFxuXG4gIGdldENvbXBvbmVudE1hbmFnZXI6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5fY29tcG9uZW50TWFuYWdlclxuICB9XG59XG5cbldlZXguYXBwZW5kU3R5bGUgPSBmdW5jdGlvbiAoY3NzKSB7XG4gIHV0aWxzLmFwcGVuZFN0eWxlKGNzcywgV0VBUFBfU1RZTEVfSUQpXG59LFxuXG4vLyBSZWdpc3RlciBhIG5ldyBjb21wb25lbnQgd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUuXG5XZWV4LnJlZ2lzdGVyQ29tcG9uZW50ID0gZnVuY3Rpb24gKG5hbWUsIGNvbXApIHtcbiAgQ29tcG9uZW50TWFuYWdlci5yZWdpc3RlckNvbXBvbmVudChuYW1lLCBjb21wKVxufSxcblxuLy8gUmVnaXN0ZXIgYSBuZXcgYXBpIG1vZHVsZS5cbi8vIElmIHRoZSBtb2R1bGUgYWxyZWFkeSBleGlzdHMsIGp1c3QgYWRkIG1ldGhvZHMgZnJvbSB0aGVcbi8vIG5ldyBtb2R1bGUgdG8gdGhlIG9sZCBvbmUuXG5XZWV4LnJlZ2lzdGVyQXBpTW9kdWxlID0gZnVuY3Rpb24gKG5hbWUsIG1vZHVsZSwgbWV0YSkge1xuICBpZiAoIXByb3RvY29sLmFwaU1vZHVsZVtuYW1lXSkge1xuICAgIHByb3RvY29sLmFwaU1vZHVsZVtuYW1lXSA9IG1vZHVsZVxuICB9IGVsc2Uge1xuICAgIGZvciAodmFyIGtleSBpbiBtb2R1bGUpIHtcbiAgICAgIGlmIChtb2R1bGUuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICBwcm90b2NvbC5hcGlNb2R1bGVbbmFtZV1ba2V5XSA9IG1vZHVsZVtrZXldXG4gICAgICB9XG4gICAgfVxuICB9XG4gIC8vIHJlZ2lzdGVyIEFQSSBtb2R1bGUncyBtZXRhIGluZm8gdG8ganNmcmFtZXdvcmtcbiAgaWYgKG1ldGEpIHtcbiAgICBwcm90b2NvbC5zZXRBcGlNb2R1bGVNZXRhKG1ldGEpXG4gICAgd2luZG93LnJlZ2lzdGVyTW9kdWxlcyhwcm90b2NvbC5nZXRBcGlNb2R1bGVNZXRhKG5hbWUpLCB0cnVlKVxuICB9XG59LFxuXG4vLyBSZWdpc3RlciBhIG5ldyBhcGkgbWV0aG9kIGZvciB0aGUgc3BlY2lmaWVkIG1vZHVsZS5cbi8vIG9wdHM6XG4vLyAgLSBhcmdzOiB0eXBlIG9mIGFyZ3VtZW50cyB0aGUgQVBJIG1ldGhvZCB0YWtlcyBzdWNoXG4vLyAgICBhcyBbJ3N0cmluZycsICdmdW5jdGlvbiddXG5XZWV4LnJlZ2lzdGVyQXBpID0gZnVuY3Rpb24gKG1vZHVsZU5hbWUsIG5hbWUsIG1ldGhvZCwgYXJncykge1xuICBpZiAodHlwZW9mIG1ldGhvZCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVyblxuICB9XG4gIGlmICghcHJvdG9jb2wuYXBpTW9kdWxlW21vZHVsZU5hbWVdKSB7XG4gICAgcHJvdG9jb2wuYXBpTW9kdWxlW21vZHVsZU5hbWVdID0ge31cbiAgICBwcm90b2NvbC5fbWV0YVttb2R1bGVOYW1lXSA9IFtdXG4gIH1cbiAgcHJvdG9jb2wuYXBpTW9kdWxlW21vZHVsZU5hbWVdW25hbWVdID0gbWV0aG9kXG4gIGlmICghYXJncykge1xuICAgIHJldHVyblxuICB9XG4gIC8vIHJlZ2lzdGVyIEFQSSBtZXRhIGluZm8gdG8ganNmcmFtZXdvcmtcbiAgcHJvdG9jb2wuc2V0QXBpTWV0YShtb2R1bGVOYW1lLCB7XG4gICAgbmFtZTogbmFtZSxcbiAgICBhcmdzOiBhcmdzXG4gIH0pXG4gIHdpbmRvdy5yZWdpc3Rlck1vZHVsZXMocHJvdG9jb2wuZ2V0QXBpTW9kdWxlTWV0YShtb2R1bGVOYW1lLCBtZXRhKSwgdHJ1ZSlcbn0sXG5cbi8vIFJlZ2lzdGVyIGEgbmV3IHdlZXgtYnVuZGxlLWxvYWRlci5cbldlZXgucmVnaXN0ZXJMb2FkZXIgPSBmdW5jdGlvbiAobmFtZSwgbG9hZGVyRnVuYykge1xuICBMb2FkZXIucmVnaXN0ZXJMb2FkZXIobmFtZSwgbG9hZGVyRnVuYylcbn1cblxuLy8gVG8gaW5zdGFsbCBjb21wb25lbnRzIGFuZCBwbHVnaW5zLlxuV2VleC5pbnN0YWxsID0gZnVuY3Rpb24gKG1vZCkge1xuICBtb2QuaW5pdChXZWV4KVxufVxuXG5XZWV4LnN0b3BUaGVXb3JsZCA9IGZ1bmN0aW9uICgpIHtcbiAgZm9yICh2YXIgaW5zdGFuY2VJZCBpbiBfaW5zdGFuY2VNYXApIHtcbiAgICBpZiAoX2luc3RhbmNlTWFwLmhhc093blByb3BlcnR5KGluc3RhbmNlSWQpKSB7XG4gICAgICB3aW5kb3cuZGVzdHJveUluc3RhbmNlKGluc3RhbmNlSWQpXG4gICAgfVxuICB9XG59XG5cbihmdW5jdGlvbiBzdGFydFJlZnJlc2hDb250cm9sbGVyKCkge1xuICBpZiAobG9jYXRpb24uc2VhcmNoLmluZGV4T2YoJ2hvdC1yZWxvYWRfY29udHJvbGxlcicpID09PSAtMSkgIHtcbiAgICByZXR1cm5cbiAgfVxuICBpZiAoIXdpbmRvdy5XZWJTb2NrZXQpIHtcbiAgICBjb25zb2xlLmluZm8oJ2F1dG8gcmVmcmVzaCBuZWVkIFdlYlNvY2tldCBzdXBwb3J0JylcbiAgICByZXR1cm5cbiAgfVxuICB2YXIgaG9zdCA9IGxvY2F0aW9uLmhvc3RuYW1lXG4gIHZhciBwb3J0ID0gODA4MlxuICB2YXIgY2xpZW50ID0gbmV3IFdlYlNvY2tldCgnd3M6Ly8nICsgaG9zdCArICc6JyArIHBvcnQgKyAnLycsXG4gICAgJ2VjaG8tcHJvdG9jb2wnXG4gIClcbiAgY2xpZW50Lm9uZXJyb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgY29uc29sZS5sb2coJ3JlZnJlc2ggY29udHJvbGxlciB3ZWJzb2NrZXQgY29ubmVjdGlvbiBlcnJvcicpXG4gIH1cbiAgY2xpZW50Lm9ubWVzc2FnZSA9IGZ1bmN0aW9uIChlKSB7XG4gICAgY29uc29sZS5sb2coJ1JlY2VpdmVkOiBcXCcnICsgZS5kYXRhICsgJ1xcJycpXG4gICAgaWYgKGUuZGF0YSAgPT09ICdyZWZyZXNoJykge1xuICAgICAgbG9jYXRpb24ucmVsb2FkKClcbiAgICB9XG4gIH1cbn0oKSlcblxuLy8gV2VleC5pbnN0YWxsKHJlcXVpcmUoJ3dlZXgtY29tcG9uZW50cycpKVxuV2VleC5pbnN0YWxsKGNvbXBvbmVudHMpXG5XZWV4Lmluc3RhbGwoYXBpKVxuXG5XZWV4LkNvbXBvbmVudCA9IENvbXBvbmVudFxuV2VleC5Db21wb25lbnRNYW5hZ2VyID0gQ29tcG9uZW50TWFuYWdlclxuV2VleC51dGlscyA9IHV0aWxzXG5XZWV4LmNvbmZpZyA9IGNvbmZpZ1xuXG5nbG9iYWwud2VleCA9IFdlZXhcbm1vZHVsZS5leHBvcnRzID0gV2VleFxuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL3NyYy93ZWV4LmpzXG4gKiogbW9kdWxlIGlkID0gMFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLy8gc3R5bGUtbG9hZGVyOiBBZGRzIHNvbWUgY3NzIHRvIHRoZSBET00gYnkgYWRkaW5nIGEgPHN0eWxlPiB0YWdcblxuLy8gbG9hZCB0aGUgc3R5bGVzXG52YXIgY29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vbm9kZV9tb2R1bGVzL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL2Jhc2Uuc2Nzc1wiKTtcbmlmKHR5cGVvZiBjb250ZW50ID09PSAnc3RyaW5nJykgY29udGVudCA9IFtbbW9kdWxlLmlkLCBjb250ZW50LCAnJ11dO1xuLy8gYWRkIHRoZSBzdHlsZXMgdG8gdGhlIERPTVxudmFyIHVwZGF0ZSA9IHJlcXVpcmUoXCIhLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2FkZFN0eWxlcy5qc1wiKShjb250ZW50LCB7fSk7XG5pZihjb250ZW50LmxvY2FscykgbW9kdWxlLmV4cG9ydHMgPSBjb250ZW50LmxvY2Fscztcbi8vIEhvdCBNb2R1bGUgUmVwbGFjZW1lbnRcbmlmKG1vZHVsZS5ob3QpIHtcblx0Ly8gV2hlbiB0aGUgc3R5bGVzIGNoYW5nZSwgdXBkYXRlIHRoZSA8c3R5bGU+IHRhZ3Ncblx0aWYoIWNvbnRlbnQubG9jYWxzKSB7XG5cdFx0bW9kdWxlLmhvdC5hY2NlcHQoXCIhIS4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vbm9kZV9tb2R1bGVzL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL2Jhc2Uuc2Nzc1wiLCBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBuZXdDb250ZW50ID0gcmVxdWlyZShcIiEhLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi9ub2RlX21vZHVsZXMvc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vYmFzZS5zY3NzXCIpO1xuXHRcdFx0aWYodHlwZW9mIG5ld0NvbnRlbnQgPT09ICdzdHJpbmcnKSBuZXdDb250ZW50ID0gW1ttb2R1bGUuaWQsIG5ld0NvbnRlbnQsICcnXV07XG5cdFx0XHR1cGRhdGUobmV3Q29udGVudCk7XG5cdFx0fSk7XG5cdH1cblx0Ly8gV2hlbiB0aGUgbW9kdWxlIGlzIGRpc3Bvc2VkLCByZW1vdmUgdGhlIDxzdHlsZT4gdGFnc1xuXHRtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24oKSB7IHVwZGF0ZSgpOyB9KTtcbn1cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL3N0eWxlcy9iYXNlLnNjc3NcbiAqKiBtb2R1bGUgaWQgPSAxXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikoKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIioge1xcbiAgbWFyZ2luOiAwO1xcbiAgcGFkZGluZzogMDtcXG4gIHRleHQtc2l6ZS1hZGp1c3Q6IG5vbmU7IH1cXG5cXG51bCwgb2wge1xcbiAgbGlzdC1zdHlsZTogbm9uZTsgfVxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi9zcmMvc3JjL3N0eWxlcy9iYXNlLnNjc3NcIl0sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIkFBQUE7RUFDRSxVQUFTO0VBQ1QsV0FBVTtFQUNWLHVCQUNELEVBQUM7O0FBQ0Y7RUFDRSxpQkFDRCxFQUFDXCIsXCJmaWxlXCI6XCJiYXNlLnNjc3NcIixcInNvdXJjZXNDb250ZW50XCI6W1wiKiB7XFxuICBtYXJnaW46MDtcXG4gIHBhZGRpbmc6MDtcXG4gIHRleHQtc2l6ZS1hZGp1c3Q6bm9uZVxcbn1cXG51bCxvbCB7XFxuICBsaXN0LXN0eWxlOm5vbmVcXG59XCJdLFwic291cmNlUm9vdFwiOlwid2VicGFjazovL1wifV0pO1xuXG4vLyBleHBvcnRzXG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL34vc2Fzcy1sb2FkZXI/c291cmNlTWFwIS4vc3JjL3N0eWxlcy9iYXNlLnNjc3NcbiAqKiBtb2R1bGUgaWQgPSAyXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKlxyXG5cdE1JVCBMaWNlbnNlIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwXHJcblx0QXV0aG9yIFRvYmlhcyBLb3BwZXJzIEBzb2tyYVxyXG4qL1xyXG4vLyBjc3MgYmFzZSBjb2RlLCBpbmplY3RlZCBieSB0aGUgY3NzLWxvYWRlclxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKCkge1xyXG5cdHZhciBsaXN0ID0gW107XHJcblxyXG5cdC8vIHJldHVybiB0aGUgbGlzdCBvZiBtb2R1bGVzIGFzIGNzcyBzdHJpbmdcclxuXHRsaXN0LnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcoKSB7XHJcblx0XHR2YXIgcmVzdWx0ID0gW107XHJcblx0XHRmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xyXG5cdFx0XHR2YXIgaXRlbSA9IHRoaXNbaV07XHJcblx0XHRcdGlmKGl0ZW1bMl0pIHtcclxuXHRcdFx0XHRyZXN1bHQucHVzaChcIkBtZWRpYSBcIiArIGl0ZW1bMl0gKyBcIntcIiArIGl0ZW1bMV0gKyBcIn1cIik7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0cmVzdWx0LnB1c2goaXRlbVsxXSk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHRcdHJldHVybiByZXN1bHQuam9pbihcIlwiKTtcclxuXHR9O1xyXG5cclxuXHQvLyBpbXBvcnQgYSBsaXN0IG9mIG1vZHVsZXMgaW50byB0aGUgbGlzdFxyXG5cdGxpc3QuaSA9IGZ1bmN0aW9uKG1vZHVsZXMsIG1lZGlhUXVlcnkpIHtcclxuXHRcdGlmKHR5cGVvZiBtb2R1bGVzID09PSBcInN0cmluZ1wiKVxyXG5cdFx0XHRtb2R1bGVzID0gW1tudWxsLCBtb2R1bGVzLCBcIlwiXV07XHJcblx0XHR2YXIgYWxyZWFkeUltcG9ydGVkTW9kdWxlcyA9IHt9O1xyXG5cdFx0Zm9yKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcclxuXHRcdFx0dmFyIGlkID0gdGhpc1tpXVswXTtcclxuXHRcdFx0aWYodHlwZW9mIGlkID09PSBcIm51bWJlclwiKVxyXG5cdFx0XHRcdGFscmVhZHlJbXBvcnRlZE1vZHVsZXNbaWRdID0gdHJ1ZTtcclxuXHRcdH1cclxuXHRcdGZvcihpID0gMDsgaSA8IG1vZHVsZXMubGVuZ3RoOyBpKyspIHtcclxuXHRcdFx0dmFyIGl0ZW0gPSBtb2R1bGVzW2ldO1xyXG5cdFx0XHQvLyBza2lwIGFscmVhZHkgaW1wb3J0ZWQgbW9kdWxlXHJcblx0XHRcdC8vIHRoaXMgaW1wbGVtZW50YXRpb24gaXMgbm90IDEwMCUgcGVyZmVjdCBmb3Igd2VpcmQgbWVkaWEgcXVlcnkgY29tYmluYXRpb25zXHJcblx0XHRcdC8vICB3aGVuIGEgbW9kdWxlIGlzIGltcG9ydGVkIG11bHRpcGxlIHRpbWVzIHdpdGggZGlmZmVyZW50IG1lZGlhIHF1ZXJpZXMuXHJcblx0XHRcdC8vICBJIGhvcGUgdGhpcyB3aWxsIG5ldmVyIG9jY3VyIChIZXkgdGhpcyB3YXkgd2UgaGF2ZSBzbWFsbGVyIGJ1bmRsZXMpXHJcblx0XHRcdGlmKHR5cGVvZiBpdGVtWzBdICE9PSBcIm51bWJlclwiIHx8ICFhbHJlYWR5SW1wb3J0ZWRNb2R1bGVzW2l0ZW1bMF1dKSB7XHJcblx0XHRcdFx0aWYobWVkaWFRdWVyeSAmJiAhaXRlbVsyXSkge1xyXG5cdFx0XHRcdFx0aXRlbVsyXSA9IG1lZGlhUXVlcnk7XHJcblx0XHRcdFx0fSBlbHNlIGlmKG1lZGlhUXVlcnkpIHtcclxuXHRcdFx0XHRcdGl0ZW1bMl0gPSBcIihcIiArIGl0ZW1bMl0gKyBcIikgYW5kIChcIiArIG1lZGlhUXVlcnkgKyBcIilcIjtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0bGlzdC5wdXNoKGl0ZW0pO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fTtcclxuXHRyZXR1cm4gbGlzdDtcclxufTtcclxuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcbiAqKiBtb2R1bGUgaWQgPSAzXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKlxyXG5cdE1JVCBMaWNlbnNlIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwXHJcblx0QXV0aG9yIFRvYmlhcyBLb3BwZXJzIEBzb2tyYVxyXG4qL1xyXG52YXIgc3R5bGVzSW5Eb20gPSB7fSxcclxuXHRtZW1vaXplID0gZnVuY3Rpb24oZm4pIHtcclxuXHRcdHZhciBtZW1vO1xyXG5cdFx0cmV0dXJuIGZ1bmN0aW9uICgpIHtcclxuXHRcdFx0aWYgKHR5cGVvZiBtZW1vID09PSBcInVuZGVmaW5lZFwiKSBtZW1vID0gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxuXHRcdFx0cmV0dXJuIG1lbW87XHJcblx0XHR9O1xyXG5cdH0sXHJcblx0aXNPbGRJRSA9IG1lbW9pemUoZnVuY3Rpb24oKSB7XHJcblx0XHRyZXR1cm4gL21zaWUgWzYtOV1cXGIvLnRlc3Qod2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQudG9Mb3dlckNhc2UoKSk7XHJcblx0fSksXHJcblx0Z2V0SGVhZEVsZW1lbnQgPSBtZW1vaXplKGZ1bmN0aW9uICgpIHtcclxuXHRcdHJldHVybiBkb2N1bWVudC5oZWFkIHx8IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiaGVhZFwiKVswXTtcclxuXHR9KSxcclxuXHRzaW5nbGV0b25FbGVtZW50ID0gbnVsbCxcclxuXHRzaW5nbGV0b25Db3VudGVyID0gMCxcclxuXHRzdHlsZUVsZW1lbnRzSW5zZXJ0ZWRBdFRvcCA9IFtdO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihsaXN0LCBvcHRpb25zKSB7XHJcblx0aWYodHlwZW9mIERFQlVHICE9PSBcInVuZGVmaW5lZFwiICYmIERFQlVHKSB7XHJcblx0XHRpZih0eXBlb2YgZG9jdW1lbnQgIT09IFwib2JqZWN0XCIpIHRocm93IG5ldyBFcnJvcihcIlRoZSBzdHlsZS1sb2FkZXIgY2Fubm90IGJlIHVzZWQgaW4gYSBub24tYnJvd3NlciBlbnZpcm9ubWVudFwiKTtcclxuXHR9XHJcblxyXG5cdG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xyXG5cdC8vIEZvcmNlIHNpbmdsZS10YWcgc29sdXRpb24gb24gSUU2LTksIHdoaWNoIGhhcyBhIGhhcmQgbGltaXQgb24gdGhlICMgb2YgPHN0eWxlPlxyXG5cdC8vIHRhZ3MgaXQgd2lsbCBhbGxvdyBvbiBhIHBhZ2VcclxuXHRpZiAodHlwZW9mIG9wdGlvbnMuc2luZ2xldG9uID09PSBcInVuZGVmaW5lZFwiKSBvcHRpb25zLnNpbmdsZXRvbiA9IGlzT2xkSUUoKTtcclxuXHJcblx0Ly8gQnkgZGVmYXVsdCwgYWRkIDxzdHlsZT4gdGFncyB0byB0aGUgYm90dG9tIG9mIDxoZWFkPi5cclxuXHRpZiAodHlwZW9mIG9wdGlvbnMuaW5zZXJ0QXQgPT09IFwidW5kZWZpbmVkXCIpIG9wdGlvbnMuaW5zZXJ0QXQgPSBcImJvdHRvbVwiO1xyXG5cclxuXHR2YXIgc3R5bGVzID0gbGlzdFRvU3R5bGVzKGxpc3QpO1xyXG5cdGFkZFN0eWxlc1RvRG9tKHN0eWxlcywgb3B0aW9ucyk7XHJcblxyXG5cdHJldHVybiBmdW5jdGlvbiB1cGRhdGUobmV3TGlzdCkge1xyXG5cdFx0dmFyIG1heVJlbW92ZSA9IFtdO1xyXG5cdFx0Zm9yKHZhciBpID0gMDsgaSA8IHN0eWxlcy5sZW5ndGg7IGkrKykge1xyXG5cdFx0XHR2YXIgaXRlbSA9IHN0eWxlc1tpXTtcclxuXHRcdFx0dmFyIGRvbVN0eWxlID0gc3R5bGVzSW5Eb21baXRlbS5pZF07XHJcblx0XHRcdGRvbVN0eWxlLnJlZnMtLTtcclxuXHRcdFx0bWF5UmVtb3ZlLnB1c2goZG9tU3R5bGUpO1xyXG5cdFx0fVxyXG5cdFx0aWYobmV3TGlzdCkge1xyXG5cdFx0XHR2YXIgbmV3U3R5bGVzID0gbGlzdFRvU3R5bGVzKG5ld0xpc3QpO1xyXG5cdFx0XHRhZGRTdHlsZXNUb0RvbShuZXdTdHlsZXMsIG9wdGlvbnMpO1xyXG5cdFx0fVxyXG5cdFx0Zm9yKHZhciBpID0gMDsgaSA8IG1heVJlbW92ZS5sZW5ndGg7IGkrKykge1xyXG5cdFx0XHR2YXIgZG9tU3R5bGUgPSBtYXlSZW1vdmVbaV07XHJcblx0XHRcdGlmKGRvbVN0eWxlLnJlZnMgPT09IDApIHtcclxuXHRcdFx0XHRmb3IodmFyIGogPSAwOyBqIDwgZG9tU3R5bGUucGFydHMubGVuZ3RoOyBqKyspXHJcblx0XHRcdFx0XHRkb21TdHlsZS5wYXJ0c1tqXSgpO1xyXG5cdFx0XHRcdGRlbGV0ZSBzdHlsZXNJbkRvbVtkb21TdHlsZS5pZF07XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9O1xyXG59XHJcblxyXG5mdW5jdGlvbiBhZGRTdHlsZXNUb0RvbShzdHlsZXMsIG9wdGlvbnMpIHtcclxuXHRmb3IodmFyIGkgPSAwOyBpIDwgc3R5bGVzLmxlbmd0aDsgaSsrKSB7XHJcblx0XHR2YXIgaXRlbSA9IHN0eWxlc1tpXTtcclxuXHRcdHZhciBkb21TdHlsZSA9IHN0eWxlc0luRG9tW2l0ZW0uaWRdO1xyXG5cdFx0aWYoZG9tU3R5bGUpIHtcclxuXHRcdFx0ZG9tU3R5bGUucmVmcysrO1xyXG5cdFx0XHRmb3IodmFyIGogPSAwOyBqIDwgZG9tU3R5bGUucGFydHMubGVuZ3RoOyBqKyspIHtcclxuXHRcdFx0XHRkb21TdHlsZS5wYXJ0c1tqXShpdGVtLnBhcnRzW2pdKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRmb3IoOyBqIDwgaXRlbS5wYXJ0cy5sZW5ndGg7IGorKykge1xyXG5cdFx0XHRcdGRvbVN0eWxlLnBhcnRzLnB1c2goYWRkU3R5bGUoaXRlbS5wYXJ0c1tqXSwgb3B0aW9ucykpO1xyXG5cdFx0XHR9XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHR2YXIgcGFydHMgPSBbXTtcclxuXHRcdFx0Zm9yKHZhciBqID0gMDsgaiA8IGl0ZW0ucGFydHMubGVuZ3RoOyBqKyspIHtcclxuXHRcdFx0XHRwYXJ0cy5wdXNoKGFkZFN0eWxlKGl0ZW0ucGFydHNbal0sIG9wdGlvbnMpKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRzdHlsZXNJbkRvbVtpdGVtLmlkXSA9IHtpZDogaXRlbS5pZCwgcmVmczogMSwgcGFydHM6IHBhcnRzfTtcclxuXHRcdH1cclxuXHR9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGxpc3RUb1N0eWxlcyhsaXN0KSB7XHJcblx0dmFyIHN0eWxlcyA9IFtdO1xyXG5cdHZhciBuZXdTdHlsZXMgPSB7fTtcclxuXHRmb3IodmFyIGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7IGkrKykge1xyXG5cdFx0dmFyIGl0ZW0gPSBsaXN0W2ldO1xyXG5cdFx0dmFyIGlkID0gaXRlbVswXTtcclxuXHRcdHZhciBjc3MgPSBpdGVtWzFdO1xyXG5cdFx0dmFyIG1lZGlhID0gaXRlbVsyXTtcclxuXHRcdHZhciBzb3VyY2VNYXAgPSBpdGVtWzNdO1xyXG5cdFx0dmFyIHBhcnQgPSB7Y3NzOiBjc3MsIG1lZGlhOiBtZWRpYSwgc291cmNlTWFwOiBzb3VyY2VNYXB9O1xyXG5cdFx0aWYoIW5ld1N0eWxlc1tpZF0pXHJcblx0XHRcdHN0eWxlcy5wdXNoKG5ld1N0eWxlc1tpZF0gPSB7aWQ6IGlkLCBwYXJ0czogW3BhcnRdfSk7XHJcblx0XHRlbHNlXHJcblx0XHRcdG5ld1N0eWxlc1tpZF0ucGFydHMucHVzaChwYXJ0KTtcclxuXHR9XHJcblx0cmV0dXJuIHN0eWxlcztcclxufVxyXG5cclxuZnVuY3Rpb24gaW5zZXJ0U3R5bGVFbGVtZW50KG9wdGlvbnMsIHN0eWxlRWxlbWVudCkge1xyXG5cdHZhciBoZWFkID0gZ2V0SGVhZEVsZW1lbnQoKTtcclxuXHR2YXIgbGFzdFN0eWxlRWxlbWVudEluc2VydGVkQXRUb3AgPSBzdHlsZUVsZW1lbnRzSW5zZXJ0ZWRBdFRvcFtzdHlsZUVsZW1lbnRzSW5zZXJ0ZWRBdFRvcC5sZW5ndGggLSAxXTtcclxuXHRpZiAob3B0aW9ucy5pbnNlcnRBdCA9PT0gXCJ0b3BcIikge1xyXG5cdFx0aWYoIWxhc3RTdHlsZUVsZW1lbnRJbnNlcnRlZEF0VG9wKSB7XHJcblx0XHRcdGhlYWQuaW5zZXJ0QmVmb3JlKHN0eWxlRWxlbWVudCwgaGVhZC5maXJzdENoaWxkKTtcclxuXHRcdH0gZWxzZSBpZihsYXN0U3R5bGVFbGVtZW50SW5zZXJ0ZWRBdFRvcC5uZXh0U2libGluZykge1xyXG5cdFx0XHRoZWFkLmluc2VydEJlZm9yZShzdHlsZUVsZW1lbnQsIGxhc3RTdHlsZUVsZW1lbnRJbnNlcnRlZEF0VG9wLm5leHRTaWJsaW5nKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGhlYWQuYXBwZW5kQ2hpbGQoc3R5bGVFbGVtZW50KTtcclxuXHRcdH1cclxuXHRcdHN0eWxlRWxlbWVudHNJbnNlcnRlZEF0VG9wLnB1c2goc3R5bGVFbGVtZW50KTtcclxuXHR9IGVsc2UgaWYgKG9wdGlvbnMuaW5zZXJ0QXQgPT09IFwiYm90dG9tXCIpIHtcclxuXHRcdGhlYWQuYXBwZW5kQ2hpbGQoc3R5bGVFbGVtZW50KTtcclxuXHR9IGVsc2Uge1xyXG5cdFx0dGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCB2YWx1ZSBmb3IgcGFyYW1ldGVyICdpbnNlcnRBdCcuIE11c3QgYmUgJ3RvcCcgb3IgJ2JvdHRvbScuXCIpO1xyXG5cdH1cclxufVxyXG5cclxuZnVuY3Rpb24gcmVtb3ZlU3R5bGVFbGVtZW50KHN0eWxlRWxlbWVudCkge1xyXG5cdHN0eWxlRWxlbWVudC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHN0eWxlRWxlbWVudCk7XHJcblx0dmFyIGlkeCA9IHN0eWxlRWxlbWVudHNJbnNlcnRlZEF0VG9wLmluZGV4T2Yoc3R5bGVFbGVtZW50KTtcclxuXHRpZihpZHggPj0gMCkge1xyXG5cdFx0c3R5bGVFbGVtZW50c0luc2VydGVkQXRUb3Auc3BsaWNlKGlkeCwgMSk7XHJcblx0fVxyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVTdHlsZUVsZW1lbnQob3B0aW9ucykge1xyXG5cdHZhciBzdHlsZUVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3R5bGVcIik7XHJcblx0c3R5bGVFbGVtZW50LnR5cGUgPSBcInRleHQvY3NzXCI7XHJcblx0aW5zZXJ0U3R5bGVFbGVtZW50KG9wdGlvbnMsIHN0eWxlRWxlbWVudCk7XHJcblx0cmV0dXJuIHN0eWxlRWxlbWVudDtcclxufVxyXG5cclxuZnVuY3Rpb24gY3JlYXRlTGlua0VsZW1lbnQob3B0aW9ucykge1xyXG5cdHZhciBsaW5rRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJsaW5rXCIpO1xyXG5cdGxpbmtFbGVtZW50LnJlbCA9IFwic3R5bGVzaGVldFwiO1xyXG5cdGluc2VydFN0eWxlRWxlbWVudChvcHRpb25zLCBsaW5rRWxlbWVudCk7XHJcblx0cmV0dXJuIGxpbmtFbGVtZW50O1xyXG59XHJcblxyXG5mdW5jdGlvbiBhZGRTdHlsZShvYmosIG9wdGlvbnMpIHtcclxuXHR2YXIgc3R5bGVFbGVtZW50LCB1cGRhdGUsIHJlbW92ZTtcclxuXHJcblx0aWYgKG9wdGlvbnMuc2luZ2xldG9uKSB7XHJcblx0XHR2YXIgc3R5bGVJbmRleCA9IHNpbmdsZXRvbkNvdW50ZXIrKztcclxuXHRcdHN0eWxlRWxlbWVudCA9IHNpbmdsZXRvbkVsZW1lbnQgfHwgKHNpbmdsZXRvbkVsZW1lbnQgPSBjcmVhdGVTdHlsZUVsZW1lbnQob3B0aW9ucykpO1xyXG5cdFx0dXBkYXRlID0gYXBwbHlUb1NpbmdsZXRvblRhZy5iaW5kKG51bGwsIHN0eWxlRWxlbWVudCwgc3R5bGVJbmRleCwgZmFsc2UpO1xyXG5cdFx0cmVtb3ZlID0gYXBwbHlUb1NpbmdsZXRvblRhZy5iaW5kKG51bGwsIHN0eWxlRWxlbWVudCwgc3R5bGVJbmRleCwgdHJ1ZSk7XHJcblx0fSBlbHNlIGlmKG9iai5zb3VyY2VNYXAgJiZcclxuXHRcdHR5cGVvZiBVUkwgPT09IFwiZnVuY3Rpb25cIiAmJlxyXG5cdFx0dHlwZW9mIFVSTC5jcmVhdGVPYmplY3RVUkwgPT09IFwiZnVuY3Rpb25cIiAmJlxyXG5cdFx0dHlwZW9mIFVSTC5yZXZva2VPYmplY3RVUkwgPT09IFwiZnVuY3Rpb25cIiAmJlxyXG5cdFx0dHlwZW9mIEJsb2IgPT09IFwiZnVuY3Rpb25cIiAmJlxyXG5cdFx0dHlwZW9mIGJ0b2EgPT09IFwiZnVuY3Rpb25cIikge1xyXG5cdFx0c3R5bGVFbGVtZW50ID0gY3JlYXRlTGlua0VsZW1lbnQob3B0aW9ucyk7XHJcblx0XHR1cGRhdGUgPSB1cGRhdGVMaW5rLmJpbmQobnVsbCwgc3R5bGVFbGVtZW50KTtcclxuXHRcdHJlbW92ZSA9IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRyZW1vdmVTdHlsZUVsZW1lbnQoc3R5bGVFbGVtZW50KTtcclxuXHRcdFx0aWYoc3R5bGVFbGVtZW50LmhyZWYpXHJcblx0XHRcdFx0VVJMLnJldm9rZU9iamVjdFVSTChzdHlsZUVsZW1lbnQuaHJlZik7XHJcblx0XHR9O1xyXG5cdH0gZWxzZSB7XHJcblx0XHRzdHlsZUVsZW1lbnQgPSBjcmVhdGVTdHlsZUVsZW1lbnQob3B0aW9ucyk7XHJcblx0XHR1cGRhdGUgPSBhcHBseVRvVGFnLmJpbmQobnVsbCwgc3R5bGVFbGVtZW50KTtcclxuXHRcdHJlbW92ZSA9IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRyZW1vdmVTdHlsZUVsZW1lbnQoc3R5bGVFbGVtZW50KTtcclxuXHRcdH07XHJcblx0fVxyXG5cclxuXHR1cGRhdGUob2JqKTtcclxuXHJcblx0cmV0dXJuIGZ1bmN0aW9uIHVwZGF0ZVN0eWxlKG5ld09iaikge1xyXG5cdFx0aWYobmV3T2JqKSB7XHJcblx0XHRcdGlmKG5ld09iai5jc3MgPT09IG9iai5jc3MgJiYgbmV3T2JqLm1lZGlhID09PSBvYmoubWVkaWEgJiYgbmV3T2JqLnNvdXJjZU1hcCA9PT0gb2JqLnNvdXJjZU1hcClcclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdHVwZGF0ZShvYmogPSBuZXdPYmopO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0cmVtb3ZlKCk7XHJcblx0XHR9XHJcblx0fTtcclxufVxyXG5cclxudmFyIHJlcGxhY2VUZXh0ID0gKGZ1bmN0aW9uICgpIHtcclxuXHR2YXIgdGV4dFN0b3JlID0gW107XHJcblxyXG5cdHJldHVybiBmdW5jdGlvbiAoaW5kZXgsIHJlcGxhY2VtZW50KSB7XHJcblx0XHR0ZXh0U3RvcmVbaW5kZXhdID0gcmVwbGFjZW1lbnQ7XHJcblx0XHRyZXR1cm4gdGV4dFN0b3JlLmZpbHRlcihCb29sZWFuKS5qb2luKCdcXG4nKTtcclxuXHR9O1xyXG59KSgpO1xyXG5cclxuZnVuY3Rpb24gYXBwbHlUb1NpbmdsZXRvblRhZyhzdHlsZUVsZW1lbnQsIGluZGV4LCByZW1vdmUsIG9iaikge1xyXG5cdHZhciBjc3MgPSByZW1vdmUgPyBcIlwiIDogb2JqLmNzcztcclxuXHJcblx0aWYgKHN0eWxlRWxlbWVudC5zdHlsZVNoZWV0KSB7XHJcblx0XHRzdHlsZUVsZW1lbnQuc3R5bGVTaGVldC5jc3NUZXh0ID0gcmVwbGFjZVRleHQoaW5kZXgsIGNzcyk7XHJcblx0fSBlbHNlIHtcclxuXHRcdHZhciBjc3NOb2RlID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoY3NzKTtcclxuXHRcdHZhciBjaGlsZE5vZGVzID0gc3R5bGVFbGVtZW50LmNoaWxkTm9kZXM7XHJcblx0XHRpZiAoY2hpbGROb2Rlc1tpbmRleF0pIHN0eWxlRWxlbWVudC5yZW1vdmVDaGlsZChjaGlsZE5vZGVzW2luZGV4XSk7XHJcblx0XHRpZiAoY2hpbGROb2Rlcy5sZW5ndGgpIHtcclxuXHRcdFx0c3R5bGVFbGVtZW50Lmluc2VydEJlZm9yZShjc3NOb2RlLCBjaGlsZE5vZGVzW2luZGV4XSk7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRzdHlsZUVsZW1lbnQuYXBwZW5kQ2hpbGQoY3NzTm9kZSk7XHJcblx0XHR9XHJcblx0fVxyXG59XHJcblxyXG5mdW5jdGlvbiBhcHBseVRvVGFnKHN0eWxlRWxlbWVudCwgb2JqKSB7XHJcblx0dmFyIGNzcyA9IG9iai5jc3M7XHJcblx0dmFyIG1lZGlhID0gb2JqLm1lZGlhO1xyXG5cclxuXHRpZihtZWRpYSkge1xyXG5cdFx0c3R5bGVFbGVtZW50LnNldEF0dHJpYnV0ZShcIm1lZGlhXCIsIG1lZGlhKVxyXG5cdH1cclxuXHJcblx0aWYoc3R5bGVFbGVtZW50LnN0eWxlU2hlZXQpIHtcclxuXHRcdHN0eWxlRWxlbWVudC5zdHlsZVNoZWV0LmNzc1RleHQgPSBjc3M7XHJcblx0fSBlbHNlIHtcclxuXHRcdHdoaWxlKHN0eWxlRWxlbWVudC5maXJzdENoaWxkKSB7XHJcblx0XHRcdHN0eWxlRWxlbWVudC5yZW1vdmVDaGlsZChzdHlsZUVsZW1lbnQuZmlyc3RDaGlsZCk7XHJcblx0XHR9XHJcblx0XHRzdHlsZUVsZW1lbnQuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoY3NzKSk7XHJcblx0fVxyXG59XHJcblxyXG5mdW5jdGlvbiB1cGRhdGVMaW5rKGxpbmtFbGVtZW50LCBvYmopIHtcclxuXHR2YXIgY3NzID0gb2JqLmNzcztcclxuXHR2YXIgc291cmNlTWFwID0gb2JqLnNvdXJjZU1hcDtcclxuXHJcblx0aWYoc291cmNlTWFwKSB7XHJcblx0XHQvLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8yNjYwMzg3NVxyXG5cdFx0Y3NzICs9IFwiXFxuLyojIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2Jhc2U2NCxcIiArIGJ0b2EodW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KEpTT04uc3RyaW5naWZ5KHNvdXJjZU1hcCkpKSkgKyBcIiAqL1wiO1xyXG5cdH1cclxuXHJcblx0dmFyIGJsb2IgPSBuZXcgQmxvYihbY3NzXSwgeyB0eXBlOiBcInRleHQvY3NzXCIgfSk7XHJcblxyXG5cdHZhciBvbGRTcmMgPSBsaW5rRWxlbWVudC5ocmVmO1xyXG5cclxuXHRsaW5rRWxlbWVudC5ocmVmID0gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcclxuXHJcblx0aWYob2xkU3JjKVxyXG5cdFx0VVJMLnJldm9rZU9iamVjdFVSTChvbGRTcmMpO1xyXG59XHJcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L3N0eWxlLWxvYWRlci9hZGRTdHlsZXMuanNcbiAqKiBtb2R1bGUgaWQgPSA0XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIndXNlIHN0cmljdCdcblxudmFyIGNvbmZpZyA9IHtcblxuICB3ZWV4VmVyc2lvbjogJzEuNC4wJyxcblxuICBkZWJ1ZzogdHJ1ZVxuXG59XG5cbm1vZHVsZS5leHBvcnRzID0gY29uZmlnXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL3NyYy9jb25maWcuanNcbiAqKiBtb2R1bGUgaWQgPSA1XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIndXNlIHN0cmljdCdcblxuZnVuY3Rpb24gbG9hZEJ5WEhSKGNvbmZpZywgY2FsbGJhY2spIHtcbiAgaWYgKCFjb25maWcuc291cmNlKSB7XG4gICAgY2FsbGJhY2sobmV3IEVycm9yKCd4aHIgbG9hZGVyOiBtaXNzaW5nIGNvbmZpZy5zb3VyY2UuJykpXG4gIH1cbiAgdmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpXG4gIHhoci5vcGVuKCdHRVQnLCBjb25maWcuc291cmNlKVxuICB4aHIub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgIGNhbGxiYWNrKG51bGwsIHRoaXMucmVzcG9uc2VUZXh0KVxuICB9XG4gIHhoci5vbmVycm9yID0gZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgY2FsbGJhY2soZXJyb3IpXG4gIH1cbiAgeGhyLnNlbmQoKVxufVxuXG5mdW5jdGlvbiBsb2FkQnlKc29ucChjb25maWcsIGNhbGxiYWNrKSB7XG4gIGlmICghY29uZmlnLnNvdXJjZSkge1xuICAgIGNhbGxiYWNrKG5ldyBFcnJvcignanNvbnAgbG9hZGVyOiBtaXNzaW5nIGNvbmZpZy5zb3VyY2UuJykpXG4gIH1cbiAgdmFyIGNhbGxiYWNrTmFtZSA9IGNvbmZpZy5qc29ucENhbGxiYWNrIHx8ICd3ZWV4SnNvbnBDYWxsYmFjaydcbiAgd2luZG93W2NhbGxiYWNrTmFtZV0gPSBmdW5jdGlvbiAoY29kZSkge1xuICAgIGlmIChjb2RlKSB7XG4gICAgICBjYWxsYmFjayhudWxsLCBjb2RlKVxuICAgIH0gZWxzZSB7XG4gICAgICBjYWxsYmFjayhuZXcgRXJyb3IoJ2xvYWQgYnkganNvbnAgZXJyb3InKSlcbiAgICB9XG4gIH1cbiAgdmFyIHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpXG4gIHNjcmlwdC5zcmMgPSBkZWNvZGVVUklDb21wb25lbnQoY29uZmlnLnNvdXJjZSlcbiAgc2NyaXB0LnR5cGUgPSAndGV4dC9qYXZhc2NyaXB0J1xuICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHNjcmlwdClcbn1cblxuZnVuY3Rpb24gbG9hZEJ5U291cmNlQ29kZShjb25maWcsIGNhbGxiYWNrKSB7XG4gIC8vIHNyYyBpcyB0aGUganNidW5kbGUuXG4gIC8vIG5vIG5lZWQgdG8gZmV0Y2ggZnJvbSBhbnl3aGVyZS5cbiAgaWYgKGNvbmZpZy5zb3VyY2UpIHtcbiAgICBjYWxsYmFjayhudWxsLCBjb25maWcuc291cmNlKVxuICB9IGVsc2Uge1xuICAgIGNhbGxiYWNrKG5ldyBFcnJvcignc291cmNlIGNvZGUgbGFvZGVyOiBtaXNzaW5nIGNvbmZpZy5zb3VyY2UuJykpXG4gIH1cbn1cblxudmFyIGNhbGxiYWNrTWFwID0ge1xuICB4aHI6IGxvYWRCeVhIUixcbiAganNvbnA6IGxvYWRCeUpzb25wLFxuICBzb3VyY2U6IGxvYWRCeVNvdXJjZUNvZGVcbn1cblxuZnVuY3Rpb24gbG9hZChvcHRpb25zLCBjYWxsYmFjaykge1xuICB2YXIgbG9hZEZuID0gY2FsbGJhY2tNYXBbb3B0aW9ucy5sb2FkZXJdXG4gIGxvYWRGbihvcHRpb25zLCBjYWxsYmFjaylcbn1cblxuZnVuY3Rpb24gcmVnaXN0ZXJMb2FkZXIobmFtZSwgbG9hZGVyRnVuYykge1xuICBpZiAodHlwZW9mIGxvYWRlckZ1bmMgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYWxsYmFja01hcFtuYW1lXSA9IGxvYWRlckZ1bmNcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgbG9hZDogbG9hZCxcbiAgcmVnaXN0ZXJMb2FkZXI6IHJlZ2lzdGVyTG9hZGVyXG59XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL2xvYWRlci5qc1xuICoqIG1vZHVsZSBpZCA9IDZcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIid1c2Ugc3RyaWN0J1xuXG52YXIgV0VBUFBfU1RZTEVfSUQgPSAnd2VhcHAtc3R5bGUnXG5cbnZhciBfaXNXZWJwU3VwcG9ydGVkID0gZmFsc2VcblxuOyAoZnVuY3Rpb24gaXNTdXBwb3J0V2VicCgpIHtcbiAgdHJ5IHtcbiAgICB2YXIgd2ViUCA9IG5ldyBJbWFnZSgpXG4gICAgd2ViUC5zcmMgPSAnZGF0YTppbWFnZS93ZWJwO2Jhc2U2NCxVa2xHUmpvQUFBQlhSVUpRVmxBNElDNEFBQUN5QWdDZEEnXG4gICAgICAgICAgICAgICsgJ1NvQ0FBSUFMbWswbWswaUlpSWlJZ0JvU3lnQUJjNldXZ0FBL3ZlZmYvMFBQOGJBLy9Md1lBQUEnXG4gICAgd2ViUC5vbmxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAod2ViUC5oZWlnaHQgPT09IDIpIHtcbiAgICAgICAgX2lzV2VicFN1cHBvcnRlZCA9IHRydWVcbiAgICAgIH1cbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBkbyBub3RoaW5nLlxuICB9XG59KSgpXG5cbmZ1bmN0aW9uIGV4dGVuZCh0bywgZnJvbSkge1xuICBmb3IgKHZhciBrZXkgaW4gZnJvbSkge1xuICAgIHRvW2tleV0gPSBmcm9tW2tleV1cbiAgfVxuICByZXR1cm4gdG9cbn1cblxuZnVuY3Rpb24gaXNBcnJheShhcnIpIHtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXlcbiAgICA/IEFycmF5LmlzQXJyYXkoYXJyKVxuICAgIDogKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChhcnIpID09PSAnW29iamVjdCBBcnJheV0nKVxufVxuXG5mdW5jdGlvbiBhcHBlbmRTdHlsZShjc3MsIHN0eWxlSWQsIHJlcGxhY2UpIHtcbiAgdmFyIHN0eWxlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoc3R5bGVJZClcbiAgaWYgKHN0eWxlICYmIHJlcGxhY2UpIHtcbiAgICBzdHlsZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHN0eWxlKVxuICAgIHN0eWxlID0gbnVsbFxuICB9XG4gIGlmICghc3R5bGUpIHtcbiAgICBzdHlsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N0eWxlJylcbiAgICBzdHlsZS50eXBlID0gJ3RleHQvY3NzJ1xuICAgIHN0eWxlSWQgJiYgKHN0eWxlLmlkID0gc3R5bGVJZClcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaGVhZCcpWzBdLmFwcGVuZENoaWxkKHN0eWxlKVxuICB9XG4gIHN0eWxlLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGNzcykpXG59XG5cbmZ1bmN0aW9uIGdldFVuaXF1ZUZyb21BcnJheShhcnIpIHtcbiAgaWYgKCFpc0FycmF5KGFycikpIHtcbiAgICByZXR1cm4gW11cbiAgfVxuICB2YXIgcmVzID0gW11cbiAgdmFyIHVuaXF1ZSA9IHt9XG4gIHZhciB2YWxcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSBhcnIubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgdmFsID0gYXJyW2ldXG4gICAgaWYgKHVuaXF1ZVt2YWxdKSB7XG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICB1bmlxdWVbdmFsXSA9IHRydWVcbiAgICByZXMucHVzaCh2YWwpXG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG5mdW5jdGlvbiB0cmFuc2l0aW9uaXplKGVsZW1lbnQsIHByb3BzKSB7XG4gIHZhciB0cmFuc2l0aW9ucyA9IFtdXG4gIGZvciAodmFyIGtleSBpbiBwcm9wcykge1xuICAgIHRyYW5zaXRpb25zLnB1c2goa2V5ICsgJyAnICsgcHJvcHNba2V5XSlcbiAgfVxuICBlbGVtZW50LnN0eWxlLnRyYW5zaXRpb24gPSB0cmFuc2l0aW9ucy5qb2luKCcsICcpXG4gIGVsZW1lbnQuc3R5bGUud2Via2l0VHJhbnNpdGlvbiA9IHRyYW5zaXRpb25zLmpvaW4oJywgJylcbn1cblxuZnVuY3Rpb24gZGV0ZWN0V2VicCgpIHtcbiAgcmV0dXJuIF9pc1dlYnBTdXBwb3J0ZWRcbn1cblxuZnVuY3Rpb24gZ2V0UmFuZG9tKG51bSkge1xuICB2YXIgX2RlZmF1bHROdW0gPSAxMFxuICBpZiAodHlwZW9mIG51bSAhPT0gJ251bWJlcicgfHwgbnVtIDw9IDApIHtcbiAgICBudW0gPSBfZGVmYXVsdE51bVxuICB9XG4gIHZhciBfbWF4ID0gTWF0aC5wb3coMTAsIG51bSlcbiAgcmV0dXJuIE1hdGguZmxvb3IoRGF0ZS5ub3coKSArIE1hdGgucmFuZG9tKCkgKiBfbWF4KSAlIF9tYXhcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGV4dGVuZDogZXh0ZW5kLFxuICBpc0FycmF5OiBpc0FycmF5LFxuICBhcHBlbmRTdHlsZTogYXBwZW5kU3R5bGUsXG4gIGdldFVuaXF1ZUZyb21BcnJheTogZ2V0VW5pcXVlRnJvbUFycmF5LFxuICB0cmFuc2l0aW9uaXplOiB0cmFuc2l0aW9uaXplLFxuICBkZXRlY3RXZWJwOiBkZXRlY3RXZWJwLFxuICBnZXRSYW5kb206IGdldFJhbmRvbVxufVxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvdXRpbHMuanNcbiAqKiBtb2R1bGUgaWQgPSA3XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIndXNlIHN0cmljdCdcblxudmFyIGV4dGVuZCA9IHJlcXVpcmUoJy4vdXRpbHMnKS5leHRlbmRcbnZhciBpc0FycmF5ID0gcmVxdWlyZSgnLi91dGlscycpLmlzQXJyYXlcbnZhciBDb21wb25lbnRNYW5hZ2VyID0gcmVxdWlyZSgnLi9jb21wb25lbnRNYW5hZ2VyJylcblxuLy8gZm9yIGpzZnJhbWV3b3JrIHRvIHJlZ2lzdGVyIG1vZHVsZXMuXG52YXIgX3JlZ2lzdGVyTW9kdWxlcyA9IGZ1bmN0aW9uIChjb25maWcpIHtcbiAgaWYgKGlzQXJyYXkoY29uZmlnKSkge1xuICAgIGZvciAodmFyIGkgPSAwLCBsID0gY29uZmlnLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgd2luZG93LnJlZ2lzdGVyTW9kdWxlcyhjb25maWdbaV0pXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHdpbmRvdy5yZWdpc3Rlck1vZHVsZXMoY29uZmlnKVxuICB9XG59XG5cbnZhciBwcm90b2NvbCA9IHtcblxuICAvLyB3ZWV4IGluc3RhbmNlc1xuICBfaW5zdGFuY2VzOiBbXSxcblxuICAvLyBhcGkgbWV0YSBpbmZvXG4gIF9tZXRhOiBbXSxcblxuICBhcGlNb2R1bGU6IHt9LFxuXG4gIGluamVjdFdlZXhJbnN0YW5jZTogZnVuY3Rpb24gKGluc3RhbmNlKSB7XG4gICAgdGhpcy5faW5zdGFuY2VzW2luc3RhbmNlLmluc3RhbmNlSWRdID0gaW5zdGFuY2VcbiAgfSxcblxuICBnZXRXZWV4SW5zdGFuY2U6IGZ1bmN0aW9uIChpbnN0YW5jZUlkKSB7XG4gICAgcmV0dXJuIHRoaXMuX2luc3RhbmNlc1tpbnN0YW5jZUlkXVxuICB9LFxuXG4gIC8vIGdldCB0aGUgYXBpIG1ldGhvZCBtZXRhIGluZm8gYXJyYXkgZm9yIHRoZSBtb2R1bGUuXG4gIGdldEFwaU1vZHVsZU1ldGE6IGZ1bmN0aW9uIChtb2R1bGVOYW1lKSB7XG4gICAgdmFyIG1ldGFPYmogPSB7fVxuICAgIG1ldGFPYmpbbW9kdWxlTmFtZV0gPSB0aGlzLl9tZXRhW21vZHVsZU5hbWVdXG4gICAgcmV0dXJuIG1ldGFPYmpcbiAgfSxcblxuICAvLyBTZXQgbWV0YSBpbmZvIGZvciBhIGFwaSBtb2R1bGUuXG4gIC8vIElmIHRoZXJlIGlzIGEgc2FtZSBuYW1lZCBhcGksIGp1c3QgcmVwbGFjZSBpdC5cbiAgLy8gb3B0czpcbiAgLy8gLSBtZXRhT2JqOiBtZXRhIG9iamVjdCBsaWtlXG4gIC8vIHtcbiAgLy8gICAgZG9tOiBbe1xuICAvLyAgICAgIG5hbWU6ICdhZGRFbGVtZW50JyxcbiAgLy8gICAgICBhcmdzOiBbJ3N0cmluZycsICdvYmplY3QnXVxuICAvLyAgICB9XVxuICAvLyB9XG4gIHNldEFwaU1vZHVsZU1ldGE6IGZ1bmN0aW9uIChtZXRhT2JqKSB7XG4gICAgdmFyIG1vZHVsZU5hbWVcbiAgICBmb3IgKHZhciBrIGluIG1ldGFPYmopIHtcbiAgICAgIGlmIChtZXRhT2JqLmhhc093blByb3BlcnR5KGspKSB7XG4gICAgICAgIG1vZHVsZU5hbWUgPSBrXG4gICAgICB9XG4gICAgfVxuICAgIHZhciBtZXRhQXJyYXkgPSB0aGlzLl9tZXRhW21vZHVsZU5hbWVdXG4gICAgaWYgKCFtZXRhQXJyYXkpIHtcbiAgICAgIHRoaXMuX21ldGFbbW9kdWxlTmFtZV0gPSBtZXRhT2JqW21vZHVsZU5hbWVdXG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBuYW1lT2JqID0ge31cbiAgICAgIG1ldGFPYmpbbW9kdWxlTmFtZV0uZm9yRWFjaChmdW5jdGlvbiAoYXBpKSB7XG4gICAgICAgIG5hbWVPYmpbYXBpLm5hbWVdID0gYXBpXG4gICAgICB9KVxuICAgICAgbWV0YUFycmF5LmZvckVhY2goZnVuY3Rpb24gKGFwaSwgaSkge1xuICAgICAgICBpZiAobmFtZU9ialthcGkubmFtZV0pIHtcbiAgICAgICAgICBtZXRhQXJyYXlbaV0gPSBuYW1lT2JqW2FwaS5uYW1lXVxuICAgICAgICAgIGRlbGV0ZSBuYW1lT2JqW2FwaS5uYW1lXVxuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgZm9yICh2YXIgayBpbiBtZXRhT2JqKSB7XG4gICAgICAgIGlmIChtZXRhT2JqLmhhc093blByb3BlcnR5KGspKSB7XG4gICAgICAgICAgbWV0YUFycmF5LnB1c2gobWV0YU9ialtrXSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLl9tZXRhW21vZHVsZU5hbWVdID0gbWV0YU9ialttb2R1bGVOYW1lXVxuICB9LFxuXG4gIC8vIFNldCBtZXRhIGluZm8gZm9yIGEgc2luZ2xlIGFwaS5cbiAgLy8gb3B0czpcbiAgLy8gIC0gbW9kdWxlTmFtZTogYXBpIG1vZHVsZSBuYW1lLlxuICAvLyAgLSBtZXRhOiBhIG1ldGEgb2JqZWN0IGxpa2U6XG4gIC8vICB7XG4gIC8vICAgIG5hbWU6ICdhZGRFbGVtZW50JyxcbiAgLy8gICAgYXJnczogWydzdHJpbmcnLCAnb2JqZWN0J11cbiAgLy8gIH1cbiAgc2V0QXBpTWV0YTogZnVuY3Rpb24gKG1vZHVsZU5hbWUsIG1ldGEpIHtcbiAgICB2YXIgbWV0YUFycmF5ID0gdGhpcy5fbWV0YVttb2R1bGVOYW1lXVxuICAgIGlmICghbWV0YUFycmF5KSB7XG4gICAgICB0aGlzLl9tZXRhW21vZHVsZU5hbWVdID0gW21ldGFdXG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBtZXRhSWR4ID0gLTFcbiAgICAgIG1ldGFBcnJheS5mb3JFYWNoKGZ1bmN0aW9uIChhcGksIGkpIHtcbiAgICAgICAgaWYgKG1ldGEubmFtZSA9PT0gbmFtZSkge1xuICAgICAgICAgIG1ldGFJZHggPSBpXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICBpZiAobWV0YUlkeCAhPT0gLTEpIHtcbiAgICAgICAgbWV0YUFycmF5W21ldGFJZHhdID0gbWV0YVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbWV0YUFycmF5LnB1c2gobWV0YSlcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuX3JlZ2lzdGVyTW9kdWxlcyhbe1xuICBtb2RhbDogW3tcbiAgICBuYW1lOiAndG9hc3QnLFxuICAgIGFyZ3M6IFsnb2JqZWN0JywgJ2Z1bmN0aW9uJ11cbiAgfSwge1xuICAgIG5hbWU6ICdhbGVydCcsXG4gICAgYXJnczogWydvYmplY3QnLCAnZnVuY3Rpb24nXVxuICB9LCB7XG4gICAgbmFtZTogJ2NvbmZpcm0nLFxuICAgIGFyZ3M6IFsnb2JqZWN0JywgJ2Z1bmN0aW9uJ11cbiAgfSwge1xuICAgIG5hbWU6ICdwcm9tcHQnLFxuICAgIGFyZ3M6IFsnb2JqZWN0JywgJ2Z1bmN0aW9uJ11cbiAgfV1cbn0sIHtcbiAgYW5pbWF0aW9uOiBbe1xuICAgIG5hbWU6ICd0cmFuc2l0aW9uJyxcbiAgICBhcmdzOiBbJ3N0cmluZycsICdvYmplY3QnLCAnZnVuY3Rpb24nXVxuICB9XVxufV0pXG5cbm1vZHVsZS5leHBvcnRzID0gcHJvdG9jb2xcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvcHJvdG9jb2wuanNcbiAqKiBtb2R1bGUgaWQgPSA4XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIndXNlIHN0cmljdCdcblxudmFyIGNvbmZpZyA9IHJlcXVpcmUoJy4vY29uZmlnJylcbnZhciBGcmFtZVVwZGF0ZXIgPSByZXF1aXJlKCcuL2ZyYW1lVXBkYXRlcicpXG52YXIgQXBwZWFyV2F0Y2hlciA9IHJlcXVpcmUoJy4vYXBwZWFyV2F0Y2hlcicpXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJylcbnZhciBMYXp5TG9hZCA9IHJlcXVpcmUoJy4vbGF6eUxvYWQnKVxudmFyIGFuaW1hdGlvbiA9IHJlcXVpcmUoJy4vYW5pbWF0aW9uJylcblxudmFyIFJFTkRFUklOR19JTkRFTlQgPSA4MDBcblxudmFyIF9pbnN0YW5jZU1hcCA9IHt9XG52YXIgdHlwZU1hcCA9IHt9XG52YXIgc2Nyb2xsYWJsZVR5cGVzID0gWydzY3JvbGxlcicsICdsaXN0J11cblxuZnVuY3Rpb24gQ29tcG9uZW50TWFuYWdlcihpbnN0YW5jZSkge1xuICB0aGlzLmluc3RhbmNlSWQgPSBpbnN0YW5jZS5pbnN0YW5jZUlkXG4gIHRoaXMud2VleEluc3RhbmNlID0gaW5zdGFuY2VcbiAgdGhpcy5jb21wb25lbnRNYXAgPSB7fVxuICBfaW5zdGFuY2VNYXBbdGhpcy5pbnN0YW5jZUlkXSA9IHRoaXNcbn1cblxuQ29tcG9uZW50TWFuYWdlci5nZXRJbnN0YW5jZSA9IGZ1bmN0aW9uIChpbnN0YW5jZUlkKSB7XG4gIHJldHVybiBfaW5zdGFuY2VNYXBbaW5zdGFuY2VJZF1cbn1cblxuQ29tcG9uZW50TWFuYWdlci5nZXRXZWV4SW5zdGFuY2UgPSBmdW5jdGlvbiAoaW5zdGFuY2VJZCkge1xuICByZXR1cm4gX2luc3RhbmNlTWFwW2luc3RhbmNlSWRdLndlZXhJbnN0YW5jZVxufVxuXG5Db21wb25lbnRNYW5hZ2VyLnJlZ2lzdGVyQ29tcG9uZW50ID0gZnVuY3Rpb24gKHR5cGUsIGRlZmluaXRpb24pIHtcbiAgdHlwZU1hcFt0eXBlXSA9IGRlZmluaXRpb25cbn1cblxuQ29tcG9uZW50TWFuYWdlci5nZXRTY3JvbGxhYmxlVHlwZXMgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBzY3JvbGxhYmxlVHlwZXNcbn1cblxuQ29tcG9uZW50TWFuYWdlci5wcm90b3R5cGUgPSB7XG5cbiAgLy8gRmlyZSBhIGV2ZW50ICdyZW5kZXJiZWdpbicvJ3JlbmRlcmVuZCcgb24gYm9keSBlbGVtZW50LlxuICByZW5kZXJpbmc6IGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBfcmVuZGVyaW5nRW5kKCkge1xuICAgICAgLy8gZ2V0IHdlZXggaW5zdGFuY2Ugcm9vdFxuICAgICAgd2luZG93LmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KCdyZW5kZXJlbmQnKSlcbiAgICAgIHRoaXMuX3JlbmRlcmluZ1RpbWVyID0gbnVsbFxuICAgIH1cbiAgICBpZiAodGhpcy5fcmVuZGVyaW5nVGltZXIpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLl9yZW5kZXJpbmdUaW1lcilcbiAgICAgIHRoaXMuX3JlbmRlcmluZ1RpbWVyID0gc2V0VGltZW91dChcbiAgICAgICAgX3JlbmRlcmluZ0VuZC5iaW5kKHRoaXMpLFxuICAgICAgICBSRU5ERVJJTkdfSU5ERU5UXG4gICAgICApXG4gICAgfSBlbHNlIHtcbiAgICAgIHdpbmRvdy5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudCgncmVuZGVyYmVnaW4nKSlcbiAgICAgIHRoaXMuX3JlbmRlcmluZ1RpbWVyID0gc2V0VGltZW91dChcbiAgICAgICAgX3JlbmRlcmluZ0VuZC5iaW5kKHRoaXMpLFxuICAgICAgICBSRU5ERVJJTkdfSU5ERU5UXG4gICAgICApXG4gICAgfVxuICB9LFxuXG4gIGdldEVsZW1lbnRCeVJlZjogZnVuY3Rpb24gKHJlZikge1xuICAgIHJldHVybiB0aGlzLmNvbXBvbmVudE1hcFtyZWZdXG4gIH0sXG5cbiAgcmVtb3ZlRWxlbWVudEJ5UmVmOiBmdW5jdGlvbiAocmVmKSB7XG4gICAgdmFyIGNtcFxuICAgIHZhciBzZWxmID0gdGhpc1xuICAgIGlmICghcmVmIHx8ICEoY21wID0gdGhpcy5jb21wb25lbnRNYXBbcmVmXSkpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICAvLyByZW1vdmUgZnJvbSB0aGlzLmNvbXBvbmVudE1hcCBjdXJzaXZlbHlcbiAgICAoZnVuY3Rpb24gX3JlbW92ZUN1cnNpdmVseShfcmVmKSB7XG4gICAgICB2YXIgY2hpbGQgPSBzZWxmLmNvbXBvbmVudE1hcFtfcmVmXVxuICAgICAgdmFyIGxpc3RlbmVycyA9IGNoaWxkLl9saXN0ZW5lcnNcbiAgICAgIHZhciBjaGlsZHJlbiA9IGNoaWxkLmRhdGEuY2hpbGRyZW5cbiAgICAgIGlmIChjaGlsZHJlbiAmJiBjaGlsZHJlbi5sZW5ndGgpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBjaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICBfcmVtb3ZlQ3Vyc2l2ZWx5KGNoaWxkcmVuW2ldLnJlZilcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gcmVtb3ZlIGV2ZW50cyBmcm9tIF9yZWYgY29tcG9uZW50XG4gICAgICBpZiAobGlzdGVuZXJzKSB7XG4gICAgICAgIGZvciAodmFyIHR5cGUgaW4gbGlzdGVuZXJzKSB7XG4gICAgICAgICAgY2hpbGQubm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyc1t0eXBlXSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgZGVsZXRlIGNoaWxkLl9saXN0ZW5lcnNcbiAgICAgIGRlbGV0ZSBjaGlsZC5ub2RlLl9saXN0ZW5lcnNcbiAgICAgIC8vIHJlbW92ZSBfcmVmIGNvbXBvbmVudFxuICAgICAgZGVsZXRlIHNlbGYuY29tcG9uZW50TWFwW19yZWZdXG4gICAgfSkocmVmKVxuXG4gIH0sXG5cbiAgY3JlYXRlRWxlbWVudDogZnVuY3Rpb24gKGRhdGEsIG5vZGVUeXBlKSB7XG4gICAgdmFyIENvbXBvbmVudFR5cGUgPSB0eXBlTWFwW2RhdGEudHlwZV1cbiAgICBpZiAoIUNvbXBvbmVudFR5cGUpIHtcbiAgICAgIENvbXBvbmVudFR5cGUgPSB0eXBlTWFwWydjb250YWluZXInXVxuICAgIH1cblxuICAgIHZhciByZWYgPSBkYXRhLnJlZlxuICAgIHZhciBjb21wb25lbnQgPSBuZXcgQ29tcG9uZW50VHlwZShkYXRhLCBub2RlVHlwZSlcblxuICAgIHRoaXMuY29tcG9uZW50TWFwW3JlZl0gPSBjb21wb25lbnRcbiAgICBjb21wb25lbnQubm9kZS5zZXRBdHRyaWJ1dGUoJ2RhdGEtcmVmJywgcmVmKVxuXG4gICAgcmV0dXJuIGNvbXBvbmVudFxuICB9LFxuXG4gIC8qKlxuICAgKiBjcmVhdGVCb2R5OiBnZW5lcmF0ZSByb290IGNvbXBvbmVudFxuICAgKiBAcGFyYW0gIHtvYmplY3R9IGVsZW1lbnRcbiAgICovXG4gIGNyZWF0ZUJvZHk6IGZ1bmN0aW9uIChlbGVtZW50KSB7XG5cbiAgICAvLyBUT0RPOiBjcmVhdGJvZHkgb24gZG9jdW1lbnQuYm9keVxuICAgIC8vIG5vIG5lZWQgdG8gY3JlYXRlIGEgZXh0cmEgZGl2XG4gICAgdmFyIHJvb3QsIGJvZHksIG5vZGVUeXBlXG4gICAgaWYgKHRoaXMuY29tcG9uZW50TWFwWydfcm9vdCddKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBub2RlVHlwZSA9IGVsZW1lbnQudHlwZVxuICAgIGVsZW1lbnQudHlwZSA9ICdyb290J1xuICAgIGVsZW1lbnQucm9vdElkID0gdGhpcy53ZWV4SW5zdGFuY2Uucm9vdElkXG4gICAgZWxlbWVudC5yZWYgPSAnX3Jvb3QnXG5cbiAgICB2YXIgcm9vdCA9IHRoaXMuY3JlYXRlRWxlbWVudChlbGVtZW50LCBub2RlVHlwZSlcbiAgICBib2R5ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignIycgKyB0aGlzLndlZXhJbnN0YW5jZS5yb290SWQpXG4gICAgICAgICAgfHwgZG9jdW1lbnQuYm9keVxuICAgIGJvZHkuYXBwZW5kQ2hpbGQocm9vdC5ub2RlKVxuICAgIHJvb3QuX2FwcGVuZGVkID0gdHJ1ZVxuICB9LFxuXG4gIGFwcGVuZENoaWxkOiBmdW5jdGlvbiAocGFyZW50UmVmLCBkYXRhKSB7XG4gICAgdmFyIHBhcmVudCA9IHRoaXMuY29tcG9uZW50TWFwW3BhcmVudFJlZl1cblxuICAgIGlmICh0aGlzLmNvbXBvbmVudE1hcFtkYXRhLnJlZl0gfHwgIXBhcmVudCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKHBhcmVudFJlZiA9PT0gJ19yb290JyAmJiAhcGFyZW50KSB7XG4gICAgICBwYXJlbnQgPSB0aGlzLmNyZWF0ZUVsZW1lbnQoe1xuICAgICAgICB0eXBlOiAncm9vdCcsXG4gICAgICAgIHJvb3RJZDogdGhpcy53ZWV4SW5zdGFuY2Uucm9vdElkLFxuICAgICAgICByZWY6ICdfcm9vdCdcbiAgICAgIH0pXG4gICAgICBwYXJlbnQuX2FwcGVuZGVkID0gdHJ1ZVxuICAgIH1cblxuICAgIHZhciBjaGlsZCA9IHBhcmVudC5hcHBlbmRDaGlsZChkYXRhKVxuXG4gICAgLy8gSW4gc29tZSBwYXJlbnQgY29tcG9uZW50IHRoZSBpbXBsZW1lbnRhdGlvbiBvZiBtZXRob2RcbiAgICAvLyBhcHBlbmRDaGlsZCBkaWRuJ3QgcmV0dXJuIHRoZSBjb21wb25lbnQgYXQgYWxsLCB0aGVyZWZvclxuICAgIC8vIGNoaWxkIG1heWJlIGEgdW5kZWZpbmVkIG9iamVjdC5cbiAgICBpZiAoY2hpbGQpIHtcbiAgICAgIGNoaWxkLnBhcmVudFJlZiA9IHBhcmVudFJlZlxuICAgIH1cblxuICAgIGlmIChjaGlsZCAmJiBwYXJlbnQuX2FwcGVuZGVkKSB7XG4gICAgICB0aGlzLmhhbmRsZUFwcGVuZChjaGlsZClcbiAgICB9XG4gIH0sXG5cbiAgYXBwZW5kQ2hpbGRyZW46IGZ1bmN0aW9uIChyZWYsIGVsZW1lbnRzKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbGVtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgdGhpcy5hcHBlbmRDaGlsZChyZWYsIGVsZW1lbnRzW2ldKVxuICAgIH1cbiAgfSxcblxuICByZW1vdmVFbGVtZW50OiBmdW5jdGlvbiAocmVmKSB7XG4gICAgdmFyIGNvbXBvbmVudCA9IHRoaXMuY29tcG9uZW50TWFwW3JlZl1cblxuICAgIC8vIGZpcmUgZXZlbnQgZm9yIHJlbmRlcmluZyBkb20gb24gYm9keSBlbG1lbnQuXG4gICAgdGhpcy5yZW5kZXJpbmcoKVxuXG4gICAgaWYgKGNvbXBvbmVudCAmJiBjb21wb25lbnQucGFyZW50UmVmKSB7XG4gICAgICB2YXIgcGFyZW50ID0gdGhpcy5jb21wb25lbnRNYXBbY29tcG9uZW50LnBhcmVudFJlZl1cbiAgICAgIGNvbXBvbmVudC5vblJlbW92ZSAmJiBjb21wb25lbnQub25SZW1vdmUoKVxuICAgICAgcGFyZW50LnJlbW92ZUNoaWxkKGNvbXBvbmVudClcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc29sZS53YXJuKCdyZWY6ICcsIHJlZilcbiAgICB9XG4gIH0sXG5cbiAgbW92ZUVsZW1lbnQ6IGZ1bmN0aW9uIChyZWYsIHBhcmVudFJlZiwgaW5kZXgpIHtcbiAgICB2YXIgY29tcG9uZW50ID0gdGhpcy5jb21wb25lbnRNYXBbcmVmXVxuICAgIHZhciBuZXdQYXJlbnQgPSB0aGlzLmNvbXBvbmVudE1hcFtwYXJlbnRSZWZdXG4gICAgdmFyIG9sZFBhcmVudFJlZiA9IGNvbXBvbmVudC5wYXJlbnRSZWZcbiAgICB2YXIgY2hpbGRyZW4sIGJlZm9yZSwgaSwgbFxuICAgIGlmICghY29tcG9uZW50IHx8ICFuZXdQYXJlbnQpIHtcbiAgICAgIGNvbnNvbGUud2FybigncmVmOiAnLCByZWYpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvLyBmaXJlIGV2ZW50IGZvciByZW5kZXJpbmcgZG9tIG9uIGJvZHkgZWxtZW50LlxuICAgIHRoaXMucmVuZGVyaW5nKClcblxuICAgIC8vIHJlbW92ZSBmcm9tIG9sZFBhcmVudC5kYXRhLmNoaWxkcmVuXG4gICAgaWYgKG9sZFBhcmVudFJlZiAmJiB0aGlzLmNvbXBvbmVudE1hcFtvbGRQYXJlbnRSZWZdKSB7XG4gICAgICBjaGlsZHJlbiA9IHRoaXMuY29tcG9uZW50TWFwW29sZFBhcmVudFJlZl0uZGF0YS5jaGlsZHJlblxuICAgICAgaWYgKGNoaWxkcmVuICYmIGNoaWxkcmVuLmxlbmd0aCkge1xuICAgICAgICBmb3IgKGkgPSAwLCBsID0gY2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgaWYgKGNoaWxkcmVuW2ldLnJlZiA9PT0gcmVmKSB7XG4gICAgICAgICAgICBicmVha1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAobCA+IGkpIHtcbiAgICAgICAgICBjaGlsZHJlbi5zcGxpY2UoaSwgMSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChpbmRleCA8IC0xKSB7XG4gICAgICBpbmRleCA9IC0xXG4gICAgICBjb25zb2xlLndhcm4oJ2luZGV4IGNhbm5vdCBiZSBsZXNzIHRoYW4gLTEuJylcbiAgICB9XG5cbiAgICBjaGlsZHJlbiA9IG5ld1BhcmVudC5kYXRhLmNoaWxkcmVuXG4gICAgaWYgKGNoaWxkcmVuXG4gICAgICAgICYmIGNoaWxkcmVuLmxlbmd0aFxuICAgICAgICAmJiBpbmRleCAhPT0gLTFcbiAgICAgICAgJiYgaW5kZXggPCBjaGlsZHJlbi5sZW5ndGgpIHtcbiAgICAgIGJlZm9yZSA9IHRoaXMuY29tcG9uZW50TWFwW25ld1BhcmVudC5kYXRhLmNoaWxkcmVuW2luZGV4XS5yZWZdXG4gICAgICBuZXdQYXJlbnQuaW5zZXJ0QmVmb3JlKGNvbXBvbmVudCwgYmVmb3JlKVxuICAgIH0gZWxzZSB7ICAvLyBhcHBlbmRcbiAgICAgIG5ld1BhcmVudC5pbnNlcnRCZWZvcmUoY29tcG9uZW50KVxuICAgIH1cblxuICAgIGNvbXBvbmVudC5vbk1vdmUgJiYgY29tcG9uZW50Lm9uTW92ZShwYXJlbnRSZWYsIGluZGV4KVxuXG4gIH0sXG5cbiAgaW5zZXJ0QmVmb3JlOiBmdW5jdGlvbiAocmVmLCBkYXRhKSB7XG4gICAgdmFyIGNoaWxkLCBiZWZvcmUsIHBhcmVudFxuICAgIGJlZm9yZSA9IHRoaXMuY29tcG9uZW50TWFwW3JlZl1cbiAgICBjaGlsZCA9IHRoaXMuY29tcG9uZW50TWFwW2RhdGEucmVmXVxuICAgIGJlZm9yZSAmJiAocGFyZW50ID0gdGhpcy5jb21wb25lbnRNYXBbYmVmb3JlLnBhcmVudFJlZl0pXG4gICAgaWYgKGNoaWxkIHx8ICFwYXJlbnQgfHwgIWJlZm9yZSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY2hpbGQgPSB0aGlzLmNyZWF0ZUVsZW1lbnQoZGF0YSlcbiAgICBpZiAoY2hpbGQpIHtcbiAgICAgIGNoaWxkLnBhcmVudFJlZiA9IGJlZm9yZS5wYXJlbnRSZWZcbiAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUoY2hpbGQsIGJlZm9yZSlcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY29tcG9uZW50TWFwW2JlZm9yZS5wYXJlbnRSZWZdLl9hcHBlbmRlZCkge1xuICAgICAgdGhpcy5oYW5kbGVBcHBlbmQoY2hpbGQpXG4gICAgfVxuICB9LFxuXG4gIC8qKlxuICAgKiBhZGRFbGVtZW50XG4gICAqIElmIGluZGV4IGlzIGxhcmdldCB0aGFuIGFueSBjaGlsZCdzIGluZGV4LCB0aGVcbiAgICogZWxlbWVudCB3aWxsIGJlIGFwcGVuZGVkIGJlaGluZC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHBhcmVudFJlZlxuICAgKiBAcGFyYW0ge29ian0gZWxlbWVudCAoZGF0YSBvZiB0aGUgY29tcG9uZW50KVxuICAgKiBAcGFyYW0ge251bWJlcn0gaW5kZXhcbiAgICovXG4gIGFkZEVsZW1lbnQ6IGZ1bmN0aW9uIChwYXJlbnRSZWYsIGVsZW1lbnQsIGluZGV4KSB7XG4gICAgdmFyIHBhcmVudCwgY2hpbGRyZW4sIGJlZm9yZVxuXG4gICAgLy8gZmlyZSBldmVudCBmb3IgcmVuZGVyaW5nIGRvbSBvbiBib2R5IGVsbWVudC5cbiAgICB0aGlzLnJlbmRlcmluZygpXG5cbiAgICBwYXJlbnQgPSB0aGlzLmNvbXBvbmVudE1hcFtwYXJlbnRSZWZdXG4gICAgaWYgKCFwYXJlbnQpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBjaGlsZHJlbiA9IHBhcmVudC5kYXRhLmNoaWxkcmVuXG4gICAgLy8gLTEgbWVhbnMgYXBwZW5kIGFzIHRoZSBsYXN0LlxuICAgIGlmIChpbmRleCA8IC0xKSB7XG4gICAgICBpbmRleCA9IC0xXG4gICAgICBjb25zb2xlLndhcm4oJ2luZGV4IGNhbm5vdCBiZSBsZXNzIHRoYW4gLTEuJylcbiAgICB9XG4gICAgaWYgKGNoaWxkcmVuICYmIGNoaWxkcmVuLmxlbmd0aFxuICAgICAgICAmJiBjaGlsZHJlbi5sZW5ndGggPiBpbmRleFxuICAgICAgICAmJiBpbmRleCAhPT0gLTEpIHtcbiAgICAgIHRoaXMuaW5zZXJ0QmVmb3JlKGNoaWxkcmVuW2luZGV4XS5yZWYsIGVsZW1lbnQpXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYXBwZW5kQ2hpbGQocGFyZW50UmVmLCBlbGVtZW50KVxuICAgIH1cbiAgfSxcblxuICBjbGVhckNoaWxkcmVuOiBmdW5jdGlvbiAocmVmKSB7XG4gICAgdmFyIGNvbXBvbmVudCA9IHRoaXMuY29tcG9uZW50TWFwW3JlZl1cbiAgICBpZiAoY29tcG9uZW50KSB7XG4gICAgICBjb21wb25lbnQubm9kZS5pbm5lckhUTUwgPSAnJ1xuICAgICAgaWYgKGNvbXBvbmVudC5kYXRhKSB7XG4gICAgICAgIGNvbXBvbmVudC5kYXRhLmNoaWxkcmVuID0gbnVsbFxuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICBhZGRFdmVudDogZnVuY3Rpb24gKHJlZiwgdHlwZSkge1xuICAgIHZhciBjb21wb25lbnRcbiAgICBpZiAodHlwZW9mIHJlZiA9PT0gJ3N0cmluZycgfHwgdHlwZW9mIHJlZiA9PT0gJ251bWJlcicpIHtcbiAgICAgIGNvbXBvbmVudCA9IHRoaXMuY29tcG9uZW50TWFwW3JlZl1cbiAgICB9IGVsc2UgaWYgKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChyZWYpLnNsaWNlKDgsIC0xKSA9PT0gJ09iamVjdCcpIHtcbiAgICAgIGNvbXBvbmVudCA9IHJlZlxuICAgICAgcmVmID0gY29tcG9uZW50LmRhdGEucmVmXG4gICAgfVxuICAgIGlmIChjb21wb25lbnQgJiYgY29tcG9uZW50Lm5vZGUpIHtcbiAgICAgIHZhciBzZW5kZXIgPSB0aGlzLndlZXhJbnN0YW5jZS5zZW5kZXJcbiAgICAgIHZhciBsaXN0ZW5lciA9IHNlbmRlci5maXJlRXZlbnQuYmluZChzZW5kZXIsIHJlZiwgdHlwZSlcbiAgICAgIHZhciBsaXN0ZW5lcnMgPSBjb21wb25lbnQuX2xpc3RlbmVyc1xuICAgICAgY29tcG9uZW50Lm5vZGUuYWRkRXZlbnRMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lciwgZmFsc2UsIGZhbHNlKVxuICAgICAgaWYgKCFsaXN0ZW5lcnMpIHtcbiAgICAgICAgbGlzdGVuZXJzID0gY29tcG9uZW50Ll9saXN0ZW5lcnMgPSB7fVxuICAgICAgICBjb21wb25lbnQubm9kZS5fbGlzdGVuZXJzID0ge31cbiAgICAgIH1cbiAgICAgIGxpc3RlbmVyc1t0eXBlXSA9IGxpc3RlbmVyXG4gICAgICBjb21wb25lbnQubm9kZS5fbGlzdGVuZXJzW3R5cGVdID0gbGlzdGVuZXJcbiAgICB9XG4gIH0sXG5cbiAgcmVtb3ZlRXZlbnQ6IGZ1bmN0aW9uIChyZWYsIHR5cGUpIHtcbiAgICB2YXIgY29tcG9uZW50ID0gdGhpcy5jb21wb25lbnRNYXBbcmVmXVxuICAgIHZhciBsaXN0ZW5lciA9IGNvbXBvbmVudC5fbGlzdGVuZXJzW3R5cGVdXG4gICAgaWYgKGNvbXBvbmVudCAmJiBsaXN0ZW5lcikge1xuICAgICAgY29tcG9uZW50Lm5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcilcbiAgICAgIGNvbXBvbmVudC5fbGlzdGVuZXJzW3R5cGVdID0gbnVsbFxuICAgICAgY29tcG9uZW50Lm5vZGUuX2xpc3RlbmVyc1t0eXBlXSA9IG51bGxcbiAgICB9XG4gIH0sXG5cbiAgdXBkYXRlQXR0cnM6IGZ1bmN0aW9uIChyZWYsIGF0dHIpIHtcbiAgICB2YXIgY29tcG9uZW50ID0gdGhpcy5jb21wb25lbnRNYXBbcmVmXVxuICAgIGlmIChjb21wb25lbnQpIHtcbiAgICAgIGNvbXBvbmVudC51cGRhdGVBdHRycyhhdHRyKVxuICAgICAgaWYgKGNvbXBvbmVudC5kYXRhLnR5cGUgPT09ICdpbWFnZScgJiYgYXR0ci5zcmMpIHtcbiAgICAgICAgTGF6eUxvYWQuc3RhcnRJZk5lZWRlZChjb21wb25lbnQpXG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIHVwZGF0ZVN0eWxlOiBmdW5jdGlvbiAocmVmLCBzdHlsZSkge1xuICAgIHZhciBjb21wb25lbnQgPSB0aGlzLmNvbXBvbmVudE1hcFtyZWZdXG4gICAgaWYgKGNvbXBvbmVudCkge1xuICAgICAgY29tcG9uZW50LnVwZGF0ZVN0eWxlKHN0eWxlKVxuICAgIH1cbiAgfSxcblxuICB1cGRhdGVGdWxsQXR0cnM6IGZ1bmN0aW9uIChyZWYsIGF0dHIpIHtcbiAgICB2YXIgY29tcG9uZW50ID0gdGhpcy5jb21wb25lbnRNYXBbcmVmXVxuICAgIGlmIChjb21wb25lbnQpIHtcbiAgICAgIGNvbXBvbmVudC5jbGVhckF0dHIoKVxuICAgICAgY29tcG9uZW50LnVwZGF0ZUF0dHJzKGF0dHIpXG4gICAgICBpZiAoY29tcG9uZW50LmRhdGEudHlwZSA9PT0gJ2ltYWdlJyAmJiBhdHRyLnNyYykge1xuICAgICAgICBMYXp5TG9hZC5zdGFydElmTmVlZGVkKGNvbXBvbmVudClcbiAgICAgIH1cbiAgICB9XG4gIH0sXG5cbiAgdXBkYXRlRnVsbFN0eWxlOiBmdW5jdGlvbiAocmVmLCBzdHlsZSkge1xuICAgIHZhciBjb21wb25lbnQgPSB0aGlzLmNvbXBvbmVudE1hcFtyZWZdXG4gICAgaWYgKGNvbXBvbmVudCkge1xuICAgICAgY29tcG9uZW50LmNsZWFyU3R5bGUoKVxuICAgICAgY29tcG9uZW50LnVwZGF0ZVN0eWxlKHN0eWxlKVxuICAgIH1cbiAgfSxcblxuICBoYW5kbGVBcHBlbmQ6IGZ1bmN0aW9uIChjb21wb25lbnQpIHtcbiAgICBjb21wb25lbnQuX2FwcGVuZGVkID0gdHJ1ZVxuICAgIGNvbXBvbmVudC5vbkFwcGVuZCAmJiBjb21wb25lbnQub25BcHBlbmQoKVxuXG4gICAgLy8gaW52b2tlIG9uQXBwZW5kIG9uIGNoaWxkcmVuIHJlY3Vyc2l2ZWx5XG4gICAgdmFyIGNoaWxkcmVuID0gY29tcG9uZW50LmRhdGEuY2hpbGRyZW5cbiAgICBpZiAoY2hpbGRyZW4pIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGNoaWxkID0gdGhpcy5jb21wb25lbnRNYXBbY2hpbGRyZW5baV0ucmVmXVxuICAgICAgICBpZiAoY2hpbGQpIHtcbiAgICAgICAgICB0aGlzLmhhbmRsZUFwcGVuZChjaGlsZClcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHdhdGNoIGFwcGVhci9kaXNhcHBlYXIgb2YgdGhlIGNvbXBvbmVudCBpZiBuZWVkZWRcbiAgICBBcHBlYXJXYXRjaGVyLndhdGNoSWZOZWVkZWQoY29tcG9uZW50KVxuXG4gICAgLy8gZG8gbGF6eWxvYWQgaWYgbmVlZGVkXG4gICAgTGF6eUxvYWQuc3RhcnRJZk5lZWRlZChjb21wb25lbnQpXG4gIH0sXG5cbiAgdHJhbnNpdGlvbjogZnVuY3Rpb24gKHJlZiwgY29uZmlnLCBjYWxsYmFjaykge1xuICAgIHZhciBjb21wb25lbnQgPSB0aGlzLmNvbXBvbmVudE1hcFtyZWZdXG4gICAgYW5pbWF0aW9uLnRyYW5zaXRpb25PbmNlKGNvbXBvbmVudCwgY29uZmlnLCBjYWxsYmFjaylcbiAgfSxcblxuICByZW5kZXJGaW5pc2g6IGZ1bmN0aW9uICgpIHtcbiAgICBGcmFtZVVwZGF0ZXIucGF1c2UoKVxuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gQ29tcG9uZW50TWFuYWdlclxuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL3NyYy9jb21wb25lbnRNYW5hZ2VyLmpzXG4gKiogbW9kdWxlIGlkID0gOVxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnZhciByYWYgPSB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lIHx8XG4gICAgICAgICAgd2luZG93LndlYmtpdFJlcXVlc3RBbmltYXRpb25GcmFtZSB8fFxuICAgICAgICAgIGZ1bmN0aW9uIChjYWxsbGJhY2spIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoY2FsbGxiYWNrLCAxNilcbiAgICAgICAgICB9XG5cbnZhciByYWZJZFxudmFyIG9ic2VydmVycyA9IFtdXG52YXIgcGF1c2VkID0gZmFsc2VcblxudmFyIEZyYW1lVXBkYXRlciA9IHtcbiAgc3RhcnQ6IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAocmFmSWQpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHJhZklkID0gcmFmKGZ1bmN0aW9uIHJ1bkxvb3AoKSB7XG4gICAgICBpZiAoIXBhdXNlZCkge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9ic2VydmVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIG9ic2VydmVyc1tpXSgpXG4gICAgICAgIH1cbiAgICAgICAgcmFmKHJ1bkxvb3ApXG4gICAgICB9XG4gICAgfSlcbiAgfSxcblxuICBpc0FjdGl2ZTogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAhcGF1c2VkXG4gIH0sXG5cbiAgcGF1c2U6IGZ1bmN0aW9uICgpIHtcbiAgICBwYXVzZWQgPSB0cnVlXG4gICAgcmFmSWQgPSB1bmRlZmluZWRcbiAgfSxcblxuICByZXN1bWU6IGZ1bmN0aW9uICgpIHtcbiAgICBwYXVzZWQgPSBmYWxzZVxuICAgIHRoaXMuc3RhcnQoKVxuICB9LFxuXG4gIGFkZFVwZGF0ZU9ic2VydmVyOiBmdW5jdGlvbiAob2JzZXJ2ZU1ldGhvZCkge1xuICAgIG9ic2VydmVycy5wdXNoKG9ic2VydmVNZXRob2QpXG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBGcmFtZVVwZGF0ZXJcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvZnJhbWVVcGRhdGVyLmpzXG4gKiogbW9kdWxlIGlkID0gMTBcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIid1c2Ugc3RyaWN0J1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJylcblxudmFyIGNvbXBvbmVudHNJblNjcm9sbGVyID0gW11cbnZhciBjb21wb25lbnRzT3V0T2ZTY3JvbGxlciA9IFtdXG52YXIgbGlzdGVuZWQgPSBmYWxzZVxudmFyIGRpcmVjdGlvbiA9ICd1cCdcbnZhciBzY3JvbGxZID0gMFxuXG52YXIgQXBwZWFyV2F0Y2hlciA9IHtcbiAgd2F0Y2hJZk5lZWRlZDogZnVuY3Rpb24gKGNvbXBvbmVudCkge1xuICAgIGlmIChuZWVkV2F0Y2goY29tcG9uZW50KSkge1xuICAgICAgaWYgKGNvbXBvbmVudC5pc0luU2Nyb2xsYWJsZSgpKSB7XG4gICAgICAgIGNvbXBvbmVudHNJblNjcm9sbGVyLnB1c2goY29tcG9uZW50KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29tcG9uZW50c091dE9mU2Nyb2xsZXIucHVzaChjb21wb25lbnQpXG4gICAgICB9XG4gICAgICBpZiAoIWxpc3RlbmVkKSB7XG4gICAgICAgIGxpc3RlbmVkID0gdHJ1ZVxuICAgICAgICAvLyB2YXIgaGFuZGxlciA9IHRocm90dGxlKG9uU2Nyb2xsLCAyNSlcbiAgICAgICAgdmFyIGhhbmRsZXIgPSB0aHJvdHRsZShvblNjcm9sbCwgMTAwKVxuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgaGFuZGxlciwgZmFsc2UpXG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIG5lZWRXYXRjaChjb21wb25lbnQpIHtcbiAgdmFyIGV2ZW50cyA9IGNvbXBvbmVudC5kYXRhLmV2ZW50XG4gIGlmIChldmVudHNcbiAgICAgICYmIChldmVudHMuaW5kZXhPZignYXBwZWFyJykgIT0gLTFcbiAgICAgICAgfHwgZXZlbnRzLmluZGV4T2YoJ2Rpc2FwcGVhcicpICE9IC0xKSkge1xuICAgIHJldHVybiB0cnVlXG4gIH1cbiAgcmV0dXJuIGZhbHNlXG59XG5cbmZ1bmN0aW9uIG9uU2Nyb2xsKGUpIHtcbiAgLy8gSWYgdGhlIHNjcm9sbCBldmVudCBpcyBkaXNwYXRjaGVkIGZyb20gYSBzY3JvbGxhYmxlIGNvbXBvbmVudFxuICAvLyBpbXBsZW1lbnRlZCB0aHJvdWdoIHNjcm9sbGVyanMsIHRoZW4gdGhlIGFwcGVhci9kaXNhcHBlYXIgZXZlbnRzXG4gIC8vIHNob3VsZCBiZSB0cmVhdGVkIHNwZWNpYWxseSBieSBoYW5kbGVTY3JvbGxlclNjcm9sbC5cbiAgaWYgKGUub3JpZ2luYWxUeXBlID09PSAnc2Nyb2xsaW5nJykge1xuICAgIGhhbmRsZVNjcm9sbGVyU2Nyb2xsKClcbiAgfSBlbHNlIHtcbiAgICBoYW5kbGVXaW5kb3dTY3JvbGwoKVxuICB9XG59XG5cbmZ1bmN0aW9uIGhhbmRsZVNjcm9sbGVyU2Nyb2xsKCkge1xuICB2YXIgY21wcyA9IGNvbXBvbmVudHNJblNjcm9sbGVyXG4gIHZhciBsZW4gPSBjbXBzLmxlbmd0aFxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgdmFyIGNvbXBvbmVudCA9IGNtcHNbaV1cbiAgICB2YXIgYXBwZWFyID0gaXNDb21wb25lbnRJblNjcm9sbGVyQXBwZWFyKGNvbXBvbmVudClcbiAgICBpZiAoYXBwZWFyICYmICFjb21wb25lbnQuX2FwcGVhcikge1xuICAgICAgY29tcG9uZW50Ll9hcHBlYXIgPSB0cnVlXG4gICAgICBmaXJlRXZlbnQoY29tcG9uZW50LCAnYXBwZWFyJylcbiAgICB9IGVsc2UgaWYgKCFhcHBlYXIgJiYgY29tcG9uZW50Ll9hcHBlYXIpIHtcbiAgICAgIGNvbXBvbmVudC5fYXBwZWFyID0gZmFsc2VcbiAgICAgIGZpcmVFdmVudChjb21wb25lbnQsICdkaXNhcHBlYXInKVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBoYW5kbGVXaW5kb3dTY3JvbGwoKSB7XG4gIHZhciB5ID0gd2luZG93LnNjcm9sbFlcbiAgZGlyZWN0aW9uID0geSA+PSBzY3JvbGxZID8gJ3VwJyA6ICdkb3duJ1xuICBzY3JvbGxZID0geVxuXG4gIHZhciBsZW4gPSBjb21wb25lbnRzT3V0T2ZTY3JvbGxlci5sZW5ndGhcbiAgaWYgKGxlbiA9PT0gMCkge1xuICAgIHJldHVyblxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICB2YXIgY29tcG9uZW50ID0gY29tcG9uZW50c091dE9mU2Nyb2xsZXJbaV1cbiAgICB2YXIgYXBwZWFyID0gaXNDb21wb25lbnRJbldpbmRvdyhjb21wb25lbnQpXG4gICAgaWYgKGFwcGVhciAmJiAhY29tcG9uZW50Ll9hcHBlYXIpIHtcbiAgICAgIGNvbXBvbmVudC5fYXBwZWFyID0gdHJ1ZVxuICAgICAgZmlyZUV2ZW50KGNvbXBvbmVudCwgJ2FwcGVhcicpXG4gICAgfSBlbHNlIGlmICghYXBwZWFyICYmIGNvbXBvbmVudC5fYXBwZWFyKSB7XG4gICAgICBjb21wb25lbnQuX2FwcGVhciA9IGZhbHNlXG4gICAgICBmaXJlRXZlbnQoY29tcG9uZW50LCAnZGlzYXBwZWFyJylcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNDb21wb25lbnRJblNjcm9sbGVyQXBwZWFyKGNvbXBvbmVudCkge1xuICB2YXIgcGFyZW50U2Nyb2xsZXIgPSBjb21wb25lbnQuX3BhcmVudFNjcm9sbGVyXG4gIHZhciBjbXBSZWN0ID0gY29tcG9uZW50Lm5vZGUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcbiAgaWYgKCFpc0NvbXBvbmVudEluV2luZG93KGNvbXBvbmVudCkpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuICB3aGlsZSAocGFyZW50U2Nyb2xsZXIpIHtcbiAgICB2YXIgcGFyZW50UmVjdCA9IHBhcmVudFNjcm9sbGVyLm5vZGUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcbiAgICBpZiAoIShjbXBSZWN0LnJpZ2h0ID4gcGFyZW50UmVjdC5sZWZ0XG4gICAgICAgICYmIGNtcFJlY3QubGVmdCA8IHBhcmVudFJlY3QucmlnaHRcbiAgICAgICAgJiYgY21wUmVjdC5ib3R0b20gPiBwYXJlbnRSZWN0LnRvcFxuICAgICAgICAmJiBjbXBSZWN0LnRvcCA8IHBhcmVudFJlY3QuYm90dG9tKSkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuICAgIHBhcmVudFNjcm9sbGVyID0gcGFyZW50U2Nyb2xsZXIuX3BhcmVudFNjcm9sbGVyXG4gIH1cbiAgcmV0dXJuIHRydWVcbn1cblxuZnVuY3Rpb24gaXNDb21wb25lbnRJbldpbmRvdyhjb21wb25lbnQpIHtcbiAgdmFyIHJlY3QgPSBjb21wb25lbnQubm9kZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICByZXR1cm4gcmVjdC5yaWdodCA+IDAgJiYgcmVjdC5sZWZ0IDwgd2luZG93LmlubmVyV2lkdGggJiZcbiAgICAgICAgIHJlY3QuYm90dG9tID4gMCAmJiByZWN0LnRvcCA8IHdpbmRvdy5pbm5lckhlaWdodFxufVxuXG5mdW5jdGlvbiBmaXJlRXZlbnQoY29tcG9uZW50LCB0eXBlKSB7XG4gIHZhciBldnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudCgnSFRNTEV2ZW50cycpXG4gIHZhciBkYXRhID0geyBkaXJlY3Rpb246IGRpcmVjdGlvbiB9XG4gIGV2dC5pbml0RXZlbnQodHlwZSwgZmFsc2UsIGZhbHNlKVxuICBldnQuZGF0YSA9IGRhdGFcbiAgdXRpbHMuZXh0ZW5kKGV2dCwgZGF0YSlcbiAgY29tcG9uZW50Lm5vZGUuZGlzcGF0Y2hFdmVudChldnQpXG59XG5cbmZ1bmN0aW9uIHRocm90dGxlKGZ1bmMsIHdhaXQpIHtcbiAgdmFyIGNvbnRleHQsIGFyZ3MsIHJlc3VsdFxuICB2YXIgdGltZW91dCA9IG51bGxcbiAgdmFyIHByZXZpb3VzID0gMFxuICB2YXIgbGF0ZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgcHJldmlvdXMgPSBEYXRlLm5vdygpXG4gICAgdGltZW91dCA9IG51bGxcbiAgICByZXN1bHQgPSBmdW5jLmFwcGx5KGNvbnRleHQsIGFyZ3MpXG4gIH1cbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgbm93ID0gRGF0ZS5ub3coKVxuICAgIHZhciByZW1haW5pbmcgPSB3YWl0IC0gKG5vdyAtIHByZXZpb3VzKVxuICAgIGNvbnRleHQgPSB0aGlzXG4gICAgYXJncyA9IGFyZ3VtZW50c1xuICAgIGlmIChyZW1haW5pbmcgPD0gMCkge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpXG4gICAgICB0aW1lb3V0ID0gbnVsbFxuICAgICAgcHJldmlvdXMgPSBub3dcbiAgICAgIHJlc3VsdCA9IGZ1bmMuYXBwbHkoY29udGV4dCwgYXJncylcbiAgICB9IGVsc2UgaWYgKCF0aW1lb3V0KSB7XG4gICAgICB0aW1lb3V0ID0gc2V0VGltZW91dChsYXRlciwgcmVtYWluaW5nKVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBBcHBlYXJXYXRjaGVyXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL3NyYy9hcHBlYXJXYXRjaGVyLmpzXG4gKiogbW9kdWxlIGlkID0gMTFcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIid1c2Ugc3RyaWN0J1xuXG5yZXF1aXJlKCdsYXp5aW1nJylcblxudmFyIGxhenlsb2FkVGltZXJcblxudmFyIExhenlMb2FkID0ge1xuICBtYWtlSW1hZ2VMYXp5OiBmdW5jdGlvbiAoaW1hZ2UsIHNyYykge1xuICAgIGltYWdlLnJlbW92ZUF0dHJpYnV0ZSgnaW1nLXNyYycpXG4gICAgaW1hZ2UucmVtb3ZlQXR0cmlidXRlKCdpLWxhenktc3JjJylcbiAgICBpbWFnZS5yZW1vdmVBdHRyaWJ1dGUoJ3NyYycpXG4gICAgaW1hZ2Uuc2V0QXR0cmlidXRlKCdpbWctc3JjJywgc3JjKVxuICAgIC8vIHNob3VsZCByZXBsYWNlICdzcmMnIHdpdGggJ2ltZy1zcmMnLiBidXQgZm9yIG5vdyBsaWIuaW1nLmZpcmUgaXNcbiAgICAvLyBub3Qgd29ya2luZyBmb3IgdGhlIHNpdHVhdGlvbiB0aGF0IHRoZSBhcHBlYXIgZXZlbnQgaGFzIGJlZW5cbiAgICAvLyBhbHJlYWR5IHRyaWdnZXJlZC5cbiAgICAvLyBpbWFnZS5zZXRBdHRyaWJ1dGUoJ3NyYycsIHNyYylcbiAgICAvLyBpbWFnZS5zZXRBdHRyaWJ1dGUoJ2ltZy1zcmMnLCBzcmMpXG4gICAgdGhpcy5maXJlKClcbiAgfSxcblxuICAvLyB3ZSBkb24ndCBrbm93IHdoZW4gYWxsIGltYWdlIGFyZSBhcHBlbmRlZFxuICAvLyBqdXN0IHVzZSBzZXRUaW1lb3V0IHRvIGRvIGRlbGF5IGxhenlsb2FkXG4gIC8vXG4gIC8vIC0tIGFjdHVhbGx5IGV2ZXJ5dGltZSB3ZSBhZGQgYSBlbGVtZW50IG9yIHVwZGF0ZSBzdHlsZXMsXG4gIC8vIHRoZSBjb21wb25lbnQgbWFuYWdlciB3aWxsIGNhbGwgc3RhcnRJZk5lZWQgdG8gZmlyZVxuICAvLyBsYXp5bG9hZCBvbmNlIGFnYWluIGluIHRoZSBoYW5kbGVBcHBlbmQgZnVuY3Rpb24uIHNvIHRoZXJlXG4gIC8vIGlzIG5vIHdheSB0aGF0IGFueSBpbWFnZSBlbGVtZW50IGNhbiBtaXNzIGl0LiBTZWUgc291cmNlXG4gIC8vIGNvZGUgaW4gY29tcG9uZW50TWFuZ2FnZXIuanMuXG4gIHN0YXJ0SWZOZWVkZWQ6IGZ1bmN0aW9uIChjb21wb25lbnQpIHtcbiAgICB2YXIgdGhhdCA9IHRoaXNcbiAgICBpZiAoY29tcG9uZW50LmRhdGEudHlwZSA9PT0gJ2ltYWdlJykge1xuICAgICAgaWYgKCFsYXp5bG9hZFRpbWVyKSB7XG4gICAgICAgIGxhenlsb2FkVGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICB0aGF0LmZpcmUoKVxuICAgICAgICAgIGNsZWFyVGltZW91dChsYXp5bG9hZFRpbWVyKVxuICAgICAgICAgIGxhenlsb2FkVGltZXIgPSBudWxsXG4gICAgICAgIH0sIDE2KVxuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICBsb2FkSWZOZWVkZWQ6IGZ1bmN0aW9uIChlbGVtZW50U2NvcGUpIHtcbiAgICB2YXIgbm90UHJlUHJvY2Vzc2VkID0gZWxlbWVudFNjb3BlLnF1ZXJ5U2VsZWN0b3JBbGwoJ1tpbWctc3JjXScpXG4gICAgdmFyIHRoYXQgPSB0aGlzXG4gICAgLy8gaW1hZ2UgZWxlbWVudHMgd2hpY2ggaGF2ZSBhdHRyaWJ1dGUgJ2ktbGF6eS1zcmMnIHdlcmUgZWxlbWVudHNcbiAgICAvLyB0aGF0IGhhZCBiZWVuIHByZXByb2Nlc3NlZCBieSBsaWItaW1nLWNvcmUsIGJ1dCBub3QgbG9hZGVkIHlldCwgYW5kXG4gICAgLy8gbXVzdCBiZSBsb2FkZWQgd2hlbiAnYXBwZWFyJyBldmVudHMgd2VyZSBmaXJlZC4gSXQgdHVybnMgb3V0IHRoZVxuICAgIC8vICdhcHBlYXInIGV2ZW50IHdhcyBub3QgZmlyZWQgY29ycmVjdGx5IGluIHRoZSBjc3MtdHJhbnNsYXRlLXRyYW5zaXRpb25cbiAgICAvLyBzaXR1YXRpb24sIHNvICdpLWxhenktc3JjJyBtdXN0IGJlIGNoZWNrZWQgYW5kIGxhenlsb2FkIG11c3QgYmVcbiAgICAvLyBmaXJlZCBtYW51YWxseS5cbiAgICB2YXIgcHJlUHJvY2Vzc2VkID0gZWxlbWVudFNjb3BlLnF1ZXJ5U2VsZWN0b3JBbGwoJ1tpLWxhenktc3JjXScpXG4gICAgaWYgKG5vdFByZVByb2Nlc3NlZC5sZW5ndGggPiAwIHx8IHByZVByb2Nlc3NlZC5sZW5ndGggPiAwKSB7XG4gICAgICB0aGF0LmZpcmUoKVxuICAgIH1cbiAgfSxcblxuICAvLyBmaXJlIGxhenlsb2FkLlxuICBmaXJlOiBmdW5jdGlvbiAoKSB7XG4gICAgbGliLmltZy5maXJlKClcbiAgfVxuXG59XG5cbm1vZHVsZS5leHBvcnRzID0gTGF6eUxvYWRcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvbGF6eUxvYWQuanNcbiAqKiBtb2R1bGUgaWQgPSAxMlxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiXCJ1bmRlZmluZWRcIj09dHlwZW9mIHdpbmRvdyYmKHdpbmRvdz17Y3RybDp7fSxsaWI6e319KSwhd2luZG93LmN0cmwmJih3aW5kb3cuY3RybD17fSksIXdpbmRvdy5saWImJih3aW5kb3cubGliPXt9KSxmdW5jdGlvbih0LGkpe2Z1bmN0aW9uIGUodCxpKXtpJiYoXCJJTUdcIj09dC5ub2RlTmFtZS50b1VwcGVyQ2FzZSgpP3Quc2V0QXR0cmlidXRlKFwic3JjXCIsaSk6dC5zdHlsZS5iYWNrZ3JvdW5kSW1hZ2U9J3VybChcIicraSsnXCIpJyl9ZnVuY3Rpb24gYSgpe3I9aS5hcHBlYXIuaW5pdCh7Y2xzOlwiaW1ndG1wXCIsb25jZTohMCx4Om8ubGF6eVdpZHRoLHk6by5sYXp5SGVpZ2h0LG9uQXBwZWFyOmZ1bmN0aW9uKHQpe3ZhciBpPXRoaXM7ZShpLGkuZ2V0QXR0cmlidXRlKFwiaS1sYXp5LXNyY1wiKSksaS5yZW1vdmVBdHRyaWJ1dGUoXCJpLWxhenktc3JjXCIpfX0pfXJlcXVpcmUoXCJhcHBlYXJqc1wiKTt2YXIgcixBPXt9LG89e2RhdGFTcmM6XCJpbWctc3JjXCIsbGF6eUhlaWdodDowLGxhenlXaWR0aDowfTtBLmxvZ0NvbmZpZz1mdW5jdGlvbigpe2NvbnNvbGUubG9nKFwibGliLWltZyBDb25maWdcXG5cIixvKX0sQS5maXJlPWZ1bmN0aW9uKCl7cnx8YSgpO3ZhciB0PVwiaV9cIitEYXRlLm5vdygpJTFlNSxpPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCJbXCIrby5kYXRhU3JjK1wiXVwiKTtbXS5mb3JFYWNoLmNhbGwoaSxmdW5jdGlvbihpKXtcImZhbHNlXCI9PWkuZGF0YXNldC5sYXp5JiZcInRydWVcIiE9aS5kYXRhc2V0Lmxhenk/ZShpLHByb2Nlc3NTcmMoaSxpLmdldEF0dHJpYnV0ZShvLmRhdGFTcmMpKSk6KGkuY2xhc3NMaXN0LmFkZCh0KSxpLnNldEF0dHJpYnV0ZShcImktbGF6eS1zcmNcIixpLmdldEF0dHJpYnV0ZShvLmRhdGFTcmMpKSksaS5yZW1vdmVBdHRyaWJ1dGUoby5kYXRhU3JjKX0pLHIuYmluZChcIi5cIit0KSxyLmZpcmUoKX0sQS5kZWZhdWx0U3JjPVwiZGF0YTppbWFnZS9naWY7YmFzZTY0LGlWQk9SdzBLR2dvQUFBQU5TVWhFVWdBQUFBRUFBQUFCQ0FZQUFBQWZGY1NKQUFBQURVbEVRVlFJbVdOZ1lHQmdBQUFBQlFBQmg2Rk8xQUFBQUFCSlJVNUVya0pnZ2c9PVwiLGkuaW1nPUEsbW9kdWxlLmV4cG9ydHM9QX0od2luZG93LHdpbmRvdy5saWJ8fCh3aW5kb3cubGliPXt9KSk7XG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbGF6eWltZy9idWlsZC9pbWcuY29tbW9uLmpzXG4gKiogbW9kdWxlIGlkID0gMTNcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIlwidW5kZWZpbmVkXCI9PXR5cGVvZiB3aW5kb3cmJih3aW5kb3c9e2N0cmw6e30sbGliOnt9fSksIXdpbmRvdy5jdHJsJiYod2luZG93LmN0cmw9e30pLCF3aW5kb3cubGliJiYod2luZG93LmxpYj17fSksZnVuY3Rpb24obixlKXtmdW5jdGlvbiBpKCl7ZD13LmNyZWF0ZUV2ZW50KFwiSFRNTEV2ZW50c1wiKSx2PXcuY3JlYXRlRXZlbnQoXCJIVE1MRXZlbnRzXCIpLGQuaW5pdEV2ZW50KFwiX2FwcGVhclwiLCExLCEwKSx2LmluaXRFdmVudChcIl9kaXNhcHBlYXJcIiwhMSwhMCl9ZnVuY3Rpb24gYSh0LG4pe3ZhciBlLGksYSxzPShEYXRlLm5vdygpLDApLG89bnVsbCxyPWZ1bmN0aW9uKCl7cz1EYXRlLm5vdygpLG89bnVsbCx0LmFwcGx5KGUsaSl9O3JldHVybiBmdW5jdGlvbigpe3ZhciBsPURhdGUubm93KCk7ZT10aGlzLGk9YXJndW1lbnRzO3ZhciBjPW4tKGwtcyk7cmV0dXJuIDA+PWN8fGM+PW4/KGNsZWFyVGltZW91dChvKSxvPW51bGwsYT10LmFwcGx5KGUsaSkpOm51bGw9PW8mJihvPXNldFRpbWVvdXQocixjKSksYX19ZnVuY3Rpb24gcyhuLGUpe3ZhciBuLGksYSxzO2lmKG4pcmV0dXJuIGV8fChlPXt4OjAseTowfSksbiE9d2luZG93PyhuPW4uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksaT1uLmxlZnQsdD1uLnRvcCxhPW4ucmlnaHQscz1uLmJvdHRvbSk6KGk9MCx0PTAsYT1pK24uaW5uZXJXaWR0aCxzPXQrbi5pbm5lckhlaWdodCkse2xlZnQ6aSx0b3A6dCxyaWdodDphK2UueCxib3R0b206cytlLnl9fWZ1bmN0aW9uIG8odCxuKXt2YXIgZT1uLnJpZ2h0PnQubGVmdCYmbi5sZWZ0PHQucmlnaHQsaT1uLmJvdHRvbT50LnRvcCYmbi50b3A8dC5ib3R0b207cmV0dXJuIGUmJml9ZnVuY3Rpb24gcih0LG4pe3ZhciBlPVwibm9uZVwiLGk9dC5sZWZ0LW4ubGVmdCxhPXQudG9wLW4udG9wO3JldHVybiAwPT1hJiYoZT0wIT1pP2k+MD9cImxlZnRcIjpcInJpZ2h0XCI6XCJub25lXCIpLDA9PWkmJihlPTAhPWE/YT4wP1widXBcIjpcImRvd25cIjpcIm5vbmVcIiksZX1mdW5jdGlvbiBsKHQsbil7Zm9yKHZhciBlIGluIG4pbi5oYXNPd25Qcm9wZXJ0eShlKSYmKHRbZV09bltlXSk7cmV0dXJuIHR9ZnVuY3Rpb24gYygpe3ZhciB0PXRoaXMsbj1hKGZ1bmN0aW9uKCl7Zi5hcHBseSh0LGFyZ3VtZW50cyl9LHRoaXMub3B0aW9ucy53YWl0KTt0aGlzLl9faGFuZGxlJiYodGhpcy5jb250YWluZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInNjcm9sbFwiLHRoaXMuX19oYW5kbGUpLHRoaXMuX19oYW5kbGU9bnVsbCksdGhpcy5fX2hhbmRsZT1uLHRoaXMuY29udGFpbmVyLmFkZEV2ZW50TGlzdGVuZXIoXCJzY3JvbGxcIixuLCExKSx0aGlzLmNvbnRhaW5lci5hZGRFdmVudExpc3RlbmVyKFwicmVzaXplXCIsZnVuY3Rpb24obil7Zi5hcHBseSh0LGFyZ3VtZW50cyl9LCExKSx0aGlzLmNvbnRhaW5lci5hZGRFdmVudExpc3RlbmVyKFwiYW5pbWF0aW9uRW5kXCIsZnVuY3Rpb24oKXtmLmFwcGx5KHQsYXJndW1lbnRzKX0sITEpLHRoaXMuY29udGFpbmVyLmFkZEV2ZW50TGlzdGVuZXIoXCJ3ZWJraXRBbmltYXRpb25FbmRcIixmdW5jdGlvbigpe2YuYXBwbHkodCxhcmd1bWVudHMpfSwhMSksdGhpcy5jb250YWluZXIuYWRkRXZlbnRMaXN0ZW5lcihcInRyYW5zaXRpb25lbmRcIixmdW5jdGlvbigpe2YuYXBwbHkodCxhcmd1bWVudHMpfSwhMSl9ZnVuY3Rpb24gcCh0KXt2YXIgbj10aGlzLGU9dGhpcy5vcHRpb25zLmNvbnRhaW5lcjtpZihcInN0cmluZ1wiPT10eXBlb2YgZT90aGlzLmNvbnRhaW5lcj13LnF1ZXJ5U2VsZWN0b3IoZSk6dGhpcy5jb250YWluZXI9ZSx0aGlzLmNvbnRhaW5lcj09d2luZG93KXZhciBpPXcucXVlcnlTZWxlY3RvckFsbCh0KTtlbHNlIHZhciBpPXRoaXMuY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwodCk7dmFyIGk9W10uc2xpY2UuY2FsbChpLG51bGwpO3JldHVybiBpPWkuZmlsdGVyKGZ1bmN0aW9uKHQpe3JldHVyblwiMVwiPT10LmRhdGFzZXQuYmluZD8oZGVsZXRlIHQuX2hhc0FwcGVhcixkZWxldGUgdC5faGFzRGlzQXBwZWFyLGRlbGV0ZSB0Ll9hcHBlYXIsdC5jbGFzc0xpc3QucmVtb3ZlKG4ub3B0aW9ucy5jbHMpLCExKTohMH0pfWZ1bmN0aW9uIGgodCl7dmFyIG49dGhpczt0JiZ0Lmxlbmd0aD4wJiZbXS5mb3JFYWNoLmNhbGwodCxmdW5jdGlvbih0KXt0Ll9lbGVPZmZzZXQ9cyh0KSx0LmNsYXNzTGlzdC5yZW1vdmUobi5vcHRpb25zLmNscyksdC5kYXRhc2V0LmJpbmQ9MX0pfWZ1bmN0aW9uIGYoKXt2YXIgdD10aGlzLmNvbnRhaW5lcixuPXRoaXMuYXBwZWFyV2F0Y2hFbGVtZW50cyxlPXRoaXMub3B0aW9ucy5vbkFwcGVhcixpPXRoaXMub3B0aW9ucy5vbkRpc2FwcGVhcixhPXModCx7eDp0aGlzLm9wdGlvbnMueCx5OnRoaXMub3B0aW9ucy55fSksbD10aGlzLm9wdGlvbnMub25jZSxjPWFyZ3VtZW50c1swXXx8e307biYmbi5sZW5ndGg+MCYmW10uZm9yRWFjaC5jYWxsKG4sZnVuY3Rpb24odCxuKXt2YXIgcD1zKHQpLGg9cih0Ll9lbGVPZmZzZXQscCk7dC5fZWxlT2Zmc2V0PXA7dmFyIGY9byhhLHApLHU9dC5fYXBwZWFyLHc9dC5faGFzQXBwZWFyLEU9dC5faGFzRGlzQXBwZWFyO2QuZGF0YT17ZGlyZWN0aW9uOmh9LHYuZGF0YT17ZGlyZWN0aW9uOmh9LGYmJiF1PyhsJiYhd3x8IWwpJiYoZSYmZS5jYWxsKHQsYyksdC5kaXNwYXRjaEV2ZW50KGQpLHQuX2hhc0FwcGVhcj0hMCx0Ll9hcHBlYXI9ITApOiFmJiZ1JiYobCYmIUV8fCFsKSYmKGkmJmkuY2FsbCh0LGMpLHQuZGlzcGF0Y2hFdmVudCh2KSx0Ll9oYXNEaXNBcHBlYXI9ITAsdC5fYXBwZWFyPSExKX0pfWZ1bmN0aW9uIHUodCl7bCh0aGlzLm9wdGlvbnMsdHx8KHQ9e30pKSx0aGlzLmFwcGVhcldhdGNoRWxlbWVudHM9dGhpcy5hcHBlYXJXYXRjaEVsZW1lbnRzfHxwLmNhbGwodGhpcyxcIi5cIit0aGlzLm9wdGlvbnMuY2xzKSxoLmNhbGwodGhpcyx0aGlzLmFwcGVhcldhdGNoRWxlbWVudHMpLGMuY2FsbCh0aGlzKX12YXIgZCx2LHc9ZG9jdW1lbnQsRT1mdW5jdGlvbigpe3UuYXBwbHkodGhpcyxhcmd1bWVudHMpfSxfPXtpbnN0YW5jZXM6W10saW5pdDpmdW5jdGlvbih0KXt2YXIgbj17b3B0aW9uczp7Y29udGFpbmVyOndpbmRvdyx3YWl0OjEwMCx4OjAseTowLGNsczpcImxpYi1hcHBlYXJcIixvbmNlOiExLG9uUmVzZXQ6ZnVuY3Rpb24oKXt9LG9uQXBwZWFyOmZ1bmN0aW9uKCl7fSxvbkRpc2FwcGVhcjpmdW5jdGlvbigpe319LGNvbnRhaW5lcjpudWxsLGFwcGVhcldhdGNoRWxlbWVudHM6bnVsbCxiaW5kOmZ1bmN0aW9uKHQpe3ZhciBuPXRoaXMub3B0aW9ucy5jbHM7aWYoXCJzdHJpbmdcIj09dHlwZW9mIHQpe3ZhciBlPXAuY2FsbCh0aGlzLHQpO1tdLmZvckVhY2guY2FsbChlLGZ1bmN0aW9uKHQsZSl7dC5jbGFzc0xpc3QuY29udGFpbnMobil8fHQuY2xhc3NMaXN0LmFkZChuKX0pfWVsc2V7aWYoMSE9dC5ub2RlVHlwZXx8IXRoaXMuY29udGFpbmVyLmNvbnRhaW5zKHQpKXJldHVybiB0aGlzO3QuY2xhc3NMaXN0LmNvbnRhaW5zKG4pfHx0LmNsYXNzTGlzdC5hZGQobil9dmFyIGk9cC5jYWxsKHRoaXMsXCIuXCIrdGhpcy5vcHRpb25zLmNscyk7cmV0dXJuIHRoaXMuYXBwZWFyV2F0Y2hFbGVtZW50cz10aGlzLmFwcGVhcldhdGNoRWxlbWVudHMuY29uY2F0KGkpLGguY2FsbCh0aGlzLGkpLHRoaXN9LHJlc2V0OmZ1bmN0aW9uKHQpe3JldHVybiB1LmNhbGwodGhpcyx0KSx0aGlzLmFwcGVhcldhdGNoRWxlbWVudHMuZm9yRWFjaChmdW5jdGlvbih0KXtkZWxldGUgdC5faGFzQXBwZWFyLGRlbGV0ZSB0Ll9oYXNEaXNBcHBlYXIsZGVsZXRlIHQuX2FwcGVhcn0pLHRoaXN9LGZpcmU6ZnVuY3Rpb24oKXt0aGlzLmFwcGVhcldhdGNoRWxlbWVudHN8fCh0aGlzLmFwcGVhcldhdGNoRWxlbWVudHM9W10pO3ZhciB0PXAuY2FsbCh0aGlzLFwiLlwiK3RoaXMub3B0aW9ucy5jbHMpO3JldHVybiB0aGlzLmFwcGVhcldhdGNoRWxlbWVudHM9dGhpcy5hcHBlYXJXYXRjaEVsZW1lbnRzLmNvbmNhdCh0KSxoLmNhbGwodGhpcyx0KSxmLmNhbGwodGhpcyksdGhpc319O0UucHJvdG90eXBlPW47dmFyIGU9bmV3IEUodCk7cmV0dXJuIHRoaXMuaW5zdGFuY2VzLnB1c2goZSksZX0sZmlyZUFsbDpmdW5jdGlvbigpe3ZhciB0PXRoaXMuaW5zdGFuY2VzO3QuZm9yRWFjaChmdW5jdGlvbih0KXt0LmZpcmUoKX0pfX07aSgpLGUuYXBwZWFyPV99KHdpbmRvdyx3aW5kb3cubGlifHwod2luZG93LmxpYj17fSkpO1xuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2FwcGVhcmpzL2J1aWxkL2FwcGVhci5jb21tb24uanNcbiAqKiBtb2R1bGUgaWQgPSAxNFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXG4gIC8qKlxuICAgKiBjb25maWc6XG4gICAqICAgLSBzdHlsZXNcbiAgICogICAtIGR1cmF0aW9uIFtOdW1iZXJdIG1pbGxpc2Vjb25kcyhtcylcbiAgICogICAtIHRpbWluZ0Z1bmN0aW9uIFtzdHJpbmddXG4gICAqICAgLSBkZWFseSBbTnVtYmVyXSBtaWxsaXNlY29uZHMobXMpXG4gICAqL1xuICB0cmFuc2l0aW9uT25jZTogZnVuY3Rpb24gKGNvbXAsIGNvbmZpZywgY2FsbGJhY2spIHtcbiAgICB2YXIgc3R5bGVzID0gY29uZmlnLnN0eWxlcyB8fCB7fVxuICAgIHZhciBkdXJhdGlvbiA9IGNvbmZpZy5kdXJhdGlvbiB8fCAxMDAwIC8vIG1zXG4gICAgdmFyIHRpbWluZ0Z1bmN0aW9uID0gY29uZmlnLnRpbWluZ0Z1bmN0aW9uIHx8ICdlYXNlJ1xuICAgIHZhciBkZWxheSA9IGNvbmZpZy5kZWxheSB8fCAwICAvLyBtc1xuICAgIHZhciB0cmFuc2l0aW9uVmFsdWUgPSAnYWxsICcgKyBkdXJhdGlvbiArICdtcyAnXG4gICAgICAgICsgdGltaW5nRnVuY3Rpb24gKyAnICcgKyBkZWxheSArICdtcydcbiAgICB2YXIgZG9tID0gY29tcC5ub2RlXG4gICAgdmFyIHRyYW5zaXRpb25FbmRIYW5kbGVyID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKClcbiAgICAgIGRvbS5yZW1vdmVFdmVudExpc3RlbmVyKCd3ZWJraXRUcmFuc2l0aW9uRW5kJywgdHJhbnNpdGlvbkVuZEhhbmRsZXIpXG4gICAgICBkb20ucmVtb3ZlRXZlbnRMaXN0ZW5lcigndHJhbnNpdGlvbmVuZCcsIHRyYW5zaXRpb25FbmRIYW5kbGVyKVxuICAgICAgZG9tLnN0eWxlLnRyYW5zaXRpb24gPSAnJ1xuICAgICAgZG9tLnN0eWxlLndlYmtpdFRyYW5zaXRpb24gPSAnJ1xuICAgICAgY2FsbGJhY2soKVxuICAgIH1cbiAgICBkb20uc3R5bGUudHJhbnNpdGlvbiA9IHRyYW5zaXRpb25WYWx1ZVxuICAgIGRvbS5zdHlsZS53ZWJraXRUcmFuc2l0aW9uID0gdHJhbnNpdGlvblZhbHVlXG4gICAgZG9tLmFkZEV2ZW50TGlzdGVuZXIoJ3dlYmtpdFRyYW5zaXRpb25FbmQnLCB0cmFuc2l0aW9uRW5kSGFuZGxlcilcbiAgICBkb20uYWRkRXZlbnRMaXN0ZW5lcigndHJhbnNpdGlvbmVuZCcsIHRyYW5zaXRpb25FbmRIYW5kbGVyKVxuICAgIGNvbXAudXBkYXRlU3R5bGUoc3R5bGVzKVxuICB9XG5cbn1cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL2FuaW1hdGlvbi5qc1xuICoqIG1vZHVsZSBpZCA9IDE1XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIndXNlIHN0cmljdCdcblxudmFyIGNvbmZpZyA9IHJlcXVpcmUoJy4uL2NvbmZpZycpXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpXG52YXIgQ29tcG9uZW50TWFuYWdlciA9IHJlcXVpcmUoJy4uL2NvbXBvbmVudE1hbmFnZXInKVxudmFyIGZsZXhib3ggPSByZXF1aXJlKCcuLi9mbGV4Ym94JylcbnJlcXVpcmUoJ2ZpeGVkc3RpY2t5JylcblxuZnVuY3Rpb24gQ29tcG9uZW50KGRhdGEsIG5vZGVUeXBlKSB7XG4gIHRoaXMuZGF0YSA9IGRhdGFcbiAgdGhpcy5ub2RlID0gdGhpcy5jcmVhdGUobm9kZVR5cGUpXG5cbiAgdGhpcy5jcmVhdGVDaGlsZHJlbigpXG4gIHRoaXMudXBkYXRlQXR0cnModGhpcy5kYXRhLmF0dHIpXG4gIC8vIGlzc3VlOiB3aGVuIGFkZCBlbGVtZW50IHRvIGEgbGlzdCBpbiBsaWZldGltZSBob29rICdyZWFkeScsIHRoZVxuICAvLyBzdHlsZXMgaXMgc2V0IHRvIHRoZSBjbGFzc1N0eWxlLCBub3Qgc3R5bGUuIFRoaXMgaXMgYSBpc3N1ZVxuICAvLyB0aGF0IGpzZnJhbWV3b3JrIHNob3VsZCBkbyBzb21ldGhpbmcgYWJvdXQuXG4gIHZhciBjbGFzc1N0eWxlID0gdGhpcy5kYXRhLmNsYXNzU3R5bGVcbiAgY2xhc3NTdHlsZSAmJiB0aGlzLnVwZGF0ZVN0eWxlKHRoaXMuZGF0YS5jbGFzc1N0eWxlKVxuICB0aGlzLnVwZGF0ZVN0eWxlKHRoaXMuZGF0YS5zdHlsZSlcbiAgdGhpcy5iaW5kRXZlbnRzKHRoaXMuZGF0YS5ldmVudClcbn1cblxuQ29tcG9uZW50LnByb3RvdHlwZSA9IHtcblxuICBjcmVhdGU6IGZ1bmN0aW9uIChub2RlVHlwZSkge1xuICAgIHZhciBub2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChub2RlVHlwZSB8fCAnZGl2JylcbiAgICByZXR1cm4gbm9kZVxuICB9LFxuXG4gIGdldENvbXBvbmVudE1hbmFnZXI6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gQ29tcG9uZW50TWFuYWdlci5nZXRJbnN0YW5jZSh0aGlzLmRhdGEuaW5zdGFuY2VJZClcbiAgfSxcblxuICBnZXRQYXJlbnQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRDb21wb25lbnRNYW5hZ2VyKCkuY29tcG9uZW50TWFwW3RoaXMucGFyZW50UmVmXVxuICB9LFxuXG4gIGlzU2Nyb2xsYWJsZTogZnVuY3Rpb24gKCkge1xuICAgIHZhciB0ID0gdGhpcy5kYXRhLnR5cGVcbiAgICByZXR1cm4gQ29tcG9uZW50TWFuYWdlci5nZXRTY3JvbGxhYmxlVHlwZXMoKS5pbmRleE9mKHQpICE9PSAtMVxuICB9LFxuXG4gIGlzSW5TY3JvbGxhYmxlOiBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLl9pc0luU2Nyb2xsYWJsZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICByZXR1cm4gdGhpcy5faXNJblNjcm9sbGFibGVcbiAgICB9XG4gICAgdmFyIHBhcmVudCA9IHRoaXMuZ2V0UGFyZW50KClcbiAgICBpZiAocGFyZW50XG4gICAgICAgICYmICh0eXBlb2YgcGFyZW50Ll9pc0luU2Nyb2xsYWJsZSAhPT0gJ2Jvb2xlYW4nKVxuICAgICAgICAmJiAhcGFyZW50LmlzU2Nyb2xsYWJsZSgpKSB7XG4gICAgICBpZiAocGFyZW50LmRhdGEudHlwZSA9PT0gJ3Jvb3QnKSB7XG4gICAgICAgIHRoaXMuX2lzSW5TY3JvbGxhYmxlID0gZmFsc2VcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICB9XG4gICAgICB0aGlzLl9pc0luU2Nyb2xsYWJsZSA9IHBhcmVudC5pc0luU2Nyb2xsYWJsZSgpXG4gICAgICB0aGlzLl9wYXJlbnRTY3JvbGxlciA9IHBhcmVudC5fcGFyZW50U2Nyb2xsZXJcbiAgICAgIHJldHVybiB0aGlzLl9pc0luU2Nyb2xsYWJsZVxuICAgIH1cbiAgICBpZiAodHlwZW9mIHBhcmVudC5faXNJblNjcm9sbGFibGUgPT09ICdib29sZWFuJykge1xuICAgICAgdGhpcy5faXNJblNjcm9sbGFibGUgPSBwYXJlbnQuX2lzSW5TY3JvbGxhYmxlXG4gICAgICB0aGlzLl9wYXJlbnRTY3JvbGxlciA9IHBhcmVudC5fcGFyZW50U2Nyb2xsZXJcbiAgICAgIHJldHVybiB0aGlzLl9pc0luU2Nyb2xsYWJsZVxuICAgIH1cbiAgICBpZiAocGFyZW50LmlzU2Nyb2xsYWJsZSgpKSB7XG4gICAgICB0aGlzLl9pc0luU2Nyb2xsYWJsZSA9IHRydWVcbiAgICAgIHRoaXMuX3BhcmVudFNjcm9sbGVyID0gcGFyZW50XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cbiAgICBpZiAoIXBhcmVudCkge1xuICAgICAgY29uc29sZSAmJiBjb25zb2xlLmVycm9yKCdpc0luU2Nyb2xsYWJsZSAtIHBhcmVudCBub3QgZXhpc3QuJylcbiAgICB9XG4gIH0sXG5cbiAgY3JlYXRlQ2hpbGRyZW46IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgY2hpbGRyZW4gPSB0aGlzLmRhdGEuY2hpbGRyZW5cbiAgICB2YXIgcGFyZW50UmVmID0gdGhpcy5kYXRhLnJlZlxuICAgIHZhciBjb21wb25lbnRNYW5hZ2VyID0gdGhpcy5nZXRDb21wb25lbnRNYW5hZ2VyKClcbiAgICBpZiAoY2hpbGRyZW4gJiYgY2hpbGRyZW4ubGVuZ3RoKSB7XG4gICAgICB2YXIgZnJhZ21lbnQgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KClcbiAgICAgIHZhciBpc0ZsZXggPSBmYWxzZVxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgICBjaGlsZHJlbltpXS5pbnN0YW5jZUlkID0gdGhpcy5kYXRhLmluc3RhbmNlSWRcbiAgICAgICAgY2hpbGRyZW5baV0uc2NhbGUgPSB0aGlzLmRhdGEuc2NhbGVcbiAgICAgICAgdmFyIGNoaWxkID0gY29tcG9uZW50TWFuYWdlci5jcmVhdGVFbGVtZW50KGNoaWxkcmVuW2ldKVxuICAgICAgICBmcmFnbWVudC5hcHBlbmRDaGlsZChjaGlsZC5ub2RlKVxuICAgICAgICBjaGlsZC5wYXJlbnRSZWYgPSBwYXJlbnRSZWZcbiAgICAgICAgaWYgKCFpc0ZsZXhcbiAgICAgICAgICAgICYmIGNoaWxkLmRhdGEuc3R5bGVcbiAgICAgICAgICAgICYmIGNoaWxkLmRhdGEuc3R5bGUuaGFzT3duUHJvcGVydHkoJ2ZsZXgnKVxuICAgICAgICAgICkge1xuICAgICAgICAgIGlzRmxleCA9IHRydWVcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhpcy5ub2RlLmFwcGVuZENoaWxkKGZyYWdtZW50KVxuICAgIH1cbiAgfSxcblxuICAvLyBAdG9kbzogY2hhbmdlZCBwYXJhbSBkYXRhIHRvIGNoaWxkXG4gIGFwcGVuZENoaWxkOiBmdW5jdGlvbiAoZGF0YSkge1xuICAgIHZhciBjaGlsZHJlbiA9IHRoaXMuZGF0YS5jaGlsZHJlblxuICAgIHZhciBjb21wb25lbnRNYW5hZ2VyID0gdGhpcy5nZXRDb21wb25lbnRNYW5hZ2VyKClcbiAgICB2YXIgY2hpbGQgPSBjb21wb25lbnRNYW5hZ2VyLmNyZWF0ZUVsZW1lbnQoZGF0YSlcbiAgICB0aGlzLm5vZGUuYXBwZW5kQ2hpbGQoY2hpbGQubm9kZSlcbiAgICAvLyB1cGRhdGUgdGhpcy5kYXRhLmNoaWxkcmVuXG4gICAgaWYgKCFjaGlsZHJlbiB8fCAhY2hpbGRyZW4ubGVuZ3RoKSB7XG4gICAgICB0aGlzLmRhdGEuY2hpbGRyZW4gPSBbZGF0YV1cbiAgICB9IGVsc2Uge1xuICAgICAgY2hpbGRyZW4ucHVzaChkYXRhKVxuICAgIH1cblxuICAgIHJldHVybiBjaGlsZFxuICB9LFxuXG4gIGluc2VydEJlZm9yZTogZnVuY3Rpb24gKGNoaWxkLCBiZWZvcmUpIHtcbiAgICB2YXIgY2hpbGRyZW4gPSB0aGlzLmRhdGEuY2hpbGRyZW5cbiAgICB2YXIgaSA9IDBcbiAgICB2YXIgbFxuICAgIHZhciBpc0FwcGVuZCA9IGZhbHNlXG5cbiAgICAvLyB1cGRhdGUgdGhpcy5kYXRhLmNoaWxkcmVuXG4gICAgaWYgKCFjaGlsZHJlbiB8fCAhY2hpbGRyZW4ubGVuZ3RoIHx8ICFiZWZvcmUpIHtcbiAgICAgIGlzQXBwZW5kID0gdHJ1ZVxuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKGwgPSBjaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgaWYgKGNoaWxkcmVuW2ldLnJlZiA9PT0gYmVmb3JlLmRhdGEucmVmKSB7XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGkgPT09IGwpIHtcbiAgICAgICAgaXNBcHBlbmQgPSB0cnVlXG4gICAgICB9XG4gICAgfVxuXG5cbiAgICBpZiAoaXNBcHBlbmQpIHtcbiAgICAgIHRoaXMubm9kZS5hcHBlbmRDaGlsZChjaGlsZC5ub2RlKVxuICAgICAgY2hpbGRyZW4ucHVzaChjaGlsZC5kYXRhKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm5vZGUuaW5zZXJ0QmVmb3JlKGNoaWxkLm5vZGUsIGJlZm9yZS5ub2RlKVxuICAgICAgY2hpbGRyZW4uc3BsaWNlKGksIDAsIGNoaWxkLmRhdGEpXG4gICAgfVxuXG4gIH0sXG5cbiAgcmVtb3ZlQ2hpbGQ6IGZ1bmN0aW9uIChjaGlsZCkge1xuICAgIHZhciBjaGlsZHJlbiA9IHRoaXMuZGF0YS5jaGlsZHJlblxuICAgIC8vIHJlbW92ZSBmcm9tIHRoaXMuZGF0YS5jaGlsZHJlblxuICAgIHZhciBpID0gMFxuICAgIHZhciBjb21wb25lbnRNYW5hZ2VyID0gdGhpcy5nZXRDb21wb25lbnRNYW5hZ2VyKClcbiAgICBpZiAoY2hpbGRyZW4gJiYgY2hpbGRyZW4ubGVuZ3RoKSB7XG4gICAgICBmb3IgKHZhciBsID0gY2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgIGlmIChjaGlsZHJlbltpXS5yZWYgPT09IGNoaWxkLmRhdGEucmVmKSB7XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGkgPCBsKSB7XG4gICAgICAgIGNoaWxkcmVuLnNwbGljZShpLCAxKVxuICAgICAgfVxuICAgIH1cbiAgICAvLyByZW1vdmUgZnJvbSBjb21wb25lbnRNYXAgcmVjdXJzaXZlbHlcbiAgICBjb21wb25lbnRNYW5hZ2VyLnJlbW92ZUVsZW1lbnRCeVJlZihjaGlsZC5kYXRhLnJlZilcbiAgICB0aGlzLm5vZGUucmVtb3ZlQ2hpbGQoY2hpbGQubm9kZSlcbiAgfSxcblxuICB1cGRhdGVBdHRyczogZnVuY3Rpb24gKGF0dHJzKSB7XG4gICAgLy8gTm90Ze+8mmF0dHIgbXVzdCBiZSBpbmplY3RlZCBpbnRvIHRoZSBkb20gZWxlbWVudCBiZWNhdXNlXG4gICAgLy8gaXQgd2lsbCBiZSBhY2Nlc3NlZCBmcm9tIHRoZSBvdXRzaWRlIGRldmVsb3BlciBieSBldmVudC50YXJnZXQuYXR0ci5cbiAgICBpZiAoIXRoaXMubm9kZS5hdHRyKSB7XG4gICAgICB0aGlzLm5vZGUuYXR0ciA9IHt9XG4gICAgfVxuICAgIGZvciAodmFyIGtleSBpbiBhdHRycykge1xuICAgICAgdmFyIHZhbHVlID0gYXR0cnNba2V5XVxuICAgICAgdmFyIGF0dHJTZXR0ZXIgPSB0aGlzLmF0dHJba2V5XVxuICAgICAgaWYgKHR5cGVvZiBhdHRyU2V0dGVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGF0dHJTZXR0ZXIuY2FsbCh0aGlzLCB2YWx1ZSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJykge1xuICAgICAgICAgIHRoaXMubm9kZVtrZXldID0gdmFsdWVcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLm5vZGUuc2V0QXR0cmlidXRlKGtleSwgdmFsdWUpXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5ub2RlLmF0dHJba2V5XSA9IHZhbHVlXG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIHVwZGF0ZVN0eWxlOiBmdW5jdGlvbiAoc3R5bGUpIHtcbiAgICBmb3IgKHZhciBrZXkgaW4gc3R5bGUpIHtcbiAgICAgIHZhciB2YWx1ZSA9IHN0eWxlW2tleV1cbiAgICAgIHZhciBzdHlsZVNldHRlciA9IHRoaXMuc3R5bGVba2V5XVxuXG4gICAgICBpZiAodHlwZW9mIHN0eWxlU2V0dGVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHN0eWxlU2V0dGVyLmNhbGwodGhpcywgdmFsdWUpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJ1xuICAgICAgICAgICAgJiYgKGtleSAhPT0gJ2ZsZXgnICYmIGtleSAhPT0gJ29wYWNpdHknICYmIGtleSAhPT0gJ3pJbmRleCcpXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgdmFsdWUgPSB2YWx1ZSAqIHRoaXMuZGF0YS5zY2FsZSArICdweCdcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm5vZGUuc3R5bGVba2V5XSA9IHZhbHVlXG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIGJpbmRFdmVudHM6IGZ1bmN0aW9uIChldnRzKSB7XG4gICAgdmFyIGNvbXBvbmVudE1hbmFnZXIgPSB0aGlzLmdldENvbXBvbmVudE1hbmFnZXIoKVxuICAgIGlmIChldnRzXG4gICAgICAgICYmIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChldnRzKS5zbGljZSg4LCAtMSkgPT09ICdBcnJheSdcbiAgICAgICkge1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBldnRzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICBjb21wb25lbnRNYW5hZ2VyLmFkZEV2ZW50KHRoaXMsIGV2dHNbaV0pXG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIC8vIGRpc3BhdGNoIGEgc3BlY2lmaWVkIGV2ZW50IG9uIHRoaXMubm9kZVxuICAvLyAgLSB0eXBlOiBldmVudCB0eXBlXG4gIC8vICAtIGRhdGE6IGV2ZW50IGRhdGFcbiAgLy8gIC0gY29uZmlnOiBldmVudCBjb25maWcgb2JqZWN0XG4gIC8vICAgICAtIGJ1YmJsZXNcbiAgLy8gICAgIC0gY2FuY2VsYWJsZVxuICBkaXNwYXRjaEV2ZW50OiBmdW5jdGlvbiAodHlwZSwgZGF0YSwgY29uZmlnKSB7XG4gICAgdmFyIGV2ZW50ID0gZG9jdW1lbnQuY3JlYXRlRXZlbnQoJ0hUTUxFdmVudHMnKVxuICAgIGNvbmZpZyA9IGNvbmZpZyB8fCB7fVxuICAgIGV2ZW50LmluaXRFdmVudCh0eXBlLCBjb25maWcuYnViYmxlcyB8fCBmYWxzZSwgY29uZmlnLmNhbmNlbGFibGUgfHwgZmFsc2UpXG4gICAgIWRhdGEgJiYgKGRhdGEgPSB7fSlcbiAgICBldmVudC5kYXRhID0gdXRpbHMuZXh0ZW5kKHt9LCBkYXRhKVxuICAgIHV0aWxzLmV4dGVuZChldmVudCwgZGF0YSlcbiAgICBpZiAodHlwZSA9PT0gJ2FwcGVhcicpIHtcbiAgICAgIGNvbnNvbGUubG9nKCdhcHBlYXInLCBkYXRhKVxuICAgIH1cbiAgICB0aGlzLm5vZGUuZGlzcGF0Y2hFdmVudChldmVudClcbiAgfSxcblxuICB1cGRhdGVSZWN1cnNpdmVBdHRyOiBmdW5jdGlvbiAoZGF0YSkge1xuICAgIHRoaXMudXBkYXRlQXR0cnMoZGF0YS5hdHRyKVxuICAgIHZhciBjb21wb25lbnRNYW5hZ2VyID0gdGhpcy5nZXRDb21wb25lbnRNYW5hZ2VyKClcbiAgICB2YXIgY2hpbGRyZW4gPSB0aGlzLmRhdGEuY2hpbGRyZW5cbiAgICBpZiAoY2hpbGRyZW4pIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGNoaWxkID0gY29tcG9uZW50TWFuYWdlci5nZXRFbGVtZW50QnlSZWYoY2hpbGRyZW5baV0ucmVmKVxuICAgICAgICBpZiAoY2hpbGQpIHtcbiAgICAgICAgICBjaGlsZC51cGRhdGVSZWN1cnNpdmVBdHRyKGRhdGEuY2hpbGRyZW5baV0pXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0sXG5cbiAgdXBkYXRlUmVjdXJzaXZlU3R5bGU6IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgdGhpcy51cGRhdGVTdHlsZShkYXRhLnN0eWxlKVxuICAgIHZhciBjb21wb25lbnRNYW5hZ2VyID0gdGhpcy5nZXRDb21wb25lbnRNYW5hZ2VyKClcbiAgICB2YXIgY2hpbGRyZW4gPSB0aGlzLmRhdGEuY2hpbGRyZW5cbiAgICBpZiAoY2hpbGRyZW4pIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGNoaWxkID0gY29tcG9uZW50TWFuYWdlci5nZXRFbGVtZW50QnlSZWYoY2hpbGRyZW5baV0ucmVmKVxuICAgICAgICBpZiAoY2hpbGQpIHtcbiAgICAgICAgICBjaGlsZC51cGRhdGVSZWN1cnNpdmVTdHlsZShkYXRhLmNoaWxkcmVuW2ldKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIHVwZGF0ZVJlY3Vyc2l2ZUFsbDogZnVuY3Rpb24gKGRhdGEpIHtcbiAgICB0aGlzLnVwZGF0ZUF0dHJzKGRhdGEuYXR0cilcbiAgICB0aGlzLnVwZGF0ZVN0eWxlKGRhdGEuc3R5bGUpXG4gICAgdmFyIGNvbXBvbmVudE1hbmFnZXIgPSB0aGlzLmdldENvbXBvbmVudE1hbmFnZXIoKVxuXG4gICAgLy8gdmFyIG9sZFJlZiA9IHRoaXMuZGF0YS5yZWZcbiAgICAvLyBpZiAoY29tcG9uZW50TWFwW29sZFJlZl0pIHtcbiAgICAvLyAgIGRlbGV0ZSBjb21wb25lbnRNYXBbb2xkUmVmXVxuICAgIC8vIH1cbiAgICAvLyB0aGlzLmRhdGEucmVmID0gZGF0YS5yZWZcbiAgICAvLyBjb21wb25lbnRNYXBbZGF0YS5yZWZdID0gdGhpc1xuXG4gICAgdmFyIGNoaWxkcmVuID0gdGhpcy5kYXRhLmNoaWxkcmVuXG4gICAgaWYgKGNoaWxkcmVuKSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBjaGlsZCA9IGNvbXBvbmVudE1hbmFnZXIuZ2V0RWxlbWVudEJ5UmVmKGNoaWxkcmVuW2ldLnJlZilcbiAgICAgICAgaWYgKGNoaWxkKSB7XG4gICAgICAgICAgY2hpbGQudXBkYXRlUmVjdXJzaXZlQWxsKGRhdGEuY2hpbGRyZW5baV0pXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0sXG5cbiAgYXR0cjoge30sIC8vIGF0dHIgc2V0dGVyc1xuXG4gIHN0eWxlOiBPYmplY3QuY3JlYXRlKGZsZXhib3gpLCAvLyBzdHlsZSBzZXR0ZXJzXG5cbiAgY2xlYXJBdHRyOiBmdW5jdGlvbiAoKSB7XG4gIH0sXG5cbiAgY2xlYXJTdHlsZTogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMubm9kZS5jc3NUZXh0ID0gJydcbiAgfVxufVxuXG5Db21wb25lbnQucHJvdG90eXBlLnN0eWxlLnBvc2l0aW9uID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gIC8vIFRPRE86IG1ha2UgaXQgaW4gYSBkZWNlbnQgaW1wbGVtZW50YXRpb25cbiAgaWYgKHZhbHVlID09PSAnc3RpY2t5Jykge1xuICAgIHRoaXMubm9kZS5zdHlsZS56SW5kZXggPSAxMDBcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoaXMuc3RpY2t5ID0gbmV3IGxpYi5zdGlja3kodGhpcy5ub2RlLCB7XG4gICAgICAgIHRvcDogMFxuICAgICAgfSlcbiAgICB9LmJpbmQodGhpcyksIDApXG4gIH0gZWxzZSB7XG4gICAgdGhpcy5ub2RlLnN0eWxlLnBvc2l0aW9uID0gdmFsdWVcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IENvbXBvbmVudFxuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL3NyYy9jb21wb25lbnRzL2NvbXBvbmVudC5qc1xuICoqIG1vZHVsZSBpZCA9IDE2XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIndXNlIHN0cmljdCdcblxuLy8gRmxleGJveCBwb2x5ZmlsbFxudmFyIGZsZXhib3hTZXR0ZXJzID0gKGZ1bmN0aW9uICgpIHtcbiAgdmFyIEJPWF9BTElHTiA9IHtcbiAgICBzdHJldGNoOiAnc3RyZXRjaCcsXG4gICAgJ2ZsZXgtc3RhcnQnOiAnc3RhcnQnLFxuICAgICdmbGV4LWVuZCc6ICdlbmQnLFxuICAgIGNlbnRlcjogJ2NlbnRlcidcbiAgfVxuICB2YXIgQk9YX09SSUVOVCA9IHtcbiAgICByb3c6ICdob3Jpem9udGFsJyxcbiAgICBjb2x1bW46ICd2ZXJ0aWNhbCdcbiAgfVxuICB2YXIgQk9YX1BBQ0sgPSB7XG4gICAgJ2ZsZXgtc3RhcnQnOiAnc3RhcnQnLFxuICAgICdmbGV4LWVuZCc6ICdlbmQnLFxuICAgIGNlbnRlcjogJ2NlbnRlcicsXG4gICAgJ3NwYWNlLWJldHdlZW4nOiAnanVzdGlmeScsXG4gICAgJ3NwYWNlLWFyb3VuZCc6ICdqdXN0aWZ5JyAvLyBKdXN0IHNhbWUgYXMgYHNwYWNlLWJldHdlZW5gXG4gIH1cbiAgcmV0dXJuIHtcbiAgICBmbGV4OiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgIHRoaXMubm9kZS5zdHlsZS53ZWJraXRCb3hGbGV4ID0gdmFsdWVcbiAgICAgIHRoaXMubm9kZS5zdHlsZS53ZWJraXRGbGV4ID0gdmFsdWVcbiAgICAgIHRoaXMubm9kZS5zdHlsZS5mbGV4ID0gdmFsdWVcbiAgICB9LFxuICAgIGFsaWduSXRlbXM6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgdGhpcy5ub2RlLnN0eWxlLndlYmtpdEJveEFsaWduID0gQk9YX0FMSUdOW3ZhbHVlXVxuICAgICAgdGhpcy5ub2RlLnN0eWxlLndlYmtpdEFsaWduSXRlbXMgPSB2YWx1ZVxuICAgICAgdGhpcy5ub2RlLnN0eWxlLmFsaWduSXRlbXMgPSB2YWx1ZVxuICAgIH0sXG4gICAgYWxpZ25TZWxmOiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgIHRoaXMubm9kZS5zdHlsZS53ZWJraXRBbGlnblNlbGYgPSB2YWx1ZVxuICAgICAgdGhpcy5ub2RlLnN0eWxlLmFsaWduU2VsZiA9IHZhbHVlXG4gICAgfSxcbiAgICBmbGV4RGlyZWN0aW9uOiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgIHRoaXMubm9kZS5zdHlsZS53ZWJraXRCb3hPcmllbnQgPSBCT1hfT1JJRU5UW3ZhbHVlXVxuICAgICAgdGhpcy5ub2RlLnN0eWxlLndlYmtpdEZsZXhEaXJlY3Rpb24gPSB2YWx1ZVxuICAgICAgdGhpcy5ub2RlLnN0eWxlLmZsZXhEaXJlY3Rpb24gPSB2YWx1ZVxuICAgIH0sXG4gICAganVzdGlmeUNvbnRlbnQ6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgdGhpcy5ub2RlLnN0eWxlLndlYmtpdEJveFBhY2sgPSBCT1hfUEFDS1t2YWx1ZV1cbiAgICAgIHRoaXMubm9kZS5zdHlsZS53ZWJraXRKdXN0aWZ5Q29udGVudCA9IHZhbHVlXG4gICAgICB0aGlzLm5vZGUuc3R5bGUuanVzdGlmeUNvbnRlbnQgPSB2YWx1ZVxuICAgIH1cbiAgfVxufSkoKVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZsZXhib3hTZXR0ZXJzXG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL2ZsZXhib3guanNcbiAqKiBtb2R1bGUgaWQgPSAxN1xuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnKSAmJiAod2luZG93ID0ge2N0cmw6IHt9LCBsaWI6IHt9fSk7IXdpbmRvdy5jdHJsICYmICh3aW5kb3cuY3RybCA9IHt9KTshd2luZG93LmxpYiAmJiAod2luZG93LmxpYiA9IHt9KTshZnVuY3Rpb24oYSxiLGMpe2Z1bmN0aW9uIGQoYSl7cmV0dXJuIG51bGwhPWEmJlwib2JqZWN0XCI9PXR5cGVvZiBhJiZPYmplY3QuZ2V0UHJvdG90eXBlT2YoYSk9PU9iamVjdC5wcm90b3R5cGV9ZnVuY3Rpb24gZShhLGIpe3ZhciBjLGQsZSxmPW51bGwsZz0wLGg9ZnVuY3Rpb24oKXtnPURhdGUubm93KCksZj1udWxsLGU9YS5hcHBseShjLGQpfTtyZXR1cm4gZnVuY3Rpb24oKXt2YXIgaT1EYXRlLm5vdygpLGo9Yi0oaS1nKTtyZXR1cm4gYz10aGlzLGQ9YXJndW1lbnRzLDA+PWo/KGNsZWFyVGltZW91dChmKSxmPW51bGwsZz1pLGU9YS5hcHBseShjLGQpKTpmfHwoZj1zZXRUaW1lb3V0KGgsaikpLGV9fWZ1bmN0aW9uIGYoYSl7dmFyIGI9XCJcIjtyZXR1cm4gT2JqZWN0LmtleXMoYSkuZm9yRWFjaChmdW5jdGlvbihjKXtiKz1jK1wiOlwiK2FbY10rXCI7XCJ9KSxifWZ1bmN0aW9uIGcoYSxjKXshYyYmZChhKSYmKGM9YSxhPWMuZWxlbWVudCksYz1jfHx7fSxhLm5vZGVUeXBlIT1iLkVMRU1FTlRfTk9ERSYmXCJzdHJpbmdcIj09dHlwZW9mIGEmJihhPWIucXVlcnlTZWxlY3RvcihhKSk7dmFyIGU9dGhpcztlLmVsZW1lbnQ9YSxlLnRvcD1jLnRvcHx8MCxlLndpdGhpblBhcmVudD12b2lkIDA9PWMud2l0aGluUGFyZW50PyExOmMud2l0aGluUGFyZW50LGUuaW5pdCgpfXZhciBoPWEucGFyc2VJbnQsaT1uYXZpZ2F0b3IudXNlckFnZW50LGo9ISFpLm1hdGNoKC9GaXJlZm94L2kpLGs9ISFpLm1hdGNoKC9JRU1vYmlsZS9pKSxsPWo/XCItbW96LVwiOms/XCItbXMtXCI6XCItd2Via2l0LVwiLG09aj9cIk1velwiOms/XCJtc1wiOlwid2Via2l0XCIsbj1mdW5jdGlvbigpe3ZhciBhPWIuY3JlYXRlRWxlbWVudChcImRpdlwiKSxjPWEuc3R5bGU7cmV0dXJuIGMuY3NzVGV4dD1cInBvc2l0aW9uOlwiK2wrXCJzdGlja3k7cG9zaXRpb246c3RpY2t5O1wiLC0xIT1jLnBvc2l0aW9uLmluZGV4T2YoXCJzdGlja3lcIil9KCk7Zy5wcm90b3R5cGU9e2NvbnN0cnVjdG9yOmcsaW5pdDpmdW5jdGlvbigpe3ZhciBhPXRoaXMsYj1hLmVsZW1lbnQsYz1iLnN0eWxlO2NbbStcIlRyYW5zZm9ybVwiXT1cInRyYW5zbGF0ZVooMClcIixjLnRyYW5zZm9ybT1cInRyYW5zbGF0ZVooMClcIixhLl9vcmlnaW5Dc3NUZXh0PWMuY3NzVGV4dCxuPyhjLnBvc2l0aW9uPWwrXCJzdGlja3lcIixjLnBvc2l0aW9uPVwic3RpY2t5XCIsYy50b3A9YS50b3ArXCJweFwiKTooYS5fc2ltdWxhdGVTdGlja3koKSxhLl9iaW5kUmVzaXplKCkpfSxfYmluZFJlc2l6ZTpmdW5jdGlvbigpe3ZhciBiPXRoaXMsYz0vYW5kcm9pZC9naS50ZXN0KG5hdmlnYXRvci5hcHBWZXJzaW9uKSxkPWIuX3Jlc2l6ZUV2ZW50PVwib25vcmllbnRhdGlvbmNoYW5nZVwiaW4gYT9cIm9yaWVudGF0aW9uY2hhbmdlXCI6XCJyZXNpemVcIixlPWIuX3Jlc2l6ZUhhbmRsZXI9ZnVuY3Rpb24oKXtzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7Yi5yZWZyZXNoKCl9LGM/MjAwOjApfTthLmFkZEV2ZW50TGlzdGVuZXIoZCxlLCExKX0scmVmcmVzaDpmdW5jdGlvbigpe3ZhciBhPXRoaXM7bnx8KGEuX2RldGFjaCgpLGEuX3NpbXVsYXRlU3RpY2t5KCkpfSxfYWRkUGxhY2Vob2xkZXI6ZnVuY3Rpb24oYSl7dmFyIGMsZD10aGlzLGU9ZC5lbGVtZW50LGc9YS5wb3NpdGlvbjtpZigtMSE9W1wic3RhdGljXCIsXCJyZWxhdGl2ZVwiXS5pbmRleE9mKGcpKXtjPWQuX3BsYWNlaG9sZGVyRWxlbWVudD1iLmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7dmFyIGk9aChhLndpZHRoKStoKGEubWFyZ2luTGVmdCkraChhLm1hcmdpblJpZ2h0KSxqPWgoYS5oZWlnaHQpO1wiYm9yZGVyLWJveFwiIT1hLmJveFNpemluZyYmKGkrPWgoYS5ib3JkZXJMZWZ0V2lkdGgpK2goYS5ib3JkZXJSaWdodFdpZHRoKStoKGEucGFkZGluZ0xlZnQpK2goYS5wYWRkaW5nUmlnaHQpLGorPWgoYS5ib3JkZXJUb3BXaWR0aCkraChhLmJvcmRlckJvdHRvbVdpZHRoKStoKGEucGFkZGluZ1RvcCkraChhLnBhZGRpbmdCb3R0b20pKSxjLnN0eWxlLmNzc1RleHQ9Zih7ZGlzcGxheTpcIm5vbmVcIix2aXNpYmlsaXR5OlwiaGlkZGVuXCIsd2lkdGg6aStcInB4XCIsaGVpZ2h0OmorXCJweFwiLG1hcmdpbjowLFwibWFyZ2luLXRvcFwiOmEubWFyZ2luVG9wLFwibWFyZ2luLWJvdHRvbVwiOmEubWFyZ2luQm90dG9tLGJvcmRlcjowLHBhZGRpbmc6MCxcImZsb2F0XCI6YVtcImZsb2F0XCJdfHxhLmNzc0Zsb2F0fSksZS5wYXJlbnROb2RlLmluc2VydEJlZm9yZShjLGUpfXJldHVybiBjfSxfc2ltdWxhdGVTdGlja3k6ZnVuY3Rpb24oKXt2YXIgYz10aGlzLGQ9Yy5lbGVtZW50LGc9Yy50b3AsaT1kLnN0eWxlLGo9ZC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxrPWdldENvbXB1dGVkU3R5bGUoZCxcIlwiKSxsPWQucGFyZW50Tm9kZSxtPWdldENvbXB1dGVkU3R5bGUobCxcIlwiKSxuPWMuX2FkZFBsYWNlaG9sZGVyKGspLG89Yy53aXRoaW5QYXJlbnQscD1jLl9vcmlnaW5Dc3NUZXh0LHE9ai50b3AtZythLnBhZ2VZT2Zmc2V0LHI9bC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5ib3R0b20taChtLnBhZGRpbmdCb3R0b20pLWgobS5ib3JkZXJCb3R0b21XaWR0aCktaChrLm1hcmdpbkJvdHRvbSktai5oZWlnaHQtZythLnBhZ2VZT2Zmc2V0LHM9cCtmKHtwb3NpdGlvbjpcImZpeGVkXCIsdG9wOmcrXCJweFwiLHdpZHRoOmsud2lkdGgsXCJtYXJnaW4tdG9wXCI6MH0pLHQ9cCtmKHtwb3NpdGlvbjpcImFic29sdXRlXCIsdG9wOnIrXCJweFwiLHdpZHRoOmsud2lkdGh9KSx1PTEsdj1jLl9zY3JvbGxIYW5kbGVyPWUoZnVuY3Rpb24oKXt2YXIgYj1hLnBhZ2VZT2Zmc2V0O3E+Yj8xIT11JiYoaS5jc3NUZXh0PXAsbiYmKG4uc3R5bGUuZGlzcGxheT1cIm5vbmVcIiksdT0xKTohbyYmYj49cXx8byYmYj49cSYmcj5iPzIhPXUmJihpLmNzc1RleHQ9cyxuJiYzIT11JiYobi5zdHlsZS5kaXNwbGF5PVwiYmxvY2tcIiksdT0yKTpvJiYzIT11JiYoaS5jc3NUZXh0PXQsbiYmMiE9dSYmKG4uc3R5bGUuZGlzcGxheT1cImJsb2NrXCIpLHU9Myl9LDEwMCk7aWYoYS5hZGRFdmVudExpc3RlbmVyKFwic2Nyb2xsXCIsdiwhMSksYS5wYWdlWU9mZnNldD49cSl7dmFyIHc9Yi5jcmVhdGVFdmVudChcIkhUTUxFdmVudHNcIik7dy5pbml0RXZlbnQoXCJzY3JvbGxcIiwhMCwhMCksYS5kaXNwYXRjaEV2ZW50KHcpfX0sX2RldGFjaDpmdW5jdGlvbigpe3ZhciBiPXRoaXMsYz1iLmVsZW1lbnQ7aWYoYy5zdHlsZS5jc3NUZXh0PWIuX29yaWdpbkNzc1RleHQsIW4pe3ZhciBkPWIuX3BsYWNlaG9sZGVyRWxlbWVudDtkJiZjLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoZCksYS5yZW1vdmVFdmVudExpc3RlbmVyKFwic2Nyb2xsXCIsYi5fc2Nyb2xsSGFuZGxlciwhMSl9fSxkZXN0cm95OmZ1bmN0aW9uKCl7dmFyIGI9dGhpcztiLl9kZXRhY2goKTt2YXIgYz1iLmVsZW1lbnQuc3R5bGU7Yy5yZW1vdmVQcm9wZXJ0eShsK1widHJhbnNmb3JtXCIpLGMucmVtb3ZlUHJvcGVydHkoXCJ0cmFuc2Zvcm1cIiksbnx8YS5yZW1vdmVFdmVudExpc3RlbmVyKGIuX3Jlc2l6ZUV2ZW50LGIuX3Jlc2l6ZUhhbmRsZXIsITEpfX0sYy5zdGlja3k9Z30od2luZG93LGRvY3VtZW50LHdpbmRvdy5saWJ8fCh3aW5kb3cubGliPXt9KSk7O21vZHVsZS5leHBvcnRzID0gd2luZG93LmxpYlsnc3RpY2t5J107XG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vZml4ZWRzdGlja3kvYnVpbGQvc3RpY2t5LmNvbW1vbi5qc1xuICoqIG1vZHVsZSBpZCA9IDE4XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIndXNlIHN0cmljdCdcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKVxuXG52YXIgX3NlbmRlck1hcCA9IHt9XG5cbmZ1bmN0aW9uIFNlbmRlcihpbnN0YW5jZSkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU2VuZGVyKSkge1xuICAgIHJldHVybiBuZXcgU2VuZGVyKGluc3RhbmNlKVxuICB9XG4gIHRoaXMuaW5zdGFuY2VJZCA9IGluc3RhbmNlLmluc3RhbmNlSWRcbiAgdGhpcy53ZWV4SW5zdGFuY2UgPSBpbnN0YW5jZVxuICBfc2VuZGVyTWFwW3RoaXMuaW5zdGFuY2VJZF0gPSB0aGlzXG59XG5cbmZ1bmN0aW9uIF9zZW5kKGluc3RhbmNlSWQsIG1zZykge1xuICBjYWxsSlMoaW5zdGFuY2VJZCwgW21zZ10pXG59XG5cblNlbmRlci5nZXRTZW5kZXIgPSBmdW5jdGlvbiAoaW5zdGFuY2VJZCkge1xuICByZXR1cm4gX3NlbmRlck1hcFtpbnN0YW5jZUlkXVxufVxuXG5TZW5kZXIucHJvdG90eXBlID0ge1xuXG4gIC8vIHBlcmZvcm0gYSBjYWxsYmFjayB0byBqc2ZyYW1ld29yay5cbiAgcGVyZm9ybUNhbGxiYWNrOiBmdW5jdGlvbiAoY2FsbGJhY2tJZCwgZGF0YSkge1xuICAgIHZhciBhcmdzID0gW2NhbGxiYWNrSWRdXG4gICAgZGF0YSAmJiBhcmdzLnB1c2goZGF0YSlcbiAgICBfc2VuZCh0aGlzLmluc3RhbmNlSWQsIHtcbiAgICAgIG1ldGhvZDogJ2NhbGxiYWNrJyxcbiAgICAgIGFyZ3M6IGFyZ3NcbiAgICB9KVxuICB9LFxuXG4gIGZpcmVFdmVudDogZnVuY3Rpb24gKHJlZiwgdHlwZSwgZXZlbnQpIHtcbiAgICAvLyBOb3RlIHRoYXQgdGhlIGV2ZW50LnRhcmdldCBtdXN0IGJlIHRoZSBzdGFuZGFyZCBldmVudCdzXG4gICAgLy8gY3VycmVudFRhcmdldC4gVGhlcmVmb3IgYSBwcm9jZXNzIGZvciByZXBsYWNpbmcgdGFyZ2V0IG11c3RcbiAgICAvLyBiZSBkb25lIHdoZW4gYSBldmVudCBpcyBmaXJlZC5cbiAgICB2YXIgZXZ0ID0gdXRpbHMuZXh0ZW5kKHt9LCBldmVudClcbiAgICBldnQudGFyZ2V0ID0gZXZ0LmN1cnJlbnRUYXJnZXRcbiAgICBldnQudmFsdWUgPSBldmVudC50YXJnZXQudmFsdWVcbiAgICBldnQudGltZXN0YW1wID0gRGF0ZS5ub3coKVxuICAgIF9zZW5kKHRoaXMuaW5zdGFuY2VJZCwge1xuICAgICAgbWV0aG9kOiAnZmlyZUV2ZW50JyxcbiAgICAgIGFyZ3M6IFtyZWYsIHR5cGUsIGV2dF1cbiAgICB9KVxuICB9XG5cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBTZW5kZXJcblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL2JyaWRnZS9zZW5kZXIuanNcbiAqKiBtb2R1bGUgaWQgPSAxOVxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnZhciBjb25maWcgPSByZXF1aXJlKCcuLi9jb25maWcnKVxudmFyIHByb3RvY29sID0gcmVxdWlyZSgnLi4vcHJvdG9jb2wnKVxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKVxudmFyIEZyYW1lVXBkYXRlciA9IHJlcXVpcmUoJy4uL2ZyYW1lVXBkYXRlcicpXG52YXIgU2VuZGVyID0gcmVxdWlyZSgnLi9zZW5kZXInKVxuXG52YXIgY2FsbFF1ZXVlID0gW11cbi8vIE5lZWQgYSB0YXNrIGNvdW50ZXI/XG4vLyBXaGVuIEZyYW1lVXBkYXRlciBpcyBub3QgYWN0aXZhdGVkLCB0YXNrcyB3aWxsIG5vdCBiZSBwdXNoXG4vLyBpbnRvIGNhbGxRdWV1ZSBhbmQgdGhlcmUgd2lsbCBiZSBubyB0cmFjZSBmb3Igc2l0dWF0aW9uIG9mXG4vLyBleGVjdXRpb24gb2YgdGFza3MuXG5cbi8vIGdpdmUgMTBtcyBmb3IgY2FsbCBoYW5kbGluZywgYW5kIHJlc3QgNm1zIGZvciBvdGhlcnNcbnZhciBNQVhfVElNRV9GT1JfRUFDSF9GUkFNRSA9IDEwXG5cbi8vIGNhbGxOYXRpdmU6IGpzRnJhbWV3b3JrIHdpbGwgY2FsbCB0aGlzIG1ldGhvZCB0byB0YWxrIHRvXG4vLyB0aGlzIHJlbmRlcmVyLlxuLy8gcGFyYW1zOlxuLy8gIC0gaW5zdGFuY2VJZDogc3RyaW5nLlxuLy8gIC0gdGFza3M6IGFycmF5IG9mIG9iamVjdC5cbi8vICAtIGNhbGxiYWNrSWQ6IG51bWJlci5cbmZ1bmN0aW9uIGNhbGxOYXRpdmUoaW5zdGFuY2VJZCwgdGFza3MsIGNhbGxiYWNrSWQpIHtcbiAgdmFyIGNhbGxzID0gW11cbiAgaWYgKHR5cGVvZiB0YXNrcyA9PT0gJ3N0cmluZycpIHtcbiAgICB0cnkge1xuICAgICAgY2FsbHMgPSBKU09OLnBhcnNlKHRhc2tzKVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ2ludmFsaWQgdGFza3M6JywgdGFza3MpXG4gICAgfVxuICB9IGVsc2UgaWYgKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh0YXNrcykuc2xpY2UoOCwgLTEpID09PSAnQXJyYXknKSB7XG4gICAgY2FsbHMgPSB0YXNrc1xuICB9XG4gIHZhciBsZW4gPSBjYWxscy5sZW5ndGhcbiAgY2FsbHNbbGVuIC0gMV0uY2FsbGJhY2tJZCA9ICghY2FsbGJhY2tJZCAmJiBjYWxsYmFja0lkICE9PSAwKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAtMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBjYWxsYmFja0lkXG4gIC8vIFRvIHNvbHZlIHRoZSBwcm9ibGVtIG9mIGNhbGxhcHAsIHRoZSB0d28td2F5IHRpbWUgbG9vcCBydWxlIG11c3RcbiAgLy8gYmUgcmVwbGFjZWQgYnkgY2FsbGluZyBkaXJlY3RseSBleGNlcHQgdGhlIHNpdHVhdGlvbiBvZiBwYWdlIGxvYWRpbmcuXG4gIC8vIDIwMTUtMTEtMDNcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgIGlmIChGcmFtZVVwZGF0ZXIuaXNBY3RpdmUoKSkge1xuICAgICAgY2FsbFF1ZXVlLnB1c2goe1xuICAgICAgICBpbnN0YW5jZUlkOiBpbnN0YW5jZUlkLFxuICAgICAgICBjYWxsOiBjYWxsc1tpXVxuICAgICAgfSlcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBwcm9jZXNzQ2FsbChpbnN0YW5jZUlkLCBjYWxsc1tpXSlcbiAgICB9XG4gIH1cblxufVxuXG5mdW5jdGlvbiBwcm9jZXNzQ2FsbFF1ZXVlKCkge1xuICB2YXIgbGVuID0gY2FsbFF1ZXVlLmxlbmd0aFxuICBpZiAobGVuID09PSAwKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgdmFyIHN0YXJ0ID0gRGF0ZS5ub3coKVxuICB2YXIgZWxhcHNlZCA9IDBcblxuICB3aGlsZSAoLS1sZW4gPj0gMCAmJiBlbGFwc2VkIDwgTUFYX1RJTUVfRk9SX0VBQ0hfRlJBTUUpIHtcbiAgICB2YXIgY2FsbE9iaiA9IGNhbGxRdWV1ZS5zaGlmdCgpXG4gICAgcHJvY2Vzc0NhbGwoY2FsbE9iai5pbnN0YW5jZUlkLCBjYWxsT2JqLmNhbGwpXG4gICAgZWxhcHNlZCA9IERhdGUubm93KCkgLSBzdGFydFxuICB9XG59XG5cbmZ1bmN0aW9uIHByb2Nlc3NDYWxsKGluc3RhbmNlSWQsIGNhbGwpIHtcbiAgdmFyIG1vZHVsZU5hbWUgPSBjYWxsLm1vZHVsZVxuICB2YXIgbWV0aG9kTmFtZSA9IGNhbGwubWV0aG9kXG4gIHZhciBtb2R1bGUsIG1ldGhvZFxuICB2YXIgYXJncyA9IGNhbGwuYXJncyB8fCBjYWxsLmFyZ3VtZW50cyB8fCBbXVxuXG4gIGlmICghKG1vZHVsZSA9IHByb3RvY29sLmFwaU1vZHVsZVttb2R1bGVOYW1lXSkpIHtcbiAgICByZXR1cm5cbiAgfVxuICBpZiAoIShtZXRob2QgPSBtb2R1bGVbbWV0aG9kTmFtZV0pKSB7XG4gICAgcmV0dXJuXG4gIH1cblxuICBtZXRob2QuYXBwbHkocHJvdG9jb2wuZ2V0V2VleEluc3RhbmNlKGluc3RhbmNlSWQpLCBhcmdzKVxuXG4gIHZhciBjYWxsYmFja0lkID0gY2FsbC5jYWxsYmFja0lkXG4gIGlmICgoY2FsbGJhY2tJZFxuICAgIHx8IGNhbGxiYWNrSWQgPT09IDBcbiAgICB8fCBjYWxsYmFja0lkID09PSAnMCcpXG4gICAgJiYgY2FsbGJhY2tJZCAhPT0gJy0xJ1xuICAgICYmIGNhbGxiYWNrSWQgIT09IC0xKSB7XG4gICAgcGVyZm9ybU5leHRUaWNrKGluc3RhbmNlSWQsIGNhbGxiYWNrSWQpXG4gIH1cbn1cblxuZnVuY3Rpb24gcGVyZm9ybU5leHRUaWNrKGluc3RhbmNlSWQsIGNhbGxiYWNrSWQpIHtcbiAgU2VuZGVyLmdldFNlbmRlcihpbnN0YW5jZUlkKS5wZXJmb3JtQ2FsbGJhY2soY2FsbGJhY2tJZClcbn1cblxuZnVuY3Rpb24gbmF0aXZlTG9nKCkge1xuICBpZiAoY29uZmlnLmRlYnVnKSB7XG4gICAgaWYgKGFyZ3VtZW50c1swXS5tYXRjaCgvXnBlcmYvKSkge1xuICAgICAgY29uc29sZS5pbmZvLmFwcGx5KGNvbnNvbGUsIGFyZ3VtZW50cylcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBjb25zb2xlLmRlYnVnLmFwcGx5KGNvbnNvbGUsIGFyZ3VtZW50cylcbiAgfVxufVxuXG5mdW5jdGlvbiBleHBvcnRzQnJpZGdlTWV0aG9kc1RvR2xvYmFsKCkge1xuICBnbG9iYWwuY2FsbE5hdGl2ZSA9IGNhbGxOYXRpdmVcbiAgZ2xvYmFsLm5hdGl2ZUxvZyA9IG5hdGl2ZUxvZ1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblxuICBpbml0OiBmdW5jdGlvbiAoKSB7XG5cbiAgICAvLyBwcm9jZXNzIGNhbGxRdWV1ZSBldmVyeSAxNiBtaWxsaXNlY29uZHMuXG4gICAgRnJhbWVVcGRhdGVyLmFkZFVwZGF0ZU9ic2VydmVyKHByb2Nlc3NDYWxsUXVldWUpXG4gICAgRnJhbWVVcGRhdGVyLnN0YXJ0KClcblxuICAgIC8vIGV4cG9ydHMgbWV0aG9kcyB0byBnbG9iYWwod2luZG93KS5cbiAgICBleHBvcnRzQnJpZGdlTWV0aG9kc1RvR2xvYmFsKClcbiAgfVxuXG59XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL2JyaWRnZS9yZWNlaXZlci5qc1xuICoqIG1vZHVsZSBpZCA9IDIwXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgUm9vdENvbXBvbmVudCA9IHJlcXVpcmUoJy4vcm9vdCcpXG52YXIgQ29udGFpbmVyID0gcmVxdWlyZSgnLi9jb250YWluZXInKVxudmFyIEltYWdlID0gcmVxdWlyZSgnLi9pbWFnZScpXG52YXIgVGV4dCA9IHJlcXVpcmUoJy4vdGV4dCcpXG52YXIgTGlzdCA9IHJlcXVpcmUoJy4vbGlzdCcpXG52YXIgQ291bnRkb3duID0gcmVxdWlyZSgnLi9jb3VudGRvd24nKVxudmFyIE1hcnF1ZWUgPSByZXF1aXJlKCcuL21hcnF1ZWUnKVxudmFyIFNsaWRlciA9IHJlcXVpcmUoJy4vc2xpZGVyJylcbnZhciBJbmRpY2F0b3IgPSByZXF1aXJlKCcuL2luZGljYXRvcicpXG52YXIgVGFiaGVhZGVyID0gcmVxdWlyZSgnLi90YWJoZWFkZXInKVxudmFyIFNjcm9sbGVyID0gcmVxdWlyZSgnLi9zY3JvbGxlcicpXG52YXIgSW5wdXQgPSByZXF1aXJlKCcuL2lucHV0JylcbnZhciBTZWxlY3QgPSByZXF1aXJlKCcuL3NlbGVjdCcpXG52YXIgRGF0ZXBpY2tlciA9IHJlcXVpcmUoJy4vZGF0ZXBpY2tlcicpXG52YXIgVGltZXBpY2tlciA9IHJlcXVpcmUoJy4vdGltZXBpY2tlcicpXG52YXIgVmlkZW8gPSByZXF1aXJlKCcuL3ZpZGVvJylcbnZhciBTd2l0Y2ggPSByZXF1aXJlKCcuL3N3aXRjaCcpXG52YXIgQSA9IHJlcXVpcmUoJy4vYScpXG52YXIgRW1iZWQgPSByZXF1aXJlKCcuL2VtYmVkJylcblxudmFyIGNvbXBvbmVudHMgPSB7XG4gIGluaXQ6IGZ1bmN0aW9uIChXZWV4KSB7XG4gICAgV2VleC5yZWdpc3RlckNvbXBvbmVudCgncm9vdCcsIFJvb3RDb21wb25lbnQpXG4gICAgV2VleC5yZWdpc3RlckNvbXBvbmVudCgncm9vdCcsIFJvb3RDb21wb25lbnQpXG4gICAgV2VleC5yZWdpc3RlckNvbXBvbmVudCgnY29udGFpbmVyJywgQ29udGFpbmVyKVxuICAgIFdlZXgucmVnaXN0ZXJDb21wb25lbnQoJ2ltYWdlJywgSW1hZ2UpXG4gICAgV2VleC5yZWdpc3RlckNvbXBvbmVudCgndGV4dCcsIFRleHQpXG4gICAgV2VleC5yZWdpc3RlckNvbXBvbmVudCgnbGlzdCcsIExpc3QpXG4gICAgV2VleC5yZWdpc3RlckNvbXBvbmVudCgnY291bnRkb3duJywgQ291bnRkb3duKVxuICAgIFdlZXgucmVnaXN0ZXJDb21wb25lbnQoJ21hcnF1ZWUnLCBNYXJxdWVlKVxuICAgIFdlZXgucmVnaXN0ZXJDb21wb25lbnQoJ3NsaWRlcicsIFNsaWRlcilcbiAgICBXZWV4LnJlZ2lzdGVyQ29tcG9uZW50KCdpbmRpY2F0b3InLCBJbmRpY2F0b3IpXG4gICAgV2VleC5yZWdpc3RlckNvbXBvbmVudCgndGFiaGVhZGVyJywgVGFiaGVhZGVyKVxuICAgIFdlZXgucmVnaXN0ZXJDb21wb25lbnQoJ3Njcm9sbGVyJywgU2Nyb2xsZXIpXG4gICAgV2VleC5yZWdpc3RlckNvbXBvbmVudCgnaW5wdXQnLCBJbnB1dClcbiAgICBXZWV4LnJlZ2lzdGVyQ29tcG9uZW50KCdzZWxlY3QnLCBTZWxlY3QpXG4gICAgV2VleC5yZWdpc3RlckNvbXBvbmVudCgnZGF0ZXBpY2tlcicsIERhdGVwaWNrZXIpXG4gICAgV2VleC5yZWdpc3RlckNvbXBvbmVudCgndGltZXBpY2tlcicsIFRpbWVwaWNrZXIpXG4gICAgV2VleC5yZWdpc3RlckNvbXBvbmVudCgndmlkZW8nLCBWaWRlbylcbiAgICBXZWV4LnJlZ2lzdGVyQ29tcG9uZW50KCdzd2l0Y2gnLCBTd2l0Y2gpXG4gICAgV2VleC5yZWdpc3RlckNvbXBvbmVudCgnYScsIEEpXG4gICAgV2VleC5yZWdpc3RlckNvbXBvbmVudCgnZW1iZWQnLCBFbWJlZClcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNvbXBvbmVudHNcblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL2NvbXBvbmVudHMvaW5kZXguanNcbiAqKiBtb2R1bGUgaWQgPSAyMVxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnZhciBDb21wb25lbnRNYW5hZ2VyID0gcmVxdWlyZSgnLi4vY29tcG9uZW50TWFuYWdlcicpXG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi9jb21wb25lbnQnKVxuXG4vLyBJZiBub2RlVHlwZSBpcyBpbiB0aGlzIFdISVRFX0xJU1QsIGp1c3QgaWdub3JlIGl0IGFuZFxuLy8gcmVwbGFjZSBpdCB3aXRoIGEgZGl2IGVsZW1lbnQuXG52YXIgV0hJVEVfTElTVCA9IFtdXG5cbmZ1bmN0aW9uIFJvb3RDb21wb25lbnQoZGF0YSwgbm9kZVR5cGUpIHtcbiAgdmFyIGlkID0gZGF0YS5yb290SWQgKyAnLXJvb3QnXG4gIHZhciBjb21wb25lbnRNYW5hZ2VyID0gQ29tcG9uZW50TWFuYWdlci5nZXRJbnN0YW5jZShkYXRhLmluc3RhbmNlSWQpXG5cbiAgLy8gUmV0dXJuIGEgTm9kZVR5cGUgaW5zdGFuY2UuXG4gIGlmIChub2RlVHlwZSAmJiBub2RlVHlwZSAhPT0gJ2RpdicgJiYgV0hJVEVfTElTVC5pbmRleE9mKG5vZGVUeXBlKSA9PT0gLTEpIHtcbiAgICBkYXRhLnR5cGUgPSBub2RlVHlwZVxuICAgIHZhciBjbXAgPSBjb21wb25lbnRNYW5hZ2VyLmNyZWF0ZUVsZW1lbnQoZGF0YSlcbiAgICBjbXAubm9kZS5pZCA9IGlkXG4gICAgcmV0dXJuIGNtcFxuICB9XG5cbiAgLy8gT3RoZXJ3aXNlIHJldHVybiBhIGNvbW1vbiB3ZWV4LWNvbnRhaW5lciBjb21wb25lbnQsXG4gIC8vIHdob3NlIG5vZGUgaXMgYSBkaXYgZWxlbWVudC5cbiAgdmFyIG5vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKVxuICB0aGlzLmRhdGEgPSBkYXRhXG4gIHRoaXMubm9kZSA9IG5vZGVcblxuICB0aGlzLmNyZWF0ZUNoaWxkcmVuKClcbiAgdGhpcy51cGRhdGVBdHRycyh0aGlzLmRhdGEuYXR0cilcbiAgLy8gaXNzdWU6IHdoZW4gYWRkIGVsZW1lbnQgdG8gYSBsaXN0IGluIGxpZmV0aW1lIGhvb2sgJ3JlYWR5JywgdGhlXG4gIC8vIHN0eWxlcyBpcyBzZXQgdG8gdGhlIGNsYXNzU3R5bGUsIG5vdCBzdHlsZS4gVGhpcyBpcyBhIGlzc3VlXG4gIC8vIHRoYXQganNmcmFtZXdvcmsgc2hvdWxkIGRvIHNvbWV0aGluZyBhYm91dC5cbiAgdmFyIGNsYXNzU3R5bGUgPSB0aGlzLmRhdGEuY2xhc3NTdHlsZVxuICBjbGFzc1N0eWxlICYmIHRoaXMudXBkYXRlU3R5bGUodGhpcy5kYXRhLmNsYXNzU3R5bGUpXG4gIHRoaXMudXBkYXRlU3R5bGUodGhpcy5kYXRhLnN0eWxlKVxuICB0aGlzLmJpbmRFdmVudHModGhpcy5kYXRhLmV2ZW50KVxufVxuXG5Sb290Q29tcG9uZW50LnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoQ29tcG9uZW50LnByb3RvdHlwZSlcblxubW9kdWxlLmV4cG9ydHMgPSBSb290Q29tcG9uZW50XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL2NvbXBvbmVudHMvcm9vdC5qc1xuICoqIG1vZHVsZSBpZCA9IDIyXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIndXNlIHN0cmljdCdcblxucmVxdWlyZSgnLi4vc3R5bGVzL2NvbnRhaW5lci5zY3NzJylcblxudmFyIENvbXBvbmVudCA9IHJlcXVpcmUoJy4vY29tcG9uZW50JylcblxuZnVuY3Rpb24gQ29udGFpbmVyIChkYXRhLCBub2RlVHlwZSkge1xuICBDb21wb25lbnQuY2FsbCh0aGlzLCBkYXRhLCBub2RlVHlwZSlcbiAgdGhpcy5ub2RlLmNsYXNzTGlzdC5hZGQoJ3dlZXgtY29udGFpbmVyJylcbn1cblxuQ29udGFpbmVyLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoQ29tcG9uZW50LnByb3RvdHlwZSlcblxubW9kdWxlLmV4cG9ydHMgPSBDb250YWluZXJcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvY29tcG9uZW50cy9jb250YWluZXIuanNcbiAqKiBtb2R1bGUgaWQgPSAyM1xuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLy8gc3R5bGUtbG9hZGVyOiBBZGRzIHNvbWUgY3NzIHRvIHRoZSBET00gYnkgYWRkaW5nIGEgPHN0eWxlPiB0YWdcblxuLy8gbG9hZCB0aGUgc3R5bGVzXG52YXIgY29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vbm9kZV9tb2R1bGVzL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL2NvbnRhaW5lci5zY3NzXCIpO1xuaWYodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSBjb250ZW50ID0gW1ttb2R1bGUuaWQsIGNvbnRlbnQsICcnXV07XG4vLyBhZGQgdGhlIHN0eWxlcyB0byB0aGUgRE9NXG52YXIgdXBkYXRlID0gcmVxdWlyZShcIiEuLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvYWRkU3R5bGVzLmpzXCIpKGNvbnRlbnQsIHt9KTtcbmlmKGNvbnRlbnQubG9jYWxzKSBtb2R1bGUuZXhwb3J0cyA9IGNvbnRlbnQubG9jYWxzO1xuLy8gSG90IE1vZHVsZSBSZXBsYWNlbWVudFxuaWYobW9kdWxlLmhvdCkge1xuXHQvLyBXaGVuIHRoZSBzdHlsZXMgY2hhbmdlLCB1cGRhdGUgdGhlIDxzdHlsZT4gdGFnc1xuXHRpZighY29udGVudC5sb2NhbHMpIHtcblx0XHRtb2R1bGUuaG90LmFjY2VwdChcIiEhLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi9ub2RlX21vZHVsZXMvc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vY29udGFpbmVyLnNjc3NcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbmV3Q29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vbm9kZV9tb2R1bGVzL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL2NvbnRhaW5lci5zY3NzXCIpO1xuXHRcdFx0aWYodHlwZW9mIG5ld0NvbnRlbnQgPT09ICdzdHJpbmcnKSBuZXdDb250ZW50ID0gW1ttb2R1bGUuaWQsIG5ld0NvbnRlbnQsICcnXV07XG5cdFx0XHR1cGRhdGUobmV3Q29udGVudCk7XG5cdFx0fSk7XG5cdH1cblx0Ly8gV2hlbiB0aGUgbW9kdWxlIGlzIGRpc3Bvc2VkLCByZW1vdmUgdGhlIDxzdHlsZT4gdGFnc1xuXHRtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24oKSB7IHVwZGF0ZSgpOyB9KTtcbn1cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL3N0eWxlcy9jb250YWluZXIuc2Nzc1xuICoqIG1vZHVsZSBpZCA9IDI0XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikoKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIi53ZWV4LWNvbnRhaW5lciB7XFxuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xcbiAgZGlzcGxheTogLXdlYmtpdC1ib3g7XFxuICBkaXNwbGF5OiAtd2Via2l0LWZsZXg7XFxuICBkaXNwbGF5OiBmbGV4O1xcbiAgLXdlYmtpdC1ib3gtb3JpZW50OiB2ZXJ0aWNhbDtcXG4gIC13ZWJraXQtZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcXG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XFxuICBwb3NpdGlvbjogcmVsYXRpdmU7XFxuICBib3JkZXI6IDAgc29saWQgYmxhY2s7XFxuICBtYXJnaW46IDA7XFxuICBwYWRkaW5nOiAwOyB9XFxuXFxuLndlZXgtZWxlbWVudCB7XFxuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xcbiAgcG9zaXRpb246IHJlbGF0aXZlOyB9XFxuXCIsIFwiXCIsIHtcInZlcnNpb25cIjozLFwic291cmNlc1wiOltcIi8uL3NyYy9zcmMvc3R5bGVzL2NvbnRhaW5lci5zY3NzXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCJBQUFBO0VBQ0UsdUJBQXNCO0VBQ3RCLHFCQUFvQjtFQUNwQixzQkFBcUI7RUFDckIsY0FBYTtFQUNiLDZCQUE0QjtFQUM1QiwrQkFBOEI7RUFDOUIsdUJBQXNCO0VBQ3RCLG1CQUFrQjtFQUNsQixzQkFBcUI7RUFDckIsVUFBUztFQUNULFdBQ0QsRUFBQzs7QUFFRjtFQUNFLHVCQUF1QjtFQUN2QixtQkFBbUIsRUFDcEJcIixcImZpbGVcIjpcImNvbnRhaW5lci5zY3NzXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIi53ZWV4LWNvbnRhaW5lciB7XFxuICBib3gtc2l6aW5nOmJvcmRlci1ib3g7XFxuICBkaXNwbGF5Oi13ZWJraXQtYm94O1xcbiAgZGlzcGxheTotd2Via2l0LWZsZXg7XFxuICBkaXNwbGF5OmZsZXg7XFxuICAtd2Via2l0LWJveC1vcmllbnQ6dmVydGljYWw7XFxuICAtd2Via2l0LWZsZXgtZGlyZWN0aW9uOmNvbHVtbjtcXG4gIGZsZXgtZGlyZWN0aW9uOmNvbHVtbjtcXG4gIHBvc2l0aW9uOnJlbGF0aXZlO1xcbiAgYm9yZGVyOjAgc29saWQgYmxhY2s7XFxuICBtYXJnaW46MDtcXG4gIHBhZGRpbmc6MFxcbn1cXG5cXG4ud2VleC1lbGVtZW50IHtcXG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XFxuICBwb3NpdGlvbjogcmVsYXRpdmU7XFxufVwiXSxcInNvdXJjZVJvb3RcIjpcIndlYnBhY2s6Ly9cIn1dKTtcblxuLy8gZXhwb3J0c1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi9+L3Nhc3MtbG9hZGVyP3NvdXJjZU1hcCEuL3NyYy9zdHlsZXMvY29udGFpbmVyLnNjc3NcbiAqKiBtb2R1bGUgaWQgPSAyNVxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnZhciBBdG9taWMgPSByZXF1aXJlKCcuL2F0b21pYycpXG52YXIgTGF6eUxvYWQgPSByZXF1aXJlKCcuLi9sYXp5TG9hZCcpXG52YXIgY29uZmlnID0gcmVxdWlyZSgnLi4vY29uZmlnJylcblxudmFyIERFRkFVTFRfU0laRSA9IDIwMFxudmFyIFJFU0laRV9NT0RFUyA9IFsnY292ZXInLCAnY29udGFpbiddIC8vIG5vdCB0ZW1wb3JhcmlseSBzdXBwb3J0ZWRcblxuLyoqXG4gKiByZXNpemU9Y292ZXJ8Y29udGFpbnxzdHJldGNoIHYxLjQgdGVtcG9yYXJpbHkgbm90IHN1cHBvcnRlZFxuICogc3JjPXVybFxuICovXG5cbmZ1bmN0aW9uIEltYWdlIChkYXRhKSB7XG4gIHRoaXMud2lkdGggPSBkYXRhLnN0eWxlICYmIGRhdGEuc3R5bGUud2lkdGhcbiAgICAgICAgICAgICAgID8gKGRhdGEuc3R5bGUud2lkdGggKyAnJykucmVwbGFjZSgvW15cXGRdL2csICcnKVxuICAgICAgICAgICAgICAgOiBERUZBVUxUX1NJWkVcbiAgdGhpcy5oZWlnaHQgPSBkYXRhLnN0eWxlICYmIGRhdGEuc3R5bGUuaGVpZ2h0XG4gICAgICAgICAgICAgICA/IChkYXRhLnN0eWxlLmhlaWdodCArICcnKS5yZXBsYWNlKC9bXlxcZF0vZywgJycpXG4gICAgICAgICAgICAgICA6IERFRkFVTFRfU0laRVxuICB0aGlzLndpZHRoICo9IGRhdGEuc2NhbGVcbiAgdGhpcy5oZWlnaHQgKj0gZGF0YS5zY2FsZVxuICB2YXIgbW9kZVxuICB2YXIgYXR0ciA9IGRhdGEuYXR0clxuICBhdHRyICYmIChtb2RlID0gYXR0ci5yZXNpemUgfHwgYXR0ci5yZXNpemVNb2RlKVxuICBpZiAoUkVTSVpFX01PREVTLmluZGV4T2YobW9kZSkgIT09IC0xKSB7XG4gICAgdGhpcy5tb2RlID0gbW9kZVxuICAgIC8vIFRPRE86IHJlc2l6ZS1tb2RlIGlzIG5vdCB0ZW1wb3JhcmlseSBzdXBwb3J0ZWQuXG4gIH1cbiAgQXRvbWljLmNhbGwodGhpcywgZGF0YSlcbn1cblxuSW1hZ2UucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShBdG9taWMucHJvdG90eXBlKVxuXG5JbWFnZS5wcm90b3R5cGUuY3JlYXRlID0gZnVuY3Rpb24gKCkge1xuICB2YXIgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2ltZycpXG4gIG5vZGUuY2xhc3NMaXN0LmFkZCgnd2VleC1lbGVtZW50JylcbiAgbm9kZS5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJ1xuICBub2RlLnN0eWxlLm91dGxpbmUgPSAnbm9uZSdcbiAgcmV0dXJuIG5vZGVcbn1cblxuSW1hZ2UucHJvdG90eXBlLmF0dHIgPSB7XG4gIHNyYzogZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgaWYgKCF0aGlzLm5vZGUuc3JjKSB7XG4gICAgICB0aGlzLm5vZGUuc3JjID0gbGliLmltZy5kZWZhdWx0U3JjXG4gICAgfVxuICAgIExhenlMb2FkLm1ha2VJbWFnZUxhenkodGhpcy5ub2RlLCB2YWx1ZSlcbiAgfVxufVxuXG5JbWFnZS5wcm90b3R5cGUuY2xlYXJBdHRyID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLm5vZGUuc3JjID0gJydcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBJbWFnZVxuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL3NyYy9jb21wb25lbnRzL2ltYWdlLmpzXG4gKiogbW9kdWxlIGlkID0gMjZcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIid1c2Ugc3RyaWN0J1xuXG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi9jb21wb25lbnQnKVxuXG4vLyBDb21wb25lbnQgd2hpY2ggY2FuIGhhdmUgbm8gc3ViY29tcG9uZW50cy5cbi8vIFRoaXMgY29tcG9uZW50IHNob3VsZCBub3QgYmUgaW5zdGFudGlhdGVkIGRpcmVjdGx5LCBzaW5jZVxuLy8gaXQgaXMgZGVzaWduZWQgdG8gYmUgdXNlZCBhcyBhIGJhc2UgY2xhc3MgdG8gZXh0ZW5kIGZyb20uXG5mdW5jdGlvbiBBdG9taWMgKGRhdGEpIHtcbiAgQ29tcG9uZW50LmNhbGwodGhpcywgZGF0YSlcbn1cblxuQXRvbWljLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoQ29tcG9uZW50LnByb3RvdHlwZSlcblxuQXRvbWljLnByb3RvdHlwZS5hcHBlbmRDaGlsZCA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIC8vIGRvIG5vdGhpbmdcbiAgcmV0dXJuXG59XG5cbkF0b21pYy5wcm90b3R5cGUuaW5zZXJ0QmVmb3JlID0gZnVuY3Rpb24gKGNoaWxkLCBiZWZvcmUpIHtcbiAgLy8gZG8gbm90aGluZ1xuICByZXR1cm5cbn1cblxuQXRvbWljLnByb3RvdHlwZS5yZW1vdmVDaGlsZCA9IGZ1bmN0aW9uIChjaGlsZCkge1xuICAvLyBkbyBub3RoaW5nXG4gIHJldHVyblxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEF0b21pY1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL3NyYy9jb21wb25lbnRzL2F0b21pYy5qc1xuICoqIG1vZHVsZSBpZCA9IDI3XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIndXNlIHN0cmljdCdcblxudmFyIEF0b21pYyA9IHJlcXVpcmUoJy4vY29tcG9uZW50JylcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJylcblxudmFyIERFRkFVTFRfRk9OVF9TSVpFID0gMzJcblxuLy8gYXR0clxuLy8gIC0gdmFsdWU6IHRleHQgY29udGVudC5cbi8vICAtIGxpbmVzOiBtYXhpbXVtIGxpbmVzIG9mIHRoZSB0ZXh0LlxuZnVuY3Rpb24gVGV4dCAoZGF0YSkge1xuICBBdG9taWMuY2FsbCh0aGlzLCBkYXRhKVxufVxuXG5UZXh0LnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoQXRvbWljLnByb3RvdHlwZSlcblxuVGV4dC5wcm90b3R5cGUuY3JlYXRlID0gZnVuY3Rpb24gKCkge1xuICB2YXIgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gIG5vZGUuY2xhc3NMaXN0LmFkZCgnd2VleC1jb250YWluZXInKVxuICBub2RlLnN0eWxlLmZvbnRTaXplID0gREVGQVVMVF9GT05UX1NJWkUgKiB0aGlzLmRhdGEuc2NhbGUgKyAncHgnXG4gIHRoaXMudGV4dE5vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJylcbiAgLy8gR2l2ZSB0aGUgZGV2ZWxvcGVycyB0aGUgYWJpbGl0eSB0byBjb250cm9sIHNwYWNlXG4gIC8vIGFuZCBsaW5lLWJyZWFrZXJzLlxuICB0aGlzLnRleHROb2RlLnN0eWxlLndoaXRlU3BhY2UgPSAncHJlLXdyYXAnXG4gIHRoaXMudGV4dE5vZGUuc3R5bGUuZGlzcGxheSA9ICctd2Via2l0LWJveCdcbiAgdGhpcy50ZXh0Tm9kZS5zdHlsZS53ZWJraXRCb3hPcmllbnQgPSAndmVydGljYWwnXG4gIHRoaXMuc3R5bGUubGluZXMuY2FsbCh0aGlzLCB0aGlzLmRhdGEuc3R5bGUubGluZXMpXG4gIG5vZGUuYXBwZW5kQ2hpbGQodGhpcy50ZXh0Tm9kZSlcbiAgcmV0dXJuIG5vZGVcbn1cblxuVGV4dC5wcm90b3R5cGUuYXR0ciA9IHtcbiAgdmFsdWU6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHZhciBzcGFuID0gdGhpcy5ub2RlLmZpcnN0Q2hpbGRcbiAgICBzcGFuLmlubmVySFRNTCA9ICcnXG4gICAgaWYgKCF2YWx1ZSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIHNwYW4udGV4dENvbnRlbnQgPSB2YWx1ZVxuICAgIC8qKlxuICAgICAqIERldmVsb3BlcnMgYXJlIHN1cHBvc2VkIHRvIGhhdmUgdGhlIGFiaWxpdHkgdG8gYnJlYWsgdGV4dFxuICAgICAqIGxpbmVzIG1hbnVhbGx5LiBVc2luZyBgYCZuYnNwO2BgIHRvIHJlcGxhY2UgdGV4dCBzcGFjZSBpc1xuICAgICAqIG5vdCBjb21wYXRpYmxlIHdpdGggdGhlIGBgLXdlYmtpdC1saW5lLWNsYW1wYGAuIFRoZXJlZm9yXG4gICAgICogd2UgdXNlIGBgd2hpdGUtc3BhY2U6IG5vLXdyYXBgYCBpbnN0ZWFkIChpbnN0ZWFkIG9mIHRoZVxuICAgICAqIGNvZGUgYmVsbG93KS5cblxuICAgICAgdmFyIGZyYWcgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KClcbiAgICAgICAgdGV4dC5zcGxpdCgnICcpLmZvckVhY2goZnVuY3Rpb24oc3RyKSB7XG4gICAgICAgICAgdmFyIHRleHROb2RlID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoc3RyKVxuICAgICAgICAgIHZhciBzcGFjZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2knKVxuICAgICAgICAgIHNwYWNlLmlubmVySFRNTCA9ICcmbmJzcDsnXG4gICAgICAgICAgZnJhZy5hcHBlbmRDaGlsZChzcGFjZSlcbiAgICAgICAgICBmcmFnLmFwcGVuZENoaWxkKHRleHROb2RlKVxuICAgICAgICB9KVxuICAgICAgICBmcmFnLnJlbW92ZUNoaWxkKGZyYWcuZmlyc3RDaGlsZClcbiAgICAgICAgc3Bhbi5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdicicpKVxuICAgICAgICBzcGFuLmFwcGVuZENoaWxkKGZyYWcpXG4gICAgICB9KVxuICAgICAgc3Bhbi5yZW1vdmVDaGlsZChzcGFuLmZpcnN0Q2hpbGQpXG4gICAgICovXG4gIH1cbn1cblxuVGV4dC5wcm90b3R5cGUuY2xlYXJBdHRyID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLm5vZGUuZmlyc3RDaGlsZC50ZXh0Q29udGVudCA9ICcnXG59XG5cblRleHQucHJvdG90eXBlLnN0eWxlID0gdXRpbHMuZXh0ZW5kKE9iamVjdC5jcmVhdGUoQXRvbWljLnByb3RvdHlwZS5zdHlsZSksIHtcblxuICBsaW5lczogZnVuY3Rpb24gKHZhbCkge1xuICAgIHZhbCA9IHBhcnNlSW50KHZhbClcbiAgICBpZiAodmFsICE9PSB2YWwpIHsgLy8gTmFOXG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgaWYgKHZhbCA8PSAwKSB7XG4gICAgICB0aGlzLnRleHROb2RlLnN0eWxlLnRleHRPdmVyZmxvdyA9ICcnXG4gICAgICB0aGlzLnRleHROb2RlLnN0eWxlLm92ZXJmbG93ID0gJ3Zpc2libGUnXG4gICAgICB0aGlzLnRleHROb2RlLnN0eWxlLndlYmtpdExpbmVDbGFtcCA9ICcnXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudGV4dE5vZGUuc3R5bGUub3ZlcmZsb3cgPSAnaGlkZGVuJ1xuICAgICAgdGhpcy50ZXh0Tm9kZS5zdHlsZS50ZXh0T3ZlcmZsb3cgPSAnZWxsaXBzaXMnXG4gICAgICB0aGlzLnRleHROb2RlLnN0eWxlLndlYmtpdExpbmVDbGFtcCA9IGxpbmVzXG4gICAgfVxuICB9XG5cbn0pXG5cbm1vZHVsZS5leHBvcnRzID0gVGV4dFxuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL3NyYy9jb21wb25lbnRzL3RleHQuanNcbiAqKiBtb2R1bGUgaWQgPSAyOFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnJlcXVpcmUoJy4uL3N0eWxlcy9saXN0LnNjc3MnKVxucmVxdWlyZSgnc2Nyb2xsanMnKVxuXG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi9jb21wb25lbnQnKVxudmFyIExhenlMb2FkID0gcmVxdWlyZSgnLi4vbGF6eUxvYWQnKVxuXG52YXIgREVGQVVMVF9MT0FEX01PUkVfT0ZGU0VUID0gNTAwXG5cbmZ1bmN0aW9uIExpc3QoZGF0YSwgbm9kZVR5cGUpIHtcbiAgLy8gdGhpcy5sb2FkbW9yZU9mZnNldCA9IE51bWJlcihkYXRhLmF0dHIubG9hZG1vcmVvZmZzZXQpXG4gIC8vIHRoaXMuaXNBdmFpbGFibGVUb0ZpcmVsb2FkbW9yZSA9IHRydWVcbiAgQ29tcG9uZW50LmNhbGwodGhpcywgZGF0YSwgbm9kZVR5cGUpXG59XG5cbkxpc3QucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShDb21wb25lbnQucHJvdG90eXBlKVxuXG5MaXN0LnByb3RvdHlwZS5jcmVhdGUgPSBmdW5jdGlvbiAobm9kZVR5cGUpIHtcbiAgdmFyIFNjcm9sbCA9IGxpYi5zY3JvbGxcbiAgdmFyIG5vZGUgPSBDb21wb25lbnQucHJvdG90eXBlLmNyZWF0ZS5jYWxsKHRoaXMsIG5vZGVUeXBlKVxuICBub2RlLmNsYXNzTGlzdC5hZGQoJ3dlZXgtY29udGFpbmVyJywgJ2xpc3Qtd3JhcCcpXG4gIHRoaXMubGlzdEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKVxuICB0aGlzLmxpc3RFbGVtZW50LmNsYXNzTGlzdC5hZGQoXG4gICAgJ3dlZXgtY29udGFpbmVyJ1xuICAgICwgJ2xpc3QtZWxlbWVudCdcbiAgKVxuICBub2RlLmFwcGVuZENoaWxkKHRoaXMubGlzdEVsZW1lbnQpXG4gIHRoaXMuc2Nyb2xsZXIgPSBuZXcgU2Nyb2xsKHtcbiAgICBzY3JvbGxFbGVtZW50OiB0aGlzLmxpc3RFbGVtZW50XG4gICAgLCBkaXJlY3Rpb246ICd5J1xuICB9KVxuICB0aGlzLnNjcm9sbGVyLmluaXQoKVxuICByZXR1cm4gbm9kZVxufVxuXG5MaXN0LnByb3RvdHlwZS5iaW5kRXZlbnRzID0gZnVuY3Rpb24gKGV2dHMpIHtcbiAgQ29tcG9uZW50LnByb3RvdHlwZS5iaW5kRXZlbnRzLmNhbGwodGhpcywgZXZ0cylcbiAgLy8gdG8gZW5hYmxlIGxhenlsb2FkIGZvciBJbWFnZXMuXG4gIHRoaXMuc2Nyb2xsZXIuYWRkRXZlbnRMaXN0ZW5lcignc2Nyb2xsaW5nJywgZnVuY3Rpb24gKGUpIHtcbiAgICB2YXIgc28gPSBlLnNjcm9sbE9ialxuICAgIHRoaXMuZGlzcGF0Y2hFdmVudCgnc2Nyb2xsJywge1xuICAgICAgb3JpZ2luYWxUeXBlOiAnc2Nyb2xsaW5nJyxcbiAgICAgIHNjcm9sbFRvcDogc28uZ2V0U2Nyb2xsVG9wKCksXG4gICAgICBzY3JvbGxMZWZ0OiBzby5nZXRTY3JvbGxMZWZ0KClcbiAgICB9LCB7XG4gICAgICBidWJibGVzOiB0cnVlXG4gICAgfSlcbiAgfS5iaW5kKHRoaXMpKVxuXG4gIHRoaXMuc2Nyb2xsZXIuYWRkRXZlbnRMaXN0ZW5lcigncHVsbHVwZW5kJywgZnVuY3Rpb24gKGUpIHtcbiAgICB0aGlzLmRpc3BhdGNoRXZlbnQoJ2xvYWRtb3JlJylcbiAgfS5iaW5kKHRoaXMpKVxufVxuXG5MaXN0LnByb3RvdHlwZS5hcHBlbmRDaGlsZCA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHZhciBjaGlsZHJlbiA9IHRoaXMuZGF0YS5jaGlsZHJlblxuICB2YXIgY29tcG9uZW50TWFuYWdlciA9IHRoaXMuZ2V0Q29tcG9uZW50TWFuYWdlcigpXG4gIHZhciBjaGlsZCA9IGNvbXBvbmVudE1hbmFnZXIuY3JlYXRlRWxlbWVudChkYXRhKVxuICB0aGlzLmxpc3RFbGVtZW50LmFwcGVuZENoaWxkKGNoaWxkLm5vZGUpXG5cbiAgLy8gdXBkYXRlIHRoaXMuZGF0YS5jaGlsZHJlblxuICBpZiAoIWNoaWxkcmVuIHx8ICFjaGlsZHJlbi5sZW5ndGgpIHtcbiAgICB0aGlzLmRhdGEuY2hpbGRyZW4gPSBbZGF0YV1cbiAgfSBlbHNlIHtcbiAgICBjaGlsZHJlbi5wdXNoKGRhdGEpXG4gIH1cblxuICByZXR1cm4gY2hpbGRcbn1cblxuTGlzdC5wcm90b3R5cGUuaW5zZXJ0QmVmb3JlID0gZnVuY3Rpb24gKGNoaWxkLCBiZWZvcmUpIHtcbiAgdmFyIGNoaWxkcmVuID0gdGhpcy5kYXRhLmNoaWxkcmVuXG4gIHZhciBpID0gMFxuICB2YXIgaXNBcHBlbmQgPSBmYWxzZVxuXG4gIC8vIHVwZGF0ZSB0aGlzLmRhdGEuY2hpbGRyZW5cbiAgaWYgKCFjaGlsZHJlbiB8fCAhY2hpbGRyZW4ubGVuZ3RoIHx8ICFiZWZvcmUpIHtcbiAgICBpc0FwcGVuZCA9IHRydWVcbiAgfSBlbHNlIHtcbiAgICBmb3IgKHZhciBsID0gY2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICBpZiAoY2hpbGRyZW5baV0ucmVmID09PSBjaGlsZC5kYXRhLnJlZikge1xuICAgICAgICBicmVha1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoaSA9PT0gbCkge1xuICAgICAgaXNBcHBlbmQgPSB0cnVlXG4gICAgfVxuICB9XG5cbiAgaWYgKGlzQXBwZW5kKSB7XG4gICAgdGhpcy5saXN0RWxlbWVudC5hcHBlbmRDaGlsZChjaGlsZC5ub2RlKVxuICAgIGNoaWxkcmVuLnB1c2goY2hpbGQuZGF0YSlcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmxpc3RFbGVtZW50Lmluc2VydEJlZm9yZShjaGlsZC5ub2RlLCBiZWZvcmUubm9kZSlcbiAgICBjaGlsZHJlbi5zcGxpY2UoaSwgMCwgY2hpbGQuZGF0YSlcbiAgfVxufVxuXG5MaXN0LnByb3RvdHlwZS5yZW1vdmVDaGlsZCA9IGZ1bmN0aW9uIChjaGlsZCkge1xuICB2YXIgY2hpbGRyZW4gPSB0aGlzLmRhdGEuY2hpbGRyZW5cbiAgLy8gcmVtb3ZlIGZyb20gdGhpcy5kYXRhLmNoaWxkcmVuXG4gIHZhciBpID0gMFxuICB2YXIgY29tcG9uZW50TWFuYWdlciA9IHRoaXMuZ2V0Q29tcG9uZW50TWFuYWdlcigpXG4gIGlmIChjaGlsZHJlbiAmJiBjaGlsZHJlbi5sZW5ndGgpIHtcbiAgICBmb3IgKHZhciBsID0gY2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICBpZiAoY2hpbGRyZW5baV0ucmVmID09PSBjaGlsZC5kYXRhLnJlZikge1xuICAgICAgICBicmVha1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoaSA8IGwpIHtcbiAgICAgIGNoaWxkcmVuLnNwbGljZShpLCAxKVxuICAgIH1cbiAgfVxuICAvLyByZW1vdmUgZnJvbSBjb21wb25lbnRNYXAgcmVjdXJzaXZlbHlcbiAgY29tcG9uZW50TWFuYWdlci5yZW1vdmVFbGVtZW50QnlSZWYoY2hpbGQuZGF0YS5yZWYpXG4gIHRoaXMubGlzdEVsZW1lbnQucmVtb3ZlQ2hpbGQoY2hpbGQubm9kZSlcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBMaXN0XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL2NvbXBvbmVudHMvbGlzdC5qc1xuICoqIG1vZHVsZSBpZCA9IDI5XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvLyBzdHlsZS1sb2FkZXI6IEFkZHMgc29tZSBjc3MgdG8gdGhlIERPTSBieSBhZGRpbmcgYSA8c3R5bGU+IHRhZ1xuXG4vLyBsb2FkIHRoZSBzdHlsZXNcbnZhciBjb250ZW50ID0gcmVxdWlyZShcIiEhLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi9ub2RlX21vZHVsZXMvc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vbGlzdC5zY3NzXCIpO1xuaWYodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSBjb250ZW50ID0gW1ttb2R1bGUuaWQsIGNvbnRlbnQsICcnXV07XG4vLyBhZGQgdGhlIHN0eWxlcyB0byB0aGUgRE9NXG52YXIgdXBkYXRlID0gcmVxdWlyZShcIiEuLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvYWRkU3R5bGVzLmpzXCIpKGNvbnRlbnQsIHt9KTtcbmlmKGNvbnRlbnQubG9jYWxzKSBtb2R1bGUuZXhwb3J0cyA9IGNvbnRlbnQubG9jYWxzO1xuLy8gSG90IE1vZHVsZSBSZXBsYWNlbWVudFxuaWYobW9kdWxlLmhvdCkge1xuXHQvLyBXaGVuIHRoZSBzdHlsZXMgY2hhbmdlLCB1cGRhdGUgdGhlIDxzdHlsZT4gdGFnc1xuXHRpZighY29udGVudC5sb2NhbHMpIHtcblx0XHRtb2R1bGUuaG90LmFjY2VwdChcIiEhLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi9ub2RlX21vZHVsZXMvc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vbGlzdC5zY3NzXCIsIGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIG5ld0NvbnRlbnQgPSByZXF1aXJlKFwiISEuLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLy4uLy4uL25vZGVfbW9kdWxlcy9zYXNzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi9saXN0LnNjc3NcIik7XG5cdFx0XHRpZih0eXBlb2YgbmV3Q29udGVudCA9PT0gJ3N0cmluZycpIG5ld0NvbnRlbnQgPSBbW21vZHVsZS5pZCwgbmV3Q29udGVudCwgJyddXTtcblx0XHRcdHVwZGF0ZShuZXdDb250ZW50KTtcblx0XHR9KTtcblx0fVxuXHQvLyBXaGVuIHRoZSBtb2R1bGUgaXMgZGlzcG9zZWQsIHJlbW92ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdG1vZHVsZS5ob3QuZGlzcG9zZShmdW5jdGlvbigpIHsgdXBkYXRlKCk7IH0pO1xufVxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvc3R5bGVzL2xpc3Quc2Nzc1xuICoqIG1vZHVsZSBpZCA9IDMwXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikoKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIi5saXN0LXdyYXAge1xcbiAgZGlzcGxheTogYmxvY2s7XFxuICBvdmVyZmxvdzogaGlkZGVuOyB9XFxuXFxuLmxpc3QtZWxlbWVudCB7XFxuICAtd2Via2l0LWJveC1vcmllbnQ6IHZlcnRpY2FsO1xcbiAgLXdlYmtpdC1mbGV4LWRpcmVjdGlvbjogY29sdW1uO1xcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjsgfVxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi9zcmMvc3JjL3N0eWxlcy9saXN0LnNjc3NcIl0sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIkFBQUE7RUFDQyxlQUFlO0VBQ2YsaUJBQWlCLEVBQ2pCOztBQUVEO0VBQ0UsNkJBQTZCO0VBQzdCLCtCQUErQjtFQUMvQix1QkFBdUIsRUFDeEJcIixcImZpbGVcIjpcImxpc3Quc2Nzc1wiLFwic291cmNlc0NvbnRlbnRcIjpbXCIubGlzdC13cmFwIHtcXG5cXHRkaXNwbGF5OiBibG9jaztcXG5cXHRvdmVyZmxvdzogaGlkZGVuO1xcbn1cXG5cXG4ubGlzdC1lbGVtZW50IHtcXG4gIC13ZWJraXQtYm94LW9yaWVudDogdmVydGljYWw7XFxuICAtd2Via2l0LWZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XFxuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xcbn1cIl0sXCJzb3VyY2VSb290XCI6XCJ3ZWJwYWNrOi8vXCJ9XSk7XG5cbi8vIGV4cG9ydHNcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2Nzcy1sb2FkZXI/c291cmNlTWFwIS4vfi9zYXNzLWxvYWRlcj9zb3VyY2VNYXAhLi9zcmMvc3R5bGVzL2xpc3Quc2Nzc1xuICoqIG1vZHVsZSBpZCA9IDMxXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIodHlwZW9mIHdpbmRvdyA9PT0gJ3VuZGVmaW5lZCcpICYmICh3aW5kb3cgPSB7Y3RybDoge30sIGxpYjoge319KTshd2luZG93LmN0cmwgJiYgKHdpbmRvdy5jdHJsID0ge30pOyF3aW5kb3cubGliICYmICh3aW5kb3cubGliID0ge30pO3JlcXVpcmUoJ2FuaW1hdGlvbmpzJyk7cmVxdWlyZSgnY3ViaWNiZXppZXInKTtyZXF1aXJlKCdnZXN0dXJlanMnKTtyZXF1aXJlKCdtb3Rpb25qcycpOyFmdW5jdGlvbihhLGIsYyl7ZnVuY3Rpb24gZCgpe2Iuc2Nyb2xsLm91dHB1dERlYnVnTG9nJiZjb25zb2xlLmRlYnVnLmFwcGx5KGNvbnNvbGUsYXJndW1lbnRzKX1mdW5jdGlvbiBlKGEpe3ZhciBiPWEuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7aWYoIWIpe2I9e30sYi53aWR0aD1hLm9mZnNldFdpZHRoLGIuaGVpZ2h0PWEub2Zmc2V0SGVpZ2h0LGIubGVmdD1hLm9mZnNldExlZnQsYi50b3A9YS5vZmZzZXRUb3A7Zm9yKHZhciBjPWEub2Zmc2V0UGFyZW50O2M7KWIubGVmdCs9Yy5vZmZzZXRMZWZ0LGIudG9wKz1jLm9mZnNldFRvcCxjPWMub2Zmc2V0UGFyZW50O2IucmlnaHQ9Yi5sZWZ0K2Iud2lkdGgsYi5ib3R0b209Yi50b3ArYi5oZWlnaHR9cmV0dXJuIGJ9ZnVuY3Rpb24gZihhKXtyZXR1cm4gMC1hLm9wdGlvbnNbYS5heGlzK1wiUGFkZGluZ1RvcFwiXX1mdW5jdGlvbiBnKGEpe3ZhciBiPWUoYS5lbGVtZW50KSxjPWUoYS52aWV3cG9ydCksZD1mKGEpO2lmKFwieVwiPT09YS5heGlzKXZhciBnPTAtYi5oZWlnaHQrYy5oZWlnaHQ7ZWxzZSB2YXIgZz0wLWIud2lkdGgrYy53aWR0aDtyZXR1cm4gTWF0aC5taW4oZythLm9wdGlvbnNbYS5heGlzK1wiUGFkZGluZ0JvdHRvbVwiXSxkKX1mdW5jdGlvbiBoKGEsYil7cmV0dXJuIGI+YS5taW5TY3JvbGxPZmZzZXQ/Yi1hLm1pblNjcm9sbE9mZnNldDpiPGEubWF4U2Nyb2xsT2Zmc2V0P2ItYS5tYXhTY3JvbGxPZmZzZXQ6dm9pZCAwfWZ1bmN0aW9uIGkoYSxiKXtyZXR1cm4gYj5hLm1pblNjcm9sbE9mZnNldD9iPWEubWluU2Nyb2xsT2Zmc2V0OmI8YS5tYXhTY3JvbGxPZmZzZXQmJihiPWEubWF4U2Nyb2xsT2Zmc2V0KSxifWZ1bmN0aW9uIGooYSxiLGMpe2QoYS5lbGVtZW50LnNjcm9sbElkLGIsYyk7dmFyIGU9cC5jcmVhdGVFdmVudChcIkhUTUxFdmVudHNcIik7aWYoZS5pbml0RXZlbnQoYiwhMSwhMCksZS5zY3JvbGxPYmo9YSxjKWZvcih2YXIgZiBpbiBjKWVbZl09Y1tmXTthLmVsZW1lbnQuZGlzcGF0Y2hFdmVudChlKSxhLnZpZXdwb3J0LmRpc3BhdGNoRXZlbnQoZSl9ZnVuY3Rpb24gayhhKXt2YXIgYixjPXt4OjAseTowfSxkPWdldENvbXB1dGVkU3R5bGUoYS5lbGVtZW50KVt5K1wiVHJhbnNmb3JtXCJdO3JldHVyblwibm9uZVwiIT09ZCYmKGI9ZC5tYXRjaCgvXm1hdHJpeDNkXFwoKD86Wy1cXGQuXSssXFxzKil7MTJ9KFstXFxkLl0rKSxcXHMqKFstXFxkLl0rKSg/OixcXHMqWy1cXGQuXSspezJ9XFwpLyl8fGQubWF0Y2goL15tYXRyaXhcXCgoPzpbLVxcZC5dKyxcXHMqKXs0fShbLVxcZC5dKyksXFxzKihbLVxcZC5dKylcXCkkLykpJiYoYy54PXBhcnNlRmxvYXQoYlsxXSl8fDAsYy55PXBhcnNlRmxvYXQoYlsyXSl8fDApLGN9ZnVuY3Rpb24gbChhLGIpe3JldHVybiBhPXBhcnNlRmxvYXQoYSksYj1wYXJzZUZsb2F0KGIpLDAhPWEmJihhKz1cInB4XCIpLDAhPWImJihiKz1cInB4XCIpLEE/XCJ0cmFuc2xhdGUzZChcIithK1wiLCBcIitiK1wiLCAwKVwiOlwidHJhbnNsYXRlKFwiK2ErXCIsIFwiK2IrXCIpXCJ9ZnVuY3Rpb24gbShhLGIsYyl7XCJcIj09PWImJlwiXCI9PT1jP2EuZWxlbWVudC5zdHlsZVt5K1wiVHJhbnNpdGlvblwiXT1cIlwiOmEuZWxlbWVudC5zdHlsZVt5K1wiVHJhbnNpdGlvblwiXT14K1widHJhbnNmb3JtIFwiK2IrXCIgXCIrYytcIiAwc1wifWZ1bmN0aW9uIG4oYSxiKXt2YXIgYz0wLGQ9MDtcIm9iamVjdFwiPT10eXBlb2YgYj8oYz1iLngsZD1iLnkpOlwieVwiPT09YS5heGlzP2Q9YjpjPWIsYS5lbGVtZW50LnN0eWxlW3krXCJUcmFuc2Zvcm1cIl09bChjLGQpfWZ1bmN0aW9uIG8oYSxjKXtmdW5jdGlvbiBsKGEpe3JldHVybiBGfHxMPyhhLnByZXZlbnREZWZhdWx0KCksYS5zdG9wUHJvcGFnYXRpb24oKSwhMSk6ITB9ZnVuY3Rpb24gbyhhKXtGfHxMfHxzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7dmFyIGI9ZG9jdW1lbnQuY3JlYXRlRXZlbnQoXCJIVE1MRXZlbnRzXCIpO2IuaW5pdEV2ZW50KFwibmljZWNsaWNrXCIsITAsITApLGEudGFyZ2V0LmRpc3BhdGNoRXZlbnQoYil9LDMwMCl9ZnVuY3Rpb24gcChhLGMpe0k9bnVsbCxjbGVhclRpbWVvdXQoSiksSj1zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7SSYmKEk9bnVsbCxiLmFuaW1hdGlvbi5yZXF1ZXN0RnJhbWUoYSkpfSxjfHw0MDApLEk9YX1mdW5jdGlvbiBxKGEpe2lmKCFFLmVuYWJsZWQpcmV0dXJuITE7aWYoXCJ1bmRlZmluZWRcIiE9dHlwZW9mIGEuaXNWZXJ0aWNhbCl7aWYoIShcInlcIj09PUUuYXhpcyYmYS5pc1ZlcnRpY2FsfHxcInhcIj09PUUuYXhpcyYmIWEuaXNWZXJ0aWNhbCkpcmV0dXJuITE7YS5zdG9wUHJvcGFnYXRpb24oKX1yZXR1cm4hMH1mdW5jdGlvbiB0KGEpe2lmKHEoYSkpaWYoTCYmRCgpLGMudXNlRnJhbWVBbmltYXRpb24pSCYmSC5zdG9wKCksSD1udWxsO2Vsc2V7dmFyIGI9ayhFKTtuKEUsYiksbShFLFwiXCIsXCJcIiksST1udWxsLGNsZWFyVGltZW91dChKKX19ZnVuY3Rpb24gdyhhKXtpZihxKGEpKXt2YXIgZD1rKEUpW0UuYXhpc10sZT1oKEUsZCk7aWYoZSl7dmFyIGY9aShFLGQpO2lmKGMudXNlRnJhbWVBbmltYXRpb24pe3ZhciBnPWYtZDtIPW5ldyBiLmFuaW1hdGlvbig0MDAsYi5jdWJpY2Jlemllci5lYXNlLDAsZnVuY3Rpb24oYSxiKXt2YXIgYz0oZCtnKmIpLnRvRml4ZWQoMik7bihFLGMpLGooRSxcInNjcm9sbGluZ1wiKX0pLEgub25lbmQoRCksSC5wbGF5KCl9ZWxzZXt2YXIgbD1mLnRvRml4ZWQoMCk7bShFLFwiMC40c1wiLFwiZWFzZVwiKSxuKEUsbCkscChELDQwMCksYi5hbmltYXRpb24ucmVxdWVzdEZyYW1lKGZ1bmN0aW9uKCl7TCYmRS5lbmFibGVkJiYoaihFLFwic2Nyb2xsaW5nXCIpLGIuYW5pbWF0aW9uLnJlcXVlc3RGcmFtZShhcmd1bWVudHMuY2FsbGVlKSl9KX1lPjA/aihFLFwieVwiPT09RS5heGlzP1wicHVsbGRvd25lbmRcIjpcInB1bGxyaWdodGVuZFwiKTowPmUmJmooRSxcInlcIj09PUUuYXhpcz9cInB1bGx1cGVuZFwiOlwicHVsbGxlZnRlbmRcIil9ZWxzZSBMJiZEKCl9fWZ1bmN0aW9uIHgoYSl7cShhKSYmKEUudHJhbnNmb3JtT2Zmc2V0PWsoRSksRS5taW5TY3JvbGxPZmZzZXQ9ZihFKSxFLm1heFNjcm9sbE9mZnNldD1nKEUpLEs9Mi41LE49ITAsTD0hMCxNPSExLGooRSxcInNjcm9sbHN0YXJ0XCIpLE89YVtcImRpc3BsYWNlbWVudFwiK0UuYXhpcy50b1VwcGVyQ2FzZSgpXSl9ZnVuY3Rpb24geihhKXtpZihxKGEpKXt2YXIgYj1hW1wiZGlzcGxhY2VtZW50XCIrRS5heGlzLnRvVXBwZXJDYXNlKCldO2lmKE1hdGguYWJzKGItTyk8NSlyZXR1cm4gdm9pZCBhLnN0b3BQcm9wYWdhdGlvbigpO089Yjt2YXIgYz1FLnRyYW5zZm9ybU9mZnNldFtFLmF4aXNdK2I7Yz5FLm1pblNjcm9sbE9mZnNldD8oYz1FLm1pblNjcm9sbE9mZnNldCsoYy1FLm1pblNjcm9sbE9mZnNldCkvSyxLKj0xLjAwMyk6YzxFLm1heFNjcm9sbE9mZnNldCYmKGM9RS5tYXhTY3JvbGxPZmZzZXQtKEUubWF4U2Nyb2xsT2Zmc2V0LWMpL0ssSyo9MS4wMDMpLEs+NCYmKEs9NCk7dmFyIGQ9aChFLGMpO2QmJihqKEUsZD4wP1wieVwiPT09RS5heGlzP1wicHVsbGRvd25cIjpcInB1bGxyaWdodFwiOlwieVwiPT09RS5heGlzP1wicHVsbHVwXCI6XCJwdWxsbGVmdFwiLHtib3VuZGFyeU9mZnNldDpNYXRoLmFicyhkKX0pLEUub3B0aW9ucy5ub0JvdW5jZSYmKGM9aShFLGMpKSksbihFLGMudG9GaXhlZCgyKSksaihFLFwic2Nyb2xsaW5nXCIpfX1mdW5jdGlvbiBBKGEpe3EoYSkmJmEuaXNmbGljayYmQyhhKX1mdW5jdGlvbiBDKGEpe049ITA7dmFyIGUsZixnLGksbCxvLHEscixzLHQsdix3LHgseSx6LEEsQjtpPWsoRSlbRS5heGlzXTt2YXIgQz1oKEUsaSk7aWYoIUMpe2U9YVtcInZlbG9jaXR5XCIrRS5heGlzLnRvVXBwZXJDYXNlKCldO3ZhciBGPTIsRz0uMDAxNTtjLmluZXJ0aWEmJnVbYy5pbmVydGlhXSYmKEY9dVtjLmluZXJ0aWFdWzBdLEc9dVtjLmluZXJ0aWFdWzFdKSxlPkYmJihlPUYpLC1GPmUmJihlPS1GKSxmPUcqKGUvTWF0aC5hYnMoZSkpLG89bmV3IGIubW90aW9uKHt2OmUsYTotZn0pLGc9by50LGw9aStvLnM7dmFyIEk9aChFLGwpO2lmKEkpe2QoXCLmg6/mgKforqHnrpfotoXlh7rkuobovrnnvJhcIixJKSxxPWUscj1mLEk+MD8odD1FLm1pblNjcm9sbE9mZnNldCx3PTEpOih0PUUubWF4U2Nyb2xsT2Zmc2V0LHc9LTEpLHY9bmV3IGIubW90aW9uKHt2OncqcSxhOi13KnIsczpNYXRoLmFicyh0LWkpfSkscz12LnQ7dmFyIEo9di5nZW5lcmF0ZUN1YmljQmV6aWVyKCk7eD1xLXIqcyx5PS4wMyooeC9NYXRoLmFicyh4KSksQj1uZXcgYi5tb3Rpb24oe3Y6eCxhOi15fSksej1CLnQsQT10K0IucztCLmdlbmVyYXRlQ3ViaWNCZXppZXIoKTtpZihjLm5vQm91bmNlKWlmKGQoXCLmsqHmnInlm57lvLnmlYjmnpxcIiksaSE9PXQpaWYoYy51c2VGcmFtZUFuaW1hdGlvbil7dmFyIEs9dC1pLE89Yi5jdWJpY2JlemllcihKWzBdWzBdLEpbMF1bMV0sSlsxXVswXSxKWzFdWzFdKTtIPW5ldyBiLmFuaW1hdGlvbihzLnRvRml4ZWQoMCksTywwLGZ1bmN0aW9uKGEsYil7dmFyIGM9aStLKmI7ayhFLGMudG9GaXhlZCgyKSksaihFLFwic2Nyb2xsaW5nXCIse2FmdGVyRmxpY2s6ITB9KX0pLEgub25lbmQoRCksSC5wbGF5KCl9ZWxzZXt2YXIgUD10LnRvRml4ZWQoMCk7bShFLChzLzFlMykudG9GaXhlZCgyKStcInNcIixcImN1YmljLWJlemllcihcIitKK1wiKVwiKSxuKEUsUCkscChELDFlMyoocy8xZTMpLnRvRml4ZWQoMikpfWVsc2UgRCgpO2Vsc2UgaWYoaSE9PUEpaWYoZChcIuaDr+aAp+a7muWKqFwiLFwicz1cIitBLnRvRml4ZWQoMCksXCJ0PVwiKygocyt6KS8xZTMpLnRvRml4ZWQoMikpLGMudXNlRnJhbWVBbmltYXRpb24pe3ZhciBLPUEtaSxPPWIuY3ViaWNiZXppZXIuZWFzZU91dDtIPW5ldyBiLmFuaW1hdGlvbigocyt6KS50b0ZpeGVkKDApLE8sMCxmdW5jdGlvbihhLGIpe3ZhciBjPWkrSypiO24oRSxjLnRvRml4ZWQoMikpLGooRSxcInNjcm9sbGluZ1wiLHthZnRlckZsaWNrOiEwfSl9KSxILm9uZW5kKGZ1bmN0aW9uKCl7aWYoRS5lbmFibGVkKXt2YXIgYT10LUEsYz1iLmN1YmljYmV6aWVyLmVhc2U7SD1uZXcgYi5hbmltYXRpb24oNDAwLGMsMCxmdW5jdGlvbihiLGMpe3ZhciBkPUErYSpjO24oRSxkLnRvRml4ZWQoMikpLGooRSxcInNjcm9sbGluZ1wiLHthZnRlckZsaWNrOiEwfSl9KSxILm9uZW5kKEQpLEgucGxheSgpfX0pLEgucGxheSgpfWVsc2V7dmFyIFA9QS50b0ZpeGVkKDApO20oRSwoKHMreikvMWUzKS50b0ZpeGVkKDIpK1wic1wiLFwiZWFzZS1vdXRcIiksbihFLFApLHAoZnVuY3Rpb24oYSl7aWYoRS5lbmFibGVkKWlmKGQoXCLmg6/mgKflm57lvLlcIixcInM9XCIrdC50b0ZpeGVkKDApLFwidD00MDBcIiksQSE9PXQpe3ZhciBiPXQudG9GaXhlZCgwKTttKEUsXCIwLjRzXCIsXCJlYXNlXCIpLG4oRSxiKSxwKEQsNDAwKX1lbHNlIEQoKX0sMWUzKigocyt6KS8xZTMpLnRvRml4ZWQoMikpfWVsc2UgRCgpfWVsc2V7ZChcIuaDr+aAp+iuoeeul+ayoeaciei2heWHuui+uee8mFwiKTt2YXIgUT1vLmdlbmVyYXRlQ3ViaWNCZXppZXIoKTtpZihjLnVzZUZyYW1lQW5pbWF0aW9uKXt2YXIgSz1sLWksTz1iLmN1YmljYmV6aWVyKFFbMF1bMF0sUVswXVsxXSxRWzFdWzBdLFFbMV1bMV0pO0g9bmV3IGIuYW5pbWF0aW9uKGcudG9GaXhlZCgwKSxPLDAsZnVuY3Rpb24oYSxiKXt2YXIgYz0oaStLKmIpLnRvRml4ZWQoMik7bihFLGMpLGooRSxcInNjcm9sbGluZ1wiLHthZnRlckZsaWNrOiEwfSl9KSxILm9uZW5kKEQpLEgucGxheSgpfWVsc2V7dmFyIFA9bC50b0ZpeGVkKDApO20oRSwoZy8xZTMpLnRvRml4ZWQoMikrXCJzXCIsXCJjdWJpYy1iZXppZXIoXCIrUStcIilcIiksbihFLFApLHAoRCwxZTMqKGcvMWUzKS50b0ZpeGVkKDIpKX19TT0hMCxjLnVzZUZyYW1lQW5pbWF0aW9ufHxiLmFuaW1hdGlvbi5yZXF1ZXN0RnJhbWUoZnVuY3Rpb24oKXtMJiZNJiZFLmVuYWJsZWQmJihqKEUsXCJzY3JvbGxpbmdcIix7YWZ0ZXJGbGljazohMH0pLGIuYW5pbWF0aW9uLnJlcXVlc3RGcmFtZShhcmd1bWVudHMuY2FsbGVlKSl9KX19ZnVuY3Rpb24gRCgpe0UuZW5hYmxlZCYmKE49ITEsc2V0VGltZW91dChmdW5jdGlvbigpeyFOJiZMJiYoTD0hMSxNPSExLGMudXNlRnJhbWVBbmltYXRpb24/KEgmJkguc3RvcCgpLEg9bnVsbCk6bShFLFwiXCIsXCJcIiksaihFLFwic2Nyb2xsZW5kXCIpKX0sNTApKX12YXIgRT10aGlzO2lmKGM9Y3x8e30sYy5ub0JvdW5jZT0hIWMubm9Cb3VuY2UsYy5wYWRkaW5nPWMucGFkZGluZ3x8e30sbnVsbD09Yy5pc1ByZXZlbnQ/Yy5pc1ByZXZlbnQ9ITA6Yy5pc1ByZXZlbnQ9ISFjLmlzUHJldmVudCxudWxsPT1jLmlzRml4U2Nyb2xsZW5kQ2xpY2s/Yy5pc0ZpeFNjcm9sbGVuZENsaWNrPSEwOmMuaXNGaXhTY3JvbGxlbmRDbGljaz0hIWMuaXNGaXhTY3JvbGxlbmRDbGljayxjLnBhZGRpbmc/KGMueVBhZGRpbmdUb3A9LWMucGFkZGluZy50b3B8fDAsYy55UGFkZGluZ0JvdHRvbT0tYy5wYWRkaW5nLmJvdHRvbXx8MCxjLnhQYWRkaW5nVG9wPS1jLnBhZGRpbmcubGVmdHx8MCxjLnhQYWRkaW5nQm90dG9tPS1jLnBhZGRpbmcucmlnaHR8fDApOihjLnlQYWRkaW5nVG9wPTAsYy55UGFkZGluZ0JvdHRvbT0wLGMueFBhZGRpbmdUb3A9MCxjLnhQYWRkaW5nQm90dG9tPTApLGMuZGlyZWN0aW9uPWMuZGlyZWN0aW9ufHxcInlcIixjLmluZXJ0aWE9Yy5pbmVydGlhfHxcIm5vcm1hbFwiLHRoaXMub3B0aW9ucz1jLEUuYXhpcz1jLmRpcmVjdGlvbix0aGlzLmVsZW1lbnQ9YSx0aGlzLnZpZXdwb3J0PWEucGFyZW50Tm9kZSx0aGlzLnBsdWdpbnM9e30sdGhpcy5lbGVtZW50LnNjcm9sbElkPXNldFRpbWVvdXQoZnVuY3Rpb24oKXtyW0UuZWxlbWVudC5zY3JvbGxJZCtcIlwiXT1FfSwxKSx0aGlzLnZpZXdwb3J0LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaHN0YXJ0XCIsdCwhMSksdGhpcy52aWV3cG9ydC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hlbmRcIix3LCExKSx0aGlzLnZpZXdwb3J0LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaGNhbmNlbFwiLHcsITEpLHRoaXMudmlld3BvcnQuYWRkRXZlbnRMaXN0ZW5lcihcInBhbnN0YXJ0XCIseCwhMSksdGhpcy52aWV3cG9ydC5hZGRFdmVudExpc3RlbmVyKFwicGFubW92ZVwiLHosITEpLHRoaXMudmlld3BvcnQuYWRkRXZlbnRMaXN0ZW5lcihcInBhbmVuZFwiLEEsITEpLGMuaXNQcmV2ZW50JiYodGhpcy52aWV3cG9ydC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hzdGFydFwiLGZ1bmN0aW9uKGEpe0I9ITB9LCExKSxFLnZpZXdwb3J0LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaGVuZFwiLGZ1bmN0aW9uKGEpe0I9ITF9LCExKSksYy5pc0ZpeFNjcm9sbGVuZENsaWNrKXt2YXIgRixHO3RoaXMudmlld3BvcnQuYWRkRXZlbnRMaXN0ZW5lcihcInNjcm9sbGluZ1wiLGZ1bmN0aW9uKCl7Rj0hMCxHJiZjbGVhclRpbWVvdXQoRyksRz1zZXRUaW1lb3V0KGZ1bmN0aW9uKGEpe0Y9ITF9LDQwMCl9LCExKSx0aGlzLnZpZXdwb3J0LmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLGwsITEpLHRoaXMudmlld3BvcnQuYWRkRXZlbnRMaXN0ZW5lcihcInRhcFwiLG8sITEpfWlmKGMudXNlRnJhbWVBbmltYXRpb24pe3ZhciBIO09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLFwiYW5pbWF0aW9uXCIse2dldDpmdW5jdGlvbigpe3JldHVybiBIfX0pfWVsc2V7dmFyIEksSj0wO2EuYWRkRXZlbnRMaXN0ZW5lcih2P1widHJhbnNpdGlvbmVuZFwiOnkrXCJUcmFuc2l0aW9uRW5kXCIsZnVuY3Rpb24oYSl7aWYoSSl7dmFyIGM9STtJPW51bGwsY2xlYXJUaW1lb3V0KEopLGIuYW5pbWF0aW9uLnJlcXVlc3RGcmFtZShmdW5jdGlvbigpe2MoYSl9KX19LCExKX12YXIgSyxMLE0sTjtPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcyxcImlzU2Nyb2xsaW5nXCIse2dldDpmdW5jdGlvbigpe3JldHVybiEhTH19KTt2YXIgTyxQPXtpbml0OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZW5hYmxlKCksdGhpcy5yZWZyZXNoKCksdGhpcy5zY3JvbGxUbygwKSx0aGlzfSxlbmFibGU6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5lbmFibGVkPSEwLHRoaXN9LGRpc2FibGU6ZnVuY3Rpb24oKXt2YXIgYT10aGlzLmVsZW1lbnQ7cmV0dXJuIHRoaXMuZW5hYmxlZD0hMSx0aGlzLm9wdGlvbnMudXNlRnJhbWVBbmltYXRpb24/SCYmSC5zdG9wKCk6Yi5hbmltYXRpb24ucmVxdWVzdEZyYW1lKGZ1bmN0aW9uKCl7YS5zdHlsZVt5K1wiVHJhbnNmb3JtXCJdPWdldENvbXB1dGVkU3R5bGUoYSlbeStcIlRyYW5zZm9ybVwiXX0pLHRoaXN9LGdldFNjcm9sbFdpZHRoOmZ1bmN0aW9uKCl7cmV0dXJuIGUodGhpcy5lbGVtZW50KS53aWR0aH0sZ2V0U2Nyb2xsSGVpZ2h0OmZ1bmN0aW9uKCl7cmV0dXJuIGUodGhpcy5lbGVtZW50KS5oZWlnaHR9LGdldFNjcm9sbExlZnQ6ZnVuY3Rpb24oKXtyZXR1cm4tayh0aGlzKS54LXRoaXMub3B0aW9ucy54UGFkZGluZ1RvcH0sZ2V0U2Nyb2xsVG9wOmZ1bmN0aW9uKCl7cmV0dXJuLWsodGhpcykueS10aGlzLm9wdGlvbnMueVBhZGRpbmdUb3B9LGdldE1heFNjcm9sbExlZnQ6ZnVuY3Rpb24oKXtyZXR1cm4tRS5tYXhTY3JvbGxPZmZzZXQtdGhpcy5vcHRpb25zLnhQYWRkaW5nVG9wfSxnZXRNYXhTY3JvbGxUb3A6ZnVuY3Rpb24oKXtyZXR1cm4tRS5tYXhTY3JvbGxPZmZzZXQtdGhpcy5vcHRpb25zLnlQYWRkaW5nVG9wfSxnZXRCb3VuZGFyeU9mZnNldDpmdW5jdGlvbigpe3JldHVybiBNYXRoLmFicyhoKHRoaXMsayh0aGlzKVt0aGlzLmF4aXNdKXx8MCl9LHJlZnJlc2g6ZnVuY3Rpb24oKXt2YXIgYT10aGlzLmVsZW1lbnQsYj1cInlcIj09PXRoaXMuYXhpcyxjPWI/XCJoZWlnaHRcIjpcIndpZHRoXCI7aWYobnVsbCE9dGhpcy5vcHRpb25zW2NdKWEuc3R5bGVbY109dGhpcy5vcHRpb25zW2NdK1wicHhcIjtlbHNlIGlmKHRoaXMub3B0aW9ucy51c2VFbGVtZW50UmVjdClhLnN0eWxlW2NdPVwiYXV0b1wiLGEuc3R5bGVbY109ZShhKVtjXStcInB4XCI7ZWxzZSBpZihhLmNoaWxkRWxlbWVudENvdW50PjApe3ZhciBkLGgsaT1hLmZpcnN0RWxlbWVudENoaWxkLGw9YS5sYXN0RWxlbWVudENoaWxkO2lmKGRvY3VtZW50LmNyZWF0ZVJhbmdlJiYhdGhpcy5vcHRpb25zLmlnbm9yZU92ZXJmbG93JiYoZD1kb2N1bWVudC5jcmVhdGVSYW5nZSgpLGQuc2VsZWN0Tm9kZUNvbnRlbnRzKGEpLGg9ZShkKSksaClhLnN0eWxlW2NdPWhbY10rXCJweFwiO2Vsc2V7Zm9yKDtpJiYwPT09ZShpKVtjXSYmaS5uZXh0RWxlbWVudFNpYmxpbmc7KWk9aS5uZXh0RWxlbWVudFNpYmxpbmc7Zm9yKDtsJiZsIT09aSYmMD09PWUobClbY10mJmwucHJldmlvdXNFbGVtZW50U2libGluZzspbD1sLnByZXZpb3VzRWxlbWVudFNpYmxpbmc7YS5zdHlsZVtjXT1lKGwpW2I/XCJib3R0b21cIjpcInJpZ2h0XCJdLWUoaSlbYj9cInRvcFwiOlwibGVmdFwiXStcInB4XCJ9fXJldHVybiB0aGlzLnRyYW5zZm9ybU9mZnNldD1rKHRoaXMpLHRoaXMubWluU2Nyb2xsT2Zmc2V0PWYodGhpcyksdGhpcy5tYXhTY3JvbGxPZmZzZXQ9Zyh0aGlzKSx0aGlzLnNjcm9sbFRvKC10aGlzLnRyYW5zZm9ybU9mZnNldFt0aGlzLmF4aXNdLXRoaXMub3B0aW9uc1t0aGlzLmF4aXMrXCJQYWRkaW5nVG9wXCJdKSxqKHRoaXMsXCJjb250ZW50cmVmcmVzaFwiKSx0aGlzfSxvZmZzZXQ6ZnVuY3Rpb24oYSl7dmFyIGI9ZSh0aGlzLmVsZW1lbnQpLGM9ZShhKTtpZihcInlcIj09PXRoaXMuYXhpcyl7dmFyIGQ9e3RvcDpjLnRvcC1iLnRvcC10aGlzLm9wdGlvbnMueVBhZGRpbmdUb3AsbGVmdDpjLmxlZnQtYi5sZWZ0LHJpZ2h0OmIucmlnaHQtYy5yaWdodCx3aWR0aDpjLndpZHRoLGhlaWdodDpjLmhlaWdodH07ZC5ib3R0b209ZC50b3ArZC5oZWlnaHR9ZWxzZXt2YXIgZD17dG9wOmMudG9wLWIudG9wLGJvdHRvbTpiLmJvdHRvbS1jLmJvdHRvbSxsZWZ0OmMubGVmdC1iLmxlZnQtdGhpcy5vcHRpb25zLnhQYWRkaW5nVG9wLHdpZHRoOmMud2lkdGgsaGVpZ2h0OmMuaGVpZ2h0fTtkLnJpZ2h0PWQubGVmdCtkLndpZHRofXJldHVybiBkfSxnZXRSZWN0OmZ1bmN0aW9uKGEpe3ZhciBiPWUodGhpcy52aWV3cG9ydCksYz1lKGEpO2lmKFwieVwiPT09dGhpcy5heGlzKXt2YXIgZD17dG9wOmMudG9wLWIudG9wLGxlZnQ6Yy5sZWZ0LWIubGVmdCxyaWdodDpiLnJpZ2h0LWMucmlnaHQsd2lkdGg6Yy53aWR0aCxoZWlnaHQ6Yy5oZWlnaHR9O2QuYm90dG9tPWQudG9wK2QuaGVpZ2h0fWVsc2V7dmFyIGQ9e3RvcDpjLnRvcC1iLnRvcCxib3R0b206Yi5ib3R0b20tYy5ib3R0b20sbGVmdDpjLmxlZnQtYi5sZWZ0LHdpZHRoOmMud2lkdGgsaGVpZ2h0OmMuaGVpZ2h0fTtkLnJpZ2h0PWQubGVmdCtkLndpZHRofXJldHVybiBkfSxpc0luVmlldzpmdW5jdGlvbihhKXt2YXIgYj10aGlzLmdldFJlY3QodGhpcy52aWV3cG9ydCksYz10aGlzLmdldFJlY3QoYSk7cmV0dXJuXCJ5XCI9PT10aGlzLmF4aXM/Yi50b3A8Yy5ib3R0b20mJmIuYm90dG9tPmMudG9wOmIubGVmdDxjLnJpZ2h0JiZiLnJpZ2h0PmMubGVmdH0sc2Nyb2xsVG86ZnVuY3Rpb24oYSxjKXt2YXIgZD10aGlzO3RoaXMuZWxlbWVudDtpZihhPS1hLXRoaXMub3B0aW9uc1t0aGlzLmF4aXMrXCJQYWRkaW5nVG9wXCJdLGE9aSh0aGlzLGEpLEw9ITAsYz09PSEwKWlmKHRoaXMub3B0aW9ucy51c2VGcmFtZUFuaW1hdGlvbil7dmFyIGU9ayhkKVt0aGlzLmF4aXNdLGY9YS1lO0g9bmV3IGIuYW5pbWF0aW9uKDQwMCxiLmN1YmljYmV6aWVyLmVhc2UsMCxmdW5jdGlvbihhLGIpe3ZhciBjPShlK2YqYikudG9GaXhlZCgyKTtuKGQsYyksaihkLFwic2Nyb2xsaW5nXCIpfSksSC5vbmVuZChEKSxILnBsYXkoKX1lbHNlIG0oZCxcIjAuNHNcIixcImVhc2VcIiksbihkLGEpLHAoRCw0MDApLGIuYW5pbWF0aW9uLnJlcXVlc3RGcmFtZShmdW5jdGlvbigpe0wmJmQuZW5hYmxlZCYmKGooZCxcInNjcm9sbGluZ1wiKSxiLmFuaW1hdGlvbi5yZXF1ZXN0RnJhbWUoYXJndW1lbnRzLmNhbGxlZSkpfSk7ZWxzZSB0aGlzLm9wdGlvbnMudXNlRnJhbWVBbmltYXRpb258fG0oZCxcIlwiLFwiXCIpLG4oZCxhKSxEKCk7cmV0dXJuIHRoaXN9LHNjcm9sbFRvRWxlbWVudDpmdW5jdGlvbihhLGIpe3ZhciBjPXRoaXMub2Zmc2V0KGEpO3JldHVybiBjPWNbXCJ5XCI9PT10aGlzLmF4aXM/XCJ0b3BcIjpcImxlZnRcIl0sdGhpcy5zY3JvbGxUbyhjLGIpfSxnZXRWaWV3V2lkdGg6ZnVuY3Rpb24oKXtyZXR1cm4gZSh0aGlzLnZpZXdwb3J0KS53aWR0aH0sZ2V0Vmlld0hlaWdodDpmdW5jdGlvbigpe3JldHVybiBlKHRoaXMudmlld3BvcnQpLmhlaWdodH0sYWRkUHVsbGRvd25IYW5kbGVyOmZ1bmN0aW9uKGEpe3ZhciBiPXRoaXM7cmV0dXJuIHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwicHVsbGRvd25lbmRcIixmdW5jdGlvbihjKXtiLmRpc2FibGUoKSxhLmNhbGwoYixjLGZ1bmN0aW9uKCl7Yi5zY3JvbGxUbygwLCEwKSxiLnJlZnJlc2goKSxiLmVuYWJsZSgpfSl9LCExKSx0aGlzfSxhZGRQdWxsdXBIYW5kbGVyOmZ1bmN0aW9uKGEpe3ZhciBiPXRoaXM7cmV0dXJuIHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwicHVsbHVwZW5kXCIsZnVuY3Rpb24oYyl7Yi5kaXNhYmxlKCksYS5jYWxsKGIsYyxmdW5jdGlvbigpe2Iuc2Nyb2xsVG8oYi5nZXRTY3JvbGxIZWlnaHQoKSwhMCksYi5yZWZyZXNoKCksYi5lbmFibGUoKX0pfSwhMSksdGhpc30sYWRkU2Nyb2xsc3RhcnRIYW5kbGVyOmZ1bmN0aW9uKGEpe3ZhciBiPXRoaXM7cmV0dXJuIHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwic2Nyb2xsc3RhcnRcIixmdW5jdGlvbihjKXthLmNhbGwoYixjKX0sITEpLHRoaXN9LGFkZFNjcm9sbGluZ0hhbmRsZXI6ZnVuY3Rpb24oYSl7dmFyIGI9dGhpcztyZXR1cm4gdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJzY3JvbGxpbmdcIixmdW5jdGlvbihjKXthLmNhbGwoYixjKX0sITEpLHRoaXN9LGFkZFNjcm9sbGVuZEhhbmRsZXI6ZnVuY3Rpb24oYSl7dmFyIGI9dGhpcztyZXR1cm4gdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJzY3JvbGxlbmRcIixmdW5jdGlvbihjKXthLmNhbGwoYixjKX0sITEpLHRoaXN9LGFkZENvbnRlbnRyZW5mcmVzaEhhbmRsZXI6ZnVuY3Rpb24oYSl7dmFyIGI9dGhpczt0aGlzLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImNvbnRlbnRyZWZyZXNoXCIsZnVuY3Rpb24oYyl7YS5jYWxsKGIsYyl9LCExKX0sYWRkRXZlbnRMaXN0ZW5lcjpmdW5jdGlvbihhLGIsYyl7dmFyIGQ9dGhpczt0aGlzLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihhLGZ1bmN0aW9uKGEpe2IuY2FsbChkLGEpfSwhIWMpfSxyZW1vdmVFdmVudExpc3RlbmVyOmZ1bmN0aW9uKGEsYil7dmFyIGM9dGhpczt0aGlzLmVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihhLGZ1bmN0aW9uKGEpe2IuY2FsbChjLGEpfSl9LGVuYWJsZVBsdWdpbjpmdW5jdGlvbihhLGIpe3ZhciBjPXNbYV07cmV0dXJuIGMmJiF0aGlzLnBsdWdpbnNbYV0mJih0aGlzLnBsdWdpbnNbYV09ITAsYj1ifHx7fSxjLmNhbGwodGhpcyxhLGIpKSx0aGlzfX07Zm9yKHZhciBRIGluIFApdGhpc1tRXT1QW1FdO2RlbGV0ZSBQfXZhciBwPWEuZG9jdW1lbnQscT1hLm5hdmlnYXRvci51c2VyQWdlbnQscj17fSxzPXt9LHQ9YS5kcHJ8fChhLm5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL2lQaG9uZXxpUGFkfGlQb2QvKT9kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGgvYS5zY3JlZW4uYXZhaWxXaWR0aDoxKSx1PXtub3JtYWw6WzIqdCwuMDAxNSp0XSxzbG93OlsxLjUqdCwuMDAzKnRdLHZlcnlzbG93OlsxLjUqdCwuMDA1KnRdfSx2PSEhcS5tYXRjaCgvRmlyZWZveC9pKSx3PSEhcS5tYXRjaCgvSUVNb2JpbGUvaSkseD12P1wiLW1vei1cIjp3P1wiLW1zLVwiOlwiLXdlYmtpdC1cIix5PXY/XCJNb3pcIjp3P1wibXNcIjpcIndlYmtpdFwiLHo9dz9cIk1TQ1NTTWF0cml4XCI6XCJXZWJLaXRDU1NNYXRyaXhcIixBPSEhdnx8eiBpbiBhJiZcIm0xMVwiaW4gbmV3IGFbel0sQj0hMTtwLmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaG1vdmVcIixmdW5jdGlvbihhKXtyZXR1cm4gQj8oYS5wcmV2ZW50RGVmYXVsdCgpLCExKTohMH0sITEpLGIuc2Nyb2xsPWZ1bmN0aW9uKGEsYyl7aWYoMT09PWFyZ3VtZW50cy5sZW5ndGgmJiEoYXJndW1lbnRzWzBdaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpaWYoYz1hcmd1bWVudHNbMF0sYy5zY3JvbGxFbGVtZW50KWE9Yy5zY3JvbGxFbGVtZW50O2Vsc2V7aWYoIWMuc2Nyb2xsV3JhcCl0aHJvdyBuZXcgRXJyb3IoXCJubyBzY3JvbGwgZWxlbWVudFwiKTthPWMuc2Nyb2xsV3JhcC5maXJzdEVsZW1lbnRDaGlsZH1pZighYS5wYXJlbnROb2RlKXRocm93IG5ldyBFcnJvcihcIndyb25nIGRvbSB0cmVlXCIpO2lmKGMmJmMuZGlyZWN0aW9uJiZbXCJ4XCIsXCJ5XCJdLmluZGV4T2YoYy5kaXJlY3Rpb24pPDApdGhyb3cgbmV3IEVycm9yKFwid3JvbmcgZGlyZWN0aW9uXCIpO3ZhciBkO3JldHVybiBkPWMuZG93bmdyYWRlPT09ITAmJmIuc2Nyb2xsLmRvd25ncmFkZT9iLnNjcm9sbC5kb3duZ3JhZGUoYSxjKTphLnNjcm9sbElkP3JbYS5zY3JvbGxJZF06bmV3IG8oYSxjKX0sYi5zY3JvbGwucGx1Z2luPWZ1bmN0aW9uKGEsYil7cmV0dXJuIGI/KGE9YS5zcGxpdChcIixcIiksdm9pZCBhLmZvckVhY2goZnVuY3Rpb24oYSl7c1thXT1ifSkpOnNbYV19fSh3aW5kb3csd2luZG93LmxpYnx8KHdpbmRvdy5saWI9e30pKTs7bW9kdWxlLmV4cG9ydHMgPSB3aW5kb3cubGliWydzY3JvbGwnXTtcblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9zY3JvbGxqcy9idWlsZC9zY3JvbGwuY29tbW9uLmpzXG4gKiogbW9kdWxlIGlkID0gMzJcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIih0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykgJiYgKHdpbmRvdyA9IHtjdHJsOiB7fSwgbGliOiB7fX0pOyF3aW5kb3cuY3RybCAmJiAod2luZG93LmN0cmwgPSB7fSk7IXdpbmRvdy5saWIgJiYgKHdpbmRvdy5saWIgPSB7fSk7IWZ1bmN0aW9uKGEsYil7ZnVuY3Rpb24gYyhhKXtyZXR1cm4gc2V0VGltZW91dChhLGwpfWZ1bmN0aW9uIGQoYSl7Y2xlYXJUaW1lb3V0KGEpfWZ1bmN0aW9uIGUoKXt2YXIgYT17fSxiPW5ldyBtKGZ1bmN0aW9uKGIsYyl7YS5yZXNvbHZlPWIsYS5yZWplY3Q9Y30pO3JldHVybiBhLnByb21pc2U9YixhfWZ1bmN0aW9uIGYoYSxiKXtyZXR1cm5bXCJ0aGVuXCIsXCJjYXRjaFwiXS5mb3JFYWNoKGZ1bmN0aW9uKGMpe2JbY109ZnVuY3Rpb24oKXtyZXR1cm4gYVtjXS5hcHBseShhLGFyZ3VtZW50cyl9fSksYn1mdW5jdGlvbiBnKGIpe3ZhciBjLGQsaD0hMTt0aGlzLnJlcXVlc3Q9ZnVuY3Rpb24oKXtoPSExO3ZhciBnPWFyZ3VtZW50cztyZXR1cm4gYz1lKCksZihjLnByb21pc2UsdGhpcyksZD1uKGZ1bmN0aW9uKCl7aHx8YyYmYy5yZXNvbHZlKGIuYXBwbHkoYSxnKSl9KSx0aGlzfSx0aGlzLmNhbmNlbD1mdW5jdGlvbigpe3JldHVybiBkJiYoaD0hMCxvKGQpLGMmJmMucmVqZWN0KFwiQ0FOQ0VMXCIpKSx0aGlzfSx0aGlzLmNsb25lPWZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBnKGIpfX1mdW5jdGlvbiBoKGEsYil7XCJmdW5jdGlvblwiPT10eXBlb2YgYiYmKGI9ezA6Yn0pO2Zvcih2YXIgYz1hL2wsZD0xL2MsZT1bXSxmPU9iamVjdC5rZXlzKGIpLm1hcChmdW5jdGlvbihhKXtyZXR1cm4gcGFyc2VJbnQoYSl9KSxoPTA7Yz5oO2grKyl7dmFyIGk9ZlswXSxqPWQqaDtpZihudWxsIT1pJiYxMDAqaj49aSl7dmFyIGs9YltcIlwiK2ldO2sgaW5zdGFuY2VvZiBnfHwoaz1uZXcgZyhrKSksZS5wdXNoKGspLGYuc2hpZnQoKX1lbHNlIGUubGVuZ3RoJiZlLnB1c2goZVtlLmxlbmd0aC0xXS5jbG9uZSgpKX1yZXR1cm4gZX1mdW5jdGlvbiBpKGEpe3ZhciBjO3JldHVyblwic3RyaW5nXCI9PXR5cGVvZiBhfHxhIGluc3RhbmNlb2YgQXJyYXk/Yi5jdWJpY2Jlemllcj9cInN0cmluZ1wiPT10eXBlb2YgYT9iLmN1YmljYmV6aWVyW2FdJiYoYz1iLmN1YmljYmV6aWVyW2FdKTphIGluc3RhbmNlb2YgQXJyYXkmJjQ9PT1hLmxlbmd0aCYmKGM9Yi5jdWJpY2Jlemllci5hcHBseShiLmN1YmljYmV6aWVyLGEpKTpjb25zb2xlLmVycm9yKFwicmVxdWlyZSBsaWIuY3ViaWNiZXppZXJcIik6XCJmdW5jdGlvblwiPT10eXBlb2YgYSYmKGM9YSksY31mdW5jdGlvbiBqKGEsYixjKXt2YXIgZCxnPWgoYSxjKSxqPTEvKGEvbCksaz0wLG09aShiKTtpZighbSl0aHJvdyBuZXcgRXJyb3IoXCJ1bmV4Y2VwdCB0aW1pbmcgZnVuY3Rpb25cIik7dmFyIG49ITE7dGhpcy5wbGF5PWZ1bmN0aW9uKCl7ZnVuY3Rpb24gYSgpe3ZhciBjPWoqKGsrMSkudG9GaXhlZCgxMCksZT1nW2tdO2UucmVxdWVzdChjLnRvRml4ZWQoMTApLGIoYykudG9GaXhlZCgxMCkpLnRoZW4oZnVuY3Rpb24oKXtuJiYoaz09PWcubGVuZ3RoLTE/KG49ITEsZCYmZC5yZXNvbHZlKFwiRklOSVNIXCIpLGQ9bnVsbCk6KGsrKyxhKCkpKX0sZnVuY3Rpb24oKXt9KX1pZighbilyZXR1cm4gbj0hMCxkfHwoZD1lKCksZihkLnByb21pc2UsdGhpcykpLGEoKSx0aGlzfSx0aGlzLnN0b3A9ZnVuY3Rpb24oKXtyZXR1cm4gbj8obj0hMSxnW2tdJiZnW2tdLmNhbmNlbCgpLHRoaXMpOnZvaWQgMH19dmFyIGs9NjAsbD0xZTMvayxtPWEuUHJvbWlzZXx8Yi5wcm9taXNlJiZiLnByb21pc2UuRVM2UHJvbWlzZSxuPXdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWV8fHdpbmRvdy5tc1JlcXVlc3RBbmltYXRpb25GcmFtZXx8d2luZG93LndlYmtpdFJlcXVlc3RBbmltYXRpb25GcmFtZXx8d2luZG93Lm1velJlcXVlc3RBbmltYXRpb25GcmFtZXx8YyxvPXdpbmRvdy5jYW5jZWxBbmltYXRpb25GcmFtZXx8d2luZG93Lm1zQ2FuY2VsQW5pbWF0aW9uRnJhbWV8fHdpbmRvdy53ZWJraXRDYW5jZWxBbmltYXRpb25GcmFtZXx8d2luZG93Lm1vekNhbmNlbEFuaW1hdGlvbkZyYW1lfHxkOyhuPT09Y3x8bz09PWQpJiYobj1jLG89ZCksYi5hbmltYXRpb249ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBuZXcgaihhLGIsYyl9LGIuYW5pbWF0aW9uLmZyYW1lPWZ1bmN0aW9uKGEpe3JldHVybiBuZXcgZyhhKX0sYi5hbmltYXRpb24ucmVxdWVzdEZyYW1lPWZ1bmN0aW9uKGEpe3ZhciBiPW5ldyBnKGEpO3JldHVybiBiLnJlcXVlc3QoKX19KHdpbmRvdyx3aW5kb3cubGlifHwod2luZG93LmxpYj17fSkpOzttb2R1bGUuZXhwb3J0cyA9IHdpbmRvdy5saWJbJ2FuaW1hdGlvbiddO1xuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2FuaW1hdGlvbmpzL2J1aWxkL2FuaW1hdGlvbi5jb21tb24uanNcbiAqKiBtb2R1bGUgaWQgPSAzM1xuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnKSAmJiAod2luZG93ID0ge2N0cmw6IHt9LCBsaWI6IHt9fSk7IXdpbmRvdy5jdHJsICYmICh3aW5kb3cuY3RybCA9IHt9KTshd2luZG93LmxpYiAmJiAod2luZG93LmxpYiA9IHt9KTshZnVuY3Rpb24oYSxiKXtmdW5jdGlvbiBjKGEsYixjLGQpe2Z1bmN0aW9uIGUoYSl7cmV0dXJuKDMqayphKzIqbCkqYSttfWZ1bmN0aW9uIGYoYSl7cmV0dXJuKChrKmErbCkqYSttKSphfWZ1bmN0aW9uIGcoYSl7cmV0dXJuKChuKmErbykqYStwKSphfWZ1bmN0aW9uIGgoYSl7Zm9yKHZhciBiLGMsZD1hLGc9MDs4Pmc7ZysrKXtpZihjPWYoZCktYSxNYXRoLmFicyhjKTxqKXJldHVybiBkO2lmKGI9ZShkKSxNYXRoLmFicyhiKTxqKWJyZWFrO2QtPWMvYn12YXIgaD0xLGk9MDtmb3IoZD1hO2g+aTspe2lmKGM9ZihkKS1hLE1hdGguYWJzKGMpPGopcmV0dXJuIGQ7Yz4wP2g9ZDppPWQsZD0oaCtpKS8yfXJldHVybiBkfWZ1bmN0aW9uIGkoYSl7cmV0dXJuIGcoaChhKSl9dmFyIGo9MWUtNixrPTMqYS0zKmMrMSxsPTMqYy02KmEsbT0zKmEsbj0zKmItMypkKzEsbz0zKmQtNipiLHA9MypiO3JldHVybiBpfWIuY3ViaWNiZXppZXI9YyxiLmN1YmljYmV6aWVyLmxpbmVhcj1jKDAsMCwxLDEpLGIuY3ViaWNiZXppZXIuZWFzZT1jKC4yNSwuMSwuMjUsMSksYi5jdWJpY2Jlemllci5lYXNlSW49YyguNDIsMCwxLDEpLGIuY3ViaWNiZXppZXIuZWFzZU91dD1jKDAsMCwuNTgsMSksYi5jdWJpY2Jlemllci5lYXNlSW5PdXQ9YyguNDIsMCwuNTgsMSl9KHdpbmRvdyx3aW5kb3cubGlifHwod2luZG93LmxpYj17fSkpOzttb2R1bGUuZXhwb3J0cyA9IHdpbmRvdy5saWJbJ2N1YmljYmV6aWVyJ107XG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vY3ViaWNiZXppZXIvYnVpbGQvY3ViaWNiZXppZXIuY29tbW9uLmpzXG4gKiogbW9kdWxlIGlkID0gMzRcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIih0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykgJiYgKHdpbmRvdyA9IHtjdHJsOiB7fSwgbGliOiB7fX0pOyF3aW5kb3cuY3RybCAmJiAod2luZG93LmN0cmwgPSB7fSk7IXdpbmRvdy5saWIgJiYgKHdpbmRvdy5saWIgPSB7fSk7IWZ1bmN0aW9uKGEpe1widXNlIHN0cmljdFwiO2Z1bmN0aW9uIGIoYSxiKXtmb3IodmFyIGM9YTtjOyl7aWYoYy5jb250YWlucyhiKXx8Yz09YilyZXR1cm4gYztjPWMucGFyZW50Tm9kZX1yZXR1cm4gbnVsbH1mdW5jdGlvbiBjKGEsYixjKXt2YXIgZD1pLmNyZWF0ZUV2ZW50KFwiSFRNTEV2ZW50c1wiKTtpZihkLmluaXRFdmVudChiLCEwLCEwKSxcIm9iamVjdFwiPT10eXBlb2YgYylmb3IodmFyIGUgaW4gYylkW2VdPWNbZV07YS5kaXNwYXRjaEV2ZW50KGQpfWZ1bmN0aW9uIGQoYSxiLGMsZCxlLGYsZyxoKXt2YXIgaT1NYXRoLmF0YW4yKGgtZixnLWUpLU1hdGguYXRhbjIoZC1iLGMtYSksaj1NYXRoLnNxcnQoKE1hdGgucG93KGgtZiwyKStNYXRoLnBvdyhnLWUsMikpLyhNYXRoLnBvdyhkLWIsMikrTWF0aC5wb3coYy1hLDIpKSksaz1bZS1qKmEqTWF0aC5jb3MoaSkraipiKk1hdGguc2luKGkpLGYtaipiKk1hdGguY29zKGkpLWoqYSpNYXRoLnNpbihpKV07cmV0dXJue3JvdGF0ZTppLHNjYWxlOmosdHJhbnNsYXRlOmssbWF0cml4OltbaipNYXRoLmNvcyhpKSwtaipNYXRoLnNpbihpKSxrWzBdXSxbaipNYXRoLnNpbihpKSxqKk1hdGguY29zKGkpLGtbMV1dLFswLDAsMV1dfX1mdW5jdGlvbiBlKGEpezA9PT1PYmplY3Qua2V5cyhsKS5sZW5ndGgmJihqLmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaG1vdmVcIixmLCExKSxqLmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaGVuZFwiLGcsITEpLGouYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNoY2FuY2VsXCIsaCwhMSkpO2Zvcih2YXIgZD0wO2Q8YS5jaGFuZ2VkVG91Y2hlcy5sZW5ndGg7ZCsrKXt2YXIgZT1hLmNoYW5nZWRUb3VjaGVzW2RdLGk9e307Zm9yKHZhciBtIGluIGUpaVttXT1lW21dO3ZhciBuPXtzdGFydFRvdWNoOmksc3RhcnRUaW1lOkRhdGUubm93KCksc3RhdHVzOlwidGFwcGluZ1wiLGVsZW1lbnQ6YS5zcmNFbGVtZW50fHxhLnRhcmdldCxwcmVzc2luZ0hhbmRsZXI6c2V0VGltZW91dChmdW5jdGlvbihiLGQpe3JldHVybiBmdW5jdGlvbigpe1widGFwcGluZ1wiPT09bi5zdGF0dXMmJihuLnN0YXR1cz1cInByZXNzaW5nXCIsYyhiLFwibG9uZ3ByZXNzXCIse3RvdWNoOmQsdG91Y2hlczphLnRvdWNoZXMsY2hhbmdlZFRvdWNoZXM6YS5jaGFuZ2VkVG91Y2hlcyx0b3VjaEV2ZW50OmF9KSksY2xlYXJUaW1lb3V0KG4ucHJlc3NpbmdIYW5kbGVyKSxuLnByZXNzaW5nSGFuZGxlcj1udWxsfX0oYS5zcmNFbGVtZW50fHxhLnRhcmdldCxhLmNoYW5nZWRUb3VjaGVzW2RdKSw1MDApfTtsW2UuaWRlbnRpZmllcl09bn1pZigyPT1PYmplY3Qua2V5cyhsKS5sZW5ndGgpe3ZhciBvPVtdO2Zvcih2YXIgbSBpbiBsKW8ucHVzaChsW21dLmVsZW1lbnQpO2MoYihvWzBdLG9bMV0pLFwiZHVhbHRvdWNoc3RhcnRcIix7dG91Y2hlczprLmNhbGwoYS50b3VjaGVzKSx0b3VjaEV2ZW50OmF9KX19ZnVuY3Rpb24gZihhKXtmb3IodmFyIGU9MDtlPGEuY2hhbmdlZFRvdWNoZXMubGVuZ3RoO2UrKyl7dmFyIGY9YS5jaGFuZ2VkVG91Y2hlc1tlXSxnPWxbZi5pZGVudGlmaWVyXTtpZighZylyZXR1cm47Zy5sYXN0VG91Y2h8fChnLmxhc3RUb3VjaD1nLnN0YXJ0VG91Y2gpLGcubGFzdFRpbWV8fChnLmxhc3RUaW1lPWcuc3RhcnRUaW1lKSxnLnZlbG9jaXR5WHx8KGcudmVsb2NpdHlYPTApLGcudmVsb2NpdHlZfHwoZy52ZWxvY2l0eVk9MCksZy5kdXJhdGlvbnx8KGcuZHVyYXRpb249MCk7dmFyIGg9RGF0ZS5ub3coKS1nLmxhc3RUaW1lLGk9KGYuY2xpZW50WC1nLmxhc3RUb3VjaC5jbGllbnRYKS9oLGo9KGYuY2xpZW50WS1nLmxhc3RUb3VjaC5jbGllbnRZKS9oLGs9NzA7aD5rJiYoaD1rKSxnLmR1cmF0aW9uK2g+ayYmKGcuZHVyYXRpb249ay1oKSxnLnZlbG9jaXR5WD0oZy52ZWxvY2l0eVgqZy5kdXJhdGlvbitpKmgpLyhnLmR1cmF0aW9uK2gpLGcudmVsb2NpdHlZPShnLnZlbG9jaXR5WSpnLmR1cmF0aW9uK2oqaCkvKGcuZHVyYXRpb24raCksZy5kdXJhdGlvbis9aCxnLmxhc3RUb3VjaD17fTtmb3IodmFyIG0gaW4gZilnLmxhc3RUb3VjaFttXT1mW21dO2cubGFzdFRpbWU9RGF0ZS5ub3coKTt2YXIgbj1mLmNsaWVudFgtZy5zdGFydFRvdWNoLmNsaWVudFgsbz1mLmNsaWVudFktZy5zdGFydFRvdWNoLmNsaWVudFkscD1NYXRoLnNxcnQoTWF0aC5wb3cobiwyKStNYXRoLnBvdyhvLDIpKTsoXCJ0YXBwaW5nXCI9PT1nLnN0YXR1c3x8XCJwcmVzc2luZ1wiPT09Zy5zdGF0dXMpJiZwPjEwJiYoZy5zdGF0dXM9XCJwYW5uaW5nXCIsZy5pc1ZlcnRpY2FsPSEoTWF0aC5hYnMobik+TWF0aC5hYnMobykpLGMoZy5lbGVtZW50LFwicGFuc3RhcnRcIix7dG91Y2g6Zix0b3VjaGVzOmEudG91Y2hlcyxjaGFuZ2VkVG91Y2hlczphLmNoYW5nZWRUb3VjaGVzLHRvdWNoRXZlbnQ6YSxpc1ZlcnRpY2FsOmcuaXNWZXJ0aWNhbH0pLGMoZy5lbGVtZW50LChnLmlzVmVydGljYWw/XCJ2ZXJ0aWNhbFwiOlwiaG9yaXpvbnRhbFwiKStcInBhbnN0YXJ0XCIse3RvdWNoOmYsdG91Y2hFdmVudDphfSkpLFwicGFubmluZ1wiPT09Zy5zdGF0dXMmJihnLnBhblRpbWU9RGF0ZS5ub3coKSxjKGcuZWxlbWVudCxcInBhbm1vdmVcIix7ZGlzcGxhY2VtZW50WDpuLGRpc3BsYWNlbWVudFk6byx0b3VjaDpmLHRvdWNoZXM6YS50b3VjaGVzLGNoYW5nZWRUb3VjaGVzOmEuY2hhbmdlZFRvdWNoZXMsdG91Y2hFdmVudDphLGlzVmVydGljYWw6Zy5pc1ZlcnRpY2FsfSksZy5pc1ZlcnRpY2FsP2MoZy5lbGVtZW50LFwidmVydGljYWxwYW5tb3ZlXCIse2Rpc3BsYWNlbWVudFk6byx0b3VjaDpmLHRvdWNoRXZlbnQ6YX0pOmMoZy5lbGVtZW50LFwiaG9yaXpvbnRhbHBhbm1vdmVcIix7ZGlzcGxhY2VtZW50WDpuLHRvdWNoOmYsdG91Y2hFdmVudDphfSkpfWlmKDI9PU9iamVjdC5rZXlzKGwpLmxlbmd0aCl7Zm9yKHZhciBxLHI9W10scz1bXSx0PVtdLGU9MDtlPGEudG91Y2hlcy5sZW5ndGg7ZSsrKXt2YXIgZj1hLnRvdWNoZXNbZV0sZz1sW2YuaWRlbnRpZmllcl07ci5wdXNoKFtnLnN0YXJ0VG91Y2guY2xpZW50WCxnLnN0YXJ0VG91Y2guY2xpZW50WV0pLHMucHVzaChbZi5jbGllbnRYLGYuY2xpZW50WV0pfWZvcih2YXIgbSBpbiBsKXQucHVzaChsW21dLmVsZW1lbnQpO3E9ZChyWzBdWzBdLHJbMF1bMV0sclsxXVswXSxyWzFdWzFdLHNbMF1bMF0sc1swXVsxXSxzWzFdWzBdLHNbMV1bMV0pLGMoYih0WzBdLHRbMV0pLFwiZHVhbHRvdWNoXCIse3RyYW5zZm9ybTpxLHRvdWNoZXM6YS50b3VjaGVzLHRvdWNoRXZlbnQ6YX0pfX1mdW5jdGlvbiBnKGEpe2lmKDI9PU9iamVjdC5rZXlzKGwpLmxlbmd0aCl7dmFyIGQ9W107Zm9yKHZhciBlIGluIGwpZC5wdXNoKGxbZV0uZWxlbWVudCk7YyhiKGRbMF0sZFsxXSksXCJkdWFsdG91Y2hlbmRcIix7dG91Y2hlczprLmNhbGwoYS50b3VjaGVzKSx0b3VjaEV2ZW50OmF9KX1mb3IodmFyIGk9MDtpPGEuY2hhbmdlZFRvdWNoZXMubGVuZ3RoO2krKyl7dmFyIG49YS5jaGFuZ2VkVG91Y2hlc1tpXSxvPW4uaWRlbnRpZmllcixwPWxbb107aWYocCl7aWYocC5wcmVzc2luZ0hhbmRsZXImJihjbGVhclRpbWVvdXQocC5wcmVzc2luZ0hhbmRsZXIpLHAucHJlc3NpbmdIYW5kbGVyPW51bGwpLFwidGFwcGluZ1wiPT09cC5zdGF0dXMmJihwLnRpbWVzdGFtcD1EYXRlLm5vdygpLGMocC5lbGVtZW50LFwidGFwXCIse3RvdWNoOm4sdG91Y2hFdmVudDphfSksbSYmcC50aW1lc3RhbXAtbS50aW1lc3RhbXA8MzAwJiZjKHAuZWxlbWVudCxcImRvdWJsZXRhcFwiLHt0b3VjaDpuLHRvdWNoRXZlbnQ6YX0pLG09cCksXCJwYW5uaW5nXCI9PT1wLnN0YXR1cyl7dmFyIHE9RGF0ZS5ub3coKSxyPXEtcC5zdGFydFRpbWUscz0oKG4uY2xpZW50WC1wLnN0YXJ0VG91Y2guY2xpZW50WCkvciwobi5jbGllbnRZLXAuc3RhcnRUb3VjaC5jbGllbnRZKS9yLG4uY2xpZW50WC1wLnN0YXJ0VG91Y2guY2xpZW50WCksdD1uLmNsaWVudFktcC5zdGFydFRvdWNoLmNsaWVudFksdT1NYXRoLnNxcnQocC52ZWxvY2l0eVkqcC52ZWxvY2l0eVkrcC52ZWxvY2l0eVgqcC52ZWxvY2l0eVgpLHY9dT4uNSYmcS1wLmxhc3RUaW1lPDEwMCx3PXtkdXJhdGlvbjpyLGlzZmxpY2s6dix2ZWxvY2l0eVg6cC52ZWxvY2l0eVgsdmVsb2NpdHlZOnAudmVsb2NpdHlZLGRpc3BsYWNlbWVudFg6cyxkaXNwbGFjZW1lbnRZOnQsdG91Y2g6bix0b3VjaGVzOmEudG91Y2hlcyxjaGFuZ2VkVG91Y2hlczphLmNoYW5nZWRUb3VjaGVzLHRvdWNoRXZlbnQ6YSxpc1ZlcnRpY2FsOnAuaXNWZXJ0aWNhbH07YyhwLmVsZW1lbnQsXCJwYW5lbmRcIix3KSx2JiYoYyhwLmVsZW1lbnQsXCJzd2lwZVwiLHcpLHAuaXNWZXJ0aWNhbD9jKHAuZWxlbWVudCxcInZlcnRpY2Fsc3dpcGVcIix3KTpjKHAuZWxlbWVudCxcImhvcml6b250YWxzd2lwZVwiLHcpKX1cInByZXNzaW5nXCI9PT1wLnN0YXR1cyYmYyhwLmVsZW1lbnQsXCJwcmVzc2VuZFwiLHt0b3VjaDpuLHRvdWNoRXZlbnQ6YX0pLGRlbGV0ZSBsW29dfX0wPT09T2JqZWN0LmtleXMobCkubGVuZ3RoJiYoai5yZW1vdmVFdmVudExpc3RlbmVyKFwidG91Y2htb3ZlXCIsZiwhMSksai5yZW1vdmVFdmVudExpc3RlbmVyKFwidG91Y2hlbmRcIixnLCExKSxqLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJ0b3VjaGNhbmNlbFwiLGgsITEpKX1mdW5jdGlvbiBoKGEpe2lmKDI9PU9iamVjdC5rZXlzKGwpLmxlbmd0aCl7dmFyIGQ9W107Zm9yKHZhciBlIGluIGwpZC5wdXNoKGxbZV0uZWxlbWVudCk7YyhiKGRbMF0sZFsxXSksXCJkdWFsdG91Y2hlbmRcIix7dG91Y2hlczprLmNhbGwoYS50b3VjaGVzKSx0b3VjaEV2ZW50OmF9KX1mb3IodmFyIGk9MDtpPGEuY2hhbmdlZFRvdWNoZXMubGVuZ3RoO2krKyl7dmFyIG09YS5jaGFuZ2VkVG91Y2hlc1tpXSxuPW0uaWRlbnRpZmllcixvPWxbbl07byYmKG8ucHJlc3NpbmdIYW5kbGVyJiYoY2xlYXJUaW1lb3V0KG8ucHJlc3NpbmdIYW5kbGVyKSxvLnByZXNzaW5nSGFuZGxlcj1udWxsKSxcInBhbm5pbmdcIj09PW8uc3RhdHVzJiZjKG8uZWxlbWVudCxcInBhbmVuZFwiLHt0b3VjaDptLHRvdWNoZXM6YS50b3VjaGVzLGNoYW5nZWRUb3VjaGVzOmEuY2hhbmdlZFRvdWNoZXMsdG91Y2hFdmVudDphfSksXCJwcmVzc2luZ1wiPT09by5zdGF0dXMmJmMoby5lbGVtZW50LFwicHJlc3NlbmRcIix7dG91Y2g6bSx0b3VjaEV2ZW50OmF9KSxkZWxldGUgbFtuXSl9MD09PU9iamVjdC5rZXlzKGwpLmxlbmd0aCYmKGoucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInRvdWNobW92ZVwiLGYsITEpLGoucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInRvdWNoZW5kXCIsZywhMSksai5yZW1vdmVFdmVudExpc3RlbmVyKFwidG91Y2hjYW5jZWxcIixoLCExKSl9dmFyIGk9YS5kb2N1bWVudCxqPWkuZG9jdW1lbnRFbGVtZW50LGs9QXJyYXkucHJvdG90eXBlLnNsaWNlLGw9e30sbT1udWxsO2ouYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNoc3RhcnRcIixlLCExKX0od2luZG93KTs7bW9kdWxlLmV4cG9ydHMgPSB3aW5kb3cubGliWydnZXN0dXJlanMnXTtcblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9nZXN0dXJlanMvYnVpbGQvZ2VzdHVyZWpzLmNvbW1vbi5qc1xuICoqIG1vZHVsZSBpZCA9IDM1XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIodHlwZW9mIHdpbmRvdyA9PT0gJ3VuZGVmaW5lZCcpICYmICh3aW5kb3cgPSB7Y3RybDoge30sIGxpYjoge319KTshd2luZG93LmN0cmwgJiYgKHdpbmRvdy5jdHJsID0ge30pOyF3aW5kb3cubGliICYmICh3aW5kb3cubGliID0ge30pOyFmdW5jdGlvbihhLGIpe2Z1bmN0aW9uIGMoYSxiKXtyZXR1cm5bWyhhLzMrKGErYikvMy1hKS8oYi1hKSwoYSphLzMrYSpiKjIvMy1hKmEpLyhiKmItYSphKV0sWyhiLzMrKGErYikvMy1hKS8oYi1hKSwoYipiLzMrYSpiKjIvMy1hKmEpLyhiKmItYSphKV1dfWZ1bmN0aW9uIGQoYSl7aWYodGhpcy52PWEudnx8MCx0aGlzLmE9YS5hfHwwLFwidW5kZWZpbmVkXCIhPXR5cGVvZiBhLnQmJih0aGlzLnQ9YS50KSxcInVuZGVmaW5lZFwiIT10eXBlb2YgYS5zJiYodGhpcy5zPWEucyksXCJ1bmRlZmluZWRcIj09dHlwZW9mIHRoaXMudClpZihcInVuZGVmaW5lZFwiPT10eXBlb2YgdGhpcy5zKXRoaXMudD0tdGhpcy52L3RoaXMuYTtlbHNle3ZhciBiPShNYXRoLnNxcnQodGhpcy52KnRoaXMudisyKnRoaXMuYSp0aGlzLnMpLXRoaXMudikvdGhpcy5hLGM9KC1NYXRoLnNxcnQodGhpcy52KnRoaXMudisyKnRoaXMuYSp0aGlzLnMpLXRoaXMudikvdGhpcy5hO3RoaXMudD1NYXRoLm1pbihiLGMpfVwidW5kZWZpbmVkXCI9PXR5cGVvZiB0aGlzLnMmJih0aGlzLnM9dGhpcy5hKnRoaXMudCp0aGlzLnQvMit0aGlzLnYqdGhpcy50KX1kLnByb3RvdHlwZS5nZW5lcmF0ZUN1YmljQmV6aWVyPWZ1bmN0aW9uKCl7cmV0dXJuIGModGhpcy52L3RoaXMuYSx0aGlzLnQrdGhpcy52L3RoaXMuYSl9LGIubW90aW9uPWR9KHdpbmRvdyx3aW5kb3cubGlifHwod2luZG93LmxpYj17fSkpOzttb2R1bGUuZXhwb3J0cyA9IHdpbmRvdy5saWJbJ21vdGlvbiddO1xuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L21vdGlvbmpzL2J1aWxkL21vdGlvbi5jb21tb24uanNcbiAqKiBtb2R1bGUgaWQgPSAzNlxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnZhciBBdG9taWMgPSByZXF1aXJlKCcuL2F0b21pYycpXG5yZXF1aXJlKCdrb3VudGRvd24vYnVpbGQvY291bnRkb3duJylcblxudmFyIEZPUk1BVFRFUl9SRUdFWFAgPSAvKFxcXFwpPyhkZCp8aGg/fG1tP3xzcz8pL2dpXG5cbmZ1bmN0aW9uIGZvcm1hdERhdGVUaW1lKGRhdGEsIGZvcm1hdHRlciwgdGltZUNvbG9yKSB7XG4gIHJldHVybiBmb3JtYXR0ZXIucmVwbGFjZShGT1JNQVRURVJfUkVHRVhQLCBmdW5jdGlvbiAobSkge1xuICAgIHZhciBsZW4gPSBtLmxlbmd0aFxuICAgIHZhciBmaXJzdENoYXIgPSBtLmNoYXJBdCgwKVxuICAgIC8vIGVzY2FwZSBjaGFyYWN0ZXJcbiAgICBpZiAoZmlyc3RDaGFyID09PSAnXFxcXCcpIHtcbiAgICAgIHJldHVybiBtLnJlcGxhY2UoJ1xcXFwnLCAnJylcbiAgICB9XG4gICAgdmFyIHZhbHVlID0gKGZpcnN0Q2hhciA9PT0gJ2QnID8gZGF0YS5kYXlzIDpcbiAgICAgICAgICAgICAgICBmaXJzdENoYXIgPT09ICdoJyA/IGRhdGEuaG91cnMgOlxuICAgICAgICAgICAgICAgIGZpcnN0Q2hhciA9PT0gJ20nID8gZGF0YS5taW51dGVzIDpcbiAgICAgICAgICAgICAgICBmaXJzdENoYXIgPT09ICdzJyA/IGRhdGEuc2Vjb25kcyA6IDApICsgJydcblxuICAgIC8vIDUgemVybyBzaG91bGQgYmUgZW5vdWdoXG4gICAgcmV0dXJuICc8c3BhbiBzdHlsZT1cIm1hcmdpbjo0cHg7Y29sb3I6J1xuICAgICAgKyB0aW1lQ29sb3IgKyAnXCIgPidcbiAgICAgICsgKCcwMDAwMCcgKyB2YWx1ZSkuc3Vic3RyKC1NYXRoLm1heCh2YWx1ZS5sZW5ndGgsIGxlbikpXG4gICAgICArICc8L3NwYW4+J1xuICB9KVxufVxuXG5mdW5jdGlvbiBDb3VudGRvd24gKGRhdGEpIHtcbiAgQXRvbWljLmNhbGwodGhpcywgZGF0YSlcbn1cblxuQ291bnRkb3duLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoQXRvbWljLnByb3RvdHlwZSlcblxuQ291bnRkb3duLnByb3RvdHlwZS5jcmVhdGUgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBub2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgbm9kZS5jbGFzc0xpc3QuYWRkKCd3ZWV4LWVsZW1lbnQnKVxuICB2YXIgZGF0YSA9IHRoaXMuZGF0YVxuICB2YXIgdGltZSA9IE51bWJlcihkYXRhLmF0dHIuY291bnRkb3duVGltZSkgfHwgMFxuICB2YXIgZW5kVGltZSA9IERhdGUubm93KCkgLyAxMDAwICsgdGltZVxuICB2YXIgY2QgPSBsaWIuY291bnRkb3duKHtcbiAgICBlbmREYXRlOiBlbmRUaW1lLFxuICAgIG9uVXBkYXRlOiBmdW5jdGlvbiAodGltZSkge1xuICAgICAgdmFyIHRpbWVDb2xvciA9IGRhdGEuc3R5bGUudGltZUNvbG9yIHx8ICcjMDAwJ1xuICAgICAgdmFyIHJlc3VsdCA9IGZvcm1hdERhdGVUaW1lKHRpbWUsIGRhdGEuYXR0ci5mb3JtYXR0ZXJWYWx1ZSwgdGltZUNvbG9yKVxuICAgICAgbm9kZS5pbm5lckhUTUwgPSByZXN1bHRcbiAgICB9LFxuICAgIG9uRW5kOiBmdW5jdGlvbiAoKSB7XG4gICAgfVxuICB9KS5zdGFydCgpXG5cbiAgcmV0dXJuIG5vZGVcbn1cblxuQ291bnRkb3duLnByb3RvdHlwZS5zdHlsZSA9IHtcbiAgdGV4dENvbG9yOiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICB0aGlzLm5vZGUuc3R5bGUuY29sb3IgPSB2YWx1ZVxuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gQ291bnRkb3duXG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL2NvbXBvbmVudHMvY291bnRkb3duLmpzXG4gKiogbW9kdWxlIGlkID0gMzdcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIiFmdW5jdGlvbihhLGIpe2Z1bmN0aW9uIGMoYSl7dmFyIGI7aWYoXCJudW1iZXJcIj09dHlwZW9mIGEpYj1uZXcgRGF0ZSgxZTMqYSk7ZWxzZSBpZihcInN0cmluZ1wiPT10eXBlb2YgYSl7dmFyIGM9YS5jaGFyQXQoMCksZD1cIitcIj09PWMsaD1cIi1cIj09PWM7aWYoZHx8aCl7Zm9yKHZhciBpLGo9YS5zdWJzdHIoMSksaz1qLnNwbGl0KFwiOlwiKSxsPVswLDAsMCwwXSxtPTQ7ay5sZW5ndGgmJi0tbT49MDspbFttXT1wYXJzZUludChrLnBvcCgpKXx8MDtpPWUqbFswXStmKmxbMV0rZypsWzJdK2xbM10sYj1uZXcgRGF0ZSxiLnNldFNlY29uZHMoYi5nZXRTZWNvbmRzKCkraSooaD8tMToxKSksYi5zZXRNaWxsaXNlY29uZHMoMCl9fXJldHVybiBifHwoYj1uZXcgRGF0ZShhKSksYn1mdW5jdGlvbiBkKGEsYil7cmV0dXJuIGIucmVwbGFjZShGT1JNQVRURVJfUkVHRVhQLGZ1bmN0aW9uKGIpe3ZhciBjPWIubGVuZ3RoLGQ9Yi5jaGFyQXQoMCk7aWYoXCJcXFxcXCI9PT1kKXJldHVybiBiLnJlcGxhY2UoXCJcXFxcXCIsXCJcIik7dmFyIGU9KFwiZFwiPT09ZD9hLmRheXM6XCJoXCI9PT1kP2EuaG91cnM6XCJtXCI9PT1kP2EubWludXRlczpcInNcIj09PWQ/YS5zZWNvbmRzOjApK1wiXCI7cmV0dXJuKFwiMDAwMDBcIitlKS5zdWJzdHIoLU1hdGgubWF4KGUubGVuZ3RoLGMpKX0pfXZhciBlPTg2NDAwLGY9MzYwMCxnPTYwLGg9XCJk5aSpaGjml7ZtbeWIhnNz56eSXCI7Rk9STUFUVEVSX1JFR0VYUD0vKFxcXFwpPyhkZCp8aGg/fG1tP3xzcz8pL2dpO3ZhciBpPWZ1bmN0aW9uKGEpe2E9YXx8e307dmFyIGI9dGhpcyxkPWMoYS5lbmREYXRlKTtpZighZHx8IWQuZ2V0VGltZSgpKXRocm93IG5ldyBFcnJvcihcIkludmFsaWQgZW5kRGF0ZVwiKTtiLmVuZERhdGU9ZCxiLm9uVXBkYXRlPWEub25VcGRhdGUsYi5vbkVuZD1hLm9uRW5kLGIuaW50ZXJ2YWw9YS5pbnRlcnZhbHx8MWUzLGIuc3RyaW5nRm9ybWF0dGVyPWEuc3RyaW5nRm9ybWF0dGVyfHxoLGIuY29ycmVjdERhdGVPZmZzZXQ9YS5jb3JyZWN0RGF0ZU9mZnNldHx8MCxiLnVwZGF0ZUVsZW1lbnQ9YS51cGRhdGVFbGVtZW50LGIuX2RhdGE9e2RheXM6MCxob3VyczowLG1pbnV0ZXM6MCxzZWNvbmRzOjB9fTtpLnByb3RvdHlwZT17c3RhcnQ6ZnVuY3Rpb24oKXt2YXIgYT10aGlzO3JldHVybiBhLnN0b3AoKSxhLl91cGRhdGUoKSYmKGEuX2ludGVydmFsSWQ9c2V0SW50ZXJ2YWwoZnVuY3Rpb24oKXthLl91cGRhdGUoKX0sYS5pbnRlcnZhbCkpLGF9LF91cGRhdGU6ZnVuY3Rpb24oKXt2YXIgYSxiPXRoaXMsYz1iLl9kYXRhLGg9Yi51cGRhdGVFbGVtZW50LGk9K25ldyBEYXRlKzFlMypiLmNvcnJlY3REYXRlT2Zmc2V0LGo9TWF0aC5tYXgoMCxNYXRoLnJvdW5kKChiLmVuZERhdGUuZ2V0VGltZSgpLWkpLzFlMykpLGs9MD49ajtyZXR1cm4gYy50b3RhbFNlY29uZHM9aixqLT0oYy5kYXlzPU1hdGguZmxvb3Ioai9lKSkqZSxqLT0oYy5ob3Vycz1NYXRoLmZsb29yKGovZikpKmYsai09KGMubWludXRlcz1NYXRoLmZsb29yKGovZykpKmcsYy5zZWNvbmRzPWosYy5zdHJpbmdWYWx1ZT1kKGMsYi5zdHJpbmdGb3JtYXR0ZXIpLGgmJihoLmlubmVySFRNTD1jLnN0cmluZ1ZhbHVlKSwoYT1iLm9uVXBkYXRlKSYmYS5jYWxsKGIsYyksaz8oYi5zdG9wKCksKGE9Yi5vbkVuZCkmJmEuY2FsbChiKSwhMSk6ITB9LHN0b3A6ZnVuY3Rpb24oKXt2YXIgYT10aGlzO3JldHVybiBhLl9pbnRlcnZhbElkJiYoY2xlYXJJbnRlcnZhbChhLl9pbnRlcnZhbElkKSxhLl9pbnRlcnZhbElkPW51bGwpLGF9LHNldEVuZERhdGU6ZnVuY3Rpb24oYSl7dmFyIGI9dGhpcztyZXR1cm4gYi5lbmREYXRlPWMoYSksYn19LGIuY291bnRkb3duPWZ1bmN0aW9uKGEpe3JldHVybiBuZXcgaShhKX19KHdpbmRvdyx3aW5kb3cubGlifHwod2luZG93LmxpYj17fSkpO1xuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2tvdW50ZG93bi9idWlsZC9jb3VudGRvd24uanNcbiAqKiBtb2R1bGUgaWQgPSAzOFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnZhciBjb25maWcgPSByZXF1aXJlKCcuLi9jb25maWcnKVxudmFyIENvbXBvbmVudCA9IHJlcXVpcmUoJy4vY29tcG9uZW50JylcbnZhciBDb21wb25lbnRNYW5hZ2VyID0gcmVxdWlyZSgnLi4vY29tcG9uZW50TWFuYWdlcicpXG52YXIgTGF6eUxvYWQgPSByZXF1aXJlKCcuLi9sYXp5TG9hZCcpXG5cbmZ1bmN0aW9uIE1hcnF1ZWUgKGRhdGEpIHtcbiAgdGhpcy5pbnRlcnZhbCA9IE51bWJlcihkYXRhLmF0dHIuaW50ZXJ2YWwpIHx8IDUgKiAxMDAwXG4gIHRoaXMudHJhbnNpdGlvbkR1cmF0aW9uID0gTnVtYmVyKGRhdGEuYXR0ci50cmFuc2l0aW9uRHVyYXRpb24pIHx8IDUwMFxuICB0aGlzLmRlbGF5ID0gTnVtYmVyKGRhdGEuYXR0ci5kZWxheSkgfHwgMFxuICBDb21wb25lbnQuY2FsbCh0aGlzLCBkYXRhKVxufVxuXG5NYXJxdWVlLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoQ29tcG9uZW50LnByb3RvdHlwZSlcblxuTWFycXVlZS5wcm90b3R5cGUuY3JlYXRlID0gZnVuY3Rpb24gKCkge1xuICB2YXIgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gIG5vZGUuY2xhc3NMaXN0LmFkZCgnd2VleC1jb250YWluZXInKVxuICBub2RlLnN0eWxlLm92ZXJmbG93ID0gJ2hpZGRlbidcbiAgLy8gZml4IHBhZ2Ugc2hha2luZyBkdXJpbmcgc2xpZGVyJ3MgcGxheWluZ1xuICBub2RlLnN0eWxlLndlYmtpdFRyYW5zZm9ybSA9ICd0cmFuc2xhdGUzRCgwLDAsMCknXG4gIG5vZGUuYWRkRXZlbnRMaXN0ZW5lcignd2Via2l0VHJhbnNpdGlvbkVuZCcsIHRoaXMuZW5kLmJpbmQodGhpcyksIGZhbHNlKVxuICByZXR1cm4gbm9kZVxufVxuXG5NYXJxdWVlLnByb3RvdHlwZS5jcmVhdGVDaGlsZHJlbiA9IGZ1bmN0aW9uICgpIHtcbiAgLy8gZmlyc3QgcnVuOlxuICAvLyAtIGNyZWF0ZSBlYWNoIGNoaWxkXG4gIC8vIC0gYXBwZW5kIHRvIHBhcmVudE5vZGVcbiAgLy8gLSBmaW5kIGN1cnJlbnQgYW5kIG5leHRcbiAgLy8gLSBzZXQgY3VycmVudCBhbmQgbmV4dCBzaG93biBhbmQgb3RoZXJzIGhpZGRlblxuICB2YXIgY2hpbGRyZW4gPSB0aGlzLmRhdGEuY2hpbGRyZW5cbiAgdmFyIHBhcmVudFJlZiA9IHRoaXMuZGF0YS5yZWZcbiAgdmFyIGluc3RhbmNlSWQgPSB0aGlzLmRhdGEuaW5zdGFuY2VJZFxuICB2YXIgaXRlbXMgPSBbXVxuICB2YXIgY29tcG9uZW50TWFuYWdlciA9IHRoaXMuZ2V0Q29tcG9uZW50TWFuYWdlcigpXG5cbiAgdmFyIGZyYWdtZW50LCBpc0ZsZXgsIGNoaWxkLCBub2RlLCBpXG5cbiAgaWYgKGNoaWxkcmVuICYmIGNoaWxkcmVuLmxlbmd0aCkge1xuICAgIGZyYWdtZW50ID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpXG4gICAgaXNGbGV4ID0gZmFsc2VcbiAgICBmb3IgKGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNoaWxkcmVuW2ldLnNjYWxlID0gdGhpcy5kYXRhLnNjYWxlXG4gICAgICBjaGlsZHJlbltpXS5pbnN0YW5jZUlkID0gaW5zdGFuY2VJZFxuICAgICAgY2hpbGQgPSBjb21wb25lbnRNYW5hZ2VyLmNyZWF0ZUVsZW1lbnQoY2hpbGRyZW5baV0pXG4gICAgICBjaGlsZC5wYXJlbnRSZWYgPSBwYXJlbnRSZWZcbiAgICAgIHRoaXMuaW5pdENoaWxkKGNoaWxkKVxuICAgICAgLy8gYXBwZW5kIGFuZCBwdXNoXG4gICAgICBpdGVtcy5wdXNoKGNoaWxkKVxuICAgICAgZnJhZ21lbnQuYXBwZW5kQ2hpbGQoY2hpbGQubm9kZSlcbiAgICAgIGlmICghaXNGbGV4ICYmIGNoaWxkLmRhdGEuc3R5bGUuaGFzT3duUHJvcGVydHkoJ2ZsZXgnKSkge1xuICAgICAgICBpc0ZsZXggPSB0cnVlXG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMubm9kZS5hcHBlbmRDaGlsZChmcmFnbWVudClcbiAgfVxuXG4gIC8vIHNldCBpdGVtc1xuICB0aGlzLml0ZW1zID0gaXRlbXNcblxuICAvLyByZXNldCB0aGUgY2xvY2sgZm9yIGZpcnN0IHRyYW5zaXRpb25cbiAgdGhpcy5yZXNldCgpXG59XG5cbk1hcnF1ZWUucHJvdG90eXBlLmluaXRDaGlsZCA9IGZ1bmN0aW9uIChjaGlsZCkge1xuICB2YXIgbm9kZSA9IGNoaWxkLm5vZGVcbiAgbm9kZS5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSdcbiAgbm9kZS5zdHlsZS50b3AgPSAnMCdcbiAgbm9kZS5zdHlsZS5sZWZ0ID0gJzAnXG59XG5cbk1hcnF1ZWUucHJvdG90eXBlLmFwcGVuZENoaWxkID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgLy8gZG9tICsgaXRlbXNcbiAgdmFyIGNvbXBvbmVudE1hbmFnZXIgPSBDb21wb25lbnRNYW5hZ2VyLmdldEluc3RhbmNlKHRoaXMuZGF0YS5pbnN0YW5jZUlkKVxuICB2YXIgY2hpbGQgPSBjb21wb25lbnRNYW5hZ2VyLmNyZWF0ZUVsZW1lbnQoZGF0YSlcbiAgdGhpcy5pbml0Q2hpbGQoY2hpbGQpXG4gIHRoaXMubm9kZS5hcHBlbmRDaGlsZChjaGlsZC5ub2RlKVxuICB0aGlzLml0ZW1zLnB1c2goY2hpbGQpXG4gIHRoaXMucmVzZXQoKVxuICByZXR1cm4gY2hpbGQgLy8gQHRvZG8gcmVkZXNpZ24gQ29tcG9uZW50I2FwcGVuZENoaWxkKGNvbXBvbmVudClcbn1cblxuTWFycXVlZS5wcm90b3R5cGUuaW5zZXJ0QmVmb3JlID0gZnVuY3Rpb24gKGNoaWxkLCBiZWZvcmUpIHtcbiAgLy8gZG9tICsgaXRlbXNcbiAgdmFyIGluZGV4ID0gdGhpcy5pdGVtcy5pbmRleE9mKGJlZm9yZSlcbiAgdGhpcy5pdGVtcy5zcGxpY2UoaW5kZXgsIDAsIGNoaWxkKVxuICB0aGlzLmluaXRDaGlsZChjaGlsZClcbiAgdGhpcy5ub2RlLmluc2VydEJlZm9yZShjaGlsZC5ub2RlLCBiZWZvcmUubm9kZSlcbiAgdGhpcy5yZXNldCgpXG59XG5cbk1hcnF1ZWUucHJvdG90eXBlLnJlbW92ZUNoaWxkID0gZnVuY3Rpb24gKGNoaWxkKSB7XG4gIC8vIGRvbSArIGl0ZW1zXG4gIHZhciBpbmRleCA9IHRoaXMuaXRlbXMuaW5kZXhPZihjaGlsZClcbiAgdGhpcy5pdGVtcy5zcGxpY2UoaW5kZXgsIDEpXG4gIHRoaXMubm9kZS5yZW1vdmVDaGlsZChjaGlsZC5ub2RlKVxuICB0aGlzLnJlc2V0KClcbn1cblxuLyoqXG4gKiBzdGF0dXM6IHtcbiAqICAgY3VycmVudDoge3RyYW5zbGF0ZVk6IDAsIHNob3duOiB0cnVlfSxcbiAqICAgbmV4dDoge3RyYW5zbGF0ZVk6IGhlaWdodCwgc2hvd246IHRydWV9LFxuICogICBvdGhlcnNbXToge3Nob3duOiBmYWxzZX1cbiAqICAgaW5kZXg6IGluZGV4XG4gKiB9XG4gKi9cbk1hcnF1ZWUucHJvdG90eXBlLnJlc2V0ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgaW50ZXJ2YWwgPSB0aGlzLmludGVydmFsIC0gMFxuICB2YXIgZGVsYXkgPSB0aGlzLmRlbGF5IC0gMFxuICB2YXIgaXRlbXMgPSB0aGlzLml0ZW1zXG4gIHZhciBzZWxmID0gdGhpc1xuXG4gIHZhciBsb29wID0gZnVuY3Rpb24gKCkge1xuICAgIHNlbGYubmV4dCgpXG4gICAgc2VsZi50aW1lcklkID0gc2V0VGltZW91dChsb29wLCBzZWxmLmludGVydmFsKVxuICB9XG5cbiAgLy8gcmVzZXQgZGlzcGxheSBhbmQgdHJhbnNmb3JtXG4gIGl0ZW1zLmZvckVhY2goZnVuY3Rpb24gKGl0ZW0sIGluZGV4KSB7XG4gICAgdmFyIG5vZGUgPSBpdGVtLm5vZGVcbiAgICAvLyBzZXQgbm9uLWN1cnJlbnQoMCl8bmV4dCgxKSBpdGVtIGhpZGRlblxuICAgIG5vZGUuc3R5bGUuZGlzcGxheSA9IGluZGV4ID4gMSA/ICdub25lJyA6ICcnXG4gICAgLy8gc2V0IG5leHQoMSkgaXRlbSB0cmFuc2xhdGVZXG4gICAgLy8gVE9ETzogaXQgc3VwcG9zZWQgdG8gdXNlIGl0ZW0uZGF0YS5zdHlsZVxuICAgIC8vIGJ1dCBzb21laG93IHRoZSBzdHlsZSBvYmplY3QgaXMgZW1wdHkuXG4gICAgLy8gVGhpcyBwcm9ibGVtIHJlbGllcyBvbiBqc2ZyYW1ld29yaydzIGJ1Z2ZpeC5cblxuICAgIC8vIG5vZGUuc3R5bGUudHJhbnNmb3JtID0gaW5kZXggPT09IDFcbiAgICAvLyAgICAgPyAndHJhbnNsYXRlM0QoMCwnICsgY29uZmlnLnNjYWxlICogaXRlbS5kYXRhLnN0eWxlLmhlaWdodCArICdweCwwKSdcbiAgICAvLyAgICAgOiAnJ1xuICAgIC8vIG5vZGUuc3R5bGUud2Via2l0VHJhbnNmb3JtID0gaW5kZXggPT09IDFcbiAgICAvLyAgICAgPyAndHJhbnNsYXRlM0QoMCwnICsgY29uZmlnLnNjYWxlICogaXRlbS5kYXRhLnN0eWxlLmhlaWdodCArICdweCwwKSdcbiAgICAvLyAgICAgOiAnJ1xuICAgIG5vZGUuc3R5bGUudHJhbnNmb3JtID0gaW5kZXggPT09IDFcbiAgICAgICAgPyAndHJhbnNsYXRlM0QoMCwnICsgc2VsZi5kYXRhLnNjYWxlICogc2VsZi5kYXRhLnN0eWxlLmhlaWdodCArICdweCwwKSdcbiAgICAgICAgOiAnJ1xuICAgIG5vZGUuc3R5bGUud2Via2l0VHJhbnNmb3JtID0gaW5kZXggPT09IDFcbiAgICAgICAgPyAndHJhbnNsYXRlM0QoMCwnICsgc2VsZi5kYXRhLnNjYWxlICogc2VsZi5kYXRhLnN0eWxlLmhlaWdodCArICdweCwwKSdcbiAgICAgICAgOiAnJ1xuICB9KVxuXG4gIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgIC8vIHJlc2V0IGN1cnJlbnQsIG5leHQsIGluZGV4XG4gICAgc2VsZi5jdXJyZW50SXRlbSA9IGl0ZW1zWzBdXG4gICAgc2VsZi5uZXh0SXRlbSA9IGl0ZW1zWzFdXG4gICAgc2VsZi5jdXJyZW50SW5kZXggPSAwXG5cbiAgICBpdGVtcy5mb3JFYWNoKGZ1bmN0aW9uIChpdGVtLCBpbmRleCkge1xuICAgICAgdmFyIG5vZGUgPSBpdGVtLm5vZGVcbiAgICAgIC8vIHNldCB0cmFuc2l0aW9uXG4gICAgICBub2RlLnN0eWxlLnRyYW5zaXRpb24gPSAndHJhbnNmb3JtICdcbiAgICAgICAgICArIHNlbGYudHJhbnNpdGlvbkR1cmF0aW9uXG4gICAgICAgICAgKyAnbXMgZWFzZSdcbiAgICAgIG5vZGUuc3R5bGUud2Via2l0VHJhbnNpdGlvbiA9ICctd2Via2l0LXRyYW5zZm9ybSAnXG4gICAgICAgICAgKyBzZWxmLnRyYW5zaXRpb25EdXJhdGlvblxuICAgICAgICAgICsgJ21zIGVhc2UnXG4gICAgfSlcblxuICAgIGNsZWFyVGltZW91dChzZWxmLnRpbWVySWQpXG5cbiAgICBpZiAoaXRlbXMubGVuZ3RoID4gMSkge1xuICAgICAgc2VsZi50aW1lcklkID0gc2V0VGltZW91dChsb29wLCBkZWxheSArIGludGVydmFsKVxuICAgIH1cbiAgfSwgMTMpXG5cbn1cblxuLyoqXG4gKiBuZXh0OlxuICogLSBjdXJyZW50OiB7dHJhbnNsYXRlWTogLWhlaWdodH1cbiAqIC0gbmV4dDoge3RyYW5zbGF0ZVk6IDB9XG4gKi9cbk1hcnF1ZWUucHJvdG90eXBlLm5leHQgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIC0gdXBkYXRlIHN0YXRlXG4gIC8vICAgLSBzZXQgY3VycmVudCBhbmQgbmV4dCB0cmFuc2l0aW9uXG4gIC8vICAgLSBoaWRlIGN1cnJlbnQgd2hlbiB0cmFuc2l0aW9uIGVuZFxuICAvLyAgIC0gc2V0IG5leHQgdG8gY3VycmVudFxuICAvLyAgIC0gZmluZCBuZXcgbmV4dFxuICB2YXIgbmV4dCA9IHRoaXMubmV4dEl0ZW0ubm9kZVxuICB2YXIgY3VycmVudCA9IHRoaXMuY3VycmVudEl0ZW0ubm9kZVxuICB0aGlzLnRyYW5zaXRpb25JbmRleCA9IHRoaXMuY3VycmVudEluZGV4XG5cbiAgLy8gVXNlIHNldFRpbWVvdXQgdG8gZml4IHRoZSBwcm9ibGVtIHRoYXQgd2hlbiB0aGVcbiAgLy8gcGFnZSByZWNvdmVyIGZyb20gYmFja3N0YWdlLCB0aGUgc2xpZGVyIHdpbGxcbiAgLy8gbm90IHdvcmsgYW55IGxvbmdlci5cbiAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgbmV4dC5zdHlsZS50cmFuc2Zvcm0gPSAndHJhbnNsYXRlM0QoMCwwLDApJ1xuICAgIG5leHQuc3R5bGUud2Via2l0VHJhbnNmb3JtID0gJ3RyYW5zbGF0ZTNEKDAsMCwwKSdcbiAgICBjdXJyZW50LnN0eWxlLnRyYW5zZm9ybSA9ICd0cmFuc2xhdGUzRCgwLC0nXG4gICAgICAgICsgdGhpcy5kYXRhLnNjYWxlICogdGhpcy5kYXRhLnN0eWxlLmhlaWdodFxuICAgICAgICArICdweCwwKSdcbiAgICBjdXJyZW50LnN0eWxlLndlYmtpdFRyYW5zZm9ybSA9ICd0cmFuc2xhdGUzRCgwLC0nXG4gICAgICAgICsgdGhpcy5kYXRhLnNjYWxlICogdGhpcy5kYXRhLnN0eWxlLmhlaWdodFxuICAgICAgICArICdweCwwKSdcbiAgICB0aGlzLmZpcmVFdmVudCgnY2hhbmdlJylcbiAgfS5iaW5kKHRoaXMpLCAzMDApXG59XG5cbk1hcnF1ZWUucHJvdG90eXBlLmZpcmVFdmVudCA9IGZ1bmN0aW9uICh0eXBlKSB7XG4gIHZhciBsZW5ndGggPSB0aGlzLml0ZW1zLmxlbmd0aFxuICB2YXIgbmV4dEluZGV4ID0gKHRoaXMuY3VycmVudEluZGV4ICsgMSkgJSBsZW5ndGhcbiAgdmFyIGV2dCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdIVE1MRXZlbnRzJylcbiAgZXZ0LmluaXRFdmVudCh0eXBlLCBmYWxzZSwgZmFsc2UpXG4gIGV2dC5kYXRhID0ge1xuICAgIHByZXZJbmRleDogdGhpcy5jdXJyZW50SW5kZXgsXG4gICAgaW5kZXg6IG5leHRJbmRleFxuICB9XG4gIHRoaXMubm9kZS5kaXNwYXRjaEV2ZW50KGV2dClcbn1cblxuLyoqXG4gKiBlbmQ6XG4gKiAtIG9sZCBjdXJyZW50OiB7c2hvd246IGZhbHNlfVxuICogLSBvbGQgY3VycmVudDoge3RyYW5zbGF0ZVk6IDB9XG4gKiAtIGluZGV4KysgJSBsZW5ndGhcbiAqIC0gbmV3IGN1cnJlbnQgPSBvbGQgbmV4dFxuICogLSBuZXcgbmV4dCA9IGl0ZW1zW2luZGV4KzEgJSBsZW5ndGhdXG4gKiAtIG5ldyBuZXh0OiB7dHJhbnNsYXRlWTogaGVpZ2h0fVxuICogLSBuZXcgbmV4dDoge3Nob3duOiB0cnVlfVxuICovXG5NYXJxdWVlLnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbiAoZSkge1xuICB2YXIgdGFyZ2V0ID0gZS50YXJnZXRcbiAgdmFyIGl0ZW1zID0gdGhpcy5pdGVtc1xuICB2YXIgbGVuZ3RoID0gaXRlbXMubGVuZ3RoXG4gIHZhciBjdXJyZW50LCBuZXh0XG4gIHZhciBjdXJyZW50SW5kZXgsIG5leHRJbmRleFxuXG4gIGN1cnJlbnRJbmRleCA9IHRoaXMudHJhbnNpdGlvbkluZGV4XG5cbiAgaWYgKGlzTmFOKGN1cnJlbnRJbmRleCkpIHtcbiAgICByZXR1cm5cbiAgfVxuICBkZWxldGUgdGhpcy50cmFuc2l0aW9uSW5kZXhcblxuICBjdXJyZW50ID0gdGhpcy5jdXJyZW50SXRlbS5ub2RlXG4gIGN1cnJlbnQuc3R5bGUuZGlzcGxheSA9ICdub25lJ1xuICBjdXJyZW50LnN0eWxlLndlYmtpdFRyYW5zZm9ybSA9ICcnXG5cbiAgY3VycmVudEluZGV4ID0gKGN1cnJlbnRJbmRleCArIDEpICUgbGVuZ3RoXG4gIG5leHRJbmRleCA9IChjdXJyZW50SW5kZXggKyAxKSAlIGxlbmd0aFxuXG4gIHRoaXMuY3VycmVudEluZGV4ID0gY3VycmVudEluZGV4XG4gIHRoaXMuY3VycmVudEl0ZW0gPSB0aGlzLm5leHRJdGVtXG4gIHRoaXMubmV4dEl0ZW0gPSBpdGVtc1tuZXh0SW5kZXhdXG5cbiAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgbmV4dCA9IHRoaXMubmV4dEl0ZW0ubm9kZVxuICAgIC8vIFRPRE86IGl0IHN1cHBvc2VkIHRvIHVzZSB0aGlzLm5leHRJdGVtLmRhdGEuc3R5bGVcbiAgICAvLyBidXQgc29tZWhvdyB0aGUgc3R5bGUgb2JqZWN0IGlzIGVtcHR5LlxuICAgIC8vIFRoaXMgcHJvYmxlbSByZWxpZXMgb24ganNmcmFtZXdvcmsncyBidWdmaXguXG5cbiAgICBuZXh0LnN0eWxlLndlYmtpdFRyYW5zZm9ybSA9ICd0cmFuc2xhdGUzRCgwLCdcbiAgICAgICAgKyB0aGlzLmRhdGEuc2NhbGUgKiB0aGlzLmRhdGEuc3R5bGUuaGVpZ2h0XG4gICAgICAgICsgJ3B4LDApJ1xuICAgIG5leHQuc3R5bGUuZGlzcGxheSA9ICcnXG4gICAgTGF6eUxvYWQubG9hZElmTmVlZGVkKG5leHQpXG4gIH0uYmluZCh0aGlzKSlcbn1cblxuTWFycXVlZS5wcm90b3R5cGUuYXR0ciA9IHtcbiAgaW50ZXJ2YWw6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHRoaXMuaW50ZXJ2YWwgPSB2YWx1ZVxuICB9LFxuICB0cmFuc2l0aW9uRHVyYXRpb246IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHRoaXMudHJhbnNpdGlvbkR1cmF0aW9uID0gdmFsdWVcbiAgfSxcbiAgZGVsYXk6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHRoaXMuZGVsYXkgPSB2YWx1ZVxuICB9XG59XG5cbk1hcnF1ZWUucHJvdG90eXBlLmNsZWFyQXR0ciA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5pbnRlcnZhbCA9IDUgKiAxMDAwXG4gIHRoaXMudHJhbnNpdGlvbkR1cmF0aW9uID0gNTAwXG4gIHRoaXMuZGVsYXkgPSAwXG59XG5cbm1vZHVsZS5leHBvcnRzID0gTWFycXVlZVxuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL3NyYy9jb21wb25lbnRzL21hcnF1ZWUuanNcbiAqKiBtb2R1bGUgaWQgPSAzOVxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnZhciBleHRlbmQgPSByZXF1aXJlKCcuLi91dGlscycpLmV4dGVuZFxudmFyIGNvbmZpZyA9IHJlcXVpcmUoJy4uL2NvbmZpZycpXG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi9jb21wb25lbnQnKVxudmFyIENvbXBvbmVudE1hbmFnZXIgPSByZXF1aXJlKCcuLi9jb21wb25lbnRNYW5hZ2VyJylcbnZhciBMYXp5TG9hZCA9IHJlcXVpcmUoJy4uL2xhenlMb2FkJylcbnJlcXVpcmUoJ2NhcnJvdXNlbCcpXG5yZXF1aXJlKCcuLi9zdHlsZXMvc2xpZGVyLnNjc3MnKVxuXG5mdW5jdGlvbiBTbGlkZXIgKGRhdGEpIHtcbiAgdGhpcy5hdXRvUGxheSA9IHRydWUgIC8vIGFsd2F5cyB0cnVlIGZvciBhdXRvcGxheVxuICB0aGlzLmRpcmVjdGlvbiA9ICdyb3cnIC8vICdjb2x1bW4nIGlzIG5vdCB0ZW1wb3JhcmlseSBzdXBwb3J0ZWQuXG4gIHRoaXMuY2hpbGRyZW4gPSBbXVxuICB0aGlzLmlzUGFnZVNob3cgPSB0cnVlXG4gIHRoaXMuaXNEb21SZW5kZXJpbmcgPSB0cnVlXG5cbiAgLy8gYmluZCBldmVudCAncGFnZXNob3cnIGFuZCAncGFnZWhpZGUnIG9uIHdpbmRvdy5cbiAgdGhpcy5faWRsZVdoZW5QYWdlRGlzYXBwZWFyKClcbiAgLy8gYmluZCBldmVudCAncmVuZGVyQmVnaW4nIGFuZCAncmVuZGVyRW5kJyBvbiB3aW5kb3cuXG4gIHRoaXMuX2lkbGVXaGVuRG9tUmVuZGVyaW5nKClcblxuICBDb21wb25lbnQuY2FsbCh0aGlzLCBkYXRhKVxufVxuXG5TbGlkZXIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShDb21wb25lbnQucHJvdG90eXBlKVxuXG5TbGlkZXIucHJvdG90eXBlLl9pZGxlV2hlblBhZ2VEaXNhcHBlYXIgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBfdGhpcyA9IHRoaXNcbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3BhZ2VzaG93JywgZnVuY3Rpb24gKCkge1xuICAgIF90aGlzLmlzUGFnZVNob3cgPSB0cnVlXG4gICAgX3RoaXMuYXV0b1BsYXkgJiYgIV90aGlzLmlzRG9tUmVuZGVyaW5nICYmIF90aGlzLnBsYXkoKVxuICB9KVxuICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncGFnZWhpZGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgX3RoaXMuaXNQYWdlU2hvdyA9IGZhbHNlXG4gICAgX3RoaXMuc3RvcCgpXG4gIH0pXG59XG5cblNsaWRlci5wcm90b3R5cGUuX2lkbGVXaGVuRG9tUmVuZGVyaW5nID0gZnVuY3Rpb24gKCkge1xuICB2YXIgX3RoaXMgPSB0aGlzXG4gIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZW5kZXJlbmQnLCBmdW5jdGlvbiAoKSB7XG4gICAgX3RoaXMuaXNEb21SZW5kZXJpbmcgPSBmYWxzZVxuICAgIF90aGlzLmF1dG9QbGF5ICYmIF90aGlzLmlzUGFnZVNob3cgJiYgX3RoaXMucGxheSgpXG4gIH0pXG4gIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZW5kZXJiZWdpbicsIGZ1bmN0aW9uICgpIHtcbiAgICBfdGhpcy5pc0RvbVJlbmRlcmluZyA9IHRydWVcbiAgICBfdGhpcy5zdG9wKClcbiAgfSlcbn1cblxuU2xpZGVyLnByb3RvdHlwZS5hdHRyID0ge1xuICBpbnRlcnZhbDogZnVuY3Rpb24gKHZhbCkge1xuICAgIHRoaXMuaW50ZXJ2YWwgPSBwYXJzZUludCh2YWwpIHx8IDMwMDBcbiAgICBpZiAodGhpcy5jYXJyb3VzZWwpIHtcbiAgICAgIHRoaXMuY2Fycm91c2VsLnBsYXlJbnRlcnZhbCA9IHRoaXMuaW50ZXJ2YWxcbiAgICB9XG4gIH0sXG5cbiAgcGxheXN0YXR1czogZnVuY3Rpb24gKHZhbCkge1xuICAgIHRoaXMucGxheXN0YXR1cyA9IHZhbCAmJiB2YWwgIT09ICdmYWxzZScgPyB0cnVlIDogZmFsc2VcbiAgICB0aGlzLmF1dG9QbGF5ID0gdGhpcy5wbGF5c3RhdHVzXG4gICAgaWYgKHRoaXMuY2Fycm91c2VsKSB7XG4gICAgICBpZiAodGhpcy5wbGF5c3RhdHVzKSB7XG4gICAgICAgIHRoaXMucGxheSgpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnN0b3AoKVxuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICAvLyBzdXBwb3J0IHBsYXlzdGF0dXMnIGFsaWFzIGF1dG8tcGxheSBmb3IgY29tcGF0aWJpbGl0eVxuICBhdXRvUGxheTogZnVuY3Rpb24gKHZhbCkge1xuICAgIHRoaXMuYXR0ci5wbGF5c3RhdHVzLmNhbGwodGhpcywgdmFsKVxuICB9XG59XG5cblNsaWRlci5wcm90b3R5cGUuY3JlYXRlID0gZnVuY3Rpb24gKCkge1xuICB2YXIgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gIG5vZGUuY2xhc3NMaXN0LmFkZCgnc2xpZGVyJylcbiAgbm9kZS5zdHlsZS5wb3NpdGlvbiA9ICdyZWxhdGl2ZSdcbiAgbm9kZS5zdHlsZS5vdmVyZmxvdyA9ICdoaWRkZW4nXG4gIHJldHVybiBub2RlXG59XG5cblNsaWRlci5wcm90b3R5cGUuX2RvUmVuZGVyID0gZnVuY3Rpb24gKCkge1xuICB2YXIgX3RoaXMgPSB0aGlzXG4gIF90aGlzLmNyZWF0ZUNoaWxkcmVuKClcbiAgX3RoaXMub25BcHBlbmQoKVxufVxuXG5TbGlkZXIucHJvdG90eXBlLnJlbW92ZUNoaWxkID0gZnVuY3Rpb24gKGNoaWxkKSB7XG4gIHZhciBjaGlsZHJlbiA9IHRoaXMuZGF0YS5jaGlsZHJlblxuICBpZiAoY2hpbGRyZW4pIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoY2hpbGQuZGF0YS5yZWYgPT09IGNoaWxkcmVuW2ldLnJlZikge1xuICAgICAgICBjaGlsZHJlbi5zcGxpY2UoaSwgMSlcbiAgICAgICAgYnJlYWtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB0aGlzLl9kb1JlbmRlcigpXG59XG5cblNsaWRlci5wcm90b3R5cGUuaW5zZXJ0QmVmb3JlID0gZnVuY3Rpb24gKGNoaWxkLCBiZWZvcmUpIHtcbiAgdmFyIGNoaWxkcmVuID0gdGhpcy5kYXRhLmNoaWxkcmVuXG4gIC8vIHZhciBjaGlsZEluZGV4ID0gdGhpcy5jaGlsZHJlbi5pbmRleE9mKGJlZm9yZS5kYXRhKVxuICB2YXIgY2hpbGRJbmRleCA9IC0xXG4gIGZvciAodmFyIGkgPSAwLCBsID0gY2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgaWYgKGNoaWxkcmVuW2ldLnJlZiA9PT0gYmVmb3JlLmRhdGEucmVmKSB7XG4gICAgICBjaGlsZEluZGV4ID0gaVxuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cbiAgY2hpbGRyZW4uc3BsaWNlKGNoaWxkSW5kZXgsIDAsIGNoaWxkLmRhdGEpXG5cbiAgdGhpcy5fZG9SZW5kZXIoKVxuICBpZiAodGhpcy5jaGlsZHJlbi5sZW5ndGggPiAwKSB7XG4gICAgcmV0dXJuIHRoaXMuY2hpbGRyZW5bdGhpcy5jaGlsZHJlbi5sZW5ndGggLSAxXVxuICB9XG59XG5cblNsaWRlci5wcm90b3R5cGUuYXBwZW5kQ2hpbGQgPSBmdW5jdGlvbiAoZGF0YSkge1xuICB2YXIgY2hpbGRyZW4gPSB0aGlzLmRhdGEuY2hpbGRyZW4gfHwgKHRoaXMuZGF0YS5jaGlsZHJlbiA9IFtdKVxuICBjaGlsZHJlbi5wdXNoKGRhdGEpXG4gIHRoaXMuX2RvUmVuZGVyKClcbiAgaWYgKHRoaXMuY2hpbGRyZW4ubGVuZ3RoID4gMCkge1xuICAgIHJldHVybiB0aGlzLmNoaWxkcmVuW3RoaXMuY2hpbGRyZW4ubGVuZ3RoIC0gMV1cbiAgfVxufVxuXG5TbGlkZXIucHJvdG90eXBlLmNyZWF0ZUNoaWxkcmVuID0gZnVuY3Rpb24gKCkge1xuXG4gIHZhciBjb21wb25lbnRNYW5hZ2VyID0gdGhpcy5nZXRDb21wb25lbnRNYW5hZ2VyKClcblxuICAvLyByZWNyZWF0ZSBzbGlkZXIgY29udGFpbmVyLlxuICBpZiAodGhpcy5zbGlkZXJDb250YWluZXIpIHtcbiAgICB0aGlzLm5vZGUucmVtb3ZlQ2hpbGQodGhpcy5zbGlkZXJDb250YWluZXIpXG4gIH1cbiAgaWYgKHRoaXMuaW5kaWNhdG9yKSB7XG4gICAgdGhpcy5pbmRpY2F0b3Iubm9kZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHRoaXMuaW5kaWNhdG9yLm5vZGUpXG4gIH1cbiAgdGhpcy5jaGlsZHJlbiA9IFtdXG5cbiAgdmFyIHNsaWRlckNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3VsJylcbiAgc2xpZGVyQ29udGFpbmVyLnN0eWxlLmxpc3RTdHlsZSA9ICdub25lJ1xuICB0aGlzLm5vZGUuYXBwZW5kQ2hpbGQoc2xpZGVyQ29udGFpbmVyKVxuICB0aGlzLnNsaWRlckNvbnRhaW5lciA9IHNsaWRlckNvbnRhaW5lclxuXG4gIHZhciBjaGlsZHJlbiA9IHRoaXMuZGF0YS5jaGlsZHJlblxuICB2YXIgc2NhbGUgPSB0aGlzLmRhdGEuc2NhbGVcbiAgdmFyIGZyYWdtZW50ID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpXG4gIHZhciBpbmRpY2F0b3JEYXRhLCB3aWR0aCwgaGVpZ2h0XG4gIHZhciBjaGlsZFdpZHRoID0gMFxuICB2YXIgY2hpbGRIZWlnaHQgPSAwXG5cbiAgaWYgKGNoaWxkcmVuICYmIGNoaWxkcmVuLmxlbmd0aCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBjaGlsZFxuICAgICAgY2hpbGRyZW5baV0uc2NhbGUgPSB0aGlzLmRhdGEuc2NhbGVcbiAgICAgIGNoaWxkcmVuW2ldLmluc3RhbmNlSWQgPSB0aGlzLmRhdGEuaW5zdGFuY2VJZFxuICAgICAgaWYgKGNoaWxkcmVuW2ldLnR5cGUgPT09ICdpbmRpY2F0b3InKSB7XG4gICAgICAgIGluZGljYXRvckRhdGEgPSBleHRlbmQoY2hpbGRyZW5baV0sIHtcbiAgICAgICAgICBleHRyYToge1xuICAgICAgICAgICAgYW1vdW50OiBjaGlsZHJlbi5sZW5ndGggLSAxLFxuICAgICAgICAgICAgaW5kZXg6IDBcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjaGlsZCA9IGNvbXBvbmVudE1hbmFnZXIuY3JlYXRlRWxlbWVudChjaGlsZHJlbltpXSwgJ2xpJylcbiAgICAgICAgdGhpcy5jaGlsZHJlbi5wdXNoKGNoaWxkKVxuICAgICAgICBmcmFnbWVudC5hcHBlbmRDaGlsZChjaGlsZC5ub2RlKVxuICAgICAgICB3aWR0aCA9IGNoaWxkLmRhdGEuc3R5bGUud2lkdGggfHwgMFxuICAgICAgICBoZWlnaHQgPSBjaGlsZC5kYXRhLnN0eWxlLmhlaWdodCB8fCAwXG4gICAgICAgIHdpZHRoID4gY2hpbGRXaWR0aCAmJiAoY2hpbGRXaWR0aCA9IHdpZHRoKVxuICAgICAgICBoZWlnaHQgPiBjaGlsZEhlaWdodCAmJiAoY2hpbGRIZWlnaHQgPSBoZWlnaHQpXG4gICAgICAgIGNoaWxkLnBhcmVudFJlZiA9IHRoaXMuZGF0YS5yZWZcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gYXBwZW5kIGluZGljYXRvclxuICAgIGlmIChpbmRpY2F0b3JEYXRhKSB7XG4gICAgICBpbmRpY2F0b3JEYXRhLmV4dHJhLndpZHRoID0gdGhpcy5kYXRhLnN0eWxlLndpZHRoIHx8IGNoaWxkV2lkdGhcbiAgICAgIGluZGljYXRvckRhdGEuZXh0cmEuaGVpZ2h0ID0gdGhpcy5kYXRhLnN0eWxlLmhlaWdodCB8fCBjaGlsZEhlaWdodFxuICAgICAgdGhpcy5pbmRpY2F0b3IgPSBjb21wb25lbnRNYW5hZ2VyLmNyZWF0ZUVsZW1lbnQoaW5kaWNhdG9yRGF0YSlcbiAgICAgIHRoaXMuaW5kaWNhdG9yLnBhcmVudFJlZiA9IHRoaXMuZGF0YS5yZWZcbiAgICAgIHRoaXMuaW5kaWNhdG9yLnNsaWRlciA9IHRoaXNcbiAgICAgIHRoaXMubm9kZS5hcHBlbmRDaGlsZCh0aGlzLmluZGljYXRvci5ub2RlKVxuICAgIH1cblxuICAgIHNsaWRlckNvbnRhaW5lci5zdHlsZS5oZWlnaHQgPSBzY2FsZSAqIHRoaXMuZGF0YS5zdHlsZS5oZWlnaHQgKyAncHgnXG4gICAgc2xpZGVyQ29udGFpbmVyLmFwcGVuZENoaWxkKGZyYWdtZW50KVxuICB9XG59XG5cblNsaWRlci5wcm90b3R5cGUub25BcHBlbmQgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmNhcnJvdXNlbCkge1xuICAgIHRoaXMuY2Fycm91c2VsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIHRoaXMuX2dldFNsaWRlckNoYW5nZUhhbmRsZXIoKSlcbiAgICB0aGlzLmNhcnJvdXNlbC5zdG9wKClcbiAgICB0aGlzLmNhcnJvdXNlbCA9IG51bGxcbiAgfVxuICB0aGlzLmNhcnJvdXNlbCA9IG5ldyBsaWIuY2Fycm91c2VsKHRoaXMuc2xpZGVyQ29udGFpbmVyLCB7XG4gICAgYXV0b3BsYXk6IHRoaXMuYXV0b1BsYXksXG4gICAgdXNlR2VzdHVyZTogdHJ1ZVxuICB9KVxuXG4gIHRoaXMuY2Fycm91c2VsLnBsYXlJbnRlcnZhbCA9IHRoaXMuaW50ZXJ2YWxcbiAgdGhpcy5jYXJyb3VzZWwuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgdGhpcy5fZ2V0U2xpZGVyQ2hhbmdlSGFuZGxlcigpKVxuICB0aGlzLmN1cnJlbnRJbmRleCA9IDBcblxuICAvLyBwcmVsb2FkIGFsbCBpbWFnZXMgZm9yIHNsaWRlclxuICAvLyBiZWNhdXNlOlxuICAvLyAxLiBsaWItaW1nIGRvZXNuJ3QgbGlzdGVuIHRvIGV2ZW50IHRyYW5zaXRpb25lbmRcbiAgLy8gMi4gZXZlbiBpZiB3ZSBmaXJlIGxhenkgbG9hZCBpbiBzbGlkZXIncyBjaGFuZ2UgZXZlbnQgaGFuZGxlcixcbiAgLy8gICAgdGhlIG5leHQgaW1hZ2Ugc3RpbGwgd29uJ3QgYmUgcHJlbG9hZGVkIHV0aWxsIHRoZSBtb21lbnQgaXRcbiAgLy8gICAgc2xpZGVzIGludG8gdGhlIHZpZXcsIHdoaWNoIGlzIHRvbyBsYXRlLlxuICBpZiAodGhpcy5wcmVsb2FkSW1nc1RpbWVyKSB7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMucHJlbG9hZEltZ3NUaW1lcilcbiAgfVxuICAvLyBUaGUgdGltZSBqdXN0IGJlZm9yZSB0aGUgc2Vjb25kIHNsaWRlIGFwcGVhciBhbmQgZW5vdWdoXG4gIC8vIGZvciBhbGwgY2hpbGQgZWxlbWVudHMgdG8gYXBwZW5kIGlzIG9rLlxuICB2YXIgcHJlbG9hZFRpbWUgPSAwLjhcbiAgdGhpcy5wcmVsb2FkSW1nc1RpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGltZ3MgPSB0aGlzLmNhcnJvdXNlbC5lbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2ltZycpXG4gICAgZm9yICh2YXIgaSA9IDAsIGwgPSBpbWdzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgdmFyIGltZyA9IGltZ3NbaV1cbiAgICAgIHZhciBpTGF6eVNyYyA9IGltZy5nZXRBdHRyaWJ1dGUoJ2ktbGF6eS1zcmMnKVxuICAgICAgdmFyIGltZ1NyYyA9IGltZy5nZXRBdHRyaWJ1dGUoJ2ltZy1zcmMnKVxuICAgICAgaWYgKGlMYXp5U3JjKSB7XG4gICAgICAgIGltZy5zZXRBdHRyaWJ1dGUoJ3NyYycsIGlMYXp5U3JjKVxuICAgICAgfSBlbHNlIGlmIChpbWdTcmMpIHtcbiAgICAgICAgaW1nLnNldEF0dHJpYnV0ZSgnc3JjJywgaW1nU3JjKVxuICAgICAgfVxuICAgICAgaW1nLnJlbW92ZUF0dHJpYnV0ZSgnaS1sYXp5LXNyYycpXG4gICAgICBpbWcucmVtb3ZlQXR0cmlidXRlKCdpbWctc3JjJylcbiAgICB9XG4gIH0uYmluZCh0aGlzKSwgcHJlbG9hZFRpbWUgKiAxMDAwKVxuXG4gIC8vIGF2b2lkIHBhZ2Ugc2Nyb2xsIHdoZW4gcGFubmluZ1xuICB2YXIgcGFubmluZyA9IGZhbHNlXG4gIHRoaXMuY2Fycm91c2VsLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigncGFuc3RhcnQnLCBmdW5jdGlvbiAoZSkge1xuICAgIGlmICghZS5pc1ZlcnRpY2FsKSB7XG4gICAgICBwYW5uaW5nID0gdHJ1ZVxuICAgIH1cbiAgfSlcbiAgdGhpcy5jYXJyb3VzZWwuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdwYW5lbmQnLCBmdW5jdGlvbiAoZSkge1xuICAgIGlmICghZS5pc1ZlcnRpY2FsKSB7XG4gICAgICBwYW5uaW5nID0gZmFsc2VcbiAgICB9XG4gIH0pXG5cbiAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2htb3ZlJywgZnVuY3Rpb24gKGUpIHtcbiAgICBpZiAocGFubmluZykge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpXG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG4gICAgcmV0dXJuIHRydWVcbiAgfS5iaW5kKHRoaXMpKVxuXG59XG5cblNsaWRlci5wcm90b3R5cGUuX3VwZGF0ZUluZGljYXRvcnMgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuaW5kaWNhdG9yICYmIHRoaXMuaW5kaWNhdG9yLnNldEluZGV4KHRoaXMuY3VycmVudEluZGV4KVxufVxuXG5TbGlkZXIucHJvdG90eXBlLl9nZXRTbGlkZXJDaGFuZ2VIYW5kbGVyID0gZnVuY3Rpb24gKGUpIHtcbiAgaWYgKCF0aGlzLnNsaWRlckNoYW5nZUhhbmRsZXIpIHtcbiAgICB0aGlzLnNsaWRlckNoYW5nZUhhbmRsZXIgPSAoZnVuY3Rpb24gKGUpIHtcbiAgICAgIHZhciBpbmRleCA9IHRoaXMuY2Fycm91c2VsLml0ZW1zLmluZGV4XG4gICAgICB0aGlzLmN1cnJlbnRJbmRleCA9IGluZGV4XG5cbiAgICAgIC8vIHVwZGF0ZUluZGljYXRvcnNcbiAgICAgIHRoaXMuX3VwZGF0ZUluZGljYXRvcnMoKVxuXG4gICAgICB0aGlzLmRpc3BhdGNoRXZlbnQoJ2NoYW5nZScsIHsgaW5kZXg6IGluZGV4IH0pXG4gICAgfSkuYmluZCh0aGlzKVxuICB9XG4gIHJldHVybiB0aGlzLnNsaWRlckNoYW5nZUhhbmRsZXJcbn1cblxuU2xpZGVyLnByb3RvdHlwZS5wbGF5ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmNhcnJvdXNlbC5wbGF5KClcbn1cblxuU2xpZGVyLnByb3RvdHlwZS5zdG9wID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmNhcnJvdXNlbC5zdG9wKClcbn1cblxuU2xpZGVyLnByb3RvdHlwZS5zbGlkZVRvID0gZnVuY3Rpb24gKGluZGV4KSB7XG4gIHZhciBvZmZzZXQgPSBpbmRleCAtIHRoaXMuY3VycmVudEluZGV4XG4gIHRoaXMuY2Fycm91c2VsLml0ZW1zLnNsaWRlKG9mZnNldClcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBTbGlkZXJcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvY29tcG9uZW50cy9zbGlkZXIuanNcbiAqKiBtb2R1bGUgaWQgPSA0MFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnKSAmJiAod2luZG93ID0ge2N0cmw6IHt9LCBsaWI6IHt9fSk7IXdpbmRvdy5jdHJsICYmICh3aW5kb3cuY3RybCA9IHt9KTshd2luZG93LmxpYiAmJiAod2luZG93LmxpYiA9IHt9KTtyZXF1aXJlKCdhbmltYXRpb25qcycpO3JlcXVpcmUoJ2N1YmljYmV6aWVyJyk7cmVxdWlyZSgnZ2VzdHVyZWpzJyk7IWZ1bmN0aW9uKCl7dmFyIGE9XCJbZGF0YS1jdHJsLW5hbWU9Y2Fycm91c2VsXXtwb3NpdGlvbjpyZWxhdGl2ZTstd2Via2l0LXRyYW5zZm9ybTp0cmFuc2xhdGVaKDFweCk7LW1zLXRyYW5zZm9ybTp0cmFuc2xhdGVaKDFweCk7dHJhbnNmb3JtOnRyYW5zbGF0ZVooMXB4KX1cIixiPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzdHlsZVwiKTtpZihkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcImhlYWRcIilbMF0uYXBwZW5kQ2hpbGQoYiksYi5zdHlsZVNoZWV0KWIuc3R5bGVTaGVldC5kaXNhYmxlZHx8KGIuc3R5bGVTaGVldC5jc3NUZXh0PWEpO2Vsc2UgdHJ5e2IuaW5uZXJIVE1MPWF9Y2F0Y2goYyl7Yi5pbm5lclRleHQ9YX19KCk7IWZ1bmN0aW9uKGEsYixjKXtmdW5jdGlvbiBkKGEpe3ZhciBiLGM9e3g6MCx5OjB9LGQ9Z2V0Q29tcHV0ZWRTdHlsZShhKVtsK1wiVHJhbnNmb3JtXCJdO3JldHVyblwibm9uZVwiIT09ZCYmKGI9ZC5tYXRjaCgvXm1hdHJpeDNkXFwoKD86Wy1cXGQuXSssXFxzKil7MTJ9KFstXFxkLl0rKSxcXHMqKFstXFxkLl0rKSg/OixcXHMqWy1cXGQuXSspezJ9XFwpLyl8fGQubWF0Y2goL15tYXRyaXhcXCgoPzpbLVxcZC5dKyxcXHMqKXs0fShbLVxcZC5dKyksXFxzKihbLVxcZC5dKylcXCkkLykpJiYoYy54PXBhcnNlRmxvYXQoYlsxXSl8fDAsYy55PXBhcnNlRmxvYXQoYlsyXSl8fDApLGN9ZnVuY3Rpb24gZShhLGIpe3JldHVybiBhPXBhcnNlRmxvYXQoYSksYj1wYXJzZUZsb2F0KGIpLDAhPWEmJihhKz1cInB4XCIpLDAhPWImJihiKz1cInB4XCIpLG4/XCJ0cmFuc2xhdGUzZChcIithK1wiLCBcIitiK1wiLCAwKVwiOlwidHJhbnNsYXRlKFwiK2ErXCIsIFwiK2IrXCIpXCJ9ZnVuY3Rpb24gZihhKXtyZXR1cm4gby5jYWxsKGEpfWZ1bmN0aW9uIGcoYSxjKXtmdW5jdGlvbiBnKGEsYil7dmFyIGM9aC5jcmVhdGVFdmVudChcIkhUTUxFdmVudHNcIik7aWYoYy5pbml0RXZlbnQoYSwhMSwhMSksYilmb3IodmFyIGQgaW4gYiljW2RdPWJbZF07bi5kaXNwYXRjaEV2ZW50KGMpfWZ1bmN0aW9uIGkoYSl7Zm9yKDswPmE7KWErPXI7Zm9yKDthPj1yOylhLT1yO3JldHVybiBhfWZ1bmN0aW9uIGooYSl7aWYoMCE9PXIpe3ZhciBiLGMsZD1xLmdldChhKTtyPjEmJihiPXEuZ2V0KGEtMSksYz0yPT09cj9xLmdldENsb25lZChhKzEpOnEuZ2V0KGErMSksZC5zdHlsZS5sZWZ0PS1vK1wicHhcIixiLnN0eWxlLmxlZnQ9LW8tcytcInB4XCIsYy5zdHlsZS5sZWZ0PS1vK3MrXCJweFwiKSx0PWQuaW5kZXgsZyhcImNoYW5nZVwiLHtwcmV2SXRlbTpiLGN1ckl0ZW06ZCxuZXh0SXRlbTpjfSl9fXZhciBrPXRoaXMsbT1EYXRlLm5vdygpK1wiLVwiKyArK3Asbj1kb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7MSE9PWFyZ3VtZW50cy5sZW5ndGh8fGFyZ3VtZW50c1swXWluc3RhbmNlb2YgSFRNTEVsZW1lbnR8fChjPWFyZ3VtZW50c1swXSxhPW51bGwpLGF8fChhPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJ1bFwiKSxuLmFwcGVuZENoaWxkKGEpKSxjPWN8fHt9LGEuc2V0QXR0cmlidXRlKFwiZGF0YS1jdHJsLW5hbWVcIixcImNhcnJvdXNlbFwiKSxhLnNldEF0dHJpYnV0ZShcImRhdGEtY3RybC1pZFwiLG0pLGEuc3R5bGUucG9zaXRpb249XCJyZWxhdGl2ZVwiLGEuc3R5bGVbbCtcIlRyYW5zZm9ybVwiXT1lKDAsMCk7dmFyIG89MCxxPXt9LHI9MCxzPWMuc3RlcHx8YS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aCx0PTA7cS5hZGQ9ZnVuY3Rpb24oYil7dmFyIGM9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImxpXCIpO3JldHVybiBjLnN0eWxlLmRpc3BsYXk9XCJub25lXCIsYy5zdHlsZVtcImZsb2F0XCJdPVwibGVmdFwiLGMuaW5kZXg9cixcInN0cmluZ1wiPT10eXBlb2YgYj9jLmlubmVySFRNTD1iOmIgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCYmYy5hcHBlbmRDaGlsZChiKSxhLmFwcGVuZENoaWxkKGMpLE9iamVjdC5kZWZpbmVQcm9wZXJ0eShxLHIrXCJcIix7Z2V0OmZ1bmN0aW9uKCl7cmV0dXJuIGN9fSkscisrLGN9LHEuZ2V0PWZ1bmN0aW9uKGEpe3JldHVybiBxW2koYSldfSxxLmdldENsb25lZD1mdW5jdGlvbihiKXtmdW5jdGlvbiBjKGEsYixkKXt2YXIgZT1hLl9saXN0ZW5lcnM7aWYoZSl7Yi5fbGlzdGVuZXJzPWU7Zm9yKHZhciBmIGluIGUpYi5hZGRFdmVudExpc3RlbmVyKGYsZVtmXSl9aWYoZCYmYS5jaGlsZHJlbiYmYS5jaGlsZHJlbi5sZW5ndGgpZm9yKHZhciBnPTAsaD1hLmNoaWxkcmVuLmxlbmd0aDtoPmc7ZysrKWMoYS5jaGlsZHJlbltnXSxiLmNoaWxkcmVuW2ddLGQpfXZhciBiPWkoYiksZD1hLnF1ZXJ5U2VsZWN0b3IoJ1tjbG9uZWQ9XCJjbG9uZWQtJytiKydcIl0nKSxlPXFbYl07cmV0dXJuIGR8fChkPWUuY2xvbmVOb2RlKCEwKSxjKGUsZCwhMCksYS5hcHBlbmRDaGlsZChkKSxkLnNldEF0dHJpYnV0ZShcImNsb25lZFwiLFwiY2xvbmVkLVwiK2IpLGQuaW5kZXg9YiksZH0scS5zbGlkZT1mdW5jdGlvbihjKXtpZigwIT09cil7MT09PXImJihjPTApO3ZhciBmPWQoYSkueCxnPW8rcyotYyxoPWctZjtpZigwIT09aCl7bmV3IGIuYW5pbWF0aW9uKDQwMCxiLmN1YmljYmV6aWVyLmVhc2UsZnVuY3Rpb24oYixjKXthLnN0eWxlW2wrXCJUcmFuc2Zvcm1cIl09ZShmK2gqYywwKX0pLnBsYXkoKS50aGVuKGZ1bmN0aW9uKCl7bz1nLGEuc3R5bGVbbCtcIlRyYW5zZm9ybVwiXT1lKGcsMCksYyYmaih0K2MpfSl9fX0scS5uZXh0PWZ1bmN0aW9uKCl7cS5zbGlkZSgxKX0scS5wcmV2PWZ1bmN0aW9uKCl7cS5zbGlkZSgtMSl9LGYoYS5xdWVyeVNlbGVjdG9yQWxsKFwibGlcIikpLmZvckVhY2goZnVuY3Rpb24oYSl7YS5zdHlsZS5wb3NpdGlvbj1cImFic29sdXRlXCIsYS5zdHlsZS50b3A9XCIwXCIsYS5zdHlsZS5sZWZ0PXIqcytcInB4XCIsYS5zdHlsZVtcImZsb2F0XCJdPVwibGVmdFwiLGEuaW5kZXg9cixPYmplY3QuZGVmaW5lUHJvcGVydHkocSxyK1wiXCIse2dldDpmdW5jdGlvbigpe3JldHVybiBhfX0pLHIrK30pLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLFwiaXRlbXNcIix7Z2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHF9fSksT2JqZWN0LmRlZmluZVByb3BlcnR5KHEsXCJsZW5ndGhcIix7Z2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHJ9fSksT2JqZWN0LmRlZmluZVByb3BlcnR5KHEsXCJpbmRleFwiLHtnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gdH19KSxPYmplY3QuZGVmaW5lUHJvcGVydHkocSxcInN0ZXBcIix7Z2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHN9LHNldDpmdW5jdGlvbihhKXtzPWF9fSk7dmFyIHU9ITEsdj0hMSx3PSExO3RoaXMucGxheT1mdW5jdGlvbigpe3JldHVybiB1P3ZvaWQodnx8KHY9c2V0VGltZW91dChmdW5jdGlvbigpe3c9ITAscS5uZXh0KCksc2V0VGltZW91dChmdW5jdGlvbigpe3c9ITF9LDUwMCksdj1zZXRUaW1lb3V0KGFyZ3VtZW50cy5jYWxsZWUsNDAwK3opfSw0MDAreikpKToodT0hMCxqKDApKX0sdGhpcy5zdG9wPWZ1bmN0aW9uKCl7diYmKGNsZWFyVGltZW91dCh2KSxzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7dj0hMX0sNTAwKSl9O3ZhciB4PSExLHk9ITE7T2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsXCJhdXRvcGxheVwiLHtnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4geH0sc2V0OmZ1bmN0aW9uKGEpe3g9ISFhLHkmJihjbGVhclRpbWVvdXQoeSkseT0hMSkseD95PXNldFRpbWVvdXQoZnVuY3Rpb24oKXtrLnBsYXkoKX0sMmUzKTprLnN0b3AoKX19KSx0aGlzLmF1dG9wbGF5PSEhYy5hdXRvcGxheTt2YXIgej0xNTAwO2lmKE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLFwicGxheUludGVydmFsXCIse2dldDpmdW5jdGlvbigpe3JldHVybiB6fSxzZXQ6ZnVuY3Rpb24oYSl7ej1hfX0pLHRoaXMucGxheUludGVydmFsPSEhYy5wbGF5SW50ZXJ2YWx8fDE1MDAsYy51c2VHZXN0dXJlKXt2YXIgQSxCPSExO2EuYWRkRXZlbnRMaXN0ZW5lcihcInBhbnN0YXJ0XCIsZnVuY3Rpb24oYSl7YS5pc1ZlcnRpY2FsfHxCJiZ3fHwoYS5wcmV2ZW50RGVmYXVsdCgpLGEuc3RvcFByb3BhZ2F0aW9uKCkseCYmay5zdG9wKCksQT0wLEI9ITApfSksYS5hZGRFdmVudExpc3RlbmVyKFwicGFubW92ZVwiLGZ1bmN0aW9uKGIpeyFiLmlzVmVydGljYWwmJkImJihiLnByZXZlbnREZWZhdWx0KCksYi5zdG9wUHJvcGFnYXRpb24oKSxBPWIuZGlzcGxhY2VtZW50WCxhLnN0eWxlW2wrXCJUcmFuc2Zvcm1cIl09ZShvK0EsMCkpfSksYS5hZGRFdmVudExpc3RlbmVyKFwicGFuZW5kXCIsZnVuY3Rpb24oYSl7IWEuaXNWZXJ0aWNhbCYmQiYmKGEucHJldmVudERlZmF1bHQoKSxhLnN0b3BQcm9wYWdhdGlvbigpLEI9ITEsYS5pc2ZsaWNrPzA+QT9xLm5leHQoKTpxLnByZXYoKTpNYXRoLmFicyhBKTxzLzI/cS5zbGlkZSgwKTpxLnNsaWRlKDA+QT8xOi0xKSx4JiZzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7ay5wbGF5KCl9LDJlMykpfSwhMSksYS5hZGRFdmVudExpc3RlbmVyKFwic3dpcGVcIixmdW5jdGlvbihhKXthLmlzVmVydGljYWx8fChhLnByZXZlbnREZWZhdWx0KCksYS5zdG9wUHJvcGFnYXRpb24oKSl9KX10aGlzLmFkZEV2ZW50TGlzdGVuZXI9ZnVuY3Rpb24oYSxiKXt0aGlzLnJvb3QuYWRkRXZlbnRMaXN0ZW5lcihhLGIsITEpfSx0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXI9ZnVuY3Rpb24oYSxiKXt0aGlzLnJvb3QucmVtb3ZlRXZlbnRMaXN0ZW5lcihhLGIsITEpfSx0aGlzLnJvb3Q9bix0aGlzLmVsZW1lbnQ9YX12YXIgaD1hLmRvY3VtZW50LGk9YS5uYXZpZ2F0b3IudXNlckFnZW50LGo9ISFpLm1hdGNoKC9GaXJlZm94L2kpLGs9ISFpLm1hdGNoKC9JRU1vYmlsZS9pKSxsPWo/XCJNb3pcIjprP1wibXNcIjpcIndlYmtpdFwiLG09az9cIk1TQ1NTTWF0cml4XCI6XCJXZWJLaXRDU1NNYXRyaXhcIixuPSEhanx8bSBpbiBhJiZcIm0xMVwiaW4gbmV3IGFbbV0sbz1BcnJheS5wcm90b3R5cGUuc2xpY2UscD0wO2IuY2Fycm91c2VsPWd9KHdpbmRvdyx3aW5kb3cubGliLHdpbmRvdy5jdHJsfHwod2luZG93LmN0cmw9e30pKTs7bW9kdWxlLmV4cG9ydHMgPSB3aW5kb3cubGliWydjYXJyb3VzZWwnXTtcblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9jYXJyb3VzZWwvYnVpbGQvY2Fycm91c2VsLmNvbW1vbi5qc1xuICoqIG1vZHVsZSBpZCA9IDQxXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvLyBzdHlsZS1sb2FkZXI6IEFkZHMgc29tZSBjc3MgdG8gdGhlIERPTSBieSBhZGRpbmcgYSA8c3R5bGU+IHRhZ1xuXG4vLyBsb2FkIHRoZSBzdHlsZXNcbnZhciBjb250ZW50ID0gcmVxdWlyZShcIiEhLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi9ub2RlX21vZHVsZXMvc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vc2xpZGVyLnNjc3NcIik7XG5pZih0eXBlb2YgY29udGVudCA9PT0gJ3N0cmluZycpIGNvbnRlbnQgPSBbW21vZHVsZS5pZCwgY29udGVudCwgJyddXTtcbi8vIGFkZCB0aGUgc3R5bGVzIHRvIHRoZSBET01cbnZhciB1cGRhdGUgPSByZXF1aXJlKFwiIS4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9hZGRTdHlsZXMuanNcIikoY29udGVudCwge30pO1xuaWYoY29udGVudC5sb2NhbHMpIG1vZHVsZS5leHBvcnRzID0gY29udGVudC5sb2NhbHM7XG4vLyBIb3QgTW9kdWxlIFJlcGxhY2VtZW50XG5pZihtb2R1bGUuaG90KSB7XG5cdC8vIFdoZW4gdGhlIHN0eWxlcyBjaGFuZ2UsIHVwZGF0ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdGlmKCFjb250ZW50LmxvY2Fscykge1xuXHRcdG1vZHVsZS5ob3QuYWNjZXB0KFwiISEuLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLy4uLy4uL25vZGVfbW9kdWxlcy9zYXNzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi9zbGlkZXIuc2Nzc1wiLCBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBuZXdDb250ZW50ID0gcmVxdWlyZShcIiEhLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi9ub2RlX21vZHVsZXMvc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vc2xpZGVyLnNjc3NcIik7XG5cdFx0XHRpZih0eXBlb2YgbmV3Q29udGVudCA9PT0gJ3N0cmluZycpIG5ld0NvbnRlbnQgPSBbW21vZHVsZS5pZCwgbmV3Q29udGVudCwgJyddXTtcblx0XHRcdHVwZGF0ZShuZXdDb250ZW50KTtcblx0XHR9KTtcblx0fVxuXHQvLyBXaGVuIHRoZSBtb2R1bGUgaXMgZGlzcG9zZWQsIHJlbW92ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdG1vZHVsZS5ob3QuZGlzcG9zZShmdW5jdGlvbigpIHsgdXBkYXRlKCk7IH0pO1xufVxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvc3R5bGVzL3NsaWRlci5zY3NzXG4gKiogbW9kdWxlIGlkID0gNDJcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsImV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2xpYi9jc3MtYmFzZS5qc1wiKSgpO1xuLy8gaW1wb3J0c1xuXG5cbi8vIG1vZHVsZVxuZXhwb3J0cy5wdXNoKFttb2R1bGUuaWQsIFwiLnNsaWRlciB7XFxuICBwb3NpdGlvbjogcmVsYXRpdmU7IH1cXG5cXG4uc2xpZGVyIC5pbmRpY2F0b3ItY29udGFpbmVyIHtcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gIGRpc3BsYXk6IC13ZWJraXQtYm94O1xcbiAgZGlzcGxheTogLXdlYmtpdC1mbGV4O1xcbiAgZGlzcGxheTogZmxleDtcXG4gIC13ZWJraXQtYm94LWFsaWduOiBjZW50ZXI7XFxuICBib3gtYWxpZ246IGNlbnRlcjtcXG4gIC13ZWJraXQtYWxpZ24taXRlbXM6IGNlbnRlcjtcXG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XFxuICAtd2Via2l0LWJveC1wYWNrOiBjZW50ZXI7XFxuICBib3gtcGFjazogY2VudGVyO1xcbiAgLXdlYmtpdC1qdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcXG4gIGp1c3RpZnktY29udGVudDogY2VudGVyO1xcbiAgZm9udC1zaXplOiAwOyB9XFxuICAuc2xpZGVyIC5pbmRpY2F0b3ItY29udGFpbmVyIC5pbmRpY2F0b3Ige1xcbiAgICBib3JkZXItcmFkaXVzOiA1MCU7IH1cXG4gIC5zbGlkZXIgLmluZGljYXRvci1jb250YWluZXIucm93IHtcXG4gICAgLXdlYmtpdC1ib3gtb3JpZW50OiBob3Jpem9udGFsO1xcbiAgICBib3gtb3JpZW50OiBob3Jpem9udGFsO1xcbiAgICAtd2Via2l0LWZsZXgtZGlyZWN0aW9uOiByb3c7XFxuICAgIGZsZXgtZGlyZWN0aW9uOiByb3c7IH1cXG4gIC5zbGlkZXIgLmluZGljYXRvci1jb250YWluZXIuY29sdW1uIHtcXG4gICAgLXdlYmtpdC1ib3gtb3JpZW50OiB2ZXJ0aWNhbDtcXG4gICAgYm94LW9yaWVudDogdmVydGljYWw7XFxuICAgIC13ZWJraXQtZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcXG4gICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjsgfVxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi9zcmMvc3JjL3N0eWxlcy9zbGlkZXIuc2Nzc1wiXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiQUFBQTtFQUNFLG1CQUFtQixFQUNwQjs7QUFDRDtFQUNFLG1CQUFtQjtFQUNuQixxQkFBcUI7RUFDckIsc0JBQXNCO0VBQ3RCLGNBQWM7RUFDZCwwQkFBMEI7RUFDMUIsa0JBQWtCO0VBQ2xCLDRCQUE0QjtFQUM1QixvQkFBb0I7RUFDcEIseUJBQXlCO0VBQ3pCLGlCQUFpQjtFQUNqQixnQ0FBZ0M7RUFDaEMsd0JBQXdCO0VBQ3hCLGFBQWEsRUFvQmQ7RUFqQ0Q7SUFnQkksbUJBQW1CLEVBQ3BCO0VBakJIO0lBb0JJLCtCQUErQjtJQUMvQix1QkFBdUI7SUFDdkIsNEJBQTRCO0lBQzVCLG9CQUFvQixFQUNyQjtFQXhCSDtJQTJCSSw2QkFBNkI7SUFDN0IscUJBQXFCO0lBQ3JCLCtCQUErQjtJQUMvQix1QkFBdUIsRUFDeEJcIixcImZpbGVcIjpcInNsaWRlci5zY3NzXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIi5zbGlkZXIge1xcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xcbn1cXG4uc2xpZGVyIC5pbmRpY2F0b3ItY29udGFpbmVyIHtcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gIGRpc3BsYXk6IC13ZWJraXQtYm94O1xcbiAgZGlzcGxheTogLXdlYmtpdC1mbGV4O1xcbiAgZGlzcGxheTogZmxleDtcXG4gIC13ZWJraXQtYm94LWFsaWduOiBjZW50ZXI7XFxuICBib3gtYWxpZ246IGNlbnRlcjtcXG4gIC13ZWJraXQtYWxpZ24taXRlbXM6IGNlbnRlcjtcXG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XFxuICAtd2Via2l0LWJveC1wYWNrOiBjZW50ZXI7XFxuICBib3gtcGFjazogY2VudGVyO1xcbiAgLXdlYmtpdC1qdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcXG4gIGp1c3RpZnktY29udGVudDogY2VudGVyO1xcbiAgZm9udC1zaXplOiAwO1xcblxcbiAgLmluZGljYXRvciB7XFxuICAgIGJvcmRlci1yYWRpdXM6IDUwJTtcXG4gIH1cXG5cXG4gICYucm93IHtcXG4gICAgLXdlYmtpdC1ib3gtb3JpZW50OiBob3Jpem9udGFsO1xcbiAgICBib3gtb3JpZW50OiBob3Jpem9udGFsO1xcbiAgICAtd2Via2l0LWZsZXgtZGlyZWN0aW9uOiByb3c7XFxuICAgIGZsZXgtZGlyZWN0aW9uOiByb3c7XFxuICB9XFxuXFxuICAmLmNvbHVtbiB7XFxuICAgIC13ZWJraXQtYm94LW9yaWVudDogdmVydGljYWw7XFxuICAgIGJveC1vcmllbnQ6IHZlcnRpY2FsO1xcbiAgICAtd2Via2l0LWZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XFxuICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XFxuICB9XFxuXFxufVwiXSxcInNvdXJjZVJvb3RcIjpcIndlYnBhY2s6Ly9cIn1dKTtcblxuLy8gZXhwb3J0c1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi9+L3Nhc3MtbG9hZGVyP3NvdXJjZU1hcCEuL3NyYy9zdHlsZXMvc2xpZGVyLnNjc3NcbiAqKiBtb2R1bGUgaWQgPSA0M1xuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnZhciBleHRlbmQgPSByZXF1aXJlKCcuLi91dGlscycpLmV4dGVuZFxudmFyIGNvbmZpZyA9IHJlcXVpcmUoJy4uL2NvbmZpZycpXG52YXIgQXRvbWljID0gcmVxdWlyZSgnLi9hdG9taWMnKVxudmFyIENvbXBvbmVudCA9IHJlcXVpcmUoJy4vY29tcG9uZW50JylcblxucmVxdWlyZSgnLi4vc3R5bGVzL2luZGljYXRvci5zY3NzJylcblxudmFyIERFRkFVTFRfSVRFTV9DT0xPUiA9ICcjOTk5J1xudmFyIERFRkFVTFRfSVRFTV9TRUxFQ1RFRF9DT0xPUiA9ICcjMDAwMGZmJ1xudmFyIERFRkFVTFRfSVRFTV9TSVpFID0gMjBcbnZhciBERUZBVUxUX01BUkdJTl9TSVpFID0gMTBcblxuLy8gU3R5bGUgc3VwcG9ydGVkOlxuLy8gICBwb3NpdGlvbjogKGRlZmF1bHQgLSBhYnNvbHV0ZSlcbi8vICAgaXRlbUNvbG9yOiBjb2xvciBvZiBpbmRpY2F0b3IgZG90c1xuLy8gICBpdGVtU2VsZWN0ZWRDb2xvcjogY29sb3Igb2YgdGhlIHNlbGVjdGVkIGluZGljYXRvciBkb3Rcbi8vICAgaXRlbVNpemU6IHNpemUgb2YgaW5kaWNhdG9yc1xuLy8gICBvdGhlciBsYXlvdXQgc3R5bGVzXG5mdW5jdGlvbiBJbmRpY2F0b3IgKGRhdGEpIHtcbiAgdGhpcy5kaXJlY3Rpb24gPSAncm93JyAvLyAnY29sdW1uJyBpcyBub3QgdGVtcG9yYXJpbHkgc3VwcG9ydGVkLlxuICB0aGlzLmFtb3VudCA9IGRhdGEuZXh0cmEuYW1vdW50XG4gIHRoaXMuaW5kZXggPSBkYXRhLmV4dHJhLmluZGV4XG4gIHRoaXMuc2xpZGVyV2lkdGggPSBkYXRhLmV4dHJhLndpZHRoXG4gIHRoaXMuc2xpZGVySGVpZ2h0ID0gZGF0YS5leHRyYS5oZWlnaHRcbiAgdmFyIHN0eWxlcyA9IGRhdGEuc3R5bGUgfHwge31cbiAgdGhpcy5kYXRhID0gZGF0YVxuICB0aGlzLnN0eWxlLndpZHRoLmNhbGwodGhpcywgc3R5bGVzLndpZHRoKVxuICB0aGlzLnN0eWxlLmhlaWdodC5jYWxsKHRoaXMsIHN0eWxlcy5oZWlnaHQpXG4gIHRoaXMuaXRlbXMgPSBbXVxuICBBdG9taWMuY2FsbCh0aGlzLCBkYXRhKVxufVxuXG5JbmRpY2F0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShBdG9taWMucHJvdG90eXBlKVxuXG5JbmRpY2F0b3IucHJvdG90eXBlLmNyZWF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIG5vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKVxuICBub2RlLmNsYXNzTGlzdC5hZGQoJ3dlZXgtaW5kaWNhdG9ycycpXG4gIG5vZGUuY2xhc3NMaXN0LmFkZCgnd2VleC1lbGVtZW50JylcbiAgbm9kZS5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSdcbiAgdGhpcy5ub2RlID0gbm9kZVxuICB0aGlzLnN0eWxlLml0ZW1TaXplLmNhbGwodGhpcywgMClcbiAgdGhpcy5pdGVtQ29sb3IgPSBERUZBVUxUX0lURU1fQ09MT1JcbiAgdGhpcy5pdGVtU2VsZWN0ZWRDb2xvciA9IERFRkFVTFRfSVRFTV9TRUxFQ1RFRF9DT0xPUlxuICB0aGlzLnVwZGF0ZVN0eWxlKHtcbiAgICBsZWZ0OiAwLFxuICAgIHRvcDogMCxcbiAgICBpdGVtU2l6ZTogMFxuICB9KVxuICByZXR1cm4gbm9kZVxufVxuXG5JbmRpY2F0b3IucHJvdG90eXBlLmNyZWF0ZUNoaWxkcmVuID0gZnVuY3Rpb24gKCkge1xuICB2YXIgcm9vdCA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuYW1vdW50OyBpKyspIHtcbiAgICB2YXIgaW5kaWNhdG9yID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgICBpbmRpY2F0b3IuY2xhc3NMaXN0LmFkZCgnd2VleC1pbmRpY2F0b3InKVxuICAgIGluZGljYXRvci5zdHlsZS5ib3hTaXppbmcgPSAnYm9yZGVyLWJveCdcbiAgICBpbmRpY2F0b3Iuc3R5bGUubWFyZ2luID0gJzAgJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgKERFRkFVTFRfTUFSR0lOX1NJWkUgKiB0aGlzLmRhdGEuc2NhbGUpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAncHgnXG4gICAgaW5kaWNhdG9yLnN0eWxlLndpZHRoID0gdGhpcy5pdGVtU2l6ZSArICdweCdcbiAgICBpbmRpY2F0b3Iuc3R5bGUuaGVpZ2h0ID0gdGhpcy5pdGVtU2l6ZSArICdweCdcbiAgICBpbmRpY2F0b3Iuc2V0QXR0cmlidXRlKCdpbmRleCcsIGkpXG4gICAgaWYgKHRoaXMuaW5kZXggPT09IGkpIHtcbiAgICAgIGluZGljYXRvci5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLml0ZW1TZWxlY3RlZENvbG9yXG4gICAgfSBlbHNlIHtcbiAgICAgIGluZGljYXRvci5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLml0ZW1Db2xvclxuICAgIH1cbiAgICBpbmRpY2F0b3IuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLl9jbGlja0hhbmRsZXIuYmluZCh0aGlzLCBpKSlcbiAgICB0aGlzLml0ZW1zW2ldID0gaW5kaWNhdG9yXG4gICAgcm9vdC5hcHBlbmRDaGlsZChpbmRpY2F0b3IpXG4gIH1cbiAgdGhpcy5ub2RlLmFwcGVuZENoaWxkKHJvb3QpXG59XG5cbkluZGljYXRvci5wcm90b3R5cGUuc3R5bGVcbiAgICA9IGV4dGVuZChPYmplY3QuY3JlYXRlKEF0b21pYy5wcm90b3R5cGUuc3R5bGUpLCB7XG4gIGl0ZW1Db2xvcjogZnVuY3Rpb24gKHZhbCkge1xuICAgIHRoaXMuaXRlbUNvbG9yID0gdmFsIHx8IERFRkFVTFRfSVRFTV9DT0xPUlxuICAgIGZvciAodmFyIGkgPSAwLCBsID0gdGhpcy5pdGVtcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgIHRoaXMuaXRlbXNbaV0uc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5pdGVtQ29sb3JcbiAgICB9XG4gIH0sXG5cbiAgaXRlbVNlbGVjdGVkQ29sb3I6IGZ1bmN0aW9uICh2YWwpIHtcbiAgICB0aGlzLml0ZW1TZWxlY3RlZENvbG9yID0gdmFsIHx8IERFRkFVTFRfSVRFTV9TRUxFQ1RFRF9DT0xPUlxuICAgIGlmICh0eXBlb2YgdGhpcy5pbmRleCAhPT0gJ3VuZGVmaW5lZCdcbiAgICAgICAgJiYgdGhpcy5pdGVtcy5sZW5ndGggPiB0aGlzLmluZGV4KSB7XG4gICAgICB0aGlzLml0ZW1zW3RoaXMuaW5kZXhdLnN0eWxlLmJhY2tncm91bmRDb2xvclxuICAgICAgICAgID0gdGhpcy5pdGVtU2VsZWN0ZWRDb2xvclxuICAgIH1cbiAgfSxcblxuICBpdGVtU2l6ZTogZnVuY3Rpb24gKHZhbCkge1xuICAgIHZhbCA9IHBhcnNlSW50KHZhbCkgKiB0aGlzLmRhdGEuc2NhbGVcbiAgICAgICAgICB8fCBERUZBVUxUX0lURU1fU0laRSAqIHRoaXMuZGF0YS5zY2FsZVxuICAgIHRoaXMuaXRlbVNpemUgPSB2YWxcbiAgICB0aGlzLm5vZGUuc3R5bGUuaGVpZ2h0ID0gdmFsICsgJ3B4J1xuICAgIGZvciAodmFyIGkgPSAwLCBsID0gdGhpcy5pdGVtcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgIHRoaXMuaXRlbXNbaV0uc3R5bGUud2lkdGggPSB2YWwgKyAncHgnXG4gICAgICB0aGlzLml0ZW1zW2ldLnN0eWxlLmhlaWdodCA9IHZhbCArICdweCdcbiAgICB9XG4gIH0sXG5cbiAgd2lkdGg6IGZ1bmN0aW9uICh2YWwpIHtcbiAgICB2YWwgPSBwYXJzZUludCh2YWwpICogdGhpcy5kYXRhLnNjYWxlIHx8IHBhcnNlSW50KHRoaXMuc2xpZGVyV2lkdGgpXG4gICAgdGhpcy52aXJ0dWFsV3JhcHBlcldpZHRoID0gdmFsXG4gIH0sXG5cbiAgaGVpZ2h0OiBmdW5jdGlvbiAodmFsKSB7XG4gICAgdmFsID0gcGFyc2VJbnQodmFsKSAqIHRoaXMuZGF0YS5zY2FsZSB8fCBwYXJzZUludCh0aGlzLnNsaWRlckhlaWdodClcbiAgICB0aGlzLnZpcnR1YWxXcmFwcGVySGVpZ2h0ID0gdmFsXG4gIH0sXG5cbiAgdG9wOiBmdW5jdGlvbiAodmFsKSB7XG4gICAgdmFsID0gdGhpcy52aXJ0dWFsV3JhcHBlckhlaWdodCAvIDIgLSB0aGlzLml0ZW1TaXplIC8gMlxuICAgICAgICArIHZhbCAqIHRoaXMuZGF0YS5zY2FsZVxuICAgIHRoaXMubm9kZS5zdHlsZS5ib3R0b20gPSAnJ1xuICAgIHRoaXMubm9kZS5zdHlsZS50b3AgPSB2YWwgKyAncHgnXG4gIH0sXG5cbiAgYm90dG9tOiBmdW5jdGlvbiAodmFsKSB7XG4gICAgdmFsID0gdGhpcy52aXJ0dWFsV3JhcHBlckhlaWdodCAvIDIgLSB0aGlzLml0ZW1TaXplIC8gMlxuICAgICAgICArIHZhbCAqIHRoaXMuZGF0YS5zY2FsZVxuICAgIHRoaXMubm9kZS5zdHlsZS50b3AgPSAnJ1xuICAgIHRoaXMubm9kZS5zdHlsZS5ib3R0b20gPSB2YWwgKyAncHgnXG4gIH0sXG5cbiAgbGVmdDogZnVuY3Rpb24gKHZhbCkge1xuICAgIHZhbCA9IHRoaXMudmlydHVhbFdyYXBwZXJXaWR0aCAvIDJcbiAgICAgICAgICAtICh0aGlzLml0ZW1TaXplICsgMiAqIERFRkFVTFRfTUFSR0lOX1NJWkUgKiB0aGlzLmRhdGEuc2NhbGUpXG4gICAgICAgICAgICAgICogdGhpcy5hbW91bnQgLyAyXG4gICAgICAgICAgKyB2YWwgKiB0aGlzLmRhdGEuc2NhbGVcbiAgICB0aGlzLm5vZGUuc3R5bGUucmlnaHQgPSAnJ1xuICAgIHRoaXMubm9kZS5zdHlsZS5sZWZ0ID0gdmFsICsgJ3B4J1xuICB9LFxuXG4gIHJpZ2h0OiBmdW5jdGlvbiAodmFsKSB7XG4gICAgdmFsID0gdGhpcy52aXJ0dWFsV3JhcHBlcldpZHRoIC8gMlxuICAgICAgICAgIC0gKHRoaXMuaXRlbVNpemUgKyAyICogREVGQVVMVF9NQVJHSU5fU0laRSAqIHRoaXMuZGF0YS5zY2FsZSlcbiAgICAgICAgICAgICAgKiB0aGlzLmFtb3VudCAvIDJcbiAgICAgICAgICArIHZhbCAqIHRoaXMuZGF0YS5zY2FsZVxuICAgIHRoaXMubm9kZS5zdHlsZS5sZWZ0ID0gJydcbiAgICB0aGlzLm5vZGUuc3R5bGUucmlnaHQgPSB2YWwgKyAncHgnXG4gIH1cbn0pXG5cbkluZGljYXRvci5wcm90b3R5cGUuc2V0SW5kZXggPSBmdW5jdGlvbiAoaWR4KSB7XG4gIGlmIChpZHggPj0gdGhpcy5hbW91bnQpIHtcbiAgICByZXR1cm5cbiAgfVxuICB2YXIgcHJldiA9IHRoaXMuaXRlbXNbdGhpcy5pbmRleF1cbiAgdmFyIGN1ciA9IHRoaXMuaXRlbXNbaWR4XVxuICBwcmV2LmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2ZScpXG4gIHByZXYuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5pdGVtQ29sb3JcbiAgY3VyLmNsYXNzTGlzdC5hZGQoJ2FjdGl2ZScpXG4gIGN1ci5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLml0ZW1TZWxlY3RlZENvbG9yXG4gIHRoaXMuaW5kZXggPSBpZHhcbn1cblxuSW5kaWNhdG9yLnByb3RvdHlwZS5fY2xpY2tIYW5kbGVyID0gZnVuY3Rpb24gKGlkeCkge1xuICB0aGlzLnNsaWRlci5zbGlkZVRvKGlkeClcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBJbmRpY2F0b3JcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvY29tcG9uZW50cy9pbmRpY2F0b3IuanNcbiAqKiBtb2R1bGUgaWQgPSA0NFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLy8gc3R5bGUtbG9hZGVyOiBBZGRzIHNvbWUgY3NzIHRvIHRoZSBET00gYnkgYWRkaW5nIGEgPHN0eWxlPiB0YWdcblxuLy8gbG9hZCB0aGUgc3R5bGVzXG52YXIgY29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vbm9kZV9tb2R1bGVzL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL2luZGljYXRvci5zY3NzXCIpO1xuaWYodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSBjb250ZW50ID0gW1ttb2R1bGUuaWQsIGNvbnRlbnQsICcnXV07XG4vLyBhZGQgdGhlIHN0eWxlcyB0byB0aGUgRE9NXG52YXIgdXBkYXRlID0gcmVxdWlyZShcIiEuLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvYWRkU3R5bGVzLmpzXCIpKGNvbnRlbnQsIHt9KTtcbmlmKGNvbnRlbnQubG9jYWxzKSBtb2R1bGUuZXhwb3J0cyA9IGNvbnRlbnQubG9jYWxzO1xuLy8gSG90IE1vZHVsZSBSZXBsYWNlbWVudFxuaWYobW9kdWxlLmhvdCkge1xuXHQvLyBXaGVuIHRoZSBzdHlsZXMgY2hhbmdlLCB1cGRhdGUgdGhlIDxzdHlsZT4gdGFnc1xuXHRpZighY29udGVudC5sb2NhbHMpIHtcblx0XHRtb2R1bGUuaG90LmFjY2VwdChcIiEhLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi9ub2RlX21vZHVsZXMvc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vaW5kaWNhdG9yLnNjc3NcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbmV3Q29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vbm9kZV9tb2R1bGVzL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL2luZGljYXRvci5zY3NzXCIpO1xuXHRcdFx0aWYodHlwZW9mIG5ld0NvbnRlbnQgPT09ICdzdHJpbmcnKSBuZXdDb250ZW50ID0gW1ttb2R1bGUuaWQsIG5ld0NvbnRlbnQsICcnXV07XG5cdFx0XHR1cGRhdGUobmV3Q29udGVudCk7XG5cdFx0fSk7XG5cdH1cblx0Ly8gV2hlbiB0aGUgbW9kdWxlIGlzIGRpc3Bvc2VkLCByZW1vdmUgdGhlIDxzdHlsZT4gdGFnc1xuXHRtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24oKSB7IHVwZGF0ZSgpOyB9KTtcbn1cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL3N0eWxlcy9pbmRpY2F0b3Iuc2Nzc1xuICoqIG1vZHVsZSBpZCA9IDQ1XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikoKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIi53ZWV4LWluZGljYXRvcnMge1xcbiAgcG9zaXRpb246IGFic29sdXRlO1xcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDsgfVxcbiAgLndlZXgtaW5kaWNhdG9ycyAud2VleC1pbmRpY2F0b3Ige1xcbiAgICBmbG9hdDogbGVmdDtcXG4gICAgYm9yZGVyLXJhZGl1czogNTAlOyB9XFxuXCIsIFwiXCIsIHtcInZlcnNpb25cIjozLFwic291cmNlc1wiOltcIi8uL3NyYy9zcmMvc3R5bGVzL2luZGljYXRvci5zY3NzXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCJBQUFBO0VBQ0UsbUJBQW1CO0VBQ25CLG9CQUFvQixFQU9yQjtFQVREO0lBS0ksWUFBWTtJQUNaLG1CQUFtQixFQUNwQlwiLFwiZmlsZVwiOlwiaW5kaWNhdG9yLnNjc3NcIixcInNvdXJjZXNDb250ZW50XCI6W1wiLndlZXgtaW5kaWNhdG9ycyB7XFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxuICB3aGl0ZS1zcGFjZTogbm93cmFwO1xcblxcbiAgLndlZXgtaW5kaWNhdG9yIHtcXG4gICAgZmxvYXQ6IGxlZnQ7XFxuICAgIGJvcmRlci1yYWRpdXM6IDUwJTtcXG4gIH1cXG5cXG59XCJdLFwic291cmNlUm9vdFwiOlwid2VicGFjazovL1wifV0pO1xuXG4vLyBleHBvcnRzXG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL34vc2Fzcy1sb2FkZXI/c291cmNlTWFwIS4vc3JjL3N0eWxlcy9pbmRpY2F0b3Iuc2Nzc1xuICoqIG1vZHVsZSBpZCA9IDQ2XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIndXNlIHN0cmljdCdcblxudmFyIEF0b21pYyA9IHJlcXVpcmUoJy4vYXRvbWljJylcbnZhciBtc2dRdWV1ZSA9IHJlcXVpcmUoJy4uL21lc3NhZ2VRdWV1ZScpXG52YXIgY29uZmlnID0gcmVxdWlyZSgnLi4vY29uZmlnJylcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJylcblxuLy8gVE9ETzogcmVmYWN0b3IgdGhpcyBzY3NzIGNvZGUgc2luY2UgdGhpcyBpcyBzdHJvbmdseVxuLy8gZGVwZW5kZW50IG9uIGxpYi5mbGV4aWJsZSBvdGhlciB0aGFuIHRoZSB2YWx1ZSBvZlxuLy8gc2NhbGUuXG5yZXF1aXJlKCcuLi9zdHlsZXMvdGFiaGVhZGVyLnNjc3MnKVxuXG5mdW5jdGlvbiBUYWJIZWFkZXIoZGF0YSkge1xuICBBdG9taWMuY2FsbCh0aGlzLCBkYXRhKVxufVxuXG52YXIgcHJvdG8gPSBUYWJIZWFkZXIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShBdG9taWMucHJvdG90eXBlKVxuXG5wcm90by5jcmVhdGUgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIG91dHNpZGUgY29udGFpbmVyLlxuICB2YXIgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gIG5vZGUuY2xhc3NOYW1lID0gJ3RhYi1oZWFkZXInXG4gIC8vIHRpcCBvbiB0aGUgdG9wLlxuICB2YXIgYmFyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgYmFyLmNsYXNzTmFtZSA9ICdoZWFkZXItYmFyJ1xuICBiYXIudGV4dENvbnRlbnQgPSAnQ0hBTkdFIEZMT09SJ1xuICAvLyBtaWRkbGUgbGF5ZXIuXG4gIHZhciBib2R5ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgYm9keS5jbGFzc05hbWUgPSAnaGVhZGVyLWJvZHknXG4gIHZhciBib3ggPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd1bCcpXG4gIGJveC5jbGFzc05hbWUgPSAndGFiaGVhZGVyJ1xuXG4gIGJvZHkuYXBwZW5kQ2hpbGQoYm94KVxuICBub2RlLmFwcGVuZENoaWxkKGJhcilcbiAgbm9kZS5hcHBlbmRDaGlsZChib2R5KVxuICB0aGlzLl9iYXIgPSBiYXJcbiAgdGhpcy5fYm9keSA9IGJvZHlcbiAgdGhpcy5ib3ggPSBib3hcbiAgdGhpcy5ub2RlID0gbm9kZVxuICAvLyBpbml0IGV2ZW50cy5cbiAgdGhpcy5faW5pdEZvbGRCdG4oKVxuICB0aGlzLl9pbml0RXZlbnQoKVxuICByZXR1cm4gbm9kZVxufVxuXG5wcm90by5faW5pdEZvbGRCdG4gPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBfdGhpcyA9IHRoaXNcbiAgdmFyIG5vZGUgPSB0aGlzLm5vZGVcbiAgdmFyIGJ0biA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKVxuICBidG4uY2xhc3NOYW1lID0gJ2ZvbGQtdG9nZ2xlIGljb25mb250J1xuICBidG4uaW5uZXJIVE1MID0gJyYjeGU2NjE7J1xuICBub2RlLmFwcGVuZENoaWxkKGJ0bilcblxuICBidG4uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKF90aGlzLnVuZm9sZGluZykge1xuICAgICAgX3RoaXMuX2ZvbGRpbmcoKVxuICAgIH0gZWxzZSB7XG4gICAgICBfdGhpcy5fdW5mb2xkaW5nKClcbiAgICB9XG4gIH0pXG59XG5cbnByb3RvLl9pbml0TWFzayA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIG1hc2sgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKVxuICBtYXNrLmNsYXNzTmFtZSA9ICd0YWJoZWFkZXItbWFzaydcbiAgdGhpcy5tYXNrID0gbWFza1xuICAvLyBzdG9wIGRlZmF1bHQgYmVoYXZpb3I6IHBhZ2UgbW92aW5nLlxuICBtYXNrLmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNobW92ZScsIGZ1bmN0aW9uIChldnQpIHtcbiAgICBldnQucHJldmVudERlZmF1bHQoKVxuICB9KVxuICAvLyBjbGljayB0byB1bmZvbGQuXG4gIHZhciBfdGhpcyA9IHRoaXNcbiAgbWFzay5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgICBfdGhpcy5fZm9sZGluZygpXG4gIH0pXG5cbiAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChtYXNrKVxufVxuXG5wcm90by5fdW5mb2xkaW5nID0gZnVuY3Rpb24gKCkge1xuICAvLyBtYXJrIHRoZSBpbml0aWFsIHBvc2lpdG9uIG9mIHRhYmhlYWRlclxuICBpZiAoIXRoaXMuZmxhZykge1xuICAgIHZhciBmbGFnID0gZG9jdW1lbnQuY3JlYXRlQ29tbWVudCgndGFiaGVhZGVyJylcbiAgICB0aGlzLmZsYWcgPSBmbGFnXG4gICAgdGhpcy5ub2RlLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGZsYWcsIHRoaXMubm9kZSlcbiAgfVxuICBpZiAoIXRoaXMubWFzaykge1xuICAgIHRoaXMuX2luaXRNYXNrKClcbiAgfVxuXG4gIC8vIHJlY29yZCB0aGUgc2Nyb2xsIHBvc2l0aW9uLlxuICB0aGlzLl9zY3JvbGxWYWwgPSB0aGlzLl9ib2R5LnNjcm9sbExlZnRcbiAgLy8gcmVjb3JkIHRoZSBwb3NpdGlvbiBpbiBkb2N1bWVudC5cbiAgdGhpcy5fdG9wVmFsID0gdGhpcy5ub2RlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnRvcFxuICB0aGlzLl9zdHlsZVRvcCA9IHRoaXMubm9kZS5zdHlsZS50b3BcblxuICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRoaXMubm9kZSlcbiAgdGhpcy5ub2RlLmNsYXNzTGlzdC5hZGQoJ3VuZm9sZC1oZWFkZXInKVxuICB0aGlzLm5vZGUuc3R5bGUuaGVpZ2h0ID0gJ2F1dG8nXG4gIC8vIHJlY2FsYyB0aGUgcG9zaXRpb24gd2hlbiBpdCBpcyB1bmZvbGRlZC5cbiAgdmFyIHRoSGVpZ2h0ID0gdGhpcy5ub2RlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmhlaWdodFxuICBpZiAodGhIZWlnaHQgKyB0aGlzLl90b3BWYWwgPiB3aW5kb3cuaW5uZXJIZWlnaHQpIHtcbiAgICB0aGlzLl90b3BWYWwgPSB0aGlzLl90b3BWYWxcbiAgICAgICAgKyAod2luZG93LmlubmVySGVpZ2h0IC0gdGhIZWlnaHQgLSB0aGlzLl90b3BWYWwpXG4gIH1cblxuICB0aGlzLm5vZGUuc3R5bGUudG9wID0gdGhpcy5fdG9wVmFsICsgJ3B4J1xuICAvLyBwcm9jZXNzIG1hc2sgc3R5bGVcbiAgdGhpcy5tYXNrLmNsYXNzTGlzdC5hZGQoJ3VuZm9sZC1oZWFkZXInKVxuICB0aGlzLm1hc2suc3R5bGUuaGVpZ2h0ID0gd2luZG93LmlubmVySGVpZ2h0ICsgJ3B4J1xuICB0aGlzLnVuZm9sZGluZyA9IHRydWVcbn1cblxucHJvdG8uX2ZvbGRpbmcgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLnVuZm9sZGluZyAhPT0gdHJ1ZSkge1xuICAgIHJldHVyblxuICB9XG5cbiAgdGhpcy5tYXNrLmNsYXNzTGlzdC5yZW1vdmUoJ3VuZm9sZC1oZWFkZXInKVxuICB0aGlzLm5vZGUuY2xhc3NMaXN0LnJlbW92ZSgndW5mb2xkLWhlYWRlcicpXG5cbiAgdGhpcy5ub2RlLnN0eWxlLmhlaWdodCA9ICcnXG4gIHRoaXMubm9kZS5zdHlsZS50b3AgPSB0aGlzLl9zdHlsZVRvcFxuXG4gIC8vIHJlY292ZXIgdGhlIHBvc2l0aW9uIG9mIHRhYmhlYWRlci5cbiAgdGhpcy5mbGFnLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHRoaXMubm9kZSwgdGhpcy5mbGFnKVxuICAvLyByZWNvdmVyIHRoZSBwb3NpdGlvbiBvZiBzY29sbGVyLlxuICB0aGlzLl9ib2R5LnNjcm9sbExlZnQgPSB0aGlzLl9zY3JvbGxWYWxcblxuICB0aGlzLl9zY3JvbGxUb1ZpZXcoKVxuICB0aGlzLnVuZm9sZGluZyA9IGZhbHNlXG59XG5cbnByb3RvLl9pbml0RXZlbnQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuX2luaXRDbGlja0V2ZW50KClcbiAgdGhpcy5faW5pdFNlbGVjdEV2ZW50KClcbn1cblxuLy8gaW5pdCBldmVudHMuXG5wcm90by5faW5pdENsaWNrRXZlbnQgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBib3ggPSB0aGlzLmJveFxuICB2YXIgX3RoaXMgPSB0aGlzXG5cbiAgYm94LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24gKGV2dCkge1xuICAgIHZhciB0YXJnZXQgPSBldnQudGFyZ2V0XG4gICAgaWYgKHRhcmdldC5ub2RlTmFtZSA9PT0gJ1VMJykge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKHRhcmdldC5wYXJlbnROb2RlLm5vZGVOYW1lID09PSAnTEknKSB7XG4gICAgICB0YXJnZXQgPSB0YXJnZXQucGFyZW50Tm9kZVxuICAgIH1cblxuICAgIHZhciBmbG9vciA9IHRhcmdldC5nZXRBdHRyaWJ1dGUoJ2RhdGEtZmxvb3InKVxuXG4gICAgaWYgKF90aGlzLmRhdGEuYXR0ci5zZWxlY3RlZEluZGV4ID09IGZsb29yKSB7XG4gICAgICAvLyBEdXBsaWNhdGVkIGNsaWNraW5nLCBub3QgdG8gdHJpZ2dlciBzZWxlY3QgZXZlbnQuXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBmaXJlRXZlbnQodGFyZ2V0LCAnc2VsZWN0Jywge2luZGV4OiAgZmxvb3J9KVxuICB9KVxufVxuXG5wcm90by5faW5pdFNlbGVjdEV2ZW50ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgbm9kZSA9IHRoaXMubm9kZVxuICB2YXIgX3RoaXMgPSB0aGlzXG4gIG5vZGUuYWRkRXZlbnRMaXN0ZW5lcignc2VsZWN0JywgZnVuY3Rpb24gKGV2dCkge1xuICAgIHZhciBpbmRleFxuICAgIGlmIChldnQuaW5kZXggIT09IHVuZGVmaW5lZCkge1xuICAgICAgaW5kZXggPSBldnQuaW5kZXhcbiAgICB9IGVsc2UgaWYgKGV2dC5kYXRhICYmIGV2dC5kYXRhLmluZGV4ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGluZGV4ID0gZXZ0LmRhdGEuaW5kZXhcbiAgICB9XG5cbiAgICBpZiAoaW5kZXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgX3RoaXMuYXR0ci5zZWxlY3RlZEluZGV4LmNhbGwoX3RoaXMsIGluZGV4KVxuICB9KVxufVxuXG5wcm90by5hdHRyID0ge1xuICBoaWdobGlnaHRJY29uOiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhpZ2hsaWdodEljb24oKVxuICB9LFxuICBkYXRhOiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGF0dHIgPSB0aGlzLmRhdGEuYXR0clxuICAgIC8vIEVuc3VyZSB0aGVyZSBpcyBhIGRlZmF1bHQgc2VsZWN0ZWQgdmFsdWUuXG4gICAgaWYgKGF0dHIuc2VsZWN0ZWRJbmRleCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBhdHRyLnNlbGVjdGVkSW5kZXggPSAwXG4gICAgfVxuXG4gICAgdmFyIGxpc3QgPSBhdHRyLmRhdGEgfHwgW11cbiAgICB2YXIgY3VySXRlbSA9IGF0dHIuc2VsZWN0ZWRJbmRleFxuXG4gICAgdmFyIHJldCA9IFtdXG4gICAgdmFyIGl0ZW1UbXBsID0gJzxsaSBjbGFzcz1cInRoLWl0ZW1cIiBkYXRhLWZsb29yPVwie3tmbG9vcn19XCI+J1xuICAgICAgICArICd7e2hsSWNvbn19e3tmbG9vck5hbWV9fTwvbGk+J1xuXG4gICAgbGlzdC5mb3JFYWNoKGZ1bmN0aW9uIChpdGVtLCBpZHgpIHtcbiAgICAgIHZhciBodG1sID0gaXRlbVRtcGwucmVwbGFjZSgne3tmbG9vcn19JywgaWR4KVxuICAgICAgaWYgKGN1ckl0ZW0gPT0gaWR4KSB7XG4gICAgICAgIGh0bWwgPSBodG1sLnJlcGxhY2UoJ3t7aGxJY29ufX0nLCBjcmVhdGVIaWdobGlnaHRJY29uKCkpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBodG1sID0gaHRtbC5yZXBsYWNlKCd7e2hsSWNvbn19JywgJycpXG4gICAgICB9XG5cbiAgICAgIGh0bWwgPSBodG1sLnJlcGxhY2UoJ3t7Zmxvb3JOYW1lfX0nLCBpdGVtKVxuXG4gICAgICByZXQucHVzaChodG1sKVxuICAgIH0sIHRoaXMpXG5cbiAgICB0aGlzLmJveC5pbm5lckhUTUwgPSByZXQuam9pbignJylcbiAgfSxcbiAgc2VsZWN0ZWRJbmRleDogZnVuY3Rpb24gKHZhbCkge1xuICAgIHZhciBhdHRyID0gdGhpcy5kYXRhLmF0dHJcblxuICAgIGlmICh2YWwgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdmFsID0gMFxuICAgIH1cblxuICAgIC8vIGlmICh2YWwgPT0gYXR0ci5zZWxlY3RlZEluZGV4KSB7XG4gICAgLy8gICByZXR1cm5cbiAgICAvLyB9XG5cbiAgICBhdHRyLnNlbGVjdGVkSW5kZXggPSB2YWxcblxuICAgIHRoaXMuYXR0ci5kYXRhLmNhbGwodGhpcylcblxuICAgIHRoaXMuX2ZvbGRpbmcoKVxuICAgIHRoaXMuc3R5bGUudGV4dEhpZ2hsaWdodENvbG9yLmNhbGwodGhpcywgdGhpcy50ZXh0SGlnaGxpZ2h0Q29sb3IpXG4gIH1cbn1cblxucHJvdG8uc3R5bGUgPSBPYmplY3QuY3JlYXRlKEF0b21pYy5wcm90b3R5cGUuc3R5bGUpXG5cbnByb3RvLnN0eWxlLm9wYWNpdHkgPSBmdW5jdGlvbiAodmFsKSB7XG4gIGlmICh2YWwgPT09IHVuZGVmaW5lZCB8fCB2YWwgPCAwIHx8IHZhbCA+IDEpIHtcbiAgICB2YWwgPSAxXG4gIH1cblxuICB0aGlzLm5vZGUuc3R5bGUub3BhY2l0eSA9IHZhbFxufVxuXG5wcm90by5zdHlsZS50ZXh0Q29sb3IgPSBmdW5jdGlvbiAodmFsKSB7XG4gIGlmICghaXNWYWxpZENvbG9yKHZhbCkpIHtcbiAgICByZXR1cm5cbiAgfVxuXG4gIHRoaXMubm9kZS5zdHlsZS5jb2xvciA9IHZhbFxufVxuXG5wcm90by5zdHlsZS50ZXh0SGlnaGxpZ2h0Q29sb3IgPSBmdW5jdGlvbiAodmFsKSB7XG4gIGlmICghaXNWYWxpZENvbG9yKHZhbCkpIHtcbiAgICByZXR1cm5cbiAgfVxuICB0aGlzLnRleHRIaWdobGlnaHRDb2xvciA9IHZhbFxuICB2YXIgYXR0ciA9IHRoaXMuZGF0YS5hdHRyXG5cbiAgdmFyIG5vZGUgPSB0aGlzLm5vZGUucXVlcnlTZWxlY3RvcignW2RhdGEtZmxvb3I9XCInXG4gICAgICArIGF0dHIuc2VsZWN0ZWRJbmRleCArICdcIl0nKVxuICBpZiAobm9kZSkge1xuICAgIG5vZGUuc3R5bGUuY29sb3IgPSB2YWxcbiAgICB0aGlzLl9zY3JvbGxUb1ZpZXcobm9kZSlcbiAgfVxufVxuXG5wcm90by5fc2Nyb2xsVG9WaWV3ID0gZnVuY3Rpb24gKG5vZGUpIHtcbiAgaWYgKCFub2RlKSB7XG4gICAgdmFyIGF0dHIgPSB0aGlzLmRhdGEuYXR0clxuICAgIG5vZGUgPSB0aGlzLm5vZGUucXVlcnlTZWxlY3RvcignW2RhdGEtZmxvb3I9XCInICsgYXR0ci5zZWxlY3RlZEluZGV4ICsgJ1wiXScpXG4gIH1cbiAgaWYgKCFub2RlKSB7XG4gICAgcmV0dXJuXG4gIH1cblxuICB2YXIgZGVmYXVsdFZhbCA9IHRoaXMuX2JvZHkuc2Nyb2xsTGVmdFxuICB2YXIgbGVmdFZhbCA9IGRlZmF1bHRWYWwgIC0gbm9kZS5vZmZzZXRMZWZ0ICsgMzAwXG5cbiAgdmFyIHNjcm9sbFZhbCA9IGdldFNjcm9sbFZhbCh0aGlzLl9ib2R5LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLCBub2RlKVxuICBkb1Njcm9sbCh0aGlzLl9ib2R5LCBzY3JvbGxWYWwpXG59XG5cbi8vIHNjcm9sbCB0aGUgdGFiaGVhZGVyLlxuLy8gcG9zaXRpdmUgdmFsIG1lYW5zIHRvIHNjcm9sbCByaWdodC5cbi8vIG5lZ2F0aXZlIHZhbCBtZWFucyB0byBzY3JvbGwgbGVmdC5cbmZ1bmN0aW9uIGRvU2Nyb2xsKG5vZGUsIHZhbCwgZmluaXNoKSB7XG4gIGlmICghdmFsKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKGZpbmlzaCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZmluaXNoID0gTWF0aC5hYnModmFsKVxuICB9XG5cbiAgaWYgKGZpbmlzaCA8PSAwKSB7XG4gICAgcmV0dXJuXG4gIH1cblxuICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodmFsID4gMCkge1xuICAgICAgbm9kZS5zY3JvbGxMZWZ0ICs9IDJcbiAgICB9IGVsc2Uge1xuICAgICAgbm9kZS5zY3JvbGxMZWZ0IC09IDJcbiAgICB9XG4gICAgZmluaXNoIC09IDJcblxuICAgIGRvU2Nyb2xsKG5vZGUsIHZhbCwgZmluaXNoKVxuICB9KVxufVxuXG4vLyBnZXQgc2Nyb2xsIGRpc3RhbmNlLlxuZnVuY3Rpb24gZ2V0U2Nyb2xsVmFsKHJlY3QsIG5vZGUpIHtcbiAgdmFyIGxlZnQgPSBub2RlLnByZXZpb3VzU2libGluZ1xuICB2YXIgcmlnaHQgPSBub2RlLm5leHRTaWJsaW5nXG4gIHZhciBzY3JvbGxWYWxcblxuICAvLyBwcm9jZXNzIGxlZnQtc2lkZSBlbGVtZW50IGZpcnN0LlxuICBpZiAobGVmdCkge1xuICAgIHZhciBsZWZ0UmVjdCA9IGxlZnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcbiAgICAvLyBvbmx5IG5lZWQgdG8gY29tcGFyZSB0aGUgdmFsdWUgb2YgbGVmdC5cbiAgICBpZiAobGVmdFJlY3QubGVmdCA8IHJlY3QubGVmdCkge1xuICAgICAgc2Nyb2xsVmFsID0gbGVmdFJlY3QubGVmdFxuICAgICAgcmV0dXJuIHNjcm9sbFZhbFxuICAgIH1cbiAgfVxuXG4gIGlmIChyaWdodCkge1xuICAgIHZhciByaWdodFJlY3QgPSByaWdodC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICAgIC8vIGNvbXBhcmUgdGhlIHZhbHVlIG9mIHJpZ2h0LlxuICAgIGlmIChyaWdodFJlY3QucmlnaHQgPiByZWN0LnJpZ2h0KSB7XG4gICAgICBzY3JvbGxWYWwgPSByaWdodFJlY3QucmlnaHQgLSByZWN0LnJpZ2h0XG4gICAgICByZXR1cm4gc2Nyb2xsVmFsXG4gICAgfVxuICB9XG5cbiAgLy8gcHJvY2VzcyBjdXJyZW50IG5vZGUsIGZyb20gbGVmdCB0byByaWdodC5cbiAgdmFyIG5vZGVSZWN0ID0gbm9kZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICBpZiAobm9kZVJlY3QubGVmdCA8IHJlY3QubGVmdCkge1xuICAgIHNjcm9sbFZhbCA9IG5vZGVSZWN0LmxlZnRcbiAgfSBlbHNlIGlmIChub2RlUmVjdC5yaWdodCA+IHJlY3QucmlnaHQpIHtcbiAgICBzY3JvbGxWYWwgPSBub2RlUmVjdC5yaWdodCAtIHJlY3QucmlnaHRcbiAgfVxuXG4gIHJldHVybiBzY3JvbGxWYWxcbn1cblxuLy8gdHJpZ2dlciBhbmQgYnJvYWRjYXN0IGV2ZW50cy5cbmZ1bmN0aW9uIGZpcmVFdmVudChlbGVtZW50LCB0eXBlLCBkYXRhKSB7XG4gIHZhciBldnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudCgnRXZlbnQnKVxuICBldnQuZGF0YSA9IGRhdGFcbiAgdXRpbHMuZXh0ZW5kKGV2dCwgZGF0YSlcbiAgLy8gbmVlZCBidWJibGUuXG4gIGV2dC5pbml0RXZlbnQodHlwZSwgdHJ1ZSwgdHJ1ZSlcblxuICBlbGVtZW50LmRpc3BhdGNoRXZlbnQoZXZ0KVxufVxuXG5mdW5jdGlvbiBjcmVhdGVIaWdobGlnaHRJY29uKGNvZGUpIHtcbiAgdmFyIGh0bWwgPSAnPGkgY2xhc3M9XCJobC1pY29uIGljb25mb250XCI+JyArICcmI3hlNjUwJyArICc8L2k+J1xuICByZXR1cm4gaHRtbFxufVxuXG5mdW5jdGlvbiBpc1ZhbGlkQ29sb3IoY29sb3IpIHtcbiAgaWYgKCFjb2xvcikge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgaWYgKGNvbG9yLmNoYXJBdCgwKSAhPT0gJyMnKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICBpZiAoY29sb3IubGVuZ3RoICE9PSA3KSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICByZXR1cm4gdHJ1ZVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFRhYkhlYWRlclxuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL3NyYy9jb21wb25lbnRzL3RhYmhlYWRlci5qc1xuICoqIG1vZHVsZSBpZCA9IDQ3XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIndXNlIHN0cmljdCdcblxudmFyIGNvbmZpZyA9IHJlcXVpcmUoJy4vY29uZmlnJylcbnZhciBtZXNzYWdlUXVldWUgPSBbXVxuXG5mdW5jdGlvbiBmbHVzaE1lc3NhZ2UoKSB7XG4gIGlmICh0eXBlb2YgY2FsbEpTID09PSAnZnVuY3Rpb24nICYmIG1lc3NhZ2VRdWV1ZS5sZW5ndGggPiAwKSB7XG4gICAgY2FsbEpTKGNvbmZpZy5pbnN0YW5jZUlkLCBKU09OLnN0cmluZ2lmeShtZXNzYWdlUXVldWUpKVxuICAgIG1lc3NhZ2VRdWV1ZS5sZW5ndGggPSAwXG4gIH1cbn1cblxuZnVuY3Rpb24gcHVzaChtc2cpIHtcbiAgbWVzc2FnZVF1ZXVlLnB1c2gobXNnKVxufVxuXG4vKipcbiAqIFRvIGZpeCB0aGUgcHJvYmxlbSBvZiBjYWxsYXBwLCB0aGUgdHdvLXdheSB0aW1lIGxvb3AgbWVjaGFuaXNtIG11c3RcbiAqIGJlIHJlcGxhY2VkIGJ5IGRpcmVjdGx5IHByb2NlZHVyZSBjYWxsIGV4Y2VwdCB0aGUgc2l0dWF0aW9uIG9mXG4gKiBwYWdlIGxvYWRpbmcuXG4gKiAyMDE1LTExLTAzXG4gKi9cbmZ1bmN0aW9uIHB1c2hEaXJlY3RseShtc2cpIHtcbiAgY2FsbEpTKGNvbmZpZy5pbnN0YW5jZUlkLCBbbXNnXSlcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHB1c2g6IHB1c2hEaXJlY3RseVxufVxuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL3NyYy9tZXNzYWdlUXVldWUuanNcbiAqKiBtb2R1bGUgaWQgPSA0OFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLy8gc3R5bGUtbG9hZGVyOiBBZGRzIHNvbWUgY3NzIHRvIHRoZSBET00gYnkgYWRkaW5nIGEgPHN0eWxlPiB0YWdcblxuLy8gbG9hZCB0aGUgc3R5bGVzXG52YXIgY29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vbm9kZV9tb2R1bGVzL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL3RhYmhlYWRlci5zY3NzXCIpO1xuaWYodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSBjb250ZW50ID0gW1ttb2R1bGUuaWQsIGNvbnRlbnQsICcnXV07XG4vLyBhZGQgdGhlIHN0eWxlcyB0byB0aGUgRE9NXG52YXIgdXBkYXRlID0gcmVxdWlyZShcIiEuLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvYWRkU3R5bGVzLmpzXCIpKGNvbnRlbnQsIHt9KTtcbmlmKGNvbnRlbnQubG9jYWxzKSBtb2R1bGUuZXhwb3J0cyA9IGNvbnRlbnQubG9jYWxzO1xuLy8gSG90IE1vZHVsZSBSZXBsYWNlbWVudFxuaWYobW9kdWxlLmhvdCkge1xuXHQvLyBXaGVuIHRoZSBzdHlsZXMgY2hhbmdlLCB1cGRhdGUgdGhlIDxzdHlsZT4gdGFnc1xuXHRpZighY29udGVudC5sb2NhbHMpIHtcblx0XHRtb2R1bGUuaG90LmFjY2VwdChcIiEhLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi9ub2RlX21vZHVsZXMvc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vdGFiaGVhZGVyLnNjc3NcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbmV3Q29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vbm9kZV9tb2R1bGVzL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL3RhYmhlYWRlci5zY3NzXCIpO1xuXHRcdFx0aWYodHlwZW9mIG5ld0NvbnRlbnQgPT09ICdzdHJpbmcnKSBuZXdDb250ZW50ID0gW1ttb2R1bGUuaWQsIG5ld0NvbnRlbnQsICcnXV07XG5cdFx0XHR1cGRhdGUobmV3Q29udGVudCk7XG5cdFx0fSk7XG5cdH1cblx0Ly8gV2hlbiB0aGUgbW9kdWxlIGlzIGRpc3Bvc2VkLCByZW1vdmUgdGhlIDxzdHlsZT4gdGFnc1xuXHRtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24oKSB7IHVwZGF0ZSgpOyB9KTtcbn1cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL3N0eWxlcy90YWJoZWFkZXIuc2Nzc1xuICoqIG1vZHVsZSBpZCA9IDQ5XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikoKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIi50YWItaGVhZGVyIHtcXG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcXG4gIHdpZHRoOiAxMHJlbTtcXG4gIGZvbnQtc2l6ZTogMTRweDtcXG4gIGNvbG9yOiAjMzMzOyB9XFxuICAudGFiLWhlYWRlciAuaGVhZGVyLWJhciB7XFxuICAgIGhlaWdodDogMS4xN3JlbTtcXG4gICAgbGluZS1oZWlnaHQ6IDEuMTdyZW07XFxuICAgIGRpc3BsYXk6IG5vbmU7XFxuICAgIGNvbG9yOiAjOTk5O1xcbiAgICBwYWRkaW5nLWxlZnQ6IDAuNHJlbTsgfVxcbiAgLnRhYi1oZWFkZXIgLmhlYWRlci1ib2R5IHtcXG4gICAgbWFyZ2luLXJpZ2h0OiAxLjA3cmVtO1xcbiAgICBvdmVyZmxvdy14OiBhdXRvO1xcbiAgICBvdmVyZmxvdy15OiBoaWRkZW47IH1cXG4gICAgLnRhYi1oZWFkZXIgLmhlYWRlci1ib2R5Ojotd2Via2l0LXNjcm9sbGJhciB7XFxuICAgICAgd2lkdGg6IDA7XFxuICAgICAgaGVpZ2h0OiAwO1xcbiAgICAgIG92ZXJmbG93OiBoaWRkZW47IH1cXG4gIC50YWItaGVhZGVyIC5mb2xkLXRvZ2dsZSB7XFxuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gICAgdG9wOiAwLjU5cmVtO1xcbiAgICAtd2Via2l0LXRyYW5zZm9ybTogdHJhbnNsYXRlWSgtNTAlKTtcXG4gICAgcmlnaHQ6IDAuMjlyZW07XFxuICAgIHdpZHRoOiAwLjQ4cmVtO1xcbiAgICBoZWlnaHQ6IDAuNDhyZW07XFxuICAgIGxpbmUtaGVpZ2h0OiAwLjQ4cmVtO1xcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XFxuICAgIHotaW5kZXg6IDk5O1xcbiAgICBmb250LXNpemU6IDE0cHg7IH1cXG4gIC50YWItaGVhZGVyLnVuZm9sZC1oZWFkZXIge1xcbiAgICBwb3NpdGlvbjogZml4ZWQgIWltcG9ydGFudDtcXG4gICAgdG9wOiAwO1xcbiAgICBsZWZ0OiAwO1xcbiAgICBvdmVyZmxvdzogaGlkZGVuOyB9XFxuXFxuLnRhYmhlYWRlciB7XFxuICBsaXN0LXN0eWxlOiBub25lO1xcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcXG4gIGhlaWdodDogMS4xN3JlbTtcXG4gIGxpbmUtaGVpZ2h0OiAxLjE3cmVtOyB9XFxuICAudGFiaGVhZGVyIC50aC1pdGVtIHtcXG4gICAgcGFkZGluZy1sZWZ0OiAwLjcycmVtO1xcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XFxuICAgIGRpc3BsYXk6IGlubGluZS1ibG9jazsgfVxcbiAgLnRhYmhlYWRlciAuaGwtaWNvbiB7XFxuICAgIHdpZHRoOiAwLjRyZW07XFxuICAgIGhlaWdodDogMC40cmVtO1xcbiAgICBsaW5lLWhlaWdodDogMC40cmVtO1xcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XFxuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gICAgdG9wOiA1MCU7XFxuICAgIC13ZWJraXQtdHJhbnNmb3JtOiB0cmFuc2xhdGVZKC01MCUpO1xcbiAgICBsZWZ0OiAwLjI0cmVtO1xcbiAgICBmb250LXNpemU6IDE0cHg7IH1cXG5cXG4udW5mb2xkLWhlYWRlciAuaGVhZGVyLWJhciB7XFxuICBkaXNwbGF5OiBibG9jazsgfVxcblxcbi51bmZvbGQtaGVhZGVyIC5mb2xkLXRvZ2dsZSB7XFxuICAtd2Via2l0LXRyYW5zZm9ybTogdHJhbnNsYXRlWSgtNTAlKSByb3RhdGUoMTgwZGVnKTsgfVxcblxcbi51bmZvbGQtaGVhZGVyIC5oZWFkZXItYm9keSB7XFxuICBtYXJnaW4tcmlnaHQ6IDA7XFxuICBwYWRkaW5nOiAwLjI0cmVtOyB9XFxuXFxuLnVuZm9sZC1oZWFkZXIgLnRhYmhlYWRlciB7XFxuICBkaXNwbGF5OiBibG9jaztcXG4gIGhlaWdodDogYXV0bzsgfVxcblxcbi51bmZvbGQtaGVhZGVyIC50aC1pdGVtIHtcXG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XFxuICBmbG9hdDogbGVmdDtcXG4gIHdpZHRoOiAzMy4zMzMzJTtcXG4gIGhlaWdodDogMS4wMXJlbTtcXG4gIGxpbmUtaGVpZ2h0OiAxLjAxcmVtOyB9XFxuXFxuLnVuZm9sZC1oZWFkZXIgLmhsLWljb24ge1xcbiAgbWFyZ2luLXJpZ2h0OiAwO1xcbiAgcG9zaXRpb246IGFic29sdXRlOyB9XFxuXFxuLnVuZm9sZC1oZWFkZXIudGFiaGVhZGVyLW1hc2sge1xcbiAgZGlzcGxheTogYmxvY2s7XFxuICB3aWR0aDogMTAwJTtcXG4gIGhlaWdodDogMTAwJTtcXG4gIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMCwgMCwgMCwgMC42KTsgfVxcblxcbi50YWJoZWFkZXItbWFzayB7XFxuICBkaXNwbGF5OiBub25lO1xcbiAgcG9zaXRpb246IGZpeGVkO1xcbiAgbGVmdDogMDtcXG4gIHRvcDogMDsgfVxcblxcbkBmb250LWZhY2Uge1xcbiAgZm9udC1mYW1pbHk6IFxcXCJpY29uZm9udFxcXCI7XFxuICBzcmM6IHVybChcXFwiZGF0YTphcHBsaWNhdGlvbi94LWZvbnQtdHRmO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LEFBRUFBQUFQQUlBQUF3QndSa1pVVFhCRDk4VUFBQUQ4QUFBQUhFOVRMekpYTDF6SUFBQUJHQUFBQUdCamJXRndzNklIYmdBQUFYZ0FBQUZhWTNaMElBeVYvc3dBQUFwUUFBQUFKR1p3WjIwdzk1NlZBQUFLZEFBQUNaWm5ZWE53QUFBQUVBQUFDa2dBQUFBSVoyeDVadXhvUEZJQUFBTFVBQUFFV0dobFlXUUhBNWgzQUFBSExBQUFBRFpvYUdWaEJ6SURjZ0FBQjJRQUFBQWthRzEwZUFzMkFXMEFBQWVJQUFBQUdHeHZZMkVEY0FRZUFBQUhvQUFBQUJCdFlYaHdBU2tLS3dBQUI3QUFBQUFnYm1GdFpRbC8zaGdBQUFmUUFBQUNMbkJ2YzNUbTdmMGJBQUFLQUFBQUFFaHdjbVZ3cGJtK1pnQUFGQXdBQUFDVkFBQUFBUUFBQUFETVBhTFBBQUFBQU5JREtub0FBQUFBMGdNcWV3QUVBL29COUFBRkFBQUNtUUxNQUFBQWp3S1pBc3dBQUFIckFETUJDUUFBQWdBR0F3QUFBQUFBQUFBQUFBRVFBQUFBQUFBQUFBQUFBQUJRWmtWa0FNQUFlT2JlQXl6L0xBQmNBeGdBbEFBQUFBRUFBQUFBQXhnQUFBQUFBQ0FBQVFBQUFBTUFBQUFEQUFBQUhBQUJBQUFBQUFCVUFBTUFBUUFBQUJ3QUJBQTRBQUFBQ2dBSUFBSUFBZ0I0NWxEbVllYmUvLzhBQUFCNDVsRG1ZZWJlLy8vL2l4bTBHYVFaS0FBQkFBQUFBQUFBQUFBQUFBQUFBUVlBQUFFQUFBQUFBQUFBQVFJQUFBQUNBQUFBQUFBQUFBQUFBQUFBQUFBQUFRQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBTUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFDQUNJQUFBRXlBcW9BQXdBSEFDbEFKZ0FBQUFNQ0FBTlhBQUlCQVFKTEFBSUNBVThFQVFFQ0FVTUFBQWNHQlFRQUF3QURFUVVQS3pNUklSRW5NeEVqSWdFUTdzek1BcXI5VmlJQ1pnQUFBQVVBTFAvaEE3d0RHQUFXQURBQU9nQlNBRjRCZDB1d0UxQllRRW9DQVFBTkRnMEFEbVlBQXc0QkRnTmVBQUVJQ0FGY0VBRUpDQW9HQ1Y0UkFRd0dCQVlNWGdBTEJBdHBEd0VJQUFZTUNBWllBQW9IQlFJRUN3b0VXUklCRGc0TlVRQU5EUW9PUWh0THNCZFFXRUJMQWdFQURRNE5BQTVtQUFNT0FRNERYZ0FCQ0FnQlhCQUJDUWdLQ0FrS1poRUJEQVlFQmd4ZUFBc0VDMmtQQVFnQUJnd0lCbGdBQ2djRkFnUUxDZ1JaRWdFT0RnMVJBQTBOQ2c1Q0cwdXdHRkJZUUV3Q0FRQU5EZzBBRG1ZQUF3NEJEZ05lQUFFSUNBRmNFQUVKQ0FvSUNRcG1FUUVNQmdRR0RBUm1BQXNFQzJrUEFRZ0FCZ3dJQmxnQUNnY0ZBZ1FMQ2dSWkVnRU9EZzFSQUEwTkNnNUNHMEJPQWdFQURRNE5BQTVtQUFNT0FRNERBV1lBQVFnT0FRaGtFQUVKQ0FvSUNRcG1FUUVNQmdRR0RBUm1BQXNFQzJrUEFRZ0FCZ3dJQmxnQUNnY0ZBZ1FMQ2dSWkVnRU9EZzFSQUEwTkNnNUNXVmxaUUNoVFV6czdNakVYRjFOZVUxNWJXRHRTTzFKTFF6YzFNVG95T2hjd0Z6QlJFVEVZRVNnVlFCTVdLd0VHS3dFaURnSWRBU0UxTkNZMU5DNENLd0VWSVFVVkZCWVVEZ0lqQmlZckFTY2hCeXNCSWljaUxnSTlBUmNpQmhRV016STJOQ1lYQmdjT0F4NEJPd1l5TmljdUFTY21Kd0UxTkQ0Q093RXlGaDBCQVJrYkdsTVNKUndTQTVBQkNoZ25Ib1grU2dLaUFSVWZJdzRPSHc0Z0xmNUpMQjBpRkJrWklCTUlkd3dTRWd3TkVoS01DQVlGQ3dRQ0JBOE9KVU5SVUVBa0Z4WUpCUWtGQlFiK3BBVVBHaFc4SHlrQ0h3RU1HU2NhVENrUUhBUU5JQnNTWVlnMEZ6bzZKUmNKQVFHQWdBRVRHeUFPcHo4UkdoRVJHaEY4R2hZVEpBNFFEUWdZR2cwakVSTVVBWGZrQ3hnVERCMG00d0FBQWdDZy8yd0RZQUxzQUJJQUdnQWhRQjRBQUFBREFnQURXUUFDQVFFQ1RRQUNBZ0ZSQUFFQ0FVVVRGamtRQkJJckFDQUdGUlFlQXhjV093RXlQd0VTTlRRQUlpWTBOaklXRkFLUy90ek9SRlZ2TVJBSkRnRU9DVzNiL3VLRVhsNkVYZ0xzenBJMWxYeUpOaEVLQzMwQkRJeVMvczVlaEY1ZWhBQUFBQUVBZ2dCSkE0UUI2QUFkQUJ0QUdCSVJBZ0VBQVVBRkFRQStBQUFCQUdnQUFRRmZFeDhDRUNzQkpnY0dCd2tCTGdFR0J3WVVGd0V3TXhjVkZqSTNBVDRETGdJRGVoRVdBd1ArdVA2MEJoRVFCZ29LQVdFQkFRb2FDUUZlQXdRQ0FRRUNCQUhoRWcwREF2NjFBVWtIQkFVR0NSc0ovcUlCQVFrSkFXSUNCd1lIQ0FZR0FBRUFmd0NMQTRFQ0p3QWhBQjFBR2hZUEFnRUFBVUFGQVFBK0FBQUJBR2dDQVFFQlh5UXVFd01SS3lVQk1DY2pOU1lIQmdjQkRnRVVGaGNlQWpNeU53a0JGak15TmpjK0FpNEJBM2YrbndFQkVoVUVBdjZpQlFVRkJRTUhDQVFPQ1FGSUFVd0tEUVlNQlFNRkFRRUZ3d0ZlQVFFUkRRSUQvcDhGREF3TUJBTUVBZ2tCUy82MkNRVUZBd29KQ2drQUFBRUFBQUFCQUFBTEl5bm9Ydzg4OVFBTEJBQUFBQUFBMGdNcWV3QUFBQURTQXlwN0FDTC9iQU84QXhnQUFBQUlBQUlBQUFBQUFBQUFBUUFBQXhqL2JBQmNCQUFBQUFBQUE3d0FBUUFBQUFBQUFBQUFBQUFBQUFBQUFBVUJkZ0FpQUFBQUFBRlZBQUFENlFBc0JBQUFvQUNDQUg4QUFBQW9BQ2dBS0FGa0FhSUI1QUlzQUFFQUFBQUhBRjhBQlFBQUFBQUFBZ0FtQURRQWJBQUFBSW9KbGdBQUFBQUFBQUFNQUpZQUFRQUFBQUFBQVFBSUFBQUFBUUFBQUFBQUFnQUdBQWdBQVFBQUFBQUFBd0FrQUE0QUFRQUFBQUFBQkFBSUFESUFBUUFBQUFBQUJRQkdBRG9BQVFBQUFBQUFCZ0FJQUlBQUF3QUJCQWtBQVFBUUFJZ0FBd0FCQkFrQUFnQU1BSmdBQXdBQkJBa0FBd0JJQUtRQUF3QUJCQWtBQkFBUUFPd0FBd0FCQkFrQUJRQ01BUHdBQXdBQkJBa0FCZ0FRQVlocFkyOXVabTl1ZEUxbFpHbDFiVVp2Ym5SR2IzSm5aU0F5TGpBZ09pQnBZMjl1Wm05dWRDQTZJREkyTFRndE1qQXhOV2xqYjI1bWIyNTBWbVZ5YzJsdmJpQXhMakFnT3lCMGRHWmhkWFJ2YUdsdWRDQW9kakF1T1RRcElDMXNJRGdnTFhJZ05UQWdMVWNnTWpBd0lDMTRJREUwSUMxM0lDSkhJaUF0WmlBdGMybGpiMjVtYjI1MEFHa0FZd0J2QUc0QVpnQnZBRzRBZEFCTkFHVUFaQUJwQUhVQWJRQkdBRzhBYmdCMEFFWUFid0J5QUdjQVpRQWdBRElBTGdBd0FDQUFPZ0FnQUdrQVl3QnZBRzRBWmdCdkFHNEFkQUFnQURvQUlBQXlBRFlBTFFBNEFDMEFNZ0F3QURFQU5RQnBBR01BYndCdUFHWUFid0J1QUhRQVZnQmxBSElBY3dCcEFHOEFiZ0FnQURFQUxnQXdBQ0FBT3dBZ0FIUUFkQUJtQUdFQWRRQjBBRzhBYUFCcEFHNEFkQUFnQUNnQWRnQXdBQzRBT1FBMEFDa0FJQUF0QUd3QUlBQTRBQ0FBTFFCeUFDQUFOUUF3QUNBQUxRQkhBQ0FBTWdBd0FEQUFJQUF0QUhnQUlBQXhBRFFBSUFBdEFIY0FJQUFpQUVjQUlnQWdBQzBBWmdBZ0FDMEFjd0JwQUdNQWJ3QnVBR1lBYndCdUFIUUFBQUFDQUFBQUFBQUEvNE1BTWdBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBY0FBQUFCQUFJQVd3RUNBUU1CQkFkMWJtbEZOalV3QjNWdWFVVTJOakVIZFc1cFJUWkVSUUFCQUFILy93QVBBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQXlBRElER1AvaEF4ai9iQU1ZLytFREdQOXNzQUFzc0NCZ1ppMndBU3dnWkNDd3dGQ3dCQ1phc0FSRlcxZ2hJeUViaWxnZ3NGQlFXQ0d3UUZrYklMQTRVRmdoc0RoWldTQ3dDa1ZoWkxBb1VGZ2hzQXBGSUxBd1VGZ2hzREJaR3lDd3dGQllJR1lnaW9waElMQUtVRmhnR3lDd0lGQllJYkFLWUJzZ3NEWlFXQ0d3Tm1BYllGbFpXUnV3QUN0WldTT3dBRkJZWlZsWkxiQUNMQ0JGSUxBRUpXRmtJTEFGUTFCWXNBVWpRckFHSTBJYklTRlpzQUZnTGJBRExDTWhJeUVnWkxFRllrSWdzQVlqUXJJS0FBSXFJU0N3QmtNZ2lpQ0tzQUFyc1RBRkpZcFJXR0JRRzJGU1dWZ2pXU0Vnc0VCVFdMQUFLeHNoc0VCWkk3QUFVRmhsV1Myd0JDeXdDQ05Dc0FjalFyQUFJMEt3QUVPd0IwTlJXTEFJUXl1eUFBRUFRMkJDc0JabEhGa3RzQVVzc0FCRElFVWdzQUpGWTdBQlJXSmdSQzJ3Qml5d0FFTWdSU0N3QUNzanNRUUVKV0FnUllvallTQmtJTEFnVUZnaHNBQWJzREJRV0xBZ0c3QkFXVmtqc0FCUVdHVlpzQU1sSTJGRVJDMndCeXl4QlFWRnNBRmhSQzJ3Q0N5d0FXQWdJTEFLUTBxd0FGQllJTEFLSTBKWnNBdERTckFBVWxnZ3NBc2pRbGt0c0Frc0lMZ0VBR0lndUFRQVk0b2pZYkFNUTJBZ2ltQWdzQXdqUWlNdHNBb3NTMVJZc1FjQlJGa2tzQTFsSTNndHNBc3NTMUZZUzFOWXNRY0JSRmtiSVZra3NCTmxJM2d0c0F3c3NRQU5RMVZZc1EwTlE3QUJZVUt3Q1N0WnNBQkRzQUlsUXJJQUFRQkRZRUt4Q2dJbFFyRUxBaVZDc0FFV0l5Q3dBeVZRV0xBQVE3QUVKVUtLaWlDS0kyR3dDQ29oSTdBQllTQ0tJMkd3Q0NvaEc3QUFRN0FDSlVLd0FpVmhzQWdxSVZtd0NrTkhzQXREUjJDd2dHSWdzQUpGWTdBQlJXSmdzUUFBRXlORXNBRkRzQUErc2dFQkFVTmdRaTJ3RFN5eEFBVkZWRmdBc0EwalFpQmdzQUZodFE0T0FRQU1BRUpDaW1DeERBUXJzR3NyR3lKWkxiQU9MTEVBRFNzdHNBOHNzUUVOS3kyd0VDeXhBZzByTGJBUkxMRUREU3N0c0JJc3NRUU5LeTJ3RXl5eEJRMHJMYkFVTExFR0RTc3RzQlVzc1FjTkt5MndGaXl4Q0EwckxiQVhMTEVKRFNzdHNCZ3NzQWNyc1FBRlJWUllBTEFOSTBJZ1lMQUJZYlVPRGdFQURBQkNRb3Bnc1F3RUs3QnJLeHNpV1Myd0dTeXhBQmdyTGJBYUxMRUJHQ3N0c0Jzc3NRSVlLeTJ3SEN5eEF4Z3JMYkFkTExFRUdDc3RzQjRzc1FVWUt5MndIeXl4QmhnckxiQWdMTEVIR0NzdHNDRXNzUWdZS3kyd0lpeXhDUmdyTGJBakxDQmdzQTVnSUVNanNBRmdRN0FDSmJBQ0pWRllJeUE4c0FGZ0k3QVNaUndiSVNGWkxiQWtMTEFqSzdBaktpMndKU3dnSUVjZ0lMQUNSV093QVVWaVlDTmhPQ01naWxWWUlFY2dJTEFDUldPd0FVVmlZQ05oT0JzaFdTMndKaXl4QUFWRlZGZ0FzQUVXc0NVcXNBRVZNQnNpV1Myd0p5eXdCeXV4QUFWRlZGZ0FzQUVXc0NVcXNBRVZNQnNpV1Myd0tDd2dOYkFCWUMyd0tTd0FzQU5GWTdBQlJXS3dBQ3V3QWtWanNBRkZZckFBSzdBQUZyUUFBQUFBQUVRK0l6aXhLQUVWS2kyd0tpd2dQQ0JISUxBQ1JXT3dBVVZpWUxBQVEyRTRMYkFyTEM0WFBDMndMQ3dnUENCSElMQUNSV093QVVWaVlMQUFRMkd3QVVOak9DMndMU3l4QWdBV0pTQXVJRWV3QUNOQ3NBSWxTWXFLUnlOSEkyRWdXR0liSVZtd0FTTkNzaXdCQVJVVUtpMndMaXl3QUJhd0JDV3dCQ1ZISTBjalliQUdSU3RsaWk0aklDQThpamd0c0M4c3NBQVdzQVFsc0FRbElDNUhJMGNqWVNDd0JDTkNzQVpGS3lDd1lGQllJTEJBVVZpekFpQURJQnV6QWlZREdsbENRaU1nc0FsRElJb2pSeU5ISTJFalJtQ3dCRU93Z0dKZ0lMQUFLeUNLaW1FZ3NBSkRZR1Fqc0FORFlXUlFXTEFDUTJFYnNBTkRZRm13QXlXd2dHSmhJeUFnc0FRbUkwWmhPQnNqc0FsRFJyQUNKYkFKUTBjalJ5TmhZQ0N3QkVPd2dHSmdJeUN3QUNzanNBUkRZTEFBSzdBRkpXR3dCU1d3Z0dLd0JDWmhJTEFFSldCa0k3QURKV0JrVUZnaEd5TWhXU01nSUxBRUppTkdZVGhaTGJBd0xMQUFGaUFnSUxBRkppQXVSeU5ISTJFalBEZ3RzREVzc0FBV0lMQUpJMElnSUNCR0kwZXdBQ3NqWVRndHNESXNzQUFXc0FNbHNBSWxSeU5ISTJHd0FGUllMaUE4SXlFYnNBSWxzQUlsUnlOSEkyRWdzQVVsc0FRbFJ5TkhJMkd3QmlXd0JTVkpzQUlsWWJBQlJXTWpJRmhpR3lGWlk3QUJSV0pnSXk0aklDQThpamdqSVZrdHNETXNzQUFXSUxBSlF5QXVSeU5ISTJFZ1lMQWdZR2F3Z0dJaklDQThpamd0c0RRc0l5QXVSckFDSlVaU1dDQThXUzZ4SkFFVUt5MndOU3dqSUM1R3NBSWxSbEJZSUR4WkxyRWtBUlFyTGJBMkxDTWdMa2F3QWlWR1VsZ2dQRmtqSUM1R3NBSWxSbEJZSUR4WkxyRWtBUlFyTGJBM0xMQXVLeU1nTGthd0FpVkdVbGdnUEZrdXNTUUJGQ3N0c0Rnc3NDOHJpaUFnUExBRUkwS0tPQ01nTGthd0FpVkdVbGdnUEZrdXNTUUJGQ3V3QkVNdXNDUXJMYkE1TExBQUZyQUVKYkFFSmlBdVJ5TkhJMkd3QmtVckl5QThJQzRqT0xFa0FSUXJMYkE2TExFSkJDVkNzQUFXc0FRbHNBUWxJQzVISTBjallTQ3dCQ05Dc0FaRkt5Q3dZRkJZSUxCQVVWaXpBaUFESUJ1ekFpWURHbGxDUWlNZ1I3QUVRN0NBWW1BZ3NBQXJJSXFLWVNDd0FrTmdaQ093QTBOaFpGQllzQUpEWVJ1d0EwTmdXYkFESmJDQVltR3dBaVZHWVRnaklEd2pPQnNoSUNCR0kwZXdBQ3NqWVRnaFdiRWtBUlFyTGJBN0xMQXVLeTZ4SkFFVUt5MndQQ3l3THlzaEl5QWdQTEFFSTBJak9MRWtBUlFyc0FSRExyQWtLeTJ3UFN5d0FCVWdSN0FBSTBLeUFBRUJGUlFUTHJBcUtpMndQaXl3QUJVZ1I3QUFJMEt5QUFFQkZSUVRMckFxS2kyd1B5eXhBQUVVRTdBcktpMndRQ3l3TFNvdHNFRXNzQUFXUlNNZ0xpQkdpaU5oT0xFa0FSUXJMYkJDTExBSkkwS3dRU3N0c0VNc3NnQUFPaXN0c0VRc3NnQUJPaXN0c0VVc3NnRUFPaXN0c0VZc3NnRUJPaXN0c0Vjc3NnQUFPeXN0c0Vnc3NnQUJPeXN0c0Vrc3NnRUFPeXN0c0Vvc3NnRUJPeXN0c0Vzc3NnQUFOeXN0c0V3c3NnQUJOeXN0c0Uwc3NnRUFOeXN0c0U0c3NnRUJOeXN0c0U4c3NnQUFPU3N0c0ZBc3NnQUJPU3N0c0ZFc3NnRUFPU3N0c0ZJc3NnRUJPU3N0c0ZNc3NnQUFQQ3N0c0ZRc3NnQUJQQ3N0c0ZVc3NnRUFQQ3N0c0ZZc3NnRUJQQ3N0c0Zjc3NnQUFPQ3N0c0Znc3NnQUJPQ3N0c0Zrc3NnRUFPQ3N0c0Zvc3NnRUJPQ3N0c0Zzc3NEQXJMckVrQVJRckxiQmNMTEF3SzdBMEt5MndYU3l3TUN1d05Tc3RzRjRzc0FBV3NEQXJzRFlyTGJCZkxMQXhLeTZ4SkFFVUt5MndZQ3l3TVN1d05Dc3RzR0Vzc0RFcnNEVXJMYkJpTExBeEs3QTJLeTJ3WXl5d01pc3VzU1FCRkNzdHNHUXNzRElyc0RRckxiQmxMTEF5SzdBMUt5MndaaXl3TWl1d05pc3RzR2Nzc0RNckxyRWtBUlFyTGJCb0xMQXpLN0EwS3kyd2FTeXdNeXV3TlNzdHNHb3NzRE1yc0RZckxiQnJMQ3V3Q0dXd0F5UlFlTEFCRlRBdEFBQkx1QURJVWxpeEFRR09XYmtJQUFnQVl5Q3dBU05FSUxBREkzQ3dEa1VnSUV1NEFBNVJTN0FHVTFwWXNEUWJzQ2haWUdZZ2lsVllzQUlsWWJBQlJXTWpZckFDSTBTekNna0ZCQ3V6Q2dzRkJDdXpEZzhGQkN0WnNnUW9DVVZTUkxNS0RRWUVLN0VHQVVTeEpBR0lVVml3UUloWXNRWURSTEVtQVloUldMZ0VBSWhZc1FZQlJGbFpXVm00QWYrRnNBU05zUVVBUkFBQUFBPT1cXFwiKSBmb3JtYXQoXFxcInRydWV0eXBlXFxcIik7IH1cXG5cXG4uaWNvbmZvbnQge1xcbiAgZm9udC1mYW1pbHk6IGljb25mb250ICFpbXBvcnRhbnQ7XFxuICBmb250LXNpemU6IDE2cHg7XFxuICBmb250LXN0eWxlOiBub3JtYWw7XFxuICAtd2Via2l0LWZvbnQtc21vb3RoaW5nOiBhbnRpYWxpYXNlZDtcXG4gIC13ZWJraXQtdGV4dC1zdHJva2Utd2lkdGg6IDAuMnB4O1xcbiAgLW1vei1vc3gtZm9udC1zbW9vdGhpbmc6IGdyYXlzY2FsZTsgfVxcblxcbltkYXRhLWRwcj1cXFwiMlxcXCJdIC50YWItaGVhZGVyIHtcXG4gIGZvbnQtc2l6ZTogMjhweDsgfVxcblxcbltkYXRhLWRwcj1cXFwiM1xcXCJdIC50YWItaGVhZGVyIHtcXG4gIGZvbnQtc2l6ZTogNDJweDsgfVxcblxcbltkYXRhLWRwcj1cXFwiMlxcXCJdIC50YWJoZWFkZXIgLmhsLWljb24ge1xcbiAgZm9udC1zaXplOiAyOHB4OyB9XFxuXFxuW2RhdGEtZHByPVxcXCIzXFxcIl0gLnRhYmhlYWRlciAuaGwtaWNvbiB7XFxuICBmb250LXNpemU6IDQycHg7IH1cXG5cXG5bZGF0YS1kcHI9XFxcIjJcXFwiXSAudGFiLWhlYWRlciAuZm9sZC10b2dnbGUge1xcbiAgZm9udC1zaXplOiAyOHB4OyB9XFxuXFxuW2RhdGEtZHByPVxcXCIzXFxcIl0gLnRhYi1oZWFkZXIgLmZvbGQtdG9nZ2xlIHtcXG4gIGZvbnQtc2l6ZTogNDJweDsgfVxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi9zcmMvc3JjL3N0eWxlcy90YWJoZWFkZXIuc2Nzc1wiLFwiLy4vc3JjL3N0eWxlcy90YWJoZWFkZXIuc2Nzc1wiXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiQUFHQTtFQUNFLG1CQUFtQjtFQUNuQixhQUFhO0VBQ2IsZ0JBQWdCO0VBQ2hCLFlBQVksRUEwQ2I7RUE5Q0Q7SUFPSSxnQkFBZ0I7SUFDaEIscUJBQXFCO0lBQ3JCLGNBQWM7SUFDZCxZQUFZO0lBQ1oscUJBQXFCLEVBQ3RCO0VBWkg7SUFlSSxzQkFBc0I7SUFDdEIsaUJBQWlCO0lBQ2pCLG1CQUFtQixFQU9wQjtJQXhCSDtNQW9CTSxTQUFTO01BQ1QsVUFBVTtNQUNWLGlCQUFpQixFQUNsQjtFQXZCTDtJQTJCSSxtQkFBbUI7SUFDbkIsYUFBYTtJQUNiLG9DQUE2QjtJQUM3QixlQUFlO0lBQ2YsZUFBZTtJQUNmLGdCQUFnQjtJQUNoQixxQkFBcUI7SUFDckIsbUJBQW1CO0lBQ25CLFlBQVk7SUFDWixnQkFBZ0IsRUFDakI7RUFyQ0g7SUF3Q0ksMkJBQTJCO0lBQzNCLE9BQU87SUFDUCxRQUFRO0lBQ1IsaUJBQWlCLEVBQ2xCOztBQUlIO0VBQ0UsaUJBQWlCO0VBQ2pCLG9CQUFvQjtFQUNwQixnQkFBZ0I7RUFDaEIscUJBQXFCLEVBb0J0QjtFQXhCRDtJQU9JLHNCQUFzQjtJQUN0QixtQkFBbUI7SUFDbkIsc0JBQXNCLEVBQ3ZCO0VBVkg7SUFhSSxjQUFjO0lBQ2QsZUFBZTtJQUNmLG9CQUFvQjtJQUNwQixtQkFBbUI7SUFDbkIsbUJBQW1CO0lBQ25CLFNBQVM7SUFDVCxvQ0FBNkI7SUFDN0IsY0FBYztJQUNkLGdCQUFnQixFQUNqQjs7QUFJSDtFQUdJLGVBQWUsRUFDaEI7O0FBSkg7RUFPSSxtREFBMEMsRUFDM0M7O0FBUkg7RUFXSSxnQkFBZ0I7RUFDaEIsaUJBQWlCLEVBQ2xCOztBQWJIO0VBZ0JJLGVBQWU7RUFDZixhQUFhLEVBQ2Q7O0FBbEJIO0VBcUJJLHVCQUF1QjtFQUN2QixZQUFZO0VBQ1osZ0JBQWdCO0VBQ2hCLGdCQUFnQjtFQUNoQixxQkFBcUIsRUFDdEI7O0FBMUJIO0VBNkJJLGdCQUFnQjtFQUNoQixtQkFBbUIsRUFDcEI7O0FBL0JIO0VBa0NJLGVBQWU7RUFDZixZQUFZO0VBQ1osYUFBYTtFQUNiLHFDQUFzQixFQUN2Qjs7QUFHSDtFQUNFLGNBQWM7RUFDZCxnQkFBZ0I7RUFDaEIsUUFBUTtFQUNSLE9BQU8sRUFDUjs7QUFFRDtFQUNFLHdCQUF3QjtFQUN4Qix5OU5BQTQ4TixFQUFBOztBQUc5OE47RUFDRSxpQ0FBaUM7RUFDakMsZ0JBQWdCO0VBQ2hCLG1CQUFtQjtFQUNuQixvQ0FBb0M7RUFDcEMsaUNBQWlDO0VBQ2pDLG1DQUFtQyxFQUNwQzs7QUNoQ0Q7RURtQ0UsZ0JBQWdCLEVBQ2pCOztBQ2pDRDtFRG9DRSxnQkFBZ0IsRUFDakI7O0FDbENEO0VEcUNFLGdCQUFnQixFQUNqQjs7QUNuQ0Q7RURzQ0UsZ0JBQWdCLEVBQ2pCOztBQ3BDRDtFRHVDRSxnQkFBZ0IsRUFDakI7O0FDckNEO0VEd0NFLGdCQUFnQixFQUNqQlwiLFwiZmlsZVwiOlwidGFiaGVhZGVyLnNjc3NcIixcInNvdXJjZXNDb250ZW50XCI6W1wiLy8gSGVhZHMgdXAhIFJlbSBpcyBub3QgYSBnb29kIHdheSBmb3JcXG4vLyB3ZWV4IEhUTUw1IHJlbmRlcmVyLlxcblxcbi50YWItaGVhZGVyIHtcXG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcXG4gIHdpZHRoOiAxMHJlbTtcXG4gIGZvbnQtc2l6ZTogMTRweDtcXG4gIGNvbG9yOiAjMzMzO1xcblxcbiAgLmhlYWRlci1iYXIge1xcbiAgICBoZWlnaHQ6IDEuMTdyZW07XFxuICAgIGxpbmUtaGVpZ2h0OiAxLjE3cmVtO1xcbiAgICBkaXNwbGF5OiBub25lO1xcbiAgICBjb2xvcjogIzk5OTtcXG4gICAgcGFkZGluZy1sZWZ0OiAwLjRyZW07XFxuICB9XFxuICBcXG4gIC5oZWFkZXItYm9keSB7XFxuICAgIG1hcmdpbi1yaWdodDogMS4wN3JlbTtcXG4gICAgb3ZlcmZsb3cteDogYXV0bztcXG4gICAgb3ZlcmZsb3cteTogaGlkZGVuO1xcblxcbiAgICAmOjotd2Via2l0LXNjcm9sbGJhciB7XFxuICAgICAgd2lkdGg6IDA7XFxuICAgICAgaGVpZ2h0OiAwO1xcbiAgICAgIG92ZXJmbG93OiBoaWRkZW47XFxuICAgIH1cXG4gIH1cXG5cXG4gIC5mb2xkLXRvZ2dsZSB7XFxuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gICAgdG9wOiAwLjU5cmVtO1xcbiAgICAtd2Via2l0LXRyYW5zZm9ybTogdHJhbnNsYXRlWSgtNTAlKTtcXG4gICAgcmlnaHQ6IDAuMjlyZW07XFxuICAgIHdpZHRoOiAwLjQ4cmVtO1xcbiAgICBoZWlnaHQ6IDAuNDhyZW07XFxuICAgIGxpbmUtaGVpZ2h0OiAwLjQ4cmVtO1xcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XFxuICAgIHotaW5kZXg6IDk5O1xcbiAgICBmb250LXNpemU6IDE0cHg7XFxuICB9XFxuXFxuICAmLnVuZm9sZC1oZWFkZXIge1xcbiAgICBwb3NpdGlvbjogZml4ZWQgIWltcG9ydGFudDtcXG4gICAgdG9wOiAwO1xcbiAgICBsZWZ0OiAwO1xcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xcbiAgfVxcblxcbn1cXG5cXG4udGFiaGVhZGVyIHtcXG4gIGxpc3Qtc3R5bGU6IG5vbmU7XFxuICB3aGl0ZS1zcGFjZTogbm93cmFwO1xcbiAgaGVpZ2h0OiAxLjE3cmVtO1xcbiAgbGluZS1oZWlnaHQ6IDEuMTdyZW07XFxuXFxuICAudGgtaXRlbSB7XFxuICAgIHBhZGRpbmctbGVmdDogMC43MnJlbTtcXG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xcbiAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XFxuICB9XFxuXFxuICAuaGwtaWNvbiB7XFxuICAgIHdpZHRoOiAwLjRyZW07XFxuICAgIGhlaWdodDogMC40cmVtO1xcbiAgICBsaW5lLWhlaWdodDogMC40cmVtO1xcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XFxuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gICAgdG9wOiA1MCU7XFxuICAgIC13ZWJraXQtdHJhbnNmb3JtOiB0cmFuc2xhdGVZKC01MCUpO1xcbiAgICBsZWZ0OiAwLjI0cmVtO1xcbiAgICBmb250LXNpemU6IDE0cHg7XFxuICB9XFxuXFxufVxcblxcbi51bmZvbGQtaGVhZGVyIHtcXG5cXG4gIC5oZWFkZXItYmFyIHtcXG4gICAgZGlzcGxheTogYmxvY2s7XFxuICB9XFxuXFxuICAuZm9sZC10b2dnbGUge1xcbiAgICAtd2Via2l0LXRyYW5zZm9ybTogdHJhbnNsYXRlWSgtNTAlKSByb3RhdGUoMTgwZGVnKTtcXG4gIH1cXG5cXG4gIC5oZWFkZXItYm9keSB7XFxuICAgIG1hcmdpbi1yaWdodDogMDtcXG4gICAgcGFkZGluZzogMC4yNHJlbTtcXG4gIH1cXG5cXG4gIC50YWJoZWFkZXIge1xcbiAgICBkaXNwbGF5OiBibG9jaztcXG4gICAgaGVpZ2h0OiBhdXRvO1xcbiAgfVxcblxcbiAgLnRoLWl0ZW0ge1xcbiAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xcbiAgICBmbG9hdDogbGVmdDtcXG4gICAgd2lkdGg6IDMzLjMzMzMlO1xcbiAgICBoZWlnaHQ6IDEuMDFyZW07XFxuICAgIGxpbmUtaGVpZ2h0OiAxLjAxcmVtO1xcbiAgfVxcblxcbiAgLmhsLWljb24ge1xcbiAgICBtYXJnaW4tcmlnaHQ6IDA7XFxuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gIH1cXG5cXG4gICYudGFiaGVhZGVyLW1hc2sge1xcbiAgICBkaXNwbGF5OiBibG9jaztcXG4gICAgd2lkdGg6IDEwMCU7XFxuICAgIGhlaWdodDogMTAwJTtcXG4gICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgwLCAwLCAwLCAwLjYpO1xcbiAgfVxcbn1cXG5cXG4udGFiaGVhZGVyLW1hc2sge1xcbiAgZGlzcGxheTogbm9uZTtcXG4gIHBvc2l0aW9uOiBmaXhlZDtcXG4gIGxlZnQ6IDA7XFxuICB0b3A6IDA7XFxufVxcblxcbkBmb250LWZhY2Uge1xcbiAgZm9udC1mYW1pbHk6IFxcXCJpY29uZm9udFxcXCI7XFxuICBzcmM6IHVybChcXFwiZGF0YTphcHBsaWNhdGlvbi94LWZvbnQtdHRmO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LEFBRUFBQUFQQUlBQUF3QndSa1pVVFhCRDk4VUFBQUQ4QUFBQUhFOVRMekpYTDF6SUFBQUJHQUFBQUdCamJXRndzNklIYmdBQUFYZ0FBQUZhWTNaMElBeVYvc3dBQUFwUUFBQUFKR1p3WjIwdzk1NlZBQUFLZEFBQUNaWm5ZWE53QUFBQUVBQUFDa2dBQUFBSVoyeDVadXhvUEZJQUFBTFVBQUFFV0dobFlXUUhBNWgzQUFBSExBQUFBRFpvYUdWaEJ6SURjZ0FBQjJRQUFBQWthRzEwZUFzMkFXMEFBQWVJQUFBQUdHeHZZMkVEY0FRZUFBQUhvQUFBQUJCdFlYaHdBU2tLS3dBQUI3QUFBQUFnYm1GdFpRbC8zaGdBQUFmUUFBQUNMbkJ2YzNUbTdmMGJBQUFLQUFBQUFFaHdjbVZ3cGJtK1pnQUFGQXdBQUFDVkFBQUFBUUFBQUFETVBhTFBBQUFBQU5JREtub0FBQUFBMGdNcWV3QUVBL29COUFBRkFBQUNtUUxNQUFBQWp3S1pBc3dBQUFIckFETUJDUUFBQWdBR0F3QUFBQUFBQUFBQUFBRVFBQUFBQUFBQUFBQUFBQUJRWmtWa0FNQUFlT2JlQXl6L0xBQmNBeGdBbEFBQUFBRUFBQUFBQXhnQUFBQUFBQ0FBQVFBQUFBTUFBQUFEQUFBQUhBQUJBQUFBQUFCVUFBTUFBUUFBQUJ3QUJBQTRBQUFBQ2dBSUFBSUFBZ0I0NWxEbVllYmUvLzhBQUFCNDVsRG1ZZWJlLy8vL2l4bTBHYVFaS0FBQkFBQUFBQUFBQUFBQUFBQUFBUVlBQUFFQUFBQUFBQUFBQVFJQUFBQUNBQUFBQUFBQUFBQUFBQUFBQUFBQUFRQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBTUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFDQUNJQUFBRXlBcW9BQXdBSEFDbEFKZ0FBQUFNQ0FBTlhBQUlCQVFKTEFBSUNBVThFQVFFQ0FVTUFBQWNHQlFRQUF3QURFUVVQS3pNUklSRW5NeEVqSWdFUTdzek1BcXI5VmlJQ1pnQUFBQVVBTFAvaEE3d0RHQUFXQURBQU9nQlNBRjRCZDB1d0UxQllRRW9DQVFBTkRnMEFEbVlBQXc0QkRnTmVBQUVJQ0FGY0VBRUpDQW9HQ1Y0UkFRd0dCQVlNWGdBTEJBdHBEd0VJQUFZTUNBWllBQW9IQlFJRUN3b0VXUklCRGc0TlVRQU5EUW9PUWh0THNCZFFXRUJMQWdFQURRNE5BQTVtQUFNT0FRNERYZ0FCQ0FnQlhCQUJDUWdLQ0FrS1poRUJEQVlFQmd4ZUFBc0VDMmtQQVFnQUJnd0lCbGdBQ2djRkFnUUxDZ1JaRWdFT0RnMVJBQTBOQ2c1Q0cwdXdHRkJZUUV3Q0FRQU5EZzBBRG1ZQUF3NEJEZ05lQUFFSUNBRmNFQUVKQ0FvSUNRcG1FUUVNQmdRR0RBUm1BQXNFQzJrUEFRZ0FCZ3dJQmxnQUNnY0ZBZ1FMQ2dSWkVnRU9EZzFSQUEwTkNnNUNHMEJPQWdFQURRNE5BQTVtQUFNT0FRNERBV1lBQVFnT0FRaGtFQUVKQ0FvSUNRcG1FUUVNQmdRR0RBUm1BQXNFQzJrUEFRZ0FCZ3dJQmxnQUNnY0ZBZ1FMQ2dSWkVnRU9EZzFSQUEwTkNnNUNXVmxaUUNoVFV6czdNakVYRjFOZVUxNWJXRHRTTzFKTFF6YzFNVG95T2hjd0Z6QlJFVEVZRVNnVlFCTVdLd0VHS3dFaURnSWRBU0UxTkNZMU5DNENLd0VWSVFVVkZCWVVEZ0lqQmlZckFTY2hCeXNCSWljaUxnSTlBUmNpQmhRV016STJOQ1lYQmdjT0F4NEJPd1l5TmljdUFTY21Kd0UxTkQ0Q093RXlGaDBCQVJrYkdsTVNKUndTQTVBQkNoZ25Ib1grU2dLaUFSVWZJdzRPSHc0Z0xmNUpMQjBpRkJrWklCTUlkd3dTRWd3TkVoS01DQVlGQ3dRQ0JBOE9KVU5SVUVBa0Z4WUpCUWtGQlFiK3BBVVBHaFc4SHlrQ0h3RU1HU2NhVENrUUhBUU5JQnNTWVlnMEZ6bzZKUmNKQVFHQWdBRVRHeUFPcHo4UkdoRVJHaEY4R2hZVEpBNFFEUWdZR2cwakVSTVVBWGZrQ3hnVERCMG00d0FBQWdDZy8yd0RZQUxzQUJJQUdnQWhRQjRBQUFBREFnQURXUUFDQVFFQ1RRQUNBZ0ZSQUFFQ0FVVVRGamtRQkJJckFDQUdGUlFlQXhjV093RXlQd0VTTlRRQUlpWTBOaklXRkFLUy90ek9SRlZ2TVJBSkRnRU9DVzNiL3VLRVhsNkVYZ0xzenBJMWxYeUpOaEVLQzMwQkRJeVMvczVlaEY1ZWhBQUFBQUVBZ2dCSkE0UUI2QUFkQUJ0QUdCSVJBZ0VBQVVBRkFRQStBQUFCQUdnQUFRRmZFeDhDRUNzQkpnY0dCd2tCTGdFR0J3WVVGd0V3TXhjVkZqSTNBVDRETGdJRGVoRVdBd1ArdVA2MEJoRVFCZ29LQVdFQkFRb2FDUUZlQXdRQ0FRRUNCQUhoRWcwREF2NjFBVWtIQkFVR0NSc0ovcUlCQVFrSkFXSUNCd1lIQ0FZR0FBRUFmd0NMQTRFQ0p3QWhBQjFBR2hZUEFnRUFBVUFGQVFBK0FBQUJBR2dDQVFFQlh5UXVFd01SS3lVQk1DY2pOU1lIQmdjQkRnRVVGaGNlQWpNeU53a0JGak15TmpjK0FpNEJBM2YrbndFQkVoVUVBdjZpQlFVRkJRTUhDQVFPQ1FGSUFVd0tEUVlNQlFNRkFRRUZ3d0ZlQVFFUkRRSUQvcDhGREF3TUJBTUVBZ2tCUy82MkNRVUZBd29KQ2drQUFBRUFBQUFCQUFBTEl5bm9Ydzg4OVFBTEJBQUFBQUFBMGdNcWV3QUFBQURTQXlwN0FDTC9iQU84QXhnQUFBQUlBQUlBQUFBQUFBQUFBUUFBQXhqL2JBQmNCQUFBQUFBQUE3d0FBUUFBQUFBQUFBQUFBQUFBQUFBQUFBVUJkZ0FpQUFBQUFBRlZBQUFENlFBc0JBQUFvQUNDQUg4QUFBQW9BQ2dBS0FGa0FhSUI1QUlzQUFFQUFBQUhBRjhBQlFBQUFBQUFBZ0FtQURRQWJBQUFBSW9KbGdBQUFBQUFBQUFNQUpZQUFRQUFBQUFBQVFBSUFBQUFBUUFBQUFBQUFnQUdBQWdBQVFBQUFBQUFBd0FrQUE0QUFRQUFBQUFBQkFBSUFESUFBUUFBQUFBQUJRQkdBRG9BQVFBQUFBQUFCZ0FJQUlBQUF3QUJCQWtBQVFBUUFJZ0FBd0FCQkFrQUFnQU1BSmdBQXdBQkJBa0FBd0JJQUtRQUF3QUJCQWtBQkFBUUFPd0FBd0FCQkFrQUJRQ01BUHdBQXdBQkJBa0FCZ0FRQVlocFkyOXVabTl1ZEUxbFpHbDFiVVp2Ym5SR2IzSm5aU0F5TGpBZ09pQnBZMjl1Wm05dWRDQTZJREkyTFRndE1qQXhOV2xqYjI1bWIyNTBWbVZ5YzJsdmJpQXhMakFnT3lCMGRHWmhkWFJ2YUdsdWRDQW9kakF1T1RRcElDMXNJRGdnTFhJZ05UQWdMVWNnTWpBd0lDMTRJREUwSUMxM0lDSkhJaUF0WmlBdGMybGpiMjVtYjI1MEFHa0FZd0J2QUc0QVpnQnZBRzRBZEFCTkFHVUFaQUJwQUhVQWJRQkdBRzhBYmdCMEFFWUFid0J5QUdjQVpRQWdBRElBTGdBd0FDQUFPZ0FnQUdrQVl3QnZBRzRBWmdCdkFHNEFkQUFnQURvQUlBQXlBRFlBTFFBNEFDMEFNZ0F3QURFQU5RQnBBR01BYndCdUFHWUFid0J1QUhRQVZnQmxBSElBY3dCcEFHOEFiZ0FnQURFQUxnQXdBQ0FBT3dBZ0FIUUFkQUJtQUdFQWRRQjBBRzhBYUFCcEFHNEFkQUFnQUNnQWRnQXdBQzRBT1FBMEFDa0FJQUF0QUd3QUlBQTRBQ0FBTFFCeUFDQUFOUUF3QUNBQUxRQkhBQ0FBTWdBd0FEQUFJQUF0QUhnQUlBQXhBRFFBSUFBdEFIY0FJQUFpQUVjQUlnQWdBQzBBWmdBZ0FDMEFjd0JwQUdNQWJ3QnVBR1lBYndCdUFIUUFBQUFDQUFBQUFBQUEvNE1BTWdBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBY0FBQUFCQUFJQVd3RUNBUU1CQkFkMWJtbEZOalV3QjNWdWFVVTJOakVIZFc1cFJUWkVSUUFCQUFILy93QVBBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQXlBRElER1AvaEF4ai9iQU1ZLytFREdQOXNzQUFzc0NCZ1ppMndBU3dnWkNDd3dGQ3dCQ1phc0FSRlcxZ2hJeUViaWxnZ3NGQlFXQ0d3UUZrYklMQTRVRmdoc0RoWldTQ3dDa1ZoWkxBb1VGZ2hzQXBGSUxBd1VGZ2hzREJaR3lDd3dGQllJR1lnaW9waElMQUtVRmhnR3lDd0lGQllJYkFLWUJzZ3NEWlFXQ0d3Tm1BYllGbFpXUnV3QUN0WldTT3dBRkJZWlZsWkxiQUNMQ0JGSUxBRUpXRmtJTEFGUTFCWXNBVWpRckFHSTBJYklTRlpzQUZnTGJBRExDTWhJeUVnWkxFRllrSWdzQVlqUXJJS0FBSXFJU0N3QmtNZ2lpQ0tzQUFyc1RBRkpZcFJXR0JRRzJGU1dWZ2pXU0Vnc0VCVFdMQUFLeHNoc0VCWkk3QUFVRmhsV1Myd0JDeXdDQ05Dc0FjalFyQUFJMEt3QUVPd0IwTlJXTEFJUXl1eUFBRUFRMkJDc0JabEhGa3RzQVVzc0FCRElFVWdzQUpGWTdBQlJXSmdSQzJ3Qml5d0FFTWdSU0N3QUNzanNRUUVKV0FnUllvallTQmtJTEFnVUZnaHNBQWJzREJRV0xBZ0c3QkFXVmtqc0FCUVdHVlpzQU1sSTJGRVJDMndCeXl4QlFWRnNBRmhSQzJ3Q0N5d0FXQWdJTEFLUTBxd0FGQllJTEFLSTBKWnNBdERTckFBVWxnZ3NBc2pRbGt0c0Frc0lMZ0VBR0lndUFRQVk0b2pZYkFNUTJBZ2ltQWdzQXdqUWlNdHNBb3NTMVJZc1FjQlJGa2tzQTFsSTNndHNBc3NTMUZZUzFOWXNRY0JSRmtiSVZra3NCTmxJM2d0c0F3c3NRQU5RMVZZc1EwTlE3QUJZVUt3Q1N0WnNBQkRzQUlsUXJJQUFRQkRZRUt4Q2dJbFFyRUxBaVZDc0FFV0l5Q3dBeVZRV0xBQVE3QUVKVUtLaWlDS0kyR3dDQ29oSTdBQllTQ0tJMkd3Q0NvaEc3QUFRN0FDSlVLd0FpVmhzQWdxSVZtd0NrTkhzQXREUjJDd2dHSWdzQUpGWTdBQlJXSmdzUUFBRXlORXNBRkRzQUErc2dFQkFVTmdRaTJ3RFN5eEFBVkZWRmdBc0EwalFpQmdzQUZodFE0T0FRQU1BRUpDaW1DeERBUXJzR3NyR3lKWkxiQU9MTEVBRFNzdHNBOHNzUUVOS3kyd0VDeXhBZzByTGJBUkxMRUREU3N0c0JJc3NRUU5LeTJ3RXl5eEJRMHJMYkFVTExFR0RTc3RzQlVzc1FjTkt5MndGaXl4Q0EwckxiQVhMTEVKRFNzdHNCZ3NzQWNyc1FBRlJWUllBTEFOSTBJZ1lMQUJZYlVPRGdFQURBQkNRb3Bnc1F3RUs3QnJLeHNpV1Myd0dTeXhBQmdyTGJBYUxMRUJHQ3N0c0Jzc3NRSVlLeTJ3SEN5eEF4Z3JMYkFkTExFRUdDc3RzQjRzc1FVWUt5MndIeXl4QmhnckxiQWdMTEVIR0NzdHNDRXNzUWdZS3kyd0lpeXhDUmdyTGJBakxDQmdzQTVnSUVNanNBRmdRN0FDSmJBQ0pWRllJeUE4c0FGZ0k3QVNaUndiSVNGWkxiQWtMTEFqSzdBaktpMndKU3dnSUVjZ0lMQUNSV093QVVWaVlDTmhPQ01naWxWWUlFY2dJTEFDUldPd0FVVmlZQ05oT0JzaFdTMndKaXl4QUFWRlZGZ0FzQUVXc0NVcXNBRVZNQnNpV1Myd0p5eXdCeXV4QUFWRlZGZ0FzQUVXc0NVcXNBRVZNQnNpV1Myd0tDd2dOYkFCWUMyd0tTd0FzQU5GWTdBQlJXS3dBQ3V3QWtWanNBRkZZckFBSzdBQUZyUUFBQUFBQUVRK0l6aXhLQUVWS2kyd0tpd2dQQ0JISUxBQ1JXT3dBVVZpWUxBQVEyRTRMYkFyTEM0WFBDMndMQ3dnUENCSElMQUNSV093QVVWaVlMQUFRMkd3QVVOak9DMndMU3l4QWdBV0pTQXVJRWV3QUNOQ3NBSWxTWXFLUnlOSEkyRWdXR0liSVZtd0FTTkNzaXdCQVJVVUtpMndMaXl3QUJhd0JDV3dCQ1ZISTBjalliQUdSU3RsaWk0aklDQThpamd0c0M4c3NBQVdzQVFsc0FRbElDNUhJMGNqWVNDd0JDTkNzQVpGS3lDd1lGQllJTEJBVVZpekFpQURJQnV6QWlZREdsbENRaU1nc0FsRElJb2pSeU5ISTJFalJtQ3dCRU93Z0dKZ0lMQUFLeUNLaW1FZ3NBSkRZR1Fqc0FORFlXUlFXTEFDUTJFYnNBTkRZRm13QXlXd2dHSmhJeUFnc0FRbUkwWmhPQnNqc0FsRFJyQUNKYkFKUTBjalJ5TmhZQ0N3QkVPd2dHSmdJeUN3QUNzanNBUkRZTEFBSzdBRkpXR3dCU1d3Z0dLd0JDWmhJTEFFSldCa0k3QURKV0JrVUZnaEd5TWhXU01nSUxBRUppTkdZVGhaTGJBd0xMQUFGaUFnSUxBRkppQXVSeU5ISTJFalBEZ3RzREVzc0FBV0lMQUpJMElnSUNCR0kwZXdBQ3NqWVRndHNESXNzQUFXc0FNbHNBSWxSeU5ISTJHd0FGUllMaUE4SXlFYnNBSWxzQUlsUnlOSEkyRWdzQVVsc0FRbFJ5TkhJMkd3QmlXd0JTVkpzQUlsWWJBQlJXTWpJRmhpR3lGWlk3QUJSV0pnSXk0aklDQThpamdqSVZrdHNETXNzQUFXSUxBSlF5QXVSeU5ISTJFZ1lMQWdZR2F3Z0dJaklDQThpamd0c0RRc0l5QXVSckFDSlVaU1dDQThXUzZ4SkFFVUt5MndOU3dqSUM1R3NBSWxSbEJZSUR4WkxyRWtBUlFyTGJBMkxDTWdMa2F3QWlWR1VsZ2dQRmtqSUM1R3NBSWxSbEJZSUR4WkxyRWtBUlFyTGJBM0xMQXVLeU1nTGthd0FpVkdVbGdnUEZrdXNTUUJGQ3N0c0Rnc3NDOHJpaUFnUExBRUkwS0tPQ01nTGthd0FpVkdVbGdnUEZrdXNTUUJGQ3V3QkVNdXNDUXJMYkE1TExBQUZyQUVKYkFFSmlBdVJ5TkhJMkd3QmtVckl5QThJQzRqT0xFa0FSUXJMYkE2TExFSkJDVkNzQUFXc0FRbHNBUWxJQzVISTBjallTQ3dCQ05Dc0FaRkt5Q3dZRkJZSUxCQVVWaXpBaUFESUJ1ekFpWURHbGxDUWlNZ1I3QUVRN0NBWW1BZ3NBQXJJSXFLWVNDd0FrTmdaQ093QTBOaFpGQllzQUpEWVJ1d0EwTmdXYkFESmJDQVltR3dBaVZHWVRnaklEd2pPQnNoSUNCR0kwZXdBQ3NqWVRnaFdiRWtBUlFyTGJBN0xMQXVLeTZ4SkFFVUt5MndQQ3l3THlzaEl5QWdQTEFFSTBJak9MRWtBUlFyc0FSRExyQWtLeTJ3UFN5d0FCVWdSN0FBSTBLeUFBRUJGUlFUTHJBcUtpMndQaXl3QUJVZ1I3QUFJMEt5QUFFQkZSUVRMckFxS2kyd1B5eXhBQUVVRTdBcktpMndRQ3l3TFNvdHNFRXNzQUFXUlNNZ0xpQkdpaU5oT0xFa0FSUXJMYkJDTExBSkkwS3dRU3N0c0VNc3NnQUFPaXN0c0VRc3NnQUJPaXN0c0VVc3NnRUFPaXN0c0VZc3NnRUJPaXN0c0Vjc3NnQUFPeXN0c0Vnc3NnQUJPeXN0c0Vrc3NnRUFPeXN0c0Vvc3NnRUJPeXN0c0Vzc3NnQUFOeXN0c0V3c3NnQUJOeXN0c0Uwc3NnRUFOeXN0c0U0c3NnRUJOeXN0c0U4c3NnQUFPU3N0c0ZBc3NnQUJPU3N0c0ZFc3NnRUFPU3N0c0ZJc3NnRUJPU3N0c0ZNc3NnQUFQQ3N0c0ZRc3NnQUJQQ3N0c0ZVc3NnRUFQQ3N0c0ZZc3NnRUJQQ3N0c0Zjc3NnQUFPQ3N0c0Znc3NnQUJPQ3N0c0Zrc3NnRUFPQ3N0c0Zvc3NnRUJPQ3N0c0Zzc3NEQXJMckVrQVJRckxiQmNMTEF3SzdBMEt5MndYU3l3TUN1d05Tc3RzRjRzc0FBV3NEQXJzRFlyTGJCZkxMQXhLeTZ4SkFFVUt5MndZQ3l3TVN1d05Dc3RzR0Vzc0RFcnNEVXJMYkJpTExBeEs3QTJLeTJ3WXl5d01pc3VzU1FCRkNzdHNHUXNzRElyc0RRckxiQmxMTEF5SzdBMUt5MndaaXl3TWl1d05pc3RzR2Nzc0RNckxyRWtBUlFyTGJCb0xMQXpLN0EwS3kyd2FTeXdNeXV3TlNzdHNHb3NzRE1yc0RZckxiQnJMQ3V3Q0dXd0F5UlFlTEFCRlRBdEFBQkx1QURJVWxpeEFRR09XYmtJQUFnQVl5Q3dBU05FSUxBREkzQ3dEa1VnSUV1NEFBNVJTN0FHVTFwWXNEUWJzQ2haWUdZZ2lsVllzQUlsWWJBQlJXTWpZckFDSTBTekNna0ZCQ3V6Q2dzRkJDdXpEZzhGQkN0WnNnUW9DVVZTUkxNS0RRWUVLN0VHQVVTeEpBR0lVVml3UUloWXNRWURSTEVtQVloUldMZ0VBSWhZc1FZQlJGbFpXVm00QWYrRnNBU05zUVVBUkFBQUFBPT1cXFwiKSBmb3JtYXQoXFxcInRydWV0eXBlXFxcIik7XFxufVxcblxcbi5pY29uZm9udCB7XFxuICBmb250LWZhbWlseTogaWNvbmZvbnQgIWltcG9ydGFudDtcXG4gIGZvbnQtc2l6ZTogMTZweDtcXG4gIGZvbnQtc3R5bGU6IG5vcm1hbDtcXG4gIC13ZWJraXQtZm9udC1zbW9vdGhpbmc6IGFudGlhbGlhc2VkO1xcbiAgLXdlYmtpdC10ZXh0LXN0cm9rZS13aWR0aDogMC4ycHg7XFxuICAtbW96LW9zeC1mb250LXNtb290aGluZzogZ3JheXNjYWxlO1xcbn1cXG5cXG5bZGF0YS1kcHI9XFxcIjJcXFwiXSAudGFiLWhlYWRlciB7XFxuICBmb250LXNpemU6IDI4cHg7XFxufVxcblxcbltkYXRhLWRwcj1cXFwiM1xcXCJdIC50YWItaGVhZGVyIHtcXG4gIGZvbnQtc2l6ZTogNDJweDtcXG59XFxuXFxuW2RhdGEtZHByPVxcXCIyXFxcIl0gLnRhYmhlYWRlciAuaGwtaWNvbiB7XFxuICBmb250LXNpemU6IDI4cHg7XFxufVxcblxcbltkYXRhLWRwcj1cXFwiM1xcXCJdIC50YWJoZWFkZXIgLmhsLWljb24ge1xcbiAgZm9udC1zaXplOiA0MnB4O1xcbn1cXG5cXG5bZGF0YS1kcHI9XFxcIjJcXFwiXSAudGFiLWhlYWRlciAuZm9sZC10b2dnbGUge1xcbiAgZm9udC1zaXplOiAyOHB4O1xcbn1cXG5cXG5bZGF0YS1kcHI9XFxcIjNcXFwiXSAudGFiLWhlYWRlciAuZm9sZC10b2dnbGUge1xcbiAgZm9udC1zaXplOiA0MnB4O1xcbn1cIixcIi50YWItaGVhZGVyIHtcXG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcXG4gIHdpZHRoOiAxMHJlbTtcXG4gIGZvbnQtc2l6ZTogMTRweDtcXG4gIGNvbG9yOiAjMzMzOyB9XFxuICAudGFiLWhlYWRlciAuaGVhZGVyLWJhciB7XFxuICAgIGhlaWdodDogMS4xN3JlbTtcXG4gICAgbGluZS1oZWlnaHQ6IDEuMTdyZW07XFxuICAgIGRpc3BsYXk6IG5vbmU7XFxuICAgIGNvbG9yOiAjOTk5O1xcbiAgICBwYWRkaW5nLWxlZnQ6IDAuNHJlbTsgfVxcbiAgLnRhYi1oZWFkZXIgLmhlYWRlci1ib2R5IHtcXG4gICAgbWFyZ2luLXJpZ2h0OiAxLjA3cmVtO1xcbiAgICBvdmVyZmxvdy14OiBhdXRvO1xcbiAgICBvdmVyZmxvdy15OiBoaWRkZW47IH1cXG4gICAgLnRhYi1oZWFkZXIgLmhlYWRlci1ib2R5Ojotd2Via2l0LXNjcm9sbGJhciB7XFxuICAgICAgd2lkdGg6IDA7XFxuICAgICAgaGVpZ2h0OiAwO1xcbiAgICAgIG92ZXJmbG93OiBoaWRkZW47IH1cXG4gIC50YWItaGVhZGVyIC5mb2xkLXRvZ2dsZSB7XFxuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gICAgdG9wOiAwLjU5cmVtO1xcbiAgICAtd2Via2l0LXRyYW5zZm9ybTogdHJhbnNsYXRlWSgtNTAlKTtcXG4gICAgcmlnaHQ6IDAuMjlyZW07XFxuICAgIHdpZHRoOiAwLjQ4cmVtO1xcbiAgICBoZWlnaHQ6IDAuNDhyZW07XFxuICAgIGxpbmUtaGVpZ2h0OiAwLjQ4cmVtO1xcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XFxuICAgIHotaW5kZXg6IDk5O1xcbiAgICBmb250LXNpemU6IDE0cHg7IH1cXG4gIC50YWItaGVhZGVyLnVuZm9sZC1oZWFkZXIge1xcbiAgICBwb3NpdGlvbjogZml4ZWQgIWltcG9ydGFudDtcXG4gICAgdG9wOiAwO1xcbiAgICBsZWZ0OiAwO1xcbiAgICBvdmVyZmxvdzogaGlkZGVuOyB9XFxuXFxuLnRhYmhlYWRlciB7XFxuICBsaXN0LXN0eWxlOiBub25lO1xcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcXG4gIGhlaWdodDogMS4xN3JlbTtcXG4gIGxpbmUtaGVpZ2h0OiAxLjE3cmVtOyB9XFxuICAudGFiaGVhZGVyIC50aC1pdGVtIHtcXG4gICAgcGFkZGluZy1sZWZ0OiAwLjcycmVtO1xcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XFxuICAgIGRpc3BsYXk6IGlubGluZS1ibG9jazsgfVxcbiAgLnRhYmhlYWRlciAuaGwtaWNvbiB7XFxuICAgIHdpZHRoOiAwLjRyZW07XFxuICAgIGhlaWdodDogMC40cmVtO1xcbiAgICBsaW5lLWhlaWdodDogMC40cmVtO1xcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XFxuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gICAgdG9wOiA1MCU7XFxuICAgIC13ZWJraXQtdHJhbnNmb3JtOiB0cmFuc2xhdGVZKC01MCUpO1xcbiAgICBsZWZ0OiAwLjI0cmVtO1xcbiAgICBmb250LXNpemU6IDE0cHg7IH1cXG5cXG4udW5mb2xkLWhlYWRlciAuaGVhZGVyLWJhciB7XFxuICBkaXNwbGF5OiBibG9jazsgfVxcblxcbi51bmZvbGQtaGVhZGVyIC5mb2xkLXRvZ2dsZSB7XFxuICAtd2Via2l0LXRyYW5zZm9ybTogdHJhbnNsYXRlWSgtNTAlKSByb3RhdGUoMTgwZGVnKTsgfVxcblxcbi51bmZvbGQtaGVhZGVyIC5oZWFkZXItYm9keSB7XFxuICBtYXJnaW4tcmlnaHQ6IDA7XFxuICBwYWRkaW5nOiAwLjI0cmVtOyB9XFxuXFxuLnVuZm9sZC1oZWFkZXIgLnRhYmhlYWRlciB7XFxuICBkaXNwbGF5OiBibG9jaztcXG4gIGhlaWdodDogYXV0bzsgfVxcblxcbi51bmZvbGQtaGVhZGVyIC50aC1pdGVtIHtcXG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XFxuICBmbG9hdDogbGVmdDtcXG4gIHdpZHRoOiAzMy4zMzMzJTtcXG4gIGhlaWdodDogMS4wMXJlbTtcXG4gIGxpbmUtaGVpZ2h0OiAxLjAxcmVtOyB9XFxuXFxuLnVuZm9sZC1oZWFkZXIgLmhsLWljb24ge1xcbiAgbWFyZ2luLXJpZ2h0OiAwO1xcbiAgcG9zaXRpb246IGFic29sdXRlOyB9XFxuXFxuLnVuZm9sZC1oZWFkZXIudGFiaGVhZGVyLW1hc2sge1xcbiAgZGlzcGxheTogYmxvY2s7XFxuICB3aWR0aDogMTAwJTtcXG4gIGhlaWdodDogMTAwJTtcXG4gIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMCwgMCwgMCwgMC42KTsgfVxcblxcbi50YWJoZWFkZXItbWFzayB7XFxuICBkaXNwbGF5OiBub25lO1xcbiAgcG9zaXRpb246IGZpeGVkO1xcbiAgbGVmdDogMDtcXG4gIHRvcDogMDsgfVxcblxcbkBmb250LWZhY2Uge1xcbiAgZm9udC1mYW1pbHk6IFxcXCJpY29uZm9udFxcXCI7XFxuICBzcmM6IHVybChcXFwiZGF0YTphcHBsaWNhdGlvbi94LWZvbnQtdHRmO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LEFBRUFBQUFQQUlBQUF3QndSa1pVVFhCRDk4VUFBQUQ4QUFBQUhFOVRMekpYTDF6SUFBQUJHQUFBQUdCamJXRndzNklIYmdBQUFYZ0FBQUZhWTNaMElBeVYvc3dBQUFwUUFBQUFKR1p3WjIwdzk1NlZBQUFLZEFBQUNaWm5ZWE53QUFBQUVBQUFDa2dBQUFBSVoyeDVadXhvUEZJQUFBTFVBQUFFV0dobFlXUUhBNWgzQUFBSExBQUFBRFpvYUdWaEJ6SURjZ0FBQjJRQUFBQWthRzEwZUFzMkFXMEFBQWVJQUFBQUdHeHZZMkVEY0FRZUFBQUhvQUFBQUJCdFlYaHdBU2tLS3dBQUI3QUFBQUFnYm1GdFpRbC8zaGdBQUFmUUFBQUNMbkJ2YzNUbTdmMGJBQUFLQUFBQUFFaHdjbVZ3cGJtK1pnQUFGQXdBQUFDVkFBQUFBUUFBQUFETVBhTFBBQUFBQU5JREtub0FBQUFBMGdNcWV3QUVBL29COUFBRkFBQUNtUUxNQUFBQWp3S1pBc3dBQUFIckFETUJDUUFBQWdBR0F3QUFBQUFBQUFBQUFBRVFBQUFBQUFBQUFBQUFBQUJRWmtWa0FNQUFlT2JlQXl6L0xBQmNBeGdBbEFBQUFBRUFBQUFBQXhnQUFBQUFBQ0FBQVFBQUFBTUFBQUFEQUFBQUhBQUJBQUFBQUFCVUFBTUFBUUFBQUJ3QUJBQTRBQUFBQ2dBSUFBSUFBZ0I0NWxEbVllYmUvLzhBQUFCNDVsRG1ZZWJlLy8vL2l4bTBHYVFaS0FBQkFBQUFBQUFBQUFBQUFBQUFBUVlBQUFFQUFBQUFBQUFBQVFJQUFBQUNBQUFBQUFBQUFBQUFBQUFBQUFBQUFRQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBTUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFDQUNJQUFBRXlBcW9BQXdBSEFDbEFKZ0FBQUFNQ0FBTlhBQUlCQVFKTEFBSUNBVThFQVFFQ0FVTUFBQWNHQlFRQUF3QURFUVVQS3pNUklSRW5NeEVqSWdFUTdzek1BcXI5VmlJQ1pnQUFBQVVBTFAvaEE3d0RHQUFXQURBQU9nQlNBRjRCZDB1d0UxQllRRW9DQVFBTkRnMEFEbVlBQXc0QkRnTmVBQUVJQ0FGY0VBRUpDQW9HQ1Y0UkFRd0dCQVlNWGdBTEJBdHBEd0VJQUFZTUNBWllBQW9IQlFJRUN3b0VXUklCRGc0TlVRQU5EUW9PUWh0THNCZFFXRUJMQWdFQURRNE5BQTVtQUFNT0FRNERYZ0FCQ0FnQlhCQUJDUWdLQ0FrS1poRUJEQVlFQmd4ZUFBc0VDMmtQQVFnQUJnd0lCbGdBQ2djRkFnUUxDZ1JaRWdFT0RnMVJBQTBOQ2c1Q0cwdXdHRkJZUUV3Q0FRQU5EZzBBRG1ZQUF3NEJEZ05lQUFFSUNBRmNFQUVKQ0FvSUNRcG1FUUVNQmdRR0RBUm1BQXNFQzJrUEFRZ0FCZ3dJQmxnQUNnY0ZBZ1FMQ2dSWkVnRU9EZzFSQUEwTkNnNUNHMEJPQWdFQURRNE5BQTVtQUFNT0FRNERBV1lBQVFnT0FRaGtFQUVKQ0FvSUNRcG1FUUVNQmdRR0RBUm1BQXNFQzJrUEFRZ0FCZ3dJQmxnQUNnY0ZBZ1FMQ2dSWkVnRU9EZzFSQUEwTkNnNUNXVmxaUUNoVFV6czdNakVYRjFOZVUxNWJXRHRTTzFKTFF6YzFNVG95T2hjd0Z6QlJFVEVZRVNnVlFCTVdLd0VHS3dFaURnSWRBU0UxTkNZMU5DNENLd0VWSVFVVkZCWVVEZ0lqQmlZckFTY2hCeXNCSWljaUxnSTlBUmNpQmhRV016STJOQ1lYQmdjT0F4NEJPd1l5TmljdUFTY21Kd0UxTkQ0Q093RXlGaDBCQVJrYkdsTVNKUndTQTVBQkNoZ25Ib1grU2dLaUFSVWZJdzRPSHc0Z0xmNUpMQjBpRkJrWklCTUlkd3dTRWd3TkVoS01DQVlGQ3dRQ0JBOE9KVU5SVUVBa0Z4WUpCUWtGQlFiK3BBVVBHaFc4SHlrQ0h3RU1HU2NhVENrUUhBUU5JQnNTWVlnMEZ6bzZKUmNKQVFHQWdBRVRHeUFPcHo4UkdoRVJHaEY4R2hZVEpBNFFEUWdZR2cwakVSTVVBWGZrQ3hnVERCMG00d0FBQWdDZy8yd0RZQUxzQUJJQUdnQWhRQjRBQUFBREFnQURXUUFDQVFFQ1RRQUNBZ0ZSQUFFQ0FVVVRGamtRQkJJckFDQUdGUlFlQXhjV093RXlQd0VTTlRRQUlpWTBOaklXRkFLUy90ek9SRlZ2TVJBSkRnRU9DVzNiL3VLRVhsNkVYZ0xzenBJMWxYeUpOaEVLQzMwQkRJeVMvczVlaEY1ZWhBQUFBQUVBZ2dCSkE0UUI2QUFkQUJ0QUdCSVJBZ0VBQVVBRkFRQStBQUFCQUdnQUFRRmZFeDhDRUNzQkpnY0dCd2tCTGdFR0J3WVVGd0V3TXhjVkZqSTNBVDRETGdJRGVoRVdBd1ArdVA2MEJoRVFCZ29LQVdFQkFRb2FDUUZlQXdRQ0FRRUNCQUhoRWcwREF2NjFBVWtIQkFVR0NSc0ovcUlCQVFrSkFXSUNCd1lIQ0FZR0FBRUFmd0NMQTRFQ0p3QWhBQjFBR2hZUEFnRUFBVUFGQVFBK0FBQUJBR2dDQVFFQlh5UXVFd01SS3lVQk1DY2pOU1lIQmdjQkRnRVVGaGNlQWpNeU53a0JGak15TmpjK0FpNEJBM2YrbndFQkVoVUVBdjZpQlFVRkJRTUhDQVFPQ1FGSUFVd0tEUVlNQlFNRkFRRUZ3d0ZlQVFFUkRRSUQvcDhGREF3TUJBTUVBZ2tCUy82MkNRVUZBd29KQ2drQUFBRUFBQUFCQUFBTEl5bm9Ydzg4OVFBTEJBQUFBQUFBMGdNcWV3QUFBQURTQXlwN0FDTC9iQU84QXhnQUFBQUlBQUlBQUFBQUFBQUFBUUFBQXhqL2JBQmNCQUFBQUFBQUE3d0FBUUFBQUFBQUFBQUFBQUFBQUFBQUFBVUJkZ0FpQUFBQUFBRlZBQUFENlFBc0JBQUFvQUNDQUg4QUFBQW9BQ2dBS0FGa0FhSUI1QUlzQUFFQUFBQUhBRjhBQlFBQUFBQUFBZ0FtQURRQWJBQUFBSW9KbGdBQUFBQUFBQUFNQUpZQUFRQUFBQUFBQVFBSUFBQUFBUUFBQUFBQUFnQUdBQWdBQVFBQUFBQUFBd0FrQUE0QUFRQUFBQUFBQkFBSUFESUFBUUFBQUFBQUJRQkdBRG9BQVFBQUFBQUFCZ0FJQUlBQUF3QUJCQWtBQVFBUUFJZ0FBd0FCQkFrQUFnQU1BSmdBQXdBQkJBa0FBd0JJQUtRQUF3QUJCQWtBQkFBUUFPd0FBd0FCQkFrQUJRQ01BUHdBQXdBQkJBa0FCZ0FRQVlocFkyOXVabTl1ZEUxbFpHbDFiVVp2Ym5SR2IzSm5aU0F5TGpBZ09pQnBZMjl1Wm05dWRDQTZJREkyTFRndE1qQXhOV2xqYjI1bWIyNTBWbVZ5YzJsdmJpQXhMakFnT3lCMGRHWmhkWFJ2YUdsdWRDQW9kakF1T1RRcElDMXNJRGdnTFhJZ05UQWdMVWNnTWpBd0lDMTRJREUwSUMxM0lDSkhJaUF0WmlBdGMybGpiMjVtYjI1MEFHa0FZd0J2QUc0QVpnQnZBRzRBZEFCTkFHVUFaQUJwQUhVQWJRQkdBRzhBYmdCMEFFWUFid0J5QUdjQVpRQWdBRElBTGdBd0FDQUFPZ0FnQUdrQVl3QnZBRzRBWmdCdkFHNEFkQUFnQURvQUlBQXlBRFlBTFFBNEFDMEFNZ0F3QURFQU5RQnBBR01BYndCdUFHWUFid0J1QUhRQVZnQmxBSElBY3dCcEFHOEFiZ0FnQURFQUxnQXdBQ0FBT3dBZ0FIUUFkQUJtQUdFQWRRQjBBRzhBYUFCcEFHNEFkQUFnQUNnQWRnQXdBQzRBT1FBMEFDa0FJQUF0QUd3QUlBQTRBQ0FBTFFCeUFDQUFOUUF3QUNBQUxRQkhBQ0FBTWdBd0FEQUFJQUF0QUhnQUlBQXhBRFFBSUFBdEFIY0FJQUFpQUVjQUlnQWdBQzBBWmdBZ0FDMEFjd0JwQUdNQWJ3QnVBR1lBYndCdUFIUUFBQUFDQUFBQUFBQUEvNE1BTWdBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBY0FBQUFCQUFJQVd3RUNBUU1CQkFkMWJtbEZOalV3QjNWdWFVVTJOakVIZFc1cFJUWkVSUUFCQUFILy93QVBBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQXlBRElER1AvaEF4ai9iQU1ZLytFREdQOXNzQUFzc0NCZ1ppMndBU3dnWkNDd3dGQ3dCQ1phc0FSRlcxZ2hJeUViaWxnZ3NGQlFXQ0d3UUZrYklMQTRVRmdoc0RoWldTQ3dDa1ZoWkxBb1VGZ2hzQXBGSUxBd1VGZ2hzREJaR3lDd3dGQllJR1lnaW9waElMQUtVRmhnR3lDd0lGQllJYkFLWUJzZ3NEWlFXQ0d3Tm1BYllGbFpXUnV3QUN0WldTT3dBRkJZWlZsWkxiQUNMQ0JGSUxBRUpXRmtJTEFGUTFCWXNBVWpRckFHSTBJYklTRlpzQUZnTGJBRExDTWhJeUVnWkxFRllrSWdzQVlqUXJJS0FBSXFJU0N3QmtNZ2lpQ0tzQUFyc1RBRkpZcFJXR0JRRzJGU1dWZ2pXU0Vnc0VCVFdMQUFLeHNoc0VCWkk3QUFVRmhsV1Myd0JDeXdDQ05Dc0FjalFyQUFJMEt3QUVPd0IwTlJXTEFJUXl1eUFBRUFRMkJDc0JabEhGa3RzQVVzc0FCRElFVWdzQUpGWTdBQlJXSmdSQzJ3Qml5d0FFTWdSU0N3QUNzanNRUUVKV0FnUllvallTQmtJTEFnVUZnaHNBQWJzREJRV0xBZ0c3QkFXVmtqc0FCUVdHVlpzQU1sSTJGRVJDMndCeXl4QlFWRnNBRmhSQzJ3Q0N5d0FXQWdJTEFLUTBxd0FGQllJTEFLSTBKWnNBdERTckFBVWxnZ3NBc2pRbGt0c0Frc0lMZ0VBR0lndUFRQVk0b2pZYkFNUTJBZ2ltQWdzQXdqUWlNdHNBb3NTMVJZc1FjQlJGa2tzQTFsSTNndHNBc3NTMUZZUzFOWXNRY0JSRmtiSVZra3NCTmxJM2d0c0F3c3NRQU5RMVZZc1EwTlE3QUJZVUt3Q1N0WnNBQkRzQUlsUXJJQUFRQkRZRUt4Q2dJbFFyRUxBaVZDc0FFV0l5Q3dBeVZRV0xBQVE3QUVKVUtLaWlDS0kyR3dDQ29oSTdBQllTQ0tJMkd3Q0NvaEc3QUFRN0FDSlVLd0FpVmhzQWdxSVZtd0NrTkhzQXREUjJDd2dHSWdzQUpGWTdBQlJXSmdzUUFBRXlORXNBRkRzQUErc2dFQkFVTmdRaTJ3RFN5eEFBVkZWRmdBc0EwalFpQmdzQUZodFE0T0FRQU1BRUpDaW1DeERBUXJzR3NyR3lKWkxiQU9MTEVBRFNzdHNBOHNzUUVOS3kyd0VDeXhBZzByTGJBUkxMRUREU3N0c0JJc3NRUU5LeTJ3RXl5eEJRMHJMYkFVTExFR0RTc3RzQlVzc1FjTkt5MndGaXl4Q0EwckxiQVhMTEVKRFNzdHNCZ3NzQWNyc1FBRlJWUllBTEFOSTBJZ1lMQUJZYlVPRGdFQURBQkNRb3Bnc1F3RUs3QnJLeHNpV1Myd0dTeXhBQmdyTGJBYUxMRUJHQ3N0c0Jzc3NRSVlLeTJ3SEN5eEF4Z3JMYkFkTExFRUdDc3RzQjRzc1FVWUt5MndIeXl4QmhnckxiQWdMTEVIR0NzdHNDRXNzUWdZS3kyd0lpeXhDUmdyTGJBakxDQmdzQTVnSUVNanNBRmdRN0FDSmJBQ0pWRllJeUE4c0FGZ0k3QVNaUndiSVNGWkxiQWtMTEFqSzdBaktpMndKU3dnSUVjZ0lMQUNSV093QVVWaVlDTmhPQ01naWxWWUlFY2dJTEFDUldPd0FVVmlZQ05oT0JzaFdTMndKaXl4QUFWRlZGZ0FzQUVXc0NVcXNBRVZNQnNpV1Myd0p5eXdCeXV4QUFWRlZGZ0FzQUVXc0NVcXNBRVZNQnNpV1Myd0tDd2dOYkFCWUMyd0tTd0FzQU5GWTdBQlJXS3dBQ3V3QWtWanNBRkZZckFBSzdBQUZyUUFBQUFBQUVRK0l6aXhLQUVWS2kyd0tpd2dQQ0JISUxBQ1JXT3dBVVZpWUxBQVEyRTRMYkFyTEM0WFBDMndMQ3dnUENCSElMQUNSV093QVVWaVlMQUFRMkd3QVVOak9DMndMU3l4QWdBV0pTQXVJRWV3QUNOQ3NBSWxTWXFLUnlOSEkyRWdXR0liSVZtd0FTTkNzaXdCQVJVVUtpMndMaXl3QUJhd0JDV3dCQ1ZISTBjalliQUdSU3RsaWk0aklDQThpamd0c0M4c3NBQVdzQVFsc0FRbElDNUhJMGNqWVNDd0JDTkNzQVpGS3lDd1lGQllJTEJBVVZpekFpQURJQnV6QWlZREdsbENRaU1nc0FsRElJb2pSeU5ISTJFalJtQ3dCRU93Z0dKZ0lMQUFLeUNLaW1FZ3NBSkRZR1Fqc0FORFlXUlFXTEFDUTJFYnNBTkRZRm13QXlXd2dHSmhJeUFnc0FRbUkwWmhPQnNqc0FsRFJyQUNKYkFKUTBjalJ5TmhZQ0N3QkVPd2dHSmdJeUN3QUNzanNBUkRZTEFBSzdBRkpXR3dCU1d3Z0dLd0JDWmhJTEFFSldCa0k3QURKV0JrVUZnaEd5TWhXU01nSUxBRUppTkdZVGhaTGJBd0xMQUFGaUFnSUxBRkppQXVSeU5ISTJFalBEZ3RzREVzc0FBV0lMQUpJMElnSUNCR0kwZXdBQ3NqWVRndHNESXNzQUFXc0FNbHNBSWxSeU5ISTJHd0FGUllMaUE4SXlFYnNBSWxzQUlsUnlOSEkyRWdzQVVsc0FRbFJ5TkhJMkd3QmlXd0JTVkpzQUlsWWJBQlJXTWpJRmhpR3lGWlk3QUJSV0pnSXk0aklDQThpamdqSVZrdHNETXNzQUFXSUxBSlF5QXVSeU5ISTJFZ1lMQWdZR2F3Z0dJaklDQThpamd0c0RRc0l5QXVSckFDSlVaU1dDQThXUzZ4SkFFVUt5MndOU3dqSUM1R3NBSWxSbEJZSUR4WkxyRWtBUlFyTGJBMkxDTWdMa2F3QWlWR1VsZ2dQRmtqSUM1R3NBSWxSbEJZSUR4WkxyRWtBUlFyTGJBM0xMQXVLeU1nTGthd0FpVkdVbGdnUEZrdXNTUUJGQ3N0c0Rnc3NDOHJpaUFnUExBRUkwS0tPQ01nTGthd0FpVkdVbGdnUEZrdXNTUUJGQ3V3QkVNdXNDUXJMYkE1TExBQUZyQUVKYkFFSmlBdVJ5TkhJMkd3QmtVckl5QThJQzRqT0xFa0FSUXJMYkE2TExFSkJDVkNzQUFXc0FRbHNBUWxJQzVISTBjallTQ3dCQ05Dc0FaRkt5Q3dZRkJZSUxCQVVWaXpBaUFESUJ1ekFpWURHbGxDUWlNZ1I3QUVRN0NBWW1BZ3NBQXJJSXFLWVNDd0FrTmdaQ093QTBOaFpGQllzQUpEWVJ1d0EwTmdXYkFESmJDQVltR3dBaVZHWVRnaklEd2pPQnNoSUNCR0kwZXdBQ3NqWVRnaFdiRWtBUlFyTGJBN0xMQXVLeTZ4SkFFVUt5MndQQ3l3THlzaEl5QWdQTEFFSTBJak9MRWtBUlFyc0FSRExyQWtLeTJ3UFN5d0FCVWdSN0FBSTBLeUFBRUJGUlFUTHJBcUtpMndQaXl3QUJVZ1I3QUFJMEt5QUFFQkZSUVRMckFxS2kyd1B5eXhBQUVVRTdBcktpMndRQ3l3TFNvdHNFRXNzQUFXUlNNZ0xpQkdpaU5oT0xFa0FSUXJMYkJDTExBSkkwS3dRU3N0c0VNc3NnQUFPaXN0c0VRc3NnQUJPaXN0c0VVc3NnRUFPaXN0c0VZc3NnRUJPaXN0c0Vjc3NnQUFPeXN0c0Vnc3NnQUJPeXN0c0Vrc3NnRUFPeXN0c0Vvc3NnRUJPeXN0c0Vzc3NnQUFOeXN0c0V3c3NnQUJOeXN0c0Uwc3NnRUFOeXN0c0U0c3NnRUJOeXN0c0U4c3NnQUFPU3N0c0ZBc3NnQUJPU3N0c0ZFc3NnRUFPU3N0c0ZJc3NnRUJPU3N0c0ZNc3NnQUFQQ3N0c0ZRc3NnQUJQQ3N0c0ZVc3NnRUFQQ3N0c0ZZc3NnRUJQQ3N0c0Zjc3NnQUFPQ3N0c0Znc3NnQUJPQ3N0c0Zrc3NnRUFPQ3N0c0Zvc3NnRUJPQ3N0c0Zzc3NEQXJMckVrQVJRckxiQmNMTEF3SzdBMEt5MndYU3l3TUN1d05Tc3RzRjRzc0FBV3NEQXJzRFlyTGJCZkxMQXhLeTZ4SkFFVUt5MndZQ3l3TVN1d05Dc3RzR0Vzc0RFcnNEVXJMYkJpTExBeEs3QTJLeTJ3WXl5d01pc3VzU1FCRkNzdHNHUXNzRElyc0RRckxiQmxMTEF5SzdBMUt5MndaaXl3TWl1d05pc3RzR2Nzc0RNckxyRWtBUlFyTGJCb0xMQXpLN0EwS3kyd2FTeXdNeXV3TlNzdHNHb3NzRE1yc0RZckxiQnJMQ3V3Q0dXd0F5UlFlTEFCRlRBdEFBQkx1QURJVWxpeEFRR09XYmtJQUFnQVl5Q3dBU05FSUxBREkzQ3dEa1VnSUV1NEFBNVJTN0FHVTFwWXNEUWJzQ2haWUdZZ2lsVllzQUlsWWJBQlJXTWpZckFDSTBTekNna0ZCQ3V6Q2dzRkJDdXpEZzhGQkN0WnNnUW9DVVZTUkxNS0RRWUVLN0VHQVVTeEpBR0lVVml3UUloWXNRWURSTEVtQVloUldMZ0VBSWhZc1FZQlJGbFpXVm00QWYrRnNBU05zUVVBUkFBQUFBPT1cXFwiKSBmb3JtYXQoXFxcInRydWV0eXBlXFxcIik7IH1cXG5cXG4uaWNvbmZvbnQge1xcbiAgZm9udC1mYW1pbHk6IGljb25mb250ICFpbXBvcnRhbnQ7XFxuICBmb250LXNpemU6IDE2cHg7XFxuICBmb250LXN0eWxlOiBub3JtYWw7XFxuICAtd2Via2l0LWZvbnQtc21vb3RoaW5nOiBhbnRpYWxpYXNlZDtcXG4gIC13ZWJraXQtdGV4dC1zdHJva2Utd2lkdGg6IDAuMnB4O1xcbiAgLW1vei1vc3gtZm9udC1zbW9vdGhpbmc6IGdyYXlzY2FsZTsgfVxcblxcbltkYXRhLWRwcj1cXFwiMlxcXCJdIC50YWItaGVhZGVyIHtcXG4gIGZvbnQtc2l6ZTogMjhweDsgfVxcblxcbltkYXRhLWRwcj1cXFwiM1xcXCJdIC50YWItaGVhZGVyIHtcXG4gIGZvbnQtc2l6ZTogNDJweDsgfVxcblxcbltkYXRhLWRwcj1cXFwiMlxcXCJdIC50YWJoZWFkZXIgLmhsLWljb24ge1xcbiAgZm9udC1zaXplOiAyOHB4OyB9XFxuXFxuW2RhdGEtZHByPVxcXCIzXFxcIl0gLnRhYmhlYWRlciAuaGwtaWNvbiB7XFxuICBmb250LXNpemU6IDQycHg7IH1cXG5cXG5bZGF0YS1kcHI9XFxcIjJcXFwiXSAudGFiLWhlYWRlciAuZm9sZC10b2dnbGUge1xcbiAgZm9udC1zaXplOiAyOHB4OyB9XFxuXFxuW2RhdGEtZHByPVxcXCIzXFxcIl0gLnRhYi1oZWFkZXIgLmZvbGQtdG9nZ2xlIHtcXG4gIGZvbnQtc2l6ZTogNDJweDsgfVxcblwiXSxcInNvdXJjZVJvb3RcIjpcIndlYnBhY2s6Ly9cIn1dKTtcblxuLy8gZXhwb3J0c1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi9+L3Nhc3MtbG9hZGVyP3NvdXJjZU1hcCEuL3NyYy9zdHlsZXMvdGFiaGVhZGVyLnNjc3NcbiAqKiBtb2R1bGUgaWQgPSA1MFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnJlcXVpcmUoJy4uL3N0eWxlcy9zY3JvbGxlci5zY3NzJylcbnJlcXVpcmUoJ3Njcm9sbGpzJylcblxuLy8gbGliLnNjcm9sbCBldmVudHM6XG4vLyAgLSBzY3JvbGxzdGFydFxuLy8gIC0gc2Nyb2xsaW5nXG4vLyAgLSBwdWxsZG93bmVuZFxuLy8gIC0gcHVsbHVwZW5kXG4vLyAgLSBwdWxsbGVmdGVuZFxuLy8gIC0gcHVsbHJpZ2h0ZW5kXG4vLyAgLSBwdWxsZG93blxuLy8gIC0gcHVsbHVwXG4vLyAgLSBwdWxsbGVmdFxuLy8gIC0gcHVsbHJpZ2h0XG4vLyAgLSBjb250ZW50cmVmcmVzaFxuXG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi9jb21wb25lbnQnKVxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKVxuXG4vLyBhdHRyczpcbi8vICAtIHNjcm9sbC1kaXJlY2l0b246IG5vbmV8dmVydGljYWx8aG9yaXpvbnRhbCAoZGVmYXVsdCBpcyB2ZXJ0aWNhbClcbi8vICAtIHNob3ctc2Nyb2xsYmFyOiB0cnVlfGZhbHNlIChkZWZhdWx0IGlzIHRydWUpXG5mdW5jdGlvbiBTY3JvbGxlciAoZGF0YSwgbm9kZVR5cGUpIHtcbiAgdmFyIGF0dHJzID0gZGF0YS5hdHRyIHx8IHt9XG4gIHRoaXMuaXRlbXMgPSBbXVxuICB0aGlzLnRvdGFsV2lkdGggPSAwXG4gIHRoaXMuc2Nyb2xsRGlyZWN0aW9uID0gYXR0cnMuc2Nyb2xsRGlyZWN0aW9uID09PSAnaG9yaXpvbnRhbCdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPyAnaG9yaXpvbnRhbCdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgOiAndmVydGljYWwnXG4gIHRoaXMuc2hvd1Njcm9sbGJhciA9IGF0dHJzLnNob3dTY3JvbGxiYXIgfHwgdHJ1ZVxuICBDb21wb25lbnQuY2FsbCh0aGlzLCBkYXRhLCBub2RlVHlwZSlcbn1cblxuU2Nyb2xsZXIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShDb21wb25lbnQucHJvdG90eXBlKVxuXG5TY3JvbGxlci5wcm90b3R5cGUuY3JlYXRlID0gZnVuY3Rpb24gKG5vZGVUeXBlKSB7XG4gIHZhciBTY3JvbGwgPSBsaWIuc2Nyb2xsXG4gIHZhciBub2RlID0gQ29tcG9uZW50LnByb3RvdHlwZS5jcmVhdGUuY2FsbCh0aGlzLCBub2RlVHlwZSlcbiAgbm9kZS5jbGFzc0xpc3QuYWRkKCd3ZWV4LWNvbnRhaW5lcicsICdzY3JvbGwtd3JhcCcpXG4gIHRoaXMuc2Nyb2xsRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gIHRoaXMuc2Nyb2xsRWxlbWVudC5jbGFzc0xpc3QuYWRkKFxuICAgICd3ZWV4LWNvbnRhaW5lcicsXG4gICAgJ3Njcm9sbC1lbGVtZW50JyxcbiAgICB0aGlzLnNjcm9sbERpcmVjdGlvblxuICApXG4gIG5vZGUuYXBwZW5kQ2hpbGQodGhpcy5zY3JvbGxFbGVtZW50KVxuICB0aGlzLnNjcm9sbGVyID0gbmV3IFNjcm9sbCh7XG4gICAgc2Nyb2xsRWxlbWVudDogdGhpcy5zY3JvbGxFbGVtZW50LFxuICAgIGRpcmVjdGlvbjogdGhpcy5zY3JvbGxEaXJlY3Rpb24gPT09ICd2ZXJ0aWNhbCcgPyAneScgOiAneCdcbiAgfSlcbiAgdGhpcy5zY3JvbGxlci5pbml0KClcbiAgcmV0dXJuIG5vZGVcbn1cblxuU2Nyb2xsZXIucHJvdG90eXBlLmJpbmRFdmVudHMgPSBmdW5jdGlvbiAoZXZ0cykge1xuICBDb21wb25lbnQucHJvdG90eXBlLmJpbmRFdmVudHMuY2FsbCh0aGlzLCBldnRzKVxuICAvLyB0byBlbmFibGUgbGF6eWxvYWQgZm9yIEltYWdlc1xuICB0aGlzLnNjcm9sbGVyLmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbGluZycsIGZ1bmN0aW9uIChlKSB7XG4gICAgdmFyIHNvID0gZS5zY3JvbGxPYmpcbiAgICB0aGlzLmRpc3BhdGNoRXZlbnQoJ3Njcm9sbCcsIHtcbiAgICAgIG9yaWdpbmFsVHlwZTogJ3Njcm9sbGluZycsXG4gICAgICBzY3JvbGxUb3A6IHNvLmdldFNjcm9sbFRvcCgpLFxuICAgICAgc2Nyb2xsTGVmdDogc28uZ2V0U2Nyb2xsTGVmdCgpXG4gICAgfSwge1xuICAgICAgYnViYmxlczogdHJ1ZVxuICAgIH0pXG4gIH0uYmluZCh0aGlzKSlcbn1cblxuU2Nyb2xsZXIucHJvdG90eXBlLmFwcGVuZENoaWxkID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdmFyIGNoaWxkcmVuID0gdGhpcy5kYXRhLmNoaWxkcmVuXG4gIHZhciBjb21wb25lbnRNYW5hZ2VyID0gdGhpcy5nZXRDb21wb25lbnRNYW5hZ2VyKClcbiAgdmFyIGNoaWxkID0gY29tcG9uZW50TWFuYWdlci5jcmVhdGVFbGVtZW50KGRhdGEpXG4gIHRoaXMuc2Nyb2xsRWxlbWVudC5hcHBlbmRDaGlsZChjaGlsZC5ub2RlKVxuXG4gIHZhciBjaGlsZFdpZHRoID0gY2hpbGQubm9kZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aFxuICB0aGlzLnRvdGFsV2lkdGggKz0gY2hpbGRXaWR0aFxuICAvLyBpZiBkaXJlY3Rpb24gaXMgaG9yaXpvbnRhbCB0aGVuIHRoZSB3aWR0aCBvZiBzY3JvbGxFbGVtZW50XG4gIC8vIHNob3VsZCBiZSBzZXQgbWFudWFsbHkgZHVlIHRvIGZsZXhib3gncyBydWxlIChjaGlsZCBlbGVtZW50c1xuICAvLyB3aWxsIG5vdCBleGNlZWQgYm94J3Mgd2lkdGggYnV0IHRvIHNocmluayB0byBhZGFwdCkuXG4gIGlmICh0aGlzLnNjcm9sbERpcmVjdGlvbiA9PT0gJ2hvcml6b250YWwnKSB7XG4gICAgdGhpcy5zY3JvbGxFbGVtZW50LnN0eWxlLndpZHRoID0gdGhpcy50b3RhbFdpZHRoICsgJ3B4J1xuICB9XG5cbiAgLy8gdXBkYXRlIHRoaXMuZGF0YS5jaGlsZHJlblxuICBpZiAoIWNoaWxkcmVuIHx8ICFjaGlsZHJlbi5sZW5ndGgpIHtcbiAgICB0aGlzLmRhdGEuY2hpbGRyZW4gPSBbZGF0YV1cbiAgfSBlbHNlIHtcbiAgICBjaGlsZHJlbi5wdXNoKGRhdGEpXG4gIH1cblxuICB0aGlzLml0ZW1zLnB1c2goY2hpbGQpXG4gIHJldHVybiBjaGlsZFxufVxuXG5TY3JvbGxlci5wcm90b3R5cGUuaW5zZXJ0QmVmb3JlID0gZnVuY3Rpb24gKGNoaWxkLCBiZWZvcmUpIHtcbiAgdmFyIGNoaWxkcmVuID0gdGhpcy5kYXRhLmNoaWxkcmVuXG4gIHZhciBpID0gMFxuICB2YXIgaXNBcHBlbmQgPSBmYWxzZVxuXG4gIC8vIHVwZGF0ZSB0aGlzLmRhdGEuY2hpbGRyZW5cbiAgaWYgKCFjaGlsZHJlbiB8fCAhY2hpbGRyZW4ubGVuZ3RoIHx8ICFiZWZvcmUpIHtcbiAgICBpc0FwcGVuZCA9IHRydWVcbiAgfSBlbHNlIHtcbiAgICBmb3IgKHZhciBsID0gY2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICBpZiAoY2hpbGRyZW5baV0ucmVmID09PSBjaGlsZC5kYXRhLnJlZikge1xuICAgICAgICBicmVha1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoaSA9PT0gbCkge1xuICAgICAgaXNBcHBlbmQgPSB0cnVlXG4gICAgfVxuICB9XG5cbiAgaWYgKGlzQXBwZW5kKSB7XG4gICAgdGhpcy5zY3JvbGxFbGVtZW50LmFwcGVuZENoaWxkKGNoaWxkLm5vZGUpXG4gICAgY2hpbGRyZW4ucHVzaChjaGlsZC5kYXRhKVxuICAgIHRoaXMuaXRlbXMucHVzaChjaGlsZClcbiAgfSBlbHNlIHtcbiAgICB0aGlzLnNjcm9sbEVsZW1lbnQuaW5zZXJ0QmVmb3JlKGNoaWxkLm5vZGUsIGJlZm9yZS5ub2RlKVxuICAgIGNoaWxkcmVuLnNwbGljZShpLCAwLCBjaGlsZC5kYXRhKVxuICAgIHRoaXMuaXRlbXMuc3BsaWNlKGksIDAsIGNoaWxkKVxuICB9XG59XG5cblNjcm9sbGVyLnByb3RvdHlwZS5yZW1vdmVDaGlsZCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGNoaWxkcmVuID0gdGhpcy5kYXRhLmNoaWxkcmVuXG4gIC8vIHJlbW92ZSBmcm9tIHRoaXMuZGF0YS5jaGlsZHJlblxuICB2YXIgaSA9IDBcbiAgdmFyIGNvbXBvbmVudE1hbmFnZXIgPSB0aGlzLmdldENvbXBvbmVudE1hbmFnZXIoKVxuICBpZiAoY2hpbGRyZW4gJiYgY2hpbGRyZW4ubGVuZ3RoKSB7XG4gICAgZm9yICh2YXIgbCA9IGNoaWxkcmVuLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgaWYgKGNoaWxkcmVuW2ldLnJlZiA9PT0gY2hpbGQuZGF0YS5yZWYpIHtcbiAgICAgICAgYnJlYWtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGkgPCBsKSB7XG4gICAgICBjaGlsZHJlbi5zcGxpY2UoaSwgMSlcbiAgICAgIHRoaXMuaXRlbXMuc3BsaWNlKGksIDEpXG4gICAgfVxuICB9XG4gIC8vIHJlbW92ZSBmcm9tIGNvbXBvbmVudE1hcCByZWN1cnNpdmVseVxuICBjb21wb25lbnRNYW5hZ2VyLnJlbW92ZUVsZW1lbnRCeVJlZihjaGlsZC5kYXRhLnJlZilcbiAgdGhpcy5zY3JvbGxFbGVtZW50LnJlbW92ZUNoaWxkKGNoaWxkLm5vZGUpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gU2Nyb2xsZXJcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvY29tcG9uZW50cy9zY3JvbGxlci5qc1xuICoqIG1vZHVsZSBpZCA9IDUxXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvLyBzdHlsZS1sb2FkZXI6IEFkZHMgc29tZSBjc3MgdG8gdGhlIERPTSBieSBhZGRpbmcgYSA8c3R5bGU+IHRhZ1xuXG4vLyBsb2FkIHRoZSBzdHlsZXNcbnZhciBjb250ZW50ID0gcmVxdWlyZShcIiEhLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi9ub2RlX21vZHVsZXMvc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vc2Nyb2xsZXIuc2Nzc1wiKTtcbmlmKHR5cGVvZiBjb250ZW50ID09PSAnc3RyaW5nJykgY29udGVudCA9IFtbbW9kdWxlLmlkLCBjb250ZW50LCAnJ11dO1xuLy8gYWRkIHRoZSBzdHlsZXMgdG8gdGhlIERPTVxudmFyIHVwZGF0ZSA9IHJlcXVpcmUoXCIhLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2FkZFN0eWxlcy5qc1wiKShjb250ZW50LCB7fSk7XG5pZihjb250ZW50LmxvY2FscykgbW9kdWxlLmV4cG9ydHMgPSBjb250ZW50LmxvY2Fscztcbi8vIEhvdCBNb2R1bGUgUmVwbGFjZW1lbnRcbmlmKG1vZHVsZS5ob3QpIHtcblx0Ly8gV2hlbiB0aGUgc3R5bGVzIGNoYW5nZSwgdXBkYXRlIHRoZSA8c3R5bGU+IHRhZ3Ncblx0aWYoIWNvbnRlbnQubG9jYWxzKSB7XG5cdFx0bW9kdWxlLmhvdC5hY2NlcHQoXCIhIS4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vbm9kZV9tb2R1bGVzL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL3Njcm9sbGVyLnNjc3NcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbmV3Q29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vbm9kZV9tb2R1bGVzL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL3Njcm9sbGVyLnNjc3NcIik7XG5cdFx0XHRpZih0eXBlb2YgbmV3Q29udGVudCA9PT0gJ3N0cmluZycpIG5ld0NvbnRlbnQgPSBbW21vZHVsZS5pZCwgbmV3Q29udGVudCwgJyddXTtcblx0XHRcdHVwZGF0ZShuZXdDb250ZW50KTtcblx0XHR9KTtcblx0fVxuXHQvLyBXaGVuIHRoZSBtb2R1bGUgaXMgZGlzcG9zZWQsIHJlbW92ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdG1vZHVsZS5ob3QuZGlzcG9zZShmdW5jdGlvbigpIHsgdXBkYXRlKCk7IH0pO1xufVxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvc3R5bGVzL3Njcm9sbGVyLnNjc3NcbiAqKiBtb2R1bGUgaWQgPSA1MlxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvbGliL2Nzcy1iYXNlLmpzXCIpKCk7XG4vLyBpbXBvcnRzXG5cblxuLy8gbW9kdWxlXG5leHBvcnRzLnB1c2goW21vZHVsZS5pZCwgXCIuc2Nyb2xsLXdyYXAge1xcbiAgZGlzcGxheTogYmxvY2s7XFxuICBvdmVyZmxvdzogaGlkZGVuOyB9XFxuXFxuLnNjcm9sbC1lbGVtZW50Lmhvcml6b250YWwge1xcbiAgLXdlYmtpdC1ib3gtb3JpZW50OiBob3Jpem9udGFsO1xcbiAgLXdlYmtpdC1mbGV4LWRpcmVjdGlvbjogcm93O1xcbiAgZmxleC1kaXJlY3Rpb246IHJvdzsgfVxcblxcbi5zY3JvbGwtZWxlbWVudC52ZXJ0aWNhbCB7XFxuICAtd2Via2l0LWJveC1vcmllbnQ6IHZlcnRpY2FsO1xcbiAgLXdlYmtpdC1mbGV4LWRpcmVjdGlvbjogY29sdW1uO1xcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjsgfVxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi9zcmMvc3JjL3N0eWxlcy9zY3JvbGxlci5zY3NzXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCJBQUFBO0VBQ0MsZUFBZTtFQUNmLGlCQUFpQixFQUNqQjs7QUFFRDtFQUVJLCtCQUErQjtFQUMvQiw0QkFBNEI7RUFDNUIsb0JBQW9CLEVBQ3JCOztBQUxIO0VBT0ksNkJBQTZCO0VBQzdCLCtCQUErQjtFQUMvQix1QkFBdUIsRUFDeEJcIixcImZpbGVcIjpcInNjcm9sbGVyLnNjc3NcIixcInNvdXJjZXNDb250ZW50XCI6W1wiLnNjcm9sbC13cmFwIHtcXG5cXHRkaXNwbGF5OiBibG9jaztcXG5cXHRvdmVyZmxvdzogaGlkZGVuO1xcbn1cXG5cXG4uc2Nyb2xsLWVsZW1lbnQge1xcbiAgJi5ob3Jpem9udGFsIHtcXG4gICAgLXdlYmtpdC1ib3gtb3JpZW50OiBob3Jpem9udGFsO1xcbiAgICAtd2Via2l0LWZsZXgtZGlyZWN0aW9uOiByb3c7XFxuICAgIGZsZXgtZGlyZWN0aW9uOiByb3c7XFxuICB9XFxuICAmLnZlcnRpY2FsIHtcXG4gICAgLXdlYmtpdC1ib3gtb3JpZW50OiB2ZXJ0aWNhbDtcXG4gICAgLXdlYmtpdC1mbGV4LWRpcmVjdGlvbjogY29sdW1uO1xcbiAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xcbiAgfVxcbn1cIl0sXCJzb3VyY2VSb290XCI6XCJ3ZWJwYWNrOi8vXCJ9XSk7XG5cbi8vIGV4cG9ydHNcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2Nzcy1sb2FkZXI/c291cmNlTWFwIS4vfi9zYXNzLWxvYWRlcj9zb3VyY2VNYXAhLi9zcmMvc3R5bGVzL3Njcm9sbGVyLnNjc3NcbiAqKiBtb2R1bGUgaWQgPSA1M1xuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnZhciBBdG9taWMgPSByZXF1aXJlKCcuL2F0b21pYycpXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpXG5cbi8vIGF0dHJzOlxuLy8gICAtIHR5cGU6IHRleHR8cGFzc3dvcmR8dGVsfGVtYWlsfHVybFxuLy8gICAtIHZhbHVlXG4vLyAgIC0gcGxhY2Vob2xkZXJcbi8vICAgLSBkaXNhYmxlZFxuLy8gICAtIGF1dG9mb2N1c1xuZnVuY3Rpb24gSW5wdXQgKGRhdGEpIHtcbiAgdmFyIGF0dHJzID0gZGF0YS5hdHRyIHx8IHt9XG4gIHRoaXMudHlwZSA9IGF0dHJzLnR5cGUgfHwgJ3RleHQnXG4gIHRoaXMudmFsdWUgPSBhdHRycy52YWx1ZVxuICB0aGlzLnBsYWNlaG9sZGVyID0gYXR0cnMucGxhY2Vob2xkZXJcbiAgdGhpcy5hdXRvZm9jdXMgPSBhdHRycy5hdXRvZm9jdXMgJiYgKGF0dHJzLmF1dG9mb2N1cyAhPT0gJ2ZhbHNlJylcbiAgICAgICAgICAgICAgICAgICAgPyB0cnVlXG4gICAgICAgICAgICAgICAgICAgIDogZmFsc2VcbiAgQXRvbWljLmNhbGwodGhpcywgZGF0YSlcbn1cblxuSW5wdXQucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShBdG9taWMucHJvdG90eXBlKVxuXG5JbnB1dC5wcm90b3R5cGUuY3JlYXRlID0gZnVuY3Rpb24gKCkge1xuICB2YXIgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lucHV0JylcbiAgdmFyIHV1aWQgPSBNYXRoLmZsb29yKDEwMDAwMDAwMDAwMDAwICogTWF0aC5yYW5kb20oKSkgKyBEYXRlLm5vdygpXG4gIHRoaXMuY2xhc3NOYW1lID0gJ3dlZXgtaXB0LScgKyB1dWlkXG4gIHRoaXMuc3R5bGVJZCA9ICd3ZWV4LXN0eWxlLScgKyB1dWlkXG4gIG5vZGUuY2xhc3NMaXN0LmFkZCh0aGlzLmNsYXNzTmFtZSlcbiAgbm9kZS5zZXRBdHRyaWJ1dGUoJ3R5cGUnLCB0aGlzLnR5cGUpXG4gIG5vZGUudHlwZSA9IHRoaXMudHlwZVxuICAvLyBGb3IgdGhlIGNvbnNpc3RlbmN5IG9mIGlucHV0IGNvbXBvbmVudCdzIHdpZHRoLlxuICAvLyBUaGUgZGF0ZSBhbmQgdGltZSB0eXBlIG9mIGlucHV0IHdpbGwgaGF2ZSBhIGJpZ2dlciB3aWR0aFxuICAvLyB3aGVuIHRoZSAnYm94LXNpemluZycgaXMgbm90IHNldCB0byAnYm9yZGVyLWJveCdcbiAgbm9kZS5jbGFzc0xpc3QuYWRkKCd3ZWV4LWVsZW1lbnQnKVxuICB0aGlzLnZhbHVlICYmIChub2RlLnZhbHVlID0gdGhpcy52YWx1ZSlcbiAgdGhpcy5wbGFjZWhvbGRlciAmJiAobm9kZS5wbGFjZWhvbGRlciA9IHRoaXMucGxhY2Vob2xkZXIpXG4gIHJldHVybiBub2RlXG59XG5cbklucHV0LnByb3RvdHlwZS51cGRhdGVTdHlsZSA9IGZ1bmN0aW9uIChzdHlsZSkge1xuICBBdG9taWMucHJvdG90eXBlLnVwZGF0ZVN0eWxlLmNhbGwodGhpcywgc3R5bGUpXG4gIGlmIChzdHlsZSAmJiBzdHlsZS5wbGFjZWhvbGRlckNvbG9yKSB7XG4gICAgdGhpcy5wbGFjZWhvbGRlckNvbG9yID0gc3R5bGUucGxhY2Vob2xkZXJDb2xvclxuICAgIHRoaXMuc2V0UGxhY2Vob2xkZXJDb2xvcigpXG4gIH1cbn1cblxuSW5wdXQucHJvdG90eXBlLmF0dHIgPSB7XG4gIGRpc2FibGVkOiBmdW5jdGlvbiAodmFsKSB7XG4gICAgdGhpcy5ub2RlLmRpc2FibGVkID0gdmFsICYmIHZhbCAhPT0gJ2ZhbHNlJ1xuICAgICAgICAgICAgICAgICAgICA/IHRydWVcbiAgICAgICAgICAgICAgICAgICAgOiBmYWxzZVxuICB9XG59XG5cbklucHV0LnByb3RvdHlwZS5zZXRQbGFjZWhvbGRlckNvbG9yID0gZnVuY3Rpb24gKCkge1xuICBpZiAoIXRoaXMucGxhY2Vob2xkZXJDb2xvcikge1xuICAgIHJldHVyblxuICB9XG4gIHZhciB2ZW5kb3JzID0gW1xuICAgICc6Oi13ZWJraXQtaW5wdXQtcGxhY2Vob2xkZXInLFxuICAgICc6LW1vei1wbGFjZWhvbGRlcicsXG4gICAgJzo6LW1vei1wbGFjZWhvbGRlcicsXG4gICAgJzotbXMtaW5wdXQtcGxhY2Vob2xkZXInLFxuICAgICc6cGxhY2Vob2xkZXItc2hvd24nXG4gIF1cbiAgdmFyIGNzcyA9ICcnXG4gIHZhciBjc3NSdWxlID0gJ2NvbG9yOiAnICsgdGhpcy5wbGFjZWhvbGRlckNvbG9yICsgJzsnXG4gIGZvciAodmFyIGkgPSAwLCBsID0gdmVuZG9ycy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBjc3MgKz0gJy4nICsgdGhpcy5jbGFzc05hbWUgKyB2ZW5kb3JzW2ldICsgJ3snXG4gICAgICAgICAgICsgY3NzUnVsZSArICd9J1xuICB9XG4gIHV0aWxzLmFwcGVuZFN0eWxlKGNzcywgdGhpcy5zdHlsZUlkLCB0cnVlKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IElucHV0XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL2NvbXBvbmVudHMvaW5wdXQuanNcbiAqKiBtb2R1bGUgaWQgPSA1NFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnZhciBBdG9taWMgPSByZXF1aXJlKCcuL2NvbXBvbmVudCcpXG52YXIgc2VuZGVyID0gcmVxdWlyZSgnLi4vYnJpZGdlL3NlbmRlcicpXG5cbi8vIGF0dHJzOlxuLy8gICAtIG9wdGlvbnM6IHRoZSBvcHRpb25zIHRvIGJlIGxpc3RlZCwgYXMgYSBhcnJheSBvZiBzdHJpbmdzLlxuLy8gICAtIHNlbGVjdGVkSW5kZXg6IHRoZSBzZWxlY3RlZCBvcHRpb25zJyBpbmRleCBudW1iZXIuXG4vLyAgIC0gZGlzYWJsZWRcbmZ1bmN0aW9uIFNlbGVjdCAoZGF0YSkge1xuICB2YXIgYXR0cnMgPSBkYXRhLmF0dHIgfHwge31cbiAgdGhpcy5vcHRpb25zID0gW11cbiAgdGhpcy5zZWxlY3RlZEluZGV4ID0gMFxuICBBdG9taWMuY2FsbCh0aGlzLCBkYXRhKVxufVxuXG5TZWxlY3QucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShBdG9taWMucHJvdG90eXBlKVxuXG5TZWxlY3QucHJvdG90eXBlLmNyZWF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIG5vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzZWxlY3QnKVxuICB2YXIgdXVpZCA9IE1hdGguZmxvb3IoMTAwMDAwMDAwMDAwMDAgKiBNYXRoLnJhbmRvbSgpKSArIERhdGUubm93KClcbiAgdGhpcy5jbGFzc05hbWUgPSAnd2VleC1zbGN0LScgKyB1dWlkXG4gIHRoaXMuc3R5bGVJZCA9ICd3ZWV4LXN0eWxlLScgKyB1dWlkXG4gIG5vZGUuY2xhc3NMaXN0LmFkZCh0aGlzLmNsYXNzTmFtZSlcbiAgLy8gRm9yIHRoZSBjb25zaXN0ZW5jeSBvZiBpbnB1dCBjb21wb25lbnQncyB3aWR0aC5cbiAgLy8gVGhlIGRhdGUgYW5kIHRpbWUgdHlwZSBvZiBpbnB1dCB3aWxsIGhhdmUgYSBiaWdnZXIgd2lkdGhcbiAgLy8gd2hlbiB0aGUgJ2JveC1zaXppbmcnIGlzIG5vdCBzZXQgdG8gJ2JvcmRlci1ib3gnXG4gIG5vZGUuc3R5bGVbJ2JveC1zaXppbmcnXSA9ICdib3JkZXItYm94J1xuICByZXR1cm4gbm9kZVxufVxuXG5TZWxlY3QucHJvdG90eXBlLmF0dHIgPSB7XG4gIGRpc2FibGVkOiBmdW5jdGlvbiAodmFsKSB7XG4gICAgdGhpcy5ub2RlLmRpc2FibGVkID0gdmFsICYmIHZhbCAhPT0gJ2ZhbHNlJ1xuICAgICAgICAgICAgICAgICAgICA/IHRydWVcbiAgICAgICAgICAgICAgICAgICAgOiBmYWxzZVxuICB9LFxuICBvcHRpb25zOiBmdW5jdGlvbiAodmFsKSB7XG4gICAgaWYgKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWwpICE9PSAnW29iamVjdCBBcnJheV0nKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgdGhpcy5vcHRpb25zID0gdmFsXG4gICAgdGhpcy5ub2RlLmlubmVySFRNTCA9ICcnXG4gICAgdGhpcy5jcmVhdGVPcHRpb25zKHZhbClcbiAgfSxcbiAgc2VsZWN0ZWRJbmRleDogZnVuY3Rpb24gKHZhbCkge1xuICAgIHZhbCA9IHBhcnNlSW50KHZhbClcbiAgICBpZiAodHlwZW9mIHZhbCAhPT0gJ251bWJlcicgfHwgdmFsICE9PSB2YWwgfHwgdmFsID49IHRoaXMub3B0aW9ucy5sZW5ndGgpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICB0aGlzLm5vZGUudmFsdWUgPSB0aGlzLm9wdGlvbnNbdmFsXVxuICB9XG59XG5cblNlbGVjdC5wcm90b3R5cGUuYmluZEV2ZW50cyA9IGZ1bmN0aW9uIChldnRzKSB7XG4gIHZhciBpc0xpc3RlblRvQ2hhbmdlID0gZmFsc2VcbiAgQXRvbWljLnByb3RvdHlwZS5iaW5kRXZlbnRzLmNhbGwoXG4gICAgICB0aGlzLFxuICAgICAgZXZ0cy5maWx0ZXIoZnVuY3Rpb24gKHZhbCkge1xuICAgICAgICB2YXIgcGFzcyA9IHZhbCAhPT0gJ2NoYW5nZSdcbiAgICAgICAgIXBhc3MgJiYgKGlzTGlzdGVuVG9DaGFuZ2UgPSB0cnVlKVxuICAgICAgICByZXR1cm4gcGFzc1xuICAgICAgfSkpXG4gIGlmIChpc0xpc3RlblRvQ2hhbmdlKSB7XG4gICAgdGhpcy5ub2RlLmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIGZ1bmN0aW9uIChlKSB7XG4gICAgICBlLmluZGV4ID0gdGhpcy5vcHRpb25zLmluZGV4T2YodGhpcy5ub2RlLnZhbHVlKVxuICAgICAgc2VuZGVyLmZpcmVFdmVudCh0aGlzLmRhdGEucmVmLCAnY2hhbmdlJywgZSlcbiAgICB9LmJpbmQodGhpcykpXG4gIH1cbn1cblxuU2VsZWN0LnByb3RvdHlwZS5jcmVhdGVPcHRpb25zID0gZnVuY3Rpb24gKG9wdHMpIHtcbiAgdmFyIG9wdERvYyA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKVxuICB2YXIgb3B0XG4gIGZvciAodmFyIGkgPSAwLCBsID0gb3B0cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBvcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdvcHRpb24nKVxuICAgIG9wdC5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShvcHRzW2ldKSlcbiAgICBvcHREb2MuYXBwZW5kQ2hpbGQob3B0KVxuICB9XG4gIHRoaXMubm9kZS5hcHBlbmRDaGlsZChvcHREb2MpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gU2VsZWN0XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL2NvbXBvbmVudHMvc2VsZWN0LmpzXG4gKiogbW9kdWxlIGlkID0gNTVcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIid1c2Ugc3RyaWN0J1xuXG52YXIgQXRvbWljID0gcmVxdWlyZSgnLi9hdG9taWMnKVxuXG4vLyBhdHRyczpcbi8vICAgLSB2YWx1ZVxuLy8gICAtIGRpc2FibGVkXG5mdW5jdGlvbiBEYXRlcGlja2VyIChkYXRhKSB7XG4gIEF0b21pYy5jYWxsKHRoaXMsIGRhdGEpXG59XG5cbkRhdGVwaWNrZXIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShBdG9taWMucHJvdG90eXBlKVxuXG5EYXRlcGlja2VyLnByb3RvdHlwZS5jcmVhdGUgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBub2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW5wdXQnKVxuICB2YXIgdXVpZCA9IE1hdGguZmxvb3IoMTAwMDAwMDAwMDAwMDAgKiBNYXRoLnJhbmRvbSgpKSArIERhdGUubm93KClcbiAgdGhpcy5jbGFzc05hbWUgPSAnd2VleC1pcHQtJyArIHV1aWRcbiAgdGhpcy5zdHlsZUlkID0gJ3dlZXgtc3R5bGUtJyArIHV1aWRcbiAgbm9kZS5jbGFzc0xpc3QuYWRkKHRoaXMuY2xhc3NOYW1lKVxuICBub2RlLnNldEF0dHJpYnV0ZSgndHlwZScsICdkYXRlJylcbiAgbm9kZS50eXBlID0gJ2RhdGUnXG4gIC8vIEZvciB0aGUgY29uc2lzdGVuY3kgb2YgaW5wdXQgY29tcG9uZW50J3Mgd2lkdGguXG4gIC8vIFRoZSBkYXRlIGFuZCB0aW1lIHR5cGUgb2YgaW5wdXQgd2lsbCBoYXZlIGEgYmlnZ2VyIHdpZHRoXG4gIC8vIHdoZW4gdGhlICdib3gtc2l6aW5nJyBpcyBub3Qgc2V0IHRvICdib3JkZXItYm94J1xuICBub2RlLmNsYXNzTGlzdC5hZGQoJ3dlZXgtZWxlbWVudCcpXG4gIHJldHVybiBub2RlXG59XG5cbkRhdGVwaWNrZXIucHJvdG90eXBlLmF0dHIgPSB7XG4gIGRpc2FibGVkOiBmdW5jdGlvbiAodmFsKSB7XG4gICAgdGhpcy5ub2RlLmRpc2FibGVkID0gdmFsICYmIHZhbCAhPT0gJ2ZhbHNlJ1xuICAgICAgICAgICAgICAgICAgICA/IHRydWVcbiAgICAgICAgICAgICAgICAgICAgOiBmYWxzZVxuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gRGF0ZXBpY2tlclxuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL3NyYy9jb21wb25lbnRzL2RhdGVwaWNrZXIuanNcbiAqKiBtb2R1bGUgaWQgPSA1NlxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnZhciBBdG9taWMgPSByZXF1aXJlKCcuL2F0b21pYycpXG5cbi8vIGF0dHJzOlxuLy8gICAtIHZhbHVlXG4vLyAgIC0gZGlzYWJsZWRcbmZ1bmN0aW9uIFRpbWVwaWNrZXIgKGRhdGEpIHtcbiAgQXRvbWljLmNhbGwodGhpcywgZGF0YSlcbn1cblxuVGltZXBpY2tlci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEF0b21pYy5wcm90b3R5cGUpXG5cblRpbWVwaWNrZXIucHJvdG90eXBlLmNyZWF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIG5vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbnB1dCcpXG4gIHZhciB1dWlkID0gTWF0aC5mbG9vcigxMDAwMDAwMDAwMDAwMCAqIE1hdGgucmFuZG9tKCkpICsgRGF0ZS5ub3coKVxuICB0aGlzLmNsYXNzTmFtZSA9ICd3ZWV4LWlwdC0nICsgdXVpZFxuICB0aGlzLnN0eWxlSWQgPSAnd2VleC1zdHlsZS0nICsgdXVpZFxuICBub2RlLmNsYXNzTGlzdC5hZGQodGhpcy5jbGFzc05hbWUpXG4gIG5vZGUuc2V0QXR0cmlidXRlKCd0eXBlJywgJ3RpbWUnKVxuICBub2RlLnR5cGUgPSAndGltZSdcbiAgLy8gRm9yIHRoZSBjb25zaXN0ZW5jeSBvZiBpbnB1dCBjb21wb25lbnQncyB3aWR0aC5cbiAgLy8gVGhlIGRhdGUgYW5kIHRpbWUgdHlwZSBvZiBpbnB1dCB3aWxsIGhhdmUgYSBiaWdnZXIgd2lkdGhcbiAgLy8gd2hlbiB0aGUgJ2JveC1zaXppbmcnIGlzIG5vdCBzZXQgdG8gJ2JvcmRlci1ib3gnXG4gIG5vZGUuY2xhc3NMaXN0LmFkZCgnd2VleC1lbGVtZW50JylcbiAgcmV0dXJuIG5vZGVcbn1cblxuVGltZXBpY2tlci5wcm90b3R5cGUuYXR0ciA9IHtcbiAgZGlzYWJsZWQ6IGZ1bmN0aW9uICh2YWwpIHtcbiAgICB0aGlzLm5vZGUuZGlzYWJsZWQgPSB2YWwgJiYgdmFsICE9PSAnZmFsc2UnXG4gICAgICAgICAgICAgICAgICAgID8gdHJ1ZVxuICAgICAgICAgICAgICAgICAgICA6IGZhbHNlXG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBUaW1lcGlja2VyXG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL2NvbXBvbmVudHMvdGltZXBpY2tlci5qc1xuICoqIG1vZHVsZSBpZCA9IDU3XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIndXNlIHN0cmljdCdcblxudmFyIEF0b21pYyA9IHJlcXVpcmUoJy4vYXRvbWljJylcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJylcbnJlcXVpcmUoJy4uL3N0eWxlcy92aWRlby5zY3NzJylcblxuLy8gYXR0cnM6XG4vLyAgIC0gYXV0b1BsYXk6IHRydWUgfCBmYWxzZSAoZGVmYXVsdDogZmFsc2UpXG4vLyAgIC0gcGxheVN0YXR1czogcGxheSB8IHBhdXNlIHwgc3RvcFxuLy8gICAtIHNyYzoge3N0cmluZ31cbi8vICAgLSBwb3N0ZXI6IHtzdHJpbmd9XG4vLyAgIC0gbG9vcDogdHJ1ZSB8IGZhbHNlIChkZWZhdWx0OiBmYWxzZSlcbi8vICAgLSBtdXRlZDogdHJ1ZSB8IGZhbHNlIChkZWZhdWx0OiBmYWxzZSlcbi8vIGV2ZW50czpcbi8vICAgLSBzdGFydFxuLy8gICAtIHBhdXNlXG4vLyAgIC0gZmluaXNoXG4vLyAgIC0gZmFpbFxuZnVuY3Rpb24gVmlkZW8gKGRhdGEpIHtcbiAgdmFyIGF1dG9QbGF5ID0gZGF0YS5hdHRyLmF1dG9QbGF5XG4gIHZhciBwbGF5U3RhdHVzID0gZGF0YS5hdHRyLnBsYXlTdGF0dXNcbiAgdGhpcy5hdXRvUGxheSA9IGF1dG9QbGF5ID09PSB0cnVlIHx8IGF1dG9QbGF5ID09PSAndHJ1ZSdcbiAgaWYgKHBsYXlTdGF0dXMgIT09ICdwbGF5J1xuICAgICAgJiYgcGxheVN0YXR1cyAhPT0gJ3N0b3AnXG4gICAgICAmJiBwbGF5U3RhdHVzICE9PSAncGF1c2UnKSB7XG4gICAgdGhpcy5wbGF5U3RhdHVzID0gJ3BhdXNlJ1xuICB9IGVsc2Uge1xuICAgIHRoaXMucGxheVN0YXR1cyA9IHBsYXlTdGF0dXNcbiAgfVxuICBBdG9taWMuY2FsbCh0aGlzLCBkYXRhKVxufVxuXG5WaWRlby5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEF0b21pYy5wcm90b3R5cGUpXG5cblZpZGVvLnByb3RvdHlwZS5hdHRyID0ge1xuICBwbGF5U3RhdHVzOiBmdW5jdGlvbiAodmFsKSB7XG4gICAgaWYgKHZhbCAhPT0gJ3BsYXknICYmIHZhbCAhPT0gJ3N0b3AnICYmIHZhbCAhPT0gJ3BhdXNlJykge1xuICAgICAgdmFsID0gJ3BhdXNlJ1xuICAgIH1cbiAgICBpZiAodGhpcy5wbGF5U3RhdHVzID09PSB2YWwpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICB0aGlzLnBsYXlTdGF0dXMgPSB2YWxcbiAgICB0aGlzLm5vZGUuc2V0QXR0cmlidXRlKCdwbGF5LXN0YXR1cycsIHZhbClcbiAgICB0aGlzW3RoaXMucGxheVN0YXR1c10oKVxuICB9LFxuICBhdXRvUGxheTogZnVuY3Rpb24gKHZhbCkge1xuICAgIC8vIERPIE5PVEhJTkdcbiAgfVxufVxuXG5WaWRlby5wcm90b3R5cGUuY3JlYXRlID0gZnVuY3Rpb24gKCkge1xuICB2YXIgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3ZpZGVvJylcbiAgbm9kZS5jbGFzc0xpc3QuYWRkKCd3ZWV4LXZpZGVvJywgJ3dlZXgtZWxlbWVudCcpXG4gIG5vZGUuY29udHJvbHMgPSB0cnVlXG4gIG5vZGUuYXV0b3BsYXkgPSB0aGlzLmF1dG9QbGF5XG4gIG5vZGUuc2V0QXR0cmlidXRlKCdwbGF5LXN0YXR1cycsIHRoaXMucGxheVN0YXR1cylcbiAgdGhpcy5ub2RlID0gbm9kZVxuICBpZiAodGhpcy5hdXRvUGxheSAmJiB0aGlzLnBsYXlTdGF0dXMgPT09ICdwbGF5Jykge1xuICAgIHRoaXMucGxheSgpXG4gIH1cbiAgcmV0dXJuIG5vZGVcbn1cblxuVmlkZW8ucHJvdG90eXBlLmJpbmRFdmVudHMgPSBmdW5jdGlvbiAoZXZ0cykge1xuICBBdG9taWMucHJvdG90eXBlLmJpbmRFdmVudHMuY2FsbCh0aGlzLCBldnRzKVxuXG4gIC8vIGNvbnZlcnQgdzNjLXZpZGVvIGV2ZW50cyB0byB3ZWV4LXZpZGVvIGV2ZW50cy5cbiAgdmFyIGV2dHNNYXAgPSB7XG4gICAgc3RhcnQ6ICdwbGF5JyxcbiAgICBmaW5pc2g6ICdlbmRlZCcsXG4gICAgZmFpbDogJ2Vycm9yJ1xuICB9XG4gIGZvciAodmFyIGV2dE5hbWUgaW4gZXZ0c01hcCkge1xuICAgIHRoaXMubm9kZS5hZGRFdmVudExpc3RlbmVyKGV2dHNNYXBbZXZ0TmFtZV0sIGZ1bmN0aW9uICh0eXBlLCBlKSB7XG4gICAgICB0aGlzLmRpc3BhdGNoRXZlbnQodHlwZSwgZS5kYXRhKVxuICAgIH0uYmluZCh0aGlzLCBldnROYW1lKSlcbiAgfVxufVxuXG5WaWRlby5wcm90b3R5cGUucGxheSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHNyYyA9IHRoaXMubm9kZS5nZXRBdHRyaWJ1dGUoJ3NyYycpXG4gIGlmICghc3JjKSB7XG4gICAgc3JjID0gdGhpcy5ub2RlLmdldEF0dHJpYnV0ZSgnZGF0YS1zcmMnKVxuICAgIHNyYyAmJiB0aGlzLm5vZGUuc2V0QXR0cmlidXRlKCdzcmMnLCBzcmMpXG4gIH1cbiAgdGhpcy5ub2RlLnBsYXkoKVxufVxuXG5WaWRlby5wcm90b3R5cGUucGF1c2UgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMubm9kZS5wYXVzZSgpXG59XG5cblZpZGVvLnByb3RvdHlwZS5zdG9wID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLm5vZGUucGF1c2UoKVxuICB0aGlzLm5vZGUuYXV0b3BsYXkgPSBmYWxzZVxuICB0aGlzLm5vZGUuc2V0QXR0cmlidXRlKCdkYXRhLXNyYycsIHRoaXMubm9kZS5zcmMpXG4gIHRoaXMubm9kZS5zcmMgPSAnJ1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFZpZGVvXG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL2NvbXBvbmVudHMvdmlkZW8uanNcbiAqKiBtb2R1bGUgaWQgPSA1OFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLy8gc3R5bGUtbG9hZGVyOiBBZGRzIHNvbWUgY3NzIHRvIHRoZSBET00gYnkgYWRkaW5nIGEgPHN0eWxlPiB0YWdcblxuLy8gbG9hZCB0aGUgc3R5bGVzXG52YXIgY29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vbm9kZV9tb2R1bGVzL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL3ZpZGVvLnNjc3NcIik7XG5pZih0eXBlb2YgY29udGVudCA9PT0gJ3N0cmluZycpIGNvbnRlbnQgPSBbW21vZHVsZS5pZCwgY29udGVudCwgJyddXTtcbi8vIGFkZCB0aGUgc3R5bGVzIHRvIHRoZSBET01cbnZhciB1cGRhdGUgPSByZXF1aXJlKFwiIS4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9hZGRTdHlsZXMuanNcIikoY29udGVudCwge30pO1xuaWYoY29udGVudC5sb2NhbHMpIG1vZHVsZS5leHBvcnRzID0gY29udGVudC5sb2NhbHM7XG4vLyBIb3QgTW9kdWxlIFJlcGxhY2VtZW50XG5pZihtb2R1bGUuaG90KSB7XG5cdC8vIFdoZW4gdGhlIHN0eWxlcyBjaGFuZ2UsIHVwZGF0ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdGlmKCFjb250ZW50LmxvY2Fscykge1xuXHRcdG1vZHVsZS5ob3QuYWNjZXB0KFwiISEuLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLy4uLy4uL25vZGVfbW9kdWxlcy9zYXNzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi92aWRlby5zY3NzXCIsIGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIG5ld0NvbnRlbnQgPSByZXF1aXJlKFwiISEuLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLy4uLy4uL25vZGVfbW9kdWxlcy9zYXNzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi92aWRlby5zY3NzXCIpO1xuXHRcdFx0aWYodHlwZW9mIG5ld0NvbnRlbnQgPT09ICdzdHJpbmcnKSBuZXdDb250ZW50ID0gW1ttb2R1bGUuaWQsIG5ld0NvbnRlbnQsICcnXV07XG5cdFx0XHR1cGRhdGUobmV3Q29udGVudCk7XG5cdFx0fSk7XG5cdH1cblx0Ly8gV2hlbiB0aGUgbW9kdWxlIGlzIGRpc3Bvc2VkLCByZW1vdmUgdGhlIDxzdHlsZT4gdGFnc1xuXHRtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24oKSB7IHVwZGF0ZSgpOyB9KTtcbn1cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL3N0eWxlcy92aWRlby5zY3NzXG4gKiogbW9kdWxlIGlkID0gNTlcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsImV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2xpYi9jc3MtYmFzZS5qc1wiKSgpO1xuLy8gaW1wb3J0c1xuXG5cbi8vIG1vZHVsZVxuZXhwb3J0cy5wdXNoKFttb2R1bGUuaWQsIFwiLndlZXgtdmlkZW8ge1xcbiAgYmFja2dyb3VuZC1jb2xvcjogIzAwMDsgfVxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi9zcmMvc3JjL3N0eWxlcy92aWRlby5zY3NzXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCJBQUFBO0VBQ0MsdUJBQXVCLEVBQ3ZCXCIsXCJmaWxlXCI6XCJ2aWRlby5zY3NzXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIi53ZWV4LXZpZGVvIHtcXG5cXHRiYWNrZ3JvdW5kLWNvbG9yOiAjMDAwO1xcbn1cIl0sXCJzb3VyY2VSb290XCI6XCJ3ZWJwYWNrOi8vXCJ9XSk7XG5cbi8vIGV4cG9ydHNcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2Nzcy1sb2FkZXI/c291cmNlTWFwIS4vfi9zYXNzLWxvYWRlcj9zb3VyY2VNYXAhLi9zcmMvc3R5bGVzL3ZpZGVvLnNjc3NcbiAqKiBtb2R1bGUgaWQgPSA2MFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnZhciBBdG9taWMgPSByZXF1aXJlKCcuL2F0b21pYycpXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpXG5yZXF1aXJlKCcuLi9zdHlsZXMvc3dpdGNoLnNjc3MnKVxuXG52YXIgZGVmYXVsdHMgPSB7XG4gIGNvbG9yOiAnIzY0YmQ2MydcbiAgLCBzZWNvbmRhcnlDb2xvcjogJyNkZmRmZGYnXG4gICwgamFja0NvbG9yOiAnI2ZmZidcbiAgLCBqYWNrU2Vjb25kYXJ5Q29sb3I6IG51bGxcbiAgLCBjbGFzc05hbWU6ICd3ZWV4LXN3aXRjaCdcbiAgLCBkaXNhYmxlZE9wYWNpdHk6IDAuNVxuICAsIHNwZWVkOiAnMC40cydcbiAgLCB3aWR0aDogMTAwXG4gICwgaGVpZ2h0OiA2MFxuICAvLyBpcyB3aWR0aCBhbmQgaGVpZ2h0IHNjYWxhYmxlID9cbiAgLCBzY2FsYWJsZTogZmFsc2Vcbn1cblxuLy8gYXR0cnM6XG4vLyAgIC0gY2hlY2tlZDogaWYgaXMgY2hlY2tlZC5cbi8vICAgLSBkaXNhYmxlZDogaWYgdHJ1ZSwgdGhpcyBjb21wb25lbnQgaXMgbm90IGF2YWlsYWJsZSBmb3IgaW50ZXJhY3Rpb24uXG5mdW5jdGlvbiBTd2l0Y2ggKGRhdGEpIHtcbiAgdGhpcy5vcHRpb25zID0gdXRpbHMuZXh0ZW5kKHt9LCBkZWZhdWx0cylcbiAgdGhpcy5jaGVja2VkID0gZGF0YS5hdHRyLmNoZWNrZWRcbiAgICAgICYmIGRhdGEuYXR0ci5jaGVja2VkICE9PSAnZmFsc2UnID8gdHJ1ZSA6IGZhbHNlXG4gIHRoaXMuZGF0YSA9IGRhdGFcbiAgdGhpcy53aWR0aCA9IHRoaXMub3B0aW9ucy53aWR0aCAqIGRhdGEuc2NhbGVcbiAgdGhpcy5oZWlnaHQgPSB0aGlzLm9wdGlvbnMuaGVpZ2h0ICogZGF0YS5zY2FsZVxuICBBdG9taWMuY2FsbCh0aGlzLCBkYXRhKVxufVxuXG5Td2l0Y2gucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShBdG9taWMucHJvdG90eXBlKVxuXG5Td2l0Y2gucHJvdG90eXBlLmNyZWF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIG5vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJylcbiAgdGhpcy5qYWNrID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc21hbGwnKVxuICBub2RlLmFwcGVuZENoaWxkKHRoaXMuamFjaylcbiAgbm9kZS5jbGFzc05hbWUgPSB0aGlzLm9wdGlvbnMuY2xhc3NOYW1lXG4gIHRoaXMubm9kZSA9IG5vZGVcbiAgdGhpcy5hdHRyLmRpc2FibGVkLmNhbGwodGhpcywgdGhpcy5kYXRhLmF0dHIuZGlzYWJsZWQpXG4gIHJldHVybiBub2RlXG59XG5cblN3aXRjaC5wcm90b3R5cGUub25BcHBlbmQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuc2V0U2l6ZSgpXG4gIHRoaXMuc2V0UG9zaXRpb24oKVxufVxuXG5Td2l0Y2gucHJvdG90eXBlLmF0dHIgPSB7XG4gIGRpc2FibGVkOiBmdW5jdGlvbiAodmFsKSB7XG4gICAgdGhpcy5kaXNhYmxlZCA9IHZhbCAmJiB2YWwgIT09ICdmYWxzZSdcbiAgICAgICAgICAgICAgICAgICAgPyB0cnVlXG4gICAgICAgICAgICAgICAgICAgIDogZmFsc2VcbiAgICB0aGlzLmRpc2FibGVkID8gdGhpcy5kaXNhYmxlKCkgOiB0aGlzLmVuYWJsZSgpXG4gIH1cbn1cblxuU3dpdGNoLnByb3RvdHlwZS5zZXRTaXplID0gZnVuY3Rpb24gKCkge1xuICB2YXIgbWluID0gTWF0aC5taW4odGhpcy53aWR0aCwgdGhpcy5oZWlnaHQpXG4gIHZhciBtYXggPSBNYXRoLm1heCh0aGlzLndpZHRoLCB0aGlzLmhlaWdodClcbiAgdGhpcy5ub2RlLnN0eWxlLndpZHRoID0gbWF4ICsgJ3B4J1xuICB0aGlzLm5vZGUuc3R5bGUuaGVpZ2h0ID0gbWluICsgJ3B4J1xuICB0aGlzLm5vZGUuc3R5bGUuYm9yZGVyUmFkaXVzID0gbWluIC8gMiArICdweCdcbiAgdGhpcy5qYWNrLnN0eWxlLndpZHRoXG4gICAgICA9IHRoaXMuamFjay5zdHlsZS5oZWlnaHRcbiAgICAgID0gbWluICsgJ3B4J1xufVxuXG5Td2l0Y2gucHJvdG90eXBlLnNldFBvc2l0aW9uID0gZnVuY3Rpb24gKGNsaWNrZWQpIHtcbiAgdmFyIGNoZWNrZWQgPSB0aGlzLmNoZWNrZWRcbiAgdmFyIG5vZGUgPSB0aGlzLm5vZGVcbiAgdmFyIGphY2sgPSB0aGlzLmphY2tcblxuICBpZiAoY2xpY2tlZCAmJiBjaGVja2VkKSB7XG4gICAgY2hlY2tlZCA9IGZhbHNlXG4gIH0gZWxzZSBpZiAoY2xpY2tlZCAmJiAhY2hlY2tlZCkge1xuICAgIGNoZWNrZWQgPSB0cnVlXG4gIH1cblxuICBpZiAoY2hlY2tlZCA9PT0gdHJ1ZSkge1xuICAgIHRoaXMuY2hlY2tlZCA9IHRydWVcblxuICAgIGlmICh3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSkge1xuICAgICAgamFjay5zdHlsZS5sZWZ0ID0gcGFyc2VJbnQod2luZG93LmdldENvbXB1dGVkU3R5bGUobm9kZSkud2lkdGgpXG4gICAgICAgICAgICAgICAgICAgICAgICAtIHBhcnNlSW50KHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGphY2spLndpZHRoKSArICdweCdcbiAgICB9IGVsc2Uge1xuICAgICAgamFjay5zdHlsZS5sZWZ0ID0gcGFyc2VJbnQobm9kZS5jdXJyZW50U3R5bGVbJ3dpZHRoJ10pXG4gICAgICAgICAgICAgICAgICAgICAgICAtIHBhcnNlSW50KGphY2suY3VycmVudFN0eWxlWyd3aWR0aCddKSArICdweCdcbiAgICB9XG5cbiAgICB0aGlzLm9wdGlvbnMuY29sb3IgJiYgdGhpcy5jb2xvcml6ZSgpXG4gICAgdGhpcy5zZXRTcGVlZCgpXG4gIH0gZWxzZSB7XG4gICAgdGhpcy5jaGVja2VkID0gZmFsc2VcbiAgICBqYWNrLnN0eWxlLmxlZnQgPSAwXG4gICAgbm9kZS5zdHlsZS5ib3hTaGFkb3cgPSAnaW5zZXQgMCAwIDAgMCAnICsgdGhpcy5vcHRpb25zLnNlY29uZGFyeUNvbG9yXG4gICAgbm9kZS5zdHlsZS5ib3JkZXJDb2xvciA9IHRoaXMub3B0aW9ucy5zZWNvbmRhcnlDb2xvclxuICAgIG5vZGUuc3R5bGUuYmFja2dyb3VuZENvbG9yXG4gICAgICAgID0gKHRoaXMub3B0aW9ucy5zZWNvbmRhcnlDb2xvciAhPT0gZGVmYXVsdHMuc2Vjb25kYXJ5Q29sb3IpXG4gICAgICAgICAgPyB0aGlzLm9wdGlvbnMuc2Vjb25kYXJ5Q29sb3JcbiAgICAgICAgICA6ICcjZmZmJ1xuICAgIGphY2suc3R5bGUuYmFja2dyb3VuZENvbG9yXG4gICAgICAgID0gKHRoaXMub3B0aW9ucy5qYWNrU2Vjb25kYXJ5Q29sb3IgIT09IHRoaXMub3B0aW9ucy5qYWNrQ29sb3IpXG4gICAgICAgICAgPyB0aGlzLm9wdGlvbnMuamFja1NlY29uZGFyeUNvbG9yXG4gICAgICAgICAgOiB0aGlzLm9wdGlvbnMuamFja0NvbG9yXG4gICAgdGhpcy5zZXRTcGVlZCgpXG4gIH1cbn1cblxuU3dpdGNoLnByb3RvdHlwZS5jb2xvcml6ZSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIG5vZGVIZWlnaHQgPSB0aGlzLm5vZGUub2Zmc2V0SGVpZ2h0IC8gMlxuXG4gIHRoaXMubm9kZS5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLm9wdGlvbnMuY29sb3JcbiAgdGhpcy5ub2RlLnN0eWxlLmJvcmRlckNvbG9yID0gdGhpcy5vcHRpb25zLmNvbG9yXG4gIHRoaXMubm9kZS5zdHlsZS5ib3hTaGFkb3cgPSAnaW5zZXQgMCAwIDAgJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBub2RlSGVpZ2h0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICdweCAnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIHRoaXMub3B0aW9ucy5jb2xvclxuICB0aGlzLmphY2suc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5vcHRpb25zLmphY2tDb2xvclxufVxuXG5Td2l0Y2gucHJvdG90eXBlLnNldFNwZWVkID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc3dpdGNoZXJQcm9wID0ge31cbiAgdmFyIGphY2tQcm9wID0ge1xuICAgICAgJ2JhY2tncm91bmQtY29sb3InOiB0aGlzLm9wdGlvbnMuc3BlZWRcbiAgICAgICwgbGVmdDogdGhpcy5vcHRpb25zLnNwZWVkLnJlcGxhY2UoL1thLXpdLywgJycpIC8gMiArICdzJ1xuICAgIH1cblxuICBpZiAodGhpcy5jaGVja2VkKSB7XG4gICAgc3dpdGNoZXJQcm9wID0ge1xuICAgICAgYm9yZGVyOiB0aGlzLm9wdGlvbnMuc3BlZWRcbiAgICAgICwgJ2JveC1zaGFkb3cnOiB0aGlzLm9wdGlvbnMuc3BlZWRcbiAgICAgICwgJ2JhY2tncm91bmQtY29sb3InOiB0aGlzLm9wdGlvbnMuc3BlZWQucmVwbGFjZSgvW2Etel0vLCAnJykgKiAzICsgJ3MnXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHN3aXRjaGVyUHJvcCA9IHtcbiAgICAgIGJvcmRlcjogdGhpcy5vcHRpb25zLnNwZWVkXG4gICAgICAsICdib3gtc2hhZG93JzogdGhpcy5vcHRpb25zLnNwZWVkXG4gICAgfVxuICB9XG5cbiAgdXRpbHMudHJhbnNpdGlvbml6ZSh0aGlzLm5vZGUsIHN3aXRjaGVyUHJvcClcbiAgdXRpbHMudHJhbnNpdGlvbml6ZSh0aGlzLmphY2ssIGphY2tQcm9wKVxufVxuXG5Td2l0Y2gucHJvdG90eXBlLmRpc2FibGUgPSBmdW5jdGlvbiAoKSB7XG4gICF0aGlzLmRpc2FibGVkICYmICh0aGlzLmRpc2FibGVkID0gdHJ1ZSlcbiAgdGhpcy5ub2RlLnN0eWxlLm9wYWNpdHkgPSBkZWZhdWx0cy5kaXNhYmxlZE9wYWNpdHlcbiAgdGhpcy5ub2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5nZXRDbGlja0hhbmRsZXIoKSlcbn1cblxuU3dpdGNoLnByb3RvdHlwZS5lbmFibGUgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuZGlzYWJsZWQgJiYgKHRoaXMuZGlzYWJsZWQgPSBmYWxzZSlcbiAgdGhpcy5ub2RlLnN0eWxlLm9wYWNpdHkgPSAxXG4gIHRoaXMubm9kZS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMuZ2V0Q2xpY2tIYW5kbGVyKCkpXG59XG5cblN3aXRjaC5wcm90b3R5cGUuZ2V0Q2xpY2tIYW5kbGVyID0gZnVuY3Rpb24gKCkge1xuICBpZiAoIXRoaXMuX2NsaWNrSGFuZGxlcikge1xuICAgIHRoaXMuX2NsaWNrSGFuZGxlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIHZhciBwYXJlbnQgPSB0aGlzLm5vZGUucGFyZW50Tm9kZS50YWdOYW1lLnRvTG93ZXJDYXNlKClcbiAgICAgIC8vIHZhciBsYWJlbFBhcmVudCA9IChwYXJlbnQgPT09ICdsYWJlbCcpID8gZmFsc2UgOiB0cnVlXG4gICAgICB0aGlzLnNldFBvc2l0aW9uKHRydWUpXG4gICAgICB0aGlzLmRpc3BhdGNoRXZlbnQoJ2NoYW5nZScsIHtcbiAgICAgICAgY2hlY2tlZDogdGhpcy5jaGVja2VkXG4gICAgICB9KVxuICAgIH0uYmluZCh0aGlzKVxuICB9XG4gIHJldHVybiB0aGlzLl9jbGlja0hhbmRsZXJcbn1cblxuU3dpdGNoLnByb3RvdHlwZS5zdHlsZVxuICAgID0gdXRpbHMuZXh0ZW5kKE9iamVjdC5jcmVhdGUoQXRvbWljLnByb3RvdHlwZS5zdHlsZSksIHtcblxuICAgICAgd2lkdGg6IGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgICAgaWYgKCF0aGlzLm9wdGlvbnMuc2NhbGFibGUpIHtcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuICAgICAgICB2YWwgPSBwYXJzZUZsb2F0KHZhbClcbiAgICAgICAgaWYgKHZhbCAhPT0gdmFsIHx8IHZhbCA8IDApIHsgLy8gTmFOXG4gICAgICAgICAgdmFsID0gdGhpcy5vcHRpb25zLndpZHRoXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy53aWR0aCA9IHZhbCAqIHRoaXMuZGF0YS5zY2FsZVxuICAgICAgICB0aGlzLnNldFNpemUoKVxuICAgICAgfSxcblxuICAgICAgaGVpZ2h0OiBmdW5jdGlvbiAodmFsKSB7XG4gICAgICAgIGlmICghdGhpcy5vcHRpb25zLnNjYWxhYmxlKSB7XG4gICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cbiAgICAgICAgdmFsID0gcGFyc2VGbG9hdCh2YWwpXG4gICAgICAgIGlmICh2YWwgIT09IHZhbCB8fCB2YWwgPCAwKSB7IC8vIE5hTlxuICAgICAgICAgIHZhbCA9IHRoaXMub3B0aW9ucy5oZWlnaHRcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmhlaWdodCA9IHZhbCAqIHRoaXMuZGF0YS5zY2FsZVxuICAgICAgICB0aGlzLnNldFNpemUoKVxuICAgICAgfVxuXG4gICAgfSlcblxubW9kdWxlLmV4cG9ydHMgPSBTd2l0Y2hcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvY29tcG9uZW50cy9zd2l0Y2guanNcbiAqKiBtb2R1bGUgaWQgPSA2MVxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLy8gc3R5bGUtbG9hZGVyOiBBZGRzIHNvbWUgY3NzIHRvIHRoZSBET00gYnkgYWRkaW5nIGEgPHN0eWxlPiB0YWdcblxuLy8gbG9hZCB0aGUgc3R5bGVzXG52YXIgY29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vbm9kZV9tb2R1bGVzL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL3N3aXRjaC5zY3NzXCIpO1xuaWYodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSBjb250ZW50ID0gW1ttb2R1bGUuaWQsIGNvbnRlbnQsICcnXV07XG4vLyBhZGQgdGhlIHN0eWxlcyB0byB0aGUgRE9NXG52YXIgdXBkYXRlID0gcmVxdWlyZShcIiEuLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvYWRkU3R5bGVzLmpzXCIpKGNvbnRlbnQsIHt9KTtcbmlmKGNvbnRlbnQubG9jYWxzKSBtb2R1bGUuZXhwb3J0cyA9IGNvbnRlbnQubG9jYWxzO1xuLy8gSG90IE1vZHVsZSBSZXBsYWNlbWVudFxuaWYobW9kdWxlLmhvdCkge1xuXHQvLyBXaGVuIHRoZSBzdHlsZXMgY2hhbmdlLCB1cGRhdGUgdGhlIDxzdHlsZT4gdGFnc1xuXHRpZighY29udGVudC5sb2NhbHMpIHtcblx0XHRtb2R1bGUuaG90LmFjY2VwdChcIiEhLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi9ub2RlX21vZHVsZXMvc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vc3dpdGNoLnNjc3NcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbmV3Q29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vbm9kZV9tb2R1bGVzL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL3N3aXRjaC5zY3NzXCIpO1xuXHRcdFx0aWYodHlwZW9mIG5ld0NvbnRlbnQgPT09ICdzdHJpbmcnKSBuZXdDb250ZW50ID0gW1ttb2R1bGUuaWQsIG5ld0NvbnRlbnQsICcnXV07XG5cdFx0XHR1cGRhdGUobmV3Q29udGVudCk7XG5cdFx0fSk7XG5cdH1cblx0Ly8gV2hlbiB0aGUgbW9kdWxlIGlzIGRpc3Bvc2VkLCByZW1vdmUgdGhlIDxzdHlsZT4gdGFnc1xuXHRtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24oKSB7IHVwZGF0ZSgpOyB9KTtcbn1cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL3N0eWxlcy9zd2l0Y2guc2Nzc1xuICoqIG1vZHVsZSBpZCA9IDYyXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikoKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIi8qIHN3aXRjaCBkZWZhdWx0cy4gKi9cXG4ud2VleC1zd2l0Y2gge1xcbiAgYmFja2dyb3VuZC1jb2xvcjogI2ZmZjtcXG4gIGJvcmRlcjogMXB4IHNvbGlkICNkZmRmZGY7XFxuICBjdXJzb3I6IHBvaW50ZXI7XFxuICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XFxuICBwb3NpdGlvbjogcmVsYXRpdmU7XFxuICB2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xcbiAgLW1vei11c2VyLXNlbGVjdDogbm9uZTtcXG4gIC1raHRtbC11c2VyLXNlbGVjdDogbm9uZTtcXG4gIC13ZWJraXQtdXNlci1zZWxlY3Q6IG5vbmU7XFxuICAtbXMtdXNlci1zZWxlY3Q6IG5vbmU7XFxuICB1c2VyLXNlbGVjdDogbm9uZTtcXG4gIGJveC1zaXppbmc6IGNvbnRlbnQtYm94O1xcbiAgYmFja2dyb3VuZC1jbGlwOiBjb250ZW50LWJveDsgfVxcblxcbi53ZWV4LXN3aXRjaCA+IHNtYWxsIHtcXG4gIGJhY2tncm91bmQ6ICNmZmY7XFxuICBib3JkZXItcmFkaXVzOiAxMDAlO1xcbiAgYm94LXNoYWRvdzogMCAxcHggM3B4IHJnYmEoMCwgMCwgMCwgMC40KTtcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gIHRvcDogMDsgfVxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi9zcmMvc3JjL3N0eWxlcy9zd2l0Y2guc2Nzc1wiXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiQUFBQSxzQkFBc0I7QUFFdEI7RUFDRSx1QkFBdUI7RUFDdkIsMEJBQTBCO0VBQzFCLGdCQUFnQjtFQUNoQixzQkFBc0I7RUFDdEIsbUJBQW1CO0VBQ25CLHVCQUF1QjtFQUV2Qix1QkFBdUI7RUFDdkIseUJBQXlCO0VBQ3pCLDBCQUEwQjtFQUMxQixzQkFBc0I7RUFDdEIsa0JBQWtCO0VBQ2xCLHdCQUF3QjtFQUN4Qiw2QkFBNkIsRUFDOUI7O0FBRUQ7RUFDRSxpQkFBaUI7RUFDakIsb0JBQW9CO0VBQ3BCLHlDQUEwQjtFQUMxQixtQkFBbUI7RUFDbkIsT0FBTyxFQUNSXCIsXCJmaWxlXCI6XCJzd2l0Y2guc2Nzc1wiLFwic291cmNlc0NvbnRlbnRcIjpbXCIvKiBzd2l0Y2ggZGVmYXVsdHMuICovXFxuXFxuLndlZXgtc3dpdGNoIHtcXG4gIGJhY2tncm91bmQtY29sb3I6ICNmZmY7XFxuICBib3JkZXI6IDFweCBzb2xpZCAjZGZkZmRmO1xcbiAgY3Vyc29yOiBwb2ludGVyO1xcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xcbiAgdmVydGljYWwtYWxpZ246IG1pZGRsZTtcXG5cXG4gIC1tb3otdXNlci1zZWxlY3Q6IG5vbmU7XFxuICAta2h0bWwtdXNlci1zZWxlY3Q6IG5vbmU7XFxuICAtd2Via2l0LXVzZXItc2VsZWN0OiBub25lO1xcbiAgLW1zLXVzZXItc2VsZWN0OiBub25lO1xcbiAgdXNlci1zZWxlY3Q6IG5vbmU7XFxuICBib3gtc2l6aW5nOiBjb250ZW50LWJveDtcXG4gIGJhY2tncm91bmQtY2xpcDogY29udGVudC1ib3g7XFxufVxcblxcbi53ZWV4LXN3aXRjaCA+IHNtYWxsIHtcXG4gIGJhY2tncm91bmQ6ICNmZmY7XFxuICBib3JkZXItcmFkaXVzOiAxMDAlO1xcbiAgYm94LXNoYWRvdzogMCAxcHggM3B4IHJnYmEoMCwgMCwgMCwgMC40KTtcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gIHRvcDogMDtcXG59XFxuXCJdLFwic291cmNlUm9vdFwiOlwid2VicGFjazovL1wifV0pO1xuXG4vLyBleHBvcnRzXG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL34vc2Fzcy1sb2FkZXI/c291cmNlTWFwIS4vc3JjL3N0eWxlcy9zd2l0Y2guc2Nzc1xuICoqIG1vZHVsZSBpZCA9IDYzXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIndXNlIHN0cmljdCdcblxudmFyIENvbXBvbmVudCA9IHJlcXVpcmUoJy4vY29tcG9uZW50JylcblxuLy8gYXR0cnM6XG4vLyAgIC0gaHJlZlxuZnVuY3Rpb24gQSAoZGF0YSkge1xuICBDb21wb25lbnQuY2FsbCh0aGlzLCBkYXRhKVxufVxuXG5BLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoQ29tcG9uZW50LnByb3RvdHlwZSlcblxuQS5wcm90b3R5cGUuY3JlYXRlID0gZnVuY3Rpb24gKCkge1xuICB2YXIgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKVxuICBub2RlLmNsYXNzTGlzdC5hZGQoJ3dlZXgtY29udGFpbmVyJylcbiAgdGhpcy5ub2RlID0gbm9kZVxuICB0aGlzLnN0eWxlLmFsaWduSXRlbXMuY2FsbCh0aGlzLCAnY2VudGVyJylcbiAgdGhpcy5zdHlsZS5qdXN0aWZ5Q29udGVudC5jYWxsKHRoaXMsICdjZW50ZXInKVxuICB0aGlzLm5vZGUuc3R5bGUudGV4dERlY29yYXRpb24gPSAnbm9uZSdcbiAgcmV0dXJuIG5vZGVcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBBXG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL2NvbXBvbmVudHMvYS5qc1xuICoqIG1vZHVsZSBpZCA9IDY0XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIndXNlIHN0cmljdCdcblxudmFyIENvbXBvbmVudCA9IHJlcXVpcmUoJy4vY29tcG9uZW50JylcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJylcblxudmFyIElEX1BSRUZJWCA9ICd3ZWV4X2VtYmVkXydcblxuZnVuY3Rpb24gX2dlbmVyYXRlSWQoKSB7XG4gIHJldHVybiBJRF9QUkVGSVggKyB1dGlscy5nZXRSYW5kb20oMTApXG59XG5cbmZ1bmN0aW9uIEVtYmVkIChkYXRhLCBub2RlVHlwZSkge1xuICB2YXIgYXR0ciA9IGRhdGEuYXR0clxuICBpZiAoYXR0cikge1xuICAgIHRoaXMuc291cmNlID0gYXR0ci5zcmNcbiAgICB0aGlzLmxvYWRlciA9IGF0dHIubG9hZGUgfHwgJ3hocidcbiAgfVxuICBDb21wb25lbnQuY2FsbCh0aGlzLCBkYXRhLCBub2RlVHlwZSlcbiAgdGhpcy5pbml0V2VleCgpXG59XG5cbkVtYmVkLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoQ29tcG9uZW50LnByb3RvdHlwZSlcblxuRW1iZWQucHJvdG90eXBlLmNyZWF0ZSA9IGZ1bmN0aW9uICgpIHtcblxuICB2YXIgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gIG5vZGUuaWQgPSB0aGlzLmlkXG4gIG5vZGUuc3R5bGUub3ZlcmZsb3cgPSAnc2Nyb2xsJ1xuICAvLyBub2RlLmNsYXNzTGlzdC5hZGQoJ3dlZXgtY29udGFpbmVyJylcbiAgcmV0dXJuIG5vZGVcbn1cblxuRW1iZWQucHJvdG90eXBlLmluaXRXZWV4ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmlkID0gX2dlbmVyYXRlSWQoKVxuICB0aGlzLm5vZGUuaWQgPSB0aGlzLmlkXG4gIHZhciBjb25maWcgPSB7XG4gICAgYXBwSWQ6IHRoaXMuaWQsXG4gICAgc291cmNlOiB0aGlzLnNvdXJjZSxcbiAgICBsb2FkZXI6IHRoaXMubG9hZGVyLFxuICAgIHdpZHRoOiB0aGlzLm5vZGUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkud2lkdGgsXG4gICAgcm9vdElkOiB0aGlzLmlkXG4gIH1cbiAgd2luZG93LndlZXguaW5pdChjb25maWcpXG59XG5cbkVtYmVkLnByb3RvdHlwZS5kZXN0cm95V2VleCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5pZCAmJiB3aW5kb3cuZGVzdHJveUluc3RhbmNlKHRoaXMuaWQpXG4gIC8vIFRPRE86IHVuYmluZCBldmVudHMgYW5kIGNsZWFyIGRvbXMuXG4gIHRoaXMubm9kZS5pbm5lckhUTUwgPSAnJ1xufVxuXG5FbWJlZC5wcm90b3R5cGUucmVsb2FkV2VleCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5kZXN0cm95V2VleCgpXG4gIHRoaXMuaW5pdFdlZXgoKVxufVxuXG4vLyBzcmMgaXMgbm90IHVwZGF0YWJsZSB0ZW1wb3JhcmlseVxuLy8gRW1iZWQucHJvdG90eXBlLmF0dHIgPSB7XG4vLyAgIHNyYzogZnVuY3Rpb24gKHZhbHVlKSB7XG4vLyAgICAgdGhpcy5zcmMgPSB2YWx1ZVxuLy8gICAgIHRoaXMucmVsb2FkV2VleCgpXG4vLyAgIH1cbi8vIH1cblxubW9kdWxlLmV4cG9ydHMgPSBFbWJlZFxuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL3NyYy9jb21wb25lbnRzL2VtYmVkLmpzXG4gKiogbW9kdWxlIGlkID0gNjVcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciBkb20gPSByZXF1aXJlKCcuL2RvbScpXG52YXIgZXZlbnQgPSByZXF1aXJlKCcuL2V2ZW50JylcbnZhciBwYWdlSW5mbyA9IHJlcXVpcmUoJy4vcGFnZUluZm8nKVxudmFyIHN0cmVhbSA9IHJlcXVpcmUoJy4vc3RyZWFtJylcbnZhciBtb2RhbCA9IHJlcXVpcmUoJy4vbW9kYWwnKVxudmFyIGFuaW1hdGlvbiA9IHJlcXVpcmUoJy4vYW5pbWF0aW9uJylcblxudmFyIGFwaSA9IHtcbiAgaW5pdDogZnVuY3Rpb24gKFdlZXgpIHtcbiAgICBXZWV4LnJlZ2lzdGVyQXBpTW9kdWxlKCdkb20nLCBkb20sIGRvbS5fbWV0YSlcbiAgICBXZWV4LnJlZ2lzdGVyQXBpTW9kdWxlKCdldmVudCcsIGV2ZW50LCBldmVudC5fbWV0YSlcbiAgICBXZWV4LnJlZ2lzdGVyQXBpTW9kdWxlKCdwYWdlSW5mbycsIHBhZ2VJbmZvLCBwYWdlSW5mby5fbWV0YSlcbiAgICBXZWV4LnJlZ2lzdGVyQXBpTW9kdWxlKCdzdHJlYW0nLCBzdHJlYW0sIHN0cmVhbS5fbWV0YSlcbiAgICBXZWV4LnJlZ2lzdGVyQXBpTW9kdWxlKCdtb2RhbCcsIG1vZGFsLCBtb2RhbC5fbWV0YSlcbiAgICBXZWV4LnJlZ2lzdGVyQXBpTW9kdWxlKCdhbmltYXRpb24nLCBhbmltYXRpb24sIGFuaW1hdGlvbi5fbWV0YSlcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFwaVxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvYXBpL2luZGV4LmpzXG4gKiogbW9kdWxlIGlkID0gNjZcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIid1c2Ugc3RyaWN0J1xuXG52YXIgbWVzc2FnZVF1ZXVlID0gcmVxdWlyZSgnLi4vbWVzc2FnZVF1ZXVlJylcbnZhciBGcmFtZVVwZGF0ZXIgPSByZXF1aXJlKCcuLi9mcmFtZVVwZGF0ZXInKVxudmFyIENvbXBvbmVudCA9IHJlcXVpcmUoJy4uL2NvbXBvbmVudHMvY29tcG9uZW50JylcbnZhciBzY3JvbGwgPSByZXF1aXJlKCdzY3JvbGwtdG8nKVxudmFyIGNvbmZpZyA9IHJlcXVpcmUoJy4uL2NvbmZpZycpXG4vLyB2YXIgV2VleCA9IHJlcXVpcmUoJy4uL3dlZXgnKVxuXG52YXIgZG9tID0ge1xuXG4gIC8qKlxuICAgKiBjcmVhdGVCb2R5OiBjcmVhdGUgcm9vdCBjb21wb25lbnRcbiAgICogQHBhcmFtICB7b2JqZWN0fSBlbGVtZW50XG4gICAqICAgIGNvbnRhaW5lcnxsaXN0dmlld3xzY3JvbGx2aWV3XG4gICAqIEByZXR1cm4ge1t0eXBlXX0gICAgICBbZGVzY3JpcHRpb25dXG4gICAqL1xuICBjcmVhdGVCb2R5OiBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgIHZhciBjb21wb25lbnRNYW5hZ2VyID0gdGhpcy5nZXRDb21wb25lbnRNYW5hZ2VyKClcbiAgICBlbGVtZW50LnNjYWxlID0gdGhpcy5zY2FsZVxuICAgIGVsZW1lbnQuaW5zdGFuY2VJZCA9IGNvbXBvbmVudE1hbmFnZXIuaW5zdGFuY2VJZFxuICAgIHJldHVybiBjb21wb25lbnRNYW5hZ2VyLmNyZWF0ZUJvZHkoZWxlbWVudClcbiAgfSxcblxuICBhZGRFbGVtZW50OiBmdW5jdGlvbiAocGFyZW50UmVmLCBlbGVtZW50LCBpbmRleCkge1xuICAgIHZhciBjb21wb25lbnRNYW5hZ2VyID0gdGhpcy5nZXRDb21wb25lbnRNYW5hZ2VyKClcbiAgICBlbGVtZW50LnNjYWxlID0gdGhpcy5zY2FsZVxuICAgIGVsZW1lbnQuaW5zdGFuY2VJZCA9IGNvbXBvbmVudE1hbmFnZXIuaW5zdGFuY2VJZFxuICAgIHJldHVybiBjb21wb25lbnRNYW5hZ2VyLmFkZEVsZW1lbnQocGFyZW50UmVmLCBlbGVtZW50LCBpbmRleClcbiAgfSxcblxuICByZW1vdmVFbGVtZW50OiBmdW5jdGlvbiAocmVmKSB7XG4gICAgdmFyIGNvbXBvbmVudE1hbmFnZXIgPSB0aGlzLmdldENvbXBvbmVudE1hbmFnZXIoKVxuICAgIHJldHVybiBjb21wb25lbnRNYW5hZ2VyLnJlbW92ZUVsZW1lbnQocmVmKVxuICB9LFxuXG4gIG1vdmVFbGVtZW50OiBmdW5jdGlvbiAocmVmLCBwYXJlbnRSZWYsIGluZGV4KSB7XG4gICAgdmFyIGNvbXBvbmVudE1hbmFnZXIgPSB0aGlzLmdldENvbXBvbmVudE1hbmFnZXIoKVxuICAgIHJldHVybiBjb21wb25lbnRNYW5hZ2VyLm1vdmVFbGVtZW50KHJlZiwgcGFyZW50UmVmLCBpbmRleClcbiAgfSxcblxuICBhZGRFdmVudDogZnVuY3Rpb24gKHJlZiwgdHlwZSkge1xuICAgIHZhciBjb21wb25lbnRNYW5hZ2VyID0gdGhpcy5nZXRDb21wb25lbnRNYW5hZ2VyKClcbiAgICByZXR1cm4gY29tcG9uZW50TWFuYWdlci5hZGRFdmVudChyZWYsIHR5cGUpXG4gIH0sXG5cbiAgcmVtb3ZlRXZlbnQ6IGZ1bmN0aW9uIChyZWYsIHR5cGUpIHtcbiAgICB2YXIgY29tcG9uZW50TWFuYWdlciA9IHRoaXMuZ2V0Q29tcG9uZW50TWFuYWdlcigpXG4gICAgcmV0dXJuIGNvbXBvbmVudE1hbmFnZXIucmVtb3ZlRXZlbnQocmVmLCB0eXBlKVxuICB9LFxuXG4gIC8qKlxuICAgKiB1cGRhdGVBdHRyczogdXBkYXRlIGF0dHJpYnV0ZXMgb2YgY29tcG9uZW50XG4gICAqIEBwYXJhbSAge3N0cmluZ30gcmVmXG4gICAqIEBwYXJhbSAge29ian0gYXR0clxuICAgKi9cbiAgdXBkYXRlQXR0cnM6IGZ1bmN0aW9uIChyZWYsIGF0dHIpIHtcbiAgICB2YXIgY29tcG9uZW50TWFuYWdlciA9IHRoaXMuZ2V0Q29tcG9uZW50TWFuYWdlcigpXG4gICAgcmV0dXJuIGNvbXBvbmVudE1hbmFnZXIudXBkYXRlQXR0cnMocmVmLCBhdHRyKVxuICB9LFxuXG4gIC8qKlxuICAgKiB1cGRhdGVTdHlsZTogdWRwYXRlIHN0eWxlIG9mIGNvbXBvbmVudFxuICAgKiBAcGFyYW0ge3N0cmluZ30gcmVmXG4gICAqIEBwYXJhbSB7b2JqfSBzdHlsZVxuICAgKi9cbiAgdXBkYXRlU3R5bGU6IGZ1bmN0aW9uIChyZWYsIHN0eWxlKSB7XG4gICAgdmFyIGNvbXBvbmVudE1hbmFnZXIgPSB0aGlzLmdldENvbXBvbmVudE1hbmFnZXIoKVxuICAgIHJldHVybiBjb21wb25lbnRNYW5hZ2VyLnVwZGF0ZVN0eWxlKHJlZiwgc3R5bGUpXG4gIH0sXG5cbiAgY3JlYXRlRmluaXNoOiBmdW5jdGlvbiAoKSB7XG4gICAgLy8gVE9ET1xuICAgIC8vIEZyYW1lVXBkYXRlci5wYXVzZSgpXG4gIH0sXG5cbiAgcmVmcmVzaEZpbmlzaDogZnVuY3Rpb24gKCkge1xuICAgIC8vIFRPRE9cbiAgfSxcblxuICAvKipcbiAgICogc2Nyb2xsVG9FbGVtZW50XG4gICAqIEBwYXJhbSAge3N0cmluZ30gcmVmXG4gICAqIEBwYXJhbSAge29ian0gb3B0aW9ucyB7b2Zmc2V0Ok51bWJlcn1cbiAgICogICBwczogc2Nyb2xsLXRvIGhhcyAnZWFzZScgYW5kICdkdXJhdGlvbicobXMpIGFzIG9wdGlvbnMuXG4gICAqL1xuICBzY3JvbGxUb0VsZW1lbnQ6IGZ1bmN0aW9uIChyZWYsIG9wdGlvbnMpIHtcbiAgICAhb3B0aW9ucyAmJiAob3B0aW9ucyA9IHt9KVxuICAgIHZhciBjb21wb25lbnRNYW5hZ2VyID0gdGhpcy5nZXRDb21wb25lbnRNYW5hZ2VyKClcbiAgICB2YXIgZWxlbSA9IGNvbXBvbmVudE1hbmFnZXIuZ2V0RWxlbWVudEJ5UmVmKHJlZilcbiAgICBpZiAoZWxlbSkge1xuICAgICAgdmFyIG9mZnNldFRvcCA9IGVsZW0ubm9kZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS50b3BcbiAgICAgICAgICArIGRvY3VtZW50LmJvZHkuc2Nyb2xsVG9wXG4gICAgICB2YXIgb2Zmc2V0ID0gKE51bWJlcihvcHRpb25zLm9mZnNldCkgfHwgMCkgKiB0aGlzLnNjYWxlXG4gICAgICB2YXIgdHdlZW4gPSBzY3JvbGwoMCwgb2Zmc2V0VG9wICsgb2Zmc2V0LCBvcHRpb25zKVxuICAgICAgLy8gdHdlZW4ub24oJ2VuZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIH0pXG4gICAgfVxuICB9XG5cbn1cblxuZG9tLl9tZXRhID0ge1xuICBkb206IFt7XG4gICAgbmFtZTogJ2NyZWF0ZUJvZHknLFxuICAgIGFyZ3M6IFsnb2JqZWN0J11cbiAgfSwge1xuICAgIG5hbWU6ICdhZGRFbGVtZW50JyxcbiAgICBhcmdzOiBbJ3N0cmluZycsICdvYmplY3QnLCAnbnVtYmVyJ11cbiAgfSwge1xuICAgIG5hbWU6ICdyZW1vdmVFbGVtZW50JyxcbiAgICBhcmdzOiBbJ3N0cmluZyddXG4gIH0sIHtcbiAgICBuYW1lOiAnbW92ZUVsZW1lbnQnLFxuICAgIGFyZ3M6IFsnc3RyaW5nJywgJ3N0cmluZycsICdudW1iZXInXVxuICB9LCB7XG4gICAgbmFtZTogJ2FkZEV2ZW50JyxcbiAgICBhcmdzOiBbJ3N0cmluZycsICdzdHJpbmcnXVxuICB9LCB7XG4gICAgbmFtZTogJ3JlbW92ZUV2ZW50JyxcbiAgICBhcmdzOiBbJ3N0cmluZycsICdzdHJpbmcnXVxuICB9LCB7XG4gICAgbmFtZTogJ3VwZGF0ZUF0dHJzJyxcbiAgICBhcmdzOiBbJ3N0cmluZycsICdvYmplY3QnXVxuICB9LCB7XG4gICAgbmFtZTogJ3VwZGF0ZVN0eWxlJyxcbiAgICBhcmdzOiBbJ3N0cmluZycsICdvYmplY3QnXVxuICB9LCB7XG4gICAgbmFtZTogJ2NyZWF0ZUZpbmlzaCcsXG4gICAgYXJnczogW11cbiAgfSwge1xuICAgIG5hbWU6ICdyZWZyZXNoRmluaXNoJyxcbiAgICBhcmdzOiBbXVxuICB9LCB7XG4gICAgbmFtZTogJ3Njcm9sbFRvRWxlbWVudCcsXG4gICAgYXJnczogWydzdHJpbmcnLCAnb2JqZWN0J11cbiAgfV1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBkb21cblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvYXBpL2RvbS5qc1xuICoqIG1vZHVsZSBpZCA9IDY3XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKi9cblxudmFyIFR3ZWVuID0gcmVxdWlyZSgndHdlZW4nKTtcbnZhciByYWYgPSByZXF1aXJlKCdyYWYnKTtcblxuLyoqXG4gKiBFeHBvc2UgYHNjcm9sbFRvYC5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IHNjcm9sbFRvO1xuXG4vKipcbiAqIFNjcm9sbCB0byBgKHgsIHkpYC5cbiAqXG4gKiBAcGFyYW0ge051bWJlcn0geFxuICogQHBhcmFtIHtOdW1iZXJ9IHlcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gc2Nyb2xsVG8oeCwgeSwgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICAvLyBzdGFydCBwb3NpdGlvblxuICB2YXIgc3RhcnQgPSBzY3JvbGwoKTtcblxuICAvLyBzZXR1cCB0d2VlblxuICB2YXIgdHdlZW4gPSBUd2VlbihzdGFydClcbiAgICAuZWFzZShvcHRpb25zLmVhc2UgfHwgJ291dC1jaXJjJylcbiAgICAudG8oeyB0b3A6IHksIGxlZnQ6IHggfSlcbiAgICAuZHVyYXRpb24ob3B0aW9ucy5kdXJhdGlvbiB8fCAxMDAwKTtcblxuICAvLyBzY3JvbGxcbiAgdHdlZW4udXBkYXRlKGZ1bmN0aW9uKG8pe1xuICAgIHdpbmRvdy5zY3JvbGxUbyhvLmxlZnQgfCAwLCBvLnRvcCB8IDApO1xuICB9KTtcblxuICAvLyBoYW5kbGUgZW5kXG4gIHR3ZWVuLm9uKCdlbmQnLCBmdW5jdGlvbigpe1xuICAgIGFuaW1hdGUgPSBmdW5jdGlvbigpe307XG4gIH0pO1xuXG4gIC8vIGFuaW1hdGVcbiAgZnVuY3Rpb24gYW5pbWF0ZSgpIHtcbiAgICByYWYoYW5pbWF0ZSk7XG4gICAgdHdlZW4udXBkYXRlKCk7XG4gIH1cblxuICBhbmltYXRlKCk7XG4gIFxuICByZXR1cm4gdHdlZW47XG59XG5cbi8qKlxuICogUmV0dXJuIHNjcm9sbCBwb3NpdGlvbi5cbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBzY3JvbGwoKSB7XG4gIHZhciB5ID0gd2luZG93LnBhZ2VZT2Zmc2V0IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3A7XG4gIHZhciB4ID0gd2luZG93LnBhZ2VYT2Zmc2V0IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxMZWZ0O1xuICByZXR1cm4geyB0b3A6IHksIGxlZnQ6IHggfTtcbn1cblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L3Njcm9sbC10by9pbmRleC5qc1xuICoqIG1vZHVsZSBpZCA9IDY4XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJcbi8qKlxuICogTW9kdWxlIGRlcGVuZGVuY2llcy5cbiAqL1xuXG52YXIgRW1pdHRlciA9IHJlcXVpcmUoJ2VtaXR0ZXInKTtcbnZhciBjbG9uZSA9IHJlcXVpcmUoJ2Nsb25lJyk7XG52YXIgdHlwZSA9IHJlcXVpcmUoJ3R5cGUnKTtcbnZhciBlYXNlID0gcmVxdWlyZSgnZWFzZScpO1xuXG4vKipcbiAqIEV4cG9zZSBgVHdlZW5gLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gVHdlZW47XG5cbi8qKlxuICogSW5pdGlhbGl6ZSBhIG5ldyBgVHdlZW5gIHdpdGggYG9iamAuXG4gKlxuICogQHBhcmFtIHtPYmplY3R8QXJyYXl9IG9ialxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBUd2VlbihvYmopIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFR3ZWVuKSkgcmV0dXJuIG5ldyBUd2VlbihvYmopO1xuICB0aGlzLl9mcm9tID0gb2JqO1xuICB0aGlzLmVhc2UoJ2xpbmVhcicpO1xuICB0aGlzLmR1cmF0aW9uKDUwMCk7XG59XG5cbi8qKlxuICogTWl4aW4gZW1pdHRlci5cbiAqL1xuXG5FbWl0dGVyKFR3ZWVuLnByb3RvdHlwZSk7XG5cbi8qKlxuICogUmVzZXQgdGhlIHR3ZWVuLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuVHdlZW4ucHJvdG90eXBlLnJlc2V0ID0gZnVuY3Rpb24oKXtcbiAgdGhpcy5pc0FycmF5ID0gJ2FycmF5JyA9PT0gdHlwZSh0aGlzLl9mcm9tKTtcbiAgdGhpcy5fY3VyciA9IGNsb25lKHRoaXMuX2Zyb20pO1xuICB0aGlzLl9kb25lID0gZmFsc2U7XG4gIHRoaXMuX3N0YXJ0ID0gRGF0ZS5ub3coKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFR3ZWVuIHRvIGBvYmpgIGFuZCByZXNldCBpbnRlcm5hbCBzdGF0ZS5cbiAqXG4gKiAgICB0d2Vlbi50byh7IHg6IDUwLCB5OiAxMDAgfSlcbiAqXG4gKiBAcGFyYW0ge09iamVjdHxBcnJheX0gb2JqXG4gKiBAcmV0dXJuIHtUd2Vlbn0gc2VsZlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5Ud2Vlbi5wcm90b3R5cGUudG8gPSBmdW5jdGlvbihvYmope1xuICB0aGlzLnJlc2V0KCk7XG4gIHRoaXMuX3RvID0gb2JqO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0IGR1cmF0aW9uIHRvIGBtc2AgWzUwMF0uXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IG1zXG4gKiBAcmV0dXJuIHtUd2Vlbn0gc2VsZlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5Ud2Vlbi5wcm90b3R5cGUuZHVyYXRpb24gPSBmdW5jdGlvbihtcyl7XG4gIHRoaXMuX2R1cmF0aW9uID0gbXM7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZXQgZWFzaW5nIGZ1bmN0aW9uIHRvIGBmbmAuXG4gKlxuICogICAgdHdlZW4uZWFzZSgnaW4tb3V0LXNpbmUnKVxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfEZ1bmN0aW9ufSBmblxuICogQHJldHVybiB7VHdlZW59XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblR3ZWVuLnByb3RvdHlwZS5lYXNlID0gZnVuY3Rpb24oZm4pe1xuICBmbiA9ICdmdW5jdGlvbicgPT0gdHlwZW9mIGZuID8gZm4gOiBlYXNlW2ZuXTtcbiAgaWYgKCFmbikgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBlYXNpbmcgZnVuY3Rpb24nKTtcbiAgdGhpcy5fZWFzZSA9IGZuO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU3RvcCB0aGUgdHdlZW4gYW5kIGltbWVkaWF0ZWx5IGVtaXQgXCJzdG9wXCIgYW5kIFwiZW5kXCIuXG4gKlxuICogQHJldHVybiB7VHdlZW59XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblR3ZWVuLnByb3RvdHlwZS5zdG9wID0gZnVuY3Rpb24oKXtcbiAgdGhpcy5zdG9wcGVkID0gdHJ1ZTtcbiAgdGhpcy5fZG9uZSA9IHRydWU7XG4gIHRoaXMuZW1pdCgnc3RvcCcpO1xuICB0aGlzLmVtaXQoJ2VuZCcpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogUGVyZm9ybSBhIHN0ZXAuXG4gKlxuICogQHJldHVybiB7VHdlZW59IHNlbGZcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblR3ZWVuLnByb3RvdHlwZS5zdGVwID0gZnVuY3Rpb24oKXtcbiAgaWYgKHRoaXMuX2RvbmUpIHJldHVybjtcblxuICAvLyBkdXJhdGlvblxuICB2YXIgZHVyYXRpb24gPSB0aGlzLl9kdXJhdGlvbjtcbiAgdmFyIG5vdyA9IERhdGUubm93KCk7XG4gIHZhciBkZWx0YSA9IG5vdyAtIHRoaXMuX3N0YXJ0O1xuICB2YXIgZG9uZSA9IGRlbHRhID49IGR1cmF0aW9uO1xuXG4gIC8vIGNvbXBsZXRlXG4gIGlmIChkb25lKSB7XG4gICAgdGhpcy5fZnJvbSA9IHRoaXMuX3RvO1xuICAgIHRoaXMuX3VwZGF0ZSh0aGlzLl90byk7XG4gICAgdGhpcy5fZG9uZSA9IHRydWU7XG4gICAgdGhpcy5lbWl0KCdlbmQnKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIHR3ZWVuXG4gIHZhciBmcm9tID0gdGhpcy5fZnJvbTtcbiAgdmFyIHRvID0gdGhpcy5fdG87XG4gIHZhciBjdXJyID0gdGhpcy5fY3VycjtcbiAgdmFyIGZuID0gdGhpcy5fZWFzZTtcbiAgdmFyIHAgPSAobm93IC0gdGhpcy5fc3RhcnQpIC8gZHVyYXRpb247XG4gIHZhciBuID0gZm4ocCk7XG5cbiAgLy8gYXJyYXlcbiAgaWYgKHRoaXMuaXNBcnJheSkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZnJvbS5sZW5ndGg7ICsraSkge1xuICAgICAgY3VycltpXSA9IGZyb21baV0gKyAodG9baV0gLSBmcm9tW2ldKSAqIG47XG4gICAgfVxuXG4gICAgdGhpcy5fdXBkYXRlKGN1cnIpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gb2JqZWNoXG4gIGZvciAodmFyIGsgaW4gZnJvbSkge1xuICAgIGN1cnJba10gPSBmcm9tW2tdICsgKHRvW2tdIC0gZnJvbVtrXSkgKiBuO1xuICB9XG5cbiAgdGhpcy5fdXBkYXRlKGN1cnIpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0IHVwZGF0ZSBmdW5jdGlvbiB0byBgZm5gIG9yXG4gKiB3aGVuIG5vIGFyZ3VtZW50IGlzIGdpdmVuIHRoaXMgcGVyZm9ybXNcbiAqIGEgXCJzdGVwXCIuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqIEByZXR1cm4ge1R3ZWVufSBzZWxmXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblR3ZWVuLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbihmbil7XG4gIGlmICgwID09IGFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB0aGlzLnN0ZXAoKTtcbiAgdGhpcy5fdXBkYXRlID0gZm47XG4gIHJldHVybiB0aGlzO1xufTtcblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9jb21wb25lbnQtdHdlZW4vaW5kZXguanNcbiAqKiBtb2R1bGUgaWQgPSA2OVxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiXG4vKipcbiAqIEV4cG9zZSBgRW1pdHRlcmAuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBFbWl0dGVyO1xuXG4vKipcbiAqIEluaXRpYWxpemUgYSBuZXcgYEVtaXR0ZXJgLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gRW1pdHRlcihvYmopIHtcbiAgaWYgKG9iaikgcmV0dXJuIG1peGluKG9iaik7XG59O1xuXG4vKipcbiAqIE1peGluIHRoZSBlbWl0dGVyIHByb3BlcnRpZXMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICogQHJldHVybiB7T2JqZWN0fVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gbWl4aW4ob2JqKSB7XG4gIGZvciAodmFyIGtleSBpbiBFbWl0dGVyLnByb3RvdHlwZSkge1xuICAgIG9ialtrZXldID0gRW1pdHRlci5wcm90b3R5cGVba2V5XTtcbiAgfVxuICByZXR1cm4gb2JqO1xufVxuXG4vKipcbiAqIExpc3RlbiBvbiB0aGUgZ2l2ZW4gYGV2ZW50YCB3aXRoIGBmbmAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHJldHVybiB7RW1pdHRlcn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuRW1pdHRlci5wcm90b3R5cGUub24gPVxuRW1pdHRlci5wcm90b3R5cGUuYWRkRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50LCBmbil7XG4gIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcbiAgKHRoaXMuX2NhbGxiYWNrc1snJCcgKyBldmVudF0gPSB0aGlzLl9jYWxsYmFja3NbJyQnICsgZXZlbnRdIHx8IFtdKVxuICAgIC5wdXNoKGZuKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEFkZHMgYW4gYGV2ZW50YCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBhIHNpbmdsZVxuICogdGltZSB0aGVuIGF1dG9tYXRpY2FsbHkgcmVtb3ZlZC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcmV0dXJuIHtFbWl0dGVyfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5FbWl0dGVyLnByb3RvdHlwZS5vbmNlID0gZnVuY3Rpb24oZXZlbnQsIGZuKXtcbiAgZnVuY3Rpb24gb24oKSB7XG4gICAgdGhpcy5vZmYoZXZlbnQsIG9uKTtcbiAgICBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgb24uZm4gPSBmbjtcbiAgdGhpcy5vbihldmVudCwgb24pO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogUmVtb3ZlIHRoZSBnaXZlbiBjYWxsYmFjayBmb3IgYGV2ZW50YCBvciBhbGxcbiAqIHJlZ2lzdGVyZWQgY2FsbGJhY2tzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqIEByZXR1cm4ge0VtaXR0ZXJ9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkVtaXR0ZXIucHJvdG90eXBlLm9mZiA9XG5FbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lciA9XG5FbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPVxuRW1pdHRlci5wcm90b3R5cGUucmVtb3ZlRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50LCBmbil7XG4gIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcblxuICAvLyBhbGxcbiAgaWYgKDAgPT0gYXJndW1lbnRzLmxlbmd0aCkge1xuICAgIHRoaXMuX2NhbGxiYWNrcyA9IHt9O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gc3BlY2lmaWMgZXZlbnRcbiAgdmFyIGNhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrc1snJCcgKyBldmVudF07XG4gIGlmICghY2FsbGJhY2tzKSByZXR1cm4gdGhpcztcblxuICAvLyByZW1vdmUgYWxsIGhhbmRsZXJzXG4gIGlmICgxID09IGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICBkZWxldGUgdGhpcy5fY2FsbGJhY2tzWyckJyArIGV2ZW50XTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIHJlbW92ZSBzcGVjaWZpYyBoYW5kbGVyXG4gIHZhciBjYjtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBjYWxsYmFja3MubGVuZ3RoOyBpKyspIHtcbiAgICBjYiA9IGNhbGxiYWNrc1tpXTtcbiAgICBpZiAoY2IgPT09IGZuIHx8IGNiLmZuID09PSBmbikge1xuICAgICAgY2FsbGJhY2tzLnNwbGljZShpLCAxKTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogRW1pdCBgZXZlbnRgIHdpdGggdGhlIGdpdmVuIGFyZ3MuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XG4gKiBAcGFyYW0ge01peGVkfSAuLi5cbiAqIEByZXR1cm4ge0VtaXR0ZXJ9XG4gKi9cblxuRW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uKGV2ZW50KXtcbiAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xuICB2YXIgYXJncyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKVxuICAgICwgY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzWyckJyArIGV2ZW50XTtcblxuICBpZiAoY2FsbGJhY2tzKSB7XG4gICAgY2FsbGJhY2tzID0gY2FsbGJhY2tzLnNsaWNlKDApO1xuICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBjYWxsYmFja3MubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgIGNhbGxiYWNrc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogUmV0dXJuIGFycmF5IG9mIGNhbGxiYWNrcyBmb3IgYGV2ZW50YC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEByZXR1cm4ge0FycmF5fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5FbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lcnMgPSBmdW5jdGlvbihldmVudCl7XG4gIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcbiAgcmV0dXJuIHRoaXMuX2NhbGxiYWNrc1snJCcgKyBldmVudF0gfHwgW107XG59O1xuXG4vKipcbiAqIENoZWNrIGlmIHRoaXMgZW1pdHRlciBoYXMgYGV2ZW50YCBoYW5kbGVycy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkVtaXR0ZXIucHJvdG90eXBlLmhhc0xpc3RlbmVycyA9IGZ1bmN0aW9uKGV2ZW50KXtcbiAgcmV0dXJuICEhIHRoaXMubGlzdGVuZXJzKGV2ZW50KS5sZW5ndGg7XG59O1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vY29tcG9uZW50LWVtaXR0ZXIvaW5kZXguanNcbiAqKiBtb2R1bGUgaWQgPSA3MFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciB0eXBlO1xudHJ5IHtcbiAgdHlwZSA9IHJlcXVpcmUoJ2NvbXBvbmVudC10eXBlJyk7XG59IGNhdGNoIChfKSB7XG4gIHR5cGUgPSByZXF1aXJlKCd0eXBlJyk7XG59XG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBjbG9uZTtcblxuLyoqXG4gKiBDbG9uZXMgb2JqZWN0cy5cbiAqXG4gKiBAcGFyYW0ge01peGVkfSBhbnkgb2JqZWN0XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGNsb25lKG9iail7XG4gIHN3aXRjaCAodHlwZShvYmopKSB7XG4gICAgY2FzZSAnb2JqZWN0JzpcbiAgICAgIHZhciBjb3B5ID0ge307XG4gICAgICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgICAgIGlmIChvYmouaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgIGNvcHlba2V5XSA9IGNsb25lKG9ialtrZXldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGNvcHk7XG5cbiAgICBjYXNlICdhcnJheSc6XG4gICAgICB2YXIgY29weSA9IG5ldyBBcnJheShvYmoubGVuZ3RoKTtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gb2JqLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICBjb3B5W2ldID0gY2xvbmUob2JqW2ldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjb3B5O1xuXG4gICAgY2FzZSAncmVnZXhwJzpcbiAgICAgIC8vIGZyb20gbWlsbGVybWVkZWlyb3MvYW1kLXV0aWxzIC0gTUlUXG4gICAgICB2YXIgZmxhZ3MgPSAnJztcbiAgICAgIGZsYWdzICs9IG9iai5tdWx0aWxpbmUgPyAnbScgOiAnJztcbiAgICAgIGZsYWdzICs9IG9iai5nbG9iYWwgPyAnZycgOiAnJztcbiAgICAgIGZsYWdzICs9IG9iai5pZ25vcmVDYXNlID8gJ2knIDogJyc7XG4gICAgICByZXR1cm4gbmV3IFJlZ0V4cChvYmouc291cmNlLCBmbGFncyk7XG5cbiAgICBjYXNlICdkYXRlJzpcbiAgICAgIHJldHVybiBuZXcgRGF0ZShvYmouZ2V0VGltZSgpKTtcblxuICAgIGRlZmF1bHQ6IC8vIHN0cmluZywgbnVtYmVyLCBib29sZWFuLCDigKZcbiAgICAgIHJldHVybiBvYmo7XG4gIH1cbn1cblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2NvbXBvbmVudC1jbG9uZS9pbmRleC5qc1xuICoqIG1vZHVsZSBpZCA9IDcxXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKipcbiAqIHRvU3RyaW5nIHJlZi5cbiAqL1xuXG52YXIgdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG4vKipcbiAqIFJldHVybiB0aGUgdHlwZSBvZiBgdmFsYC5cbiAqXG4gKiBAcGFyYW0ge01peGVkfSB2YWxcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqIEBhcGkgcHVibGljXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbih2YWwpe1xuICBzd2l0Y2ggKHRvU3RyaW5nLmNhbGwodmFsKSkge1xuICAgIGNhc2UgJ1tvYmplY3QgRGF0ZV0nOiByZXR1cm4gJ2RhdGUnO1xuICAgIGNhc2UgJ1tvYmplY3QgUmVnRXhwXSc6IHJldHVybiAncmVnZXhwJztcbiAgICBjYXNlICdbb2JqZWN0IEFyZ3VtZW50c10nOiByZXR1cm4gJ2FyZ3VtZW50cyc7XG4gICAgY2FzZSAnW29iamVjdCBBcnJheV0nOiByZXR1cm4gJ2FycmF5JztcbiAgICBjYXNlICdbb2JqZWN0IEVycm9yXSc6IHJldHVybiAnZXJyb3InO1xuICB9XG5cbiAgaWYgKHZhbCA9PT0gbnVsbCkgcmV0dXJuICdudWxsJztcbiAgaWYgKHZhbCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gJ3VuZGVmaW5lZCc7XG4gIGlmICh2YWwgIT09IHZhbCkgcmV0dXJuICduYW4nO1xuICBpZiAodmFsICYmIHZhbC5ub2RlVHlwZSA9PT0gMSkgcmV0dXJuICdlbGVtZW50JztcblxuICB2YWwgPSB2YWwudmFsdWVPZlxuICAgID8gdmFsLnZhbHVlT2YoKVxuICAgIDogT2JqZWN0LnByb3RvdHlwZS52YWx1ZU9mLmFwcGx5KHZhbClcblxuICByZXR1cm4gdHlwZW9mIHZhbDtcbn07XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9jb21wb25lbnQtdHlwZS9pbmRleC5qc1xuICoqIG1vZHVsZSBpZCA9IDcyXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJcbi8vIGVhc2luZyBmdW5jdGlvbnMgZnJvbSBcIlR3ZWVuLmpzXCJcblxuZXhwb3J0cy5saW5lYXIgPSBmdW5jdGlvbihuKXtcbiAgcmV0dXJuIG47XG59O1xuXG5leHBvcnRzLmluUXVhZCA9IGZ1bmN0aW9uKG4pe1xuICByZXR1cm4gbiAqIG47XG59O1xuXG5leHBvcnRzLm91dFF1YWQgPSBmdW5jdGlvbihuKXtcbiAgcmV0dXJuIG4gKiAoMiAtIG4pO1xufTtcblxuZXhwb3J0cy5pbk91dFF1YWQgPSBmdW5jdGlvbihuKXtcbiAgbiAqPSAyO1xuICBpZiAobiA8IDEpIHJldHVybiAwLjUgKiBuICogbjtcbiAgcmV0dXJuIC0gMC41ICogKC0tbiAqIChuIC0gMikgLSAxKTtcbn07XG5cbmV4cG9ydHMuaW5DdWJlID0gZnVuY3Rpb24obil7XG4gIHJldHVybiBuICogbiAqIG47XG59O1xuXG5leHBvcnRzLm91dEN1YmUgPSBmdW5jdGlvbihuKXtcbiAgcmV0dXJuIC0tbiAqIG4gKiBuICsgMTtcbn07XG5cbmV4cG9ydHMuaW5PdXRDdWJlID0gZnVuY3Rpb24obil7XG4gIG4gKj0gMjtcbiAgaWYgKG4gPCAxKSByZXR1cm4gMC41ICogbiAqIG4gKiBuO1xuICByZXR1cm4gMC41ICogKChuIC09IDIgKSAqIG4gKiBuICsgMik7XG59O1xuXG5leHBvcnRzLmluUXVhcnQgPSBmdW5jdGlvbihuKXtcbiAgcmV0dXJuIG4gKiBuICogbiAqIG47XG59O1xuXG5leHBvcnRzLm91dFF1YXJ0ID0gZnVuY3Rpb24obil7XG4gIHJldHVybiAxIC0gKC0tbiAqIG4gKiBuICogbik7XG59O1xuXG5leHBvcnRzLmluT3V0UXVhcnQgPSBmdW5jdGlvbihuKXtcbiAgbiAqPSAyO1xuICBpZiAobiA8IDEpIHJldHVybiAwLjUgKiBuICogbiAqIG4gKiBuO1xuICByZXR1cm4gLTAuNSAqICgobiAtPSAyKSAqIG4gKiBuICogbiAtIDIpO1xufTtcblxuZXhwb3J0cy5pblF1aW50ID0gZnVuY3Rpb24obil7XG4gIHJldHVybiBuICogbiAqIG4gKiBuICogbjtcbn1cblxuZXhwb3J0cy5vdXRRdWludCA9IGZ1bmN0aW9uKG4pe1xuICByZXR1cm4gLS1uICogbiAqIG4gKiBuICogbiArIDE7XG59XG5cbmV4cG9ydHMuaW5PdXRRdWludCA9IGZ1bmN0aW9uKG4pe1xuICBuICo9IDI7XG4gIGlmIChuIDwgMSkgcmV0dXJuIDAuNSAqIG4gKiBuICogbiAqIG4gKiBuO1xuICByZXR1cm4gMC41ICogKChuIC09IDIpICogbiAqIG4gKiBuICogbiArIDIpO1xufTtcblxuZXhwb3J0cy5pblNpbmUgPSBmdW5jdGlvbihuKXtcbiAgcmV0dXJuIDEgLSBNYXRoLmNvcyhuICogTWF0aC5QSSAvIDIgKTtcbn07XG5cbmV4cG9ydHMub3V0U2luZSA9IGZ1bmN0aW9uKG4pe1xuICByZXR1cm4gTWF0aC5zaW4obiAqIE1hdGguUEkgLyAyKTtcbn07XG5cbmV4cG9ydHMuaW5PdXRTaW5lID0gZnVuY3Rpb24obil7XG4gIHJldHVybiAuNSAqICgxIC0gTWF0aC5jb3MoTWF0aC5QSSAqIG4pKTtcbn07XG5cbmV4cG9ydHMuaW5FeHBvID0gZnVuY3Rpb24obil7XG4gIHJldHVybiAwID09IG4gPyAwIDogTWF0aC5wb3coMTAyNCwgbiAtIDEpO1xufTtcblxuZXhwb3J0cy5vdXRFeHBvID0gZnVuY3Rpb24obil7XG4gIHJldHVybiAxID09IG4gPyBuIDogMSAtIE1hdGgucG93KDIsIC0xMCAqIG4pO1xufTtcblxuZXhwb3J0cy5pbk91dEV4cG8gPSBmdW5jdGlvbihuKXtcbiAgaWYgKDAgPT0gbikgcmV0dXJuIDA7XG4gIGlmICgxID09IG4pIHJldHVybiAxO1xuICBpZiAoKG4gKj0gMikgPCAxKSByZXR1cm4gLjUgKiBNYXRoLnBvdygxMDI0LCBuIC0gMSk7XG4gIHJldHVybiAuNSAqICgtTWF0aC5wb3coMiwgLTEwICogKG4gLSAxKSkgKyAyKTtcbn07XG5cbmV4cG9ydHMuaW5DaXJjID0gZnVuY3Rpb24obil7XG4gIHJldHVybiAxIC0gTWF0aC5zcXJ0KDEgLSBuICogbik7XG59O1xuXG5leHBvcnRzLm91dENpcmMgPSBmdW5jdGlvbihuKXtcbiAgcmV0dXJuIE1hdGguc3FydCgxIC0gKC0tbiAqIG4pKTtcbn07XG5cbmV4cG9ydHMuaW5PdXRDaXJjID0gZnVuY3Rpb24obil7XG4gIG4gKj0gMlxuICBpZiAobiA8IDEpIHJldHVybiAtMC41ICogKE1hdGguc3FydCgxIC0gbiAqIG4pIC0gMSk7XG4gIHJldHVybiAwLjUgKiAoTWF0aC5zcXJ0KDEgLSAobiAtPSAyKSAqIG4pICsgMSk7XG59O1xuXG5leHBvcnRzLmluQmFjayA9IGZ1bmN0aW9uKG4pe1xuICB2YXIgcyA9IDEuNzAxNTg7XG4gIHJldHVybiBuICogbiAqICgoIHMgKyAxICkgKiBuIC0gcyk7XG59O1xuXG5leHBvcnRzLm91dEJhY2sgPSBmdW5jdGlvbihuKXtcbiAgdmFyIHMgPSAxLjcwMTU4O1xuICByZXR1cm4gLS1uICogbiAqICgocyArIDEpICogbiArIHMpICsgMTtcbn07XG5cbmV4cG9ydHMuaW5PdXRCYWNrID0gZnVuY3Rpb24obil7XG4gIHZhciBzID0gMS43MDE1OCAqIDEuNTI1O1xuICBpZiAoICggbiAqPSAyICkgPCAxICkgcmV0dXJuIDAuNSAqICggbiAqIG4gKiAoICggcyArIDEgKSAqIG4gLSBzICkgKTtcbiAgcmV0dXJuIDAuNSAqICggKCBuIC09IDIgKSAqIG4gKiAoICggcyArIDEgKSAqIG4gKyBzICkgKyAyICk7XG59O1xuXG5leHBvcnRzLmluQm91bmNlID0gZnVuY3Rpb24obil7XG4gIHJldHVybiAxIC0gZXhwb3J0cy5vdXRCb3VuY2UoMSAtIG4pO1xufTtcblxuZXhwb3J0cy5vdXRCb3VuY2UgPSBmdW5jdGlvbihuKXtcbiAgaWYgKCBuIDwgKCAxIC8gMi43NSApICkge1xuICAgIHJldHVybiA3LjU2MjUgKiBuICogbjtcbiAgfSBlbHNlIGlmICggbiA8ICggMiAvIDIuNzUgKSApIHtcbiAgICByZXR1cm4gNy41NjI1ICogKCBuIC09ICggMS41IC8gMi43NSApICkgKiBuICsgMC43NTtcbiAgfSBlbHNlIGlmICggbiA8ICggMi41IC8gMi43NSApICkge1xuICAgIHJldHVybiA3LjU2MjUgKiAoIG4gLT0gKCAyLjI1IC8gMi43NSApICkgKiBuICsgMC45Mzc1O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiA3LjU2MjUgKiAoIG4gLT0gKCAyLjYyNSAvIDIuNzUgKSApICogbiArIDAuOTg0Mzc1O1xuICB9XG59O1xuXG5leHBvcnRzLmluT3V0Qm91bmNlID0gZnVuY3Rpb24obil7XG4gIGlmIChuIDwgLjUpIHJldHVybiBleHBvcnRzLmluQm91bmNlKG4gKiAyKSAqIC41O1xuICByZXR1cm4gZXhwb3J0cy5vdXRCb3VuY2UobiAqIDIgLSAxKSAqIC41ICsgLjU7XG59O1xuXG4vLyBhbGlhc2VzXG5cbmV4cG9ydHNbJ2luLXF1YWQnXSA9IGV4cG9ydHMuaW5RdWFkO1xuZXhwb3J0c1snb3V0LXF1YWQnXSA9IGV4cG9ydHMub3V0UXVhZDtcbmV4cG9ydHNbJ2luLW91dC1xdWFkJ10gPSBleHBvcnRzLmluT3V0UXVhZDtcbmV4cG9ydHNbJ2luLWN1YmUnXSA9IGV4cG9ydHMuaW5DdWJlO1xuZXhwb3J0c1snb3V0LWN1YmUnXSA9IGV4cG9ydHMub3V0Q3ViZTtcbmV4cG9ydHNbJ2luLW91dC1jdWJlJ10gPSBleHBvcnRzLmluT3V0Q3ViZTtcbmV4cG9ydHNbJ2luLXF1YXJ0J10gPSBleHBvcnRzLmluUXVhcnQ7XG5leHBvcnRzWydvdXQtcXVhcnQnXSA9IGV4cG9ydHMub3V0UXVhcnQ7XG5leHBvcnRzWydpbi1vdXQtcXVhcnQnXSA9IGV4cG9ydHMuaW5PdXRRdWFydDtcbmV4cG9ydHNbJ2luLXF1aW50J10gPSBleHBvcnRzLmluUXVpbnQ7XG5leHBvcnRzWydvdXQtcXVpbnQnXSA9IGV4cG9ydHMub3V0UXVpbnQ7XG5leHBvcnRzWydpbi1vdXQtcXVpbnQnXSA9IGV4cG9ydHMuaW5PdXRRdWludDtcbmV4cG9ydHNbJ2luLXNpbmUnXSA9IGV4cG9ydHMuaW5TaW5lO1xuZXhwb3J0c1snb3V0LXNpbmUnXSA9IGV4cG9ydHMub3V0U2luZTtcbmV4cG9ydHNbJ2luLW91dC1zaW5lJ10gPSBleHBvcnRzLmluT3V0U2luZTtcbmV4cG9ydHNbJ2luLWV4cG8nXSA9IGV4cG9ydHMuaW5FeHBvO1xuZXhwb3J0c1snb3V0LWV4cG8nXSA9IGV4cG9ydHMub3V0RXhwbztcbmV4cG9ydHNbJ2luLW91dC1leHBvJ10gPSBleHBvcnRzLmluT3V0RXhwbztcbmV4cG9ydHNbJ2luLWNpcmMnXSA9IGV4cG9ydHMuaW5DaXJjO1xuZXhwb3J0c1snb3V0LWNpcmMnXSA9IGV4cG9ydHMub3V0Q2lyYztcbmV4cG9ydHNbJ2luLW91dC1jaXJjJ10gPSBleHBvcnRzLmluT3V0Q2lyYztcbmV4cG9ydHNbJ2luLWJhY2snXSA9IGV4cG9ydHMuaW5CYWNrO1xuZXhwb3J0c1snb3V0LWJhY2snXSA9IGV4cG9ydHMub3V0QmFjaztcbmV4cG9ydHNbJ2luLW91dC1iYWNrJ10gPSBleHBvcnRzLmluT3V0QmFjaztcbmV4cG9ydHNbJ2luLWJvdW5jZSddID0gZXhwb3J0cy5pbkJvdW5jZTtcbmV4cG9ydHNbJ291dC1ib3VuY2UnXSA9IGV4cG9ydHMub3V0Qm91bmNlO1xuZXhwb3J0c1snaW4tb3V0LWJvdW5jZSddID0gZXhwb3J0cy5pbk91dEJvdW5jZTtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2Vhc2UtY29tcG9uZW50L2luZGV4LmpzXG4gKiogbW9kdWxlIGlkID0gNzNcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIi8qKlxuICogRXhwb3NlIGByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKWAuXG4gKi9cblxuZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZVxuICB8fCB3aW5kb3cud2Via2l0UmVxdWVzdEFuaW1hdGlvbkZyYW1lXG4gIHx8IHdpbmRvdy5tb3pSZXF1ZXN0QW5pbWF0aW9uRnJhbWVcbiAgfHwgZmFsbGJhY2s7XG5cbi8qKlxuICogRmFsbGJhY2sgaW1wbGVtZW50YXRpb24uXG4gKi9cblxudmFyIHByZXYgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbmZ1bmN0aW9uIGZhbGxiYWNrKGZuKSB7XG4gIHZhciBjdXJyID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gIHZhciBtcyA9IE1hdGgubWF4KDAsIDE2IC0gKGN1cnIgLSBwcmV2KSk7XG4gIHZhciByZXEgPSBzZXRUaW1lb3V0KGZuLCBtcyk7XG4gIHByZXYgPSBjdXJyO1xuICByZXR1cm4gcmVxO1xufVxuXG4vKipcbiAqIENhbmNlbC5cbiAqL1xuXG52YXIgY2FuY2VsID0gd2luZG93LmNhbmNlbEFuaW1hdGlvbkZyYW1lXG4gIHx8IHdpbmRvdy53ZWJraXRDYW5jZWxBbmltYXRpb25GcmFtZVxuICB8fCB3aW5kb3cubW96Q2FuY2VsQW5pbWF0aW9uRnJhbWVcbiAgfHwgd2luZG93LmNsZWFyVGltZW91dDtcblxuZXhwb3J0cy5jYW5jZWwgPSBmdW5jdGlvbihpZCl7XG4gIGNhbmNlbC5jYWxsKHdpbmRvdywgaWQpO1xufTtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2NvbXBvbmVudC1yYWYvaW5kZXguanNcbiAqKiBtb2R1bGUgaWQgPSA3NFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnZhciBldmVudCA9IHtcbiAgLyoqXG4gICAqIG9wZW5VcmxcbiAgICogQHBhcmFtICB7c3RyaW5nfSB1cmxcbiAgICovXG4gIG9wZW5VUkw6IGZ1bmN0aW9uICh1cmwpIHtcbiAgICBsb2NhdGlvbi5ocmVmID0gdXJsXG4gIH1cblxufVxuXG5ldmVudC5fbWV0YSA9IHtcbiAgZXZlbnQ6IFt7XG4gICAgbmFtZTogJ29wZW5VUkwnLFxuICAgIGFyZ3M6IFsnc3RyaW5nJ11cbiAgfV1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBldmVudFxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvYXBpL2V2ZW50LmpzXG4gKiogbW9kdWxlIGlkID0gNzVcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIid1c2Ugc3RyaWN0J1xuXG52YXIgcGFnZUluZm8gPSB7XG5cbiAgc2V0VGl0bGU6IGZ1bmN0aW9uICh0aXRsZSkge1xuICAgIHRpdGxlID0gdGl0bGUgfHwgJ1dlZXggSFRNTDUnXG4gICAgdHJ5IHtcbiAgICAgIHRpdGxlID0gZGVjb2RlVVJJQ29tcG9uZW50KHRpdGxlKVxuICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgZG9jdW1lbnQudGl0bGUgPSB0aXRsZVxuICB9XG59XG5cbnBhZ2VJbmZvLl9tZXRhID0ge1xuICBwYWdlSW5mbzogW3tcbiAgICBuYW1lOiAnc2V0VGl0bGUnLFxuICAgIGFyZ3M6IFsnc3RyaW5nJ11cbiAgfV1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBwYWdlSW5mb1xuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvYXBpL3BhZ2VJbmZvLmpzXG4gKiogbW9kdWxlIGlkID0gNzZcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIid1c2Ugc3RyaWN0J1xuXG4vLyByZXF1aXJlKCdodHRwdXJsJylcblxuLy8gdmFyIGpzb25wQ250ID0gMFxuXG4vLyBmdW5jdGlvbiBfc2VuZEpzb25wKGNvbmZpZywgY2FsbGJhY2tJZCkge1xuLy8gICB2YXIgY2JOYW1lID0gJ19jYWxsYmFja18nICsgKCsranNvbnBDbnQpXG4vLyAgIHZhciBzY3JpcHQsIHVybCwgaGVhZFxuLy8gICBnbG9iYWxbY2JOYW1lXSA9IChmdW5jdGlvbiAoY2IpIHtcbi8vICAgICByZXR1cm4gZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4vLyAgICAgICB0aGlzLnNlbmRlci5wZXJmb3JtQ2FsbGJhY2soY2FsbGJhY2tJZCwgcmVzcG9uc2UpXG4vLyAgICAgICBkZWxldGUgZ2xvYmFsW2NiXVxuLy8gICAgIH1cbi8vICAgfSkoY2JOYW1lKVxuLy8gICBzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKVxuLy8gICB1cmwgPSBsaWIuaHR0cHVybChjb25maWcudXJsKVxuLy8gICB1cmwucGFyYW1zLmNhbGxiYWNrID0gY2JOYW1lXG4vLyAgIHNjcmlwdC50eXBlID0gJ3RleHQvamF2YXNjcmlwdCdcbi8vICAgc2NyaXB0LnNyYyA9IHVybC50b1N0cmluZygpXG4vLyAgIC8vIHNjcmlwdC5vbmVycm9yIGlzIG5vdCB3b3JraW5nIG9uIElFIG9yIHNhZmFyaS5cbi8vICAgLy8gYnV0IHRoZXkgYXJlIG5vdCBjb25zaWRlcmVkIGhlcmUuXG4vLyAgIHNjcmlwdC5vbmVycm9yID0gKGZ1bmN0aW9uIChjYikge1xuLy8gICAgIHJldHVybiBmdW5jdGlvbiAoZXJyKSB7XG4vLyAgICAgICB0aGlzLnNlbmRlci5wZXJmb3JtQ2FsbGJhY2soY2FsbGJhY2tJZCwgZXJyKVxuLy8gICAgICAgZGVsZXRlIGdsb2JhbFtjYl1cbi8vICAgICB9XG4vLyAgIH0pKGNiTmFtZSlcbi8vICAgaGVhZCA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdoZWFkJylbMF1cbi8vICAgaGVhZC5pbnNlcnRCZWZvcmUoc2NyaXB0LCBudWxsKVxuLy8gfVxuXG52YXIgc3RyZWFtID0ge1xuXG4gIC8qKlxuICAgKiBzZW5kSHR0cFxuICAgKiBAcGFyYW0gIHtvYmp9IHBhcmFtc1xuICAgKiAgLSBtZXRob2Q6ICdHRVQnIHwgJ1BPU1QnLFxuICAgKiAgLSB1cmw6IHVybCByZXF1ZXN0ZWRcbiAgICogQHBhcmFtICB7c3RyaW5nfSBjYWxsYmFja0lkXG4gICAqL1xuICBzZW5kSHR0cDogZnVuY3Rpb24gKHBhcmFtLCBjYWxsYmFja0lkKSB7XG4gICAgaWYgKHR5cGVvZiBwYXJhbSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHBhcmFtID0gSlNPTi5wYXJzZShwYXJhbSlcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG4gICAgfVxuICAgIGlmICh0eXBlb2YgcGFyYW0gIT09ICdvYmplY3QnIHx8ICFwYXJhbS51cmwpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIC8vIE5vdCB0byB1c2UganNvbnAgdG8gc2VuZCBodHRwIHJlcXVlc3Qgc2luY2UgaXQgcmVxdWlyZXMgdGhlIHNlcnZlclxuICAgIC8vIHRvIHN1cHBvcnQganNvbnAgY2FsbGJhY2sgYXQgdGhlIGZpcnN0IHBsYWNlLlxuICAgIC8vIF9zZW5kSnNvbnAuY2FsbCh0aGlzLCBwYXJhbSwgY2FsbGJhY2tJZClcblxuICAgIHZhciBzZWxmID0gdGhpc1xuICAgIHZhciBtZXRob2QgPSBwYXJhbS5tZXRob2QgfHwgJ0dFVCdcbiAgICB2YXIgeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KClcbiAgICB4aHIub3BlbihtZXRob2QsIHBhcmFtLnVybCwgdHJ1ZSlcbiAgICB4aHIub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgICAgc2VsZi5zZW5kZXIucGVyZm9ybUNhbGxiYWNrKGNhbGxiYWNrSWQsIHRoaXMucmVzcG9uc2VUZXh0KVxuICAgIH1cbiAgICB4aHIub25lcnJvciA9IGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgc2VsZi5zZW5kZXIucGVyZm9ybUNhbGxiYWNrKGNhbGxiYWNrSWQsIGVycm9yKVxuICAgIH1cbiAgICB4aHIuc2VuZCgpXG4gIH1cblxufVxuXG5zdHJlYW0uX21ldGEgPSB7XG4gIHN0cmVhbTogW3tcbiAgICBuYW1lOiAnc2VuZEh0dHAnLFxuICAgIGFyZ3M6IFsnb2JqZWN0JywgJ3N0cmluZyddXG4gIH1dXG59XG5cbm1vZHVsZS5leHBvcnRzID0gc3RyZWFtXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL3NyYy9hcGkvc3RyZWFtLmpzXG4gKiogbW9kdWxlIGlkID0gNzdcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIid1c2Ugc3RyaWN0J1xuXG52YXIgc2VuZGVyID0gcmVxdWlyZSgnLi4vYnJpZGdlL3NlbmRlcicpXG52YXIgbW9kYWwgPSByZXF1aXJlKCdtb2RhbHMnKVxuXG52YXIgbXNnID0ge1xuXG4gIC8vIGR1cmF0aW9uOiBkZWZhdWx0IGlzIDAuOCBzZWNvbmRzLlxuICB0b2FzdDogZnVuY3Rpb24gKGNvbmZpZykge1xuICAgIG1vZGFsLnRvYXN0KGNvbmZpZy5tZXNzYWdlLCBjb25maWcuZHVyYXRpb24pXG4gIH0sXG5cbiAgLy8gY29uZmlnOlxuICAvLyAgLSBtZXNzYWdlOiBzdHJpbmdcbiAgLy8gIC0gb2tUaXRsZTogdGl0bGUgb2Ygb2sgYnV0dG9uXG4gIC8vICAtIGNhbGxiYWNrXG4gIGFsZXJ0OiBmdW5jdGlvbiAoY29uZmlnLCBjYWxsYmFja0lkKSB7XG4gICAgdmFyIHNlbmRlciA9ICB0aGlzLnNlbmRlclxuICAgIGNvbmZpZy5jYWxsYmFjayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHNlbmRlci5wZXJmb3JtQ2FsbGJhY2soY2FsbGJhY2tJZClcbiAgICB9XG4gICAgbW9kYWwuYWxlcnQoY29uZmlnKVxuICB9LFxuXG4gIC8vIGNvbmZpZzpcbiAgLy8gIC0gbWVzc2FnZTogc3RyaW5nXG4gIC8vICAtIG9rVGl0bGU6IHRpdGxlIG9mIG9rIGJ1dHRvblxuICAvLyAgLSBjYW5jZWxUaXRsZTogdGl0bGUgb2YgY2FuY2VsIGJ1dHRvblxuICAvLyAgLSBjYWxsYmFja1xuICBjb25maXJtOiBmdW5jdGlvbiAoY29uZmlnLCBjYWxsYmFja0lkKSB7XG4gICAgdmFyIHNlbmRlciA9ICB0aGlzLnNlbmRlclxuICAgIGNvbmZpZy5jYWxsYmFjayA9IGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgIHNlbmRlci5wZXJmb3JtQ2FsbGJhY2soY2FsbGJhY2tJZCwgdmFsKVxuICAgIH1cbiAgICBtb2RhbC5jb25maXJtKGNvbmZpZylcbiAgfSxcblxuICAvLyBjb25maWc6XG4gIC8vICAtIG1lc3NhZ2U6IHN0cmluZ1xuICAvLyAgLSBva1RpdGxlOiB0aXRsZSBvZiBvayBidXR0b25cbiAgLy8gIC0gY2FuY2VsVGl0bGU6IHRpdGxlIG9mIGNhbmNlbCBidXR0b25cbiAgLy8gIC0gY2FsbGJhY2tcbiAgcHJvbXB0OiBmdW5jdGlvbiAoY29uZmlnLCBjYWxsYmFja0lkKSB7XG4gICAgdmFyIHNlbmRlciA9ICB0aGlzLnNlbmRlclxuICAgIGNvbmZpZy5jYWxsYmFjayA9IGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgIHNlbmRlci5wZXJmb3JtQ2FsbGJhY2soY2FsbGJhY2tJZCwgdmFsKVxuICAgIH1cbiAgICBtb2RhbC5wcm9tcHQoY29uZmlnKVxuICB9XG5cbn1cblxubXNnLl9tZXRhID0ge1xuICBtb2RhbDogW3tcbiAgICBuYW1lOiAndG9hc3QnLFxuICAgIGFyZ3M6IFsnb2JqZWN0J11cbiAgfSwge1xuICAgIG5hbWU6ICdhbGVydCcsXG4gICAgYXJnczogWydvYmplY3QnLCAnc3RyaW5nJ11cbiAgfSwge1xuICAgIG5hbWU6ICdjb25maXJtJyxcbiAgICBhcmdzOiBbJ29iamVjdCcsICdzdHJpbmcnXVxuICB9LCB7XG4gICAgbmFtZTogJ3Byb21wdCcsXG4gICAgYXJnczogWydvYmplY3QnLCAnc3RyaW5nJ11cbiAgfV1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBtc2dcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvYXBpL21vZGFsLmpzXG4gKiogbW9kdWxlIGlkID0gNzhcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIid1c2Ugc3RyaWN0J1xuXG52YXIgQWxlcnQgPSByZXF1aXJlKCcuL2FsZXJ0JylcbnZhciBDb25maXJtID0gcmVxdWlyZSgnLi9jb25maXJtJylcbnZhciBQcm9tcHQgPSByZXF1aXJlKCcuL3Byb21wdCcpXG52YXIgdG9hc3QgPSByZXF1aXJlKCcuL3RvYXN0JylcblxudmFyIG1vZGFsID0ge1xuXG4gIHRvYXN0OiBmdW5jdGlvbiAobXNnLCBkdXJhdGlvbikge1xuICAgIHRvYXN0LnB1c2gobXNnLCBkdXJhdGlvbilcbiAgfSxcblxuICBhbGVydDogZnVuY3Rpb24gKGNvbmZpZykge1xuICAgIG5ldyBBbGVydChjb25maWcpLnNob3coKVxuICB9LFxuXG4gIHByb21wdDogZnVuY3Rpb24gKGNvbmZpZykge1xuICAgIG5ldyBQcm9tcHQoY29uZmlnKS5zaG93KClcbiAgfSxcblxuICBjb25maXJtOiBmdW5jdGlvbiAoY29uZmlnKSB7XG4gICAgbmV3IENvbmZpcm0oY29uZmlnKS5zaG93KClcbiAgfVxuXG59XG5cbiF3aW5kb3cubGliICYmICh3aW5kb3cubGliID0ge30pXG53aW5kb3cubGliLm1vZGFsID0gbW9kYWxcblxubW9kdWxlLmV4cG9ydHMgPSBtb2RhbFxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L21vZGFscy9zcmMvaW5kZXguanNcbiAqKiBtb2R1bGUgaWQgPSA3OVxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnZhciBNb2RhbCA9IHJlcXVpcmUoJy4vbW9kYWwnKVxucmVxdWlyZSgnLi4vc3R5bGVzL2FsZXJ0LnNjc3MnKVxuXG52YXIgQ09OVEVOVF9DTEFTUyA9ICdjb250ZW50J1xudmFyIE1TR19DTEFTUyA9ICdjb250ZW50LW1zZydcbnZhciBCVVRUT05fR1JPVVBfQ0xBU1MgPSAnYnRuLWdyb3VwJ1xudmFyIEJVVFRPTl9DTEFTUyA9ICdidG4nXG5cbmZ1bmN0aW9uIEFsZXJ0KGNvbmZpZykge1xuICB0aGlzLm1zZyA9IGNvbmZpZy5tZXNzYWdlIHx8ICcnXG4gIHRoaXMuY2FsbGJhY2sgPSBjb25maWcuY2FsbGJhY2tcbiAgdGhpcy5va1RpdGxlID0gY29uZmlnLm9rVGl0bGUgfHwgJ09LJ1xuICBNb2RhbC5jYWxsKHRoaXMpXG4gIHRoaXMubm9kZS5jbGFzc0xpc3QuYWRkKCdhbWZlLWFsZXJ0Jylcbn1cblxuQWxlcnQucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShNb2RhbC5wcm90b3R5cGUpXG5cbkFsZXJ0LnByb3RvdHlwZS5jcmVhdGVOb2RlQ29udGVudCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGNvbnRlbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKVxuICBjb250ZW50LmNsYXNzTGlzdC5hZGQoQ09OVEVOVF9DTEFTUylcbiAgdGhpcy5ub2RlLmFwcGVuZENoaWxkKGNvbnRlbnQpXG5cbiAgdmFyIG1zZyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gIG1zZy5jbGFzc0xpc3QuYWRkKE1TR19DTEFTUylcbiAgbXNnLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHRoaXMubXNnKSlcbiAgY29udGVudC5hcHBlbmRDaGlsZChtc2cpXG5cbiAgdmFyIGJ1dHRvbkdyb3VwID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgYnV0dG9uR3JvdXAuY2xhc3NMaXN0LmFkZChCVVRUT05fR1JPVVBfQ0xBU1MpXG4gIHRoaXMubm9kZS5hcHBlbmRDaGlsZChidXR0b25Hcm91cClcbiAgdmFyIGJ1dHRvbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gIGJ1dHRvbi5jbGFzc0xpc3QuYWRkKEJVVFRPTl9DTEFTUywgJ2FsZXJ0LW9rJylcbiAgYnV0dG9uLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHRoaXMub2tUaXRsZSkpXG4gIGJ1dHRvbkdyb3VwLmFwcGVuZENoaWxkKGJ1dHRvbilcbn1cblxuQWxlcnQucHJvdG90eXBlLmJpbmRFdmVudHMgPSBmdW5jdGlvbiAoKSB7XG4gIE1vZGFsLnByb3RvdHlwZS5iaW5kRXZlbnRzLmNhbGwodGhpcylcbiAgdmFyIGJ1dHRvbiA9IHRoaXMubm9kZS5xdWVyeVNlbGVjdG9yKCcuJyArIEJVVFRPTl9DTEFTUylcbiAgYnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuZGVzdHJveSgpXG4gICAgdGhpcy5jYWxsYmFjayAmJiB0aGlzLmNhbGxiYWNrKClcbiAgfS5iaW5kKHRoaXMpKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEFsZXJ0XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9tb2RhbHMvc3JjL2FsZXJ0LmpzXG4gKiogbW9kdWxlIGlkID0gODBcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIid1c2Ugc3RyaWN0J1xuXG5yZXF1aXJlKCcuLi9zdHlsZXMvbW9kYWwuc2NzcycpXG5cbi8vIHRoZXJlIHdpbGwgYmUgb25seSBvbmUgaW5zdGFuY2Ugb2YgbW9kYWwuXG52YXIgTU9EQUxfV1JBUF9DTEFTUyA9ICdhbWZlLW1vZGFsLXdyYXAnXG52YXIgTU9EQUxfTk9ERV9DTEFTUyA9ICdhbWZlLW1vZGFsLW5vZGUnXG5cbmZ1bmN0aW9uIE1vZGFsKCkge1xuICB0aGlzLndyYXAgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKE1PREFMX1dSQVBfQ0xBU1MpXG4gIHRoaXMubm9kZSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoTU9EQUxfTk9ERV9DTEFTUylcbiAgaWYgKCF0aGlzLndyYXApIHtcbiAgICB0aGlzLmNyZWF0ZVdyYXAoKVxuICB9XG4gIGlmICghdGhpcy5ub2RlKSB7XG4gICAgdGhpcy5jcmVhdGVOb2RlKClcbiAgfVxuICB0aGlzLmNsZWFyTm9kZSgpXG4gIHRoaXMuY3JlYXRlTm9kZUNvbnRlbnQoKVxuICB0aGlzLmJpbmRFdmVudHMoKVxufVxuXG5Nb2RhbC5wcm90b3R5cGUgPSB7XG5cbiAgc2hvdzogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMud3JhcC5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJ1xuICAgIHRoaXMubm9kZS5jbGFzc0xpc3QucmVtb3ZlKCdoaWRlJylcbiAgfSxcblxuICBkZXN0cm95OiBmdW5jdGlvbiAoKSB7XG4gICAgZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZCh0aGlzLndyYXApXG4gICAgZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZCh0aGlzLm5vZGUpXG4gICAgdGhpcy53cmFwID0gbnVsbFxuICAgIHRoaXMubm9kZSA9IG51bGxcbiAgfSxcblxuICBjcmVhdGVXcmFwOiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy53cmFwID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgICB0aGlzLndyYXAuY2xhc3NOYW1lID0gTU9EQUxfV1JBUF9DTEFTU1xuICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodGhpcy53cmFwKVxuICB9LFxuXG4gIGNyZWF0ZU5vZGU6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLm5vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKVxuICAgIHRoaXMubm9kZS5jbGFzc0xpc3QuYWRkKE1PREFMX05PREVfQ0xBU1MsICdoaWRlJylcbiAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRoaXMubm9kZSlcbiAgfSxcblxuICBjbGVhck5vZGU6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLm5vZGUuaW5uZXJIVE1MID0gJydcbiAgfSxcblxuICBjcmVhdGVOb2RlQ29udGVudDogZnVuY3Rpb24gKCkge1xuXG4gICAgLy8gZG8gbm90aGluZy5cbiAgICAvLyBjaGlsZCBjbGFzc2VzIGNhbiBvdmVycmlkZSB0aGlzIG1ldGhvZC5cbiAgfSxcblxuICBiaW5kRXZlbnRzOiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy53cmFwLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKVxuICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKVxuICAgIH0pXG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBNb2RhbFxuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbW9kYWxzL3NyYy9tb2RhbC5qc1xuICoqIG1vZHVsZSBpZCA9IDgxXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvLyBzdHlsZS1sb2FkZXI6IEFkZHMgc29tZSBjc3MgdG8gdGhlIERPTSBieSBhZGRpbmcgYSA8c3R5bGU+IHRhZ1xuXG4vLyBsb2FkIHRoZSBzdHlsZXNcbnZhciBjb250ZW50ID0gcmVxdWlyZShcIiEhLi8uLi8uLi9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLy4uLy4uL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL21vZGFsLnNjc3NcIik7XG5pZih0eXBlb2YgY29udGVudCA9PT0gJ3N0cmluZycpIGNvbnRlbnQgPSBbW21vZHVsZS5pZCwgY29udGVudCwgJyddXTtcbi8vIGFkZCB0aGUgc3R5bGVzIHRvIHRoZSBET01cbnZhciB1cGRhdGUgPSByZXF1aXJlKFwiIS4vLi4vLi4vc3R5bGUtbG9hZGVyL2FkZFN0eWxlcy5qc1wiKShjb250ZW50LCB7fSk7XG5pZihjb250ZW50LmxvY2FscykgbW9kdWxlLmV4cG9ydHMgPSBjb250ZW50LmxvY2Fscztcbi8vIEhvdCBNb2R1bGUgUmVwbGFjZW1lbnRcbmlmKG1vZHVsZS5ob3QpIHtcblx0Ly8gV2hlbiB0aGUgc3R5bGVzIGNoYW5nZSwgdXBkYXRlIHRoZSA8c3R5bGU+IHRhZ3Ncblx0aWYoIWNvbnRlbnQubG9jYWxzKSB7XG5cdFx0bW9kdWxlLmhvdC5hY2NlcHQoXCIhIS4vLi4vLi4vY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi9zYXNzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi9tb2RhbC5zY3NzXCIsIGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIG5ld0NvbnRlbnQgPSByZXF1aXJlKFwiISEuLy4uLy4uL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vbW9kYWwuc2Nzc1wiKTtcblx0XHRcdGlmKHR5cGVvZiBuZXdDb250ZW50ID09PSAnc3RyaW5nJykgbmV3Q29udGVudCA9IFtbbW9kdWxlLmlkLCBuZXdDb250ZW50LCAnJ11dO1xuXHRcdFx0dXBkYXRlKG5ld0NvbnRlbnQpO1xuXHRcdH0pO1xuXHR9XG5cdC8vIFdoZW4gdGhlIG1vZHVsZSBpcyBkaXNwb3NlZCwgcmVtb3ZlIHRoZSA8c3R5bGU+IHRhZ3Ncblx0bW9kdWxlLmhvdC5kaXNwb3NlKGZ1bmN0aW9uKCkgeyB1cGRhdGUoKTsgfSk7XG59XG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbW9kYWxzL3N0eWxlcy9tb2RhbC5zY3NzXG4gKiogbW9kdWxlIGlkID0gODJcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsImV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuLy4uLy4uL2Nzcy1sb2FkZXIvbGliL2Nzcy1iYXNlLmpzXCIpKCk7XG4vLyBpbXBvcnRzXG5cblxuLy8gbW9kdWxlXG5leHBvcnRzLnB1c2goW21vZHVsZS5pZCwgXCIuYW1mZS1tb2RhbC13cmFwIHtcXG4gIGRpc3BsYXk6IG5vbmU7XFxuICBwb3NpdGlvbjogZml4ZWQ7XFxuICB6LWluZGV4OiA5OTk5OTk5OTk7XFxuICB0b3A6IDA7XFxuICBsZWZ0OiAwO1xcbiAgd2lkdGg6IDEwMCU7XFxuICBoZWlnaHQ6IDEwMCU7XFxuICBiYWNrZ3JvdW5kLWNvbG9yOiAjMDAwO1xcbiAgb3BhY2l0eTogMC41OyB9XFxuXFxuLmFtZmUtbW9kYWwtbm9kZSB7XFxuICBwb3NpdGlvbjogZml4ZWQ7XFxuICB6LWluZGV4OiA5OTk5OTk5OTk5O1xcbiAgdG9wOiA1MCU7XFxuICBsZWZ0OiA1MCU7XFxuICB3aWR0aDogNi42NjY2NjdyZW07XFxuICBtaW4taGVpZ2h0OiAyLjY2NjY2N3JlbTtcXG4gIGJvcmRlci1yYWRpdXM6IDAuMDY2NjY3cmVtO1xcbiAgLXdlYmtpdC10cmFuc2Zvcm06IHRyYW5zbGF0ZSgtNTAlLCAtNTAlKTtcXG4gIHRyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUsIC01MCUpO1xcbiAgYmFja2dyb3VuZC1jb2xvcjogI2ZmZjsgfVxcbiAgLmFtZmUtbW9kYWwtbm9kZS5oaWRlIHtcXG4gICAgZGlzcGxheTogbm9uZTsgfVxcbiAgLmFtZmUtbW9kYWwtbm9kZSAuY29udGVudCB7XFxuICAgIHdpZHRoOiAxMDAlO1xcbiAgICBtaW4taGVpZ2h0OiAxLjg2NjY2N3JlbTtcXG4gICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcXG4gICAgZm9udC1zaXplOiAwLjMycmVtO1xcbiAgICBsaW5lLWhlaWdodDogMC40MjY2NjdyZW07XFxuICAgIHBhZGRpbmc6IDAuMjEzMzMzcmVtO1xcbiAgICBib3JkZXItYm90dG9tOiAxcHggc29saWQgI2RkZDsgfVxcbiAgLmFtZmUtbW9kYWwtbm9kZSAuYnRuLWdyb3VwIHtcXG4gICAgd2lkdGg6IDEwMCU7XFxuICAgIGhlaWdodDogMC44cmVtO1xcbiAgICBmb250LXNpemU6IDAuMzczMzMzcmVtO1xcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7IH1cXG4gICAgLmFtZmUtbW9kYWwtbm9kZSAuYnRuLWdyb3VwIC5idG4ge1xcbiAgICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XFxuICAgICAgaGVpZ2h0OiAwLjhyZW07XFxuICAgICAgbGluZS1oZWlnaHQ6IDAuOHJlbTsgfVxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi9ub2RlX21vZHVsZXMvbW9kYWxzL25vZGVfbW9kdWxlcy9tb2RhbHMvc3R5bGVzL21vZGFsLnNjc3NcIl0sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIkFBQUE7RUFDRSxjQUFjO0VBQ2QsZ0JBQWdCO0VBQ2hCLG1CQUFtQjtFQUNuQixPQUFPO0VBQ1AsUUFBUTtFQUNSLFlBQVk7RUFDWixhQUFhO0VBQ2IsdUJBQXVCO0VBQ3ZCLGFBQWEsRUFFZDs7QUFFRDtFQUNFLGdCQUFnQjtFQUNoQixvQkFBb0I7RUFDcEIsU0FBUztFQUNULFVBQVU7RUFDVixtQkFBbUI7RUFDbkIsd0JBQXdCO0VBQ3hCLDJCQUEyQjtFQUMzQix5Q0FBNEI7RUFDNUIsaUNBQW9CO0VBQ3BCLHVCQUF1QixFQTRCeEI7RUF0Q0Q7SUFhSSxjQUNELEVBQUM7RUFkSjtJQWlCSSxZQUFZO0lBQ1osd0JBQXdCO0lBQ3hCLHVCQUF1QjtJQUN2QixtQkFBbUI7SUFDbkIseUJBQXlCO0lBQ3pCLHFCQUFxQjtJQUNyQiw4QkFBOEIsRUFDL0I7RUF4Qkg7SUEyQkksWUFBWTtJQUNaLGVBQWU7SUFDZix1QkFBdUI7SUFDdkIsbUJBQW1CLEVBT3BCO0lBckNIO01BaUNNLHVCQUF1QjtNQUN2QixlQUFlO01BQ2Ysb0JBQW9CLEVBQ3JCXCIsXCJmaWxlXCI6XCJtb2RhbC5zY3NzXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIi5hbWZlLW1vZGFsLXdyYXAge1xcbiAgZGlzcGxheTogbm9uZTtcXG4gIHBvc2l0aW9uOiBmaXhlZDtcXG4gIHotaW5kZXg6IDk5OTk5OTk5OTtcXG4gIHRvcDogMDtcXG4gIGxlZnQ6IDA7XFxuICB3aWR0aDogMTAwJTtcXG4gIGhlaWdodDogMTAwJTtcXG4gIGJhY2tncm91bmQtY29sb3I6ICMwMDA7XFxuICBvcGFjaXR5OiAwLjU7XFxuXFxufVxcblxcbi5hbWZlLW1vZGFsLW5vZGUge1xcbiAgcG9zaXRpb246IGZpeGVkO1xcbiAgei1pbmRleDogOTk5OTk5OTk5OTtcXG4gIHRvcDogNTAlO1xcbiAgbGVmdDogNTAlO1xcbiAgd2lkdGg6IDYuNjY2NjY3cmVtOyAvLyA1MDBweFxcbiAgbWluLWhlaWdodDogMi42NjY2NjdyZW07IC8vIDIwMHB4XFxuICBib3JkZXItcmFkaXVzOiAwLjA2NjY2N3JlbTsgLy8gNXB4XFxuICAtd2Via2l0LXRyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUsIC01MCUpO1xcbiAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoLTUwJSwgLTUwJSk7XFxuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmO1xcblxcbiAgJi5oaWRlIHtcXG4gICAgZGlzcGxheTogbm9uZVxcbiAgfVxcblxcbiAgLmNvbnRlbnQge1xcbiAgICB3aWR0aDogMTAwJTtcXG4gICAgbWluLWhlaWdodDogMS44NjY2NjdyZW07IC8vIDE0MHB4XFxuICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XFxuICAgIGZvbnQtc2l6ZTogMC4zMnJlbTsgLy8gMjRweFxcbiAgICBsaW5lLWhlaWdodDogMC40MjY2NjdyZW07IC8vIDMycHhcXG4gICAgcGFkZGluZzogMC4yMTMzMzNyZW07IC8vIDE2cHhcXG4gICAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkICNkZGQ7XFxuICB9XFxuXFxuICAuYnRuLWdyb3VwIHtcXG4gICAgd2lkdGg6IDEwMCU7XFxuICAgIGhlaWdodDogMC44cmVtOyAvLyA2MHB4XFxuICAgIGZvbnQtc2l6ZTogMC4zNzMzMzNyZW07IC8vIDI4cHhcXG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xcblxcbiAgICAuYnRuIHtcXG4gICAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xcbiAgICAgIGhlaWdodDogMC44cmVtOyAvLyA2MHB4XFxuICAgICAgbGluZS1oZWlnaHQ6IDAuOHJlbTsgLy8gNjBweFxcbiAgICB9XFxuICB9XFxufVxcblwiXSxcInNvdXJjZVJvb3RcIjpcIndlYnBhY2s6Ly9cIn1dKTtcblxuLy8gZXhwb3J0c1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi9+L3Nhc3MtbG9hZGVyP3NvdXJjZU1hcCEuL34vbW9kYWxzL3N0eWxlcy9tb2RhbC5zY3NzXG4gKiogbW9kdWxlIGlkID0gODNcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIi8vIHN0eWxlLWxvYWRlcjogQWRkcyBzb21lIGNzcyB0byB0aGUgRE9NIGJ5IGFkZGluZyBhIDxzdHlsZT4gdGFnXG5cbi8vIGxvYWQgdGhlIHN0eWxlc1xudmFyIGNvbnRlbnQgPSByZXF1aXJlKFwiISEuLy4uLy4uL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vYWxlcnQuc2Nzc1wiKTtcbmlmKHR5cGVvZiBjb250ZW50ID09PSAnc3RyaW5nJykgY29udGVudCA9IFtbbW9kdWxlLmlkLCBjb250ZW50LCAnJ11dO1xuLy8gYWRkIHRoZSBzdHlsZXMgdG8gdGhlIERPTVxudmFyIHVwZGF0ZSA9IHJlcXVpcmUoXCIhLi8uLi8uLi9zdHlsZS1sb2FkZXIvYWRkU3R5bGVzLmpzXCIpKGNvbnRlbnQsIHt9KTtcbmlmKGNvbnRlbnQubG9jYWxzKSBtb2R1bGUuZXhwb3J0cyA9IGNvbnRlbnQubG9jYWxzO1xuLy8gSG90IE1vZHVsZSBSZXBsYWNlbWVudFxuaWYobW9kdWxlLmhvdCkge1xuXHQvLyBXaGVuIHRoZSBzdHlsZXMgY2hhbmdlLCB1cGRhdGUgdGhlIDxzdHlsZT4gdGFnc1xuXHRpZighY29udGVudC5sb2NhbHMpIHtcblx0XHRtb2R1bGUuaG90LmFjY2VwdChcIiEhLi8uLi8uLi9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLy4uLy4uL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL2FsZXJ0LnNjc3NcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbmV3Q29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi9zYXNzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi9hbGVydC5zY3NzXCIpO1xuXHRcdFx0aWYodHlwZW9mIG5ld0NvbnRlbnQgPT09ICdzdHJpbmcnKSBuZXdDb250ZW50ID0gW1ttb2R1bGUuaWQsIG5ld0NvbnRlbnQsICcnXV07XG5cdFx0XHR1cGRhdGUobmV3Q29udGVudCk7XG5cdFx0fSk7XG5cdH1cblx0Ly8gV2hlbiB0aGUgbW9kdWxlIGlzIGRpc3Bvc2VkLCByZW1vdmUgdGhlIDxzdHlsZT4gdGFnc1xuXHRtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24oKSB7IHVwZGF0ZSgpOyB9KTtcbn1cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9tb2RhbHMvc3R5bGVzL2FsZXJ0LnNjc3NcbiAqKiBtb2R1bGUgaWQgPSA4NFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4vLi4vLi4vY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikoKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIi5hbWZlLWFsZXJ0IC5hbWZlLWFsZXJ0LW9rIHtcXG4gIHdpZHRoOiAxMDAlOyB9XFxuXCIsIFwiXCIsIHtcInZlcnNpb25cIjozLFwic291cmNlc1wiOltcIi8uL25vZGVfbW9kdWxlcy9tb2RhbHMvbm9kZV9tb2R1bGVzL21vZGFscy9zdHlsZXMvYWxlcnQuc2Nzc1wiXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiQUFBQTtFQUdJLFlBQVksRUFDYlwiLFwiZmlsZVwiOlwiYWxlcnQuc2Nzc1wiLFwic291cmNlc0NvbnRlbnRcIjpbXCIuYW1mZS1hbGVydCB7XFxuXFxuICAuYW1mZS1hbGVydC1vayB7XFxuICAgIHdpZHRoOiAxMDAlO1xcbiAgfVxcbn1cXG5cIl0sXCJzb3VyY2VSb290XCI6XCJ3ZWJwYWNrOi8vXCJ9XSk7XG5cbi8vIGV4cG9ydHNcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2Nzcy1sb2FkZXI/c291cmNlTWFwIS4vfi9zYXNzLWxvYWRlcj9zb3VyY2VNYXAhLi9+L21vZGFscy9zdHlsZXMvYWxlcnQuc2Nzc1xuICoqIG1vZHVsZSBpZCA9IDg1XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIndXNlIHN0cmljdCdcblxudmFyIE1vZGFsID0gcmVxdWlyZSgnLi9tb2RhbCcpXG5yZXF1aXJlKCcuLi9zdHlsZXMvY29uZmlybS5zY3NzJylcblxudmFyIENPTlRFTlRfQ0xBU1MgPSAnY29udGVudCdcbnZhciBNU0dfQ0xBU1MgPSAnY29udGVudC1tc2cnXG52YXIgQlVUVE9OX0dST1VQX0NMQVNTID0gJ2J0bi1ncm91cCdcbnZhciBCVVRUT05fQ0xBU1MgPSAnYnRuJ1xuXG5mdW5jdGlvbiBDb25maXJtKGNvbmZpZykge1xuICB0aGlzLm1zZyA9IGNvbmZpZy5tZXNzYWdlIHx8ICcnXG4gIHRoaXMuY2FsbGJhY2sgPSBjb25maWcuY2FsbGJhY2tcbiAgdGhpcy5va1RpdGxlID0gY29uZmlnLm9rVGl0bGUgfHwgJ09LJ1xuICB0aGlzLmNhbmNlbFRpdGxlID0gY29uZmlnLmNhbmNlbFRpdGxlIHx8ICdDYW5jZWwnXG4gIE1vZGFsLmNhbGwodGhpcylcbiAgdGhpcy5ub2RlLmNsYXNzTGlzdC5hZGQoJ2FtZmUtY29uZmlybScpXG59XG5cbkNvbmZpcm0ucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShNb2RhbC5wcm90b3R5cGUpXG5cbkNvbmZpcm0ucHJvdG90eXBlLmNyZWF0ZU5vZGVDb250ZW50ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgY29udGVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gIGNvbnRlbnQuY2xhc3NMaXN0LmFkZChDT05URU5UX0NMQVNTKVxuICB0aGlzLm5vZGUuYXBwZW5kQ2hpbGQoY29udGVudClcblxuICB2YXIgbXNnID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgbXNnLmNsYXNzTGlzdC5hZGQoTVNHX0NMQVNTKVxuICBtc2cuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUodGhpcy5tc2cpKVxuICBjb250ZW50LmFwcGVuZENoaWxkKG1zZylcblxuICB2YXIgYnV0dG9uR3JvdXAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKVxuICBidXR0b25Hcm91cC5jbGFzc0xpc3QuYWRkKEJVVFRPTl9HUk9VUF9DTEFTUylcbiAgdGhpcy5ub2RlLmFwcGVuZENoaWxkKGJ1dHRvbkdyb3VwKVxuICB2YXIgYnRuT2sgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKVxuICBidG5Pay5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSh0aGlzLm9rVGl0bGUpKVxuICBidG5Pay5jbGFzc0xpc3QuYWRkKCdidG4tb2snLCBCVVRUT05fQ0xBU1MpXG4gIHZhciBidG5DYW5jZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKVxuICBidG5DYW5jZWwuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUodGhpcy5jYW5jZWxUaXRsZSkpXG4gIGJ0bkNhbmNlbC5jbGFzc0xpc3QuYWRkKCdidG4tY2FuY2VsJywgQlVUVE9OX0NMQVNTKVxuICBidXR0b25Hcm91cC5hcHBlbmRDaGlsZChidG5PaylcbiAgYnV0dG9uR3JvdXAuYXBwZW5kQ2hpbGQoYnRuQ2FuY2VsKVxuICB0aGlzLm5vZGUuYXBwZW5kQ2hpbGQoYnV0dG9uR3JvdXApXG59XG5cbkNvbmZpcm0ucHJvdG90eXBlLmJpbmRFdmVudHMgPSBmdW5jdGlvbiAoKSB7XG4gIE1vZGFsLnByb3RvdHlwZS5iaW5kRXZlbnRzLmNhbGwodGhpcylcbiAgdmFyIGJ0bk9rID0gdGhpcy5ub2RlLnF1ZXJ5U2VsZWN0b3IoJy4nICsgQlVUVE9OX0NMQVNTICsgJy5idG4tb2snKVxuICB2YXIgYnRuQ2FuY2VsID0gdGhpcy5ub2RlLnF1ZXJ5U2VsZWN0b3IoJy4nICsgQlVUVE9OX0NMQVNTICsgJy5idG4tY2FuY2VsJylcbiAgYnRuT2suYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5kZXN0cm95KClcbiAgICB0aGlzLmNhbGxiYWNrICYmIHRoaXMuY2FsbGJhY2sodGhpcy5va1RpdGxlKVxuICB9LmJpbmQodGhpcykpXG4gIGJ0bkNhbmNlbC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmRlc3Ryb3koKVxuICAgIHRoaXMuY2FsbGJhY2sgJiYgdGhpcy5jYWxsYmFjayh0aGlzLmNhbmNlbFRpdGxlKVxuICB9LmJpbmQodGhpcykpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gQ29uZmlybVxuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbW9kYWxzL3NyYy9jb25maXJtLmpzXG4gKiogbW9kdWxlIGlkID0gODZcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIi8vIHN0eWxlLWxvYWRlcjogQWRkcyBzb21lIGNzcyB0byB0aGUgRE9NIGJ5IGFkZGluZyBhIDxzdHlsZT4gdGFnXG5cbi8vIGxvYWQgdGhlIHN0eWxlc1xudmFyIGNvbnRlbnQgPSByZXF1aXJlKFwiISEuLy4uLy4uL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vY29uZmlybS5zY3NzXCIpO1xuaWYodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSBjb250ZW50ID0gW1ttb2R1bGUuaWQsIGNvbnRlbnQsICcnXV07XG4vLyBhZGQgdGhlIHN0eWxlcyB0byB0aGUgRE9NXG52YXIgdXBkYXRlID0gcmVxdWlyZShcIiEuLy4uLy4uL3N0eWxlLWxvYWRlci9hZGRTdHlsZXMuanNcIikoY29udGVudCwge30pO1xuaWYoY29udGVudC5sb2NhbHMpIG1vZHVsZS5leHBvcnRzID0gY29udGVudC5sb2NhbHM7XG4vLyBIb3QgTW9kdWxlIFJlcGxhY2VtZW50XG5pZihtb2R1bGUuaG90KSB7XG5cdC8vIFdoZW4gdGhlIHN0eWxlcyBjaGFuZ2UsIHVwZGF0ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdGlmKCFjb250ZW50LmxvY2Fscykge1xuXHRcdG1vZHVsZS5ob3QuYWNjZXB0KFwiISEuLy4uLy4uL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vY29uZmlybS5zY3NzXCIsIGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIG5ld0NvbnRlbnQgPSByZXF1aXJlKFwiISEuLy4uLy4uL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vY29uZmlybS5zY3NzXCIpO1xuXHRcdFx0aWYodHlwZW9mIG5ld0NvbnRlbnQgPT09ICdzdHJpbmcnKSBuZXdDb250ZW50ID0gW1ttb2R1bGUuaWQsIG5ld0NvbnRlbnQsICcnXV07XG5cdFx0XHR1cGRhdGUobmV3Q29udGVudCk7XG5cdFx0fSk7XG5cdH1cblx0Ly8gV2hlbiB0aGUgbW9kdWxlIGlzIGRpc3Bvc2VkLCByZW1vdmUgdGhlIDxzdHlsZT4gdGFnc1xuXHRtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24oKSB7IHVwZGF0ZSgpOyB9KTtcbn1cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9tb2RhbHMvc3R5bGVzL2NvbmZpcm0uc2Nzc1xuICoqIG1vZHVsZSBpZCA9IDg3XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi8uLi8uLi9jc3MtbG9hZGVyL2xpYi9jc3MtYmFzZS5qc1wiKSgpO1xuLy8gaW1wb3J0c1xuXG5cbi8vIG1vZHVsZVxuZXhwb3J0cy5wdXNoKFttb2R1bGUuaWQsIFwiLmFtZmUtY29uZmlybSAuYnRuLWdyb3VwIC5idG4ge1xcbiAgZmxvYXQ6IGxlZnQ7XFxuICB3aWR0aDogNTAlOyB9XFxuICAuYW1mZS1jb25maXJtIC5idG4tZ3JvdXAgLmJ0bi5idG4tb2sge1xcbiAgICBib3JkZXItcmlnaHQ6IDFweCBzb2xpZCAjZGRkOyB9XFxuXCIsIFwiXCIsIHtcInZlcnNpb25cIjozLFwic291cmNlc1wiOltcIi8uL25vZGVfbW9kdWxlcy9tb2RhbHMvbm9kZV9tb2R1bGVzL21vZGFscy9zdHlsZXMvY29uZmlybS5zY3NzXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCJBQUFBO0VBS00sWUFBWTtFQUNaLFdBQVcsRUFLWjtFQVhMO0lBU08sNkJBQTZCLEVBQzdCXCIsXCJmaWxlXCI6XCJjb25maXJtLnNjc3NcIixcInNvdXJjZXNDb250ZW50XCI6W1wiLmFtZmUtY29uZmlybSB7XFxuXFxuICAuYnRuLWdyb3VwIHtcXG5cXG4gICAgLmJ0biB7XFxuICAgICAgZmxvYXQ6IGxlZnQ7XFxuICAgICAgd2lkdGg6IDUwJTtcXG5cXG4gICAgICAmLmJ0bi1vayB7XFxuICAgICAgXFx0Ym9yZGVyLXJpZ2h0OiAxcHggc29saWQgI2RkZDtcXG4gICAgICB9XFxuICAgIH1cXG4gIH1cXG59XCJdLFwic291cmNlUm9vdFwiOlwid2VicGFjazovL1wifV0pO1xuXG4vLyBleHBvcnRzXG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL34vc2Fzcy1sb2FkZXI/c291cmNlTWFwIS4vfi9tb2RhbHMvc3R5bGVzL2NvbmZpcm0uc2Nzc1xuICoqIG1vZHVsZSBpZCA9IDg4XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIndXNlIHN0cmljdCdcblxudmFyIE1vZGFsID0gcmVxdWlyZSgnLi9tb2RhbCcpXG5yZXF1aXJlKCcuLi9zdHlsZXMvcHJvbXB0LnNjc3MnKVxuXG52YXIgQ09OVEVOVF9DTEFTUyA9ICdjb250ZW50J1xudmFyIE1TR19DTEFTUyA9ICdjb250ZW50LW1zZydcbnZhciBCVVRUT05fR1JPVVBfQ0xBU1MgPSAnYnRuLWdyb3VwJ1xudmFyIEJVVFRPTl9DTEFTUyA9ICdidG4nXG52YXIgSU5QVVRfV1JBUF9DTEFTUyA9ICdpbnB1dC13cmFwJ1xudmFyIElOUFVUX0NMQVNTID0gJ2lucHV0J1xuXG5mdW5jdGlvbiBQcm9tcHQoY29uZmlnKSB7XG4gIHRoaXMubXNnID0gY29uZmlnLm1lc3NhZ2UgfHwgJydcbiAgdGhpcy5kZWZhdWx0TXNnID0gY29uZmlnLmRlZmF1bHQgfHwgJydcbiAgdGhpcy5jYWxsYmFjayA9IGNvbmZpZy5jYWxsYmFja1xuICB0aGlzLm9rVGl0bGUgPSBjb25maWcub2tUaXRsZSB8fCAnT0snXG4gIHRoaXMuY2FuY2VsVGl0bGUgPSBjb25maWcuY2FuY2VsVGl0bGUgfHwgJ0NhbmNlbCdcbiAgTW9kYWwuY2FsbCh0aGlzKVxuICB0aGlzLm5vZGUuY2xhc3NMaXN0LmFkZCgnYW1mZS1wcm9tcHQnKVxufVxuXG5Qcm9tcHQucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShNb2RhbC5wcm90b3R5cGUpXG5cblByb21wdC5wcm90b3R5cGUuY3JlYXRlTm9kZUNvbnRlbnQgPSBmdW5jdGlvbiAoKSB7XG5cbiAgdmFyIGNvbnRlbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKVxuICBjb250ZW50LmNsYXNzTGlzdC5hZGQoQ09OVEVOVF9DTEFTUylcbiAgdGhpcy5ub2RlLmFwcGVuZENoaWxkKGNvbnRlbnQpXG5cbiAgdmFyIG1zZyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gIG1zZy5jbGFzc0xpc3QuYWRkKE1TR19DTEFTUylcbiAgbXNnLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHRoaXMubXNnKSlcbiAgY29udGVudC5hcHBlbmRDaGlsZChtc2cpXG5cbiAgdmFyIGlucHV0V3JhcCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gIGlucHV0V3JhcC5jbGFzc0xpc3QuYWRkKElOUFVUX1dSQVBfQ0xBU1MpXG4gIGNvbnRlbnQuYXBwZW5kQ2hpbGQoaW5wdXRXcmFwKVxuICB2YXIgaW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbnB1dCcpXG4gIGlucHV0LmNsYXNzTGlzdC5hZGQoSU5QVVRfQ0xBU1MpXG4gIGlucHV0LnR5cGUgPSAndGV4dCdcbiAgaW5wdXQuYXV0b2ZvY3VzID0gdHJ1ZVxuICBpbnB1dC5wbGFjZWhvbGRlciA9IHRoaXMuZGVmYXVsdE1zZ1xuICBpbnB1dFdyYXAuYXBwZW5kQ2hpbGQoaW5wdXQpXG5cbiAgdmFyIGJ1dHRvbkdyb3VwID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgYnV0dG9uR3JvdXAuY2xhc3NMaXN0LmFkZChCVVRUT05fR1JPVVBfQ0xBU1MpXG4gIHZhciBidG5PayA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gIGJ0bk9rLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHRoaXMub2tUaXRsZSkpXG4gIGJ0bk9rLmNsYXNzTGlzdC5hZGQoJ2J0bi1vaycsIEJVVFRPTl9DTEFTUylcbiAgdmFyIGJ0bkNhbmNlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gIGJ0bkNhbmNlbC5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSh0aGlzLmNhbmNlbFRpdGxlKSlcbiAgYnRuQ2FuY2VsLmNsYXNzTGlzdC5hZGQoJ2J0bi1jYW5jZWwnLCBCVVRUT05fQ0xBU1MpXG4gIGJ1dHRvbkdyb3VwLmFwcGVuZENoaWxkKGJ0bk9rKVxuICBidXR0b25Hcm91cC5hcHBlbmRDaGlsZChidG5DYW5jZWwpXG4gIHRoaXMubm9kZS5hcHBlbmRDaGlsZChidXR0b25Hcm91cClcbn1cblxuUHJvbXB0LnByb3RvdHlwZS5iaW5kRXZlbnRzID0gZnVuY3Rpb24gKCkge1xuICBNb2RhbC5wcm90b3R5cGUuYmluZEV2ZW50cy5jYWxsKHRoaXMpXG4gIHZhciBidG5PayA9IHRoaXMubm9kZS5xdWVyeVNlbGVjdG9yKCcuJyArIEJVVFRPTl9DTEFTUyArICcuYnRuLW9rJylcbiAgdmFyIGJ0bkNhbmNlbCA9IHRoaXMubm9kZS5xdWVyeVNlbGVjdG9yKCcuJyArIEJVVFRPTl9DTEFTUyArICcuYnRuLWNhbmNlbCcpXG4gIHZhciB0aGF0ID0gdGhpc1xuICBidG5Pay5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgdmFsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignaW5wdXQnKS52YWx1ZVxuICAgIHRoaXMuZGVzdHJveSgpXG4gICAgdGhpcy5jYWxsYmFjayAmJiB0aGlzLmNhbGxiYWNrKHtcbiAgICAgIHJlc3VsdDogdGhhdC5va1RpdGxlLFxuICAgICAgZGF0YTogdmFsXG4gICAgfSlcbiAgfS5iaW5kKHRoaXMpKVxuICBidG5DYW5jZWwuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHZhbCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2lucHV0JykudmFsdWVcbiAgICB0aGlzLmRlc3Ryb3koKVxuICAgIHRoaXMuY2FsbGJhY2sgJiYgdGhpcy5jYWxsYmFjayh7XG4gICAgICByZXN1bHQ6IHRoYXQuY2FuY2VsVGl0bGVcbiAgICB9KVxuICB9LmJpbmQodGhpcykpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gUHJvbXB0XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9tb2RhbHMvc3JjL3Byb21wdC5qc1xuICoqIG1vZHVsZSBpZCA9IDg5XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvLyBzdHlsZS1sb2FkZXI6IEFkZHMgc29tZSBjc3MgdG8gdGhlIERPTSBieSBhZGRpbmcgYSA8c3R5bGU+IHRhZ1xuXG4vLyBsb2FkIHRoZSBzdHlsZXNcbnZhciBjb250ZW50ID0gcmVxdWlyZShcIiEhLi8uLi8uLi9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLy4uLy4uL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL3Byb21wdC5zY3NzXCIpO1xuaWYodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSBjb250ZW50ID0gW1ttb2R1bGUuaWQsIGNvbnRlbnQsICcnXV07XG4vLyBhZGQgdGhlIHN0eWxlcyB0byB0aGUgRE9NXG52YXIgdXBkYXRlID0gcmVxdWlyZShcIiEuLy4uLy4uL3N0eWxlLWxvYWRlci9hZGRTdHlsZXMuanNcIikoY29udGVudCwge30pO1xuaWYoY29udGVudC5sb2NhbHMpIG1vZHVsZS5leHBvcnRzID0gY29udGVudC5sb2NhbHM7XG4vLyBIb3QgTW9kdWxlIFJlcGxhY2VtZW50XG5pZihtb2R1bGUuaG90KSB7XG5cdC8vIFdoZW4gdGhlIHN0eWxlcyBjaGFuZ2UsIHVwZGF0ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdGlmKCFjb250ZW50LmxvY2Fscykge1xuXHRcdG1vZHVsZS5ob3QuYWNjZXB0KFwiISEuLy4uLy4uL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vcHJvbXB0LnNjc3NcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbmV3Q29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi9zYXNzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi9wcm9tcHQuc2Nzc1wiKTtcblx0XHRcdGlmKHR5cGVvZiBuZXdDb250ZW50ID09PSAnc3RyaW5nJykgbmV3Q29udGVudCA9IFtbbW9kdWxlLmlkLCBuZXdDb250ZW50LCAnJ11dO1xuXHRcdFx0dXBkYXRlKG5ld0NvbnRlbnQpO1xuXHRcdH0pO1xuXHR9XG5cdC8vIFdoZW4gdGhlIG1vZHVsZSBpcyBkaXNwb3NlZCwgcmVtb3ZlIHRoZSA8c3R5bGU+IHRhZ3Ncblx0bW9kdWxlLmhvdC5kaXNwb3NlKGZ1bmN0aW9uKCkgeyB1cGRhdGUoKTsgfSk7XG59XG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbW9kYWxzL3N0eWxlcy9wcm9tcHQuc2Nzc1xuICoqIG1vZHVsZSBpZCA9IDkwXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi8uLi8uLi9jc3MtbG9hZGVyL2xpYi9jc3MtYmFzZS5qc1wiKSgpO1xuLy8gaW1wb3J0c1xuXG5cbi8vIG1vZHVsZVxuZXhwb3J0cy5wdXNoKFttb2R1bGUuaWQsIFwiLmFtZmUtcHJvbXB0IC5pbnB1dC13cmFwIHtcXG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XFxuICB3aWR0aDogMTAwJTtcXG4gIHBhZGRpbmc6IDAuMjRyZW0gMC4yMTMzMzNyZW0gMC4yMTMzMzNyZW07XFxuICBoZWlnaHQ6IDAuOTZyZW07IH1cXG4gIC5hbWZlLXByb21wdCAuaW5wdXQtd3JhcCAuaW5wdXQge1xcbiAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xcbiAgICB3aWR0aDogMTAwJTtcXG4gICAgaGVpZ2h0OiAwLjU2cmVtO1xcbiAgICBsaW5lLWhlaWdodDogMC41NnJlbTtcXG4gICAgZm9udC1zaXplOiAwLjMycmVtOyB9XFxuXFxuLmFtZmUtcHJvbXB0IC5idG4tZ3JvdXAgLmJ0biB7XFxuICBmbG9hdDogbGVmdDtcXG4gIHdpZHRoOiA1MCU7IH1cXG4gIC5hbWZlLXByb21wdCAuYnRuLWdyb3VwIC5idG4uYnRuLW9rIHtcXG4gICAgYm9yZGVyLXJpZ2h0OiAxcHggc29saWQgI2RkZDsgfVxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi9ub2RlX21vZHVsZXMvbW9kYWxzL25vZGVfbW9kdWxlcy9tb2RhbHMvc3R5bGVzL3Byb21wdC5zY3NzXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCJBQUFBO0VBR0ksdUJBQXVCO0VBQ3ZCLFlBQVk7RUFDWix5Q0FBeUM7RUFDekMsZ0JBQWdCLEVBU2pCO0VBZkg7SUFTTSx1QkFBdUI7SUFDdkIsWUFBWTtJQUNaLGdCQUFnQjtJQUNoQixxQkFBcUI7SUFDckIsbUJBQW1CLEVBQ3BCOztBQWRMO0VBb0JNLFlBQVk7RUFDWixXQUFXLEVBS1o7RUExQkw7SUF3QlEsNkJBQTZCLEVBQzlCXCIsXCJmaWxlXCI6XCJwcm9tcHQuc2Nzc1wiLFwic291cmNlc0NvbnRlbnRcIjpbXCIuYW1mZS1wcm9tcHQge1xcblxcbiAgLmlucHV0LXdyYXAge1xcbiAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xcbiAgICB3aWR0aDogMTAwJTtcXG4gICAgcGFkZGluZzogMC4yNHJlbSAwLjIxMzMzM3JlbSAwLjIxMzMzM3JlbTsgLy8gMThweCAxNnB4IDE2cHhcXG4gICAgaGVpZ2h0OiAwLjk2cmVtOyAvLyA3NHB4XFxuXFxuICAgIC5pbnB1dCB7XFxuICAgICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcXG4gICAgICB3aWR0aDogMTAwJTtcXG4gICAgICBoZWlnaHQ6IDAuNTZyZW07IC8vIDQycHhcXG4gICAgICBsaW5lLWhlaWdodDogMC41NnJlbTsgLy8gNDJweFxcbiAgICAgIGZvbnQtc2l6ZTogMC4zMnJlbTsgLy8gMjRweFxcbiAgICB9XFxuICB9XFxuXFxuICAuYnRuLWdyb3VwIHtcXG5cXG4gICAgLmJ0biB7XFxuICAgICAgZmxvYXQ6IGxlZnQ7XFxuICAgICAgd2lkdGg6IDUwJTtcXG5cXG4gICAgICAmLmJ0bi1vayB7XFxuICAgICAgICBib3JkZXItcmlnaHQ6IDFweCBzb2xpZCAjZGRkO1xcbiAgICAgIH1cXG4gICAgfVxcbiAgfVxcbn1cIl0sXCJzb3VyY2VSb290XCI6XCJ3ZWJwYWNrOi8vXCJ9XSk7XG5cbi8vIGV4cG9ydHNcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2Nzcy1sb2FkZXI/c291cmNlTWFwIS4vfi9zYXNzLWxvYWRlcj9zb3VyY2VNYXAhLi9+L21vZGFscy9zdHlsZXMvcHJvbXB0LnNjc3NcbiAqKiBtb2R1bGUgaWQgPSA5MVxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnJlcXVpcmUoJy4uL3N0eWxlcy90b2FzdC5zY3NzJylcblxudmFyIHF1ZXVlID0gW11cbnZhciB0aW1lclxudmFyIGlzUHJvY2Vzc2luZyA9IGZhbHNlXG52YXIgdG9hc3RXaW5cbnZhciBUT0FTVF9XSU5fQ0xBU1NfTkFNRSA9ICdhbWZlLXRvYXN0J1xuXG52YXIgREVGQVVMVF9EVVJBVElPTiA9IDAuOFxuXG5mdW5jdGlvbiBzaG93VG9hc3RXaW5kb3cobXNnLCBjYWxsYmFjaykge1xuICB2YXIgaGFuZGxlVHJhbnNpdGlvbkVuZCA9IGZ1bmN0aW9uICgpIHtcbiAgICB0b2FzdFdpbi5yZW1vdmVFdmVudExpc3RlbmVyKCd0cmFuc2l0aW9uZW5kJywgaGFuZGxlVHJhbnNpdGlvbkVuZClcbiAgICBjYWxsYmFjayAmJiBjYWxsYmFjaygpXG4gIH1cbiAgaWYgKCF0b2FzdFdpbikge1xuICAgIHRvYXN0V2luID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgICB0b2FzdFdpbi5jbGFzc0xpc3QuYWRkKFRPQVNUX1dJTl9DTEFTU19OQU1FLCAnaGlkZScpXG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCh0b2FzdFdpbilcbiAgfVxuICB0b2FzdFdpbi5pbm5lckhUTUwgPSBtc2dcbiAgdG9hc3RXaW4uYWRkRXZlbnRMaXN0ZW5lcigndHJhbnNpdGlvbmVuZCcsIGhhbmRsZVRyYW5zaXRpb25FbmQpXG4gIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgIHRvYXN0V2luLmNsYXNzTGlzdC5yZW1vdmUoJ2hpZGUnKVxuICB9LCAwKVxufVxuXG5mdW5jdGlvbiBoaWRlVG9hc3RXaW5kb3coY2FsbGJhY2spIHtcbiAgdmFyIGhhbmRsZVRyYW5zaXRpb25FbmQgPSBmdW5jdGlvbiAoKSB7XG4gICAgdG9hc3RXaW4ucmVtb3ZlRXZlbnRMaXN0ZW5lcigndHJhbnNpdGlvbmVuZCcsIGhhbmRsZVRyYW5zaXRpb25FbmQpXG4gICAgY2FsbGJhY2sgJiYgY2FsbGJhY2soKVxuICB9XG4gIGlmICghdG9hc3RXaW4pIHtcbiAgICByZXR1cm5cbiAgfVxuICB0b2FzdFdpbi5hZGRFdmVudExpc3RlbmVyKCd0cmFuc2l0aW9uZW5kJywgaGFuZGxlVHJhbnNpdGlvbkVuZClcbiAgdG9hc3RXaW4uY2xhc3NMaXN0LmFkZCgnaGlkZScpXG59XG5cbnZhciB0b2FzdCA9IHtcblxuICBwdXNoOiBmdW5jdGlvbiAobXNnLCBkdXJhdGlvbikge1xuICAgIHF1ZXVlLnB1c2goe1xuICAgICAgbXNnOiBtc2csXG4gICAgICBkdXJhdGlvbjogZHVyYXRpb24gfHwgREVGQVVMVF9EVVJBVElPTlxuICAgIH0pXG4gICAgdGhpcy5zaG93KClcbiAgfSxcblxuICBzaG93OiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHRoYXQgPSB0aGlzXG5cbiAgICAvLyBBbGwgbWVzc2FnZXMgaGFkIGJlZW4gdG9hc3RlZCBhbHJlYWR5LCBzbyByZW1vdmUgdGhlIHRvYXN0IHdpbmRvdyxcbiAgICBpZiAoIXF1ZXVlLmxlbmd0aCkge1xuICAgICAgdG9hc3RXaW4gJiYgdG9hc3RXaW4ucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0b2FzdFdpbilcbiAgICAgIHRvYXN0V2luID0gbnVsbFxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgLy8gdGhlIHByZXZpb3VzIHRvYXN0IGlzIG5vdCBlbmRlZCB5ZXQuXG4gICAgaWYgKGlzUHJvY2Vzc2luZykge1xuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIGlzUHJvY2Vzc2luZyA9IHRydWVcblxuICAgIHZhciB0b2FzdEluZm8gPSBxdWV1ZS5zaGlmdCgpXG4gICAgc2hvd1RvYXN0V2luZG93KHRvYXN0SW5mby5tc2csIGZ1bmN0aW9uICgpIHtcbiAgICAgIHRpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRpbWVyID0gbnVsbFxuICAgICAgICBoaWRlVG9hc3RXaW5kb3coZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGlzUHJvY2Vzc2luZyA9IGZhbHNlXG4gICAgICAgICAgdGhhdC5zaG93KClcbiAgICAgICAgfSlcbiAgICAgIH0sIHRvYXN0SW5mby5kdXJhdGlvbiAqIDEwMDApXG4gICAgfSlcbiAgfVxuXG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBwdXNoOiB0b2FzdC5wdXNoLmJpbmQodG9hc3QpXG59XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9tb2RhbHMvc3JjL3RvYXN0LmpzXG4gKiogbW9kdWxlIGlkID0gOTJcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIi8vIHN0eWxlLWxvYWRlcjogQWRkcyBzb21lIGNzcyB0byB0aGUgRE9NIGJ5IGFkZGluZyBhIDxzdHlsZT4gdGFnXG5cbi8vIGxvYWQgdGhlIHN0eWxlc1xudmFyIGNvbnRlbnQgPSByZXF1aXJlKFwiISEuLy4uLy4uL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vdG9hc3Quc2Nzc1wiKTtcbmlmKHR5cGVvZiBjb250ZW50ID09PSAnc3RyaW5nJykgY29udGVudCA9IFtbbW9kdWxlLmlkLCBjb250ZW50LCAnJ11dO1xuLy8gYWRkIHRoZSBzdHlsZXMgdG8gdGhlIERPTVxudmFyIHVwZGF0ZSA9IHJlcXVpcmUoXCIhLi8uLi8uLi9zdHlsZS1sb2FkZXIvYWRkU3R5bGVzLmpzXCIpKGNvbnRlbnQsIHt9KTtcbmlmKGNvbnRlbnQubG9jYWxzKSBtb2R1bGUuZXhwb3J0cyA9IGNvbnRlbnQubG9jYWxzO1xuLy8gSG90IE1vZHVsZSBSZXBsYWNlbWVudFxuaWYobW9kdWxlLmhvdCkge1xuXHQvLyBXaGVuIHRoZSBzdHlsZXMgY2hhbmdlLCB1cGRhdGUgdGhlIDxzdHlsZT4gdGFnc1xuXHRpZighY29udGVudC5sb2NhbHMpIHtcblx0XHRtb2R1bGUuaG90LmFjY2VwdChcIiEhLi8uLi8uLi9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLy4uLy4uL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL3RvYXN0LnNjc3NcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbmV3Q29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi9zYXNzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi90b2FzdC5zY3NzXCIpO1xuXHRcdFx0aWYodHlwZW9mIG5ld0NvbnRlbnQgPT09ICdzdHJpbmcnKSBuZXdDb250ZW50ID0gW1ttb2R1bGUuaWQsIG5ld0NvbnRlbnQsICcnXV07XG5cdFx0XHR1cGRhdGUobmV3Q29udGVudCk7XG5cdFx0fSk7XG5cdH1cblx0Ly8gV2hlbiB0aGUgbW9kdWxlIGlzIGRpc3Bvc2VkLCByZW1vdmUgdGhlIDxzdHlsZT4gdGFnc1xuXHRtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24oKSB7IHVwZGF0ZSgpOyB9KTtcbn1cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9tb2RhbHMvc3R5bGVzL3RvYXN0LnNjc3NcbiAqKiBtb2R1bGUgaWQgPSA5M1xuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4vLi4vLi4vY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikoKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIi5hbWZlLXRvYXN0IHtcXG4gIGZvbnQtc2l6ZTogMC4zMnJlbTtcXG4gIGxpbmUtaGVpZ2h0OiAwLjQyNjY2N3JlbTtcXG4gIHBvc2l0aW9uOiBmaXhlZDtcXG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XFxuICBtYXgtd2lkdGg6IDgwJTtcXG4gIGJvdHRvbTogMi42NjY2NjdyZW07XFxuICBsZWZ0OiA1MCU7XFxuICBwYWRkaW5nOiAwLjIxMzMzM3JlbTtcXG4gIGJhY2tncm91bmQtY29sb3I6ICMwMDA7XFxuICBjb2xvcjogI2ZmZjtcXG4gIHRleHQtYWxpZ246IGNlbnRlcjtcXG4gIG9wYWNpdHk6IDAuNjtcXG4gIHRyYW5zaXRpb246IGFsbCAwLjRzIGVhc2UtaW4tb3V0O1xcbiAgYm9yZGVyLXJhZGl1czogMC4wNjY2NjdyZW07XFxuICAtd2Via2l0LXRyYW5zZm9ybTogdHJhbnNsYXRlWCgtNTAlKTtcXG4gIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgtNTAlKTsgfVxcblxcbi5hbWZlLXRvYXN0LmhpZGUge1xcbiAgb3BhY2l0eTogMDsgfVxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi9ub2RlX21vZHVsZXMvbW9kYWxzL25vZGVfbW9kdWxlcy9tb2RhbHMvc3R5bGVzL3RvYXN0LnNjc3NcIl0sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIkFBQUE7RUFDQyxtQkFBbUI7RUFDbkIseUJBQXlCO0VBQ3pCLGdCQUFnQjtFQUNoQix1QkFBdUI7RUFDdkIsZUFBZTtFQUNmLG9CQUFvQjtFQUNwQixVQUFVO0VBQ1YscUJBQXFCO0VBQ3JCLHVCQUF1QjtFQUN2QixZQUFZO0VBQ1osbUJBQW1CO0VBQ25CLGFBQWE7RUFDYixpQ0FBaUM7RUFDakMsMkJBQTJCO0VBQzNCLG9DQUE2QjtFQUM1Qiw0QkFBcUIsRUFDdEI7O0FBRUQ7RUFDQyxXQUFXLEVBQ1hcIixcImZpbGVcIjpcInRvYXN0LnNjc3NcIixcInNvdXJjZXNDb250ZW50XCI6W1wiLmFtZmUtdG9hc3Qge1xcblxcdGZvbnQtc2l6ZTogMC4zMnJlbTsgLy8gMjRweFxcblxcdGxpbmUtaGVpZ2h0OiAwLjQyNjY2N3JlbTsgLy8gMzJweFxcblxcdHBvc2l0aW9uOiBmaXhlZDtcXG5cXHRib3gtc2l6aW5nOiBib3JkZXItYm94O1xcblxcdG1heC13aWR0aDogODAlO1xcblxcdGJvdHRvbTogMi42NjY2NjdyZW07IC8vIDIwMHB4XFxuXFx0bGVmdDogNTAlO1xcblxcdHBhZGRpbmc6IDAuMjEzMzMzcmVtOyAvLyAxNnB4XFxuXFx0YmFja2dyb3VuZC1jb2xvcjogIzAwMDtcXG5cXHRjb2xvcjogI2ZmZjtcXG5cXHR0ZXh0LWFsaWduOiBjZW50ZXI7XFxuXFx0b3BhY2l0eTogMC42O1xcblxcdHRyYW5zaXRpb246IGFsbCAwLjRzIGVhc2UtaW4tb3V0O1xcblxcdGJvcmRlci1yYWRpdXM6IDAuMDY2NjY3cmVtOyAvLyA1cHhcXG5cXHQtd2Via2l0LXRyYW5zZm9ybTogdHJhbnNsYXRlWCgtNTAlKTtcXG4gIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgtNTAlKTtcXG59XFxuXFxuLmFtZmUtdG9hc3QuaGlkZSB7XFxuXFx0b3BhY2l0eTogMDtcXG59XCJdLFwic291cmNlUm9vdFwiOlwid2VicGFjazovL1wifV0pO1xuXG4vLyBleHBvcnRzXG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL34vc2Fzcy1sb2FkZXI/c291cmNlTWFwIS4vfi9tb2RhbHMvc3R5bGVzL3RvYXN0LnNjc3NcbiAqKiBtb2R1bGUgaWQgPSA5NFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnZhciBTZW5kZXIgPSByZXF1aXJlKCcuLi9icmlkZ2Uvc2VuZGVyJylcblxudmFyIF9kYXRhID0ge31cblxudmFyIGFuaW1hdGlvbiA9IHtcblxuICAvKipcbiAgICogdHJhbnNpdGlvblxuICAgKiBAcGFyYW0gIHtzdHJpbmd9IHJlZiAgICAgICAgW2Rlc2NyaXB0aW9uXVxuICAgKiBAcGFyYW0gIHtvYmp9IGNvbmZpZyAgICAgW2Rlc2NyaXB0aW9uXVxuICAgKiBAcGFyYW0gIHtzdHJpbmd9IGNhbGxiYWNrSWQgW2Rlc2NyaXB0aW9uXVxuICAgKi9cbiAgdHJhbnNpdGlvbjogZnVuY3Rpb24gKHJlZiwgY29uZmlnLCBjYWxsYmFja0lkKSB7XG4gICAgdmFyIHJlZkRhdGEgPSBfZGF0YVtyZWZdXG4gICAgdmFyIHN0eWxlc0tleSA9IEpTT04uc3RyaW5naWZ5KGNvbmZpZy5zdHlsZXMpXG4gICAgdmFyIHdlZXhJbnN0YW5jZSA9IHRoaXNcbiAgICAvLyBJZiB0aGUgc2FtZSBjb21wb25lbnQgcGVyZm9ybSBhIGFuaW1hdGlvbiB3aXRoIGV4YWN0bHkgdGhlIHNhbWVcbiAgICAvLyBzdHlsZXMgaW4gYSBzZXF1ZW5jZSB3aXRoIHNvIHNob3J0IGludGVydmFsIHRoYXQgdGhlIHByZXYgYW5pbWF0aW9uXG4gICAgLy8gaXMgc3RpbGwgaW4gcGxheWluZywgdGhlbiB0aGUgbmV4dCBhbmltYXRpb24gc2hvdWxkIGJlIGlnbm9yZWQuXG4gICAgaWYgKHJlZkRhdGEgJiYgcmVmRGF0YVtzdHlsZXNLZXldKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgaWYgKCFyZWZEYXRhKSB7XG4gICAgICByZWZEYXRhID0gX2RhdGFbcmVmXSA9IHt9XG4gICAgfVxuICAgIHJlZkRhdGFbc3R5bGVzS2V5XSA9IHRydWVcbiAgICByZXR1cm4gdGhpcy5nZXRDb21wb25lbnRNYW5hZ2VyKCkudHJhbnNpdGlvbihyZWYsIGNvbmZpZywgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gUmVtb3ZlIHRoZSBzdHlsZXNLZXkgaW4gcmVmRGF0YSBzbyB0aGF0IHRoZSBzYW1lIGFuaW1hdGlvblxuICAgICAgLy8gY2FuIGJlIHBsYXllZCBhZ2FpbiBhZnRlciBjdXJyZW50IGFuaW1hdGlvbiBpcyBhbHJlYWR5IGZpbmlzaGVkLlxuICAgICAgZGVsZXRlIHJlZkRhdGFbc3R5bGVzS2V5XVxuICAgICAgd2VleEluc3RhbmNlLnNlbmRlci5wZXJmb3JtQ2FsbGJhY2soY2FsbGJhY2tJZClcbiAgICB9KVxuICB9XG5cbn1cblxuYW5pbWF0aW9uLl9tZXRhID0ge1xuICBhbmltYXRpb246IFt7XG4gICAgbmFtZTogJ3RyYW5zaXRpb24nLFxuICAgIGFyZ3M6IFsnc3RyaW5nJywgJ29iamVjdCcsICdzdHJpbmcnXVxuICB9XVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFuaW1hdGlvblxuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL3NyYy9hcGkvYW5pbWF0aW9uLmpzXG4gKiogbW9kdWxlIGlkID0gOTVcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIih0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykgJiYgKHdpbmRvdyA9IHtjdHJsOiB7fSwgbGliOiB7fX0pOyF3aW5kb3cuY3RybCAmJiAod2luZG93LmN0cmwgPSB7fSk7IXdpbmRvdy5saWIgJiYgKHdpbmRvdy5saWIgPSB7fSk7IWZ1bmN0aW9uKGEsYil7ZnVuY3Rpb24gYyhhKXtPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcyxcInZhbFwiLHt2YWx1ZTphLnRvU3RyaW5nKCksZW51bWVyYWJsZTohMH0pLHRoaXMuZ3Q9ZnVuY3Rpb24oYSl7cmV0dXJuIGMuY29tcGFyZSh0aGlzLGEpPjB9LHRoaXMuZ3RlPWZ1bmN0aW9uKGEpe3JldHVybiBjLmNvbXBhcmUodGhpcyxhKT49MH0sdGhpcy5sdD1mdW5jdGlvbihhKXtyZXR1cm4gYy5jb21wYXJlKHRoaXMsYSk8MH0sdGhpcy5sdGU9ZnVuY3Rpb24oYSl7cmV0dXJuIGMuY29tcGFyZSh0aGlzLGEpPD0wfSx0aGlzLmVxPWZ1bmN0aW9uKGEpe3JldHVybiAwPT09Yy5jb21wYXJlKHRoaXMsYSl9fWIuZW52PWIuZW52fHx7fSxjLnByb3RvdHlwZS50b1N0cmluZz1mdW5jdGlvbigpe3JldHVybiB0aGlzLnZhbH0sYy5wcm90b3R5cGUudmFsdWVPZj1mdW5jdGlvbigpe2Zvcih2YXIgYT10aGlzLnZhbC5zcGxpdChcIi5cIiksYj1bXSxjPTA7YzxhLmxlbmd0aDtjKyspe3ZhciBkPXBhcnNlSW50KGFbY10sMTApO2lzTmFOKGQpJiYoZD0wKTt2YXIgZT1kLnRvU3RyaW5nKCk7ZS5sZW5ndGg8NSYmKGU9QXJyYXkoNi1lLmxlbmd0aCkuam9pbihcIjBcIikrZSksYi5wdXNoKGUpLDE9PT1iLmxlbmd0aCYmYi5wdXNoKFwiLlwiKX1yZXR1cm4gcGFyc2VGbG9hdChiLmpvaW4oXCJcIikpfSxjLmNvbXBhcmU9ZnVuY3Rpb24oYSxiKXthPWEudG9TdHJpbmcoKS5zcGxpdChcIi5cIiksYj1iLnRvU3RyaW5nKCkuc3BsaXQoXCIuXCIpO2Zvcih2YXIgYz0wO2M8YS5sZW5ndGh8fGM8Yi5sZW5ndGg7YysrKXt2YXIgZD1wYXJzZUludChhW2NdLDEwKSxlPXBhcnNlSW50KGJbY10sMTApO2lmKHdpbmRvdy5pc05hTihkKSYmKGQ9MCksd2luZG93LmlzTmFOKGUpJiYoZT0wKSxlPmQpcmV0dXJuLTE7aWYoZD5lKXJldHVybiAxfXJldHVybiAwfSxiLnZlcnNpb249ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBjKGEpfX0od2luZG93LHdpbmRvdy5saWJ8fCh3aW5kb3cubGliPXt9KSksZnVuY3Rpb24oYSxiKXtiLmVudj1iLmVudnx8e307dmFyIGM9YS5sb2NhdGlvbi5zZWFyY2gucmVwbGFjZSgvXlxcPy8sXCJcIik7aWYoYi5lbnYucGFyYW1zPXt9LGMpZm9yKHZhciBkPWMuc3BsaXQoXCImXCIpLGU9MDtlPGQubGVuZ3RoO2UrKyl7ZFtlXT1kW2VdLnNwbGl0KFwiPVwiKTt0cnl7Yi5lbnYucGFyYW1zW2RbZV1bMF1dPWRlY29kZVVSSUNvbXBvbmVudChkW2VdWzFdKX1jYXRjaChmKXtiLmVudi5wYXJhbXNbZFtlXVswXV09ZFtlXVsxXX19fSh3aW5kb3csd2luZG93LmxpYnx8KHdpbmRvdy5saWI9e30pKSxmdW5jdGlvbihhLGIpe2IuZW52PWIuZW52fHx7fTt2YXIgYyxkPWEubmF2aWdhdG9yLnVzZXJBZ2VudDtpZihjPWQubWF0Y2goL1dpbmRvd3NcXHNQaG9uZVxccyg/Ok9TXFxzKT8oW1xcZFxcLl0rKS8pKWIuZW52Lm9zPXtuYW1lOlwiV2luZG93cyBQaG9uZVwiLGlzV2luZG93c1Bob25lOiEwLHZlcnNpb246Y1sxXX07ZWxzZSBpZihkLm1hdGNoKC9TYWZhcmkvKSYmKGM9ZC5tYXRjaCgvQW5kcm9pZFtcXHNcXC9dKFtcXGRcXC5dKykvKSkpYi5lbnYub3M9e3ZlcnNpb246Y1sxXX0sZC5tYXRjaCgvTW9iaWxlXFxzK1NhZmFyaS8pPyhiLmVudi5vcy5uYW1lPVwiQW5kcm9pZFwiLGIuZW52Lm9zLmlzQW5kcm9pZD0hMCk6KGIuZW52Lm9zLm5hbWU9XCJBbmRyb2lkUGFkXCIsYi5lbnYub3MuaXNBbmRyb2lkUGFkPSEwKTtlbHNlIGlmKGM9ZC5tYXRjaCgvKGlQaG9uZXxpUGFkfGlQb2QpLykpe3ZhciBlPWNbMV07Yz1kLm1hdGNoKC9PUyAoW1xcZF9cXC5dKykgbGlrZSBNYWMgT1MgWC8pLGIuZW52Lm9zPXtuYW1lOmUsaXNJUGhvbmU6XCJpUGhvbmVcIj09PWV8fFwiaVBvZFwiPT09ZSxpc0lQYWQ6XCJpUGFkXCI9PT1lLGlzSU9TOiEwLHZlcnNpb246Y1sxXS5zcGxpdChcIl9cIikuam9pbihcIi5cIil9fWVsc2UgYi5lbnYub3M9e25hbWU6XCJ1bmtub3duXCIsdmVyc2lvbjpcIjAuMC4wXCJ9O2IudmVyc2lvbiYmKGIuZW52Lm9zLnZlcnNpb249Yi52ZXJzaW9uKGIuZW52Lm9zLnZlcnNpb24pKX0od2luZG93LHdpbmRvdy5saWJ8fCh3aW5kb3cubGliPXt9KSksZnVuY3Rpb24oYSxiKXtiLmVudj1iLmVudnx8e307dmFyIGMsZD1hLm5hdmlnYXRvci51c2VyQWdlbnQ7KGM9ZC5tYXRjaCgvKD86VUNXRUJ8VUNCcm93c2VyXFwvKShbXFxkXFwuXSspLykpP2IuZW52LmJyb3dzZXI9e25hbWU6XCJVQ1wiLGlzVUM6ITAsdmVyc2lvbjpjWzFdfTooYz1kLm1hdGNoKC9NUVFCcm93c2VyXFwvKFtcXGRcXC5dKykvKSk/Yi5lbnYuYnJvd3Nlcj17bmFtZTpcIlFRXCIsaXNRUTohMCx2ZXJzaW9uOmNbMV19OihjPWQubWF0Y2goL0ZpcmVmb3hcXC8oW1xcZFxcLl0rKS8pKT9iLmVudi5icm93c2VyPXtuYW1lOlwiRmlyZWZveFwiLGlzRmlyZWZveDohMCx2ZXJzaW9uOmNbMV19OihjPWQubWF0Y2goL01TSUVcXHMoW1xcZFxcLl0rKS8pKXx8KGM9ZC5tYXRjaCgvSUVNb2JpbGVcXC8oW1xcZFxcLl0rKS8pKT8oYi5lbnYuYnJvd3Nlcj17dmVyc2lvbjpjWzFdfSxkLm1hdGNoKC9JRU1vYmlsZS8pPyhiLmVudi5icm93c2VyLm5hbWU9XCJJRU1vYmlsZVwiLGIuZW52LmJyb3dzZXIuaXNJRU1vYmlsZT0hMCk6KGIuZW52LmJyb3dzZXIubmFtZT1cIklFXCIsYi5lbnYuYnJvd3Nlci5pc0lFPSEwKSxkLm1hdGNoKC9BbmRyb2lkfGlQaG9uZS8pJiYoYi5lbnYuYnJvd3Nlci5pc0lFTGlrZVdlYmtpdD0hMCkpOihjPWQubWF0Y2goLyg/OkNocm9tZXxDcmlPUylcXC8oW1xcZFxcLl0rKS8pKT8oYi5lbnYuYnJvd3Nlcj17bmFtZTpcIkNocm9tZVwiLGlzQ2hyb21lOiEwLHZlcnNpb246Y1sxXX0sZC5tYXRjaCgvVmVyc2lvblxcL1tcXGQrXFwuXStcXHMqQ2hyb21lLykmJihiLmVudi5icm93c2VyLm5hbWU9XCJDaHJvbWUgV2Vidmlld1wiLGIuZW52LmJyb3dzZXIuaXNXZWJ2aWV3PSEwKSk6ZC5tYXRjaCgvU2FmYXJpLykmJihjPWQubWF0Y2goL0FuZHJvaWRbXFxzXFwvXShbXFxkXFwuXSspLykpP2IuZW52LmJyb3dzZXI9e25hbWU6XCJBbmRyb2lkXCIsaXNBbmRyb2lkOiEwLHZlcnNpb246Y1sxXX06ZC5tYXRjaCgvaVBob25lfGlQYWR8aVBvZC8pP2QubWF0Y2goL1NhZmFyaS8pPyhjPWQubWF0Y2goL1ZlcnNpb25cXC8oW1xcZFxcLl0rKS8pLGIuZW52LmJyb3dzZXI9e25hbWU6XCJTYWZhcmlcIixpc1NhZmFyaTohMCx2ZXJzaW9uOmNbMV19KTooYz1kLm1hdGNoKC9PUyAoW1xcZF9cXC5dKykgbGlrZSBNYWMgT1MgWC8pLGIuZW52LmJyb3dzZXI9e25hbWU6XCJpT1MgV2Vidmlld1wiLGlzV2VidmlldzohMCx2ZXJzaW9uOmNbMV0ucmVwbGFjZSgvXFxfL2csXCIuXCIpfSk6Yi5lbnYuYnJvd3Nlcj17bmFtZTpcInVua25vd25cIix2ZXJzaW9uOlwiMC4wLjBcIn0sYi52ZXJzaW9uJiYoYi5lbnYuYnJvd3Nlci52ZXJzaW9uPWIudmVyc2lvbihiLmVudi5icm93c2VyLnZlcnNpb24pKX0od2luZG93LHdpbmRvdy5saWJ8fCh3aW5kb3cubGliPXt9KSksZnVuY3Rpb24oYSxiKXtiLmVudj1iLmVudnx8e307dmFyIGM9YS5uYXZpZ2F0b3IudXNlckFnZW50O2MubWF0Y2goL1dlaWJvL2kpP2IuZW52LnRoaXJkYXBwPXthcHBuYW1lOlwiV2VpYm9cIixpc1dlaWJvOiEwfTpjLm1hdGNoKC9NaWNyb01lc3Nlbmdlci9pKT9iLmVudi50aGlyZGFwcD17YXBwbmFtZTpcIldlaXhpblwiLGlzV2VpeGluOiEwfTpiLmVudi50aGlyZGFwcD0hMX0od2luZG93LHdpbmRvdy5saWJ8fCh3aW5kb3cubGliPXt9KSksZnVuY3Rpb24oYSxiKXtiLmVudj1iLmVudnx8e307dmFyIGMsZCxlPWEubmF2aWdhdG9yLnVzZXJBZ2VudDsoZD1lLm1hdGNoKC9XaW5kVmFuZVtcXC9cXHNdKFtcXGRcXC5cXF9dKykvKSkmJihjPWRbMV0pO3ZhciBmPSExLGc9XCJcIixoPVwiXCIsaT1cIlwiOyhkPWUubWF0Y2goL0FsaUFwcFxcKChbQS1aXFwtXSspXFwvKFtcXGRcXC5dKylcXCkvaSkpJiYoZj0hMCxnPWRbMV0saT1kWzJdLGg9Zy5pbmRleE9mKFwiLVBEXCIpPjA/Yi5lbnYub3MuaXNJT1M/XCJpUGFkXCI6Yi5lbnYub3MuaXNBbmRyb2lkP1wiQW5kcm9pZFBhZFwiOmIuZW52Lm9zLm5hbWU6Yi5lbnYub3MubmFtZSksIWcmJmUuaW5kZXhPZihcIlRCSU9TXCIpPjAmJihnPVwiVEJcIiksZj9iLmVudi5hbGlhcHA9e3dpbmR2YW5lOmIudmVyc2lvbihjfHxcIjAuMC4wXCIpLGFwcG5hbWU6Z3x8XCJ1bmtvd25cIix2ZXJzaW9uOmIudmVyc2lvbihpfHxcIjAuMC4wXCIpLHBsYXRmb3JtOmh8fGIuZW52Lm9zLm5hbWV9OmIuZW52LmFsaWFwcD0hMSxiLmVudi50YW9iYW9BcHA9Yi5lbnYuYWxpYXBwfSh3aW5kb3csd2luZG93LmxpYnx8KHdpbmRvdy5saWI9e30pKTs7bW9kdWxlLmV4cG9ydHMgPSB3aW5kb3cubGliWydlbnYnXTtcblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9lbnZkL2J1aWxkL2VudmQuY29tbW9uLmpzXG4gKiogbW9kdWxlIGlkID0gOTZcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyJdLCJzb3VyY2VSb290IjoiIn0=
\ No newline at end of file
diff --git a/test/lib/jsfm.js b/test/lib/jsfm.js
deleted file mode 100644
index ddd0b49..0000000
--- a/test/lib/jsfm.js
+++ /dev/null
@@ -1,7851 +0,0 @@
-(this.nativeLog || function(s) {console.log(s)})('START JS FRAMEWORK: 0.13.7');
-/******/ (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] = {
-/******/      exports: {},
-/******/      id: moduleId,
-/******/      loaded: false
-/******/    };
-/******/
-/******/    // Execute the module function
-/******/    modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
-/******/
-/******/    // Flag the module as loaded
-/******/    module.loaded = 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;
-/******/
-/******/  // __webpack_public_path__
-/******/  __webpack_require__.p = "";
-/******/
-/******/  // Load entry module and return exports
-/******/  return __webpack_require__(0);
-/******/ })
-/************************************************************************/
-/******/ ([
-/* 0 */
-/***/ function(module, exports, __webpack_require__) {
-
-  /* WEBPACK VAR INJECTION */(function(global) {'use strict';
-  
-  __webpack_require__(1);
-  
-  var _framework = __webpack_require__(76);
-  
-  var framework = _interopRequireWildcard(_framework);
-  
-  var _package = __webpack_require__(105);
-  
-  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
-  
-  var _loop = function _loop(methodName) {
-      global[methodName] = function () {
-          var ret = framework[methodName].apply(framework, arguments);
-          if (ret instanceof Error) {
-              console.error(ret.toString());
-          } else if (ret instanceof Array) {
-              ret.forEach(function (r) {
-                  if (r instanceof Error) {
-                      console.error(r.toString());
-                  }
-              });
-          }
-          return ret;
-      };
-  };
-  
-  for (var methodName in framework) {
-      _loop(methodName);
-  }
-  
-  Object.assign(global, {
-      frameworkVersion: _package.version,
-      needTransformerVersion: _package.optionalDependencies['weex-transformer']
-  });
-  
-  /**
-   * register methods
-   */
-  var methods = __webpack_require__(106);
-  var _global = global;
-  var registerMethods = _global.registerMethods;
-  
-  registerMethods(methods);
-  /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
-
-/***/ },
-/* 1 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  __webpack_require__(2);
-  
-  __webpack_require__(40);
-  
-  __webpack_require__(74);
-  
-  __webpack_require__(75);
-
-/***/ },
-/* 2 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  __webpack_require__(3);
-
-/***/ },
-/* 3 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  __webpack_require__(4);
-  module.exports = __webpack_require__(7).Object.assign;
-
-/***/ },
-/* 4 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  // 19.1.3.1 Object.assign(target, source)
-  var $export = __webpack_require__(5);
-  
-  $export($export.S + $export.F, 'Object', { assign: __webpack_require__(23) });
-
-/***/ },
-/* 5 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  var global = __webpack_require__(6),
-      core = __webpack_require__(7),
-      hide = __webpack_require__(8),
-      redefine = __webpack_require__(18),
-      ctx = __webpack_require__(21),
-      PROTOTYPE = 'prototype';
-  
-  var $export = function $export(type, name, source) {
-    var IS_FORCED = type & $export.F,
-        IS_GLOBAL = type & $export.G,
-        IS_STATIC = type & $export.S,
-        IS_PROTO = type & $export.P,
-        IS_BIND = type & $export.B,
-        target = IS_GLOBAL ? global : IS_STATIC ? global[name] || (global[name] = {}) : (global[name] || {})[PROTOTYPE],
-        exports = IS_GLOBAL ? core : core[name] || (core[name] = {}),
-        expProto = exports[PROTOTYPE] || (exports[PROTOTYPE] = {}),
-        key,
-        own,
-        out,
-        exp;
-    if (IS_GLOBAL) source = name;
-    for (key in source) {
-      // contains in native
-      own = !IS_FORCED && target && target[key] !== undefined;
-      // export native or passed
-      out = (own ? target : source)[key];
-      // bind timers to global for call from export context
-      exp = IS_BIND && own ? ctx(out, global) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;
-      // extend global
-      if (target) redefine(target, key, out, type & $export.U);
-      // export
-      if (exports[key] != out) hide(exports, key, exp);
-      if (IS_PROTO && expProto[key] != out) expProto[key] = out;
-    }
-  };
-  global.core = core;
-  // type bitmap
-  $export.F = 1; // forced
-  $export.G = 2; // global
-  $export.S = 4; // static
-  $export.P = 8; // proto
-  $export.B = 16; // bind
-  $export.W = 32; // wrap
-  $export.U = 64; // safe
-  $export.R = 128; // real proto method for `library`
-  module.exports = $export;
-
-/***/ },
-/* 6 */
-/***/ function(module, exports) {
-
-  'use strict';
-  
-  // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
-  var global = module.exports = typeof window != 'undefined' && window.Math == Math ? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')();
-  if (typeof __g == 'number') __g = global; // eslint-disable-line no-undef
-
-/***/ },
-/* 7 */
-/***/ function(module, exports) {
-
-  'use strict';
-  
-  var core = module.exports = { version: '2.1.5' };
-  if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef
-
-/***/ },
-/* 8 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  var dP = __webpack_require__(9),
-      createDesc = __webpack_require__(17);
-  module.exports = __webpack_require__(13) ? function (object, key, value) {
-    return dP.f(object, key, createDesc(1, value));
-  } : function (object, key, value) {
-    object[key] = value;
-    return object;
-  };
-
-/***/ },
-/* 9 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  var anObject = __webpack_require__(10),
-      IE8_DOM_DEFINE = __webpack_require__(12),
-      toPrimitive = __webpack_require__(16),
-      dP = Object.defineProperty;
-  
-  exports.f = __webpack_require__(13) ? Object.defineProperty : function defineProperty(O, P, Attributes) {
-    anObject(O);
-    P = toPrimitive(P, true);
-    anObject(Attributes);
-    if (IE8_DOM_DEFINE) try {
-      return dP(O, P, Attributes);
-    } catch (e) {/* empty */}
-    if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!');
-    if ('value' in Attributes) O[P] = Attributes.value;
-    return O;
-  };
-
-/***/ },
-/* 10 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  var isObject = __webpack_require__(11);
-  module.exports = function (it) {
-    if (!isObject(it)) throw TypeError(it + ' is not an object!');
-    return it;
-  };
-
-/***/ },
-/* 11 */
-/***/ function(module, exports) {
-
-  'use strict';
-  
-  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
-  
-  module.exports = function (it) {
-    return (typeof it === 'undefined' ? 'undefined' : _typeof(it)) === 'object' ? it !== null : typeof it === 'function';
-  };
-
-/***/ },
-/* 12 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  module.exports = !__webpack_require__(13) && !__webpack_require__(14)(function () {
-    return Object.defineProperty(__webpack_require__(15)('div'), 'a', { get: function get() {
-        return 7;
-      } }).a != 7;
-  });
-
-/***/ },
-/* 13 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  // Thank's IE8 for his funny defineProperty
-  module.exports = !__webpack_require__(14)(function () {
-    return Object.defineProperty({}, 'a', { get: function get() {
-        return 7;
-      } }).a != 7;
-  });
-
-/***/ },
-/* 14 */
-/***/ function(module, exports) {
-
-  "use strict";
-  
-  module.exports = function (exec) {
-    try {
-      return !!exec();
-    } catch (e) {
-      return true;
-    }
-  };
-
-/***/ },
-/* 15 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  var isObject = __webpack_require__(11),
-      document = __webpack_require__(6).document
-  // in old IE typeof document.createElement is 'object'
-  ,
-      is = isObject(document) && isObject(document.createElement);
-  module.exports = function (it) {
-    return is ? document.createElement(it) : {};
-  };
-
-/***/ },
-/* 16 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  // 7.1.1 ToPrimitive(input [, PreferredType])
-  var isObject = __webpack_require__(11);
-  // instead of the ES6 spec version, we didn't implement @@toPrimitive case
-  // and the second argument - flag - preferred type is a string
-  module.exports = function (it, S) {
-    if (!isObject(it)) return it;
-    var fn, val;
-    if (S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val;
-    if (typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it))) return val;
-    if (!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val;
-    throw TypeError("Can't convert object to primitive value");
-  };
-
-/***/ },
-/* 17 */
-/***/ function(module, exports) {
-
-  "use strict";
-  
-  module.exports = function (bitmap, value) {
-    return {
-      enumerable: !(bitmap & 1),
-      configurable: !(bitmap & 2),
-      writable: !(bitmap & 4),
-      value: value
-    };
-  };
-
-/***/ },
-/* 18 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  var global = __webpack_require__(6),
-      hide = __webpack_require__(8),
-      has = __webpack_require__(19),
-      SRC = __webpack_require__(20)('src'),
-      TO_STRING = 'toString',
-      $toString = Function[TO_STRING],
-      TPL = ('' + $toString).split(TO_STRING);
-  
-  __webpack_require__(7).inspectSource = function (it) {
-    return $toString.call(it);
-  };
-  
-  (module.exports = function (O, key, val, safe) {
-    var isFunction = typeof val == 'function';
-    if (isFunction) has(val, 'name') || hide(val, 'name', key);
-    if (O[key] === val) return;
-    if (isFunction) has(val, SRC) || hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key)));
-    if (O === global) {
-      O[key] = val;
-    } else {
-      if (!safe) {
-        delete O[key];
-        hide(O, key, val);
-      } else {
-        if (O[key]) O[key] = val;else hide(O, key, val);
-      }
-    }
-    // add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
-  })(Function.prototype, TO_STRING, function toString() {
-    return typeof this == 'function' && this[SRC] || $toString.call(this);
-  });
-
-/***/ },
-/* 19 */
-/***/ function(module, exports) {
-
-  "use strict";
-  
-  var hasOwnProperty = {}.hasOwnProperty;
-  module.exports = function (it, key) {
-    return hasOwnProperty.call(it, key);
-  };
-
-/***/ },
-/* 20 */
-/***/ function(module, exports) {
-
-  'use strict';
-  
-  var id = 0,
-      px = Math.random();
-  module.exports = function (key) {
-    return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));
-  };
-
-/***/ },
-/* 21 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  // optional / simple context binding
-  var aFunction = __webpack_require__(22);
-  module.exports = function (fn, that, length) {
-    aFunction(fn);
-    if (that === undefined) return fn;
-    switch (length) {
-      case 1:
-        return function (a) {
-          return fn.call(that, a);
-        };
-      case 2:
-        return function (a, b) {
-          return fn.call(that, a, b);
-        };
-      case 3:
-        return function (a, b, c) {
-          return fn.call(that, a, b, c);
-        };
-    }
-    return function () /* ...args */{
-      return fn.apply(that, arguments);
-    };
-  };
-
-/***/ },
-/* 22 */
-/***/ function(module, exports) {
-
-  'use strict';
-  
-  module.exports = function (it) {
-    if (typeof it != 'function') throw TypeError(it + ' is not a function!');
-    return it;
-  };
-
-/***/ },
-/* 23 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  // 19.1.2.1 Object.assign(target, source, ...)
-  
-  var getKeys = __webpack_require__(24),
-      gOPS = __webpack_require__(37),
-      pIE = __webpack_require__(38),
-      toObject = __webpack_require__(39),
-      IObject = __webpack_require__(27),
-      $assign = Object.assign;
-  
-  // should work with symbols and should have deterministic property order (V8 bug)
-  module.exports = !$assign || __webpack_require__(14)(function () {
-    var A = {},
-        B = {},
-        S = Symbol(),
-        K = 'abcdefghijklmnopqrst';
-    A[S] = 7;
-    K.split('').forEach(function (k) {
-      B[k] = k;
-    });
-    return $assign({}, A)[S] != 7 || Object.keys($assign({}, B)).join('') != K;
-  }) ? function assign(target, source) {
-    // eslint-disable-line no-unused-vars
-    var T = toObject(target),
-        aLen = arguments.length,
-        index = 1,
-        getSymbols = gOPS.f,
-        isEnum = pIE.f;
-    while (aLen > index) {
-      var S = IObject(arguments[index++]),
-          keys = getSymbols ? getKeys(S).concat(getSymbols(S)) : getKeys(S),
-          length = keys.length,
-          j = 0,
-          key;
-      while (length > j) {
-        if (isEnum.call(S, key = keys[j++])) T[key] = S[key];
-      }
-    }return T;
-  } : $assign;
-
-/***/ },
-/* 24 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  // 19.1.2.14 / 15.2.3.14 Object.keys(O)
-  var $keys = __webpack_require__(25),
-      enumBugKeys = __webpack_require__(36);
-  
-  module.exports = Object.keys || function keys(O) {
-    return $keys(O, enumBugKeys);
-  };
-
-/***/ },
-/* 25 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  var has = __webpack_require__(19),
-      toIObject = __webpack_require__(26),
-      arrayIndexOf = __webpack_require__(30)(false),
-      IE_PROTO = __webpack_require__(34)('IE_PROTO');
-  
-  module.exports = function (object, names) {
-    var O = toIObject(object),
-        i = 0,
-        result = [],
-        key;
-    for (key in O) {
-      if (key != IE_PROTO) has(O, key) && result.push(key);
-    } // Don't enum bug & hidden keys
-    while (names.length > i) {
-      if (has(O, key = names[i++])) {
-        ~arrayIndexOf(result, key) || result.push(key);
-      }
-    }return result;
-  };
-
-/***/ },
-/* 26 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  // to indexed object, toObject with fallback for non-array-like ES3 strings
-  var IObject = __webpack_require__(27),
-      defined = __webpack_require__(29);
-  module.exports = function (it) {
-    return IObject(defined(it));
-  };
-
-/***/ },
-/* 27 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  // fallback for non-array-like ES3 and non-enumerable old V8 strings
-  var cof = __webpack_require__(28);
-  module.exports = Object('z').propertyIsEnumerable(0) ? Object : function (it) {
-    return cof(it) == 'String' ? it.split('') : Object(it);
-  };
-
-/***/ },
-/* 28 */
-/***/ function(module, exports) {
-
-  "use strict";
-  
-  var toString = {}.toString;
-  
-  module.exports = function (it) {
-    return toString.call(it).slice(8, -1);
-  };
-
-/***/ },
-/* 29 */
-/***/ function(module, exports) {
-
-  "use strict";
-  
-  // 7.2.1 RequireObjectCoercible(argument)
-  module.exports = function (it) {
-    if (it == undefined) throw TypeError("Can't call method on  " + it);
-    return it;
-  };
-
-/***/ },
-/* 30 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  // false -> Array#indexOf
-  // true  -> Array#includes
-  var toIObject = __webpack_require__(26),
-      toLength = __webpack_require__(31),
-      toIndex = __webpack_require__(33);
-  module.exports = function (IS_INCLUDES) {
-    return function ($this, el, fromIndex) {
-      var O = toIObject($this),
-          length = toLength(O.length),
-          index = toIndex(fromIndex, length),
-          value;
-      // Array#includes uses SameValueZero equality algorithm
-      if (IS_INCLUDES && el != el) while (length > index) {
-        value = O[index++];
-        if (value != value) return true;
-        // Array#toIndex ignores holes, Array#includes - not
-      } else for (; length > index; index++) {
-          if (IS_INCLUDES || index in O) {
-            if (O[index] === el) return IS_INCLUDES || index;
-          }
-        }return !IS_INCLUDES && -1;
-    };
-  };
-
-/***/ },
-/* 31 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  // 7.1.15 ToLength
-  var toInteger = __webpack_require__(32),
-      min = Math.min;
-  module.exports = function (it) {
-    return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991
-  };
-
-/***/ },
-/* 32 */
-/***/ function(module, exports) {
-
-  "use strict";
-  
-  // 7.1.4 ToInteger
-  var ceil = Math.ceil,
-      floor = Math.floor;
-  module.exports = function (it) {
-    return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);
-  };
-
-/***/ },
-/* 33 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  var toInteger = __webpack_require__(32),
-      max = Math.max,
-      min = Math.min;
-  module.exports = function (index, length) {
-    index = toInteger(index);
-    return index < 0 ? max(index + length, 0) : min(index, length);
-  };
-
-/***/ },
-/* 34 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  var shared = __webpack_require__(35)('keys'),
-      uid = __webpack_require__(20);
-  module.exports = function (key) {
-    return shared[key] || (shared[key] = uid(key));
-  };
-
-/***/ },
-/* 35 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  var global = __webpack_require__(6),
-      SHARED = '__core-js_shared__',
-      store = global[SHARED] || (global[SHARED] = {});
-  module.exports = function (key) {
-    return store[key] || (store[key] = {});
-  };
-
-/***/ },
-/* 36 */
-/***/ function(module, exports) {
-
-  'use strict';
-  
-  // IE 8- don't enum bug keys
-  module.exports = 'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf'.split(',');
-
-/***/ },
-/* 37 */
-/***/ function(module, exports) {
-
-  "use strict";
-  
-  exports.f = Object.getOwnPropertySymbols;
-
-/***/ },
-/* 38 */
-/***/ function(module, exports) {
-
-  "use strict";
-  
-  exports.f = {}.propertyIsEnumerable;
-
-/***/ },
-/* 39 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  // 7.1.13 ToObject(argument)
-  var defined = __webpack_require__(29);
-  module.exports = function (it) {
-    return Object(defined(it));
-  };
-
-/***/ },
-/* 40 */
-/***/ function(module, exports, __webpack_require__) {
-
-  /* WEBPACK VAR INJECTION */(function(global) {'use strict';
-  
-  // fix Promise Problem on JSContext of iOS7~8
-  // @see https://bugs.webkit.org/show_bug.cgi?id=135866
-  global.Promise = null;
-  __webpack_require__(41);
-  __webpack_require__(44);
-  __webpack_require__(55);
-  __webpack_require__(59);
-  /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
-
-/***/ },
-/* 41 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  // 19.1.3.6 Object.prototype.toString()
-  
-  var classof = __webpack_require__(42),
-      test = {};
-  test[__webpack_require__(43)('toStringTag')] = 'z';
-  if (test + '' != '[object z]') {
-    __webpack_require__(18)(Object.prototype, 'toString', function toString() {
-      return '[object ' + classof(this) + ']';
-    }, true);
-  }
-
-/***/ },
-/* 42 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  // getting tag from 19.1.3.6 Object.prototype.toString()
-  var cof = __webpack_require__(28),
-      TAG = __webpack_require__(43)('toStringTag')
-  // ES3 wrong here
-  ,
-      ARG = cof(function () {
-    return arguments;
-  }()) == 'Arguments';
-  
-  // fallback for IE11 Script Access Denied error
-  var tryGet = function tryGet(it, key) {
-    try {
-      return it[key];
-    } catch (e) {/* empty */}
-  };
-  
-  module.exports = function (it) {
-    var O, T, B;
-    return it === undefined ? 'Undefined' : it === null ? 'Null'
-    // @@toStringTag case
-    : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T
-    // builtinTag case
-    : ARG ? cof(O)
-    // ES3 arguments fallback
-    : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B;
-  };
-
-/***/ },
-/* 43 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  var store = __webpack_require__(35)('wks'),
-      uid = __webpack_require__(20),
-      _Symbol = __webpack_require__(6).Symbol,
-      USE_SYMBOL = typeof _Symbol == 'function';
-  module.exports = function (name) {
-    return store[name] || (store[name] = USE_SYMBOL && _Symbol[name] || (USE_SYMBOL ? _Symbol : uid)('Symbol.' + name));
-  };
-
-/***/ },
-/* 44 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  var $at = __webpack_require__(45)(true);
-  
-  // 21.1.3.27 String.prototype[@@iterator]()
-  __webpack_require__(46)(String, 'String', function (iterated) {
-    this._t = String(iterated); // target
-    this._i = 0; // next index
-    // 21.1.5.2.1 %StringIteratorPrototype%.next()
-  }, function () {
-    var O = this._t,
-        index = this._i,
-        point;
-    if (index >= O.length) return { value: undefined, done: true };
-    point = $at(O, index);
-    this._i += point.length;
-    return { value: point, done: false };
-  });
-
-/***/ },
-/* 45 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  var toInteger = __webpack_require__(32),
-      defined = __webpack_require__(29);
-  // true  -> String#at
-  // false -> String#codePointAt
-  module.exports = function (TO_STRING) {
-    return function (that, pos) {
-      var s = String(defined(that)),
-          i = toInteger(pos),
-          l = s.length,
-          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;
-    };
-  };
-
-/***/ },
-/* 46 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  var LIBRARY = __webpack_require__(47),
-      $export = __webpack_require__(5),
-      redefine = __webpack_require__(18),
-      hide = __webpack_require__(8),
-      has = __webpack_require__(19),
-      Iterators = __webpack_require__(48),
-      $iterCreate = __webpack_require__(49),
-      setToStringTag = __webpack_require__(53),
-      getPrototypeOf = __webpack_require__(54),
-      ITERATOR = __webpack_require__(43)('iterator'),
-      BUGGY = !([].keys && 'next' in [].keys()) // Safari has buggy iterators w/o `next`
-  ,
-      FF_ITERATOR = '@@iterator',
-      KEYS = 'keys',
-      VALUES = 'values';
-  
-  var returnThis = function returnThis() {
-    return this;
-  };
-  
-  module.exports = function (Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED) {
-    $iterCreate(Constructor, NAME, next);
-    var getMethod = function getMethod(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',
-        DEF_VALUES = DEFAULT == VALUES,
-        VALUES_BUG = false,
-        proto = Base.prototype,
-        $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT],
-        $default = $native || getMethod(DEFAULT),
-        $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined,
-        $anyNative = NAME == 'Array' ? proto.entries || $native : $native,
-        methods,
-        key,
-        IteratorPrototype;
-    // Fix native
-    if ($anyNative) {
-      IteratorPrototype = getPrototypeOf($anyNative.call(new Base()));
-      if (IteratorPrototype !== Object.prototype) {
-        // Set @@toStringTag to native iterators
-        setToStringTag(IteratorPrototype, TAG, true);
-        // fix for some old engines
-        if (!LIBRARY && !has(IteratorPrototype, ITERATOR)) 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;
-  };
-
-/***/ },
-/* 47 */
-/***/ function(module, exports) {
-
-  "use strict";
-  
-  module.exports = false;
-
-/***/ },
-/* 48 */
-/***/ function(module, exports) {
-
-  "use strict";
-  
-  module.exports = {};
-
-/***/ },
-/* 49 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  var create = __webpack_require__(50),
-      descriptor = __webpack_require__(17),
-      setToStringTag = __webpack_require__(53),
-      IteratorPrototype = {};
-  
-  // 25.1.2.1.1 %IteratorPrototype%[@@iterator]()
-  __webpack_require__(8)(IteratorPrototype, __webpack_require__(43)('iterator'), function () {
-    return this;
-  });
-  
-  module.exports = function (Constructor, NAME, next) {
-    Constructor.prototype = create(IteratorPrototype, { next: descriptor(1, next) });
-    setToStringTag(Constructor, NAME + ' Iterator');
-  };
-
-/***/ },
-/* 50 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  // 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])
-  var anObject = __webpack_require__(10),
-      dPs = __webpack_require__(51),
-      enumBugKeys = __webpack_require__(36),
-      IE_PROTO = __webpack_require__(34)('IE_PROTO'),
-      Empty = function Empty() {/* empty */},
-      PROTOTYPE = 'prototype';
-  
-  // Create object with fake `null` prototype: use iframe Object with cleared prototype
-  var _createDict = function createDict() {
-    // Thrash, waste and sodomy: IE GC bug
-    var iframe = __webpack_require__(15)('iframe'),
-        i = enumBugKeys.length,
-        gt = '>',
-        iframeDocument;
-    iframe.style.display = 'none';
-    __webpack_require__(52).appendChild(iframe);
-    iframe.src = 'javascript:'; // eslint-disable-line no-script-url
-    // createDict = iframe.contentWindow.Object;
-    // html.removeChild(iframe);
-    iframeDocument = iframe.contentWindow.document;
-    iframeDocument.open();
-    iframeDocument.write('<script>document.F=Object</script' + gt);
-    iframeDocument.close();
-    _createDict = iframeDocument.F;
-    while (i--) {
-      delete _createDict[PROTOTYPE][enumBugKeys[i]];
-    }return _createDict();
-  };
-  
-  module.exports = Object.create || function create(O, Properties) {
-    var result;
-    if (O !== null) {
-      Empty[PROTOTYPE] = anObject(O);
-      result = new Empty();
-      Empty[PROTOTYPE] = null;
-      // add "__proto__" for Object.getPrototypeOf polyfill
-      result[IE_PROTO] = O;
-    } else result = _createDict();
-    return Properties === undefined ? result : dPs(result, Properties);
-  };
-
-/***/ },
-/* 51 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  var dP = __webpack_require__(9),
-      anObject = __webpack_require__(10),
-      getKeys = __webpack_require__(24);
-  
-  module.exports = __webpack_require__(13) ? Object.defineProperties : function defineProperties(O, Properties) {
-    anObject(O);
-    var keys = getKeys(Properties),
-        length = keys.length,
-        i = 0,
-        P;
-    while (length > i) {
-      dP.f(O, P = keys[i++], Properties[P]);
-    }return O;
-  };
-
-/***/ },
-/* 52 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  module.exports = __webpack_require__(6).document && document.documentElement;
-
-/***/ },
-/* 53 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  var def = __webpack_require__(9).f,
-      has = __webpack_require__(19),
-      TAG = __webpack_require__(43)('toStringTag');
-  
-  module.exports = function (it, tag, stat) {
-    if (it && !has(it = stat ? it : it.prototype, TAG)) def(it, TAG, { configurable: true, value: tag });
-  };
-
-/***/ },
-/* 54 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  // 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O)
-  var has = __webpack_require__(19),
-      toObject = __webpack_require__(39),
-      IE_PROTO = __webpack_require__(34)('IE_PROTO'),
-      ObjectProto = Object.prototype;
-  
-  module.exports = Object.getPrototypeOf || function (O) {
-    O = toObject(O);
-    if (has(O, IE_PROTO)) return O[IE_PROTO];
-    if (typeof O.constructor == 'function' && O instanceof O.constructor) {
-      return O.constructor.prototype;
-    }return O instanceof Object ? ObjectProto : null;
-  };
-
-/***/ },
-/* 55 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  var $iterators = __webpack_require__(56),
-      redefine = __webpack_require__(18),
-      global = __webpack_require__(6),
-      hide = __webpack_require__(8),
-      Iterators = __webpack_require__(48),
-      wks = __webpack_require__(43),
-      ITERATOR = wks('iterator'),
-      TO_STRING_TAG = wks('toStringTag'),
-      ArrayValues = Iterators.Array;
-  
-  for (var collections = ['NodeList', 'DOMTokenList', 'MediaList', 'StyleSheetList', 'CSSRuleList'], i = 0; i < 5; i++) {
-    var NAME = collections[i],
-        Collection = global[NAME],
-        proto = Collection && Collection.prototype,
-        key;
-    if (proto) {
-      if (!proto[ITERATOR]) hide(proto, ITERATOR, ArrayValues);
-      if (!proto[TO_STRING_TAG]) hide(proto, TO_STRING_TAG, NAME);
-      Iterators[NAME] = ArrayValues;
-      for (key in $iterators) {
-        if (!proto[key]) redefine(proto, key, $iterators[key], true);
-      }
-    }
-  }
-
-/***/ },
-/* 56 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  var addToUnscopables = __webpack_require__(57),
-      step = __webpack_require__(58),
-      Iterators = __webpack_require__(48),
-      toIObject = __webpack_require__(26);
-  
-  // 22.1.3.4 Array.prototype.entries()
-  // 22.1.3.13 Array.prototype.keys()
-  // 22.1.3.29 Array.prototype.values()
-  // 22.1.3.30 Array.prototype[@@iterator]()
-  module.exports = __webpack_require__(46)(Array, 'Array', function (iterated, kind) {
-    this._t = toIObject(iterated); // target
-    this._i = 0; // next index
-    this._k = kind; // kind
-    // 22.1.5.2.1 %ArrayIteratorPrototype%.next()
-  }, function () {
-    var O = this._t,
-        kind = this._k,
-        index = this._i++;
-    if (!O || index >= O.length) {
-      this._t = undefined;
-      return step(1);
-    }
-    if (kind == 'keys') return step(0, index);
-    if (kind == 'values') return step(0, O[index]);
-    return step(0, [index, O[index]]);
-  }, 'values');
-  
-  // argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7)
-  Iterators.Arguments = Iterators.Array;
-  
-  addToUnscopables('keys');
-  addToUnscopables('values');
-  addToUnscopables('entries');
-
-/***/ },
-/* 57 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  // 22.1.3.31 Array.prototype[@@unscopables]
-  var UNSCOPABLES = __webpack_require__(43)('unscopables'),
-      ArrayProto = Array.prototype;
-  if (ArrayProto[UNSCOPABLES] == undefined) __webpack_require__(8)(ArrayProto, UNSCOPABLES, {});
-  module.exports = function (key) {
-    ArrayProto[UNSCOPABLES][key] = true;
-  };
-
-/***/ },
-/* 58 */
-/***/ function(module, exports) {
-
-  "use strict";
-  
-  module.exports = function (done, value) {
-    return { value: value, done: !!done };
-  };
-
-/***/ },
-/* 59 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  var LIBRARY = __webpack_require__(47),
-      global = __webpack_require__(6),
-      ctx = __webpack_require__(21),
-      classof = __webpack_require__(42),
-      $export = __webpack_require__(5),
-      isObject = __webpack_require__(11),
-      anObject = __webpack_require__(10),
-      aFunction = __webpack_require__(22),
-      anInstance = __webpack_require__(60),
-      forOf = __webpack_require__(61),
-      setProto = __webpack_require__(65).set,
-      speciesConstructor = __webpack_require__(67),
-      task = __webpack_require__(68).set,
-      microtask = __webpack_require__(70),
-      PROMISE = 'Promise',
-      TypeError = global.TypeError,
-      process = global.process,
-      $Promise = global[PROMISE],
-      process = global.process,
-      isNode = classof(process) == 'process',
-      empty = function empty() {/* empty */},
-      Internal,
-      GenericPromiseCapability,
-      Wrapper;
-  
-  var USE_NATIVE = !!function () {
-    try {
-      // correct subclassing with @@species support
-      var promise = $Promise.resolve(1),
-          FakePromise = (promise.constructor = {})[__webpack_require__(43)('species')] = function (exec) {
-        exec(empty, empty);
-      };
-      // unhandled rejections tracking support, NodeJS Promise without it fails @@species test
-      return (isNode || typeof PromiseRejectionEvent == 'function') && promise.then(empty) instanceof FakePromise;
-    } catch (e) {/* empty */}
-  }();
-  
-  // helpers
-  var sameConstructor = function sameConstructor(a, b) {
-    // with library wrapper special case
-    return a === b || a === $Promise && b === Wrapper;
-  };
-  var isThenable = function isThenable(it) {
-    var then;
-    return isObject(it) && typeof (then = it.then) == 'function' ? then : false;
-  };
-  var newPromiseCapability = function newPromiseCapability(C) {
-    return sameConstructor($Promise, C) ? new PromiseCapability(C) : new GenericPromiseCapability(C);
-  };
-  var PromiseCapability = GenericPromiseCapability = function GenericPromiseCapability(C) {
-    var resolve, reject;
-    this.promise = new C(function ($$resolve, $$reject) {
-      if (resolve !== undefined || reject !== undefined) throw TypeError('Bad Promise constructor');
-      resolve = $$resolve;
-      reject = $$reject;
-    });
-    this.resolve = aFunction(resolve);
-    this.reject = aFunction(reject);
-  };
-  var perform = function perform(exec) {
-    try {
-      exec();
-    } catch (e) {
-      return { error: e };
-    }
-  };
-  var notify = function notify(promise, isReject) {
-    if (promise._n) return;
-    promise._n = true;
-    var chain = promise._c;
-    microtask(function () {
-      var value = promise._v,
-          ok = promise._s == 1,
-          i = 0;
-      var run = function run(reaction) {
-        var handler = ok ? reaction.ok : reaction.fail,
-            resolve = reaction.resolve,
-            reject = reaction.reject,
-            domain = reaction.domain,
-            result,
-            then;
-        try {
-          if (handler) {
-            if (!ok) {
-              if (promise._h == 2) onHandleUnhandled(promise);
-              promise._h = 1;
-            }
-            if (handler === true) result = value;else {
-              if (domain) domain.enter();
-              result = handler(value);
-              if (domain) domain.exit();
-            }
-            if (result === reaction.promise) {
-              reject(TypeError('Promise-chain cycle'));
-            } else if (then = isThenable(result)) {
-              then.call(result, resolve, reject);
-            } else resolve(result);
-          } else reject(value);
-        } catch (e) {
-          reject(e);
-        }
-      };
-      while (chain.length > i) {
-        run(chain[i++]);
-      } // variable length - can't use forEach
-      promise._c = [];
-      promise._n = false;
-      if (isReject && !promise._h) onUnhandled(promise);
-    });
-  };
-  var onUnhandled = function onUnhandled(promise) {
-    task.call(global, function () {
-      var value = promise._v,
-          abrupt,
-          handler,
-          console;
-      if (isUnhandled(promise)) {
-        abrupt = perform(function () {
-          if (isNode) {
-            process.emit('unhandledRejection', value, promise);
-          } else if (handler = global.onunhandledrejection) {
-            handler({ promise: promise, reason: value });
-          } else if ((console = global.console) && console.error) {
-            console.error('Unhandled promise rejection', value);
-          }
-        });
-        // Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should
-        promise._h = isNode || isUnhandled(promise) ? 2 : 1;
-      }promise._a = undefined;
-      if (abrupt) throw abrupt.error;
-    });
-  };
-  var isUnhandled = function isUnhandled(promise) {
-    if (promise._h == 1) return false;
-    var chain = promise._a || promise._c,
-        i = 0,
-        reaction;
-    while (chain.length > i) {
-      reaction = chain[i++];
-      if (reaction.fail || !isUnhandled(reaction.promise)) return false;
-    }return true;
-  };
-  var onHandleUnhandled = function onHandleUnhandled(promise) {
-    task.call(global, function () {
-      var handler;
-      if (isNode) {
-        process.emit('rejectionHandled', promise);
-      } else if (handler = global.onrejectionhandled) {
-        handler({ promise: promise, reason: promise._v });
-      }
-    });
-  };
-  var $reject = function $reject(value) {
-    var promise = this;
-    if (promise._d) return;
-    promise._d = true;
-    promise = promise._w || promise; // unwrap
-    promise._v = value;
-    promise._s = 2;
-    if (!promise._a) promise._a = promise._c.slice();
-    notify(promise, true);
-  };
-  var $resolve = function $resolve(value) {
-    var promise = this,
-        then;
-    if (promise._d) return;
-    promise._d = true;
-    promise = promise._w || promise; // unwrap
-    try {
-      if (promise === value) throw TypeError("Promise can't be resolved itself");
-      if (then = isThenable(value)) {
-        microtask(function () {
-          var wrapper = { _w: promise, _d: false }; // wrap
-          try {
-            then.call(value, ctx($resolve, wrapper, 1), ctx($reject, wrapper, 1));
-          } catch (e) {
-            $reject.call(wrapper, e);
-          }
-        });
-      } else {
-        promise._v = value;
-        promise._s = 1;
-        notify(promise, false);
-      }
-    } catch (e) {
-      $reject.call({ _w: promise, _d: false }, e); // wrap
-    }
-  };
-  
-  // constructor polyfill
-  if (!USE_NATIVE) {
-    // 25.4.3.1 Promise(executor)
-    $Promise = function Promise(executor) {
-      anInstance(this, $Promise, PROMISE, '_h');
-      aFunction(executor);
-      Internal.call(this);
-      try {
-        executor(ctx($resolve, this, 1), ctx($reject, this, 1));
-      } catch (err) {
-        $reject.call(this, err);
-      }
-    };
-    Internal = function Promise(executor) {
-      this._c = []; // <- awaiting reactions
-      this._a = undefined; // <- checked in isUnhandled reactions
-      this._s = 0; // <- state
-      this._d = false; // <- done
-      this._v = undefined; // <- value
-      this._h = 0; // <- rejection state, 0 - default, 1 - handled, 2 - unhandled
-      this._n = false; // <- notify
-    };
-    Internal.prototype = __webpack_require__(71)($Promise.prototype, {
-      // 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected)
-      then: function then(onFulfilled, onRejected) {
-        var reaction = newPromiseCapability(speciesConstructor(this, $Promise));
-        reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true;
-        reaction.fail = typeof onRejected == 'function' && onRejected;
-        reaction.domain = isNode ? process.domain : undefined;
-        this._c.push(reaction);
-        if (this._a) this._a.push(reaction);
-        if (this._s) notify(this, false);
-        return reaction.promise;
-      },
-      // 25.4.5.1 Promise.prototype.catch(onRejected)
-      'catch': function _catch(onRejected) {
-        return this.then(undefined, onRejected);
-      }
-    });
-    PromiseCapability = function PromiseCapability() {
-      var promise = new Internal();
-      this.promise = promise;
-      this.resolve = ctx($resolve, promise, 1);
-      this.reject = ctx($reject, promise, 1);
-    };
-  }
-  
-  $export($export.G + $export.W + $export.F * !USE_NATIVE, { Promise: $Promise });
-  __webpack_require__(53)($Promise, PROMISE);
-  __webpack_require__(72)(PROMISE);
-  Wrapper = __webpack_require__(7)[PROMISE];
-  
-  // statics
-  $export($export.S + $export.F * !USE_NATIVE, PROMISE, {
-    // 25.4.4.5 Promise.reject(r)
-    reject: function reject(r) {
-      var capability = newPromiseCapability(this),
-          $$reject = capability.reject;
-      $$reject(r);
-      return capability.promise;
-    }
-  });
-  $export($export.S + $export.F * (LIBRARY || !USE_NATIVE), PROMISE, {
-    // 25.4.4.6 Promise.resolve(x)
-    resolve: function resolve(x) {
-      // instanceof instead of internal slot check because we should fix it without replacement native Promise core
-      if (x instanceof $Promise && sameConstructor(x.constructor, this)) return x;
-      var capability = newPromiseCapability(this),
-          $$resolve = capability.resolve;
-      $$resolve(x);
-      return capability.promise;
-    }
-  });
-  $export($export.S + $export.F * !(USE_NATIVE && __webpack_require__(73)(function (iter) {
-    $Promise.all(iter)['catch'](empty);
-  })), PROMISE, {
-    // 25.4.4.1 Promise.all(iterable)
-    all: function all(iterable) {
-      var C = this,
-          capability = newPromiseCapability(C),
-          resolve = capability.resolve,
-          reject = capability.reject;
-      var abrupt = perform(function () {
-        var values = [],
-            index = 0,
-            remaining = 1;
-        forOf(iterable, false, function (promise) {
-          var $index = index++,
-              alreadyCalled = false;
-          values.push(undefined);
-          remaining++;
-          C.resolve(promise).then(function (value) {
-            if (alreadyCalled) return;
-            alreadyCalled = true;
-            values[$index] = value;
-            --remaining || resolve(values);
-          }, reject);
-        });
-        --remaining || resolve(values);
-      });
-      if (abrupt) reject(abrupt.error);
-      return capability.promise;
-    },
-    // 25.4.4.4 Promise.race(iterable)
-    race: function race(iterable) {
-      var C = this,
-          capability = newPromiseCapability(C),
-          reject = capability.reject;
-      var abrupt = perform(function () {
-        forOf(iterable, false, function (promise) {
-          C.resolve(promise).then(capability.resolve, reject);
-        });
-      });
-      if (abrupt) reject(abrupt.error);
-      return capability.promise;
-    }
-  });
-
-/***/ },
-/* 60 */
-/***/ function(module, exports) {
-
-  'use strict';
-  
-  module.exports = function (it, Constructor, name, forbiddenField) {
-    if (!(it instanceof Constructor) || forbiddenField !== undefined && forbiddenField in it) {
-      throw TypeError(name + ': incorrect invocation!');
-    }return it;
-  };
-
-/***/ },
-/* 61 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  var ctx = __webpack_require__(21),
-      call = __webpack_require__(62),
-      isArrayIter = __webpack_require__(63),
-      anObject = __webpack_require__(10),
-      toLength = __webpack_require__(31),
-      getIterFn = __webpack_require__(64);
-  module.exports = function (iterable, entries, fn, that, ITERATOR) {
-    var iterFn = ITERATOR ? function () {
-      return iterable;
-    } : getIterFn(iterable),
-        f = ctx(fn, that, entries ? 2 : 1),
-        index = 0,
-        length,
-        step,
-        iterator;
-    if (typeof iterFn != 'function') throw TypeError(iterable + ' is not iterable!');
-    // fast case for arrays with default iterator
-    if (isArrayIter(iterFn)) for (length = toLength(iterable.length); length > index; index++) {
-      entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]);
-    } else for (iterator = iterFn.call(iterable); !(step = iterator.next()).done;) {
-      call(iterator, f, step.value, entries);
-    }
-  };
-
-/***/ },
-/* 62 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  // call something on iterator step with safe closing on error
-  var anObject = __webpack_require__(10);
-  module.exports = function (iterator, fn, value, entries) {
-    try {
-      return entries ? fn(anObject(value)[0], value[1]) : fn(value);
-      // 7.4.6 IteratorClose(iterator, completion)
-    } catch (e) {
-      var ret = iterator['return'];
-      if (ret !== undefined) anObject(ret.call(iterator));
-      throw e;
-    }
-  };
-
-/***/ },
-/* 63 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  // check on default Array iterator
-  var Iterators = __webpack_require__(48),
-      ITERATOR = __webpack_require__(43)('iterator'),
-      ArrayProto = Array.prototype;
-  
-  module.exports = function (it) {
-    return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it);
-  };
-
-/***/ },
-/* 64 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  var classof = __webpack_require__(42),
-      ITERATOR = __webpack_require__(43)('iterator'),
-      Iterators = __webpack_require__(48);
-  module.exports = __webpack_require__(7).getIteratorMethod = function (it) {
-    if (it != undefined) return it[ITERATOR] || it['@@iterator'] || Iterators[classof(it)];
-  };
-
-/***/ },
-/* 65 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  // Works with __proto__ only. Old v8 can't work with null proto objects.
-  /* eslint-disable no-proto */
-  var isObject = __webpack_require__(11),
-      anObject = __webpack_require__(10);
-  var check = function check(O, proto) {
-    anObject(O);
-    if (!isObject(proto) && proto !== null) throw TypeError(proto + ": can't set as prototype!");
-  };
-  module.exports = {
-    set: Object.setPrototypeOf || ('__proto__' in {} ? // eslint-disable-line
-    function (test, buggy, set) {
-      try {
-        set = __webpack_require__(21)(Function.call, __webpack_require__(66).f(Object.prototype, '__proto__').set, 2);
-        set(test, []);
-        buggy = !(test instanceof Array);
-      } catch (e) {
-        buggy = true;
-      }
-      return function setPrototypeOf(O, proto) {
-        check(O, proto);
-        if (buggy) O.__proto__ = proto;else set(O, proto);
-        return O;
-      };
-    }({}, false) : undefined),
-    check: check
-  };
-
-/***/ },
-/* 66 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  var pIE = __webpack_require__(38),
-      createDesc = __webpack_require__(17),
-      toIObject = __webpack_require__(26),
-      toPrimitive = __webpack_require__(16),
-      has = __webpack_require__(19),
-      IE8_DOM_DEFINE = __webpack_require__(12),
-      gOPD = Object.getOwnPropertyDescriptor;
-  
-  exports.f = __webpack_require__(13) ? gOPD : function getOwnPropertyDescriptor(O, P) {
-    O = toIObject(O);
-    P = toPrimitive(P, true);
-    if (IE8_DOM_DEFINE) try {
-      return gOPD(O, P);
-    } catch (e) {/* empty */}
-    if (has(O, P)) return createDesc(!pIE.f.call(O, P), O[P]);
-  };
-
-/***/ },
-/* 67 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  // 7.3.20 SpeciesConstructor(O, defaultConstructor)
-  var anObject = __webpack_require__(10),
-      aFunction = __webpack_require__(22),
-      SPECIES = __webpack_require__(43)('species');
-  module.exports = function (O, D) {
-    var C = anObject(O).constructor,
-        S;
-    return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S);
-  };
-
-/***/ },
-/* 68 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  var ctx = __webpack_require__(21),
-      invoke = __webpack_require__(69),
-      html = __webpack_require__(52),
-      cel = __webpack_require__(15),
-      global = __webpack_require__(6),
-      process = global.process,
-      setTask = global.setImmediate,
-      clearTask = global.clearImmediate,
-      MessageChannel = global.MessageChannel,
-      counter = 0,
-      queue = {},
-      ONREADYSTATECHANGE = 'onreadystatechange',
-      defer,
-      channel,
-      port;
-  var run = function run() {
-    var id = +this;
-    if (queue.hasOwnProperty(id)) {
-      var fn = queue[id];
-      delete queue[id];
-      fn();
-    }
-  };
-  var listener = function listener(event) {
-    run.call(event.data);
-  };
-  // Node.js 0.9+ & IE10+ has setImmediate, otherwise:
-  if (!setTask || !clearTask) {
-    setTask = function setImmediate(fn) {
-      var args = [],
-          i = 1;
-      while (arguments.length > i) {
-        args.push(arguments[i++]);
-      }queue[++counter] = function () {
-        invoke(typeof fn == 'function' ? fn : Function(fn), args);
-      };
-      defer(counter);
-      return counter;
-    };
-    clearTask = function clearImmediate(id) {
-      delete queue[id];
-    };
-    // Node.js 0.8-
-    if (__webpack_require__(28)(process) == 'process') {
-      defer = function defer(id) {
-        process.nextTick(ctx(run, id, 1));
-      };
-      // Browsers with MessageChannel, includes WebWorkers
-    } else if (MessageChannel) {
-        channel = new MessageChannel();
-        port = channel.port2;
-        channel.port1.onmessage = listener;
-        defer = ctx(port.postMessage, port, 1);
-        // Browsers with postMessage, skip WebWorkers
-        // IE8 has postMessage, but it's sync & typeof its postMessage is 'object'
-      } else if (global.addEventListener && typeof postMessage == 'function' && !global.importScripts) {
-          defer = function defer(id) {
-            global.postMessage(id + '', '*');
-          };
-          global.addEventListener('message', listener, false);
-          // IE8-
-        } else if (ONREADYSTATECHANGE in cel('script')) {
-            defer = function defer(id) {
-              html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function () {
-                html.removeChild(this);
-                run.call(id);
-              };
-            };
-            // Rest old browsers
-          } else {
-              defer = function defer(id) {
-                setTimeout(ctx(run, id, 1), 0);
-              };
-            }
-  }
-  module.exports = {
-    set: setTask,
-    clear: clearTask
-  };
-
-/***/ },
-/* 69 */
-/***/ function(module, exports) {
-
-  "use strict";
-  
-  // fast apply, http://jsperf.lnkit.com/fast-apply/5
-  module.exports = function (fn, args, that) {
-                    var un = that === undefined;
-                    switch (args.length) {
-                                      case 0:
-                                                        return un ? fn() : fn.call(that);
-                                      case 1:
-                                                        return un ? fn(args[0]) : fn.call(that, args[0]);
-                                      case 2:
-                                                        return un ? fn(args[0], args[1]) : fn.call(that, args[0], args[1]);
-                                      case 3:
-                                                        return un ? fn(args[0], args[1], args[2]) : fn.call(that, args[0], args[1], args[2]);
-                                      case 4:
-                                                        return un ? fn(args[0], args[1], args[2], args[3]) : fn.call(that, args[0], args[1], args[2], args[3]);
-                    }return fn.apply(that, args);
-  };
-
-/***/ },
-/* 70 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  var global = __webpack_require__(6),
-      macrotask = __webpack_require__(68).set,
-      Observer = global.MutationObserver || global.WebKitMutationObserver,
-      process = global.process,
-      Promise = global.Promise,
-      isNode = __webpack_require__(28)(process) == 'process',
-      head,
-      last,
-      notify;
-  
-  var flush = function flush() {
-    var parent, fn;
-    if (isNode && (parent = process.domain)) parent.exit();
-    while (head) {
-      fn = head.fn;
-      fn(); // <- currently we use it only for Promise - try / catch not required
-      head = head.next;
-    }last = undefined;
-    if (parent) parent.enter();
-  };
-  
-  // Node.js
-  if (isNode) {
-    notify = function notify() {
-      process.nextTick(flush);
-    };
-    // browsers with MutationObserver
-  } else if (Observer) {
-      var toggle = true,
-          node = document.createTextNode('');
-      new Observer(flush).observe(node, { characterData: true }); // eslint-disable-line no-new
-      notify = function notify() {
-        node.data = toggle = !toggle;
-      };
-      // environments with maybe non-completely correct, but existent Promise
-    } else if (Promise && Promise.resolve) {
-        notify = function notify() {
-          Promise.resolve().then(flush);
-        };
-        // for other environments - macrotask based on:
-        // - setImmediate
-        // - MessageChannel
-        // - window.postMessag
-        // - onreadystatechange
-        // - setTimeout
-      } else {
-          notify = function notify() {
-            // strange IE + webpack dev server bug - use .call(global)
-            macrotask.call(global, flush);
-          };
-        }
-  
-  module.exports = function (fn) {
-    var task = { fn: fn, next: undefined };
-    if (last) last.next = task;
-    if (!head) {
-      head = task;
-      notify();
-    }last = task;
-  };
-
-/***/ },
-/* 71 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  var redefine = __webpack_require__(18);
-  module.exports = function (target, src, safe) {
-    for (var key in src) {
-      redefine(target, key, src[key], safe);
-    }return target;
-  };
-
-/***/ },
-/* 72 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  var global = __webpack_require__(6),
-      dP = __webpack_require__(9),
-      DESCRIPTORS = __webpack_require__(13),
-      SPECIES = __webpack_require__(43)('species');
-  
-  module.exports = function (KEY) {
-    var C = global[KEY];
-    if (DESCRIPTORS && C && !C[SPECIES]) dP.f(C, SPECIES, {
-      configurable: true,
-      get: function get() {
-        return this;
-      }
-    });
-  };
-
-/***/ },
-/* 73 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  var ITERATOR = __webpack_require__(43)('iterator'),
-      SAFE_CLOSING = false;
-  
-  try {
-    var riter = [7][ITERATOR]();
-    riter['return'] = function () {
-      SAFE_CLOSING = true;
-    };
-    Array.from(riter, function () {
-      throw 2;
-    });
-  } catch (e) {/* empty */}
-  
-  module.exports = function (exec, skipClosing) {
-    if (!skipClosing && !SAFE_CLOSING) return false;
-    var safe = false;
-    try {
-      var arr = [7],
-          iter = arr[ITERATOR]();
-      iter.next = function () {
-        safe = true;
-      };
-      arr[ITERATOR] = function () {
-        return iter;
-      };
-      exec(arr);
-    } catch (e) {/* empty */}
-    return safe;
-  };
-
-/***/ },
-/* 74 */
-/***/ function(module, exports) {
-
-  /* WEBPACK VAR INJECTION */(function(global) {'use strict';
-  
-  var _global = global;
-  var setTimeout = _global.setTimeout;
-  var setTimeoutNative = _global.setTimeoutNative;
-  
-  // fix no setTimeout on Android V8
-  
-  if (typeof setTimeout === 'undefined' && typeof setTimeoutNative === 'function') {
-    (function () {
-      var timeoutMap = {};
-      var timeoutId = 0;
-      global.setTimeout = function (cb, time) {
-        timeoutMap[++timeoutId] = cb;
-        setTimeoutNative(timeoutId.toString(), time);
-      };
-      global.setTimeoutCallback = function (id) {
-        if (typeof timeoutMap[id] === 'function') {
-          timeoutMap[id]();
-          delete timeoutMap[id];
-        }
-      };
-    })();
-  }
-  /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
-
-/***/ },
-/* 75 */
-/***/ function(module, exports) {
-
-  /* WEBPACK VAR INJECTION */(function(global) {'use strict';
-  
-  var _global = global;
-  var console = _global.console;
-  
-  
-  if (typeof console === 'undefined') {
-    global.console = {
-      log: function log() {
-        if (typeof nativeLog === 'function') {
-          nativeLog.apply(undefined, arguments);
-        }
-      },
-      error: function error() {
-        for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
-          args[_key] = arguments[_key];
-        }
-  
-        throw new Error(args);
-      }
-    };
-  }
-  /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
-
-/***/ },
-/* 76 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  Object.defineProperty(exports, "__esModule", {
-    value: true
-  });
-  
-  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; /**
-                                                                                                                                                                                                                                                     * @fileOverview Main entry, instance manager
-                                                                                                                                                                                                                                                     *
-                                                                                                                                                                                                                                                     * - createInstance(instanceId, code, options, data)
-                                                                                                                                                                                                                                                     * - refreshInstance(instanceId, data)
-                                                                                                                                                                                                                                                     * - destroyInstance(instanceId)
-                                                                                                                                                                                                                                                     * - registerComponents(components)
-                                                                                                                                                                                                                                                     * - registerModules(modules)
-                                                                                                                                                                                                                                                     * - getRoot(instanceId)
-                                                                                                                                                                                                                                                     * - instanceMap
-                                                                                                                                                                                                                                                     * - callJS(instanceId, tasks)
-                                                                                                                                                                                                                                                     *   - fireEvent(ref, type, data)
-                                                                                                                                                                                                                                                     *   - callback(funcId, data)
-                                                                                                                                                                                                                                                     */
-  
-  exports.createInstance = createInstance;
-  exports.refreshInstance = refreshInstance;
-  exports.destroyInstance = destroyInstance;
-  exports.registerComponents = registerComponents;
-  exports.registerModules = registerModules;
-  exports.registerMethods = registerMethods;
-  exports.getRoot = getRoot;
-  exports.callJS = callJS;
-  
-  var _perf = __webpack_require__(77);
-  
-  var perf = _interopRequireWildcard(_perf);
-  
-  var _config = __webpack_require__(79);
-  
-  var config = _interopRequireWildcard(_config);
-  
-  var _app = __webpack_require__(80);
-  
-  var _app2 = _interopRequireDefault(_app);
-  
-  var _vm = __webpack_require__(85);
-  
-  var _vm2 = _interopRequireDefault(_vm);
-  
-  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-  
-  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
-  
-  function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
-  
-  var nativeComponentMap = config.nativeComponentMap;
-  
-  var instanceMap = {};
-  
-  /**
-   * create a Weex instance
-   *
-   * @param  {string} instanceId
-   * @param  {string} code
-   * @param  {object} [options] option `HAS_LOG` enable print log
-   * @param  {object} [data]
-   */
-  function createInstance(instanceId, code, options, data) {
-    var instance = instanceMap[instanceId];
-    options = options || {};
-  
-    config.debug = options.debug;
-  
-    var result;
-    if (!instance) {
-      perf.start('createInstance', instanceId);
-      instance = new _app2.default(instanceId, options);
-      instanceMap[instanceId] = instance;
-      result = instance.init(code, data);
-      perf.end('createInstance', instanceId);
-    } else {
-      result = new Error('invalid instance id "' + instanceId + '"');
-    }
-  
-    return result;
-  }
-  
-  /**
-   * refresh a Weex instance
-   *
-   * @param  {string} instanceId
-   * @param  {object} data
-   */
-  function refreshInstance(instanceId, data) {
-    var instance = instanceMap[instanceId];
-    var result;
-    if (instance) {
-      perf.start('refreshData', instanceId);
-      result = instance.refreshData(data);
-      perf.end('refreshData', instanceId);
-    } else {
-      result = new Error('invalid instance id "' + instanceId + '"');
-    }
-    return result;
-  }
-  
-  /**
-   * destroy a Weex instance
-   * @param  {string} instanceId
-   */
-  function destroyInstance(instanceId) {
-    var instance = instanceMap[instanceId];
-    if (!instance) {
-      return new Error('invalid instance id "' + instanceId + '"');
-    }
-  
-    perf.start('destroyInstance', instanceId);
-    instance.destroy();
-    delete instanceMap[instanceId];
-    perf.end('destroyInstance', instanceId);
-  
-    return instanceMap;
-  }
-  
-  /**
-   * register the name of each native component
-   * @param  {array} components array of name
-   */
-  function registerComponents(components) {
-    if (Array.isArray(components)) {
-      components.forEach(function register(name) {
-        /* istanbul ignore if */
-        if (!name) {
-          return;
-        }
-        if (typeof name === 'string') {
-          nativeComponentMap[name] = true;
-        } else if ((typeof name === 'undefined' ? 'undefined' : _typeof(name)) === 'object' && typeof name.type === 'string') {
-          nativeComponentMap[name.type] = name;
-        }
-      });
-    }
-  }
-  
-  /**
-   * register the name and methods of each module
-   * @param  {object} modules a object of modules
-   */
-  function registerModules(modules) {
-    if ((typeof modules === 'undefined' ? 'undefined' : _typeof(modules)) === 'object') {
-      _vm2.default.registerModules(modules);
-    }
-  }
-  
-  /**
-   * register the name and methods of each api
-   * @param  {object} apis a object of apis
-   */
-  function registerMethods(apis) {
-    if ((typeof apis === 'undefined' ? 'undefined' : _typeof(apis)) === 'object') {
-      _vm2.default.registerMethods(apis);
-    }
-  }
-  
-  /**
-   * get a whole element tree of an instance
-   * for debugging
-   * @param  {string} instanceId
-   * @return {object} a virtual dom tree
-   */
-  function getRoot(instanceId) {
-    var instance = instanceMap[instanceId];
-    var result;
-    if (instance) {
-      result = instance.getRootElement();
-    } else {
-      result = new Error('invalid instance id "' + instanceId + '"');
-    }
-    return result;
-  }
-  
-  var jsHandlers = {
-    fireEvent: function fireEvent(instanceId, ref, type, data) {
-      var instance = instanceMap[instanceId];
-      var result;
-      perf.start('fireEvent', instanceId + '-' + ref + '-' + type);
-      result = instance.fireEvent(ref, type, data);
-      perf.end('fireEvent', instanceId + '-' + ref + '-' + type);
-      return result;
-    },
-  
-    callback: function callback(instanceId, funcId, data, ifLast) {
-      var instance = instanceMap[instanceId];
-      var result;
-      perf.start('callback', instanceId + '-' + funcId + '-' + data + '-' + ifLast);
-      result = instance.callback(funcId, data, ifLast);
-      perf.end('callback', instanceId + '-' + funcId + '-' + data + '-' + ifLast);
-      return result;
-    }
-  };
-  
-  /**
-   * accept calls from native (event or callback)
-   *
-   * @param  {string} instanceId
-   * @param  {array} tasks list with `method` and `args`
-   */
-  function callJS(instanceId, tasks) {
-    var instance = instanceMap[instanceId];
-    var results = [];
-    if (instance && Array.isArray(tasks)) {
-      tasks.forEach(function (task) {
-        var handler = jsHandlers[task.method];
-        var args = [].concat(_toConsumableArray(task.args));
-        if (typeof handler === 'function') {
-          log('javascript:', task.method, task.args);
-          args.unshift(instanceId);
-          results.push(handler.apply(undefined, _toConsumableArray(args)));
-        }
-      });
-    } else {
-      results.push(new Error('invalid instance id "' + instanceId + '" or tasks'));
-    }
-  
-    return results;
-  }
-
-/***/ },
-/* 77 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  Object.defineProperty(exports, "__esModule", {
-    value: true
-  });
-  exports.start = start;
-  exports.end = end;
-  exports.reset = reset;
-  exports.toJSON = toJSON;
-  
-  var _log = __webpack_require__(78);
-  
-  var _log2 = _interopRequireDefault(_log);
-  
-  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-  
-  var data = { type: 'root', children: [] };
-  var current = data;
-  var stack = [current];
-  
-  function spaces(num) {
-    return Array(num).join(' ');
-  }
-  
-  function start(type, id) {
-    var task = { type: type, id: id, children: [], start: Date.now() };
-    current.children.push(task);
-    stack.push(task);
-    current = task;
-    (0, _log2.default)('perf:' + spaces(stack.length - 1), 'start', task.type, task.id);
-  }
-  
-  function end(type, id) {
-    var task = stack.pop();
-    task.end = Date.now();
-    current = stack[stack.length - 1];
-    (0, _log2.default)('perf:' + spaces(stack.length), 'end', task.end - task.start + 'ms', task.type, task.id);
-  }
-  
-  function reset() {
-    data.children = [];
-    current = data;
-    stack.length = 0;
-    stack.push(current);
-  }
-  
-  function toJSON() {
-    return JSON.parse(JSON.stringify(data));
-  }
-
-/***/ },
-/* 78 */
-/***/ function(module, exports, __webpack_require__) {
-
-  /* WEBPACK VAR INJECTION */(function(global) {'use strict';
-  
-  Object.defineProperty(exports, "__esModule", {
-    value: true
-  });
-  exports.default = log;
-  
-  var _config = __webpack_require__(79);
-  
-  var config = _interopRequireWildcard(_config);
-  
-  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
-  
-  function log() {
-    if (config.debug) {
-      var _global$console;
-  
-      (_global$console = global.console).log.apply(_global$console, arguments);
-    }
-  }
-  
-  global.log = log;
-  /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
-
-/***/ },
-/* 79 */
-/***/ function(module, exports) {
-
-  'use strict';
-  
-  Object.defineProperty(exports, "__esModule", {
-    value: true
-  });
-  var nativeComponentMap = exports.nativeComponentMap = {
-    text: true,
-    image: true,
-    container: true,
-    slider: {
-      type: 'slider',
-      append: 'tree'
-    },
-    cell: {
-      type: 'cell',
-      append: 'tree'
-    }
-  };
-  
-  var customComponentMap = exports.customComponentMap = {};
-  
-  var debug = exports.debug = false;
-
-/***/ },
-/* 80 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  Object.defineProperty(exports, "__esModule", {
-    value: true
-  });
-  exports.default = AppInstance;
-  
-  var _util = __webpack_require__(81);
-  
-  var _perf = __webpack_require__(77);
-  
-  var perf = _interopRequireWildcard(_perf);
-  
-  var _bundle = __webpack_require__(82);
-  
-  var bundle = _interopRequireWildcard(_bundle);
-  
-  var _ctrl = __webpack_require__(100);
-  
-  var ctrl = _interopRequireWildcard(_ctrl);
-  
-  var _differ = __webpack_require__(102);
-  
-  var _differ2 = _interopRequireDefault(_differ);
-  
-  var _event = __webpack_require__(103);
-  
-  var _event2 = _interopRequireDefault(_event);
-  
-  var _domListener = __webpack_require__(101);
-  
-  var _domListener2 = _interopRequireDefault(_domListener);
-  
-  var _dom = __webpack_require__(104);
-  
-  var _register = __webpack_require__(98);
-  
-  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-  
-  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
-  
-  function AppInstance(instanceId, options) {
-    var _this = this;
-  
-    perf.start('initInstance', instanceId);
-    this.id = instanceId;
-    this.options = options || {};
-    this.vm = null;
-    this.doc = new _dom.Document(instanceId);
-    this.customComponentMap = {};
-    this.callbacks = {};
-    this.differ = new _differ2.default(instanceId);
-    this.uid = 0;
-    this.rendered = false;
-    this.eventManager = new _event2.default();
-    this.listener = new _domListener2.default(this.id, function (tasks) {
-      _this.callTasks(tasks);
-    });
-    this.doc.setEventManager(this.eventManager);
-    this.doc.setListener(this.listener);
-  
-    perf.end('initInstance', instanceId);
-  } /**
-     * @fileOverview
-     * Weex instance constructor & definition
-     */
-  
-  function normalize(app, v) {
-    var type = (0, _util.typof)(v);
-  
-    switch (type) {
-      case 'undefined':
-      case 'null':
-        return '';
-      case 'regexp':
-        return v.toString();
-      case 'date':
-        return v.toISOString();
-      case 'number':
-      case 'string':
-      case 'boolean':
-      case 'array':
-      case 'object':
-        if (v instanceof _dom.Node) {
-          return v.ref;
-        }
-        return v;
-      case 'function':
-        app.callbacks[++app.uid] = v;
-        return app.uid.toString();
-      default:
-        return JSON.stringify(v);
-    }
-  }
-  
-  AppInstance.prototype.callTasks = function (tasks) {
-    var _this2 = this;
-  
-    if ((0, _util.typof)(tasks) !== 'array') {
-      tasks = [tasks];
-    }
-  
-    tasks.forEach(function (task) {
-      task.args = task.args.map(function (arg) {
-        return normalize(_this2, arg);
-      });
-    });
-  
-    callNative(this.id, tasks, '-1');
-  };
-  
-  (0, _util.extend)(AppInstance.prototype, bundle, ctrl, {
-    registerComponent: _register.registerComponent,
-    requireComponent: _register.requireComponent,
-    requireModule: _register.requireModule
-  });
-
-/***/ },
-/* 81 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  Object.defineProperty(exports, "__esModule", {
-    value: true
-  });
-  exports.warn = exports.log = exports.indexOf = exports.define = exports.normalize = exports.typof = exports.stringify = exports.isArray = exports.isPlainObject = exports.isObject = exports.extend = exports.toArray = exports.bind = exports.camelize = exports.isReserved = undefined;
-  
-  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; /// lang.js
-  
-  
-  var _config2 = __webpack_require__(79);
-  
-  var _config3 = _interopRequireDefault(_config2);
-  
-  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-  
-  /**
-   * Check is a string starts with $ or _
-   *
-   * @param {String} str
-   * @return {Boolean}
-   */
-  
-  var isReserved = exports.isReserved = function isReserved(str) {
-    var c = (str + '').charCodeAt(0);
-    return c === 0x24 || c === 0x5F;
-  };
-  
-  /**
-   * Camelize a hyphen-delmited string.
-   *
-   * @param {String} str
-   * @return {String}
-   */
-  
-  var camelRE = /-(\w)/g;
-  function toUpper(_, c) {
-    return c ? c.toUpperCase() : '';
-  }
-  var camelize = exports.camelize = function camelize(str) {
-    return str.replace(camelRE, toUpper);
-  };
-  
-  /**
-   * Simple bind, faster than native
-   *
-   * @param {Function} fn
-   * @param {Object} ctx
-   * @return {Function}
-   */
-  
-  var bind = exports.bind = function bind(fn, ctx) {
-    return function (a) {
-      var l = arguments.length;
-      return l ? l > 1 ? fn.apply(ctx, arguments) : fn.call(ctx, a) : fn.call(ctx);
-    };
-  };
-  
-  /**
-   * Convert an Array-like object to a real Array.
-   *
-   * @param {Array-like} list
-   * @param {Number} [start] - start index
-   * @return {Array}
-   */
-  
-  var toArray = exports.toArray = 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.
-   *
-   * @param {Object} to
-   * @param {Object} from
-   */
-  
-  var extend = exports.extend = function extend(target) {
-    for (var _len = arguments.length, src = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
-      src[_key - 1] = arguments[_key];
-    }
-  
-    if (typeof Object.assign === 'function') {
-      Object.assign.apply(Object, [target].concat(src));
-    } else {
-      var first = src.shift();
-      for (var key in first) {
-        target[key] = first[key];
-      }
-      if (src.length) {
-        extend.apply(undefined, [target].concat(src));
-      }
-    }
-    return target;
-  };
-  
-  /**
-   * Quick object check - this is primarily used to tell
-   * Objects from primitive values when we know the value
-   * is a JSON-compliant type.
-   *
-   * @param {*} obj
-   * @return {Boolean}
-   */
-  
-  var isObject = exports.isObject = function isObject(obj) {
-    return !!(obj && (typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object');
-  };
-  
-  /**
-   * Strict object type check. Only returns true
-   * for plain JavaScript objects.
-   *
-   * @param {*} obj
-   * @return {Boolean}
-   */
-  
-  var toString = Object.prototype.toString;
-  var isPlainObject = exports.isPlainObject = function isPlainObject(obj) {
-    return toString.call(obj) === '[object Object]';
-  };
-  
-  /**
-   * Array type check.
-   *
-   * @param {*} obj
-   * @return {Boolean}
-   */
-  
-  var isArray = exports.isArray = function isArray(obj) {
-    return Array.isArray(obj);
-  };
-  
-  var stringify = exports.stringify = function stringify(x) {
-    return typeof x === 'undefined' || x === null || typeof x === 'function' ? '' : (typeof x === 'undefined' ? 'undefined' : _typeof(x)) === 'object' ? x instanceof RegExp ? x.toString() : x instanceof Date ? JSON.parse(JSON.stringify(x)) : JSON.stringify(x) : x.toString();
-  };
-  
-  var typof = exports.typof = function typof(v) {
-    var s = Object.prototype.toString.call(v);
-    return s.substring(8, s.length - 1).toLowerCase();
-  };
-  
-  var normalize = exports.normalize = function normalize(v) {
-    var type = typof(v);
-  
-    switch (type) {
-      case 'undefined':
-      case 'null':
-        return '';
-      case 'regexp':
-        return v.toString();
-      case 'date':
-        return v.toISOString();
-      case 'number':
-      case 'string':
-      case 'boolean':
-      case 'array':
-      case 'object':
-      case 'function':
-        return v;
-      default:
-        return JSON.stringify(v);
-    }
-  };
-  
-  /**
-   * Define a non-enumerable property
-   *
-   * @param {Object} obj
-   * @param {String} key
-   * @param {*} val
-   * @param {Boolean} [enumerable]
-   */
-  
-  var define = exports.define = function define(obj, key, val, enumerable) {
-    Object.defineProperty(obj, key, {
-      value: val,
-      enumerable: !!enumerable,
-      writable: true,
-      configurable: true
-    });
-  };
-  
-  /**
-   * Manual indexOf because it's slightly faster than
-   * native.
-   *
-   * @param {Array} arr
-   * @param {*} obj
-   */
-  
-  var indexOf = exports.indexOf = function indexOf(arr, obj) {
-    for (var i = 0, l = arr.length; i < l; i++) {
-      if (arr[i] === obj) return i;
-    }
-    return -1;
-  };
-  
-  /// debug.js
-  
-  var hasConsole = typeof console !== 'undefined';
-  
-  /**
-   * Log a message.
-   *
-   * @param {String} msg
-   */
-  
-  var log = exports.log = function log(msg) {
-    var _config = _config3.default || {};
-    if (hasConsole && _config.debug) {
-      console.log.call(undefined, '[info]: ', msg);
-    }
-  };
-  
-  /**
-   * We've got a problem here.
-   *
-   * @param {String} msg
-   */
-  
-  var warn = exports.warn = function warn(msg) {
-    // if (hasConsole && (!config.silent || config.debug)) {
-    if (hasConsole) {
-      console.warn.call(undefined, '[warn]: ', msg);
-      /* istanbul ignore if */
-      // if (config.debug) {
-      //   /* jshint debug: true */
-      //   debugger
-      // }
-    }
-  };
-
-/***/ },
-/* 82 */
-/***/ function(module, exports, __webpack_require__) {
-
-  /* WEBPACK VAR INJECTION */(function(global) {'use strict';
-  
-  Object.defineProperty(exports, "__esModule", {
-    value: true
-  });
-  exports.require = exports.define = undefined;
-  exports.clearCommonModules = clearCommonModules;
-  exports.bootstrap = bootstrap;
-  exports.register = register;
-  exports.render = render;
-  
-  var _semver = __webpack_require__(83);
-  
-  var _semver2 = _interopRequireDefault(_semver);
-  
-  var _util = __webpack_require__(81);
-  
-  var _ = _interopRequireWildcard(_util);
-  
-  var _config = __webpack_require__(79);
-  
-  var config = _interopRequireWildcard(_config);
-  
-  var _perf = __webpack_require__(77);
-  
-  var perf = _interopRequireWildcard(_perf);
-  
-  var _vm = __webpack_require__(85);
-  
-  var _vm2 = _interopRequireDefault(_vm);
-  
-  var _downgrade = __webpack_require__(99);
-  
-  var downgrade = _interopRequireWildcard(_downgrade);
-  
-  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
-  
-  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-  
-  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } /**
-                                                                                                                                                                                                                     * @fileOverview
-                                                                                                                                                                                                                     * api that invoked by js bundle code
-                                                                                                                                                                                                                     *
-                                                                                                                                                                                                                     * - define(name, factory): define a new composed component type
-                                                                                                                                                                                                                     * - bootstrap(type, config, data): require a certain type &
-                                                                                                                                                                                                                     *         render with (optional) data
-                                                                                                                                                                                                                     *
-                                                                                                                                                                                                                     * deprecated:
-                                                                                                                                                                                                                     * - register(type, options): register a new composed component type
-                                                                                                                                                                                                                     * - render(type, data): render by a certain type with (optional) data
-                                                                                                                                                                                                                     * - require(type)(data): require a type then render with data
-                                                                                                                                                                                                                     */
-  
-  var WEEX_COMPONENT_REG = /^\@weex-component\//;
-  var WEEX_MODULE_REG = /^\@weex-module\//;
-  var NORMAL_MODULE_REG = /^\.{1,2}\//;
-  var JS_SURFIX_REG = /\.js$/;
-  
-  var isWeexComponent = function isWeexComponent(name) {
-    return !!name.match(WEEX_COMPONENT_REG);
-  };
-  var isWeexModule = function isWeexModule(name) {
-    return !!name.match(WEEX_MODULE_REG);
-  };
-  var isNormalModule = function isNormalModule(name) {
-    return !!name.match(NORMAL_MODULE_REG);
-  };
-  var isNpmModule = function isNpmModule(name) {
-    return !isWeexComponent(name) && !isWeexModule(name) && !isNormalModule(name);
-  };
-  
-  function removeWeexPrefix(str) {
-    return str.replace(WEEX_COMPONENT_REG, '').replace(WEEX_MODULE_REG, '');
-  }
-  
-  function removeJSSurfix(str) {
-    return str.replace(JS_SURFIX_REG, '');
-  }
-  
-  var commonModules = {};
-  
-  function clearCommonModules() {
-    commonModules = {};
-  }
-  
-  // define(name, factory) for primary usage
-  // or
-  // define(name, deps, factory) for compatibility
-  // Notice: DO NOT use function define() {},
-  // it will cause error after builded by webpack
-  var define = exports.define = function define(name, deps, factory) {
-    var _this = this;
-  
-    perf.start('define', name);
-  
-    if (_.typof(deps) === 'function') {
-      factory = deps;
-      deps = [];
-    }
-  
-    var _require = function _require(name) {
-      var cleanName = void 0;
-  
-      if (isWeexComponent(name)) {
-        cleanName = removeWeexPrefix(name);
-        return _this.requireComponent(cleanName);
-      }
-      if (isWeexModule(name)) {
-        cleanName = removeWeexPrefix(name);
-        return _this.requireModule(cleanName);
-      }
-      if (isNormalModule(name)) {
-        cleanName = removeJSSurfix(name);
-        return commonModules[name];
-      }
-      if (isNpmModule(name)) {
-        cleanName = removeJSSurfix(name);
-        return commonModules[name];
-      }
-    };
-    var _module = { exports: {} };
-  
-    var cleanName = void 0;
-    if (isWeexComponent(name)) {
-      cleanName = removeWeexPrefix(name);
-  
-      factory(_require, _module.exports, _module);
-  
-      this.registerComponent(cleanName, _module.exports);
-    } else if (isWeexModule(name)) {
-      cleanName = removeWeexPrefix(name);
-  
-      factory(_require, _module.exports, _module);
-  
-      _vm2.default.registerModules(_defineProperty({}, cleanName, _module.exports));
-    } else if (isNormalModule(name)) {
-      cleanName = removeJSSurfix(name);
-  
-      factory(_require, _module.exports, _module);
-  
-      commonModules[cleanName] = _module.exports;
-    } else if (isNpmModule(name)) {
-      cleanName = removeJSSurfix(name);
-  
-      factory(_require, _module.exports, _module);
-  
-      var exports = _module.exports;
-      if (exports.template || exports.style || exports.methods) {
-        // downgrade to old define method (define('componentName', factory))
-        // the exports contain one key of template, style or methods
-        // but it has risk!!!
-        this.registerComponent(cleanName, exports);
-      } else {
-        commonModules[cleanName] = _module.exports;
-      }
-    }
-  
-    perf.end('define', name);
-  };
-  
-  function bootstrap(name, config, data) {
-    var cleanName = void 0;
-  
-    if (isWeexComponent(name)) {
-      cleanName = removeWeexPrefix(name);
-    } else if (isNpmModule(name)) {
-      cleanName = removeJSSurfix(name);
-      // check if define by old 'define' method
-      if (!this.customComponentMap[cleanName]) {
-        return new Error('It\'s not a component: ' + name);
-      }
-    } else {
-      return new Error('Wrong component name: ' + name);
-    }
-  
-    config = _.isPlainObject(config) ? config : {};
-  
-    if (typeof config.transformerVersion === 'string' && typeof global.needTransformerVersion === 'string' && !_semver2.default.satisfies(config.transformerVersion, global.needTransformerVersion)) {
-      return new Error('JS Bundle version: ' + config.transformerVersion + ' ' + ('not compatible with ' + global.needTransformerVersion));
-    }
-  
-    var _checkDowngrade = downgrade.check(config.downgrade);
-    if (_checkDowngrade.isDowngrade) {
-      this.callTasks([{
-        module: 'instanceWrap',
-        method: 'error',
-        args: [_checkDowngrade.errorType, _checkDowngrade.code, _checkDowngrade.errorMessage]
-      }]);
-      return new Error('Downgrade: ' + config.downgrade);
-    }
-  
-    perf.start('create vm', cleanName);
-  
-    this.vm = new _vm2.default(cleanName, { _app: this }, null, data, {
-      'hook:ready': function hookReady() {
-        perf.end('create vm', cleanName);
-      }
-    });
-  }
-  
-  /**
-   * @deprecated
-   */
-  function register(type, options) {
-    perf.start('register', type);
-    this.registerComponent(type, options);
-    perf.end('register', type);
-  }
-  
-  /**
-   * @deprecated
-   */
-  function render(type, data) {
-    return this.bootstrap(type, {}, data);
-  }
-  
-  /**
-   * @deprecated
-   */
-  function _require2(type) {
-    var _this2 = this;
-  
-    return function (data) {
-      return _this2.bootstrap(type, {}, data);
-    };
-  }
-  exports.require = _require2;
-  /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
-
-/***/ },
-/* 83 */
-/***/ function(module, exports, __webpack_require__) {
-
-  /* WEBPACK VAR INJECTION */(function(process) {'use strict';
-  
-  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
-  
-  exports = module.exports = SemVer;
-  
-  // The debug function is excluded entirely from the minified version.
-  /* nomin */var debug;
-  /* nomin */if ((typeof process === 'undefined' ? 'undefined' : _typeof(process)) === 'object' &&
-  /* nomin */process.env &&
-  /* nomin */process.env.NODE_DEBUG &&
-  /* nomin *//\bsemver\b/i.test(process.env.NODE_DEBUG))
-    /* nomin */debug = function debug() {
-      /* nomin */var args = Array.prototype.slice.call(arguments, 0);
-      /* nomin */args.unshift('SEMVER');
-      /* nomin */console.log.apply(console, args);
-      /* nomin */
-    };
-    /* nomin */else
-    /* nomin */debug = function debug() {};
-  
-  // Note: this is the semver.org version of the spec that it implements
-  // Not necessarily the package version of this code.
-  exports.SEMVER_SPEC_VERSION = '2.0.0';
-  
-  var MAX_LENGTH = 256;
-  var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991;
-  
-  // The actual regexps go on exports.re
-  var re = exports.re = [];
-  var src = exports.src = [];
-  var R = 0;
-  
-  // The following Regular Expressions can be used for tokenizing,
-  // validating, and parsing SemVer version strings.
-  
-  // ## Numeric Identifier
-  // A single `0`, or a non-zero digit followed by zero or more digits.
-  
-  var NUMERICIDENTIFIER = R++;
-  src[NUMERICIDENTIFIER] = '0|[1-9]\\d*';
-  var NUMERICIDENTIFIERLOOSE = R++;
-  src[NUMERICIDENTIFIERLOOSE] = '[0-9]+';
-  
-  // ## Non-numeric Identifier
-  // Zero or more digits, followed by a letter or hyphen, and then zero or
-  // more letters, digits, or hyphens.
-  
-  var NONNUMERICIDENTIFIER = R++;
-  src[NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*';
-  
-  // ## Main Version
-  // Three dot-separated numeric identifiers.
-  
-  var MAINVERSION = R++;
-  src[MAINVERSION] = '(' + src[NUMERICIDENTIFIER] + ')\\.' + '(' + src[NUMERICIDENTIFIER] + ')\\.' + '(' + src[NUMERICIDENTIFIER] + ')';
-  
-  var MAINVERSIONLOOSE = R++;
-  src[MAINVERSIONLOOSE] = '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + '(' + src[NUMERICIDENTIFIERLOOSE] + ')';
-  
-  // ## Pre-release Version Identifier
-  // A numeric identifier, or a non-numeric identifier.
-  
-  var PRERELEASEIDENTIFIER = R++;
-  src[PRERELEASEIDENTIFIER] = '(?:' + src[NUMERICIDENTIFIER] + '|' + src[NONNUMERICIDENTIFIER] + ')';
-  
-  var PRERELEASEIDENTIFIERLOOSE = R++;
-  src[PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[NUMERICIDENTIFIERLOOSE] + '|' + src[NONNUMERICIDENTIFIER] + ')';
-  
-  // ## Pre-release Version
-  // Hyphen, followed by one or more dot-separated pre-release version
-  // identifiers.
-  
-  var PRERELEASE = R++;
-  src[PRERELEASE] = '(?:-(' + src[PRERELEASEIDENTIFIER] + '(?:\\.' + src[PRERELEASEIDENTIFIER] + ')*))';
-  
-  var PRERELEASELOOSE = R++;
-  src[PRERELEASELOOSE] = '(?:-?(' + src[PRERELEASEIDENTIFIERLOOSE] + '(?:\\.' + src[PRERELEASEIDENTIFIERLOOSE] + ')*))';
-  
-  // ## Build Metadata Identifier
-  // Any combination of digits, letters, or hyphens.
-  
-  var BUILDIDENTIFIER = R++;
-  src[BUILDIDENTIFIER] = '[0-9A-Za-z-]+';
-  
-  // ## Build Metadata
-  // Plus sign, followed by one or more period-separated build metadata
-  // identifiers.
-  
-  var BUILD = R++;
-  src[BUILD] = '(?:\\+(' + src[BUILDIDENTIFIER] + '(?:\\.' + src[BUILDIDENTIFIER] + ')*))';
-  
-  // ## Full Version String
-  // A main version, followed optionally by a pre-release version and
-  // build metadata.
-  
-  // Note that the only major, minor, patch, and pre-release sections of
-  // the version string are capturing groups.  The build metadata is not a
-  // capturing group, because it should not ever be used in version
-  // comparison.
-  
-  var FULL = R++;
-  var FULLPLAIN = 'v?' + src[MAINVERSION] + src[PRERELEASE] + '?' + src[BUILD] + '?';
-  
-  src[FULL] = '^' + FULLPLAIN + '$';
-  
-  // like full, but allows v1.2.3 and =1.2.3, which people do sometimes.
-  // also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty
-  // common in the npm registry.
-  var LOOSEPLAIN = '[v=\\s]*' + src[MAINVERSIONLOOSE] + src[PRERELEASELOOSE] + '?' + src[BUILD] + '?';
-  
-  var LOOSE = R++;
-  src[LOOSE] = '^' + LOOSEPLAIN + '$';
-  
-  var GTLT = R++;
-  src[GTLT] = '((?:<|>)?=?)';
-  
-  // Something like "2.*" or "1.2.x".
-  // Note that "x.x" is a valid xRange identifer, meaning "any version"
-  // Only the first item is strictly required.
-  var XRANGEIDENTIFIERLOOSE = R++;
-  src[XRANGEIDENTIFIERLOOSE] = src[NUMERICIDENTIFIERLOOSE] + '|x|X|\\*';
-  var XRANGEIDENTIFIER = R++;
-  src[XRANGEIDENTIFIER] = src[NUMERICIDENTIFIER] + '|x|X|\\*';
-  
-  var XRANGEPLAIN = R++;
-  src[XRANGEPLAIN] = '[v=\\s]*(' + src[XRANGEIDENTIFIER] + ')' + '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + '(?:' + src[PRERELEASE] + ')?' + src[BUILD] + '?' + ')?)?';
-  
-  var XRANGEPLAINLOOSE = R++;
-  src[XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[XRANGEIDENTIFIERLOOSE] + ')' + '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + '(?:' + src[PRERELEASELOOSE] + ')?' + src[BUILD] + '?' + ')?)?';
-  
-  var XRANGE = R++;
-  src[XRANGE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAIN] + '$';
-  var XRANGELOOSE = R++;
-  src[XRANGELOOSE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAINLOOSE] + '$';
-  
-  // Tilde ranges.
-  // Meaning is "reasonably at or greater than"
-  var LONETILDE = R++;
-  src[LONETILDE] = '(?:~>?)';
-  
-  var TILDETRIM = R++;
-  src[TILDETRIM] = '(\\s*)' + src[LONETILDE] + '\\s+';
-  re[TILDETRIM] = new RegExp(src[TILDETRIM], 'g');
-  var tildeTrimReplace = '$1~';
-  
-  var TILDE = R++;
-  src[TILDE] = '^' + src[LONETILDE] + src[XRANGEPLAIN] + '$';
-  var TILDELOOSE = R++;
-  src[TILDELOOSE] = '^' + src[LONETILDE] + src[XRANGEPLAINLOOSE] + '$';
-  
-  // Caret ranges.
-  // Meaning is "at least and backwards compatible with"
-  var LONECARET = R++;
-  src[LONECARET] = '(?:\\^)';
-  
-  var CARETTRIM = R++;
-  src[CARETTRIM] = '(\\s*)' + src[LONECARET] + '\\s+';
-  re[CARETTRIM] = new RegExp(src[CARETTRIM], 'g');
-  var caretTrimReplace = '$1^';
-  
-  var CARET = R++;
-  src[CARET] = '^' + src[LONECARET] + src[XRANGEPLAIN] + '$';
-  var CARETLOOSE = R++;
-  src[CARETLOOSE] = '^' + src[LONECARET] + src[XRANGEPLAINLOOSE] + '$';
-  
-  // A simple gt/lt/eq thing, or just "" to indicate "any version"
-  var COMPARATORLOOSE = R++;
-  src[COMPARATORLOOSE] = '^' + src[GTLT] + '\\s*(' + LOOSEPLAIN + ')$|^$';
-  var COMPARATOR = R++;
-  src[COMPARATOR] = '^' + src[GTLT] + '\\s*(' + FULLPLAIN + ')$|^$';
-  
-  // An expression to strip any whitespace between the gtlt and the thing
-  // it modifies, so that `> 1.2.3` ==> `>1.2.3`
-  var COMPARATORTRIM = R++;
-  src[COMPARATORTRIM] = '(\\s*)' + src[GTLT] + '\\s*(' + LOOSEPLAIN + '|' + src[XRANGEPLAIN] + ')';
-  
-  // this one has to use the /g flag
-  re[COMPARATORTRIM] = new RegExp(src[COMPARATORTRIM], 'g');
-  var comparatorTrimReplace = '$1$2$3';
-  
-  // Something like `1.2.3 - 1.2.4`
-  // Note that these all use the loose form, because they'll be
-  // checked against either the strict or loose comparator form
-  // later.
-  var HYPHENRANGE = R++;
-  src[HYPHENRANGE] = '^\\s*(' + src[XRANGEPLAIN] + ')' + '\\s+-\\s+' + '(' + src[XRANGEPLAIN] + ')' + '\\s*$';
-  
-  var HYPHENRANGELOOSE = R++;
-  src[HYPHENRANGELOOSE] = '^\\s*(' + src[XRANGEPLAINLOOSE] + ')' + '\\s+-\\s+' + '(' + src[XRANGEPLAINLOOSE] + ')' + '\\s*$';
-  
-  // Star ranges basically just allow anything at all.
-  var STAR = R++;
-  src[STAR] = '(<|>)?=?\\s*\\*';
-  
-  // Compile to actual regexp objects.
-  // All are flag-free, unless they were created above with a flag.
-  for (var i = 0; i < R; i++) {
-    debug(i, src[i]);
-    if (!re[i]) re[i] = new RegExp(src[i]);
-  }
-  
-  exports.parse = parse;
-  function parse(version, loose) {
-    if (version instanceof SemVer) return version;
-  
-    if (typeof version !== 'string') return null;
-  
-    if (version.length > MAX_LENGTH) return null;
-  
-    var r = loose ? re[LOOSE] : re[FULL];
-    if (!r.test(version)) return null;
-  
-    try {
-      return new SemVer(version, loose);
-    } catch (er) {
-      return null;
-    }
-  }
-  
-  exports.valid = valid;
-  function valid(version, loose) {
-    var v = parse(version, loose);
-    return v ? v.version : null;
-  }
-  
-  exports.clean = clean;
-  function clean(version, loose) {
-    var s = parse(version.trim().replace(/^[=v]+/, ''), loose);
-    return s ? s.version : null;
-  }
-  
-  exports.SemVer = SemVer;
-  
-  function SemVer(version, loose) {
-    if (version instanceof SemVer) {
-      if (version.loose === loose) return version;else version = version.version;
-    } else if (typeof version !== 'string') {
-      throw new TypeError('Invalid Version: ' + version);
-    }
-  
-    if (version.length > MAX_LENGTH) throw new TypeError('version is longer than ' + MAX_LENGTH + ' characters');
-  
-    if (!(this instanceof SemVer)) return new SemVer(version, loose);
-  
-    debug('SemVer', version, loose);
-    this.loose = loose;
-    var m = version.trim().match(loose ? re[LOOSE] : re[FULL]);
-  
-    if (!m) throw new TypeError('Invalid Version: ' + version);
-  
-    this.raw = version;
-  
-    // these are actually numbers
-    this.major = +m[1];
-    this.minor = +m[2];
-    this.patch = +m[3];
-  
-    if (this.major > MAX_SAFE_INTEGER || this.major < 0) throw new TypeError('Invalid major version');
-  
-    if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) throw new TypeError('Invalid minor version');
-  
-    if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) throw new TypeError('Invalid patch version');
-  
-    // numberify any prerelease numeric ids
-    if (!m[4]) this.prerelease = [];else this.prerelease = m[4].split('.').map(function (id) {
-      if (/^[0-9]+$/.test(id)) {
-        var num = +id;
-        if (num >= 0 && num < MAX_SAFE_INTEGER) return num;
-      }
-      return id;
-    });
-  
-    this.build = m[5] ? m[5].split('.') : [];
-    this.format();
-  }
-  
-  SemVer.prototype.format = function () {
-    this.version = this.major + '.' + this.minor + '.' + this.patch;
-    if (this.prerelease.length) this.version += '-' + this.prerelease.join('.');
-    return this.version;
-  };
-  
-  SemVer.prototype.toString = function () {
-    return this.version;
-  };
-  
-  SemVer.prototype.compare = function (other) {
-    debug('SemVer.compare', this.version, this.loose, other);
-    if (!(other instanceof SemVer)) other = new SemVer(other, this.loose);
-  
-    return this.compareMain(other) || this.comparePre(other);
-  };
-  
-  SemVer.prototype.compareMain = function (other) {
-    if (!(other instanceof SemVer)) other = new SemVer(other, this.loose);
-  
-    return compareIdentifiers(this.major, other.major) || compareIdentifiers(this.minor, other.minor) || compareIdentifiers(this.patch, other.patch);
-  };
-  
-  SemVer.prototype.comparePre = function (other) {
-    if (!(other instanceof SemVer)) other = new SemVer(other, this.loose);
-  
-    // NOT having a prerelease is > having one
-    if (this.prerelease.length && !other.prerelease.length) return -1;else if (!this.prerelease.length && other.prerelease.length) return 1;else if (!this.prerelease.length && !other.prerelease.length) return 0;
-  
-    var i = 0;
-    do {
-      var a = this.prerelease[i];
-      var b = other.prerelease[i];
-      debug('prerelease compare', i, a, b);
-      if (a === undefined && b === undefined) return 0;else if (b === undefined) return 1;else if (a === undefined) return -1;else if (a === b) continue;else return compareIdentifiers(a, b);
-    } while (++i);
-  };
-  
-  // preminor will bump the version up to the next minor release, and immediately
-  // down to pre-release. premajor and prepatch work the same way.
-  SemVer.prototype.inc = function (release, identifier) {
-    switch (release) {
-      case 'premajor':
-        this.prerelease.length = 0;
-        this.patch = 0;
-        this.minor = 0;
-        this.major++;
-        this.inc('pre', identifier);
-        break;
-      case 'preminor':
-        this.prerelease.length = 0;
-        this.patch = 0;
-        this.minor++;
-        this.inc('pre', identifier);
-        break;
-      case 'prepatch':
-        // If this is already a prerelease, it will bump to the next version
-        // drop any prereleases that might already exist, since they are not
-        // relevant at this point.
-        this.prerelease.length = 0;
-        this.inc('patch', identifier);
-        this.inc('pre', identifier);
-        break;
-      // If the input is a non-prerelease version, this acts the same as
-      // prepatch.
-      case 'prerelease':
-        if (this.prerelease.length === 0) this.inc('patch', identifier);
-        this.inc('pre', identifier);
-        break;
-  
-      case 'major':
-        // If this is a pre-major version, bump up to the same major version.
-        // Otherwise increment major.
-        // 1.0.0-5 bumps to 1.0.0
-        // 1.1.0 bumps to 2.0.0
-        if (this.minor !== 0 || this.patch !== 0 || this.prerelease.length === 0) this.major++;
-        this.minor = 0;
-        this.patch = 0;
-        this.prerelease = [];
-        break;
-      case 'minor':
-        // If this is a pre-minor version, bump up to the same minor version.
-        // Otherwise increment minor.
-        // 1.2.0-5 bumps to 1.2.0
-        // 1.2.1 bumps to 1.3.0
-        if (this.patch !== 0 || this.prerelease.length === 0) this.minor++;
-        this.patch = 0;
-        this.prerelease = [];
-        break;
-      case 'patch':
-        // If this is not a pre-release version, it will increment the patch.
-        // If it is a pre-release it will bump up to the same patch version.
-        // 1.2.0-5 patches to 1.2.0
-        // 1.2.0 patches to 1.2.1
-        if (this.prerelease.length === 0) this.patch++;
-        this.prerelease = [];
-        break;
-      // This probably shouldn't be used publicly.
-      // 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction.
-      case 'pre':
-        if (this.prerelease.length === 0) this.prerelease = [0];else {
-          var i = this.prerelease.length;
-          while (--i >= 0) {
-            if (typeof this.prerelease[i] === 'number') {
-              this.prerelease[i]++;
-              i = -2;
-            }
-          }
-          if (i === -1) // didn't increment anything
-            this.prerelease.push(0);
-        }
-        if (identifier) {
-          // 1.2.0-beta.1 bumps to 1.2.0-beta.2,
-          // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0
-          if (this.prerelease[0] === identifier) {
-            if (isNaN(this.prerelease[1])) this.prerelease = [identifier, 0];
-          } else this.prerelease = [identifier, 0];
-        }
-        break;
-  
-      default:
-        throw new Error('invalid increment argument: ' + release);
-    }
-    this.format();
-    this.raw = this.version;
-    return this;
-  };
-  
-  exports.inc = inc;
-  function inc(version, release, loose, identifier) {
-    if (typeof loose === 'string') {
-      identifier = loose;
-      loose = undefined;
-    }
-  
-    try {
-      return new SemVer(version, loose).inc(release, identifier).version;
-    } catch (er) {
-      return null;
-    }
-  }
-  
-  exports.diff = diff;
-  function diff(version1, version2) {
-    if (eq(version1, version2)) {
-      return null;
-    } else {
-      var v1 = parse(version1);
-      var v2 = parse(version2);
-      if (v1.prerelease.length || v2.prerelease.length) {
-        for (var key in v1) {
-          if (key === 'major' || key === 'minor' || key === 'patch') {
-            if (v1[key] !== v2[key]) {
-              return 'pre' + key;
-            }
-          }
-        }
-        return 'prerelease';
-      }
-      for (var key in v1) {
-        if (key === 'major' || key === 'minor' || key === 'patch') {
-          if (v1[key] !== v2[key]) {
-            return key;
-          }
-        }
-      }
-    }
-  }
-  
-  exports.compareIdentifiers = compareIdentifiers;
-  
-  var numeric = /^[0-9]+$/;
-  function compareIdentifiers(a, b) {
-    var anum = numeric.test(a);
-    var bnum = numeric.test(b);
-  
-    if (anum && bnum) {
-      a = +a;
-      b = +b;
-    }
-  
-    return anum && !bnum ? -1 : bnum && !anum ? 1 : a < b ? -1 : a > b ? 1 : 0;
-  }
-  
-  exports.rcompareIdentifiers = rcompareIdentifiers;
-  function rcompareIdentifiers(a, b) {
-    return compareIdentifiers(b, a);
-  }
-  
-  exports.major = major;
-  function major(a, loose) {
-    return new SemVer(a, loose).major;
-  }
-  
-  exports.minor = minor;
-  function minor(a, loose) {
-    return new SemVer(a, loose).minor;
-  }
-  
-  exports.patch = patch;
-  function patch(a, loose) {
-    return new SemVer(a, loose).patch;
-  }
-  
-  exports.compare = compare;
-  function compare(a, b, loose) {
-    return new SemVer(a, loose).compare(b);
-  }
-  
-  exports.compareLoose = compareLoose;
-  function compareLoose(a, b) {
-    return compare(a, b, true);
-  }
-  
-  exports.rcompare = rcompare;
-  function rcompare(a, b, loose) {
-    return compare(b, a, loose);
-  }
-  
-  exports.sort = sort;
-  function sort(list, loose) {
-    return list.sort(function (a, b) {
-      return exports.compare(a, b, loose);
-    });
-  }
-  
-  exports.rsort = rsort;
-  function rsort(list, loose) {
-    return list.sort(function (a, b) {
-      return exports.rcompare(a, b, loose);
-    });
-  }
-  
-  exports.gt = gt;
-  function gt(a, b, loose) {
-    return compare(a, b, loose) > 0;
-  }
-  
-  exports.lt = lt;
-  function lt(a, b, loose) {
-    return compare(a, b, loose) < 0;
-  }
-  
-  exports.eq = eq;
-  function eq(a, b, loose) {
-    return compare(a, b, loose) === 0;
-  }
-  
-  exports.neq = neq;
-  function neq(a, b, loose) {
-    return compare(a, b, loose) !== 0;
-  }
-  
-  exports.gte = gte;
-  function gte(a, b, loose) {
-    return compare(a, b, loose) >= 0;
-  }
-  
-  exports.lte = lte;
-  function lte(a, b, loose) {
-    return compare(a, b, loose) <= 0;
-  }
-  
-  exports.cmp = cmp;
-  function cmp(a, op, b, loose) {
-    var ret;
-    switch (op) {
-      case '===':
-        if ((typeof a === 'undefined' ? 'undefined' : _typeof(a)) === 'object') a = a.version;
-        if ((typeof b === 'undefined' ? 'undefined' : _typeof(b)) === 'object') b = b.version;
-        ret = a === b;
-        break;
-      case '!==':
-        if ((typeof a === 'undefined' ? 'undefined' : _typeof(a)) === 'object') a = a.version;
-        if ((typeof b === 'undefined' ? 'undefined' : _typeof(b)) === 'object') b = b.version;
-        ret = a !== b;
-        break;
-      case '':case '=':case '==':
-        ret = eq(a, b, loose);break;
-      case '!=':
-        ret = neq(a, b, loose);break;
-      case '>':
-        ret = gt(a, b, loose);break;
-      case '>=':
-        ret = gte(a, b, loose);break;
-      case '<':
-        ret = lt(a, b, loose);break;
-      case '<=':
-        ret = lte(a, b, loose);break;
-      default:
-        throw new TypeError('Invalid operator: ' + op);
-    }
-    return ret;
-  }
-  
-  exports.Comparator = Comparator;
-  function Comparator(comp, loose) {
-    if (comp instanceof Comparator) {
-      if (comp.loose === loose) return comp;else comp = comp.value;
-    }
-  
-    if (!(this instanceof Comparator)) return new Comparator(comp, loose);
-  
-    debug('comparator', comp, loose);
-    this.loose = loose;
-    this.parse(comp);
-  
-    if (this.semver === ANY) this.value = '';else this.value = this.operator + this.semver.version;
-  
-    debug('comp', this);
-  }
-  
-  var ANY = {};
-  Comparator.prototype.parse = function (comp) {
-    var r = this.loose ? re[COMPARATORLOOSE] : re[COMPARATOR];
-    var m = comp.match(r);
-  
-    if (!m) throw new TypeError('Invalid comparator: ' + comp);
-  
-    this.operator = m[1];
-    if (this.operator === '=') this.operator = '';
-  
-    // if it literally is just '>' or '' then allow anything.
-    if (!m[2]) this.semver = ANY;else this.semver = new SemVer(m[2], this.loose);
-  };
-  
-  Comparator.prototype.toString = function () {
-    return this.value;
-  };
-  
-  Comparator.prototype.test = function (version) {
-    debug('Comparator.test', version, this.loose);
-  
-    if (this.semver === ANY) return true;
-  
-    if (typeof version === 'string') version = new SemVer(version, this.loose);
-  
-    return cmp(version, this.operator, this.semver, this.loose);
-  };
-  
-  exports.Range = Range;
-  function Range(range, loose) {
-    if (range instanceof Range && range.loose === loose) return range;
-  
-    if (!(this instanceof Range)) return new Range(range, loose);
-  
-    this.loose = loose;
-  
-    // First, split based on boolean or ||
-    this.raw = range;
-    this.set = range.split(/\s*\|\|\s*/).map(function (range) {
-      return this.parseRange(range.trim());
-    }, this).filter(function (c) {
-      // throw out any that are not relevant for whatever reason
-      return c.length;
-    });
-  
-    if (!this.set.length) {
-      throw new TypeError('Invalid SemVer Range: ' + range);
-    }
-  
-    this.format();
-  }
-  
-  Range.prototype.format = function () {
-    this.range = this.set.map(function (comps) {
-      return comps.join(' ').trim();
-    }).join('||').trim();
-    return this.range;
-  };
-  
-  Range.prototype.toString = function () {
-    return this.range;
-  };
-  
-  Range.prototype.parseRange = function (range) {
-    var loose = this.loose;
-    range = range.trim();
-    debug('range', range, loose);
-    // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4`
-    var hr = loose ? re[HYPHENRANGELOOSE] : re[HYPHENRANGE];
-    range = range.replace(hr, hyphenReplace);
-    debug('hyphen replace', range);
-    // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5`
-    range = range.replace(re[COMPARATORTRIM], comparatorTrimReplace);
-    debug('comparator trim', range, re[COMPARATORTRIM]);
-  
-    // `~ 1.2.3` => `~1.2.3`
-    range = range.replace(re[TILDETRIM], tildeTrimReplace);
-  
-    // `^ 1.2.3` => `^1.2.3`
-    range = range.replace(re[CARETTRIM], caretTrimReplace);
-  
-    // normalize spaces
-    range = range.split(/\s+/).join(' ');
-  
-    // At this point, the range is completely trimmed and
-    // ready to be split into comparators.
-  
-    var compRe = loose ? re[COMPARATORLOOSE] : re[COMPARATOR];
-    var set = range.split(' ').map(function (comp) {
-      return parseComparator(comp, loose);
-    }).join(' ').split(/\s+/);
-    if (this.loose) {
-      // in loose mode, throw out any that are not valid comparators
-      set = set.filter(function (comp) {
-        return !!comp.match(compRe);
-      });
-    }
-    set = set.map(function (comp) {
-      return new Comparator(comp, loose);
-    });
-  
-    return set;
-  };
-  
-  // Mostly just for testing and legacy API reasons
-  exports.toComparators = toComparators;
-  function toComparators(range, loose) {
-    return new Range(range, loose).set.map(function (comp) {
-      return comp.map(function (c) {
-        return c.value;
-      }).join(' ').trim().split(' ');
-    });
-  }
-  
-  // comprised of xranges, tildes, stars, and gtlt's at this point.
-  // already replaced the hyphen ranges
-  // turn into a set of JUST comparators.
-  function parseComparator(comp, loose) {
-    debug('comp', comp);
-    comp = replaceCarets(comp, loose);
-    debug('caret', comp);
-    comp = replaceTildes(comp, loose);
-    debug('tildes', comp);
-    comp = replaceXRanges(comp, loose);
-    debug('xrange', comp);
-    comp = replaceStars(comp, loose);
-    debug('stars', comp);
-    return comp;
-  }
-  
-  function isX(id) {
-    return !id || id.toLowerCase() === 'x' || id === '*';
-  }
-  
-  // ~, ~> --> * (any, kinda silly)
-  // ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0
-  // ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0
-  // ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0
-  // ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0
-  // ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0
-  function replaceTildes(comp, loose) {
-    return comp.trim().split(/\s+/).map(function (comp) {
-      return replaceTilde(comp, loose);
-    }).join(' ');
-  }
-  
-  function replaceTilde(comp, loose) {
-    var r = loose ? re[TILDELOOSE] : re[TILDE];
-    return comp.replace(r, function (_, M, m, p, pr) {
-      debug('tilde', comp, _, M, m, p, pr);
-      var ret;
-  
-      if (isX(M)) ret = '';else if (isX(m)) ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0';else if (isX(p))
-        // ~1.2 == >=1.2.0- <1.3.0-
-        ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0';else if (pr) {
-        debug('replaceTilde pr', pr);
-        if (pr.charAt(0) !== '-') pr = '-' + pr;
-        ret = '>=' + M + '.' + m + '.' + p + pr + ' <' + M + '.' + (+m + 1) + '.0';
-      } else
-        // ~1.2.3 == >=1.2.3 <1.3.0
-        ret = '>=' + M + '.' + m + '.' + p + ' <' + M + '.' + (+m + 1) + '.0';
-  
-      debug('tilde return', ret);
-      return ret;
-    });
-  }
-  
-  // ^ --> * (any, kinda silly)
-  // ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0
-  // ^2.0, ^2.0.x --> >=2.0.0 <3.0.0
-  // ^1.2, ^1.2.x --> >=1.2.0 <2.0.0
-  // ^1.2.3 --> >=1.2.3 <2.0.0
-  // ^1.2.0 --> >=1.2.0 <2.0.0
-  function replaceCarets(comp, loose) {
-    return comp.trim().split(/\s+/).map(function (comp) {
-      return replaceCaret(comp, loose);
-    }).join(' ');
-  }
-  
-  function replaceCaret(comp, loose) {
-    debug('caret', comp, loose);
-    var r = loose ? re[CARETLOOSE] : re[CARET];
-    return comp.replace(r, function (_, M, m, p, pr) {
-      debug('caret', comp, _, M, m, p, pr);
-      var ret;
-  
-      if (isX(M)) ret = '';else if (isX(m)) ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0';else if (isX(p)) {
-        if (M === '0') ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0';else ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0';
-      } else if (pr) {
-        debug('replaceCaret pr', pr);
-        if (pr.charAt(0) !== '-') pr = '-' + pr;
-        if (M === '0') {
-          if (m === '0') ret = '>=' + M + '.' + m + '.' + p + pr + ' <' + M + '.' + m + '.' + (+p + 1);else ret = '>=' + M + '.' + m + '.' + p + pr + ' <' + M + '.' + (+m + 1) + '.0';
-        } else ret = '>=' + M + '.' + m + '.' + p + pr + ' <' + (+M + 1) + '.0.0';
-      } else {
-        debug('no pr');
-        if (M === '0') {
-          if (m === '0') ret = '>=' + M + '.' + m + '.' + p + ' <' + M + '.' + m + '.' + (+p + 1);else ret = '>=' + M + '.' + m + '.' + p + ' <' + M + '.' + (+m + 1) + '.0';
-        } else ret = '>=' + M + '.' + m + '.' + p + ' <' + (+M + 1) + '.0.0';
-      }
-  
-      debug('caret return', ret);
-      return ret;
-    });
-  }
-  
-  function replaceXRanges(comp, loose) {
-    debug('replaceXRanges', comp, loose);
-    return comp.split(/\s+/).map(function (comp) {
-      return replaceXRange(comp, loose);
-    }).join(' ');
-  }
-  
-  function replaceXRange(comp, loose) {
-    comp = comp.trim();
-    var r = loose ? re[XRANGELOOSE] : re[XRANGE];
-    return comp.replace(r, function (ret, gtlt, M, m, p, pr) {
-      debug('xRange', comp, ret, gtlt, M, m, p, pr);
-      var xM = isX(M);
-      var xm = xM || isX(m);
-      var xp = xm || isX(p);
-      var anyX = xp;
-  
-      if (gtlt === '=' && anyX) gtlt = '';
-  
-      if (xM) {
-        if (gtlt === '>' || gtlt === '<') {
-          // nothing is allowed
-          ret = '<0.0.0';
-        } else {
-          // nothing is forbidden
-          ret = '*';
-        }
-      } else if (gtlt && anyX) {
-        // replace X with 0
-        if (xm) m = 0;
-        if (xp) p = 0;
-  
-        if (gtlt === '>') {
-          // >1 => >=2.0.0
-          // >1.2 => >=1.3.0
-          // >1.2.3 => >= 1.2.4
-          gtlt = '>=';
-          if (xm) {
-            M = +M + 1;
-            m = 0;
-            p = 0;
-          } else if (xp) {
-            m = +m + 1;
-            p = 0;
-          }
-        } else if (gtlt === '<=') {
-          // <=0.7.x is actually <0.8.0, since any 0.7.x should
-          // pass.  Similarly, <=7.x is actually <8.0.0, etc.
-          gtlt = '<';
-          if (xm) M = +M + 1;else m = +m + 1;
-        }
-  
-        ret = gtlt + M + '.' + m + '.' + p;
-      } else if (xm) {
-        ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0';
-      } else if (xp) {
-        ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0';
-      }
-  
-      debug('xRange return', ret);
-  
-      return ret;
-    });
-  }
-  
-  // Because * is AND-ed with everything else in the comparator,
-  // and '' means "any version", just remove the *s entirely.
-  function replaceStars(comp, loose) {
-    debug('replaceStars', comp, loose);
-    // Looseness is ignored here.  star is always as loose as it gets!
-    return comp.trim().replace(re[STAR], '');
-  }
-  
-  // This function is passed to string.replace(re[HYPHENRANGE])
-  // M, m, patch, prerelease, build
-  // 1.2 - 3.4.5 => >=1.2.0 <=3.4.5
-  // 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do
-  // 1.2 - 3.4 => >=1.2.0 <3.5.0
-  function hyphenReplace($0, from, fM, fm, fp, fpr, fb, to, tM, tm, tp, tpr, tb) {
-  
-    if (isX(fM)) from = '';else if (isX(fm)) from = '>=' + fM + '.0.0';else if (isX(fp)) from = '>=' + fM + '.' + fm + '.0';else from = '>=' + from;
-  
-    if (isX(tM)) to = '';else if (isX(tm)) to = '<' + (+tM + 1) + '.0.0';else if (isX(tp)) to = '<' + tM + '.' + (+tm + 1) + '.0';else if (tpr) to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr;else to = '<=' + to;
-  
-    return (from + ' ' + to).trim();
-  }
-  
-  // if ANY of the sets match ALL of its comparators, then pass
-  Range.prototype.test = function (version) {
-    if (!version) return false;
-  
-    if (typeof version === 'string') version = new SemVer(version, this.loose);
-  
-    for (var i = 0; i < this.set.length; i++) {
-      if (testSet(this.set[i], version)) return true;
-    }
-    return false;
-  };
-  
-  function testSet(set, version) {
-    for (var i = 0; i < set.length; i++) {
-      if (!set[i].test(version)) return false;
-    }
-  
-    if (version.prerelease.length) {
-      // Find the set of versions that are allowed to have prereleases
-      // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0
-      // That should allow `1.2.3-pr.2` to pass.
-      // However, `1.2.4-alpha.notready` should NOT be allowed,
-      // even though it's within the range set by the comparators.
-      for (var i = 0; i < set.length; i++) {
-        debug(set[i].semver);
-        if (set[i].semver === ANY) continue;
-  
-        if (set[i].semver.prerelease.length > 0) {
-          var allowed = set[i].semver;
-          if (allowed.major === version.major && allowed.minor === version.minor && allowed.patch === version.patch) return true;
-        }
-      }
-  
-      // Version has a -pre, but it's not one of the ones we like.
-      return false;
-    }
-  
-    return true;
-  }
-  
-  exports.satisfies = satisfies;
-  function satisfies(version, range, loose) {
-    try {
-      range = new Range(range, loose);
-    } catch (er) {
-      return false;
-    }
-    return range.test(version);
-  }
-  
-  exports.maxSatisfying = maxSatisfying;
-  function maxSatisfying(versions, range, loose) {
-    return versions.filter(function (version) {
-      return satisfies(version, range, loose);
-    }).sort(function (a, b) {
-      return rcompare(a, b, loose);
-    })[0] || null;
-  }
-  
-  exports.validRange = validRange;
-  function validRange(range, loose) {
-    try {
-      // Return '*' instead of '' so that truthiness works.
-      // This will throw if it's invalid anyway
-      return new Range(range, loose).range || '*';
-    } catch (er) {
-      return null;
-    }
-  }
-  
-  // Determine if version is less than all the versions possible in the range
-  exports.ltr = ltr;
-  function ltr(version, range, loose) {
-    return outside(version, range, '<', loose);
-  }
-  
-  // Determine if version is greater than all the versions possible in the range.
-  exports.gtr = gtr;
-  function gtr(version, range, loose) {
-    return outside(version, range, '>', loose);
-  }
-  
-  exports.outside = outside;
-  function outside(version, range, hilo, loose) {
-    version = new SemVer(version, loose);
-    range = new Range(range, loose);
-  
-    var gtfn, ltefn, ltfn, comp, ecomp;
-    switch (hilo) {
-      case '>':
-        gtfn = gt;
-        ltefn = lte;
-        ltfn = lt;
-        comp = '>';
-        ecomp = '>=';
-        break;
-      case '<':
-        gtfn = lt;
-        ltefn = gte;
-        ltfn = gt;
-        comp = '<';
-        ecomp = '<=';
-        break;
-      default:
-        throw new TypeError('Must provide a hilo val of "<" or ">"');
-    }
-  
-    // If it satisifes the range it is not outside
-    if (satisfies(version, range, loose)) {
-      return false;
-    }
-  
-    // From now on, variable terms are as if we're in "gtr" mode.
-    // but note that everything is flipped for the "ltr" function.
-  
-    for (var i = 0; i < range.set.length; ++i) {
-      var comparators = range.set[i];
-  
-      var high = null;
-      var low = null;
-  
-      comparators.forEach(function (comparator) {
-        if (comparator.semver === ANY) {
-          comparator = new Comparator('>=0.0.0');
-        }
-        high = high || comparator;
-        low = low || comparator;
-        if (gtfn(comparator.semver, high.semver, loose)) {
-          high = comparator;
-        } else if (ltfn(comparator.semver, low.semver, loose)) {
-          low = comparator;
-        }
-      });
-  
-      // If the edge version comparator has a operator then our version
-      // isn't outside it
-      if (high.operator === comp || high.operator === ecomp) {
-        return false;
-      }
-  
-      // If the lowest version comparator has an operator and our version
-      // is less than it then it isn't higher than the range
-      if ((!low.operator || low.operator === comp) && ltefn(version, low.semver)) {
-        return false;
-      } else if (low.operator === ecomp && ltfn(version, low.semver)) {
-        return false;
-      }
-    }
-    return true;
-  }
-  /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(84)))
-
-/***/ },
-/* 84 */
-/***/ function(module, exports) {
-
-  'use strict';
-  
-  // shim for using process in browser
-  
-  var process = module.exports = {};
-  var queue = [];
-  var draining = false;
-  var currentQueue;
-  var queueIndex = -1;
-  
-  function cleanUpNextTick() {
-      draining = false;
-      if (currentQueue.length) {
-          queue = currentQueue.concat(queue);
-      } else {
-          queueIndex = -1;
-      }
-      if (queue.length) {
-          drainQueue();
-      }
-  }
-  
-  function drainQueue() {
-      if (draining) {
-          return;
-      }
-      var timeout = setTimeout(cleanUpNextTick);
-      draining = true;
-  
-      var len = queue.length;
-      while (len) {
-          currentQueue = queue;
-          queue = [];
-          while (++queueIndex < len) {
-              if (currentQueue) {
-                  currentQueue[queueIndex].run();
-              }
-          }
-          queueIndex = -1;
-          len = queue.length;
-      }
-      currentQueue = null;
-      draining = false;
-      clearTimeout(timeout);
-  }
-  
-  process.nextTick = function (fun) {
-      var args = new Array(arguments.length - 1);
-      if (arguments.length > 1) {
-          for (var i = 1; i < arguments.length; i++) {
-              args[i - 1] = arguments[i];
-          }
-      }
-      queue.push(new Item(fun, args));
-      if (queue.length === 1 && !draining) {
-          setTimeout(drainQueue, 0);
-      }
-  };
-  
-  // v8 likes predictible objects
-  function Item(fun, array) {
-      this.fun = fun;
-      this.array = array;
-  }
-  Item.prototype.run = function () {
-      this.fun.apply(null, this.array);
-  };
-  process.title = 'browser';
-  process.browser = true;
-  process.env = {};
-  process.argv = [];
-  process.version = ''; // empty string to avoid regexp issues
-  process.versions = {};
-  
-  function noop() {}
-  
-  process.on = noop;
-  process.addListener = noop;
-  process.once = noop;
-  process.off = noop;
-  process.removeListener = noop;
-  process.removeAllListeners = noop;
-  process.emit = noop;
-  
-  process.binding = function (name) {
-      throw new Error('process.binding is not supported');
-  };
-  
-  process.cwd = function () {
-      return '/';
-  };
-  process.chdir = function (dir) {
-      throw new Error('process.chdir is not supported');
-  };
-  process.umask = function () {
-      return 0;
-  };
-
-/***/ },
-/* 85 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  Object.defineProperty(exports, "__esModule", {
-    value: true
-  });
-  exports.default = Vm;
-  
-  var _util = __webpack_require__(81);
-  
-  var _scope = __webpack_require__(86);
-  
-  var scope = _interopRequireWildcard(_scope);
-  
-  var _compiler = __webpack_require__(93);
-  
-  var compiler = _interopRequireWildcard(_compiler);
-  
-  var _directive = __webpack_require__(94);
-  
-  var directive = _interopRequireWildcard(_directive);
-  
-  var _domHelper = __webpack_require__(96);
-  
-  var domHelper = _interopRequireWildcard(_domHelper);
-  
-  var _events = __webpack_require__(97);
-  
-  var events = _interopRequireWildcard(_events);
-  
-  var _register = __webpack_require__(98);
-  
-  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
-  
-  function callOldReadyEntry(vm, component) {
-    if (component.methods && component.methods.ready) {
-      component.methods.ready.call(vm);
-    }
-  }
-  
-  /**
-   * ViewModel constructor
-   *
-   * @param {string} type
-   * @param {object} parentVm   which contains _app
-   * @param {object} parentEl   root element or frag block
-   * @param {object} mergedData external data
-   * @param {object} externalEvents external events
-   */
-  
-  // import * as modules from './../api/modules'
-  // import * as api from './../api/api'
-  
-  /**
-   * @fileOverview
-   * ViewModel Constructor & definition
-   */
-  
-  function Vm(type, parentVm, parentEl, mergedData, externalEvents) {
-    this._parent = parentVm._realParent ? parentVm._realParent : parentVm;
-    this._app = parentVm._app;
-    parentVm._childrenVms && parentVm._childrenVms.push(this);
-  
-    var component = this._app.customComponentMap[type] || {};
-    var data = component.data || {};
-  
-    this._options = component;
-    this._methods = component.methods || {};
-    this._computed = component.computed || {};
-    this._css = component.style || {};
-    this._ids = {};
-    this._watchers = [];
-    this._vmEvents = {};
-    this._childrenVms = [];
-    this._type = type;
-  
-    // bind events and lifecycles
-    this._initEvents(externalEvents);
-  
-    this.$emit('hook:init');
-    this._inited = true;
-    // proxy data and methods
-    // observe data and add this to vms
-    this._data = typeof data === 'function' ? data() : data;
-    if (mergedData) {
-      (0, _util.extend)(this._data, mergedData);
-    }
-    this._initScope();
-  
-    this.$emit('hook:created');
-    this._created = true;
-    // backward old ready entry
-    callOldReadyEntry(this, component);
-  
-    // if no parentElement then specify the documentElement
-    this._parentEl = parentEl || this._app.doc.documentElement;
-    this._build();
-  }
-  
-  (0, _util.extend)(Vm.prototype, scope, compiler, directive, domHelper, events);
-  (0, _util.extend)(Vm, {
-    registerModules: _register.registerModules,
-    registerMethods: _register.registerMethods
-  });
-  // Vm.registerModules(modules)
-
-/***/ },
-/* 86 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  var _ = __webpack_require__(87);
-  var Observer = __webpack_require__(88);
-  var Dep = __webpack_require__(90);
-  
-  /**
-   * Setup the scope of an instance, which contains:
-   * - observed data
-   * - computed properties
-   * - user methods
-   * - meta properties
-   */
-  
-  exports._initScope = function () {
-    this._initData();
-    this._initComputed();
-    this._initMethods();
-    // this._initMeta()
-  };
-  
-  /**
-   * Initialize the data. 
-   */
-  
-  exports._initData = function () {
-    // proxy data on instance
-    var data = this._data;
-    var i, key;
-    // // make sure all props properties are observed
-    // var props = this.$options.props
-    // if (props) {
-    //   i = props.length
-    //   while (i--) {
-    //     key = _.camelize(props[i])
-    //     if (!(key in data)) {
-    //       data[key] = null
-    //     }
-    //   }
-    // }
-    var keys = Object.keys(data);
-    i = keys.length;
-    while (i--) {
-      key = keys[i];
-      if (!_.isReserved(key)) {
-        this._proxy(key);
-      }
-    }
-    // observe data
-    Observer.create(data).addVm(this);
-  };
-  
-  // /**
-  //  * Swap the isntance's $data. Called in $data's setter.
-  //  *
-  //  * @param {Object} newData
-  //  */
-  
-  // exports._setData = function (newData) {
-  //   newData = newData || {}
-  //   var oldData = this._data
-  //   this._data = newData
-  //   var keys, key, i
-  //   // unproxy keys not present in new data
-  //   keys = Object.keys(oldData)
-  //   i = keys.length
-  //   while (i--) {
-  //     key = keys[i]
-  //     if (!_.isReserved(key) && !(key in newData)) {
-  //       this._unproxy(key)
-  //     }
-  //   }
-  //   // proxy keys not already proxied,
-  //   // and trigger change for changed values
-  //   keys = Object.keys(newData)
-  //   i = keys.length
-  //   while (i--) {
-  //     key = keys[i]
-  //     if (!this.hasOwnProperty(key) && !_.isReserved(key)) {
-  //       // new property
-  //       this._proxy(key)
-  //     }
-  //   }
-  //   oldData.__ob__.removeVm(this)
-  //   Observer.create(newData).addVm(this)
-  //   this._digest()
-  // }
-  
-  /**
-   * Proxy a property, so that
-   * vm.prop === vm._data.prop
-   *
-   * @param {String} key
-   */
-  
-  exports._proxy = function (key) {
-    // need to store ref to self here
-    // because these getter/setters might
-    // be called by child instances!
-    var self = this;
-    Object.defineProperty(self, key, {
-      configurable: true,
-      enumerable: true,
-      get: function proxyGetter() {
-        return self._data[key];
-      },
-      set: function proxySetter(val) {
-        self._data[key] = val;
-      }
-    });
-  };
-  
-  /**
-   * Unproxy a property.
-   *
-   * @param {String} key
-   */
-  
-  exports._unproxy = function (key) {
-    delete this[key];
-  };
-  
-  // /**
-  //  * Force update on every watcher in scope.
-  //  */
-  
-  // exports._digest = function () {
-  //   var i = this._watchers.length
-  //   while (i--) {
-  //     this._watchers[i].update()
-  //   }
-  //   var children = this._children
-  //   i = children.length
-  //   while (i--) {
-  //     var child = children[i]
-  //     if (child.$options.inherit) {
-  //       child._digest()
-  //     }
-  //   }
-  // }
-  
-  /**
-   * Setup computed properties. They are essentially
-   * special getter/setters
-   */
-  
-  function noop() {}
-  exports._initComputed = function () {
-    // var computed = this.$options.computed
-    var computed = this._computed;
-    if (computed) {
-      for (var key in computed) {
-        var userDef = computed[key];
-        var def = {
-          enumerable: true,
-          configurable: true
-        };
-        if (typeof userDef === 'function') {
-          def.get = _.bind(userDef, this);
-          def.set = noop;
-        } else {
-          def.get = userDef.get ? _.bind(userDef.get, this) : noop;
-          def.set = userDef.set ? _.bind(userDef.set, this) : noop;
-        }
-        Object.defineProperty(this, key, def);
-      }
-    }
-  };
-  
-  /**
-   * Setup instance methods. Methods must be bound to the
-   * instance since they might be called by children
-   * inheriting them.
-   */
-  
-  exports._initMethods = function () {
-    // var methods = this.$options.methods
-    var methods = this._methods;
-    if (methods) {
-      for (var key in methods) {
-        this[key] = _.bind(methods[key], this);
-      }
-    }
-  };
-  
-  // /**
-  //  * Initialize meta information like $index, $key & $value.
-  //  */
-
-  // exports._initMeta = function () {
-  //   var metas = this.$options._meta
-  //   if (metas) {
-  //     for (var key in metas) {
-  //       this._defineMeta(key, metas[key])
-  //     }
-  //   }
-  // }
-
-  // /**
-  //  * Define a meta property, e.g $index, $key, $value
-  //  * which only exists on the vm instance but not in $data.
-  //  *
-  //  * @param {String} key
-  //  * @param {*} value
-  //  */
-
-  // exports._defineMeta = function (key, value) {
-  //   var dep = new Dep()
-  //   Object.defineProperty(this, key, {
-  //     enumerable: true,
-  //     configurable: true,
-  //     get: function metaGetter () {
-  //       if (Observer.target) {
-  //         Observer.target.addDep(dep)
-  //       }
-  //       return value
-  //     },
-  //     set: function metaSetter (val) {
-  //       if (val !== value) {
-  //         value = val
-  //         dep.notify()
-  //       }
-  //     }
-  //   })
-  // }
-
-/***/ },
-/* 87 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  // required for code in instance/observer
-  module.exports = __webpack_require__(81);
-
-/***/ },
-/* 88 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  var _ = __webpack_require__(87);
-  var config = __webpack_require__(89);
-  var Dep = __webpack_require__(90);
-  var arrayMethods = __webpack_require__(91);
-  var arrayKeys = Object.getOwnPropertyNames(arrayMethods);
-  __webpack_require__(92);
-  
-  var uid = 0;
-  
-  /**
-   * Type enums
-   */
-  
-  var ARRAY = 0;
-  var OBJECT = 1;
-  
-  /**
-   * Augment an target Object or Array by intercepting
-   * the prototype chain using __proto__
-   *
-   * @param {Object|Array} target
-   * @param {Object} proto
-   */
-  
-  function protoAugment(target, src) {
-    target.__proto__ = src;
-  }
-  
-  /**
-   * Augment an target Object or Array by defining
-   * hidden properties.
-   *
-   * @param {Object|Array} target
-   * @param {Object} proto
-   */
-  
-  function copyAugment(target, src, keys) {
-    var i = keys.length;
-    var key;
-    while (i--) {
-      key = keys[i];
-      _.define(target, key, src[key]);
-    }
-  }
-  
-  /**
-   * 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.
-   *
-   * @param {Array|Object} value
-   * @param {Number} type
-   * @constructor
-   */
-  
-  function Observer(value, type) {
-    this.id = ++uid;
-    this.value = value;
-    this.active = true;
-    this.deps = [];
-    _.define(value, '__ob__', this);
-    if (type === ARRAY) {
-      var augment = config.proto && _.hasProto ? protoAugment : copyAugment;
-      augment(value, arrayMethods, arrayKeys);
-      this.observeArray(value);
-    } else if (type === OBJECT) {
-      this.walk(value);
-    }
-  }
-  
-  Observer.target = null;
-  
-  var p = Observer.prototype;
-  
-  /**
-   * 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.
-   *
-   * @param {*} value
-   * @return {Observer|undefined}
-   * @static
-   */
-  
-  Observer.create = function (value) {
-    if (value && value.hasOwnProperty('__ob__') && value.__ob__ instanceof Observer) {
-      return value.__ob__;
-    } else if (_.isArray(value)) {
-      return new Observer(value, ARRAY);
-    } else if (_.isPlainObject(value) && !value._isVue // avoid Vue instance
-    ) {
-        return new Observer(value, OBJECT);
-      }
-  };
-  
-  /**
-   * Walk through each property and convert them into
-   * getter/setters. This method should only be called when
-   * value type is Object. Properties prefixed with `$` or `_`
-   * and accessor properties are ignored.
-   *
-   * @param {Object} obj
-   */
-  
-  p.walk = function (obj) {
-    var keys = Object.keys(obj);
-    var i = keys.length;
-    var key, prefix;
-    while (i--) {
-      key = keys[i];
-      prefix = key.charCodeAt(0);
-      if (prefix !== 0x24 && prefix !== 0x5F) {
-        // skip $ or _
-        this.convert(key, obj[key]);
-      }
-    }
-  };
-  
-  /**
-   * Try to carete an observer for a child value,
-   * and if value is array, link dep to the array.
-   *
-   * @param {*} val
-   * @return {Dep|undefined}
-   */
-  
-  p.observe = function (val) {
-    return Observer.create(val);
-  };
-  
-  /**
-   * Observe a list of Array items.
-   *
-   * @param {Array} items
-   */
-  
-  p.observeArray = function (items) {
-    var i = items.length;
-    while (i--) {
-      this.observe(items[i]);
-    }
-  };
-  
-  /**
-   * Convert a property into getter/setter so we can emit
-   * the events when the property is accessed/changed.
-   *
-   * @param {String} key
-   * @param {*} val
-   */
-  
-  p.convert = function (key, val) {
-    var ob = this;
-    var childOb = ob.observe(val);
-    var dep = new Dep();
-    if (childOb) {
-      childOb.deps.push(dep);
-    }
-    Object.defineProperty(ob.value, key, {
-      enumerable: true,
-      configurable: true,
-      get: function get() {
-        // Observer.target is a watcher whose getter is
-        // currently being evaluated.
-        if (ob.active && Observer.target) {
-          Observer.target.addDep(dep);
-        }
-        return val;
-      },
-      set: function set(newVal) {
-        if (newVal === val) return;
-        // remove dep from old value
-        var oldChildOb = val && val.__ob__;
-        if (oldChildOb) {
-          oldChildOb.deps.$remove(dep);
-        }
-        val = newVal;
-        // add dep to new value
-        var newChildOb = ob.observe(newVal);
-        if (newChildOb) {
-          newChildOb.deps.push(dep);
-        }
-        dep.notify();
-      }
-    });
-  };
-  
-  /**
-   * Notify change on all self deps on an observer.
-   * This is called when a mutable value mutates. e.g.
-   * when an Array's mutating methods are called, or an
-   * Object's $add/$delete are called.
-   */
-  
-  p.notify = function () {
-    var deps = this.deps;
-    for (var i = 0, l = deps.length; i < l; i++) {
-      deps[i].notify();
-    }
-  };
-  
-  /**
-   * Add an owner vm, so that when $add/$delete mutations
-   * happen we can notify owner vms to proxy the keys and
-   * digest the watchers. This is only called when the object
-   * is observed as an instance's root $data.
-   *
-   * @param {Vue} vm
-   */
-  
-  p.addVm = function (vm) {
-    (this.vms = this.vms || []).push(vm);
-  };
-  
-  /**
-   * Remove an owner vm. This is called when the object is
-   * swapped out as an instance's $data object.
-   *
-   * @param {Vue} vm
-   */
-  
-  p.removeVm = function (vm) {
-    this.vms.$remove(vm);
-  };
-  
-  module.exports = Observer;
-
-/***/ },
-/* 89 */
-/***/ function(module, exports) {
-
-  "use strict";
-  
-  module.exports = { proto: true };
-
-/***/ },
-/* 90 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  var _ = __webpack_require__(87);
-  
-  /**
-   * A dep is an observable that can have multiple
-   * directives subscribing to it.
-   *
-   * @constructor
-   */
-  
-  function Dep() {
-    this.subs = [];
-  }
-  
-  var p = Dep.prototype;
-  
-  /**
-   * Add a directive subscriber.
-   *
-   * @param {Directive} sub
-   */
-  
-  p.addSub = function (sub) {
-    this.subs.push(sub);
-  };
-  
-  /**
-   * Remove a directive subscriber.
-   *
-   * @param {Directive} sub
-   */
-  
-  p.removeSub = function (sub) {
-    this.subs.$remove(sub);
-  };
-  
-  /**
-   * Notify all subscribers of a new value.
-   */
-  
-  p.notify = function () {
-    // stablize the subscriber list first
-    var subs = _.toArray(this.subs);
-    for (var i = 0, l = subs.length; i < l; i++) {
-      subs[i].update();
-    }
-  };
-  
-  module.exports = Dep;
-
-/***/ },
-/* 91 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  var _ = __webpack_require__(87);
-  var arrayProto = Array.prototype;
-  var arrayMethods = Object.create(arrayProto)
-  
-  /**
-   * Intercept mutating methods and emit events
-   */
-  
-  ;['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'].forEach(function (method) {
-    // cache original method
-    var original = arrayProto[method];
-    _.define(arrayMethods, method, function mutator() {
-      // avoid leaking arguments:
-      // http://jsperf.com/closure-with-arguments
-      var i = arguments.length;
-      var args = new Array(i);
-      while (i--) {
-        args[i] = arguments[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.notify();
-      return result;
-    });
-  });
-  
-  /**
-   * Swap the element at the given index with a new value
-   * and emits corresponding event.
-   *
-   * @param {Number} index
-   * @param {*} val
-   * @return {*} - replaced element
-   */
-  
-  _.define(arrayProto, '$set', function $set(index, val) {
-    if (index >= this.length) {
-      this.length = index + 1;
-    }
-    return this.splice(index, 1, val)[0];
-  });
-  
-  /**
-   * Convenience method to remove the element at given index.
-   *
-   * @param {Number} index
-   * @param {*} val
-   */
-  
-  _.define(arrayProto, '$remove', function $remove(index) {
-    /* istanbul ignore if */
-    if (!this.length) return;
-    if (typeof index !== 'number') {
-      index = _.indexOf(this, index);
-    }
-    if (index > -1) {
-      this.splice(index, 1);
-    }
-  });
-  
-  module.exports = arrayMethods;
-
-/***/ },
-/* 92 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  var _ = __webpack_require__(87);
-  var objProto = Object.prototype;
-  
-  /**
-   * Add a new property to an observed object
-   * and emits corresponding event
-   *
-   * @param {String} key
-   * @param {*} val
-   * @public
-   */
-  
-  _.define(objProto, '$add', function $add(key, val) {
-    if (this.hasOwnProperty(key)) return;
-    var ob = this.__ob__;
-    if (!ob || _.isReserved(key)) {
-      this[key] = val;
-      return;
-    }
-    ob.convert(key, val);
-    ob.notify();
-    if (ob.vms) {
-      var i = ob.vms.length;
-      while (i--) {
-        var vm = ob.vms[i];
-        vm._proxy(key);
-        // vm._digest() // todo
-      }
-    }
-  });
-  
-  /**
-   * Set a property on an observed object, calling add to
-   * ensure the property is observed.
-   *
-   * @param {String} key
-   * @param {*} val
-   * @public
-   */
-  
-  _.define(objProto, '$set', function $set(key, val) {
-    this.$add(key, val);
-    this[key] = val;
-  });
-  
-  /**
-   * Deletes a property from an observed object
-   * and emits corresponding event
-   *
-   * @param {String} key
-   * @public
-   */
-  
-  _.define(objProto, '$delete', function $delete(key) {
-    if (!this.hasOwnProperty(key)) return;
-    delete this[key];
-    var ob = this.__ob__;
-    if (!ob || _.isReserved(key)) {
-      return;
-    }
-    ob.notify();
-    if (ob.vms) {
-      var i = ob.vms.length;
-      while (i--) {
-        var vm = ob.vms[i];
-        vm._unproxy(key);
-        // vm._digest() // todo
-      }
-    }
-  });
-
-/***/ },
-/* 93 */
-/***/ function(module, exports) {
-
-  'use strict';
-  
-  Object.defineProperty(exports, "__esModule", {
-    value: true
-  });
-  
-  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
-  
-  exports._build = _build;
-  exports._generate = _generate;
-  exports._generateElement = _generateElement;
-  exports._setChildren = _setChildren;
-  exports._checkRepeat = _checkRepeat;
-  exports._checkDisplay = _checkDisplay;
-  exports._watchBlock = _watchBlock;
-  exports._mergeContext = _mergeContext;
-  /**
-  * @fileOverview
-  * ViewModel template parser & data-binding process
-  *
-  * required:
-  * index.js: Vm
-  * dom-helper.js: _createElement, _createBlock
-  * dom-helper.js: _attachTarget, _moveTarget, _removeTarget
-  * directive.js: _bindElement, _bindSubVm, _watch
-  * events.js: $on
-  */
-  
-  /**
-   * build(externalDirs)
-   *   createVm()
-   *   merge(externalDirs, dirs)
-   *   generate(template, parentNode)
-   *     if (type is content) create contentNode
-   *     else if (dirs have v-for) foreach -> create context
-   *       -> generate(templateWithoutFor, parentNode): diff(list) onchange
-   *     else if (dirs have v-if) assert
-   *       -> generate(templateWithoutIf, parentNode): toggle(shown) onchange
-   *     else if (type is native)
-   *       set(dirs): update(id/attr/style/class) onchange
-   *       append(template, parentNode)
-   *       foreach childNodes -> generate(childNode, template)
-   *     else if (type is custom)
-   *       addChildVm(vm, parentVm)
-   *       build(externalDirs)
-   *       foreach childNodes -> generate(childNode, template)
-   */
-  function _build() {
-    var opt = this._options || {};
-    var template = opt.template || {};
-  
-    if (opt.replace) {
-      if (template.children && template.children.length === 1) {
-        this._generate(template.children[0], this._parentEl);
-      } else {
-        this._generate(template.children, this._parentEl);
-      }
-    } else {
-      this._generate(template, this._parentEl);
-    }
-  
-    this.$emit('hook:ready');
-    this._ready = true;
-  }
-  
-  /**
-   * Generate elements by child or children and append to parent elements.
-   * Root element info would be merged if has. The first argument may be an array
-   * if the root element with options.replace has not only one child.
-   *
-   * @param  {object|array} target
-   * @param  {object} parentEl
-   * @param  {object} context
-   */
-  function _generate(target, parentEl, context) {
-    var _this = this;
-  
-    if (Array.isArray(target)) {
-      var _ret = function () {
-        var fragBlock = _this._createBlock(parentEl);
-        target.forEach(function (child) {
-          _this._generate(child, fragBlock, context);
-        });
-        return {
-          v: void 0
-        };
-      }();
-  
-      if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v;
-    }
-  
-    context = context || {};
-  
-    if (target.type === 'content' || target.type === 'slot') {
-      this._content = this._createBlock(parentEl);
-      return;
-    }
-  
-    if (!context.hasOwnProperty('repeat') && target.repeat) {
-      var _ret2 = function () {
-        var expression = target.repeat.expression || target.repeat;
-        var list = expression.call(_this);
-        var repeatId = latestRepeatId++;
-        var latestItemId = markList(list, repeatId);
-  
-        var fragBlock = _this._createBlock(parentEl);
-        fragBlock.children = [];
-        fragBlock.data = list.slice(0);
-  
-        _this._checkRepeat(target, fragBlock, repeatId, latestItemId);
-  
-        list.forEach(function (item, index) {
-          if ((typeof item === 'undefined' ? 'undefined' : _typeof(item)) === 'object') {
-            item.INDEX = index;
-          }
-          _this._generate(target, fragBlock, { repeat: item });
-        });
-  
-        return {
-          v: void 0
-        };
-      }();
-  
-      if ((typeof _ret2 === 'undefined' ? 'undefined' : _typeof(_ret2)) === "object") return _ret2.v;
-    }
-  
-    var subContext = this;
-    if (context.repeat && !context.shown) {
-      subContext = this._mergeContext(context.repeat);
-    }
-  
-    if (!context.hasOwnProperty('shown') && target.shown) {
-      var display = target.shown.call(subContext);
-      var newContext = { shown: true };
-      var _fragBlock = subContext._createBlock(parentEl);
-  
-      if (parentEl.element && parentEl.children) {
-        parentEl.children.push(_fragBlock);
-      }
-  
-      if (context.repeat) {
-        newContext.repeat = context.repeat;
-      }
-  
-      _fragBlock.display = !!display;
-      subContext._checkDisplay(target, _fragBlock, newContext);
-  
-      if (display) {
-        subContext._generate(target, _fragBlock, newContext);
-      }
-  
-      return;
-    }
-  
-    var typeGetter = target.type;
-    var type = typeGetter;
-  
-    if (typeof typeGetter === 'function') {
-      type = typeGetter.call(subContext);
-  
-      if (!context.hasOwnProperty('type')) {
-        var _ret3 = function () {
-          var newContext = { type: type };
-          var fragBlock = subContext._createBlock(parentEl);
-  
-          if (parentEl.element && parentEl.children) {
-            parentEl.children.push(fragBlock);
-          }
-  
-          subContext._watch(typeGetter, function (value) {
-            subContext._removeBlock(fragBlock, true);
-            subContext._generate(target, fragBlock, { type: value });
-          });
-  
-          subContext._generate(target, fragBlock, newContext);
-  
-          return {
-            v: void 0
-          };
-        }();
-  
-        if ((typeof _ret3 === 'undefined' ? 'undefined' : _typeof(_ret3)) === "object") return _ret3.v;
-      }
-    }
-  
-    var isComponent = void 0;
-    if (this._app && this._app.customComponentMap && type) {
-      isComponent = this._app.customComponentMap[type];
-    } else {
-      isComponent = target.component;
-    }
-  
-    if (isComponent) {
-      var Vm = this.constructor;
-      var subVm = new Vm(type, subContext, parentEl, undefined, {
-        'hook:init': function hookInit() {
-          subContext._setId(target.id, null, this);
-        },
-        'hook:created': function hookCreated() {
-          subContext._bindSubVm(this, target, context.repeat);
-        },
-        'hook:ready': function hookReady() {
-          if (this._content) {
-            subContext._setChildren(target, this._content);
-          }
-        }
-      });
-      subContext._bindSubVmAfterInitialized(subVm, target);
-      return;
-    }
-  
-    var element = subContext._generateElement(type, target, parentEl);
-    var treeMode = target.append === 'tree';
-    if (!treeMode) {
-      subContext._attachTarget(element, parentEl);
-    }
-    subContext._setChildren(target, element);
-    if (treeMode) {
-      subContext._attachTarget(element, parentEl);
-    }
-  }
-  
-  /**
-   * Generate element from template and attach to the dest if needed.
-   * The time to attach depends on whether the mode status is node or tree.
-   *
-   * @param  {object} template
-   * @param  {object} dest
-   */
-  function _generateElement(type, template, dest) {
-  
-    this._applyNaitveComponentOptions(template);
-  
-    var element = void 0;
-    if (dest.ref === '_documentElement') {
-      // if its parent is documentElement then it's a body
-      element = this._createBody(type);
-    } else {
-      element = this._createElement(type);
-    }
-    // TODO it was a root element when not in a fragment
-    if (!this._rootEl) {
-      this._rootEl = element;
-    }
-  
-    this._bindElement(element, template);
-  
-    if (template.attr && template.attr.append) {
-      // backward, append prop in attr
-      element.append = template.attr.append;
-    }
-  
-    return element;
-  }
-  
-  /**
-   * Set all children to a certain parent element.
-   *
-   * @param {object} template
-   * @param {object} parentEl
-   */
-  function _setChildren(template, parentEl) {
-    var _this2 = this;
-  
-    var children = template.children;
-    if (children && children.length) {
-      children.forEach(function (child) {
-        _this2._generate(child, parentEl);
-      });
-    }
-  }
-  
-  /**
-   * Watch the list update and refresh the changes.
-   *
-   * @param  {object} target
-   * @param  {object} fragBlock
-   */
-  function _checkRepeat(target, fragBlock, repeatId, latestItemId) {
-    var _this3 = this;
-  
-    var expression = target.repeat.expression || target.repeat;
-    var children = fragBlock.children;
-  
-    this._watchBlock(fragBlock, expression, 'repeat', function (value) {
-      if (!fragBlock) {
-        return;
-      }
-  
-      var oldChildren = children.slice();
-      var oldValue = fragBlock.data.slice();
-      // 1. collect all new refs track by
-      var trackMap = {};
-      var reusedMap = {};
-      value.forEach(function (item, index) {
-        var key = item['__wx_repeat_' + repeatId + '__'];
-        if (!key) {
-          key = latestItemId++;
-          setRepeatItemId(item, repeatId, key);
-        }
-        trackMap[key] = item;
-      });
-  
-      // 2. remove unused element foreach old item
-      var reusedList = [];
-      oldValue.forEach(function (item, index) {
-        var key = item['__wx_repeat_' + repeatId + '__'];
-        if (trackMap.hasOwnProperty(key)) {
-          reusedMap[key] = { item: item, index: index, target: oldChildren[index] };
-          reusedList.push(item);
-        } else {
-          _this3._removeTarget(oldChildren[index]);
-        }
-      });
-  
-      // 3. create new element foreach new item
-      children.length = 0;
-      fragBlock.data = value.slice();
-      fragBlock.updateMark = fragBlock.start;
-  
-      value.forEach(function (item, index) {
-        var key = item['__wx_repeat_' + repeatId + '__'];
-        var reused = reusedMap[key];
-        if ((typeof item === 'undefined' ? 'undefined' : _typeof(item)) === 'object') {
-          item.INDEX = index;
-        }
-        if (reused) {
-          if (reused.item === reusedList[0]) {
-            reusedList.shift();
-          } else {
-            reusedList.$remove(reused.item);
-            _this3._moveTarget(reused.target, fragBlock.updateMark, true);
-          }
-          children.push(reused.target);
-          fragBlock.updateMark = reused.target;
-        } else {
-          _this3._generate(target, fragBlock, { repeat: item });
-        }
-      });
-  
-      delete fragBlock.updateMark;
-    });
-  }
-  
-  var latestRepeatId = 1;
-  
-  function markList(list, repeatId) {
-    var latestItemId = 1;
-    list.forEach(function (item) {
-      setRepeatItemId(item, repeatId, latestItemId++);
-    });
-    return latestItemId;
-  }
-  
-  function setRepeatItemId(item, repeatId, itemId) {
-    var key = '__wx_repeat_' + repeatId + '__';
-    if ((typeof item === 'undefined' ? 'undefined' : _typeof(item)) === 'object') {
-      Object.defineProperty(item, key, {
-        value: itemId
-      });
-    }
-  }
-  
-  /**
-   * Watch the display update and add/remove the element.
-   *
-   * @param  {object} target
-   * @param  {object} fragBlock
-   * @param  {object} context
-   */
-  function _checkDisplay(target, fragBlock, context) {
-    var _this4 = this;
-  
-    this._watchBlock(fragBlock, target.shown, 'shown', function (value) {
-      if (!fragBlock || !!fragBlock.display === !!value) {
-        return;
-      }
-      fragBlock.display = value;
-      if (value) {
-        _this4._generate(target, fragBlock, context);
-      } else {
-        _this4._removeBlock(fragBlock, true);
-      }
-    });
-  }
-  
-  function _watchBlock(fragBlock, calc, type, handler) {
-    var differ = this && this._app && this._app.differ;
-    var config = {};
-    var depth = (fragBlock.element.depth || 0) + 1;
-  
-    this._watch(calc, function (value) {
-      config.latestValue = value;
-      if (differ && !config.recorded) {
-        differ.append(type, depth, fragBlock.blockId, function () {
-          var latestValue = config.latestValue;
-          handler(latestValue);
-          config.recorded = false;
-          config.latestValue = undefined;
-        });
-      }
-      config.recorded = true;
-    });
-  }
-  
-  /**
-   * Clone a context and merge certain data.
-   *
-   * @param  {object} mergedData
-   * @return {object}
-   */
-  function _mergeContext(mergedData) {
-    var context = Object.create(this);
-    context._data = mergedData;
-    context._initData();
-    context._realParent = this;
-    return context;
-  }
-
-/***/ },
-/* 94 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  Object.defineProperty(exports, "__esModule", {
-    value: true
-  });
-  
-  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; /**
-                                                                                                                                                                                                                                                     * @fileOverview
-                                                                                                                                                                                                                                                     * Directive Parser
-                                                                                                                                                                                                                                                     */
-  
-  exports._applyNaitveComponentOptions = _applyNaitveComponentOptions;
-  exports._bindElement = _bindElement;
-  exports._bindSubVm = _bindSubVm;
-  exports._bindSubVmAfterInitialized = _bindSubVmAfterInitialized;
-  exports._setId = _setId;
-  exports._setAttr = _setAttr;
-  exports._setClass = _setClass;
-  exports._setStyle = _setStyle;
-  exports._setEvent = _setEvent;
-  exports._bindEvents = _bindEvents;
-  exports._bindDir = _bindDir;
-  exports._bindKey = _bindKey;
-  exports._watch = _watch;
-  
-  var _util = __webpack_require__(81);
-  
-  var _watcher = __webpack_require__(95);
-  
-  var _watcher2 = _interopRequireDefault(_watcher);
-  
-  var _config = __webpack_require__(79);
-  
-  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-  
-  var SETTERS = {
-    attr: 'setAttr',
-    style: 'setStyle',
-    event: 'addEvent'
-  };
-  
-  /**
-   * apply the native component's options(specified by template.type)
-   * to the template
-   */
-  function _applyNaitveComponentOptions(template) {
-    var type = template.type;
-  
-    var options = _config.nativeComponentMap[type];
-  
-    if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) === 'object') {
-      (0, _util.extend)(template, options);
-    }
-  }
-  
-  /**
-   * bind all id, attr, classnames, style, events to an element
-   */
-  function _bindElement(el, template) {
-    this._setId(template.id, el, this);
-    this._setAttr(el, template.attr);
-    this._setClass(el, template.classList);
-    this._setStyle(el, template.style);
-    this._bindEvents(el, template.events);
-  }
-  
-  /**
-   * bind all props to sub vm and bind all style, events to the root element
-   * of the sub vm if it doesn't have a replaced multi-node fragment
-   */
-  function _bindSubVm(subVm, template, repeatItem) {
-    subVm = subVm || {};
-    template = template || {};
-  
-    var options = subVm._options || {};
-  
-    // bind props
-    var props = options.props;
-  
-    if (Array.isArray(props)) {
-      props = props.reduce(function (result, value) {
-        result[value] = true;
-        return result;
-      }, {});
-    }
-  
-    mergeProps(repeatItem, props, this, subVm);
-    mergeProps(template.attr, props, this, subVm);
-  }
-  
-  function _bindSubVmAfterInitialized(subVm, template) {
-    mergeClassStyle(template.classList, this, subVm);
-    mergeStyle(template.style, this, subVm);
-    mergeEvent(template.events, this, subVm);
-  }
-  
-  function mergeProps(target, props, vm, subVm) {
-    if (!target) {
-      return;
-    }
-  
-    var _loop = function _loop(key) {
-      if (!props || props[key]) {
-        var value = target[key];
-        if (typeof value === 'function') {
-          var returnValue = vm._watch(value, function (v) {
-            subVm[key] = v;
-          });
-          subVm[key] = returnValue;
-        } else {
-          subVm[key] = value;
-        }
-      }
-    };
-  
-    for (var key in target) {
-      _loop(key);
-    }
-  }
-  
-  function mergeStyle(target, vm, subVm) {
-    var _loop2 = function _loop2(key) {
-      var value = target[key];
-      if (typeof value === 'function') {
-        var returnValue = vm._watch(value, function (v) {
-          if (subVm._rootEl) {
-            subVm._rootEl.setStyle(key, v);
-          }
-        });
-        subVm._rootEl.setStyle(key, returnValue);
-      } else {
-        if (subVm._rootEl) {
-          subVm._rootEl.setStyle(key, value);
-        }
-      }
-    };
-  
-    for (var key in target) {
-      _loop2(key);
-    }
-  }
-  
-  function mergeClassStyle(target, vm, subVm) {
-    var css = vm._options && vm._options.style || {};
-  
-    if (!subVm._rootEl) {
-      return;
-    }
-  
-    if (typeof target === 'function') {
-      var _value = vm._watch(target, function (v) {
-        setClassStyle(subVm._rootEl, css, v);
-      });
-      setClassStyle(subVm._rootEl, css, _value);
-    } else if (target) {
-      setClassStyle(subVm._rootEl, css, target);
-    }
-  }
-  
-  function mergeEvent(target, vm, subVm) {
-    if (target && subVm._rootEl) {
-      for (var type in target) {
-        var handler = vm[target[type]];
-        if (handler) {
-          subVm._rootEl.addEvent(type, (0, _util.bind)(handler, vm));
-        }
-      }
-    }
-  }
-  
-  /**
-   * bind id to an element
-   * each id is unique in a whole vm
-   */
-  function _setId(id, el, vm) {
-    var _this = this;
-  
-    var map = Object.create(null);
-  
-    Object.defineProperties(map, {
-      vm: {
-        value: vm,
-        writable: false,
-        configurable: false
-      },
-      el: {
-        get: function get() {
-          return el || vm._rootEl;
-        },
-        configurable: false
-      }
-    });
-  
-    if (typeof id === 'function') {
-      var handler = id;
-      id = handler.call(this);
-      if (id) {
-        this._ids[id] = map;
-      }
-      this._watch(handler, function (newId) {
-        if (newId) {
-          _this._ids[newId] = map;
-        }
-      });
-    } else if (id && typeof id === 'string') {
-      this._ids[id] = map;
-    }
-  }
-  
-  /**
-   * bind attr to an element
-   */
-  function _setAttr(el, attr) {
-    this._bindDir(el, 'attr', attr);
-  }
-  
-  function setClassStyle(el, css, classList) {
-    var classStyle = {};
-    var length = classList.length;
-  
-    for (var i = 0; i < length; i++) {
-      var style = css[classList[i]];
-      if (style) {
-        for (var key in style) {
-          classStyle[key] = style[key];
-        }
-      }
-    }
-    el.setClassStyle(classStyle);
-  }
-  
-  /**
-   * bind classnames to an element
-   */
-  function _setClass(el, classList) {
-  
-    if (typeof classList !== 'function' && !Array.isArray(classList)) {
-      return;
-    }
-    if (Array.isArray(classList) && !classList.length) {
-      el.setClassStyle({});
-      return;
-    }
-  
-    var style = this._options && this._options.style || {};
-    if (typeof classList === 'function') {
-      var _value2 = this._watch(classList, function (v) {
-        setClassStyle(el, style, v);
-      });
-      setClassStyle(el, style, _value2);
-    } else {
-      setClassStyle(el, style, classList);
-    }
-  }
-  
-  /**
-   * bind style to an element
-   */
-  function _setStyle(el, style) {
-    this._bindDir(el, 'style', style);
-  }
-  
-  /**
-   * add an event type and handler to an element and generate a dom update
-   */
-  function _setEvent(el, type, handler) {
-    el.addEvent(type, (0, _util.bind)(handler, this));
-  }
-  
-  /**
-   * add all events of an element
-   */
-  function _bindEvents(el, events) {
-    if (!events) {
-      return;
-    }
-    var keys = Object.keys(events);
-    var i = keys.length;
-    while (i--) {
-      var key = keys[i];
-      var handler = events[key];
-      if (typeof handler === 'string') {
-        handler = this[handler];
-      }
-      this._setEvent(el, key, handler);
-    }
-  }
-  
-  /**
-   * set a series of members as a kind of an element
-   * for example: style, attr, ...
-   * if the value is a function then bind the data changes
-   */
-  function _bindDir(el, name, data) {
-    if (!data) {
-      return;
-    }
-    var keys = Object.keys(data);
-    var i = keys.length;
-    while (i--) {
-      var key = keys[i];
-      var _value3 = data[key];
-      if (typeof _value3 === 'function') {
-        var update = _value3;
-        this._bindKey(el, name, key, update);
-      } else {
-        el[SETTERS[name]](key, _value3);
-      }
-    }
-  }
-  
-  /**
-   * bind data changes to a certain key to a name series in an element
-   */
-  function _bindKey(el, name, key, calc) {
-    var _this2 = this;
-  
-    var methodName = SETTERS[name];
-    var obj = el[name];
-    // watch the calc, and returns a value by calc.call()
-    var value = this._watch(calc, function (value) {
-      function handler() {
-        el[methodName](key, value);
-      }
-      var differ = _this2 && _this2._app && _this2._app.differ;
-      if (differ) {
-        differ.append('element', el.depth, el.ref, handler);
-      } else {
-        handler();
-      }
-    });
-  
-    el[methodName](key, value);
-  }
-  
-  /**
-   * watch a calc function and callback if the calc value changes
-   */
-  function _watch(calc, callback) {
-    var watcher = new _watcher2.default(this, calc, function (value, oldValue) {
-      /* istanbul ignore if */
-      if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) !== 'object' && value === oldValue) {
-        return;
-      }
-      callback(value);
-    });
-  
-    return watcher.value;
-  }
-
-/***/ },
-/* 95 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  /**
-   * The MIT License (MIT)
-   *
-   * Copyright (c) 2013-2015 Yuxi Evan You
-   *
-   * Permission is hereby granted, free of charge, to any person obtaining a copy
-   * of this software and associated documentation files (the "Software"), to deal
-   * in the Software without restriction, including without limitation the rights
-   * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-   * copies of the Software, and to permit persons to whom the Software is
-   * furnished to do so, subject to the following conditions:
-   *
-   * The above copyright notice and this permission notice shall be included in
-   * all copies or substantial portions of the Software.
-   *
-   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-   * THE SOFTWARE.
-   */
-  
-  var _ = __webpack_require__(87);
-  // var config = require('./config')
-  var Observer = __webpack_require__(88);
-  // var expParser = require('./parsers/expression')
-  // var batcher = require('./batcher')
-  var uid = 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.
-   *
-   * @param {Vue} vm
-   * @param {String} expression
-   * @param {Function} cb
-   * @param {Object} options
-   *                 - {Array} filters
-   *                 - {Boolean} twoWay
-   *                 - {Boolean} deep
-   *                 - {Boolean} user
-   *                 - {Function} [preProcess]
-   * @constructor
-   */
-  
-  // function Watcher (vm, expression, cb, options) {
-  function Watcher(vm, update, cb) {
-    this.vm = vm;
-    vm._watchers.push(this);
-    // this.expression = expression
-    this.cb = cb;
-    this.id = ++uid; // uid for batching
-    this.active = true;
-    // options = options || {}
-    // this.deep = !!options.deep
-    // this.user = !!options.user
-    // this.twoWay = !!options.twoWay
-    // this.filters = options.filters
-    // this.preProcess = options.preProcess
-    this.deps = [];
-    this.newDeps = [];
-    // parse expression for getter/setter
-    // var res = expParser.parse(expression, options.twoWay)
-    // this.getter = res.get
-    // this.setter = res.set
-    this.getter = update;
-    this.value = this.get();
-  }
-  
-  var p = Watcher.prototype;
-  
-  /**
-   * Add a dependency to this directive.
-   *
-   * @param {Dep} dep
-   */
-  
-  p.addDep = function (dep) {
-    var newDeps = this.newDeps;
-    var old = this.deps;
-    if (_.indexOf(newDeps, dep) < 0) {
-      newDeps.push(dep);
-      var i = _.indexOf(old, dep);
-      if (i < 0) {
-        dep.addSub(this);
-      } else {
-        old[i] = null;
-      }
-    }
-  };
-  
-  /**
-   * Evaluate the getter, and re-collect dependencies.
-   */
-  
-  p.get = function () {
-    this.beforeGet();
-    var vm = this.vm;
-    var value;
-    try {
-      value = this.getter.call(vm, vm);
-    } catch (e) {
-      // if (config.warnExpressionErrors) {
-      //   _.warn(
-      //     'Error when evaluating expression "' +
-      //     this.expression + '":\n   ' + e
-      //   )
-      // }
-      _.warn('Error when update"');
-    }
-    // "touch" every property so they are all tracked as
-    // dependencies for deep watching
-    if (this.deep) {
-      traverse(value);
-    }
-    if (this.preProcess) {
-      value = this.preProcess(value);
-    }
-    if (this.filters) {
-      value = vm._applyFilters(value, null, this.filters, false);
-    }
-    this.afterGet();
-    return value;
-  };
-  
-  // /**
-  //  * Set the corresponding value with the setter.
-  //  *
-  //  * @param {*} value
-  //  */
-  
-  // p.set = function (value) {
-  //   var vm = this.vm
-  //   if (this.filters) {
-  //     value = vm._applyFilters(
-  //       value, this.value, this.filters, true)
-  //   }
-  //   try {
-  //     this.setter.call(vm, vm, value)
-  //   } catch (e) {
-  //     // if (config.warnExpressionErrors) {
-  //       _.warn(
-  //         'Error when evaluating setter "' +
-  //         this.expression + '":\n   ' + e
-  //       )
-  //     // }
-  //   }
-  // }
-  
-  /**
-   * Prepare for dependency collection.
-   */
-  
-  p.beforeGet = function () {
-    Observer.target = this;
-  };
-  
-  /**
-   * Clean up for dependency collection.
-   */
-  
-  p.afterGet = function () {
-    Observer.target = null;
-    var i = this.deps.length;
-    while (i--) {
-      var dep = this.deps[i];
-      if (dep) {
-        dep.removeSub(this);
-      }
-    }
-    this.deps = this.newDeps;
-    this.newDeps = [];
-  };
-  
-  /**
-   * Subscriber interface.
-   * Will be called when a dependency changes.
-   */
-  
-  // p.update = function () {
-  //   if (!config.async || config.debug) {
-  //     this.run()
-  //   } else {
-  //     batcher.push(this)
-  //   }
-  // }
-  
-  // /**
-  //  * Batcher job interface.
-  //  * Will be called by the batcher.
-  //  */
-  
-  // p.run = function () {
-  p.update = function () {
-    if (this.active) {
-      var value = this.get();
-      if (value !== this.value || Array.isArray(value) || this.deep) {
-        var oldValue = this.value;
-        this.value = value;
-        this.cb(value, oldValue);
-      }
-    }
-  };
-  
-  /**
-   * Remove self from all dependencies' subcriber list.
-   */
-  
-  p.teardown = function () {
-    if (this.active) {
-      // remove self from vm's watcher list
-      // we can skip this if the vm if being destroyed
-      // which can improve teardown performance.
-      if (!this.vm._isBeingDestroyed) {
-        this.vm._watchers.$remove(this);
-      }
-      var i = this.deps.length;
-      while (i--) {
-        this.deps[i].removeSub(this);
-      }
-      this.active = false;
-      this.vm = this.cb = this.value = null;
-    }
-  };
-  
-  /**
-   * Recrusively traverse an object to evoke all converted
-   * getters, so that every nested property inside the object
-   * is collected as a "deep" dependency.
-   *
-   * @param {Object} obj
-   */
-  
-  function traverse(obj) {
-    var key, val, i;
-    for (key in obj) {
-      val = obj[key];
-      if (_.isArray(val)) {
-        i = val.length;
-        while (i--) {
-          traverse(val[i]);
-        }
-      } else if (_.isObject(val)) {
-        traverse(val);
-      }
-    }
-  }
-  
-  module.exports = Watcher;
-
-/***/ },
-/* 96 */
-/***/ function(module, exports) {
-
-  'use strict';
-  
-  Object.defineProperty(exports, "__esModule", {
-    value: true
-  });
-  exports._createBody = _createBody;
-  exports._createElement = _createElement;
-  exports._createBlock = _createBlock;
-  exports._createBlockStart = _createBlockStart;
-  exports._createBlockEnd = _createBlockEnd;
-  exports._attachTarget = _attachTarget;
-  exports._moveTarget = _moveTarget;
-  exports._moveElement = _moveElement;
-  exports._moveBlock = _moveBlock;
-  exports._removeTarget = _removeTarget;
-  exports._removeElement = _removeElement;
-  exports._removeBlock = _removeBlock;
-  /**
-   * @fileOverview Document & Element Helpers.
-   *
-   * required:
-   * Document#: createElement, createComment, getRef
-   * Element#: appendChild, insertBefore, removeChild, nextSibling
-   */
-  
-  /**
-   * Create a body by type
-   * Using this._app.doc
-   *
-   * @param  {string} type
-   */
-  function _createBody(type) {
-    var doc = this._app.doc;
-    return doc.createBody(type);
-  }
-  
-  /**
-   * Create an element by type
-   * Using this._app.doc
-   *
-   * @param  {string} type
-   */
-  function _createElement(type) {
-    var doc = this._app.doc;
-    return doc.createElement(type);
-  }
-  
-  /**
-   * Create and return a frag block for an element.
-   * The frag block has a starter, ender and the element itself.
-   *
-   * @param  {object} element
-   */
-  function _createBlock(element) {
-    var start = this._createBlockStart();
-    var end = this._createBlockEnd();
-    var blockId = lastestBlockId++;
-    if (element.element) {
-      element.element.insertBefore(start, element.end);
-      element.element.insertBefore(end, element.end);
-      element = element.element;
-    } else {
-      element.appendChild(start);
-      element.appendChild(end);
-    }
-    return { start: start, end: end, element: element, blockId: blockId };
-  }
-  
-  var lastestBlockId = 1;
-  
-  /**
-   * Create and return a block starter.
-   * Using this._app.doc
-   */
-  function _createBlockStart() {
-    var doc = this._app.doc;
-    var anchor = doc.createComment('start');
-    return anchor;
-  }
-  
-  /**
-   * Create and return a block ender.
-   * Using this._app.doc
-   */
-  function _createBlockEnd() {
-    var doc = this._app.doc;
-    var anchor = doc.createComment('end');
-    return anchor;
-  }
-  
-  /**
-   * Attach target to a certain dest using appendChild by default.
-   * If the dest is a frag block then insert before the ender.
-   * If the target is a frag block then attach the starter and ender in order.
-   *
-   * @param  {object} target
-   * @param  {object} dest
-   */
-  function _attachTarget(target, dest) {
-  
-    if (dest.element) {
-      var before = dest.end;
-      var after = dest.updateMark;
-      // push new target for watch list update later
-      if (dest.children) {
-        dest.children.push(target);
-      }
-      // for check repeat case
-      if (after) {
-        this._moveTarget(target, after);
-        dest.updateMark = target.element ? target.end : target;
-      } else if (target.element) {
-        dest.element.insertBefore(target.start, before);
-        dest.element.insertBefore(target.end, before);
-      } else {
-        dest.element.insertBefore(target, before);
-      }
-    } else {
-      if (target.element) {
-        dest.appendChild(target.start);
-        dest.appendChild(target.end);
-      } else {
-        dest.appendChild(target);
-      }
-    }
-  }
-  
-  /**
-   * Move target before a certain element. The target maybe block or element.
-   *
-   * @param  {object} target
-   * @param  {object} before
-   */
-  function _moveTarget(target, after) {
-    if (target.element) {
-      this._moveBlock(target, after);
-    } else {
-      this._moveElement(target, after);
-    }
-  }
-  
-  /**
-   * Move element before a certain element.
-   *
-   * @param  {object} element
-   * @param  {object} before
-   */
-  function _moveElement(element, after) {
-    var doc = this._app.doc;
-    var parent = doc.getRef(after.parentRef);
-  
-    if (parent) {
-      parent.insertAfter(element, after);
-    }
-  }
-  
-  /**
-   * Move all elements of the block before a certain element.
-   *
-   * @param  {object} fragBlock
-   * @param  {object} before
-   */
-  function _moveBlock(fragBlock, after) {
-    var doc = this._app.doc;
-    var parent = doc.getRef(after.parentRef);
-  
-    if (parent) {
-      (function () {
-        var el = fragBlock.start;
-        var group = [el];
-  
-        while (el && el !== fragBlock.end) {
-          el = el.next();
-          group.push(el);
-        }
-  
-        var temp = after;
-        group.forEach(function (el) {
-          parent.insertAfter(el, temp);
-          temp = el;
-        });
-      })();
-    }
-  }
-  
-  /**
-   * Remove target from DOM tree.
-   * If the target is a frag block then call _removeBlock
-   *
-   * @param  {object} target
-   */
-  function _removeTarget(target) {
-  
-    if (target.element) {
-      this._removeBlock(target);
-    } else {
-      this._removeElement(target);
-    }
-  }
-  
-  /**
-   * Remove a certain element.
-   * Using this._app.doc
-   *
-   * @param  {object} target
-   */
-  function _removeElement(target) {
-    var doc = this._app.doc;
-    var parent = doc.getRef(target.parentRef);
-  
-    if (parent) {
-      parent.removeChild(target);
-    }
-  }
-  
-  /**
-   * Remove a frag block.
-   * The second param decides whether the block self should be removed too.
-   *
-   * @param  {object}  fragBlock
-   * @param  {Boolean} preserveBlock=false
-   */
-  function _removeBlock(fragBlock) {
-    var _this = this;
-  
-    var preserveBlock = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];
-  
-    var result = [];
-    var el = fragBlock.start.next();
-  
-    while (el && el !== fragBlock.end) {
-      result.push(el);
-      el = el.next();
-    }
-  
-    if (!preserveBlock) {
-      this._removeElement(fragBlock.start);
-    }
-    result.forEach(function (el) {
-      _this._removeElement(el);
-    });
-    if (!preserveBlock) {
-      this._removeElement(fragBlock.end);
-    }
-  }
-
-/***/ },
-/* 97 */
-/***/ function(module, exports) {
-
-  'use strict';
-  
-  Object.defineProperty(exports, "__esModule", {
-    value: true
-  });
-  exports.$emit = $emit;
-  exports.$dispatch = $dispatch;
-  exports.$broadcast = $broadcast;
-  exports.$on = $on;
-  exports.$off = $off;
-  exports._initEvents = _initEvents;
-  function Evt(type, detail) {
-    if (detail instanceof Evt) {
-      return detail;
-    }
-  
-    this.timestamp = Date.now();
-    this.detail = detail;
-    this.type = type;
-  
-    var shouldStop = false;
-    this.stop = function () {
-      shouldStop = true;
-    };
-    this.hasStopped = function () {
-      return shouldStop;
-    };
-  }
-  
-  function $emit(type, detail) {
-    var _this = this;
-  
-    var events = this._vmEvents;
-    var handlerList = events[type];
-    if (handlerList) {
-      (function () {
-        var evt = new Evt(type, detail);
-        handlerList.forEach(function (handler) {
-          handler.call(_this, evt);
-        });
-      })();
-    }
-  }
-  
-  function $dispatch(type, detail) {
-    var evt = new Evt(type, detail);
-    this.$emit(type, evt);
-  
-    if (!evt.hasStopped() && this._parent && this._parent.$dispatch) {
-      this._parent.$dispatch(type, evt);
-    }
-  }
-  
-  function $broadcast(type, detail) {
-    var evt = new Evt(type, detail);
-    this.$emit(type, evt);
-  
-    if (!evt.hasStopped() && this._childrenVms) {
-      this._childrenVms.forEach(function (subVm) {
-        subVm.$broadcast(type, evt);
-      });
-    }
-  }
-  
-  function $on(type, handler) {
-    if (!type || typeof handler !== 'function') {
-      return;
-    }
-    var events = this._vmEvents;
-    var handlerList = events[type] || [];
-    handlerList.push(handler);
-    events[type] = handlerList;
-  
-    // fixed old version lifecycle design
-    if (type === 'hook:ready' && this._ready) {
-      this.$emit('hook:ready');
-    }
-  }
-  
-  function $off(type, handler) {
-    if (!type) {
-      return;
-    }
-    var events = this._vmEvents;
-    if (!handler) {
-      delete events[type];
-      return;
-    }
-    var handlerList = events[type];
-    if (!handlerList) {
-      return;
-    }
-    handlerList.$remove(handler);
-  }
-  
-  var LIFE_CYCLE_TYPES = ['init', 'created', 'ready'];
-  
-  function _initEvents(externalEvents) {
-    var _this2 = this;
-  
-    var options = this._options || {};
-    var events = options.events || {};
-    for (var type1 in events) {
-      this.$on(type1, events[type1]);
-    }
-    for (var type2 in externalEvents) {
-      this.$on(type2, externalEvents[type2]);
-    }
-    LIFE_CYCLE_TYPES.forEach(function (type) {
-      _this2.$on('hook:' + type, options[type]);
-    });
-  }
-
-/***/ },
-/* 98 */
-/***/ function(module, exports) {
-
-  'use strict';
-  
-  Object.defineProperty(exports, "__esModule", {
-    value: true
-  });
-  exports.clearModules = clearModules;
-  exports.getModule = getModule;
-  exports.requireModule = requireModule;
-  exports.registerModules = registerModules;
-  exports.registerMethods = registerMethods;
-  exports.requireComponent = requireComponent;
-  exports.registerComponent = registerComponent;
-  var nativeModules = {};
-  
-  function assignModules(modules, ifReplace) {
-    var _loop = function _loop(moduleName) {
-  
-      // init `modules[moduleName][]`
-      var methods = nativeModules[moduleName];
-      if (!methods) {
-        methods = {};
-        nativeModules[moduleName] = methods;
-      }
-  
-      // push each non-existed new method
-      modules[moduleName].forEach(function (method) {
-        if (typeof method === 'string') {
-          method = {
-            name: method
-          };
-        }
-  
-        if (!methods[method.name] || ifReplace) {
-          methods[method.name] = method;
-        }
-      });
-    };
-  
-    for (var moduleName in modules) {
-      _loop(moduleName);
-    }
-  }
-  
-  function assignApis(Ctor, apis) {
-    var p = Ctor.prototype;
-  
-    for (var apiName in apis) {
-      if (!p.hasOwnProperty(apiName)) {
-        p[apiName] = apis[apiName];
-      }
-    }
-  }
-  
-  function clearModules() {
-    nativeModules = {};
-  }
-  
-  function getModule(moduleName) {
-    return nativeModules[moduleName];
-  }
-  
-  /**
-   * @context a instance of AppInstance
-   */
-  function requireModule(moduleName) {
-    var _this = this;
-  
-    var methods = nativeModules[moduleName];
-    var target = {};
-  
-    var _loop2 = function _loop2(methodName) {
-      target[methodName] = function () {
-        for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
-          args[_key] = arguments[_key];
-        }
-  
-        return _this.callTasks({
-          module: moduleName,
-          method: methodName,
-          args: args
-        });
-      };
-    };
-  
-    for (var methodName in methods) {
-      _loop2(methodName);
-    }
-  
-    return target;
-  }
-  
-  /**
-   * @context Vm
-   */
-  function registerModules(modules, ifReplace) {
-    assignModules(modules, ifReplace);
-  }
-  
-  /**
-   * @context Vm
-   */
-  function registerMethods(apis) {
-    assignApis(this, apis);
-  }
-  
-  /**
-   * @context a instance of AppInstance
-   */
-  function requireComponent(name) {
-    var customComponentMap = this.customComponentMap;
-  
-    return customComponentMap[name];
-  }
-  
-  /**
-   * @context a instance of AppInstance
-   */
-  function registerComponent(name, exports) {
-    var customComponentMap = this.customComponentMap;
-  
-  
-    if (customComponentMap[name]) {
-      throw new Error('define a component(' + name + ') that already exists');
-    }
-  
-    customComponentMap[name] = exports;
-  }
-
-/***/ },
-/* 99 */
-/***/ function(module, exports, __webpack_require__) {
-
-  /* WEBPACK VAR INJECTION */(function(global) {'use strict';
-  
-  Object.defineProperty(exports, "__esModule", {
-    value: true
-  });
-  exports.normalizeVersion = normalizeVersion;
-  exports.getError = getError;
-  exports.check = check;
-  
-  var _semver = __webpack_require__(83);
-  
-  var _semver2 = _interopRequireDefault(_semver);
-  
-  var _util = __webpack_require__(81);
-  
-  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-  
-  /**
-   * [normalizeVersion description]
-   * @param  {String} Version. ie: 1, 1.0, 1.0.0
-   * @return {String} Version
-   */
-  function normalizeVersion(v) {
-    var isValid = _semver2.default.valid(v) ? true : false;
-    if (isValid) {
-      return v;
-    }
-  
-    v = typeof v === 'string' ? v : '';
-    var split = v.split('.');
-    var i = 0;
-    var result = [];
-  
-    while (i < 3) {
-      var s = typeof split[i] === 'string' && split[i] ? split[i] : '0';
-      result.push(s);
-      i++;
-    }
-  
-    return result.join('.');
-  }
-  
-  function getError(key, val, criteria) {
-    var result = {
-      isDowngrade: true,
-      errorType: 1,
-      code: 1000
-    };
-    var getMsg = function getMsg(key, val, criteria) {
-      return 'Downgrade[' + key + '] :: deviceInfo ' + val + ' matched criteria ' + criteria;
-    };
-    var _key = key.toLowerCase();
-  
-    result.errorMessage = getMsg(key, val, criteria);
-  
-    if (_key.indexOf('osversion') >= 0) {
-      result.code = 1001;
-    } else if (_key.indexOf('appversion') >= 0) {
-      result.code = 1002;
-    } else if (_key.indexOf('weexversion') >= 0) {
-      result.code = 1003;
-    } else if (_key.indexOf('devicemodel') >= 0) {
-      result.code = 1004;
-    }
-  
-    return result;
-  }
-  
-  /**
-   * WEEX framework input(deviceInfo)
-   * {
-   *   platform: 'iOS' or 'android'
-   *   osVersion: '1.0.0' or '1.0' or '1'
-   *   appVersion: '1.0.0' or '1.0' or '1'
-   *   weexVersion: '1.0.0' or '1.0' or '1'
-   *   dDeviceModel: 'MODEL_NAME'
-   * }
-   *
-   * downgrade config(config)
-   * {
-   *   ios: {
-   *     osVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
-   *     appVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
-   *     weexVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
-   *     deviceModel: ['modelA', 'modelB', ...]
-   *   },
-   *   android: {
-   *     osVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
-   *     appVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
-   *     weexVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
-   *     deviceModel: ['modelA', 'modelB', ...]
-   *   }
-   * }
-   *
-   *
-   * @param  {object} deviceInfo Weex SDK framework input
-   * @param  {object} config     user input
-   * @return {Object}            { isDowngrade: true/false, errorMessage... }
-   */
-  function check(config, deviceInfo) {
-    deviceInfo = deviceInfo || global.WXEnvironment;
-    deviceInfo = (0, _util.isPlainObject)(deviceInfo) ? deviceInfo : {};
-    config = (0, _util.isPlainObject)(config) ? config : {};
-    var platform = deviceInfo.platform || 'unknow';
-    var dPlatform = platform.toLowerCase();
-    var cObj = config[dPlatform] || {};
-  
-    var result = {
-      isDowngrade: false // defautl is pass
-    };
-  
-    for (var i in deviceInfo) {
-      var key = i;
-      var keyLower = key.toLowerCase();
-      var val = deviceInfo[i];
-      var isVersion = keyLower.indexOf('version') >= 0 ? true : false;
-      var isDeviceModel = keyLower.indexOf('devicemodel') >= 0 ? true : false;
-      var criteria = cObj[i];
-  
-      if (criteria && isVersion) {
-        var c = this.normalizeVersion(criteria);
-        var d = this.normalizeVersion(deviceInfo[i]);
-  
-        if (_semver2.default.satisfies(d, c)) {
-          result = (0, _util.extend)(this.getError(key, val, criteria));
-          break;
-        }
-      } else if (isDeviceModel) {
-        var _criteria = (0, _util.typof)(criteria) === 'array' ? criteria : [criteria];
-        if (_criteria.indexOf(val) >= 0) {
-          result = (0, _util.extend)(this.getError(key, val, criteria));
-          break;
-        }
-      }
-    }
-  
-    return result;
-  }
-  /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
-
-/***/ },
-/* 100 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  Object.defineProperty(exports, "__esModule", {
-    value: true
-  });
-  exports.init = init;
-  exports.destroy = destroy;
-  exports.getRootElement = getRootElement;
-  exports.updateActions = updateActions;
-  exports.fireEvent = fireEvent;
-  exports.callback = callback;
-  exports.refreshData = refreshData;
-  
-  var _util = __webpack_require__(81);
-  
-  var _perf = __webpack_require__(77);
-  
-  var perf = _interopRequireWildcard(_perf);
-  
-  var _domListener = __webpack_require__(101);
-  
-  var _domListener2 = _interopRequireDefault(_domListener);
-  
-  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-  
-  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
-  
-  function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } /**
-                                                                                                                                                                                                       * @fileOverview
-                                                                                                                                                                                                       * instance controls from native
-                                                                                                                                                                                                       *
-                                                                                                                                                                                                       * - init bundle
-                                                                                                                                                                                                       * - fire event
-                                                                                                                                                                                                       * - callback
-                                                                                                                                                                                                       * - destroy
-                                                                                                                                                                                                       *
-                                                                                                                                                                                                       * corresponded with the API of instance manager (framework.js)
-                                                                                                                                                                                                       */
-  
-  function init(code, data) {
-    var _this = this;
-  
-    var result;
-    // @see: lib/app/bundle.js
-    var define = (0, _util.bind)(this.define, this);
-    var bootstrap = function bootstrap(name, config, _data) {
-      result = _this.bootstrap(name, config, _data || data);
-      _this.doc.listener.createFinish();
-      _this.doc.close();
-    };
-  
-    // backward(register/render)
-    var register = (0, _util.bind)(this.register, this);
-    var render = function render(name, _data) {
-      result = _this.bootstrap(name, {}, _data);
-    };
-  
-    var require = function require(name) {
-      return function (_data) {
-        result = _this.bootstrap(name, {}, _data);
-      };
-    };
-  
-    var document = this.doc;
-  
-    perf.start('run bundle', this.id);
-  
-    var functionBody = void 0;
-    /* istanbul ignore if */
-    if (typeof code === 'function') {
-      // `function () {...}` -> `{...}`
-      // not very strict
-      functionBody = code.toString().substr(12);
-    } else if (code) {
-      functionBody = code.toString();
-    }
-  
-    var fn = new Function('define', 'require', 'document', 'bootstrap', 'register', 'render', '__weex_define__', // alias for define
-    '__weex_bootstrap__', // alias for bootstrap
-    functionBody);
-  
-    fn(define, require, document, bootstrap, register, render, define, bootstrap);
-  
-    perf.end('run bundle', this.id);
-    return result;
-  }
-  
-  function destroy() {
-    this.id = '';
-    this.eventManager = null;
-    this.options = null;
-    this.blocks = null;
-    this.vm = null;
-    this.doc = null;
-    this.customComponentMap = null;
-    this.callbacks = null;
-  }
-  
-  function getRootElement() {
-    var doc = this.doc || {};
-    var body = doc.body || {};
-    return body.toJSON ? body.toJSON() : {};
-  }
-  
-  function updateActions(addonTasks) {
-    this.differ.flush();
-    var tasks = [];
-    if (this.listener && this.listener.updates.length) {
-      tasks.push.apply(tasks, _toConsumableArray(this.listener.updates));
-      this.listener.updates = [];
-    }
-    if (addonTasks && addonTasks.length) {
-      tasks.push.apply(tasks, _toConsumableArray(addonTasks));
-    }
-    if (tasks.length) {
-      this.callTasks(tasks);
-    }
-  }
-  
-  function fireEvent(ref, type, e, domChanges) {
-    var _this2 = this;
-  
-    if (Array.isArray(ref)) {
-      ref.some(function (ref) {
-        return _this2.fireEvent(ref, type, e) !== false;
-      });
-      return;
-    }
-  
-    var el = this.doc.getRef(ref);
-  
-    if (el) {
-      perf.start('manage event', ref + '-' + type);
-      e = e || {};
-      e.type = type;
-      e.target = el;
-      e.timestamp = Date.now();
-      if (domChanges) {
-        updateElement(el, domChanges);
-      }
-      var result = this.eventManager.fire(el, type, e);
-      perf.end('manage event', ref + '-' + type);
-      this.updateActions();
-      return result;
-    }
-  
-    return new Error('invalid element reference "' + ref + '"');
-  }
-  
-  function callback(callbackId, data, ifKeepAlive) {
-    var callback = this.callbacks[callbackId];
-  
-    if (typeof callback === 'function') {
-      callback(data); // data is already a object, @see: lib/framework.js
-  
-      if (typeof ifKeepAlive === 'undefined' || ifKeepAlive === false) {
-        this.callbacks[callbackId] = undefined;
-      }
-  
-      this.updateActions();
-      return;
-    }
-  
-    return new Error('invalid callback id "' + callbackId + '"');
-  }
-  
-  function refreshData(data) {
-    var vm = this.vm;
-  
-    if (vm && data) {
-      if (typeof vm.refreshData === 'function') {
-        vm.refreshData(data);
-      } else {
-        (0, _util.extend)(vm, data);
-      }
-      this.updateActions([(0, _domListener.createAction)('refreshFinish', [])]);
-      return;
-    }
-  
-    return new Error('invalid data "' + data + '"');
-  }
-  
-  function updateElement(el, changes) {
-    var attrs = changes.attrs || {};
-    for (var name in attrs) {
-      el.setAttr(name, attrs);
-    }
-    var style = changes.style || {};
-    for (var _name in style) {
-      el.setStyle(_name, style[_name]);
-    }
-  }
-
-/***/ },
-/* 101 */
-/***/ function(module, exports) {
-
-  'use strict';
-  
-  Object.defineProperty(exports, "__esModule", {
-    value: true
-  });
-  exports.default = Listener;
-  exports.createAction = createAction;
-  function Listener(id, handler) {
-    this.id = id;
-    this.batched = false;
-    this.updates = [];
-    if (typeof handler === 'function') {
-      this.handler = handler;
-    }
-  }
-  
-  Listener.prototype.createFinish = function (callback) {
-    var handler = this.handler;
-    handler([createAction('createFinish', [])], callback);
-  };
-  
-  Listener.prototype.createBody = function (element, ref) {
-    var actions = [createAction('createBody', [element.toJSON()])];
-    this.addActions(actions);
-  };
-  
-  Listener.prototype.addElement = function (element, ref, index) {
-    if (!(index >= 0)) {
-      index = -1;
-    }
-    this.addActions(createAction('addElement', [ref, element.toJSON(), index]));
-  };
-  
-  Listener.prototype.removeElement = function (ref) {
-    if (Array.isArray(ref)) {
-      var actions = ref.map(function (r) {
-        return createAction('removeElement', [r]);
-      });
-      this.addActions(actions);
-    } else {
-      this.addActions(createAction('removeElement', [ref]));
-    }
-  };
-  
-  Listener.prototype.moveElement = function (targetRef, parentRef, index) {
-    this.addActions(createAction('moveElement', [targetRef, parentRef, index]));
-  };
-  
-  Listener.prototype.setAttr = function (ref, key, value) {
-    var result = {};
-    result[key] = value;
-    this.addActions(createAction('updateAttrs', [ref, result]));
-  };
-  
-  Listener.prototype.setStyle = function (ref, key, value) {
-    var result = {};
-    result[key] = value;
-    this.addActions(createAction('updateStyle', [ref, result]));
-  };
-  
-  Listener.prototype.setStyles = function (ref, style) {
-    this.addActions(createAction('updateStyle', [ref, style]));
-  };
-  
-  Listener.prototype.addEvent = function (ref, type) {
-    this.addActions(createAction('addEvent', [ref, type]));
-  };
-  
-  Listener.prototype.removeEvent = function (ref, type) {
-    this.addActions(createAction('removeEvent', [ref, type]));
-  };
-  
-  Listener.prototype.handler = function (actions, cb) {
-    cb && cb();
-  };
-  
-  Listener.prototype.addActions = function (actions) {
-    var updates = this.updates;
-    var handler = this.handler;
-  
-    if (!Array.isArray(actions)) {
-      actions = [actions];
-    }
-  
-    if (this.batched) {
-      updates.push.apply(updates, actions);
-    } else {
-      handler(actions);
-    }
-  };
-  
-  function createAction(name, args) {
-    return { module: 'dom', method: name, args: args };
-  }
-
-/***/ },
-/* 102 */
-/***/ function(module, exports) {
-
-  'use strict';
-  
-  Object.defineProperty(exports, "__esModule", {
-    value: true
-  });
-  
-  var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-  
-  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-  
-  var Differ = function () {
-    function Differ(id) {
-      _classCallCheck(this, Differ);
-  
-      this.id = id;
-      this.map = [];
-      this.hooks = [];
-    }
-  
-    _createClass(Differ, [{
-      key: 'isEmpty',
-      value: function isEmpty() {
-        return this.map.length === 0;
-      }
-    }, {
-      key: 'append',
-      value: function append(type, depth, ref, handler) {
-        var map = this.map;
-        if (!map[depth]) {
-          map[depth] = {};
-        }
-        var group = map[depth];
-        if (!group[type]) {
-          group[type] = {};
-        }
-        if (type === 'element') {
-          if (!group[type][ref]) {
-            group[type][ref] = [];
-          }
-          group[type][ref].push(handler);
-        } else {
-          group[type][ref] = handler;
-        }
-      }
-    }, {
-      key: 'flush',
-      value: function flush() {
-        var map = this.map.slice();
-        this.map.length = 0;
-        map.forEach(function (group) {
-          callTypeMap(group, 'repeat');
-          callTypeMap(group, 'shown');
-          callTypeList(group, 'element');
-        });
-  
-        var hooks = this.hooks.slice();
-        this.hooks.length = 0;
-        hooks.forEach(function (fn) {
-          fn();
-        });
-  
-        if (!this.isEmpty()) {
-          this.flush();
-        }
-      }
-    }, {
-      key: 'then',
-      value: function then(fn) {
-        this.hooks.push(fn);
-      }
-    }]);
-  
-    return Differ;
-  }();
-  
-  exports.default = Differ;
-  
-  
-  function callTypeMap(group, type) {
-    var map = group[type];
-    for (var ref in map) {
-      map[ref]();
-    }
-  }
-  
-  function callTypeList(group, type) {
-    var map = group[type];
-    for (var ref in map) {
-      var list = map[ref];
-      list.forEach(function (handler) {
-        handler();
-      });
-    }
-  }
-
-/***/ },
-/* 103 */
-/***/ function(module, exports, __webpack_require__) {
-
-  'use strict';
-  
-  Object.defineProperty(exports, "__esModule", {
-    value: true
-  });
-  
-  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; /**
-                                                                                                                                                                                                                                                     * @fileOverview event manager
-                                                                                                                                                                                                                                                     */
-  
-  exports.default = EventManager;
-  
-  var _util = __webpack_require__(81);
-  
-  var _ = _interopRequireWildcard(_util);
-  
-  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
-  
-  function EventManager() {
-    this.els = [];
-    this.targets = [];
-  }
-  
-  EventManager.prototype._get = function (el, force) {
-    var index = _.indexOf(this.els, el);
-    var target;
-    if (index >= 0) {
-      target = this.targets[index];
-    } else if (force) {
-      target = { el: el, events: {} };
-      this.els.push(el);
-      this.targets.push(target);
-    }
-    return target;
-  };
-  
-  EventManager.prototype.add = function (el, type, handler) {
-    if ((typeof el === 'undefined' ? 'undefined' : _typeof(el)) !== 'object' || !el || typeof type !== 'string' || !type || typeof handler !== 'function') {
-      return;
-    }
-    var target = this._get(el, true);
-    target.events[type] = handler;
-  };
-  
-  EventManager.prototype.remove = function (el, type) {
-    if ((typeof el === 'undefined' ? 'undefined' : _typeof(el)) !== 'object' || !el || typeof type !== 'string' || !type) {
-      return;
-    }
-    var target = this._get(el);
-    if (target) {
-      delete target.events[type];
-    }
-  };
-  
-  EventManager.prototype.fire = function (el, type, e) {
-    var target = this._get(el);
-    var handler, el;
-    if (target) {
-      el = target.el;
-      handler = target.events[type];
-      if (typeof handler === 'function') {
-        return handler.call(el, e);
-      }
-    }
-  };
-
-/***/ },
-/* 104 */
-/***/ function(module, exports) {
-
-  'use strict';
-  
-  Object.defineProperty(exports, "__esModule", {
-    value: true
-  });
-  exports.Document = Document;
-  exports.destroyDocument = destroyDocument;
-  exports.Node = Node;
-  exports.Element = Element;
-  exports.Comment = Comment;
-  /**
-   * @fileOverview
-   * A simple virtual dom implementation
-   */
-  
-  var DEFAULT_TAG_NAME = 'div';
-  
-  var instanceMap = exports.instanceMap = {};
-  
-  function Document(id) {
-    id = id ? id.toString() : '';
-    this.id = id;
-    this.nextRef = 1;
-    this.nodeMap = {};
-    this.listener = null;
-    this.eventManager = null;
-    this.closed = false;
-    instanceMap[id] = this;
-  
-    this.createDocumentElement();
-  }
-  
-  function destroyDocument(id) {
-    delete instanceMap[id];
-  }
-  
-  Document.prototype.open = function () {
-    this.closed = false;
-    if (this.listener) {
-      this.listener.batched = false;
-    }
-  };
-  Document.prototype.close = function () {
-    this.closed = true;
-    if (this.listener) {
-      this.listener.batched = true;
-    }
-  };
-  
-  Document.prototype.setEventManager = function (eventManager) {
-    this.eventManager = eventManager;
-  };
-  
-  Document.prototype.setListener = function (listener) {
-    this.listener = listener;
-    listener.batched = !!this.closed;
-  };
-  
-  Document.prototype.addRef = function (el) {
-    el.ref = this.nextRef.toString();
-    this.nodeMap[el.ref] = el;
-    this.nextRef++;
-  };
-  
-  Document.prototype.getRef = function (ref) {
-    return this.nodeMap[ref];
-  };
-  
-  Document.prototype.removeRef = function (ref) {
-    delete this.nodeMap[ref];
-  };
-  
-  Document.prototype.createDocumentElement = function (type, props) {
-    if (!this.documentElement) {
-      this.documentElement = new Element(type, props, this);
-      this.nodeMap._documentElement = this.documentElement;
-      this.documentElement.ref = '_documentElement';
-      this.documentElement.attached = true;
-    }
-  
-    return this.documentElement;
-  };
-  
-  Document.prototype.createBody = function (type, props) {
-    if (!this.body) {
-      this.body = new Element(type, props, this);
-      this.nodeMap._root = this.body;
-      this.body.ref = '_root';
-      this.body.depth = 1;
-    }
-  
-    return this.body;
-  };
-  
-  Document.prototype.createElement = function (tagName, props) {
-    return new Element(tagName, props, this);
-  };
-  
-  Document.prototype.createComment = function (text) {
-    return new Comment(text, this);
-  };
-  
-  function Node() {}
-  
-  Node.prototype.create = function (instanceId) {
-    this.parentRef = null;
-    this.attached = false;
-    if (instanceId) {
-      this.instanceId = instanceId;
-      var doc = instanceMap[instanceId];
-      doc.addRef(this);
-    }
-  };
-  
-  Node.prototype.destroy = function () {
-    var ref = this.ref;
-    var instanceId = this.instanceId;
-    if (instanceId) {
-      var doc = instanceMap[instanceId];
-      doc.removeRef(ref);
-    }
-  
-    var children = this.children || [];
-    var length = children.length;
-    for (var i = 0; i < length; i++) {
-      children[i].destroy();
-    }
-  };
-  
-  Node.prototype.getRenderer = function () {
-    var doc = instanceMap[this.instanceId];
-    return doc.listener;
-  };
-  
-  Node.prototype.next = function () {
-    var instanceId = this.instanceId;
-    var doc = instanceMap[instanceId];
-    var parent = doc.getRef(this.parentRef);
-    if (parent) {
-      return parent.children[parent.children.indexOf(this) + 1];
-    }
-  };
-  
-  Node.prototype.prev = function () {
-    var instanceId = this.instanceId;
-    var doc = instanceMap[instanceId];
-    var parent = doc.getRef(this.parentRef);
-    if (parent) {
-      return parent.children[parent.children.indexOf(this) - 1];
-    }
-  };
-  
-  function Element() {
-    var type = arguments.length <= 0 || arguments[0] === undefined ? DEFAULT_TAG_NAME : arguments[0];
-    var props = arguments[1];
-    var ownerDocument = arguments[2];
-  
-    props = props || {};
-    this.create(ownerDocument.id);
-    this.ownerDocument = ownerDocument;
-    this.type = type;
-    this.attr = props.attr || {};
-    this.classStyle = props.classStyle || {};
-    this.style = props.style || {};
-    this.event = [];
-    this.children = [];
-    this.pureChildren = [];
-  }
-  
-  Element.prototype = new Node();
-  
-  Element.prototype.appendChild = function (node) {
-  
-    removeIfExisted(node);
-    node.parentRef = this.ref;
-    this.children.push(node);
-  
-    if (this.attached) {
-      setAttached(node, this.depth);
-    } else {
-      setDetached(node);
-    }
-  
-    if (node instanceof Element) {
-      this.pureChildren.push(node);
-  
-      if (this.attached) {
-        var renderer = this.getRenderer();
-        if (renderer) {
-          if (this.ref === '_documentElement') {
-            // if its parent is documentElement then it's a body
-            renderer.createBody(node, this.ref);
-          } else {
-            renderer.addElement(node, this.ref);
-          }
-        }
-      }
-    }
-  };
-  
-  Element.prototype.insertBefore = function (node, before) {
-  
-    if (node.parentRef === this.ref) {
-      moveBefore(node, before, this.children);
-      if (node instanceof Element) {
-        var pureBeforeIndex = movePureBefore(node, before, this.pureChildren);
-        if (pureBeforeIndex >= 0 && this.attached) {
-          var renderer = this.getRenderer();
-          if (renderer) {
-            renderer.moveElement(node.ref, this.ref, pureBeforeIndex);
-          }
-        }
-      }
-      return;
-    }
-  
-    removeIfExisted(node);
-  
-    var children = this.children;
-    var index = children.indexOf(before);
-  
-    node.parentRef = this.ref;
-    if (this.attached) {
-      setAttached(node, this.depth);
-    } else {
-      setDetached(node);
-    }
-    children.splice(index, 0, node);
-  
-    if (node instanceof Element) {
-      var pureChildren = this.pureChildren;
-      var pureIndex = getPureAfter(before, pureChildren);
-  
-      pureChildren.splice(pureIndex, 0, node);
-  
-      if (this.attached) {
-        var _renderer = this.getRenderer();
-        if (_renderer) {
-          _renderer.addElement(node, this.ref, pureIndex);
-        }
-      }
-    }
-  };
-  
-  Element.prototype.insertAfter = function (node, after) {
-  
-    if (node.parentRef === this.ref) {
-      moveAfter(node, after, this.children);
-      if (node instanceof Element) {
-        var pureAfterIndex = movePureAfter(node, after, this.pureChildren);
-        if (pureAfterIndex >= 0 && this.attached) {
-          var renderer = this.getRenderer();
-          if (renderer) {
-            renderer.moveElement(node.ref, this.ref, pureAfterIndex);
-          }
-        }
-      }
-      return;
-    }
-  
-    removeIfExisted(node);
-  
-    var children = this.children;
-    var index = children.indexOf(after);
-  
-    node.parentRef = this.ref;
-    if (this.attached) {
-      setAttached(node, this.depth);
-    } else {
-      setDetached(node);
-    }
-    children.splice(index + 1, 0, node);
-  
-    if (node instanceof Element) {
-      var pureChildren = this.pureChildren;
-      var pureIndex = getPureBefore(after, pureChildren);
-  
-      pureChildren.splice(pureIndex + 1, 0, node);
-  
-      if (this.attached) {
-        var _renderer2 = this.getRenderer();
-        if (_renderer2) {
-          _renderer2.addElement(node, this.ref, pureIndex + 1);
-        }
-      }
-    }
-  };
-  
-  Element.prototype.removeChild = function (node, preserved) {
-    var children = this.children;
-    var index = children.indexOf(node);
-  
-    setDetached(node);
-  
-    if (index >= 0) {
-      node.parentRef = null;
-      children.splice(index, 1);
-      if (!preserved) {
-        node.destroy();
-      }
-    }
-  
-    if (node instanceof Element) {
-      this.pureChildren.$remove(node);
-      if (this.attached) {
-        var renderer = this.getRenderer();
-        if (renderer) {
-          renderer.removeElement(node.ref);
-        }
-      }
-    }
-  };
-  
-  Element.prototype.clear = function () {
-    var children = this.children;
-    var length = children.length;
-    for (var i = 0; i < length; i++) {
-      var child = children[i];
-      child.parentRef = null;
-      setDetached(child);
-      child.destroy();
-    }
-    children.length = 0;
-  
-    if (this.attached) {
-      var refs = this.pureChildren.map(function (child) {
-        return child.ref;
-      });
-      this.pureChildren.length = 0;
-      var renderer = this.getRenderer();
-      if (renderer) {
-        renderer.removeElement(refs);
-      }
-    }
-  };
-  
-  function moveBefore(node, before, children) {
-    var targetIndex = children.indexOf(node);
-    var beforeIndex = children.indexOf(before);
-  
-    /* istanbul ignore next */
-    if (targetIndex === beforeIndex || targetIndex + 1 === beforeIndex) {
-      return -1;
-    }
-  
-    var newIndex = targetIndex < beforeIndex ? beforeIndex - 1 : beforeIndex;
-    children.splice(targetIndex, 1);
-    children.splice(newIndex, 0, node);
-  
-    return beforeIndex;
-  }
-  
-  function movePureBefore(node, before, pureChildren) {
-    var pureTargetIndex = pureChildren.indexOf(node);
-    var pureBeforeIndex = getPureAfter(before, pureChildren);
-  
-    /* istanbul ignore next */
-    if (pureTargetIndex === pureBeforeIndex || pureTargetIndex + 1 === pureBeforeIndex) {
-      return -1;
-    }
-  
-    var pureNewIndex = pureTargetIndex < pureBeforeIndex ? pureBeforeIndex - 1 : pureBeforeIndex;
-  
-    pureChildren.splice(pureTargetIndex, 1);
-    pureChildren.splice(pureNewIndex, 0, node);
-  
-    return pureBeforeIndex;
-  }
-  
-  function getPureAfter(node, pureChildren) {
-    var pureIndex = pureChildren.indexOf(node);
-    while (node && pureIndex < 0) {
-      node = node.next();
-      pureIndex = pureChildren.indexOf(node);
-    }
-    if (pureIndex < 0) {
-      pureIndex = pureChildren.length;
-    }
-    return pureIndex;
-  }
-  
-  function moveAfter(node, after, children) {
-    var targetIndex = children.indexOf(node);
-    var afterIndex = children.indexOf(after);
-  
-    /* istanbul ignore next */
-    if (targetIndex === afterIndex || targetIndex === afterIndex + 1) {
-      return -1;
-    }
-  
-    var newIndex = targetIndex < afterIndex ? afterIndex : afterIndex + 1;
-    children.splice(targetIndex, 1);
-    children.splice(newIndex, 0, node);
-  
-    return afterIndex;
-  }
-  
-  function movePureAfter(node, after, pureChildren) {
-    var pureTargetIndex = pureChildren.indexOf(node);
-    var pureAfterIndex = getPureBefore(after, pureChildren);
-  
-    /* istanbul ignore next */
-    if (pureTargetIndex === pureAfterIndex || pureTargetIndex === pureAfterIndex + 1) {
-      return -1;
-    }
-  
-    var pureNewIndex = pureTargetIndex < pureAfterIndex ? pureAfterIndex : pureAfterIndex + 1;
-  
-    pureChildren.splice(pureTargetIndex, 1);
-    pureChildren.splice(pureNewIndex, 0, node);
-  
-    return pureAfterIndex + 1;
-  }
-  
-  function getPureBefore(node, pureChildren) {
-    var pureIndex = pureChildren.indexOf(node);
-    while (node && pureIndex < 0) {
-      node = node.prev();
-      pureIndex = pureChildren.indexOf(node);
-    }
-    /* istanbul ignore next */
-    if (pureIndex < 0) {
-      pureIndex = -1;
-    }
-    return pureIndex;
-  }
-  
-  function setAttached(node, depth) {
-    if (node.ref === '_root') {
-      depth = 1;
-    } else {
-      depth = depth > 0 ? depth + 1 : 0;
-    }
-    node.attached = true;
-    node.depth = depth;
-    if (node.children) {
-      node.children.forEach(function (sub) {
-        setAttached(sub, depth);
-      });
-    }
-  }
-  
-  function setDetached(node) {
-    node.attached = false;
-    node.depth = 0;
-    if (node.children) {
-      node.children.forEach(function (sub) {
-        setDetached(sub);
-      });
-    }
-  }
-  
-  function removeIfExisted(node) {
-    var doc = instanceMap[node.instanceId];
-    if (doc) {
-      var existedNode = doc.getRef(node.ref);
-      if (existedNode) {
-        var existedParent = doc.getRef(existedNode.parentRef);
-        if (existedParent && existedParent.removeChild) {
-          existedParent.removeChild(existedNode, true);
-        }
-      }
-    }
-  }
-  
-  Element.prototype.setAttr = function (key, value) {
-    if (this.attr[key] === value) {
-      return;
-    }
-    this.attr[key] = value;
-    if (this.attached) {
-      var renderer = this.getRenderer();
-      if (renderer) {
-        renderer.setAttr(this.ref, key, value);
-      }
-    }
-  };
-  
-  Element.prototype.setStyle = function (key, value) {
-    if (this.style[key] === value) {
-      return;
-    }
-    this.style[key] = value;
-    if (this.attached) {
-      var renderer = this.getRenderer();
-      if (renderer) {
-        renderer.setStyle(this.ref, key, value);
-      }
-    }
-  };
-  
-  Element.prototype.setClassStyle = function (classStyle) {
-    this.classStyle = classStyle;
-    if (this.attached) {
-      var renderer = this.getRenderer();
-      if (renderer) {
-        renderer.setStyles(this.ref, this.toStyle());
-      }
-    }
-  };
-  
-  Element.prototype.addEvent = function (type, handler) {
-    var index = this.event.indexOf(type);
-  
-    if (index < 0) {
-      this.event.push(type);
-      var eventManager = this.ownerDocument.eventManager;
-      eventManager.add(this, type, handler);
-  
-      if (this.attached) {
-        var renderer = this.getRenderer();
-        if (renderer) {
-          renderer.addEvent(this.ref, type);
-        }
-      }
-    }
-  };
-  
-  Element.prototype.removeEvent = function (type) {
-    var index = this.event.indexOf(type);
-  
-    if (index >= 0) {
-      this.event.splice(index, 1);
-      var eventManager = this.ownerDocument.eventManager;
-      eventManager.remove(this, type);
-  
-      if (this.attached) {
-        var renderer = this.getRenderer();
-        if (renderer) {
-          renderer.removeEvent(this.ref, type);
-        }
-      }
-    }
-  };
-  
-  Element.prototype.toStyle = function () {
-    var result = {};
-    var classStyle = this.classStyle;
-    var style = this.style;
-    for (var name in classStyle) {
-      result[name] = classStyle[name];
-    }
-    for (var _name in style) {
-      result[_name] = style[_name];
-    }
-    return result;
-  };
-  
-  Element.prototype.toJSON = function () {
-    var result = {
-      ref: this.ref.toString(),
-      type: this.type,
-      attr: this.attr,
-      style: this.toStyle()
-    };
-  
-    if (this.event && this.event.length) {
-      result.event = this.event;
-    }
-    if (this.pureChildren && this.pureChildren.length) {
-      result.children = this.pureChildren.map(function (child) {
-        return child.toJSON();
-      });
-    }
-  
-    return result;
-  };
-  
-  Element.prototype.toString = function () {
-    return '<' + this.type + ' attr=' + JSON.stringify(this.attr) + ' style=' + JSON.stringify(this.toStyle()) + '>' + this.pureChildren.map(function (child) {
-      return child.toString();
-    }).join('') + '</' + this.type + '>';
-  };
-  
-  function Comment(value, ownerDocument) {
-    this.create(ownerDocument.id);
-    this.type = 'comment';
-    this.value = value;
-  }
-  
-  Comment.prototype = new Node();
-  
-  Comment.prototype.toString = function () {
-    return '<!-- ' + this.value + ' -->';
-  };
-
-/***/ },
-/* 105 */
-/***/ function(module, exports) {
-
-  module.exports = {
-    "name": "weex-jsframework",
-    "version": "0.13.7",
-    "description": "JS Framework for Weex solution which is a extendable cross-platform solution for dynamic programming and publishing projects",
-    "main": "index.js",
-    "scripts": {
-      "dev": "webpack --watch --config ./webpack.config.js",
-      "build": "webpack --config ./webpack.config.js",
-      "compress": "uglifyjs dist/index.js -o dist/index.min.js",
-      "lint": "jscs --config .jscsrc polyfill/*.js polyfill/__test__/*.js lib/*.js lib/__test__/*.js lib/app/*.js lib/app/__test__/*.js lib/vm/*.js lib/vm/__test__/*.js",
-      "test": "mocha --compilers js:babel-core/register polyfill/__test__/*.js lib/__test__/*.js lib/**/__test__/*.js",
-      "cover": "babel-node node_modules/isparta/bin/isparta cover --report text node_modules/mocha/bin/_mocha -- --reporter dot lib/__test__/*.js lib/**/__test__/*.js",
-      "ci": "npm run lint && npm run cover"
-    },
-    "repository": {
-      "type": "git",
-      "url": "git@github.com:alibaba/weex.git"
-    },
-    "author": [
-      {
-        "name": "jinjiang",
-        "email": "zhaojinjiang@me.com"
-      },
-      {
-        "name": "Terry King",
-        "email": "terrykingcha@gmail.com"
-      }
-    ],
-    "contributors": [
-      {
-        "name": "pushiming",
-        "email": "pushiming@gmail.com"
-      },
-      {
-        "name": "iskenhuang",
-        "email": "iskenhuang@gmail.com"
-      },
-      {
-        "name": "yuanyan",
-        "email": "yuanyan.cao@gmail.com"
-      }
-    ],
-    "keywords": [
-      "weex",
-      "mvvm",
-      "browser",
-      "hybrid",
-      "framework"
-    ],
-    "license": "Apache-2.0",
-    "dependencies": {
-      "semver": "~5.1.0",
-      "core-js": "~2.1.1"
-    },
-    "devDependencies": {
-      "babel-cli": "~6.4.5",
-      "babel-core": "~6.4.5",
-      "babel-loader": "~6.2.1",
-      "babel-preset-es2015": "~6.3.13",
-      "chai": "~3.2.0",
-      "isparta": "~4.0.0",
-      "istanbul": "~0.4.2",
-      "jscs": "~2.9.0",
-      "json-loader": "^0.5.4",
-      "mocha": "~2.3.4",
-      "sinon": "~1.17.2",
-      "sinon-chai": "~2.8.0",
-      "uglify-js": "^2.6.2",
-      "watch-cli": "~0.2.1",
-      "webpack": "~1.12.12"
-    },
-    "optionalDependencies": {
-      "weex-transformer": "~0.3"
-    }
-  };
-
-/***/ },
-/* 106 */
-/***/ function(module, exports, __webpack_require__) {
-
-  /* WEBPACK VAR INJECTION */(function(global) {'use strict';
-  
-  Object.defineProperty(exports, "__esModule", {
-    value: true
-  });
-  exports.$ = $;
-  exports.$el = $el;
-  exports.$vm = $vm;
-  exports.$renderThen = $renderThen;
-  exports.$scrollTo = $scrollTo;
-  exports.$transition = $transition;
-  exports.$getConfig = $getConfig;
-  exports.$sendHttp = $sendHttp;
-  exports.$openURL = $openURL;
-  exports.$setTitle = $setTitle;
-  exports.$call = $call;
-  
-  var _util = __webpack_require__(81);
-  
-  /**
-   * ==========================================================
-   * common
-   * ==========================================================
-   */
-  
-  /**
-   * @deprecated use $vm instead
-   * find the vm by id
-   * Note: there is only one id in whole component
-   * @param  {string} id
-   * @return {Vm}
-   */
-  function $(id) {
-    nativeLog('[WARNING] the Vm#$ api is deprecated, please use Vm#$vm instead');
-    var info = this._ids[id];
-    if (info) {
-      return info.vm;
-    }
-  }
-  
-  /**
-   * find the element by id
-   * Note: there is only one id in whole component
-   * @param  {string} id
-   * @return {Element}
-   */
-  /**
-   * @fileOverview The api for invoking with "$" prefix
-   */
-  function $el(id) {
-    var info = this._ids[id];
-    if (info) {
-      return info.el;
-    }
-  }
-  
-  /**
-   * find the vm of the custom component by id
-   * Note: there is only one id in whole component
-   * @param  {string} id
-   * @return {Vm}
-   */
-  function $vm(id) {
-    var info = this._ids[id];
-    if (info) {
-      return info.vm;
-    }
-  }
-  
-  /**
-   * Fire when differ rendering finished
-   *
-   * @param  {Function} fn
-   */
-  function $renderThen(fn) {
-    var app = this._app;
-    var differ = app.differ;
-    return differ.then(function () {
-      fn();
-    });
-  }
-  
-  /**
-   * scroll an element specified by id into view, 
-   * moreover specify a number of offset optionally
-   * @param  {string} id
-   * @param  {number} offset
-   */
-  function $scrollTo(id, offset) {
-    var el = this.$el(id);
-    if (el) {
-      var dom = this._app.requireModule('dom');
-      dom.scrollToElement(el.ref, { offset: offset });
-    }
-  }
-  
-  /**
-   * perform transition animation on an element specified by id
-   * @param  {string}   id
-   * @param  {object}   options
-   * @param  {object}   options.styles
-   * @param  {object}   options.duration(ms)
-   * @param  {object}   [options.timingFunction]
-   * @param  {object}   [options.delay=0(ms)]
-   * @param  {Function} callback
-   */
-  function $transition(id, options, callback) {
-    var _this = this;
-  
-    var el = this.$el(id);
-    if (el && options && options.styles) {
-      var animation = this._app.requireModule('animation');
-      animation.transition(el.ref, options, function () {
-        _this._setStyle(el, options.styles);
-        callback && callback.apply(undefined, arguments);
-      });
-    }
-  }
-  
-  /**
-   * get some config
-   * @return {object} some config for app instance
-   * @property {string} bundleUrl
-   * @property {boolean} debug
-   * @property {object} env
-   * @property {string} env.weexVersion(ex. 1.0.0)
-   * @property {string} env.appName(ex. TB/TM)
-   * @property {string} env.appVersion(ex. 5.0.0)
-   * @property {string} env.platform(ex. iOS/Android)
-   * @property {string} env.osVersion(ex. 7.0.0)
-   * @property {string} env.deviceModel **native only**
-   * @property {number} env.[deviceWidth=750]
-   * @property {number} env.deviceHeight
-   */
-  function $getConfig(callback) {
-    var config = (0, _util.extend)({
-      env: global.WXEnvironment || {}
-    }, this._app.options);
-    if ((0, _util.typof)(callback) === 'function') {
-      nativeLog('[WARNING] the callback of Vm#$getConfig(callback) is deprecated, ' + 'this api now can directly RETURN config info.');
-      callback(config);
-    }
-    return config;
-  }
-  
-  /**
-   * request network via http protocol
-   * @param  {object}   params
-   * @param  {Function} callback
-   */
-  function $sendHttp(params, callback) {
-    var stream = this._app.requireModule('stream');
-    stream.sendHttp(params, callback);
-  }
-  
-  /**
-   * open a url
-   * @param  {string} url
-   */
-  function $openURL(url) {
-    var event = this._app.requireModule('event');
-    event.openURL(url);
-  }
-  
-  /**
-   * set a title for page
-   * @param  {string} title
-   */
-  function $setTitle(title) {
-    var pageInfo = this._app.requireModule('pageInfo');
-    pageInfo.setTitle(title);
-  }
-  
-  /**
-   * invoke a native method by specifing the name of module and method
-   * @param  {string} moduleName
-   * @param  {string} methodName
-   * @param  {...*} the rest arguments
-   */
-  function $call(moduleName, methodName) {
-    var module = this._app.requireModule(moduleName);
-    if (module && module[methodName]) {
-      for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
-        args[_key - 2] = arguments[_key];
-      }
-  
-      module[methodName].apply(module, args);
-    }
-  }
-  /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
-
-/***/ }
-/******/ ]);
-//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgNjNiODNkODQ3Zjc5MDZiZGY0YWIiLCJ3ZWJwYWNrOi8vLy4vaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vcG9seWZpbGwvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vcG9seWZpbGwvb2JqZWN0QXNzaWduLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9mbi9vYmplY3QvYXNzaWduLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuYXNzaWduLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX2dsb2JhbC5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9fY29yZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9faGlkZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWRwLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL19hbi1vYmplY3QuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX2lzLW9iamVjdC5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9faWU4LWRvbS1kZWZpbmUuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX2Rlc2NyaXB0b3JzLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL19mYWlscy5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9fZG9tLWNyZWF0ZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9fdG8tcHJpbWl0aXZlLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL19wcm9wZXJ0eS1kZXNjLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL19yZWRlZmluZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9faGFzLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL191aWQuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX2N0eC5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9fYS1mdW5jdGlvbi5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWFzc2lnbi5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWtleXMuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1rZXlzLWludGVybmFsLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL190by1pb2JqZWN0LmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL19pb2JqZWN0LmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL19jb2YuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX2RlZmluZWQuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX2FycmF5LWluY2x1ZGVzLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL190by1sZW5ndGguanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX3RvLWludGVnZXIuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX3RvLWluZGV4LmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL19zaGFyZWQta2V5LmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL19zaGFyZWQuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX2VudW0tYnVnLWtleXMuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1nb3BzLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL19vYmplY3QtcGllLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL190by1vYmplY3QuanMiLCJ3ZWJwYWNrOi8vLy4vcG9seWZpbGwvcHJvbWlzZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LnRvLXN0cmluZy5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9fY2xhc3NvZi5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9fd2tzLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuaXRlcmF0b3IuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy1hdC5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9faXRlci1kZWZpbmUuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX2xpYnJhcnkuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX2l0ZXJhdG9ycy5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9faXRlci1jcmVhdGUuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1jcmVhdGUuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1kcHMuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX2h0bWwuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX3NldC10by1zdHJpbmctdGFnLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ3BvLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL3dlYi5kb20uaXRlcmFibGUuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5Lml0ZXJhdG9yLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL19hZGQtdG8tdW5zY29wYWJsZXMuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX2l0ZXItc3RlcC5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9lczYucHJvbWlzZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9fYW4taW5zdGFuY2UuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX2Zvci1vZi5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9faXRlci1jYWxsLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL19pcy1hcnJheS1pdGVyLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL2NvcmUuZ2V0LWl0ZXJhdG9yLW1ldGhvZC5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9fc2V0LXByb3RvLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ29wZC5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9fc3BlY2llcy1jb25zdHJ1Y3Rvci5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9fdGFzay5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9faW52b2tlLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL19taWNyb3Rhc2suanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX3JlZGVmaW5lLWFsbC5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9fc2V0LXNwZWNpZXMuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX2l0ZXItZGV0ZWN0LmpzIiwid2VicGFjazovLy8uL3BvbHlmaWxsL3NldFRpbWVvdXQuanMiLCJ3ZWJwYWNrOi8vLy4vcG9seWZpbGwvY29uc29sZWxvZy5qcyIsIndlYnBhY2s6Ly8vLi9saWIvZnJhbWV3b3JrLmpzIiwid2VicGFjazovLy8uL2xpYi9wZXJmLmpzIiwid2VicGFjazovLy8uL2xpYi9sb2cuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL2NvbmZpZy5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYXBwL2luZGV4LmpzIiwid2VicGFjazovLy8uL2xpYi91dGlsL2luZGV4LmpzIiwid2VicGFjazovLy8uL2xpYi9hcHAvYnVuZGxlLmpzIiwid2VicGFjazovLy8uL34vc2VtdmVyL3NlbXZlci5qcyIsIndlYnBhY2s6Ly8vLi9+L3Byb2Nlc3MvYnJvd3Nlci5qcyIsIndlYnBhY2s6Ly8vLi9saWIvdm0vaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vbGliL3ZtL2luc3RhbmNlL3Njb3BlLmpzIiwid2VicGFjazovLy8uL2xpYi92bS91dGlsLmpzIiwid2VicGFjazovLy8uL2xpYi92bS9vYnNlcnZlci9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvdm0vY29uZmlnLmpzIiwid2VicGFjazovLy8uL2xpYi92bS9vYnNlcnZlci9kZXAuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL3ZtL29ic2VydmVyL2FycmF5LmpzIiwid2VicGFjazovLy8uL2xpYi92bS9vYnNlcnZlci9vYmplY3QuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL3ZtL2NvbXBpbGVyLmpzIiwid2VicGFjazovLy8uL2xpYi92bS9kaXJlY3RpdmUuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL3ZtL3dhdGNoZXIuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL3ZtL2RvbS1oZWxwZXIuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL3ZtL2V2ZW50cy5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYXBwL3JlZ2lzdGVyLmpzIiwid2VicGFjazovLy8uL2xpYi9hcHAvZG93bmdyYWRlLmpzIiwid2VicGFjazovLy8uL2xpYi9hcHAvY3RybC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYXBwL2RvbS1saXN0ZW5lci5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYXBwL2RpZmZlci5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYXBwL2V2ZW50LmpzIiwid2VicGFjazovLy8uL2xpYi9hcHAvZG9tLmpzIiwid2VicGFjazovLy8uL3BhY2thZ2UuanNvbiIsIndlYnBhY2s6Ly8vLi9saWIvYXBpL21ldGhvZHMuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx1QkFBZTtBQUNmO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOzs7Ozs7Ozs7QUN0Q0E7O0FBQ0E7O0tBQVksUzs7QUFDWjs7Ozs0QkFFUyxVO0FBQ0wsWUFBTyxVQUFQLElBQXFCLFlBQW1CO0FBQ3BDLGFBQU0sTUFBTSxVQUFVLFVBQVYsNkJBQVo7QUFDQSxhQUFJLGVBQWUsS0FBbkIsRUFBMEI7QUFDdEIscUJBQVEsS0FBUixDQUFjLElBQUksUUFBSixFQUFkO0FBQ0gsVUFGRCxNQUVPLElBQUksZUFBZSxLQUFuQixFQUEwQjtBQUM3QixpQkFBSSxPQUFKLENBQVksYUFBSztBQUNiLHFCQUFJLGFBQWEsS0FBakIsRUFBd0I7QUFDcEIsNkJBQVEsS0FBUixDQUFjLEVBQUUsUUFBRixFQUFkO0FBQ0g7QUFDSixjQUpEO0FBS0g7QUFDRCxnQkFBTyxHQUFQO0FBQ0gsTUFaRDs7O0FBREosTUFBSyxJQUFJLFVBQVQsSUFBdUIsU0FBdkIsRUFBa0M7QUFBQSxXQUF6QixVQUF5QjtBQWNqQzs7QUFFRCxRQUFPLE1BQVAsQ0FBYyxNQUFkLEVBQXNCO0FBQ2xCLHVDQURrQjtBQUVsQiw2QkFBd0IsOEJBQXFCLGtCQUFyQjtBQUZOLEVBQXRCOzs7OztBQVFBLEtBQU0sVUFBVSxvQkFBUSxHQUFSLENBQWhCO2VB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RVosS0FBSyxJQUFMLENBQVUsT0FGRSxDQUFmO0FBR0EsT0FBSSxpQkFBTSxRQUFOLE1BQW9CLFVBQXhCLEVBQW9DO0FBQ2xDLGVBQVUsc0VBQ1IsK0NBREY7QUFFQSxjQUFTLE1BQVQ7QUFDRDtBQUNELFVBQU8sTUFBUDtBQUNEOzs7Ozs7O0FBT00sVUFBUyxTQUFULENBQW1CLE1BQW5CLEVBQTJCLFFBQTNCLEVBQXFDO0FBQzFDLE9BQU0sU0FBUyxLQUFLLElBQUwsQ0FBVSxhQUFWLENBQXdCLFFBQXhCLENBQWY7QUFDQSxVQUFPLFFBQVAsQ0FBZ0IsTUFBaEIsRUFBd0IsUUFBeEI7QUFDRDs7Ozs7O0FBTU0sVUFBUyxRQUFULENBQWtCLEdBQWxCLEVBQXVCO0FBQzVCLE9BQU0sUUFBUSxLQUFLLElBQUwsQ0FBVSxhQUFWLENBQXdCLE9BQXhCLENBQWQ7QUFDQSxTQUFNLE9BQU4sQ0FBYyxHQUFkO0FBQ0Q7Ozs7OztBQU1NLFVBQVMsU0FBVCxDQUFtQixLQUFuQixFQUEwQjtBQUMvQixPQUFNLFdBQVcsS0FBSyxJQUFMLENBQVUsYUFBVixDQUF3QixVQUF4QixDQUFqQjtBQUNBLFlBQVMsUUFBVCxDQUFrQixLQUFsQjtBQUNEOzs7Ozs7OztBQVFNLFVBQVMsS0FBVCxDQUFlLFVBQWYsRUFBMkIsVUFBM0IsRUFBZ0Q7QUFDckQsT0FBTSxTQUFTLEtBQUssSUFBTCxDQUFVLGFBQVYsQ0FBd0IsVUFBeEIsQ0FBZjtBQUNBLE9BQUksVUFBVSxPQUFPLFVBQVAsQ0FBZCxFQUFrQztBQUFBLHVDQUZhLElBRWI7QUFGYSxXQUViO0FBQUE7O0FBQ2hDLFlBQU8sVUFBUCxnQkFBc0IsSUFBdEI7QUFDRDtBQUNGLEUiLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VzQ29udGVudCI6WyIgXHQvLyBUaGUgbW9kdWxlIGNhY2hlXG4gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuXG4gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXG4gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSlcbiBcdFx0XHRyZXR1cm4gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0uZXhwb3J0cztcblxuIFx0XHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuIFx0XHR2YXIgbW9kdWxlID0gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0gPSB7XG4gXHRcdFx0ZXhwb3J0czoge30sXG4gXHRcdFx0aWQ6IG1vZHVsZUlkLFxuIFx0XHRcdGxvYWRlZDogZmFsc2VcbiBcdFx0fTtcblxuIFx0XHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cbiBcdFx0bW9kdWxlc1ttb2R1bGVJZF0uY2FsbChtb2R1bGUuZXhwb3J0cywgbW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cbiBcdFx0Ly8gRmxhZyB0aGUgbW9kdWxlIGFzIGxvYWRlZFxuIFx0XHRtb2R1bGUubG9hZGVkID0gdHJ1ZTtcblxuIFx0XHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG4gXHR9XG5cblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBpbnN0YWxsZWRNb2R1bGVzO1xuXG4gXHQvLyBfX3dlYnBhY2tfcHVibGljX3BhdGhfX1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCJcIjtcblxuIFx0Ly8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzXG4gXHRyZXR1cm4gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIHdlYnBhY2svYm9vdHN0cmFwIDYzYjgzZDg0N2Y3OTA2YmRmNGFiXG4gKiovIiwiaW1wb3J0ICcuL3BvbHlmaWxsJ1xuaW1wb3J0ICogYXMgZnJhbWV3b3JrIGZyb20gJy4vbGliL2ZyYW1ld29yaydcbmltcG9ydCB7dmVyc2lvbiwgb3B0aW9uYWxEZXBlbmRlbmNpZXN9IGZyb20gJy4vcGFja2FnZS5qc29uJ1xuXG5mb3IgKGxldCBtZXRob2ROYW1lIGluIGZyYW1ld29yaykge1xuICAgIGdsb2JhbFttZXRob2ROYW1lXSA9IGZ1bmN0aW9uICguLi5hcmdzKSB7XG4gICAgICAgIGNvbnN0IHJldCA9IGZyYW1ld29ya1ttZXRob2ROYW1lXSguLi5hcmdzKVxuICAgICAgICBpZiAocmV0IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IocmV0LnRvU3RyaW5nKCkpXG4gICAgICAgIH0gZWxzZSBpZiAocmV0IGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgICAgICAgIHJldC5mb3JFYWNoKHIgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChyIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihyLnRvU3RyaW5nKCkpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmV0XG4gICAgfVxufVxuXG5PYmplY3QuYXNzaWduKGdsb2JhbCwge1xuICAgIGZyYW1ld29ya1ZlcnNpb246IHZlcnNpb24sXG4gICAgbmVlZFRyYW5zZm9ybWVyVmVyc2lvbjogb3B0aW9uYWxEZXBlbmRlbmNpZXNbJ3dlZXgtdHJhbnNmb3JtZXInXVxufSlcblxuLyoqXG4gKiByZWdpc3RlciBtZXRob2RzXG4gKi9cbmNvbnN0IG1ldGhvZHMgPSByZXF1aXJlKCcuL2xpYi9hcGkvbWV0aG9kcycpXG5jb25zdCB7cmVnaXN0ZXJNZXRob2RzfSA9IGdsb2JhbFxucmVnaXN0ZXJNZXRob2RzKG1ldGhvZHMpXG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL2luZGV4LmpzXG4gKiovIiwiaW1wb3J0ICcuL29iamVjdEFzc2lnbidcbmltcG9ydCAnLi9wcm9taXNlJ1xuaW1wb3J0ICcuL3NldFRpbWVvdXQnXG5pbXBvcnQgJy4vY29uc29sZWxvZydcblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vcG9seWZpbGwvaW5kZXguanNcbiAqKi8iLCJpbXBvcnQgJ2NvcmUtanMvZm4vb2JqZWN0L2Fzc2lnbidcblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vcG9seWZpbGwvb2JqZWN0QXNzaWduLmpzXG4gKiovIiwicmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9lczYub2JqZWN0LmFzc2lnbicpO1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuLi8uLi9tb2R1bGVzL19jb3JlJykuT2JqZWN0LmFzc2lnbjtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9mbi9vYmplY3QvYXNzaWduLmpzXG4gKiovIiwiLy8gMTkuMS4zLjEgT2JqZWN0LmFzc2lnbih0YXJnZXQsIHNvdXJjZSlcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GLCAnT2JqZWN0Jywge2Fzc2lnbjogcmVxdWlyZSgnLi9fb2JqZWN0LWFzc2lnbicpfSk7XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmFzc2lnbi5qc1xuICoqLyIsInZhciBnbG9iYWwgICAgPSByZXF1aXJlKCcuL19nbG9iYWwnKVxuICAsIGNvcmUgICAgICA9IHJlcXVpcmUoJy4vX2NvcmUnKVxuICAsIGhpZGUgICAgICA9IHJlcXVpcmUoJy4vX2hpZGUnKVxuICAsIHJlZGVmaW5lICA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lJylcbiAgLCBjdHggICAgICAgPSByZXF1aXJlKCcuL19jdHgnKVxuICAsIFBST1RPVFlQRSA9ICdwcm90b3R5cGUnO1xuXG52YXIgJGV4cG9ydCA9IGZ1bmN0aW9uKHR5cGUsIG5hbWUsIHNvdXJjZSl7XG4gIHZhciBJU19GT1JDRUQgPSB0eXBlICYgJGV4cG9ydC5GXG4gICAgLCBJU19HTE9CQUwgPSB0eXBlICYgJGV4cG9ydC5HXG4gICAgLCBJU19TVEFUSUMgPSB0eXBlICYgJGV4cG9ydC5TXG4gICAgLCBJU19QUk9UTyAgPSB0eXBlICYgJGV4cG9ydC5QXG4gICAgLCBJU19CSU5EICAgPSB0eXBlICYgJGV4cG9ydC5CXG4gICAgLCB0YXJnZXQgICAgPSBJU19HTE9CQUwgPyBnbG9iYWwgOiBJU19TVEFUSUMgPyBnbG9iYWxbbmFtZV0gfHwgKGdsb2JhbFtuYW1lXSA9IHt9KSA6IChnbG9iYWxbbmFtZV0gfHwge30pW1BST1RPVFlQRV1cbiAgICAsIGV4cG9ydHMgICA9IElTX0dMT0JBTCA/IGNvcmUgOiBjb3JlW25hbWVdIHx8IChjb3JlW25hbWVdID0ge30pXG4gICAgLCBleHBQcm90byAgPSBleHBvcnRzW1BST1RPVFlQRV0gfHwgKGV4cG9ydHNbUFJPVE9UWVBFXSA9IHt9KVxuICAgICwga2V5LCBvd24sIG91dCwgZXhwO1xuICBpZihJU19HTE9CQUwpc291cmNlID0gbmFtZTtcbiAgZm9yKGtleSBpbiBzb3VyY2Upe1xuICAgIC8vIGNvbnRhaW5zIGluIG5hdGl2ZVxuICAgIG93biA9ICFJU19GT1JDRUQgJiYgdGFyZ2V0ICYmIHRhcmdldFtrZXldICE9PSB1bmRlZmluZWQ7XG4gICAgLy8gZXhwb3J0IG5hdGl2ZSBvciBwYXNzZWRcbiAgICBvdXQgPSAob3duID8gdGFyZ2V0IDogc291cmNlKVtrZXldO1xuICAgIC8vIGJpbmQgdGltZXJzIHRvIGdsb2JhbCBmb3IgY2FsbCBmcm9tIGV4cG9ydCBjb250ZXh0XG4gICAgZXhwID0gSVNfQklORCAmJiBvd24gPyBjdHgob3V0LCBnbG9iYWwpIDogSVNfUFJPVE8gJiYgdHlwZW9mIG91dCA9PSAnZnVuY3Rpb24nID8gY3R4KEZ1bmN0aW9uLmNhbGwsIG91dCkgOiBvdXQ7XG4gICAgLy8gZXh0ZW5kIGdsb2JhbFxuICAgIGlmKHRhcmdldClyZWRlZmluZSh0YXJnZXQsIGtleSwgb3V0LCB0eXBlICYgJGV4cG9ydC5VKTtcbiAgICAvLyBleHBvcnRcbiAgICBpZihleHBvcnRzW2tleV0gIT0gb3V0KWhpZGUoZXhwb3J0cywga2V5LCBleHApO1xuICAgIGlmKElTX1BST1RPICYmIGV4cFByb3RvW2tleV0gIT0gb3V0KWV4cFByb3RvW2tleV0gPSBvdXQ7XG4gIH1cbn07XG5nbG9iYWwuY29yZSA9IGNvcmU7XG4vLyB0eXBlIGJpdG1hcFxuJGV4cG9ydC5GID0gMTsgICAvLyBmb3JjZWRcbiRleHBvcnQuRyA9IDI7ICAgLy8gZ2xvYmFsXG4kZXhwb3J0LlMgPSA0OyAgIC8vIHN0YXRpY1xuJGV4cG9ydC5QID0gODsgICAvLyBwcm90b1xuJGV4cG9ydC5CID0gMTY7ICAvLyBiaW5kXG4kZXhwb3J0LlcgPSAzMjsgIC8vIHdyYXBcbiRleHBvcnQuVSA9IDY0OyAgLy8gc2FmZVxuJGV4cG9ydC5SID0gMTI4OyAvLyByZWFsIHByb3RvIG1ldGhvZCBmb3IgYGxpYnJhcnlgIFxubW9kdWxlLmV4cG9ydHMgPSAkZXhwb3J0O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX2V4cG9ydC5qc1xuICoqLyIsIi8vIGh0dHBzOi8vZ2l0aHViLmNvbS96bG9pcm9jay9jb3JlLWpzL2lzc3Vlcy84NiNpc3N1ZWNvbW1lbnQtMTE1NzU5MDI4XG52YXIgZ2xvYmFsID0gbW9kdWxlLmV4cG9ydHMgPSB0eXBlb2Ygd2luZG93ICE9ICd1bmRlZmluZWQnICYmIHdpbmRvdy5NYXRoID09IE1hdGhcbiAgPyB3aW5kb3cgOiB0eXBlb2Ygc2VsZiAhPSAndW5kZWZpbmVkJyAmJiBzZWxmLk1hdGggPT0gTWF0aCA/IHNlbGYgOiBGdW5jdGlvbigncmV0dXJuIHRoaXMnKSgpO1xuaWYodHlwZW9mIF9fZyA9PSAnbnVtYmVyJylfX2cgPSBnbG9iYWw7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW5kZWZcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19nbG9iYWwuanNcbiAqKi8iLCJ2YXIgY29yZSA9IG1vZHVsZS5leHBvcnRzID0ge3ZlcnNpb246ICcyLjEuNSd9O1xuaWYodHlwZW9mIF9fZSA9PSAnbnVtYmVyJylfX2UgPSBjb3JlOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVuZGVmXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9fY29yZS5qc1xuICoqLyIsInZhciBkUCAgICAgICAgID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJylcbiAgLCBjcmVhdGVEZXNjID0gcmVxdWlyZSgnLi9fcHJvcGVydHktZGVzYycpO1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpID8gZnVuY3Rpb24ob2JqZWN0LCBrZXksIHZhbHVlKXtcbiAgcmV0dXJuIGRQLmYob2JqZWN0LCBrZXksIGNyZWF0ZURlc2MoMSwgdmFsdWUpKTtcbn0gOiBmdW5jdGlvbihvYmplY3QsIGtleSwgdmFsdWUpe1xuICBvYmplY3Rba2V5XSA9IHZhbHVlO1xuICByZXR1cm4gb2JqZWN0O1xufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19oaWRlLmpzXG4gKiovIiwidmFyIGFuT2JqZWN0ICAgICAgID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0JylcbiAgLCBJRThfRE9NX0RFRklORSA9IHJlcXVpcmUoJy4vX2llOC1kb20tZGVmaW5lJylcbiAgLCB0b1ByaW1pdGl2ZSAgICA9IHJlcXVpcmUoJy4vX3RvLXByaW1pdGl2ZScpXG4gICwgZFAgICAgICAgICAgICAgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7XG5cbmV4cG9ydHMuZiA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJykgPyBPYmplY3QuZGVmaW5lUHJvcGVydHkgOiBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0eShPLCBQLCBBdHRyaWJ1dGVzKXtcbiAgYW5PYmplY3QoTyk7XG4gIFAgPSB0b1ByaW1pdGl2ZShQLCB0cnVlKTtcbiAgYW5PYmplY3QoQXR0cmlidXRlcyk7XG4gIGlmKElFOF9ET01fREVGSU5FKXRyeSB7XG4gICAgcmV0dXJuIGRQKE8sIFAsIEF0dHJpYnV0ZXMpO1xuICB9IGNhdGNoKGUpeyAvKiBlbXB0eSAqLyB9XG4gIGlmKCdnZXQnIGluIEF0dHJpYnV0ZXMgfHwgJ3NldCcgaW4gQXR0cmlidXRlcyl0aHJvdyBUeXBlRXJyb3IoJ0FjY2Vzc29ycyBub3Qgc3VwcG9ydGVkIScpO1xuICBpZigndmFsdWUnIGluIEF0dHJpYnV0ZXMpT1tQXSA9IEF0dHJpYnV0ZXMudmFsdWU7XG4gIHJldHVybiBPO1xufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZHAuanNcbiAqKi8iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQpe1xuICBpZighaXNPYmplY3QoaXQpKXRocm93IFR5cGVFcnJvcihpdCArICcgaXMgbm90IGFuIG9iamVjdCEnKTtcbiAgcmV0dXJuIGl0O1xufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19hbi1vYmplY3QuanNcbiAqKi8iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcbiAgcmV0dXJuIHR5cGVvZiBpdCA9PT0gJ29iamVjdCcgPyBpdCAhPT0gbnVsbCA6IHR5cGVvZiBpdCA9PT0gJ2Z1bmN0aW9uJztcbn07XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9faXMtb2JqZWN0LmpzXG4gKiovIiwibW9kdWxlLmV4cG9ydHMgPSAhcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSAmJiAhcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbigpe1xyXG4gIHJldHVybiBPYmplY3QuZGVmaW5lUHJvcGVydHkocmVxdWlyZSgnLi9fZG9tLWNyZWF0ZScpKCdkaXYnKSwgJ2EnLCB7Z2V0OiBmdW5jdGlvbigpeyByZXR1cm4gNzsgfX0pLmEgIT0gNztcclxufSk7XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9faWU4LWRvbS1kZWZpbmUuanNcbiAqKi8iLCIvLyBUaGFuaydzIElFOCBmb3IgaGlzIGZ1bm55IGRlZmluZVByb3BlcnR5XG5tb2R1bGUuZXhwb3J0cyA9ICFyZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uKCl7XG4gIHJldHVybiBPYmplY3QuZGVmaW5lUHJvcGVydHkoe30sICdhJywge2dldDogZnVuY3Rpb24oKXsgcmV0dXJuIDc7IH19KS5hICE9IDc7XG59KTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19kZXNjcmlwdG9ycy5qc1xuICoqLyIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZXhlYyl7XG4gIHRyeSB7XG4gICAgcmV0dXJuICEhZXhlYygpO1xuICB9IGNhdGNoKGUpe1xuICAgIHJldHVybiB0cnVlO1xuICB9XG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX2ZhaWxzLmpzXG4gKiovIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0JylcbiAgLCBkb2N1bWVudCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpLmRvY3VtZW50XG4gIC8vIGluIG9sZCBJRSB0eXBlb2YgZG9jdW1lbnQuY3JlYXRlRWxlbWVudCBpcyAnb2JqZWN0J1xuICAsIGlzID0gaXNPYmplY3QoZG9jdW1lbnQpICYmIGlzT2JqZWN0KGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCl7XG4gIHJldHVybiBpcyA/IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoaXQpIDoge307XG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX2RvbS1jcmVhdGUuanNcbiAqKi8iLCIvLyA3LjEuMSBUb1ByaW1pdGl2ZShpbnB1dCBbLCBQcmVmZXJyZWRUeXBlXSlcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xuLy8gaW5zdGVhZCBvZiB0aGUgRVM2IHNwZWMgdmVyc2lvbiwgd2UgZGlkbid0IGltcGxlbWVudCBAQHRvUHJpbWl0aXZlIGNhc2Vcbi8vIGFuZCB0aGUgc2Vjb25kIGFyZ3VtZW50IC0gZmxhZyAtIHByZWZlcnJlZCB0eXBlIGlzIGEgc3RyaW5nXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0LCBTKXtcbiAgaWYoIWlzT2JqZWN0KGl0KSlyZXR1cm4gaXQ7XG4gIHZhciBmbiwgdmFsO1xuICBpZihTICYmIHR5cGVvZiAoZm4gPSBpdC50b1N0cmluZykgPT0gJ2Z1bmN0aW9uJyAmJiAhaXNPYmplY3QodmFsID0gZm4uY2FsbChpdCkpKXJldHVybiB2YWw7XG4gIGlmKHR5cGVvZiAoZm4gPSBpdC52YWx1ZU9mKSA9PSAnZnVuY3Rpb24nICYmICFpc09iamVjdCh2YWwgPSBmbi5jYWxsKGl0KSkpcmV0dXJuIHZhbDtcbiAgaWYoIVMgJiYgdHlwZW9mIChmbiA9IGl0LnRvU3RyaW5nKSA9PSAnZnVuY3Rpb24nICYmICFpc09iamVjdCh2YWwgPSBmbi5jYWxsKGl0KSkpcmV0dXJuIHZhbDtcbiAgdGhyb3cgVHlwZUVycm9yKFwiQ2FuJ3QgY29udmVydCBvYmplY3QgdG8gcHJpbWl0aXZlIHZhbHVlXCIpO1xufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL190by1wcmltaXRpdmUuanNcbiAqKi8iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGJpdG1hcCwgdmFsdWUpe1xuICByZXR1cm4ge1xuICAgIGVudW1lcmFibGUgIDogIShiaXRtYXAgJiAxKSxcbiAgICBjb25maWd1cmFibGU6ICEoYml0bWFwICYgMiksXG4gICAgd3JpdGFibGUgICAgOiAhKGJpdG1hcCAmIDQpLFxuICAgIHZhbHVlICAgICAgIDogdmFsdWVcbiAgfTtcbn07XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9fcHJvcGVydHktZGVzYy5qc1xuICoqLyIsInZhciBnbG9iYWwgICAgPSByZXF1aXJlKCcuL19nbG9iYWwnKVxuICAsIGhpZGUgICAgICA9IHJlcXVpcmUoJy4vX2hpZGUnKVxuICAsIGhhcyAgICAgICA9IHJlcXVpcmUoJy4vX2hhcycpXG4gICwgU1JDICAgICAgID0gcmVxdWlyZSgnLi9fdWlkJykoJ3NyYycpXG4gICwgVE9fU1RSSU5HID0gJ3RvU3RyaW5nJ1xuICAsICR0b1N0cmluZyA9IEZ1bmN0aW9uW1RPX1NUUklOR11cbiAgLCBUUEwgICAgICAgPSAoJycgKyAkdG9TdHJpbmcpLnNwbGl0KFRPX1NUUklORyk7XG5cbnJlcXVpcmUoJy4vX2NvcmUnKS5pbnNwZWN0U291cmNlID0gZnVuY3Rpb24oaXQpe1xuICByZXR1cm4gJHRvU3RyaW5nLmNhbGwoaXQpO1xufTtcblxuKG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oTywga2V5LCB2YWwsIHNhZmUpe1xuICB2YXIgaXNGdW5jdGlvbiA9IHR5cGVvZiB2YWwgPT0gJ2Z1bmN0aW9uJztcbiAgaWYoaXNGdW5jdGlvbiloYXModmFsLCAnbmFtZScpIHx8IGhpZGUodmFsLCAnbmFtZScsIGtleSk7XG4gIGlmKE9ba2V5XSA9PT0gdmFsKXJldHVybjtcbiAgaWYoaXNGdW5jdGlvbiloYXModmFsLCBTUkMpIHx8IGhpZGUodmFsLCBTUkMsIE9ba2V5XSA/ICcnICsgT1trZXldIDogVFBMLmpvaW4oU3RyaW5nKGtleSkpKTtcbiAgaWYoTyA9PT0gZ2xvYmFsKXtcbiAgICBPW2tleV0gPSB2YWw7XG4gIH0gZWxzZSB7XG4gICAgaWYoIXNhZmUpe1xuICAgICAgZGVsZXRlIE9ba2V5XTtcbiAgICAgIGhpZGUoTywga2V5LCB2YWwpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZihPW2tleV0pT1trZXldID0gdmFsO1xuICAgICAgZWxzZSBoaWRlKE8sIGtleSwgdmFsKTtcbiAgICB9XG4gIH1cbi8vIGFkZCBmYWtlIEZ1bmN0aW9uI3RvU3RyaW5nIGZvciBjb3JyZWN0IHdvcmsgd3JhcHBlZCBtZXRob2RzIC8gY29uc3RydWN0b3JzIHdpdGggbWV0aG9kcyBsaWtlIExvRGFzaCBpc05hdGl2ZVxufSkoRnVuY3Rpb24ucHJvdG90eXBlLCBUT19TVFJJTkcsIGZ1bmN0aW9uIHRvU3RyaW5nKCl7XG4gIHJldHVybiB0eXBlb2YgdGhpcyA9PSAnZnVuY3Rpb24nICYmIHRoaXNbU1JDXSB8fCAkdG9TdHJpbmcuY2FsbCh0aGlzKTtcbn0pO1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX3JlZGVmaW5lLmpzXG4gKiovIiwidmFyIGhhc093blByb3BlcnR5ID0ge30uaGFzT3duUHJvcGVydHk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0LCBrZXkpe1xuICByZXR1cm4gaGFzT3duUHJvcGVydHkuY2FsbChpdCwga2V5KTtcbn07XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9faGFzLmpzXG4gKiovIiwidmFyIGlkID0gMFxuICAsIHB4ID0gTWF0aC5yYW5kb20oKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oa2V5KXtcbiAgcmV0dXJuICdTeW1ib2woJy5jb25jYXQoa2V5ID09PSB1bmRlZmluZWQgPyAnJyA6IGtleSwgJylfJywgKCsraWQgKyBweCkudG9TdHJpbmcoMzYpKTtcbn07XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9fdWlkLmpzXG4gKiovIiwiLy8gb3B0aW9uYWwgLyBzaW1wbGUgY29udGV4dCBiaW5kaW5nXG52YXIgYUZ1bmN0aW9uID0gcmVxdWlyZSgnLi9fYS1mdW5jdGlvbicpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmbiwgdGhhdCwgbGVuZ3RoKXtcbiAgYUZ1bmN0aW9uKGZuKTtcbiAgaWYodGhhdCA9PT0gdW5kZWZpbmVkKXJldHVybiBmbjtcbiAgc3dpdGNoKGxlbmd0aCl7XG4gICAgY2FzZSAxOiByZXR1cm4gZnVuY3Rpb24oYSl7XG4gICAgICByZXR1cm4gZm4uY2FsbCh0aGF0LCBhKTtcbiAgICB9O1xuICAgIGNhc2UgMjogcmV0dXJuIGZ1bmN0aW9uKGEsIGIpe1xuICAgICAgcmV0dXJuIGZuLmNhbGwodGhhdCwgYSwgYik7XG4gICAgfTtcbiAgICBjYXNlIDM6IHJldHVybiBmdW5jdGlvbihhLCBiLCBjKXtcbiAgICAgIHJldHVybiBmbi5jYWxsKHRoYXQsIGEsIGIsIGMpO1xuICAgIH07XG4gIH1cbiAgcmV0dXJuIGZ1bmN0aW9uKC8qIC4uLmFyZ3MgKi8pe1xuICAgIHJldHVybiBmbi5hcHBseSh0aGF0LCBhcmd1bWVudHMpO1xuICB9O1xufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19jdHguanNcbiAqKi8iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcbiAgaWYodHlwZW9mIGl0ICE9ICdmdW5jdGlvbicpdGhyb3cgVHlwZUVycm9yKGl0ICsgJyBpcyBub3QgYSBmdW5jdGlvbiEnKTtcbiAgcmV0dXJuIGl0O1xufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19hLWZ1bmN0aW9uLmpzXG4gKiovIiwiJ3VzZSBzdHJpY3QnO1xuLy8gMTkuMS4yLjEgT2JqZWN0LmFzc2lnbih0YXJnZXQsIHNvdXJjZSwgLi4uKVxudmFyIGdldEtleXMgID0gcmVxdWlyZSgnLi9fb2JqZWN0LWtleXMnKVxuICAsIGdPUFMgICAgID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcHMnKVxuICAsIHBJRSAgICAgID0gcmVxdWlyZSgnLi9fb2JqZWN0LXBpZScpXG4gICwgdG9PYmplY3QgPSByZXF1aXJlKCcuL190by1vYmplY3QnKVxuICAsIElPYmplY3QgID0gcmVxdWlyZSgnLi9faW9iamVjdCcpXG4gICwgJGFzc2lnbiAgPSBPYmplY3QuYXNzaWduO1xuXG4vLyBzaG91bGQgd29yayB3aXRoIHN5bWJvbHMgYW5kIHNob3VsZCBoYXZlIGRldGVybWluaXN0aWMgcHJvcGVydHkgb3JkZXIgKFY4IGJ1Zylcbm1vZHVsZS5leHBvcnRzID0gISRhc3NpZ24gfHwgcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbigpe1xuICB2YXIgQSA9IHt9XG4gICAgLCBCID0ge31cbiAgICAsIFMgPSBTeW1ib2woKVxuICAgICwgSyA9ICdhYmNkZWZnaGlqa2xtbm9wcXJzdCc7XG4gIEFbU10gPSA3O1xuICBLLnNwbGl0KCcnKS5mb3JFYWNoKGZ1bmN0aW9uKGspeyBCW2tdID0gazsgfSk7XG4gIHJldHVybiAkYXNzaWduKHt9LCBBKVtTXSAhPSA3IHx8IE9iamVjdC5rZXlzKCRhc3NpZ24oe30sIEIpKS5qb2luKCcnKSAhPSBLO1xufSkgPyBmdW5jdGlvbiBhc3NpZ24odGFyZ2V0LCBzb3VyY2UpeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXG4gIHZhciBUICAgICA9IHRvT2JqZWN0KHRhcmdldClcbiAgICAsIGFMZW4gID0gYXJndW1lbnRzLmxlbmd0aFxuICAgICwgaW5kZXggPSAxXG4gICAgLCBnZXRTeW1ib2xzID0gZ09QUy5mXG4gICAgLCBpc0VudW0gICAgID0gcElFLmY7XG4gIHdoaWxlKGFMZW4gPiBpbmRleCl7XG4gICAgdmFyIFMgICAgICA9IElPYmplY3QoYXJndW1lbnRzW2luZGV4KytdKVxuICAgICAgLCBrZXlzICAgPSBnZXRTeW1ib2xzID8gZ2V0S2V5cyhTKS5jb25jYXQoZ2V0U3ltYm9scyhTKSkgOiBnZXRLZXlzKFMpXG4gICAgICAsIGxlbmd0aCA9IGtleXMubGVuZ3RoXG4gICAgICAsIGogICAgICA9IDBcbiAgICAgICwga2V5O1xuICAgIHdoaWxlKGxlbmd0aCA+IGopaWYoaXNFbnVtLmNhbGwoUywga2V5ID0ga2V5c1tqKytdKSlUW2tleV0gPSBTW2tleV07XG4gIH0gcmV0dXJuIFQ7XG59IDogJGFzc2lnbjtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19vYmplY3QtYXNzaWduLmpzXG4gKiovIiwiLy8gMTkuMS4yLjE0IC8gMTUuMi4zLjE0IE9iamVjdC5rZXlzKE8pXHJcbnZhciAka2V5cyAgICAgICA9IHJlcXVpcmUoJy4vX29iamVjdC1rZXlzLWludGVybmFsJylcclxuICAsIGVudW1CdWdLZXlzID0gcmVxdWlyZSgnLi9fZW51bS1idWcta2V5cycpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBPYmplY3Qua2V5cyB8fCBmdW5jdGlvbiBrZXlzKE8pe1xyXG4gIHJldHVybiAka2V5cyhPLCBlbnVtQnVnS2V5cyk7XHJcbn07XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWtleXMuanNcbiAqKi8iLCJ2YXIgaGFzICAgICAgICAgID0gcmVxdWlyZSgnLi9faGFzJylcclxuICAsIHRvSU9iamVjdCAgICA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKVxyXG4gICwgYXJyYXlJbmRleE9mID0gcmVxdWlyZSgnLi9fYXJyYXktaW5jbHVkZXMnKShmYWxzZSlcclxuICAsIElFX1BST1RPICAgICA9IHJlcXVpcmUoJy4vX3NoYXJlZC1rZXknKSgnSUVfUFJPVE8nKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24ob2JqZWN0LCBuYW1lcyl7XHJcbiAgdmFyIE8gICAgICA9IHRvSU9iamVjdChvYmplY3QpXHJcbiAgICAsIGkgICAgICA9IDBcclxuICAgICwgcmVzdWx0ID0gW11cclxuICAgICwga2V5O1xyXG4gIGZvcihrZXkgaW4gTylpZihrZXkgIT0gSUVfUFJPVE8paGFzKE8sIGtleSkgJiYgcmVzdWx0LnB1c2goa2V5KTtcclxuICAvLyBEb24ndCBlbnVtIGJ1ZyAmIGhpZGRlbiBrZXlzXHJcbiAgd2hpbGUobmFtZXMubGVuZ3RoID4gaSlpZihoYXMoTywga2V5ID0gbmFtZXNbaSsrXSkpe1xyXG4gICAgfmFycmF5SW5kZXhPZihyZXN1bHQsIGtleSkgfHwgcmVzdWx0LnB1c2goa2V5KTtcclxuICB9XHJcbiAgcmV0dXJuIHJlc3VsdDtcclxufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19vYmplY3Qta2V5cy1pbnRlcm5hbC5qc1xuICoqLyIsIi8vIHRvIGluZGV4ZWQgb2JqZWN0LCB0b09iamVjdCB3aXRoIGZhbGxiYWNrIGZvciBub24tYXJyYXktbGlrZSBFUzMgc3RyaW5nc1xudmFyIElPYmplY3QgPSByZXF1aXJlKCcuL19pb2JqZWN0JylcbiAgLCBkZWZpbmVkID0gcmVxdWlyZSgnLi9fZGVmaW5lZCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCl7XG4gIHJldHVybiBJT2JqZWN0KGRlZmluZWQoaXQpKTtcbn07XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9fdG8taW9iamVjdC5qc1xuICoqLyIsIi8vIGZhbGxiYWNrIGZvciBub24tYXJyYXktbGlrZSBFUzMgYW5kIG5vbi1lbnVtZXJhYmxlIG9sZCBWOCBzdHJpbmdzXG52YXIgY29mID0gcmVxdWlyZSgnLi9fY29mJyk7XG5tb2R1bGUuZXhwb3J0cyA9IE9iamVjdCgneicpLnByb3BlcnR5SXNFbnVtZXJhYmxlKDApID8gT2JqZWN0IDogZnVuY3Rpb24oaXQpe1xuICByZXR1cm4gY29mKGl0KSA9PSAnU3RyaW5nJyA/IGl0LnNwbGl0KCcnKSA6IE9iamVjdChpdCk7XG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX2lvYmplY3QuanNcbiAqKi8iLCJ2YXIgdG9TdHJpbmcgPSB7fS50b1N0cmluZztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCl7XG4gIHJldHVybiB0b1N0cmluZy5jYWxsKGl0KS5zbGljZSg4LCAtMSk7XG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX2NvZi5qc1xuICoqLyIsIi8vIDcuMi4xIFJlcXVpcmVPYmplY3RDb2VyY2libGUoYXJndW1lbnQpXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcbiAgaWYoaXQgPT0gdW5kZWZpbmVkKXRocm93IFR5cGVFcnJvcihcIkNhbid0IGNhbGwgbWV0aG9kIG9uICBcIiArIGl0KTtcbiAgcmV0dXJuIGl0O1xufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19kZWZpbmVkLmpzXG4gKiovIiwiLy8gZmFsc2UgLT4gQXJyYXkjaW5kZXhPZlxuLy8gdHJ1ZSAgLT4gQXJyYXkjaW5jbHVkZXNcbnZhciB0b0lPYmplY3QgPSByZXF1aXJlKCcuL190by1pb2JqZWN0JylcbiAgLCB0b0xlbmd0aCAgPSByZXF1aXJlKCcuL190by1sZW5ndGgnKVxuICAsIHRvSW5kZXggICA9IHJlcXVpcmUoJy4vX3RvLWluZGV4Jyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKElTX0lOQ0xVREVTKXtcbiAgcmV0dXJuIGZ1bmN0aW9uKCR0aGlzLCBlbCwgZnJvbUluZGV4KXtcbiAgICB2YXIgTyAgICAgID0gdG9JT2JqZWN0KCR0aGlzKVxuICAgICAgLCBsZW5ndGggPSB0b0xlbmd0aChPLmxlbmd0aClcbiAgICAgICwgaW5kZXggID0gdG9JbmRleChmcm9tSW5kZXgsIGxlbmd0aClcbiAgICAgICwgdmFsdWU7XG4gICAgLy8gQXJyYXkjaW5jbHVkZXMgdXNlcyBTYW1lVmFsdWVaZXJvIGVxdWFsaXR5IGFsZ29yaXRobVxuICAgIGlmKElTX0lOQ0xVREVTICYmIGVsICE9IGVsKXdoaWxlKGxlbmd0aCA+IGluZGV4KXtcbiAgICAgIHZhbHVlID0gT1tpbmRleCsrXTtcbiAgICAgIGlmKHZhbHVlICE9IHZhbHVlKXJldHVybiB0cnVlO1xuICAgIC8vIEFycmF5I3RvSW5kZXggaWdub3JlcyBob2xlcywgQXJyYXkjaW5jbHVkZXMgLSBub3RcbiAgICB9IGVsc2UgZm9yKDtsZW5ndGggPiBpbmRleDsgaW5kZXgrKylpZihJU19JTkNMVURFUyB8fCBpbmRleCBpbiBPKXtcbiAgICAgIGlmKE9baW5kZXhdID09PSBlbClyZXR1cm4gSVNfSU5DTFVERVMgfHwgaW5kZXg7XG4gICAgfSByZXR1cm4gIUlTX0lOQ0xVREVTICYmIC0xO1xuICB9O1xufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19hcnJheS1pbmNsdWRlcy5qc1xuICoqLyIsIi8vIDcuMS4xNSBUb0xlbmd0aFxudmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKVxuICAsIG1pbiAgICAgICA9IE1hdGgubWluO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCl7XG4gIHJldHVybiBpdCA+IDAgPyBtaW4odG9JbnRlZ2VyKGl0KSwgMHgxZmZmZmZmZmZmZmZmZikgOiAwOyAvLyBwb3coMiwgNTMpIC0gMSA9PSA5MDA3MTk5MjU0NzQwOTkxXG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX3RvLWxlbmd0aC5qc1xuICoqLyIsIi8vIDcuMS40IFRvSW50ZWdlclxudmFyIGNlaWwgID0gTWF0aC5jZWlsXG4gICwgZmxvb3IgPSBNYXRoLmZsb29yO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCl7XG4gIHJldHVybiBpc05hTihpdCA9ICtpdCkgPyAwIDogKGl0ID4gMCA/IGZsb29yIDogY2VpbCkoaXQpO1xufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL190by1pbnRlZ2VyLmpzXG4gKiovIiwidmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKVxuICAsIG1heCAgICAgICA9IE1hdGgubWF4XG4gICwgbWluICAgICAgID0gTWF0aC5taW47XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGluZGV4LCBsZW5ndGgpe1xuICBpbmRleCA9IHRvSW50ZWdlcihpbmRleCk7XG4gIHJldHVybiBpbmRleCA8IDAgPyBtYXgoaW5kZXggKyBsZW5ndGgsIDApIDogbWluKGluZGV4LCBsZW5ndGgpO1xufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL190by1pbmRleC5qc1xuICoqLyIsInZhciBzaGFyZWQgPSByZXF1aXJlKCcuL19zaGFyZWQnKSgna2V5cycpXHJcbiAgLCB1aWQgICAgPSByZXF1aXJlKCcuL191aWQnKTtcclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihrZXkpe1xyXG4gIHJldHVybiBzaGFyZWRba2V5XSB8fCAoc2hhcmVkW2tleV0gPSB1aWQoa2V5KSk7XHJcbn07XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9fc2hhcmVkLWtleS5qc1xuICoqLyIsInZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKVxuICAsIFNIQVJFRCA9ICdfX2NvcmUtanNfc2hhcmVkX18nXG4gICwgc3RvcmUgID0gZ2xvYmFsW1NIQVJFRF0gfHwgKGdsb2JhbFtTSEFSRURdID0ge30pO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihrZXkpe1xuICByZXR1cm4gc3RvcmVba2V5XSB8fCAoc3RvcmVba2V5XSA9IHt9KTtcbn07XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9fc2hhcmVkLmpzXG4gKiovIiwiLy8gSUUgOC0gZG9uJ3QgZW51bSBidWcga2V5c1xyXG5tb2R1bGUuZXhwb3J0cyA9IChcclxuICAnY29uc3RydWN0b3IsaGFzT3duUHJvcGVydHksaXNQcm90b3R5cGVPZixwcm9wZXJ0eUlzRW51bWVyYWJsZSx0b0xvY2FsZVN0cmluZyx0b1N0cmluZyx2YWx1ZU9mJ1xyXG4pLnNwbGl0KCcsJyk7XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9fZW51bS1idWcta2V5cy5qc1xuICoqLyIsImV4cG9ydHMuZiA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWdvcHMuanNcbiAqKi8iLCJleHBvcnRzLmYgPSB7fS5wcm9wZXJ0eUlzRW51bWVyYWJsZTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19vYmplY3QtcGllLmpzXG4gKiovIiwiLy8gNy4xLjEzIFRvT2JqZWN0KGFyZ3VtZW50KVxudmFyIGRlZmluZWQgPSByZXF1aXJlKCcuL19kZWZpbmVkJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcbiAgcmV0dXJuIE9iamVjdChkZWZpbmVkKGl0KSk7XG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX3RvLW9iamVjdC5qc1xuICoqLyIsIi8vIGZpeCBQcm9taXNlIFByb2JsZW0gb24gSlNDb250ZXh0IG9mIGlPUzd+OFxuLy8gQHNlZSBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTM1ODY2XG5nbG9iYWwuUHJvbWlzZSA9IG51bGxcbnJlcXVpcmUoJ2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LnRvLXN0cmluZycpXG5yZXF1aXJlKCdjb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5pdGVyYXRvcicpXG5yZXF1aXJlKCdjb3JlLWpzL21vZHVsZXMvd2ViLmRvbS5pdGVyYWJsZScpXG5yZXF1aXJlKCdjb3JlLWpzL21vZHVsZXMvZXM2LnByb21pc2UnKVxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vcG9seWZpbGwvcHJvbWlzZS5qc1xuICoqLyIsIid1c2Ugc3RyaWN0Jztcbi8vIDE5LjEuMy42IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcoKVxudmFyIGNsYXNzb2YgPSByZXF1aXJlKCcuL19jbGFzc29mJylcbiAgLCB0ZXN0ICAgID0ge307XG50ZXN0W3JlcXVpcmUoJy4vX3drcycpKCd0b1N0cmluZ1RhZycpXSA9ICd6JztcbmlmKHRlc3QgKyAnJyAhPSAnW29iamVjdCB6XScpe1xuICByZXF1aXJlKCcuL19yZWRlZmluZScpKE9iamVjdC5wcm90b3R5cGUsICd0b1N0cmluZycsIGZ1bmN0aW9uIHRvU3RyaW5nKCl7XG4gICAgcmV0dXJuICdbb2JqZWN0ICcgKyBjbGFzc29mKHRoaXMpICsgJ10nO1xuICB9LCB0cnVlKTtcbn1cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QudG8tc3RyaW5nLmpzXG4gKiovIiwiLy8gZ2V0dGluZyB0YWcgZnJvbSAxOS4xLjMuNiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nKClcbnZhciBjb2YgPSByZXF1aXJlKCcuL19jb2YnKVxuICAsIFRBRyA9IHJlcXVpcmUoJy4vX3drcycpKCd0b1N0cmluZ1RhZycpXG4gIC8vIEVTMyB3cm9uZyBoZXJlXG4gICwgQVJHID0gY29mKGZ1bmN0aW9uKCl7IHJldHVybiBhcmd1bWVudHM7IH0oKSkgPT0gJ0FyZ3VtZW50cyc7XG5cbi8vIGZhbGxiYWNrIGZvciBJRTExIFNjcmlwdCBBY2Nlc3MgRGVuaWVkIGVycm9yXG52YXIgdHJ5R2V0ID0gZnVuY3Rpb24oaXQsIGtleSl7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGl0W2tleV07XG4gIH0gY2F0Y2goZSl7IC8qIGVtcHR5ICovIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQpe1xuICB2YXIgTywgVCwgQjtcbiAgcmV0dXJuIGl0ID09PSB1bmRlZmluZWQgPyAnVW5kZWZpbmVkJyA6IGl0ID09PSBudWxsID8gJ051bGwnXG4gICAgLy8gQEB0b1N0cmluZ1RhZyBjYXNlXG4gICAgOiB0eXBlb2YgKFQgPSB0cnlHZXQoTyA9IE9iamVjdChpdCksIFRBRykpID09ICdzdHJpbmcnID8gVFxuICAgIC8vIGJ1aWx0aW5UYWcgY2FzZVxuICAgIDogQVJHID8gY29mKE8pXG4gICAgLy8gRVMzIGFyZ3VtZW50cyBmYWxsYmFja1xuICAgIDogKEIgPSBjb2YoTykpID09ICdPYmplY3QnICYmIHR5cGVvZiBPLmNhbGxlZSA9PSAnZnVuY3Rpb24nID8gJ0FyZ3VtZW50cycgOiBCO1xufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19jbGFzc29mLmpzXG4gKiovIiwidmFyIHN0b3JlICAgICAgPSByZXF1aXJlKCcuL19zaGFyZWQnKSgnd2tzJylcbiAgLCB1aWQgICAgICAgID0gcmVxdWlyZSgnLi9fdWlkJylcbiAgLCBTeW1ib2wgICAgID0gcmVxdWlyZSgnLi9fZ2xvYmFsJykuU3ltYm9sXG4gICwgVVNFX1NZTUJPTCA9IHR5cGVvZiBTeW1ib2wgPT0gJ2Z1bmN0aW9uJztcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24obmFtZSl7XG4gIHJldHVybiBzdG9yZVtuYW1lXSB8fCAoc3RvcmVbbmFtZV0gPVxuICAgIFVTRV9TWU1CT0wgJiYgU3ltYm9sW25hbWVdIHx8IChVU0VfU1lNQk9MID8gU3ltYm9sIDogdWlkKSgnU3ltYm9sLicgKyBuYW1lKSk7XG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX3drcy5qc1xuICoqLyIsIid1c2Ugc3RyaWN0JztcbnZhciAkYXQgID0gcmVxdWlyZSgnLi9fc3RyaW5nLWF0JykodHJ1ZSk7XG5cbi8vIDIxLjEuMy4yNyBTdHJpbmcucHJvdG90eXBlW0BAaXRlcmF0b3JdKClcbnJlcXVpcmUoJy4vX2l0ZXItZGVmaW5lJykoU3RyaW5nLCAnU3RyaW5nJywgZnVuY3Rpb24oaXRlcmF0ZWQpe1xuICB0aGlzLl90ID0gU3RyaW5nKGl0ZXJhdGVkKTsgLy8gdGFyZ2V0XG4gIHRoaXMuX2kgPSAwOyAgICAgICAgICAgICAgICAvLyBuZXh0IGluZGV4XG4vLyAyMS4xLjUuMi4xICVTdHJpbmdJdGVyYXRvclByb3RvdHlwZSUubmV4dCgpXG59LCBmdW5jdGlvbigpe1xuICB2YXIgTyAgICAgPSB0aGlzLl90XG4gICAgLCBpbmRleCA9IHRoaXMuX2lcbiAgICAsIHBvaW50O1xuICBpZihpbmRleCA+PSBPLmxlbmd0aClyZXR1cm4ge3ZhbHVlOiB1bmRlZmluZWQsIGRvbmU6IHRydWV9O1xuICBwb2ludCA9ICRhdChPLCBpbmRleCk7XG4gIHRoaXMuX2kgKz0gcG9pbnQubGVuZ3RoO1xuICByZXR1cm4ge3ZhbHVlOiBwb2ludCwgZG9uZTogZmFsc2V9O1xufSk7XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLml0ZXJhdG9yLmpzXG4gKiovIiwidmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKVxuICAsIGRlZmluZWQgICA9IHJlcXVpcmUoJy4vX2RlZmluZWQnKTtcbi8vIHRydWUgIC0+IFN0cmluZyNhdFxuLy8gZmFsc2UgLT4gU3RyaW5nI2NvZGVQb2ludEF0XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKFRPX1NUUklORyl7XG4gIHJldHVybiBmdW5jdGlvbih0aGF0LCBwb3Mpe1xuICAgIHZhciBzID0gU3RyaW5nKGRlZmluZWQodGhhdCkpXG4gICAgICAsIGkgPSB0b0ludGVnZXIocG9zKVxuICAgICAgLCBsID0gcy5sZW5ndGhcbiAgICAgICwgYSwgYjtcbiAgICBpZihpIDwgMCB8fCBpID49IGwpcmV0dXJuIFRPX1NUUklORyA/ICcnIDogdW5kZWZpbmVkO1xuICAgIGEgPSBzLmNoYXJDb2RlQXQoaSk7XG4gICAgcmV0dXJuIGEgPCAweGQ4MDAgfHwgYSA+IDB4ZGJmZiB8fCBpICsgMSA9PT0gbCB8fCAoYiA9IHMuY2hhckNvZGVBdChpICsgMSkpIDwgMHhkYzAwIHx8IGIgPiAweGRmZmZcbiAgICAgID8gVE9fU1RSSU5HID8gcy5jaGFyQXQoaSkgOiBhXG4gICAgICA6IFRPX1NUUklORyA/IHMuc2xpY2UoaSwgaSArIDIpIDogKGEgLSAweGQ4MDAgPDwgMTApICsgKGIgLSAweGRjMDApICsgMHgxMDAwMDtcbiAgfTtcbn07XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9fc3RyaW5nLWF0LmpzXG4gKiovIiwiJ3VzZSBzdHJpY3QnO1xudmFyIExJQlJBUlkgICAgICAgID0gcmVxdWlyZSgnLi9fbGlicmFyeScpXG4gICwgJGV4cG9ydCAgICAgICAgPSByZXF1aXJlKCcuL19leHBvcnQnKVxuICAsIHJlZGVmaW5lICAgICAgID0gcmVxdWlyZSgnLi9fcmVkZWZpbmUnKVxuICAsIGhpZGUgICAgICAgICAgID0gcmVxdWlyZSgnLi9faGlkZScpXG4gICwgaGFzICAgICAgICAgICAgPSByZXF1aXJlKCcuL19oYXMnKVxuICAsIEl0ZXJhdG9ycyAgICAgID0gcmVxdWlyZSgnLi9faXRlcmF0b3JzJylcbiAgLCAkaXRlckNyZWF0ZSAgICA9IHJlcXVpcmUoJy4vX2l0ZXItY3JlYXRlJylcbiAgLCBzZXRUb1N0cmluZ1RhZyA9IHJlcXVpcmUoJy4vX3NldC10by1zdHJpbmctdGFnJylcbiAgLCBnZXRQcm90b3R5cGVPZiA9IHJlcXVpcmUoJy4vX29iamVjdC1ncG8nKVxuICAsIElURVJBVE9SICAgICAgID0gcmVxdWlyZSgnLi9fd2tzJykoJ2l0ZXJhdG9yJylcbiAgLCBCVUdHWSAgICAgICAgICA9ICEoW10ua2V5cyAmJiAnbmV4dCcgaW4gW10ua2V5cygpKSAvLyBTYWZhcmkgaGFzIGJ1Z2d5IGl0ZXJhdG9ycyB3L28gYG5leHRgXG4gICwgRkZfSVRFUkFUT1IgICAgPSAnQEBpdGVyYXRvcidcbiAgLCBLRVlTICAgICAgICAgICA9ICdrZXlzJ1xuICAsIFZBTFVFUyAgICAgICAgID0gJ3ZhbHVlcyc7XG5cbnZhciByZXR1cm5UaGlzID0gZnVuY3Rpb24oKXsgcmV0dXJuIHRoaXM7IH07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oQmFzZSwgTkFNRSwgQ29uc3RydWN0b3IsIG5leHQsIERFRkFVTFQsIElTX1NFVCwgRk9SQ0VEKXtcbiAgJGl0ZXJDcmVhdGUoQ29uc3RydWN0b3IsIE5BTUUsIG5leHQpO1xuICB2YXIgZ2V0TWV0aG9kID0gZnVuY3Rpb24oa2luZCl7XG4gICAgaWYoIUJVR0dZICYmIGtpbmQgaW4gcHJvdG8pcmV0dXJuIHByb3RvW2tpbmRdO1xuICAgIHN3aXRjaChraW5kKXtcbiAgICAgIGNhc2UgS0VZUzogcmV0dXJuIGZ1bmN0aW9uIGtleXMoKXsgcmV0dXJuIG5ldyBDb25zdHJ1Y3Rvcih0aGlzLCBraW5kKTsgfTtcbiAgICAgIGNhc2UgVkFMVUVTOiByZXR1cm4gZnVuY3Rpb24gdmFsdWVzKCl7IHJldHVybiBuZXcgQ29uc3RydWN0b3IodGhpcywga2luZCk7IH07XG4gICAgfSByZXR1cm4gZnVuY3Rpb24gZW50cmllcygpeyByZXR1cm4gbmV3IENvbnN0cnVjdG9yKHRoaXMsIGtpbmQpOyB9O1xuICB9O1xuICB2YXIgVEFHICAgICAgICA9IE5BTUUgKyAnIEl0ZXJhdG9yJ1xuICAgICwgREVGX1ZBTFVFUyA9IERFRkFVTFQgPT0gVkFMVUVTXG4gICAgLCBWQUxVRVNfQlVHID0gZmFsc2VcbiAgICAsIHByb3RvICAgICAgPSBCYXNlLnByb3RvdHlwZVxuICAgICwgJG5hdGl2ZSAgICA9IHByb3RvW0lURVJBVE9SXSB8fCBwcm90b1tGRl9JVEVSQVRPUl0gfHwgREVGQVVMVCAmJiBwcm90b1tERUZBVUxUXVxuICAgICwgJGRlZmF1bHQgICA9ICRuYXRpdmUgfHwgZ2V0TWV0aG9kKERFRkFVTFQpXG4gICAgLCAkZW50cmllcyAgID0gREVGQVVMVCA/ICFERUZfVkFMVUVTID8gJGRlZmF1bHQgOiBnZXRNZXRob2QoJ2VudHJpZXMnKSA6IHVuZGVmaW5lZFxuICAgICwgJGFueU5hdGl2ZSA9IE5BTUUgPT0gJ0FycmF5JyA/IHByb3RvLmVudHJpZXMgfHwgJG5hdGl2ZSA6ICRuYXRpdmVcbiAgICAsIG1ldGhvZHMsIGtleSwgSXRlcmF0b3JQcm90b3R5cGU7XG4gIC8vIEZpeCBuYXRpdmVcbiAgaWYoJGFueU5hdGl2ZSl7XG4gICAgSXRlcmF0b3JQcm90b3R5cGUgPSBnZXRQcm90b3R5cGVPZigkYW55TmF0aXZlLmNhbGwobmV3IEJhc2UpKTtcbiAgICBpZihJdGVyYXRvclByb3RvdHlwZSAhPT0gT2JqZWN0LnByb3RvdHlwZSl7XG4gICAgICAvLyBTZXQgQEB0b1N0cmluZ1RhZyB0byBuYXRpdmUgaXRlcmF0b3JzXG4gICAgICBzZXRUb1N0cmluZ1RhZyhJdGVyYXRvclByb3RvdHlwZSwgVEFHLCB0cnVlKTtcbiAgICAgIC8vIGZpeCBmb3Igc29tZSBvbGQgZW5naW5lc1xuICAgICAgaWYoIUxJQlJBUlkgJiYgIWhhcyhJdGVyYXRvclByb3RvdHlwZSwgSVRFUkFUT1IpKWhpZGUoSXRlcmF0b3JQcm90b3R5cGUsIElURVJBVE9SLCByZXR1cm5UaGlzKTtcbiAgICB9XG4gIH1cbiAgLy8gZml4IEFycmF5I3t2YWx1ZXMsIEBAaXRlcmF0b3J9Lm5hbWUgaW4gVjggLyBGRlxuICBpZihERUZfVkFMVUVTICYmICRuYXRpdmUgJiYgJG5hdGl2ZS5uYW1lICE9PSBWQUxVRVMpe1xuICAgIFZBTFVFU19CVUcgPSB0cnVlO1xuICAgICRkZWZhdWx0ID0gZnVuY3Rpb24gdmFsdWVzKCl7IHJldHVybiAkbmF0aXZlLmNhbGwodGhpcyk7IH07XG4gIH1cbiAgLy8gRGVmaW5lIGl0ZXJhdG9yXG4gIGlmKCghTElCUkFSWSB8fCBGT1JDRUQpICYmIChCVUdHWSB8fCBWQUxVRVNfQlVHIHx8ICFwcm90b1tJVEVSQVRPUl0pKXtcbiAgICBoaWRlKHByb3RvLCBJVEVSQVRPUiwgJGRlZmF1bHQpO1xuICB9XG4gIC8vIFBsdWcgZm9yIGxpYnJhcnlcbiAgSXRlcmF0b3JzW05BTUVdID0gJGRlZmF1bHQ7XG4gIEl0ZXJhdG9yc1tUQUddICA9IHJldHVyblRoaXM7XG4gIGlmKERFRkFVTFQpe1xuICAgIG1ldGhvZHMgPSB7XG4gICAgICB2YWx1ZXM6ICBERUZfVkFMVUVTID8gJGRlZmF1bHQgOiBnZXRNZXRob2QoVkFMVUVTKSxcbiAgICAgIGtleXM6ICAgIElTX1NFVCAgICAgPyAkZGVmYXVsdCA6IGdldE1ldGhvZChLRVlTKSxcbiAgICAgIGVudHJpZXM6ICRlbnRyaWVzXG4gICAgfTtcbiAgICBpZihGT1JDRUQpZm9yKGtleSBpbiBtZXRob2RzKXtcbiAgICAgIGlmKCEoa2V5IGluIHByb3RvKSlyZWRlZmluZShwcm90bywga2V5LCBtZXRob2RzW2tleV0pO1xuICAgIH0gZWxzZSAkZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIChCVUdHWSB8fCBWQUxVRVNfQlVHKSwgTkFNRSwgbWV0aG9kcyk7XG4gIH1cbiAgcmV0dXJuIG1ldGhvZHM7XG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX2l0ZXItZGVmaW5lLmpzXG4gKiovIiwibW9kdWxlLmV4cG9ydHMgPSBmYWxzZTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19saWJyYXJ5LmpzXG4gKiovIiwibW9kdWxlLmV4cG9ydHMgPSB7fTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19pdGVyYXRvcnMuanNcbiAqKi8iLCIndXNlIHN0cmljdCc7XG52YXIgY3JlYXRlICAgICAgICAgPSByZXF1aXJlKCcuL19vYmplY3QtY3JlYXRlJylcbiAgLCBkZXNjcmlwdG9yICAgICA9IHJlcXVpcmUoJy4vX3Byb3BlcnR5LWRlc2MnKVxuICAsIHNldFRvU3RyaW5nVGFnID0gcmVxdWlyZSgnLi9fc2V0LXRvLXN0cmluZy10YWcnKVxuICAsIEl0ZXJhdG9yUHJvdG90eXBlID0ge307XG5cbi8vIDI1LjEuMi4xLjEgJUl0ZXJhdG9yUHJvdG90eXBlJVtAQGl0ZXJhdG9yXSgpXG5yZXF1aXJlKCcuL19oaWRlJykoSXRlcmF0b3JQcm90b3R5cGUsIHJlcXVpcmUoJy4vX3drcycpKCdpdGVyYXRvcicpLCBmdW5jdGlvbigpeyByZXR1cm4gdGhpczsgfSk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oQ29uc3RydWN0b3IsIE5BTUUsIG5leHQpe1xuICBDb25zdHJ1Y3Rvci5wcm90b3R5cGUgPSBjcmVhdGUoSXRlcmF0b3JQcm90b3R5cGUsIHtuZXh0OiBkZXNjcmlwdG9yKDEsIG5leHQpfSk7XG4gIHNldFRvU3RyaW5nVGFnKENvbnN0cnVjdG9yLCBOQU1FICsgJyBJdGVyYXRvcicpO1xufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19pdGVyLWNyZWF0ZS5qc1xuICoqLyIsIi8vIDE5LjEuMi4yIC8gMTUuMi4zLjUgT2JqZWN0LmNyZWF0ZShPIFssIFByb3BlcnRpZXNdKVxyXG52YXIgYW5PYmplY3QgICAgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKVxyXG4gICwgZFBzICAgICAgICAgPSByZXF1aXJlKCcuL19vYmplY3QtZHBzJylcclxuICAsIGVudW1CdWdLZXlzID0gcmVxdWlyZSgnLi9fZW51bS1idWcta2V5cycpXHJcbiAgLCBJRV9QUk9UTyAgICA9IHJlcXVpcmUoJy4vX3NoYXJlZC1rZXknKSgnSUVfUFJPVE8nKVxyXG4gICwgRW1wdHkgICAgICAgPSBmdW5jdGlvbigpeyAvKiBlbXB0eSAqLyB9XHJcbiAgLCBQUk9UT1RZUEUgICA9ICdwcm90b3R5cGUnO1xyXG5cclxuLy8gQ3JlYXRlIG9iamVjdCB3aXRoIGZha2UgYG51bGxgIHByb3RvdHlwZTogdXNlIGlmcmFtZSBPYmplY3Qgd2l0aCBjbGVhcmVkIHByb3RvdHlwZVxyXG52YXIgY3JlYXRlRGljdCA9IGZ1bmN0aW9uKCl7XHJcbiAgLy8gVGhyYXNoLCB3YXN0ZSBhbmQgc29kb215OiBJRSBHQyBidWdcclxuICB2YXIgaWZyYW1lID0gcmVxdWlyZSgnLi9fZG9tLWNyZWF0ZScpKCdpZnJhbWUnKVxyXG4gICAgLCBpICAgICAgPSBlbnVtQnVnS2V5cy5sZW5ndGhcclxuICAgICwgZ3QgICAgID0gJz4nXHJcbiAgICAsIGlmcmFtZURvY3VtZW50O1xyXG4gIGlmcmFtZS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xyXG4gIHJlcXVpcmUoJy4vX2h0bWwnKS5hcHBlbmRDaGlsZChpZnJhbWUpO1xyXG4gIGlmcmFtZS5zcmMgPSAnamF2YXNjcmlwdDonOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXNjcmlwdC11cmxcclxuICAvLyBjcmVhdGVEaWN0ID0gaWZyYW1lLmNvbnRlbnRXaW5kb3cuT2JqZWN0O1xyXG4gIC8vIGh0bWwucmVtb3ZlQ2hpbGQoaWZyYW1lKTtcclxuICBpZnJhbWVEb2N1bWVudCA9IGlmcmFtZS5jb250ZW50V2luZG93LmRvY3VtZW50O1xyXG4gIGlmcmFtZURvY3VtZW50Lm9wZW4oKTtcclxuICBpZnJhbWVEb2N1bWVudC53cml0ZSgnPHNjcmlwdD5kb2N1bWVudC5GPU9iamVjdDwvc2NyaXB0JyArIGd0KTtcclxuICBpZnJhbWVEb2N1bWVudC5jbG9zZSgpO1xyXG4gIGNyZWF0ZURpY3QgPSBpZnJhbWVEb2N1bWVudC5GO1xyXG4gIHdoaWxlKGktLSlkZWxldGUgY3JlYXRlRGljdFtQUk9UT1RZUEVdW2VudW1CdWdLZXlzW2ldXTtcclxuICByZXR1cm4gY3JlYXRlRGljdCgpO1xyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBPYmplY3QuY3JlYXRlIHx8IGZ1bmN0aW9uIGNyZWF0ZShPLCBQcm9wZXJ0aWVzKXtcclxuICB2YXIgcmVzdWx0O1xyXG4gIGlmKE8gIT09IG51bGwpe1xyXG4gICAgRW1wdHlbUFJPVE9UWVBFXSA9IGFuT2JqZWN0KE8pO1xyXG4gICAgcmVzdWx0ID0gbmV3IEVtcHR5O1xyXG4gICAgRW1wdHlbUFJPVE9UWVBFXSA9IG51bGw7XHJcbiAgICAvLyBhZGQgXCJfX3Byb3RvX19cIiBmb3IgT2JqZWN0LmdldFByb3RvdHlwZU9mIHBvbHlmaWxsXHJcbiAgICByZXN1bHRbSUVfUFJPVE9dID0gTztcclxuICB9IGVsc2UgcmVzdWx0ID0gY3JlYXRlRGljdCgpO1xyXG4gIHJldHVybiBQcm9wZXJ0aWVzID09PSB1bmRlZmluZWQgPyByZXN1bHQgOiBkUHMocmVzdWx0LCBQcm9wZXJ0aWVzKTtcclxufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19vYmplY3QtY3JlYXRlLmpzXG4gKiovIiwidmFyIGRQICAgICAgID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJylcclxuICAsIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0JylcclxuICAsIGdldEtleXMgID0gcmVxdWlyZSgnLi9fb2JqZWN0LWtleXMnKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSA/IE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzIDogZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyhPLCBQcm9wZXJ0aWVzKXtcclxuICBhbk9iamVjdChPKTtcclxuICB2YXIga2V5cyAgID0gZ2V0S2V5cyhQcm9wZXJ0aWVzKVxyXG4gICAgLCBsZW5ndGggPSBrZXlzLmxlbmd0aFxyXG4gICAgLCBpID0gMFxyXG4gICAgLCBQO1xyXG4gIHdoaWxlKGxlbmd0aCA+IGkpZFAuZihPLCBQID0ga2V5c1tpKytdLCBQcm9wZXJ0aWVzW1BdKTtcclxuICByZXR1cm4gTztcclxufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZHBzLmpzXG4gKiovIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19nbG9iYWwnKS5kb2N1bWVudCAmJiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9faHRtbC5qc1xuICoqLyIsInZhciBkZWYgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKS5mXG4gICwgaGFzID0gcmVxdWlyZSgnLi9faGFzJylcbiAgLCBUQUcgPSByZXF1aXJlKCcuL193a3MnKSgndG9TdHJpbmdUYWcnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCwgdGFnLCBzdGF0KXtcbiAgaWYoaXQgJiYgIWhhcyhpdCA9IHN0YXQgPyBpdCA6IGl0LnByb3RvdHlwZSwgVEFHKSlkZWYoaXQsIFRBRywge2NvbmZpZ3VyYWJsZTogdHJ1ZSwgdmFsdWU6IHRhZ30pO1xufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19zZXQtdG8tc3RyaW5nLXRhZy5qc1xuICoqLyIsIi8vIDE5LjEuMi45IC8gMTUuMi4zLjIgT2JqZWN0LmdldFByb3RvdHlwZU9mKE8pXHJcbnZhciBoYXMgICAgICAgICA9IHJlcXVpcmUoJy4vX2hhcycpXHJcbiAgLCB0b09iamVjdCAgICA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpXHJcbiAgLCBJRV9QUk9UTyAgICA9IHJlcXVpcmUoJy4vX3NoYXJlZC1rZXknKSgnSUVfUFJPVE8nKVxyXG4gICwgT2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YgfHwgZnVuY3Rpb24oTyl7XHJcbiAgTyA9IHRvT2JqZWN0KE8pO1xyXG4gIGlmKGhhcyhPLCBJRV9QUk9UTykpcmV0dXJuIE9bSUVfUFJPVE9dO1xyXG4gIGlmKHR5cGVvZiBPLmNvbnN0cnVjdG9yID09ICdmdW5jdGlvbicgJiYgTyBpbnN0YW5jZW9mIE8uY29uc3RydWN0b3Ipe1xyXG4gICAgcmV0dXJuIE8uY29uc3RydWN0b3IucHJvdG90eXBlO1xyXG4gIH0gcmV0dXJuIE8gaW5zdGFuY2VvZiBPYmplY3QgPyBPYmplY3RQcm90byA6IG51bGw7XHJcbn07XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWdwby5qc1xuICoqLyIsInZhciAkaXRlcmF0b3JzICAgID0gcmVxdWlyZSgnLi9lczYuYXJyYXkuaXRlcmF0b3InKVxuICAsIHJlZGVmaW5lICAgICAgPSByZXF1aXJlKCcuL19yZWRlZmluZScpXG4gICwgZ2xvYmFsICAgICAgICA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpXG4gICwgaGlkZSAgICAgICAgICA9IHJlcXVpcmUoJy4vX2hpZGUnKVxuICAsIEl0ZXJhdG9ycyAgICAgPSByZXF1aXJlKCcuL19pdGVyYXRvcnMnKVxuICAsIHdrcyAgICAgICAgICAgPSByZXF1aXJlKCcuL193a3MnKVxuICAsIElURVJBVE9SICAgICAgPSB3a3MoJ2l0ZXJhdG9yJylcbiAgLCBUT19TVFJJTkdfVEFHID0gd2tzKCd0b1N0cmluZ1RhZycpXG4gICwgQXJyYXlWYWx1ZXMgICA9IEl0ZXJhdG9ycy5BcnJheTtcblxuZm9yKHZhciBjb2xsZWN0aW9ucyA9IFsnTm9kZUxpc3QnLCAnRE9NVG9rZW5MaXN0JywgJ01lZGlhTGlzdCcsICdTdHlsZVNoZWV0TGlzdCcsICdDU1NSdWxlTGlzdCddLCBpID0gMDsgaSA8IDU7IGkrKyl7XG4gIHZhciBOQU1FICAgICAgID0gY29sbGVjdGlvbnNbaV1cbiAgICAsIENvbGxlY3Rpb24gPSBnbG9iYWxbTkFNRV1cbiAgICAsIHByb3RvICAgICAgPSBDb2xsZWN0aW9uICYmIENvbGxlY3Rpb24ucHJvdG90eXBlXG4gICAgLCBrZXk7XG4gIGlmKHByb3RvKXtcbiAgICBpZighcHJvdG9bSVRFUkFUT1JdKWhpZGUocHJvdG8sIElURVJBVE9SLCBBcnJheVZhbHVlcyk7XG4gICAgaWYoIXByb3RvW1RPX1NUUklOR19UQUddKWhpZGUocHJvdG8sIFRPX1NUUklOR19UQUcsIE5BTUUpO1xuICAgIEl0ZXJhdG9yc1tOQU1FXSA9IEFycmF5VmFsdWVzO1xuICAgIGZvcihrZXkgaW4gJGl0ZXJhdG9ycylpZighcHJvdG9ba2V5XSlyZWRlZmluZShwcm90bywga2V5LCAkaXRlcmF0b3JzW2tleV0sIHRydWUpO1xuICB9XG59XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy93ZWIuZG9tLml0ZXJhYmxlLmpzXG4gKiovIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGFkZFRvVW5zY29wYWJsZXMgPSByZXF1aXJlKCcuL19hZGQtdG8tdW5zY29wYWJsZXMnKVxuICAsIHN0ZXAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19pdGVyLXN0ZXAnKVxuICAsIEl0ZXJhdG9ycyAgICAgICAgPSByZXF1aXJlKCcuL19pdGVyYXRvcnMnKVxuICAsIHRvSU9iamVjdCAgICAgICAgPSByZXF1aXJlKCcuL190by1pb2JqZWN0Jyk7XG5cbi8vIDIyLjEuMy40IEFycmF5LnByb3RvdHlwZS5lbnRyaWVzKClcbi8vIDIyLjEuMy4xMyBBcnJheS5wcm90b3R5cGUua2V5cygpXG4vLyAyMi4xLjMuMjkgQXJyYXkucHJvdG90eXBlLnZhbHVlcygpXG4vLyAyMi4xLjMuMzAgQXJyYXkucHJvdG90eXBlW0BAaXRlcmF0b3JdKClcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9faXRlci1kZWZpbmUnKShBcnJheSwgJ0FycmF5JywgZnVuY3Rpb24oaXRlcmF0ZWQsIGtpbmQpe1xuICB0aGlzLl90ID0gdG9JT2JqZWN0KGl0ZXJhdGVkKTsgLy8gdGFyZ2V0XG4gIHRoaXMuX2kgPSAwOyAgICAgICAgICAgICAgICAgICAvLyBuZXh0IGluZGV4XG4gIHRoaXMuX2sgPSBraW5kOyAgICAgICAgICAgICAgICAvLyBraW5kXG4vLyAyMi4xLjUuMi4xICVBcnJheUl0ZXJhdG9yUHJvdG90eXBlJS5uZXh0KClcbn0sIGZ1bmN0aW9uKCl7XG4gIHZhciBPICAgICA9IHRoaXMuX3RcbiAgICAsIGtpbmQgID0gdGhpcy5fa1xuICAgICwgaW5kZXggPSB0aGlzLl9pKys7XG4gIGlmKCFPIHx8IGluZGV4ID49IE8ubGVuZ3RoKXtcbiAgICB0aGlzLl90ID0gdW5kZWZpbmVkO1xuICAgIHJldHVybiBzdGVwKDEpO1xuICB9XG4gIGlmKGtpbmQgPT0gJ2tleXMnICApcmV0dXJuIHN0ZXAoMCwgaW5kZXgpO1xuICBpZihraW5kID09ICd2YWx1ZXMnKXJldHVybiBzdGVwKDAsIE9baW5kZXhdKTtcbiAgcmV0dXJuIHN0ZXAoMCwgW2luZGV4LCBPW2luZGV4XV0pO1xufSwgJ3ZhbHVlcycpO1xuXG4vLyBhcmd1bWVudHNMaXN0W0BAaXRlcmF0b3JdIGlzICVBcnJheVByb3RvX3ZhbHVlcyUgKDkuNC40LjYsIDkuNC40LjcpXG5JdGVyYXRvcnMuQXJndW1lbnRzID0gSXRlcmF0b3JzLkFycmF5O1xuXG5hZGRUb1Vuc2NvcGFibGVzKCdrZXlzJyk7XG5hZGRUb1Vuc2NvcGFibGVzKCd2YWx1ZXMnKTtcbmFkZFRvVW5zY29wYWJsZXMoJ2VudHJpZXMnKTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5pdGVyYXRvci5qc1xuICoqLyIsIi8vIDIyLjEuMy4zMSBBcnJheS5wcm90b3R5cGVbQEB1bnNjb3BhYmxlc11cbnZhciBVTlNDT1BBQkxFUyA9IHJlcXVpcmUoJy4vX3drcycpKCd1bnNjb3BhYmxlcycpXG4gICwgQXJyYXlQcm90byAgPSBBcnJheS5wcm90b3R5cGU7XG5pZihBcnJheVByb3RvW1VOU0NPUEFCTEVTXSA9PSB1bmRlZmluZWQpcmVxdWlyZSgnLi9faGlkZScpKEFycmF5UHJvdG8sIFVOU0NPUEFCTEVTLCB7fSk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGtleSl7XG4gIEFycmF5UHJvdG9bVU5TQ09QQUJMRVNdW2tleV0gPSB0cnVlO1xufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19hZGQtdG8tdW5zY29wYWJsZXMuanNcbiAqKi8iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGRvbmUsIHZhbHVlKXtcbiAgcmV0dXJuIHt2YWx1ZTogdmFsdWUsIGRvbmU6ICEhZG9uZX07XG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX2l0ZXItc3RlcC5qc1xuICoqLyIsIid1c2Ugc3RyaWN0JztcbnZhciBMSUJSQVJZICAgICAgICAgICAgPSByZXF1aXJlKCcuL19saWJyYXJ5JylcbiAgLCBnbG9iYWwgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19nbG9iYWwnKVxuICAsIGN0eCAgICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX2N0eCcpXG4gICwgY2xhc3NvZiAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fY2xhc3NvZicpXG4gICwgJGV4cG9ydCAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCBpc09iamVjdCAgICAgICAgICAgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKVxuICAsIGFuT2JqZWN0ICAgICAgICAgICA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpXG4gICwgYUZ1bmN0aW9uICAgICAgICAgID0gcmVxdWlyZSgnLi9fYS1mdW5jdGlvbicpXG4gICwgYW5JbnN0YW5jZSAgICAgICAgID0gcmVxdWlyZSgnLi9fYW4taW5zdGFuY2UnKVxuICAsIGZvck9mICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX2Zvci1vZicpXG4gICwgc2V0UHJvdG8gICAgICAgICAgID0gcmVxdWlyZSgnLi9fc2V0LXByb3RvJykuc2V0XG4gICwgc3BlY2llc0NvbnN0cnVjdG9yID0gcmVxdWlyZSgnLi9fc3BlY2llcy1jb25zdHJ1Y3RvcicpXG4gICwgdGFzayAgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fdGFzaycpLnNldFxuICAsIG1pY3JvdGFzayAgICAgICAgICA9IHJlcXVpcmUoJy4vX21pY3JvdGFzaycpXG4gICwgUFJPTUlTRSAgICAgICAgICAgID0gJ1Byb21pc2UnXG4gICwgVHlwZUVycm9yICAgICAgICAgID0gZ2xvYmFsLlR5cGVFcnJvclxuICAsIHByb2Nlc3MgICAgICAgICAgICA9IGdsb2JhbC5wcm9jZXNzXG4gICwgJFByb21pc2UgICAgICAgICAgID0gZ2xvYmFsW1BST01JU0VdXG4gICwgcHJvY2VzcyAgICAgICAgICAgID0gZ2xvYmFsLnByb2Nlc3NcbiAgLCBpc05vZGUgICAgICAgICAgICAgPSBjbGFzc29mKHByb2Nlc3MpID09ICdwcm9jZXNzJ1xuICAsIGVtcHR5ICAgICAgICAgICAgICA9IGZ1bmN0aW9uKCl7IC8qIGVtcHR5ICovIH1cbiAgLCBJbnRlcm5hbCwgR2VuZXJpY1Byb21pc2VDYXBhYmlsaXR5LCBXcmFwcGVyO1xuXG52YXIgVVNFX05BVElWRSA9ICEhZnVuY3Rpb24oKXtcbiAgdHJ5IHtcbiAgICAvLyBjb3JyZWN0IHN1YmNsYXNzaW5nIHdpdGggQEBzcGVjaWVzIHN1cHBvcnRcbiAgICB2YXIgcHJvbWlzZSAgICAgPSAkUHJvbWlzZS5yZXNvbHZlKDEpXG4gICAgICAsIEZha2VQcm9taXNlID0gKHByb21pc2UuY29uc3RydWN0b3IgPSB7fSlbcmVxdWlyZSgnLi9fd2tzJykoJ3NwZWNpZXMnKV0gPSBmdW5jdGlvbihleGVjKXsgZXhlYyhlbXB0eSwgZW1wdHkpOyB9O1xuICAgIC8vIHVuaGFuZGxlZCByZWplY3Rpb25zIHRyYWNraW5nIHN1cHBvcnQsIE5vZGVKUyBQcm9taXNlIHdpdGhvdXQgaXQgZmFpbHMgQEBzcGVjaWVzIHRlc3RcbiAgICByZXR1cm4gKGlzTm9kZSB8fCB0eXBlb2YgUHJvbWlzZVJlamVjdGlvbkV2ZW50ID09ICdmdW5jdGlvbicpICYmIHByb21pc2UudGhlbihlbXB0eSkgaW5zdGFuY2VvZiBGYWtlUHJvbWlzZTtcbiAgfSBjYXRjaChlKXsgLyogZW1wdHkgKi8gfVxufSgpO1xuXG4vLyBoZWxwZXJzXG52YXIgc2FtZUNvbnN0cnVjdG9yID0gZnVuY3Rpb24oYSwgYil7XG4gIC8vIHdpdGggbGlicmFyeSB3cmFwcGVyIHNwZWNpYWwgY2FzZVxuICByZXR1cm4gYSA9PT0gYiB8fCBhID09PSAkUHJvbWlzZSAmJiBiID09PSBXcmFwcGVyO1xufTtcbnZhciBpc1RoZW5hYmxlID0gZnVuY3Rpb24oaXQpe1xuICB2YXIgdGhlbjtcbiAgcmV0dXJuIGlzT2JqZWN0KGl0KSAmJiB0eXBlb2YgKHRoZW4gPSBpdC50aGVuKSA9PSAnZnVuY3Rpb24nID8gdGhlbiA6IGZhbHNlO1xufTtcbnZhciBuZXdQcm9taXNlQ2FwYWJpbGl0eSA9IGZ1bmN0aW9uKEMpe1xuICByZXR1cm4gc2FtZUNvbnN0cnVjdG9yKCRQcm9taXNlLCBDKVxuICAgID8gbmV3IFByb21pc2VDYXBhYmlsaXR5KEMpXG4gICAgOiBuZXcgR2VuZXJpY1Byb21pc2VDYXBhYmlsaXR5KEMpO1xufTtcbnZhciBQcm9taXNlQ2FwYWJpbGl0eSA9IEdlbmVyaWNQcm9taXNlQ2FwYWJpbGl0eSA9IGZ1bmN0aW9uKEMpe1xuICB2YXIgcmVzb2x2ZSwgcmVqZWN0O1xuICB0aGlzLnByb21pc2UgPSBuZXcgQyhmdW5jdGlvbigkJHJlc29sdmUsICQkcmVqZWN0KXtcbiAgICBpZihyZXNvbHZlICE9PSB1bmRlZmluZWQgfHwgcmVqZWN0ICE9PSB1bmRlZmluZWQpdGhyb3cgVHlwZUVycm9yKCdCYWQgUHJvbWlzZSBjb25zdHJ1Y3RvcicpO1xuICAgIHJlc29sdmUgPSAkJHJlc29sdmU7XG4gICAgcmVqZWN0ICA9ICQkcmVqZWN0O1xuICB9KTtcbiAgdGhpcy5yZXNvbHZlID0gYUZ1bmN0aW9uKHJlc29sdmUpO1xuICB0aGlzLnJlamVjdCAgPSBhRnVuY3Rpb24ocmVqZWN0KTtcbn07XG52YXIgcGVyZm9ybSA9IGZ1bmN0aW9uKGV4ZWMpe1xuICB0cnkge1xuICAgIGV4ZWMoKTtcbiAgfSBjYXRjaChlKXtcbiAgICByZXR1cm4ge2Vycm9yOiBlfTtcbiAgfVxufTtcbnZhciBub3RpZnkgPSBmdW5jdGlvbihwcm9taXNlLCBpc1JlamVjdCl7XG4gIGlmKHByb21pc2UuX24pcmV0dXJuO1xuICBwcm9taXNlLl9uID0gdHJ1ZTtcbiAgdmFyIGNoYWluID0gcHJvbWlzZS5fYztcbiAgbWljcm90YXNrKGZ1bmN0aW9uKCl7XG4gICAgdmFyIHZhbHVlID0gcHJvbWlzZS5fdlxuICAgICAgLCBvayAgICA9IHByb21pc2UuX3MgPT0gMVxuICAgICAgLCBpICAgICA9IDA7XG4gICAgdmFyIHJ1biA9IGZ1bmN0aW9uKHJlYWN0aW9uKXtcbiAgICAgIHZhciBoYW5kbGVyID0gb2sgPyByZWFjdGlvbi5vayA6IHJlYWN0aW9uLmZhaWxcbiAgICAgICAgLCByZXNvbHZlID0gcmVhY3Rpb24ucmVzb2x2ZVxuICAgICAgICAsIHJlamVjdCAgPSByZWFjdGlvbi5yZWplY3RcbiAgICAgICAgLCBkb21haW4gID0gcmVhY3Rpb24uZG9tYWluXG4gICAgICAgICwgcmVzdWx0LCB0aGVuO1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYoaGFuZGxlcil7XG4gICAgICAgICAgaWYoIW9rKXtcbiAgICAgICAgICAgIGlmKHByb21pc2UuX2ggPT0gMilvbkhhbmRsZVVuaGFuZGxlZChwcm9taXNlKTtcbiAgICAgICAgICAgIHByb21pc2UuX2ggPSAxO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZihoYW5kbGVyID09PSB0cnVlKXJlc3VsdCA9IHZhbHVlO1xuICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaWYoZG9tYWluKWRvbWFpbi5lbnRlcigpO1xuICAgICAgICAgICAgcmVzdWx0ID0gaGFuZGxlcih2YWx1ZSk7XG4gICAgICAgICAgICBpZihkb21haW4pZG9tYWluLmV4aXQoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYocmVzdWx0ID09PSByZWFjdGlvbi5wcm9taXNlKXtcbiAgICAgICAgICAgIHJlamVjdChUeXBlRXJyb3IoJ1Byb21pc2UtY2hhaW4gY3ljbGUnKSk7XG4gICAgICAgICAgfSBlbHNlIGlmKHRoZW4gPSBpc1RoZW5hYmxlKHJlc3VsdCkpe1xuICAgICAgICAgICAgdGhlbi5jYWxsKHJlc3VsdCwgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgICB9IGVsc2UgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICB9IGVsc2UgcmVqZWN0KHZhbHVlKTtcbiAgICAgIH0gY2F0Y2goZSl7XG4gICAgICAgIHJlamVjdChlKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIHdoaWxlKGNoYWluLmxlbmd0aCA+IGkpcnVuKGNoYWluW2krK10pOyAvLyB2YXJpYWJsZSBsZW5ndGggLSBjYW4ndCB1c2UgZm9yRWFjaFxuICAgIHByb21pc2UuX2MgPSBbXTtcbiAgICBwcm9taXNlLl9uID0gZmFsc2U7XG4gICAgaWYoaXNSZWplY3QgJiYgIXByb21pc2UuX2gpb25VbmhhbmRsZWQocHJvbWlzZSk7XG4gIH0pO1xufTtcbnZhciBvblVuaGFuZGxlZCA9IGZ1bmN0aW9uKHByb21pc2Upe1xuICB0YXNrLmNhbGwoZ2xvYmFsLCBmdW5jdGlvbigpe1xuICAgIHZhciB2YWx1ZSA9IHByb21pc2UuX3ZcbiAgICAgICwgYWJydXB0LCBoYW5kbGVyLCBjb25zb2xlO1xuICAgIGlmKGlzVW5oYW5kbGVkKHByb21pc2UpKXtcbiAgICAgIGFicnVwdCA9IHBlcmZvcm0oZnVuY3Rpb24oKXtcbiAgICAgICAgaWYoaXNOb2RlKXtcbiAgICAgICAgICBwcm9jZXNzLmVtaXQoJ3VuaGFuZGxlZFJlamVjdGlvbicsIHZhbHVlLCBwcm9taXNlKTtcbiAgICAgICAgfSBlbHNlIGlmKGhhbmRsZXIgPSBnbG9iYWwub251bmhhbmRsZWRyZWplY3Rpb24pe1xuICAgICAgICAgIGhhbmRsZXIoe3Byb21pc2U6IHByb21pc2UsIHJlYXNvbjogdmFsdWV9KTtcbiAgICAgICAgfSBlbHNlIGlmKChjb25zb2xlID0gZ2xvYmFsLmNvbnNvbGUpICYmIGNvbnNvbGUuZXJyb3Ipe1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1VuaGFuZGxlZCBwcm9taXNlIHJlamVjdGlvbicsIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICAvLyBCcm93c2VycyBzaG91bGQgbm90IHRyaWdnZXIgYHJlamVjdGlvbkhhbmRsZWRgIGV2ZW50IGlmIGl0IHdhcyBoYW5kbGVkIGhlcmUsIE5vZGVKUyAtIHNob3VsZFxuICAgICAgcHJvbWlzZS5faCA9IGlzTm9kZSB8fCBpc1VuaGFuZGxlZChwcm9taXNlKSA/IDIgOiAxO1xuICAgIH0gcHJvbWlzZS5fYSA9IHVuZGVmaW5lZDtcbiAgICBpZihhYnJ1cHQpdGhyb3cgYWJydXB0LmVycm9yO1xuICB9KTtcbn07XG52YXIgaXNVbmhhbmRsZWQgPSBmdW5jdGlvbihwcm9taXNlKXtcbiAgaWYocHJvbWlzZS5faCA9PSAxKXJldHVybiBmYWxzZTtcbiAgdmFyIGNoYWluID0gcHJvbWlzZS5fYSB8fCBwcm9taXNlLl9jXG4gICAgLCBpICAgICA9IDBcbiAgICAsIHJlYWN0aW9uO1xuICB3aGlsZShjaGFpbi5sZW5ndGggPiBpKXtcbiAgICByZWFjdGlvbiA9IGNoYWluW2krK107XG4gICAgaWYocmVhY3Rpb24uZmFpbCB8fCAhaXNVbmhhbmRsZWQocmVhY3Rpb24ucHJvbWlzZSkpcmV0dXJuIGZhbHNlO1xuICB9IHJldHVybiB0cnVlO1xufTtcbnZhciBvbkhhbmRsZVVuaGFuZGxlZCA9IGZ1bmN0aW9uKHByb21pc2Upe1xuICB0YXNrLmNhbGwoZ2xvYmFsLCBmdW5jdGlvbigpe1xuICAgIHZhciBoYW5kbGVyO1xuICAgIGlmKGlzTm9kZSl7XG4gICAgICBwcm9jZXNzLmVtaXQoJ3JlamVjdGlvbkhhbmRsZWQnLCBwcm9taXNlKTtcbiAgICB9IGVsc2UgaWYoaGFuZGxlciA9IGdsb2JhbC5vbnJlamVjdGlvbmhhbmRsZWQpe1xuICAgICAgaGFuZGxlcih7cHJvbWlzZTogcHJvbWlzZSwgcmVhc29uOiBwcm9taXNlLl92fSk7XG4gICAgfVxuICB9KTtcbn07XG52YXIgJHJlamVjdCA9IGZ1bmN0aW9uKHZhbHVlKXtcbiAgdmFyIHByb21pc2UgPSB0aGlzO1xuICBpZihwcm9taXNlLl9kKXJldHVybjtcbiAgcHJvbWlzZS5fZCA9IHRydWU7XG4gIHByb21pc2UgPSBwcm9taXNlLl93IHx8IHByb21pc2U7IC8vIHVud3JhcFxuICBwcm9taXNlLl92ID0gdmFsdWU7XG4gIHByb21pc2UuX3MgPSAyO1xuICBpZighcHJvbWlzZS5fYSlwcm9taXNlLl9hID0gcHJvbWlzZS5fYy5zbGljZSgpO1xuICBub3RpZnkocHJvbWlzZSwgdHJ1ZSk7XG59O1xudmFyICRyZXNvbHZlID0gZnVuY3Rpb24odmFsdWUpe1xuICB2YXIgcHJvbWlzZSA9IHRoaXNcbiAgICAsIHRoZW47XG4gIGlmKHByb21pc2UuX2QpcmV0dXJuO1xuICBwcm9taXNlLl9kID0gdHJ1ZTtcbiAgcHJvbWlzZSA9IHByb21pc2UuX3cgfHwgcHJvbWlzZTsgLy8gdW53cmFwXG4gIHRyeSB7XG4gICAgaWYocHJvbWlzZSA9PT0gdmFsdWUpdGhyb3cgVHlwZUVycm9yKFwiUHJvbWlzZSBjYW4ndCBiZSByZXNvbHZlZCBpdHNlbGZcIik7XG4gICAgaWYodGhlbiA9IGlzVGhlbmFibGUodmFsdWUpKXtcbiAgICAgIG1pY3JvdGFzayhmdW5jdGlvbigpe1xuICAgICAgICB2YXIgd3JhcHBlciA9IHtfdzogcHJvbWlzZSwgX2Q6IGZhbHNlfTsgLy8gd3JhcFxuICAgICAgICB0cnkge1xuICAgICAgICAgIHRoZW4uY2FsbCh2YWx1ZSwgY3R4KCRyZXNvbHZlLCB3cmFwcGVyLCAxKSwgY3R4KCRyZWplY3QsIHdyYXBwZXIsIDEpKTtcbiAgICAgICAgfSBjYXRjaChlKXtcbiAgICAgICAgICAkcmVqZWN0LmNhbGwod3JhcHBlciwgZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBwcm9taXNlLl92ID0gdmFsdWU7XG4gICAgICBwcm9taXNlLl9zID0gMTtcbiAgICAgIG5vdGlmeShwcm9taXNlLCBmYWxzZSk7XG4gICAgfVxuICB9IGNhdGNoKGUpe1xuICAgICRyZWplY3QuY2FsbCh7X3c6IHByb21pc2UsIF9kOiBmYWxzZX0sIGUpOyAvLyB3cmFwXG4gIH1cbn07XG5cbi8vIGNvbnN0cnVjdG9yIHBvbHlmaWxsXG5pZighVVNFX05BVElWRSl7XG4gIC8vIDI1LjQuMy4xIFByb21pc2UoZXhlY3V0b3IpXG4gICRQcm9taXNlID0gZnVuY3Rpb24gUHJvbWlzZShleGVjdXRvcil7XG4gICAgYW5JbnN0YW5jZSh0aGlzLCAkUHJvbWlzZSwgUFJPTUlTRSwgJ19oJyk7XG4gICAgYUZ1bmN0aW9uKGV4ZWN1dG9yKTtcbiAgICBJbnRlcm5hbC5jYWxsKHRoaXMpO1xuICAgIHRyeSB7XG4gICAgICBleGVjdXRvcihjdHgoJHJlc29sdmUsIHRoaXMsIDEpLCBjdHgoJHJlamVjdCwgdGhpcywgMSkpO1xuICAgIH0gY2F0Y2goZXJyKXtcbiAgICAgICRyZWplY3QuY2FsbCh0aGlzLCBlcnIpO1xuICAgIH1cbiAgfTtcbiAgSW50ZXJuYWwgPSBmdW5jdGlvbiBQcm9taXNlKGV4ZWN1dG9yKXtcbiAgICB0aGlzLl9jID0gW107ICAgICAgICAgICAgIC8vIDwtIGF3YWl0aW5nIHJlYWN0aW9uc1xuICAgIHRoaXMuX2EgPSB1bmRlZmluZWQ7ICAgICAgLy8gPC0gY2hlY2tlZCBpbiBpc1VuaGFuZGxlZCByZWFjdGlvbnNcbiAgICB0aGlzLl9zID0gMDsgICAgICAgICAgICAgIC8vIDwtIHN0YXRlXG4gICAgdGhpcy5fZCA9IGZhbHNlOyAgICAgICAgICAvLyA8LSBkb25lXG4gICAgdGhpcy5fdiA9IHVuZGVmaW5lZDsgICAgICAvLyA8LSB2YWx1ZVxuICAgIHRoaXMuX2ggPSAwOyAgICAgICAgICAgICAgLy8gPC0gcmVqZWN0aW9uIHN0YXRlLCAwIC0gZGVmYXVsdCwgMSAtIGhhbmRsZWQsIDIgLSB1bmhhbmRsZWRcbiAgICB0aGlzLl9uID0gZmFsc2U7ICAgICAgICAgIC8vIDwtIG5vdGlmeVxuICB9O1xuICBJbnRlcm5hbC5wcm90b3R5cGUgPSByZXF1aXJlKCcuL19yZWRlZmluZS1hbGwnKSgkUHJvbWlzZS5wcm90b3R5cGUsIHtcbiAgICAvLyAyNS40LjUuMyBQcm9taXNlLnByb3RvdHlwZS50aGVuKG9uRnVsZmlsbGVkLCBvblJlamVjdGVkKVxuICAgIHRoZW46IGZ1bmN0aW9uIHRoZW4ob25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQpe1xuICAgICAgdmFyIHJlYWN0aW9uICAgID0gbmV3UHJvbWlzZUNhcGFiaWxpdHkoc3BlY2llc0NvbnN0cnVjdG9yKHRoaXMsICRQcm9taXNlKSk7XG4gICAgICByZWFjdGlvbi5vayAgICAgPSB0eXBlb2Ygb25GdWxmaWxsZWQgPT0gJ2Z1bmN0aW9uJyA/IG9uRnVsZmlsbGVkIDogdHJ1ZTtcbiAgICAgIHJlYWN0aW9uLmZhaWwgICA9IHR5cGVvZiBvblJlamVjdGVkID09ICdmdW5jdGlvbicgJiYgb25SZWplY3RlZDtcbiAgICAgIHJlYWN0aW9uLmRvbWFpbiA9IGlzTm9kZSA/IHByb2Nlc3MuZG9tYWluIDogdW5kZWZpbmVkO1xuICAgICAgdGhpcy5fYy5wdXNoKHJlYWN0aW9uKTtcbiAgICAgIGlmKHRoaXMuX2EpdGhpcy5fYS5wdXNoKHJlYWN0aW9uKTtcbiAgICAgIGlmKHRoaXMuX3Mpbm90aWZ5KHRoaXMsIGZhbHNlKTtcbiAgICAgIHJldHVybiByZWFjdGlvbi5wcm9taXNlO1xuICAgIH0sXG4gICAgLy8gMjUuNC41LjEgUHJvbWlzZS5wcm90b3R5cGUuY2F0Y2gob25SZWplY3RlZClcbiAgICAnY2F0Y2gnOiBmdW5jdGlvbihvblJlamVjdGVkKXtcbiAgICAgIHJldHVybiB0aGlzLnRoZW4odW5kZWZpbmVkLCBvblJlamVjdGVkKTtcbiAgICB9XG4gIH0pO1xuICBQcm9taXNlQ2FwYWJpbGl0eSA9IGZ1bmN0aW9uKCl7XG4gICAgdmFyIHByb21pc2UgID0gbmV3IEludGVybmFsO1xuICAgIHRoaXMucHJvbWlzZSA9IHByb21pc2U7XG4gICAgdGhpcy5yZXNvbHZlID0gY3R4KCRyZXNvbHZlLCBwcm9taXNlLCAxKTtcbiAgICB0aGlzLnJlamVjdCAgPSBjdHgoJHJlamVjdCwgcHJvbWlzZSwgMSk7XG4gIH07XG59XG5cbiRleHBvcnQoJGV4cG9ydC5HICsgJGV4cG9ydC5XICsgJGV4cG9ydC5GICogIVVTRV9OQVRJVkUsIHtQcm9taXNlOiAkUHJvbWlzZX0pO1xucmVxdWlyZSgnLi9fc2V0LXRvLXN0cmluZy10YWcnKSgkUHJvbWlzZSwgUFJPTUlTRSk7XG5yZXF1aXJlKCcuL19zZXQtc3BlY2llcycpKFBST01JU0UpO1xuV3JhcHBlciA9IHJlcXVpcmUoJy4vX2NvcmUnKVtQUk9NSVNFXTtcblxuLy8gc3RhdGljc1xuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhVVNFX05BVElWRSwgUFJPTUlTRSwge1xuICAvLyAyNS40LjQuNSBQcm9taXNlLnJlamVjdChyKVxuICByZWplY3Q6IGZ1bmN0aW9uIHJlamVjdChyKXtcbiAgICB2YXIgY2FwYWJpbGl0eSA9IG5ld1Byb21pc2VDYXBhYmlsaXR5KHRoaXMpXG4gICAgICAsICQkcmVqZWN0ICAgPSBjYXBhYmlsaXR5LnJlamVjdDtcbiAgICAkJHJlamVjdChyKTtcbiAgICByZXR1cm4gY2FwYWJpbGl0eS5wcm9taXNlO1xuICB9XG59KTtcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogKExJQlJBUlkgfHwgIVVTRV9OQVRJVkUpLCBQUk9NSVNFLCB7XG4gIC8vIDI1LjQuNC42IFByb21pc2UucmVzb2x2ZSh4KVxuICByZXNvbHZlOiBmdW5jdGlvbiByZXNvbHZlKHgpe1xuICAgIC8vIGluc3RhbmNlb2YgaW5zdGVhZCBvZiBpbnRlcm5hbCBzbG90IGNoZWNrIGJlY2F1c2Ugd2Ugc2hvdWxkIGZpeCBpdCB3aXRob3V0IHJlcGxhY2VtZW50IG5hdGl2ZSBQcm9taXNlIGNvcmVcbiAgICBpZih4IGluc3RhbmNlb2YgJFByb21pc2UgJiYgc2FtZUNvbnN0cnVjdG9yKHguY29uc3RydWN0b3IsIHRoaXMpKXJldHVybiB4O1xuICAgIHZhciBjYXBhYmlsaXR5ID0gbmV3UHJvbWlzZUNhcGFiaWxpdHkodGhpcylcbiAgICAgICwgJCRyZXNvbHZlICA9IGNhcGFiaWxpdHkucmVzb2x2ZTtcbiAgICAkJHJlc29sdmUoeCk7XG4gICAgcmV0dXJuIGNhcGFiaWxpdHkucHJvbWlzZTtcbiAgfVxufSk7XG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICEoVVNFX05BVElWRSAmJiByZXF1aXJlKCcuL19pdGVyLWRldGVjdCcpKGZ1bmN0aW9uKGl0ZXIpe1xuICAkUHJvbWlzZS5hbGwoaXRlcilbJ2NhdGNoJ10oZW1wdHkpO1xufSkpLCBQUk9NSVNFLCB7XG4gIC8vIDI1LjQuNC4xIFByb21pc2UuYWxsKGl0ZXJhYmxlKVxuICBhbGw6IGZ1bmN0aW9uIGFsbChpdGVyYWJsZSl7XG4gICAgdmFyIEMgICAgICAgICAgPSB0aGlzXG4gICAgICAsIGNhcGFiaWxpdHkgPSBuZXdQcm9taXNlQ2FwYWJpbGl0eShDKVxuICAgICAgLCByZXNvbHZlICAgID0gY2FwYWJpbGl0eS5yZXNvbHZlXG4gICAgICAsIHJlamVjdCAgICAgPSBjYXBhYmlsaXR5LnJlamVjdDtcbiAgICB2YXIgYWJydXB0ID0gcGVyZm9ybShmdW5jdGlvbigpe1xuICAgICAgdmFyIHZhbHVlcyAgICA9IFtdXG4gICAgICAgICwgaW5kZXggICAgID0gMFxuICAgICAgICAsIHJlbWFpbmluZyA9IDE7XG4gICAgICBmb3JPZihpdGVyYWJsZSwgZmFsc2UsIGZ1bmN0aW9uKHByb21pc2Upe1xuICAgICAgICB2YXIgJGluZGV4ICAgICAgICA9IGluZGV4KytcbiAgICAgICAgICAsIGFscmVhZHlDYWxsZWQgPSBmYWxzZTtcbiAgICAgICAgdmFsdWVzLnB1c2godW5kZWZpbmVkKTtcbiAgICAgICAgcmVtYWluaW5nKys7XG4gICAgICAgIEMucmVzb2x2ZShwcm9taXNlKS50aGVuKGZ1bmN0aW9uKHZhbHVlKXtcbiAgICAgICAgICBpZihhbHJlYWR5Q2FsbGVkKXJldHVybjtcbiAgICAgICAgICBhbHJlYWR5Q2FsbGVkICA9IHRydWU7XG4gICAgICAgICAgdmFsdWVzWyRpbmRleF0gPSB2YWx1ZTtcbiAgICAgICAgICAtLXJlbWFpbmluZyB8fCByZXNvbHZlKHZhbHVlcyk7XG4gICAgICAgIH0sIHJlamVjdCk7XG4gICAgICB9KTtcbiAgICAgIC0tcmVtYWluaW5nIHx8IHJlc29sdmUodmFsdWVzKTtcbiAgICB9KTtcbiAgICBpZihhYnJ1cHQpcmVqZWN0KGFicnVwdC5lcnJvcik7XG4gICAgcmV0dXJuIGNhcGFiaWxpdHkucHJvbWlzZTtcbiAgfSxcbiAgLy8gMjUuNC40LjQgUHJvbWlzZS5yYWNlKGl0ZXJhYmxlKVxuICByYWNlOiBmdW5jdGlvbiByYWNlKGl0ZXJhYmxlKXtcbiAgICB2YXIgQyAgICAgICAgICA9IHRoaXNcbiAgICAgICwgY2FwYWJpbGl0eSA9IG5ld1Byb21pc2VDYXBhYmlsaXR5KEMpXG4gICAgICAsIHJlamVjdCAgICAgPSBjYXBhYmlsaXR5LnJlamVjdDtcbiAgICB2YXIgYWJydXB0ID0gcGVyZm9ybShmdW5jdGlvbigpe1xuICAgICAgZm9yT2YoaXRlcmFibGUsIGZhbHNlLCBmdW5jdGlvbihwcm9taXNlKXtcbiAgICAgICAgQy5yZXNvbHZlKHByb21pc2UpLnRoZW4oY2FwYWJpbGl0eS5yZXNvbHZlLCByZWplY3QpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gICAgaWYoYWJydXB0KXJlamVjdChhYnJ1cHQuZXJyb3IpO1xuICAgIHJldHVybiBjYXBhYmlsaXR5LnByb21pc2U7XG4gIH1cbn0pO1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvZXM2LnByb21pc2UuanNcbiAqKi8iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0LCBDb25zdHJ1Y3RvciwgbmFtZSwgZm9yYmlkZGVuRmllbGQpe1xuICBpZighKGl0IGluc3RhbmNlb2YgQ29uc3RydWN0b3IpIHx8IChmb3JiaWRkZW5GaWVsZCAhPT0gdW5kZWZpbmVkICYmIGZvcmJpZGRlbkZpZWxkIGluIGl0KSl7XG4gICAgdGhyb3cgVHlwZUVycm9yKG5hbWUgKyAnOiBpbmNvcnJlY3QgaW52b2NhdGlvbiEnKTtcbiAgfSByZXR1cm4gaXQ7XG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX2FuLWluc3RhbmNlLmpzXG4gKiovIiwidmFyIGN0eCAgICAgICAgID0gcmVxdWlyZSgnLi9fY3R4JylcbiAgLCBjYWxsICAgICAgICA9IHJlcXVpcmUoJy4vX2l0ZXItY2FsbCcpXG4gICwgaXNBcnJheUl0ZXIgPSByZXF1aXJlKCcuL19pcy1hcnJheS1pdGVyJylcbiAgLCBhbk9iamVjdCAgICA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpXG4gICwgdG9MZW5ndGggICAgPSByZXF1aXJlKCcuL190by1sZW5ndGgnKVxuICAsIGdldEl0ZXJGbiAgID0gcmVxdWlyZSgnLi9jb3JlLmdldC1pdGVyYXRvci1tZXRob2QnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXRlcmFibGUsIGVudHJpZXMsIGZuLCB0aGF0LCBJVEVSQVRPUil7XG4gIHZhciBpdGVyRm4gPSBJVEVSQVRPUiA/IGZ1bmN0aW9uKCl7IHJldHVybiBpdGVyYWJsZTsgfSA6IGdldEl0ZXJGbihpdGVyYWJsZSlcbiAgICAsIGYgICAgICA9IGN0eChmbiwgdGhhdCwgZW50cmllcyA/IDIgOiAxKVxuICAgICwgaW5kZXggID0gMFxuICAgICwgbGVuZ3RoLCBzdGVwLCBpdGVyYXRvcjtcbiAgaWYodHlwZW9mIGl0ZXJGbiAhPSAnZnVuY3Rpb24nKXRocm93IFR5cGVFcnJvcihpdGVyYWJsZSArICcgaXMgbm90IGl0ZXJhYmxlIScpO1xuICAvLyBmYXN0IGNhc2UgZm9yIGFycmF5cyB3aXRoIGRlZmF1bHQgaXRlcmF0b3JcbiAgaWYoaXNBcnJheUl0ZXIoaXRlckZuKSlmb3IobGVuZ3RoID0gdG9MZW5ndGgoaXRlcmFibGUubGVuZ3RoKTsgbGVuZ3RoID4gaW5kZXg7IGluZGV4Kyspe1xuICAgIGVudHJpZXMgPyBmKGFuT2JqZWN0KHN0ZXAgPSBpdGVyYWJsZVtpbmRleF0pWzBdLCBzdGVwWzFdKSA6IGYoaXRlcmFibGVbaW5kZXhdKTtcbiAgfSBlbHNlIGZvcihpdGVyYXRvciA9IGl0ZXJGbi5jYWxsKGl0ZXJhYmxlKTsgIShzdGVwID0gaXRlcmF0b3IubmV4dCgpKS5kb25lOyApe1xuICAgIGNhbGwoaXRlcmF0b3IsIGYsIHN0ZXAudmFsdWUsIGVudHJpZXMpO1xuICB9XG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX2Zvci1vZi5qc1xuICoqLyIsIi8vIGNhbGwgc29tZXRoaW5nIG9uIGl0ZXJhdG9yIHN0ZXAgd2l0aCBzYWZlIGNsb3Npbmcgb24gZXJyb3JcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdGVyYXRvciwgZm4sIHZhbHVlLCBlbnRyaWVzKXtcbiAgdHJ5IHtcbiAgICByZXR1cm4gZW50cmllcyA/IGZuKGFuT2JqZWN0KHZhbHVlKVswXSwgdmFsdWVbMV0pIDogZm4odmFsdWUpO1xuICAvLyA3LjQuNiBJdGVyYXRvckNsb3NlKGl0ZXJhdG9yLCBjb21wbGV0aW9uKVxuICB9IGNhdGNoKGUpe1xuICAgIHZhciByZXQgPSBpdGVyYXRvclsncmV0dXJuJ107XG4gICAgaWYocmV0ICE9PSB1bmRlZmluZWQpYW5PYmplY3QocmV0LmNhbGwoaXRlcmF0b3IpKTtcbiAgICB0aHJvdyBlO1xuICB9XG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX2l0ZXItY2FsbC5qc1xuICoqLyIsIi8vIGNoZWNrIG9uIGRlZmF1bHQgQXJyYXkgaXRlcmF0b3JcbnZhciBJdGVyYXRvcnMgID0gcmVxdWlyZSgnLi9faXRlcmF0b3JzJylcbiAgLCBJVEVSQVRPUiAgID0gcmVxdWlyZSgnLi9fd2tzJykoJ2l0ZXJhdG9yJylcbiAgLCBBcnJheVByb3RvID0gQXJyYXkucHJvdG90eXBlO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcbiAgcmV0dXJuIGl0ICE9PSB1bmRlZmluZWQgJiYgKEl0ZXJhdG9ycy5BcnJheSA9PT0gaXQgfHwgQXJyYXlQcm90b1tJVEVSQVRPUl0gPT09IGl0KTtcbn07XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9faXMtYXJyYXktaXRlci5qc1xuICoqLyIsInZhciBjbGFzc29mICAgPSByZXF1aXJlKCcuL19jbGFzc29mJylcbiAgLCBJVEVSQVRPUiAgPSByZXF1aXJlKCcuL193a3MnKSgnaXRlcmF0b3InKVxuICAsIEl0ZXJhdG9ycyA9IHJlcXVpcmUoJy4vX2l0ZXJhdG9ycycpO1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19jb3JlJykuZ2V0SXRlcmF0b3JNZXRob2QgPSBmdW5jdGlvbihpdCl7XG4gIGlmKGl0ICE9IHVuZGVmaW5lZClyZXR1cm4gaXRbSVRFUkFUT1JdXG4gICAgfHwgaXRbJ0BAaXRlcmF0b3InXVxuICAgIHx8IEl0ZXJhdG9yc1tjbGFzc29mKGl0KV07XG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvY29yZS5nZXQtaXRlcmF0b3ItbWV0aG9kLmpzXG4gKiovIiwiLy8gV29ya3Mgd2l0aCBfX3Byb3RvX18gb25seS4gT2xkIHY4IGNhbid0IHdvcmsgd2l0aCBudWxsIHByb3RvIG9iamVjdHMuXG4vKiBlc2xpbnQtZGlzYWJsZSBuby1wcm90byAqL1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0JylcbiAgLCBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIGNoZWNrID0gZnVuY3Rpb24oTywgcHJvdG8pe1xuICBhbk9iamVjdChPKTtcbiAgaWYoIWlzT2JqZWN0KHByb3RvKSAmJiBwcm90byAhPT0gbnVsbCl0aHJvdyBUeXBlRXJyb3IocHJvdG8gKyBcIjogY2FuJ3Qgc2V0IGFzIHByb3RvdHlwZSFcIik7XG59O1xubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHNldDogT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8ICgnX19wcm90b19fJyBpbiB7fSA/IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcbiAgICBmdW5jdGlvbih0ZXN0LCBidWdneSwgc2V0KXtcbiAgICAgIHRyeSB7XG4gICAgICAgIHNldCA9IHJlcXVpcmUoJy4vX2N0eCcpKEZ1bmN0aW9uLmNhbGwsIHJlcXVpcmUoJy4vX29iamVjdC1nb3BkJykuZihPYmplY3QucHJvdG90eXBlLCAnX19wcm90b19fJykuc2V0LCAyKTtcbiAgICAgICAgc2V0KHRlc3QsIFtdKTtcbiAgICAgICAgYnVnZ3kgPSAhKHRlc3QgaW5zdGFuY2VvZiBBcnJheSk7XG4gICAgICB9IGNhdGNoKGUpeyBidWdneSA9IHRydWU7IH1cbiAgICAgIHJldHVybiBmdW5jdGlvbiBzZXRQcm90b3R5cGVPZihPLCBwcm90byl7XG4gICAgICAgIGNoZWNrKE8sIHByb3RvKTtcbiAgICAgICAgaWYoYnVnZ3kpTy5fX3Byb3RvX18gPSBwcm90bztcbiAgICAgICAgZWxzZSBzZXQoTywgcHJvdG8pO1xuICAgICAgICByZXR1cm4gTztcbiAgICAgIH07XG4gICAgfSh7fSwgZmFsc2UpIDogdW5kZWZpbmVkKSxcbiAgY2hlY2s6IGNoZWNrXG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX3NldC1wcm90by5qc1xuICoqLyIsInZhciBwSUUgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX29iamVjdC1waWUnKVxyXG4gICwgY3JlYXRlRGVzYyAgICAgPSByZXF1aXJlKCcuL19wcm9wZXJ0eS1kZXNjJylcclxuICAsIHRvSU9iamVjdCAgICAgID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpXHJcbiAgLCB0b1ByaW1pdGl2ZSAgICA9IHJlcXVpcmUoJy4vX3RvLXByaW1pdGl2ZScpXHJcbiAgLCBoYXMgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX2hhcycpXHJcbiAgLCBJRThfRE9NX0RFRklORSA9IHJlcXVpcmUoJy4vX2llOC1kb20tZGVmaW5lJylcclxuICAsIGdPUEQgICAgICAgICAgID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcjtcclxuXHJcbmV4cG9ydHMuZiA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJykgPyBnT1BEIDogZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKE8sIFApe1xyXG4gIE8gPSB0b0lPYmplY3QoTyk7XHJcbiAgUCA9IHRvUHJpbWl0aXZlKFAsIHRydWUpO1xyXG4gIGlmKElFOF9ET01fREVGSU5FKXRyeSB7XHJcbiAgICByZXR1cm4gZ09QRChPLCBQKTtcclxuICB9IGNhdGNoKGUpeyAvKiBlbXB0eSAqLyB9XHJcbiAgaWYoaGFzKE8sIFApKXJldHVybiBjcmVhdGVEZXNjKCFwSUUuZi5jYWxsKE8sIFApLCBPW1BdKTtcclxufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ29wZC5qc1xuICoqLyIsIi8vIDcuMy4yMCBTcGVjaWVzQ29uc3RydWN0b3IoTywgZGVmYXVsdENvbnN0cnVjdG9yKVxudmFyIGFuT2JqZWN0ICA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpXG4gICwgYUZ1bmN0aW9uID0gcmVxdWlyZSgnLi9fYS1mdW5jdGlvbicpXG4gICwgU1BFQ0lFUyAgID0gcmVxdWlyZSgnLi9fd2tzJykoJ3NwZWNpZXMnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oTywgRCl7XG4gIHZhciBDID0gYW5PYmplY3QoTykuY29uc3RydWN0b3IsIFM7XG4gIHJldHVybiBDID09PSB1bmRlZmluZWQgfHwgKFMgPSBhbk9iamVjdChDKVtTUEVDSUVTXSkgPT0gdW5kZWZpbmVkID8gRCA6IGFGdW5jdGlvbihTKTtcbn07XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9fc3BlY2llcy1jb25zdHJ1Y3Rvci5qc1xuICoqLyIsInZhciBjdHggICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19jdHgnKVxuICAsIGludm9rZSAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX2ludm9rZScpXG4gICwgaHRtbCAgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9faHRtbCcpXG4gICwgY2VsICAgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fZG9tLWNyZWF0ZScpXG4gICwgZ2xvYmFsICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fZ2xvYmFsJylcbiAgLCBwcm9jZXNzICAgICAgICAgICAgPSBnbG9iYWwucHJvY2Vzc1xuICAsIHNldFRhc2sgICAgICAgICAgICA9IGdsb2JhbC5zZXRJbW1lZGlhdGVcbiAgLCBjbGVhclRhc2sgICAgICAgICAgPSBnbG9iYWwuY2xlYXJJbW1lZGlhdGVcbiAgLCBNZXNzYWdlQ2hhbm5lbCAgICAgPSBnbG9iYWwuTWVzc2FnZUNoYW5uZWxcbiAgLCBjb3VudGVyICAgICAgICAgICAgPSAwXG4gICwgcXVldWUgICAgICAgICAgICAgID0ge31cbiAgLCBPTlJFQURZU1RBVEVDSEFOR0UgPSAnb25yZWFkeXN0YXRlY2hhbmdlJ1xuICAsIGRlZmVyLCBjaGFubmVsLCBwb3J0O1xudmFyIHJ1biA9IGZ1bmN0aW9uKCl7XG4gIHZhciBpZCA9ICt0aGlzO1xuICBpZihxdWV1ZS5oYXNPd25Qcm9wZXJ0eShpZCkpe1xuICAgIHZhciBmbiA9IHF1ZXVlW2lkXTtcbiAgICBkZWxldGUgcXVldWVbaWRdO1xuICAgIGZuKCk7XG4gIH1cbn07XG52YXIgbGlzdGVuZXIgPSBmdW5jdGlvbihldmVudCl7XG4gIHJ1bi5jYWxsKGV2ZW50LmRhdGEpO1xufTtcbi8vIE5vZGUuanMgMC45KyAmIElFMTArIGhhcyBzZXRJbW1lZGlhdGUsIG90aGVyd2lzZTpcbmlmKCFzZXRUYXNrIHx8ICFjbGVhclRhc2spe1xuICBzZXRUYXNrID0gZnVuY3Rpb24gc2V0SW1tZWRpYXRlKGZuKXtcbiAgICB2YXIgYXJncyA9IFtdLCBpID0gMTtcbiAgICB3aGlsZShhcmd1bWVudHMubGVuZ3RoID4gaSlhcmdzLnB1c2goYXJndW1lbnRzW2krK10pO1xuICAgIHF1ZXVlWysrY291bnRlcl0gPSBmdW5jdGlvbigpe1xuICAgICAgaW52b2tlKHR5cGVvZiBmbiA9PSAnZnVuY3Rpb24nID8gZm4gOiBGdW5jdGlvbihmbiksIGFyZ3MpO1xuICAgIH07XG4gICAgZGVmZXIoY291bnRlcik7XG4gICAgcmV0dXJuIGNvdW50ZXI7XG4gIH07XG4gIGNsZWFyVGFzayA9IGZ1bmN0aW9uIGNsZWFySW1tZWRpYXRlKGlkKXtcbiAgICBkZWxldGUgcXVldWVbaWRdO1xuICB9O1xuICAvLyBOb2RlLmpzIDAuOC1cbiAgaWYocmVxdWlyZSgnLi9fY29mJykocHJvY2VzcykgPT0gJ3Byb2Nlc3MnKXtcbiAgICBkZWZlciA9IGZ1bmN0aW9uKGlkKXtcbiAgICAgIHByb2Nlc3MubmV4dFRpY2soY3R4KHJ1biwgaWQsIDEpKTtcbiAgICB9O1xuICAvLyBCcm93c2VycyB3aXRoIE1lc3NhZ2VDaGFubmVsLCBpbmNsdWRlcyBXZWJXb3JrZXJzXG4gIH0gZWxzZSBpZihNZXNzYWdlQ2hhbm5lbCl7XG4gICAgY2hhbm5lbCA9IG5ldyBNZXNzYWdlQ2hhbm5lbDtcbiAgICBwb3J0ICAgID0gY2hhbm5lbC5wb3J0MjtcbiAgICBjaGFubmVsLnBvcnQxLm9ubWVzc2FnZSA9IGxpc3RlbmVyO1xuICAgIGRlZmVyID0gY3R4KHBvcnQucG9zdE1lc3NhZ2UsIHBvcnQsIDEpO1xuICAvLyBCcm93c2VycyB3aXRoIHBvc3RNZXNzYWdlLCBza2lwIFdlYldvcmtlcnNcbiAgLy8gSUU4IGhhcyBwb3N0TWVzc2FnZSwgYnV0IGl0J3Mgc3luYyAmIHR5cGVvZiBpdHMgcG9zdE1lc3NhZ2UgaXMgJ29iamVjdCdcbiAgfSBlbHNlIGlmKGdsb2JhbC5hZGRFdmVudExpc3RlbmVyICYmIHR5cGVvZiBwb3N0TWVzc2FnZSA9PSAnZnVuY3Rpb24nICYmICFnbG9iYWwuaW1wb3J0U2NyaXB0cyl7XG4gICAgZGVmZXIgPSBmdW5jdGlvbihpZCl7XG4gICAgICBnbG9iYWwucG9zdE1lc3NhZ2UoaWQgKyAnJywgJyonKTtcbiAgICB9O1xuICAgIGdsb2JhbC5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgbGlzdGVuZXIsIGZhbHNlKTtcbiAgLy8gSUU4LVxuICB9IGVsc2UgaWYoT05SRUFEWVNUQVRFQ0hBTkdFIGluIGNlbCgnc2NyaXB0Jykpe1xuICAgIGRlZmVyID0gZnVuY3Rpb24oaWQpe1xuICAgICAgaHRtbC5hcHBlbmRDaGlsZChjZWwoJ3NjcmlwdCcpKVtPTlJFQURZU1RBVEVDSEFOR0VdID0gZnVuY3Rpb24oKXtcbiAgICAgICAgaHRtbC5yZW1vdmVDaGlsZCh0aGlzKTtcbiAgICAgICAgcnVuLmNhbGwoaWQpO1xuICAgICAgfTtcbiAgICB9O1xuICAvLyBSZXN0IG9sZCBicm93c2Vyc1xuICB9IGVsc2Uge1xuICAgIGRlZmVyID0gZnVuY3Rpb24oaWQpe1xuICAgICAgc2V0VGltZW91dChjdHgocnVuLCBpZCwgMSksIDApO1xuICAgIH07XG4gIH1cbn1cbm1vZHVsZS5leHBvcnRzID0ge1xuICBzZXQ6ICAgc2V0VGFzayxcbiAgY2xlYXI6IGNsZWFyVGFza1xufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL190YXNrLmpzXG4gKiovIiwiLy8gZmFzdCBhcHBseSwgaHR0cDovL2pzcGVyZi5sbmtpdC5jb20vZmFzdC1hcHBseS81XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZuLCBhcmdzLCB0aGF0KXtcbiAgdmFyIHVuID0gdGhhdCA9PT0gdW5kZWZpbmVkO1xuICBzd2l0Y2goYXJncy5sZW5ndGgpe1xuICAgIGNhc2UgMDogcmV0dXJuIHVuID8gZm4oKVxuICAgICAgICAgICAgICAgICAgICAgIDogZm4uY2FsbCh0aGF0KTtcbiAgICBjYXNlIDE6IHJldHVybiB1biA/IGZuKGFyZ3NbMF0pXG4gICAgICAgICAgICAgICAgICAgICAgOiBmbi5jYWxsKHRoYXQsIGFyZ3NbMF0pO1xuICAgIGNhc2UgMjogcmV0dXJuIHVuID8gZm4oYXJnc1swXSwgYXJnc1sxXSlcbiAgICAgICAgICAgICAgICAgICAgICA6IGZuLmNhbGwodGhhdCwgYXJnc1swXSwgYXJnc1sxXSk7XG4gICAgY2FzZSAzOiByZXR1cm4gdW4gPyBmbihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKVxuICAgICAgICAgICAgICAgICAgICAgIDogZm4uY2FsbCh0aGF0LCBhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICBjYXNlIDQ6IHJldHVybiB1biA/IGZuKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10pXG4gICAgICAgICAgICAgICAgICAgICAgOiBmbi5jYWxsKHRoYXQsIGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10pO1xuICB9IHJldHVybiAgICAgICAgICAgICAgZm4uYXBwbHkodGhhdCwgYXJncyk7XG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX2ludm9rZS5qc1xuICoqLyIsInZhciBnbG9iYWwgICAgPSByZXF1aXJlKCcuL19nbG9iYWwnKVxuICAsIG1hY3JvdGFzayA9IHJlcXVpcmUoJy4vX3Rhc2snKS5zZXRcbiAgLCBPYnNlcnZlciAgPSBnbG9iYWwuTXV0YXRpb25PYnNlcnZlciB8fCBnbG9iYWwuV2ViS2l0TXV0YXRpb25PYnNlcnZlclxuICAsIHByb2Nlc3MgICA9IGdsb2JhbC5wcm9jZXNzXG4gICwgUHJvbWlzZSAgID0gZ2xvYmFsLlByb21pc2VcbiAgLCBpc05vZGUgICAgPSByZXF1aXJlKCcuL19jb2YnKShwcm9jZXNzKSA9PSAncHJvY2VzcydcbiAgLCBoZWFkLCBsYXN0LCBub3RpZnk7XG5cbnZhciBmbHVzaCA9IGZ1bmN0aW9uKCl7XG4gIHZhciBwYXJlbnQsIGZuO1xuICBpZihpc05vZGUgJiYgKHBhcmVudCA9IHByb2Nlc3MuZG9tYWluKSlwYXJlbnQuZXhpdCgpO1xuICB3aGlsZShoZWFkKXtcbiAgICBmbiA9IGhlYWQuZm47XG4gICAgZm4oKTsgLy8gPC0gY3VycmVudGx5IHdlIHVzZSBpdCBvbmx5IGZvciBQcm9taXNlIC0gdHJ5IC8gY2F0Y2ggbm90IHJlcXVpcmVkXG4gICAgaGVhZCA9IGhlYWQubmV4dDtcbiAgfSBsYXN0ID0gdW5kZWZpbmVkO1xuICBpZihwYXJlbnQpcGFyZW50LmVudGVyKCk7XG59O1xuXG4vLyBOb2RlLmpzXG5pZihpc05vZGUpe1xuICBub3RpZnkgPSBmdW5jdGlvbigpe1xuICAgIHByb2Nlc3MubmV4dFRpY2soZmx1c2gpO1xuICB9O1xuLy8gYnJvd3NlcnMgd2l0aCBNdXRhdGlvbk9ic2VydmVyXG59IGVsc2UgaWYoT2JzZXJ2ZXIpe1xuICB2YXIgdG9nZ2xlID0gdHJ1ZVxuICAgICwgbm9kZSAgID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoJycpO1xuICBuZXcgT2JzZXJ2ZXIoZmx1c2gpLm9ic2VydmUobm9kZSwge2NoYXJhY3RlckRhdGE6IHRydWV9KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1uZXdcbiAgbm90aWZ5ID0gZnVuY3Rpb24oKXtcbiAgICBub2RlLmRhdGEgPSB0b2dnbGUgPSAhdG9nZ2xlO1xuICB9O1xuLy8gZW52aXJvbm1lbnRzIHdpdGggbWF5YmUgbm9uLWNvbXBsZXRlbHkgY29ycmVjdCwgYnV0IGV4aXN0ZW50IFByb21pc2Vcbn0gZWxzZSBpZihQcm9taXNlICYmIFByb21pc2UucmVzb2x2ZSl7XG4gIG5vdGlmeSA9IGZ1bmN0aW9uKCl7XG4gICAgUHJvbWlzZS5yZXNvbHZlKCkudGhlbihmbHVzaCk7XG4gIH07XG4vLyBmb3Igb3RoZXIgZW52aXJvbm1lbnRzIC0gbWFjcm90YXNrIGJhc2VkIG9uOlxuLy8gLSBzZXRJbW1lZGlhdGVcbi8vIC0gTWVzc2FnZUNoYW5uZWxcbi8vIC0gd2luZG93LnBvc3RNZXNzYWdcbi8vIC0gb25yZWFkeXN0YXRlY2hhbmdlXG4vLyAtIHNldFRpbWVvdXRcbn0gZWxzZSB7XG4gIG5vdGlmeSA9IGZ1bmN0aW9uKCl7XG4gICAgLy8gc3RyYW5nZSBJRSArIHdlYnBhY2sgZGV2IHNlcnZlciBidWcgLSB1c2UgLmNhbGwoZ2xvYmFsKVxuICAgIG1hY3JvdGFzay5jYWxsKGdsb2JhbCwgZmx1c2gpO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZuKXtcbiAgdmFyIHRhc2sgPSB7Zm46IGZuLCBuZXh0OiB1bmRlZmluZWR9O1xuICBpZihsYXN0KWxhc3QubmV4dCA9IHRhc2s7XG4gIGlmKCFoZWFkKXtcbiAgICBoZWFkID0gdGFzaztcbiAgICBub3RpZnkoKTtcbiAgfSBsYXN0ID0gdGFzaztcbn07XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9fbWljcm90YXNrLmpzXG4gKiovIiwidmFyIHJlZGVmaW5lID0gcmVxdWlyZSgnLi9fcmVkZWZpbmUnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24odGFyZ2V0LCBzcmMsIHNhZmUpe1xuICBmb3IodmFyIGtleSBpbiBzcmMpcmVkZWZpbmUodGFyZ2V0LCBrZXksIHNyY1trZXldLCBzYWZlKTtcbiAgcmV0dXJuIHRhcmdldDtcbn07XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9fcmVkZWZpbmUtYWxsLmpzXG4gKiovIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGdsb2JhbCAgICAgID0gcmVxdWlyZSgnLi9fZ2xvYmFsJylcbiAgLCBkUCAgICAgICAgICA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpXG4gICwgREVTQ1JJUFRPUlMgPSByZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpXG4gICwgU1BFQ0lFUyAgICAgPSByZXF1aXJlKCcuL193a3MnKSgnc3BlY2llcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKEtFWSl7XG4gIHZhciBDID0gZ2xvYmFsW0tFWV07XG4gIGlmKERFU0NSSVBUT1JTICYmIEMgJiYgIUNbU1BFQ0lFU10pZFAuZihDLCBTUEVDSUVTLCB7XG4gICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgIGdldDogZnVuY3Rpb24oKXsgcmV0dXJuIHRoaXM7IH1cbiAgfSk7XG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX3NldC1zcGVjaWVzLmpzXG4gKiovIiwidmFyIElURVJBVE9SICAgICA9IHJlcXVpcmUoJy4vX3drcycpKCdpdGVyYXRvcicpXG4gICwgU0FGRV9DTE9TSU5HID0gZmFsc2U7XG5cbnRyeSB7XG4gIHZhciByaXRlciA9IFs3XVtJVEVSQVRPUl0oKTtcbiAgcml0ZXJbJ3JldHVybiddID0gZnVuY3Rpb24oKXsgU0FGRV9DTE9TSU5HID0gdHJ1ZTsgfTtcbiAgQXJyYXkuZnJvbShyaXRlciwgZnVuY3Rpb24oKXsgdGhyb3cgMjsgfSk7XG59IGNhdGNoKGUpeyAvKiBlbXB0eSAqLyB9XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZXhlYywgc2tpcENsb3Npbmcpe1xuICBpZighc2tpcENsb3NpbmcgJiYgIVNBRkVfQ0xPU0lORylyZXR1cm4gZmFsc2U7XG4gIHZhciBzYWZlID0gZmFsc2U7XG4gIHRyeSB7XG4gICAgdmFyIGFyciAgPSBbN11cbiAgICAgICwgaXRlciA9IGFycltJVEVSQVRPUl0oKTtcbiAgICBpdGVyLm5leHQgPSBmdW5jdGlvbigpeyBzYWZlID0gdHJ1ZTsgfTtcbiAgICBhcnJbSVRFUkFUT1JdID0gZnVuY3Rpb24oKXsgcmV0dXJuIGl0ZXI7IH07XG4gICAgZXhlYyhhcnIpO1xuICB9IGNhdGNoKGUpeyAvKiBlbXB0eSAqLyB9XG4gIHJldHVybiBzYWZlO1xufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19pdGVyLWRldGVjdC5qc1xuICoqLyIsImNvbnN0IHtcbiAgc2V0VGltZW91dCwgc2V0VGltZW91dE5hdGl2ZVxufSA9IGdsb2JhbFxuXG4vLyBmaXggbm8gc2V0VGltZW91dCBvbiBBbmRyb2lkIFY4XG5pZiAodHlwZW9mIHNldFRpbWVvdXQgPT09ICd1bmRlZmluZWQnICYmXG4gIHR5cGVvZiBzZXRUaW1lb3V0TmF0aXZlID09PSAnZnVuY3Rpb24nKSB7XG4gIGNvbnN0IHRpbWVvdXRNYXAgPSB7fVxuICBsZXQgdGltZW91dElkID0gMFxuICBnbG9iYWwuc2V0VGltZW91dCA9IChjYiwgdGltZSkgPT4ge1xuICAgIHRpbWVvdXRNYXBbKyt0aW1lb3V0SWRdID0gY2JcbiAgICBzZXRUaW1lb3V0TmF0aXZlKHRpbWVvdXRJZC50b1N0cmluZygpLCB0aW1lKVxuICB9XG4gIGdsb2JhbC5zZXRUaW1lb3V0Q2FsbGJhY2sgPSAoaWQpID0+IHtcbiAgICBpZiAodHlwZW9mIHRpbWVvdXRNYXBbaWRdID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aW1lb3V0TWFwW2lkXSgpXG4gICAgICBkZWxldGUgdGltZW91dE1hcFtpZF1cbiAgICB9XG4gIH1cbn1cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL3BvbHlmaWxsL3NldFRpbWVvdXQuanNcbiAqKi8iLCJjb25zdCB7Y29uc29sZX0gPSBnbG9iYWxcblxuaWYgKHR5cGVvZiBjb25zb2xlID09PSAndW5kZWZpbmVkJykge1xuICBnbG9iYWwuY29uc29sZSA9IHtcbiAgICBsb2c6ICguLi5hcmdzKSA9PiB7XG4gICAgICBpZiAodHlwZW9mIG5hdGl2ZUxvZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBuYXRpdmVMb2coLi4uYXJncylcbiAgICAgIH1cbiAgICB9LFxuICAgIGVycm9yOiAoLi4uYXJncykgPT4ge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGFyZ3MpXG4gICAgfVxuICB9XG59XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9wb2x5ZmlsbC9jb25zb2xlbG9nLmpzXG4gKiovIiwiLyoqXG4gKiBAZmlsZU92ZXJ2aWV3IE1haW4gZW50cnksIGluc3RhbmNlIG1hbmFnZXJcbiAqXG4gKiAtIGNyZWF0ZUluc3RhbmNlKGluc3RhbmNlSWQsIGNvZGUsIG9wdGlvbnMsIGRhdGEpXG4gKiAtIHJlZnJlc2hJbnN0YW5jZShpbnN0YW5jZUlkLCBkYXRhKVxuICogLSBkZXN0cm95SW5zdGFuY2UoaW5zdGFuY2VJZClcbiAqIC0gcmVnaXN0ZXJDb21wb25lbnRzKGNvbXBvbmVudHMpXG4gKiAtIHJlZ2lzdGVyTW9kdWxlcyhtb2R1bGVzKVxuICogLSBnZXRSb290KGluc3RhbmNlSWQpXG4gKiAtIGluc3RhbmNlTWFwXG4gKiAtIGNhbGxKUyhpbnN0YW5jZUlkLCB0YXNrcylcbiAqICAgLSBmaXJlRXZlbnQocmVmLCB0eXBlLCBkYXRhKVxuICogICAtIGNhbGxiYWNrKGZ1bmNJZCwgZGF0YSlcbiAqL1xuXG5pbXBvcnQgKiBhcyBwZXJmIGZyb20gJy4vcGVyZidcbmltcG9ydCAqIGFzIGNvbmZpZyBmcm9tICcuL2NvbmZpZydcbmltcG9ydCBBcHBJbnN0YW5jZSBmcm9tICcuL2FwcCdcbmltcG9ydCBWbSBmcm9tICcuL3ZtJ1xuXG52YXIge1xuICBuYXRpdmVDb21wb25lbnRNYXBcbn0gPSBjb25maWdcbnZhciBpbnN0YW5jZU1hcCA9IHt9XG5cbi8qKlxuICogY3JlYXRlIGEgV2VleCBpbnN0YW5jZVxuICpcbiAqIEBwYXJhbSAge3N0cmluZ30gaW5zdGFuY2VJZFxuICogQHBhcmFtICB7c3RyaW5nfSBjb2RlXG4gKiBAcGFyYW0gIHtvYmplY3R9IFtvcHRpb25zXSBvcHRpb24gYEhBU19MT0dgIGVuYWJsZSBwcmludCBsb2dcbiAqIEBwYXJhbSAge29iamVjdH0gW2RhdGFdXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVJbnN0YW5jZShpbnN0YW5jZUlkLCBjb2RlLCBvcHRpb25zLCBkYXRhKSB7XG4gIHZhciBpbnN0YW5jZSA9IGluc3RhbmNlTWFwW2luc3RhbmNlSWRdXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9XG5cbiAgY29uZmlnLmRlYnVnID0gb3B0aW9ucy5kZWJ1Z1xuXG4gIHZhciByZXN1bHRcbiAgaWYgKCFpbnN0YW5jZSkge1xuICAgIHBlcmYuc3RhcnQoJ2NyZWF0ZUluc3RhbmNlJywgaW5zdGFuY2VJZClcbiAgICBpbnN0YW5jZSA9IG5ldyBBcHBJbnN0YW5jZShpbnN0YW5jZUlkLCBvcHRpb25zKVxuICAgIGluc3RhbmNlTWFwW2luc3RhbmNlSWRdID0gaW5zdGFuY2VcbiAgICByZXN1bHQgPSBpbnN0YW5jZS5pbml0KGNvZGUsIGRhdGEpXG4gICAgcGVyZi5lbmQoJ2NyZWF0ZUluc3RhbmNlJywgaW5zdGFuY2VJZClcbiAgfSBlbHNlIHtcbiAgICByZXN1bHQgPSBuZXcgRXJyb3IoYGludmFsaWQgaW5zdGFuY2UgaWQgXCIke2luc3RhbmNlSWR9XCJgKVxuICB9XG5cbiAgcmV0dXJuIHJlc3VsdFxufVxuXG4vKipcbiAqIHJlZnJlc2ggYSBXZWV4IGluc3RhbmNlXG4gKlxuICogQHBhcmFtICB7c3RyaW5nfSBpbnN0YW5jZUlkXG4gKiBAcGFyYW0gIHtvYmplY3R9IGRhdGFcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZnJlc2hJbnN0YW5jZShpbnN0YW5jZUlkLCBkYXRhKSB7XG4gIHZhciBpbnN0YW5jZSA9IGluc3RhbmNlTWFwW2luc3RhbmNlSWRdXG4gIHZhciByZXN1bHRcbiAgaWYgKGluc3RhbmNlKSB7XG4gICAgcGVyZi5zdGFydCgncmVmcmVzaERhdGEnLCBpbnN0YW5jZUlkKVxuICAgIHJlc3VsdCA9IGluc3RhbmNlLnJlZnJlc2hEYXRhKGRhdGEpXG4gICAgcGVyZi5lbmQoJ3JlZnJlc2hEYXRhJywgaW5zdGFuY2VJZClcbiAgfSBlbHNlIHtcbiAgICByZXN1bHQgPSBuZXcgRXJyb3IoYGludmFsaWQgaW5zdGFuY2UgaWQgXCIke2luc3RhbmNlSWR9XCJgKVxuICB9XG4gIHJldHVybiByZXN1bHRcbn1cblxuLyoqXG4gKiBkZXN0cm95IGEgV2VleCBpbnN0YW5jZVxuICogQHBhcmFtICB7c3RyaW5nfSBpbnN0YW5jZUlkXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZXN0cm95SW5zdGFuY2UoaW5zdGFuY2VJZCkge1xuICB2YXIgaW5zdGFuY2UgPSBpbnN0YW5jZU1hcFtpbnN0YW5jZUlkXVxuICBpZiAoIWluc3RhbmNlKSB7XG4gICAgcmV0dXJuIG5ldyBFcnJvcihgaW52YWxpZCBpbnN0YW5jZSBpZCBcIiR7aW5zdGFuY2VJZH1cImApXG4gIH1cblxuICBwZXJmLnN0YXJ0KCdkZXN0cm95SW5zdGFuY2UnLCBpbnN0YW5jZUlkKVxuICBpbnN0YW5jZS5kZXN0cm95KClcbiAgZGVsZXRlIGluc3RhbmNlTWFwW2luc3RhbmNlSWRdXG4gIHBlcmYuZW5kKCdkZXN0cm95SW5zdGFuY2UnLCBpbnN0YW5jZUlkKVxuXG4gIHJldHVybiBpbnN0YW5jZU1hcFxufVxuXG4vKipcbiAqIHJlZ2lzdGVyIHRoZSBuYW1lIG9mIGVhY2ggbmF0aXZlIGNvbXBvbmVudFxuICogQHBhcmFtICB7YXJyYXl9IGNvbXBvbmVudHMgYXJyYXkgb2YgbmFtZVxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXJDb21wb25lbnRzKGNvbXBvbmVudHMpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkoY29tcG9uZW50cykpIHtcbiAgICBjb21wb25lbnRzLmZvckVhY2goZnVuY3Rpb24gcmVnaXN0ZXIobmFtZSkge1xuICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIG5hbWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIG5hdGl2ZUNvbXBvbmVudE1hcFtuYW1lXSA9IHRydWVcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIG5hbWUgPT09ICdvYmplY3QnICYmIHR5cGVvZiBuYW1lLnR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIG5hdGl2ZUNvbXBvbmVudE1hcFtuYW1lLnR5cGVdID0gbmFtZVxuICAgICAgfVxuICAgIH0pXG4gIH1cbn1cblxuLyoqXG4gKiByZWdpc3RlciB0aGUgbmFtZSBhbmQgbWV0aG9kcyBvZiBlYWNoIG1vZHVsZVxuICogQHBhcmFtICB7b2JqZWN0fSBtb2R1bGVzIGEgb2JqZWN0IG9mIG1vZHVsZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyTW9kdWxlcyhtb2R1bGVzKSB7XG4gIGlmICh0eXBlb2YgbW9kdWxlcyA9PT0gJ29iamVjdCcpIHtcbiAgICBWbS5yZWdpc3Rlck1vZHVsZXMobW9kdWxlcylcbiAgfVxufVxuXG4vKipcbiAqIHJlZ2lzdGVyIHRoZSBuYW1lIGFuZCBtZXRob2RzIG9mIGVhY2ggYXBpXG4gKiBAcGFyYW0gIHtvYmplY3R9IGFwaXMgYSBvYmplY3Qgb2YgYXBpc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXJNZXRob2RzKGFwaXMpIHtcbiAgaWYgKHR5cGVvZiBhcGlzID09PSAnb2JqZWN0Jykge1xuICAgIFZtLnJlZ2lzdGVyTWV0aG9kcyhhcGlzKVxuICB9XG59XG5cbi8qKlxuICogZ2V0IGEgd2hvbGUgZWxlbWVudCB0cmVlIG9mIGFuIGluc3RhbmNlXG4gKiBmb3IgZGVidWdnaW5nXG4gKiBAcGFyYW0gIHtzdHJpbmd9IGluc3RhbmNlSWRcbiAqIEByZXR1cm4ge29iamVjdH0gYSB2aXJ0dWFsIGRvbSB0cmVlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRSb290KGluc3RhbmNlSWQpIHtcbiAgdmFyIGluc3RhbmNlID0gaW5zdGFuY2VNYXBbaW5zdGFuY2VJZF1cbiAgdmFyIHJlc3VsdFxuICBpZiAoaW5zdGFuY2UpIHtcbiAgICByZXN1bHQgPSBpbnN0YW5jZS5nZXRSb290RWxlbWVudCgpXG4gIH0gZWxzZSB7XG4gICAgcmVzdWx0ID0gbmV3IEVycm9yKGBpbnZhbGlkIGluc3RhbmNlIGlkIFwiJHtpbnN0YW5jZUlkfVwiYClcbiAgfVxuICByZXR1cm4gcmVzdWx0XG59XG5cbnZhciBqc0hhbmRsZXJzID0ge1xuICBmaXJlRXZlbnQ6IGZ1bmN0aW9uIGZpcmVFdmVudChpbnN0YW5jZUlkLCByZWYsIHR5cGUsIGRhdGEpIHtcbiAgICB2YXIgaW5zdGFuY2UgPSBpbnN0YW5jZU1hcFtpbnN0YW5jZUlkXVxuICAgIHZhciByZXN1bHRcbiAgICBwZXJmLnN0YXJ0KCdmaXJlRXZlbnQnLCBpbnN0YW5jZUlkICsgJy0nICsgcmVmICsgJy0nICsgdHlwZSlcbiAgICByZXN1bHQgPSBpbnN0YW5jZS5maXJlRXZlbnQocmVmLCB0eXBlLCBkYXRhKVxuICAgIHBlcmYuZW5kKCdmaXJlRXZlbnQnLCBpbnN0YW5jZUlkICsgJy0nICsgcmVmICsgJy0nICsgdHlwZSlcbiAgICByZXR1cm4gcmVzdWx0XG4gIH0sXG5cbiAgY2FsbGJhY2s6IGZ1bmN0aW9uIGNhbGxiYWNrKGluc3RhbmNlSWQsIGZ1bmNJZCwgZGF0YSwgaWZMYXN0KSB7XG4gICAgdmFyIGluc3RhbmNlID0gaW5zdGFuY2VNYXBbaW5zdGFuY2VJZF1cbiAgICB2YXIgcmVzdWx0XG4gICAgcGVyZi5zdGFydCgnY2FsbGJhY2snLFxuICAgICAgaW5zdGFuY2VJZCArICctJyArIGZ1bmNJZCArICctJyArIGRhdGEgKyAnLScgKyBpZkxhc3QpXG4gICAgcmVzdWx0ID0gaW5zdGFuY2UuY2FsbGJhY2soZnVuY0lkLCBkYXRhLCBpZkxhc3QpXG4gICAgcGVyZi5lbmQoJ2NhbGxiYWNrJyxcbiAgICAgIGluc3RhbmNlSWQgKyAnLScgKyBmdW5jSWQgKyAnLScgKyBkYXRhICsgJy0nICsgaWZMYXN0KVxuICAgIHJldHVybiByZXN1bHRcbiAgfVxufVxuXG4vKipcbiAqIGFjY2VwdCBjYWxscyBmcm9tIG5hdGl2ZSAoZXZlbnQgb3IgY2FsbGJhY2spXG4gKlxuICogQHBhcmFtICB7c3RyaW5nfSBpbnN0YW5jZUlkXG4gKiBAcGFyYW0gIHthcnJheX0gdGFza3MgbGlzdCB3aXRoIGBtZXRob2RgIGFuZCBgYXJnc2BcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhbGxKUyhpbnN0YW5jZUlkLCB0YXNrcykge1xuICBjb25zdCBpbnN0YW5jZSA9IGluc3RhbmNlTWFwW2luc3RhbmNlSWRdXG4gIGxldCByZXN1bHRzID0gW11cbiAgaWYgKGluc3RhbmNlICYmIEFycmF5LmlzQXJyYXkodGFza3MpKSB7XG4gICAgdGFza3MuZm9yRWFjaCgodGFzaykgPT4ge1xuICAgICAgY29uc3QgaGFuZGxlciA9IGpzSGFuZGxlcnNbdGFzay5tZXRob2RdXG4gICAgICBjb25zdCBhcmdzID0gWy4uLnRhc2suYXJnc11cbiAgICAgIGlmICh0eXBlb2YgaGFuZGxlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBsb2coJ2phdmFzY3JpcHQ6JywgdGFzay5tZXRob2QsIHRhc2suYXJncylcbiAgICAgICAgYXJncy51bnNoaWZ0KGluc3RhbmNlSWQpXG4gICAgICAgIHJlc3VsdHMucHVzaChoYW5kbGVyKC4uLmFyZ3MpKVxuICAgICAgfVxuICAgIH0pXG4gIH0gZWxzZSB7XG4gICAgcmVzdWx0cy5wdXNoKG5ldyBFcnJvcihgaW52YWxpZCBpbnN0YW5jZSBpZCBcIiR7aW5zdGFuY2VJZH1cIiBvciB0YXNrc2ApKVxuICB9XG5cbiAgcmV0dXJuIHJlc3VsdHNcbn1cblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vbGliL2ZyYW1ld29yay5qc1xuICoqLyIsImltcG9ydCBsb2cgZnJvbSAnLi9sb2cnXG5cbnZhciBkYXRhID0ge3R5cGU6ICdyb290JywgY2hpbGRyZW46IFtdfVxudmFyIGN1cnJlbnQgPSBkYXRhXG52YXIgc3RhY2sgPSBbY3VycmVudF1cblxuZnVuY3Rpb24gc3BhY2VzKG51bSkge1xuICByZXR1cm4gQXJyYXkobnVtKS5qb2luKCcgJylcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHN0YXJ0KHR5cGUsIGlkKSB7XG4gIHZhciB0YXNrID0ge3R5cGU6IHR5cGUsIGlkOiBpZCwgY2hpbGRyZW46IFtdLCBzdGFydDogRGF0ZS5ub3coKX1cbiAgY3VycmVudC5jaGlsZHJlbi5wdXNoKHRhc2spXG4gIHN0YWNrLnB1c2godGFzaylcbiAgY3VycmVudCA9IHRhc2tcbiAgbG9nKCdwZXJmOicgKyBzcGFjZXMoc3RhY2subGVuZ3RoIC0gMSksICdzdGFydCcsIHRhc2sudHlwZSwgdGFzay5pZClcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGVuZCh0eXBlLCBpZCkge1xuICB2YXIgdGFzayA9IHN0YWNrLnBvcCgpXG4gIHRhc2suZW5kID0gRGF0ZS5ub3coKVxuICBjdXJyZW50ID0gc3RhY2tbc3RhY2subGVuZ3RoIC0gMV1cbiAgbG9nKCdwZXJmOicgKyBzcGFjZXMoc3RhY2subGVuZ3RoKSwgJ2VuZCcsXG4gICAgKHRhc2suZW5kIC0gdGFzay5zdGFydCkgKyAnbXMnLCB0YXNrLnR5cGUsIHRhc2suaWQpXG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZXNldCgpIHtcbiAgZGF0YS5jaGlsZHJlbiA9IFtdXG4gIGN1cnJlbnQgPSBkYXRhXG4gIHN0YWNrLmxlbmd0aCA9IDBcbiAgc3RhY2sucHVzaChjdXJyZW50KVxufVxuXG5leHBvcnQgZnVuY3Rpb24gdG9KU09OKCkge1xuICByZXR1cm4gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShkYXRhKSlcbn1cblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vbGliL3BlcmYuanNcbiAqKi8iLCJpbXBvcnQgKiBhcyBjb25maWcgZnJvbSAnLi9jb25maWcnXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGxvZyguLi5hcmdzKSB7XG4gIGlmIChjb25maWcuZGVidWcpIHtcbiAgICBnbG9iYWwuY29uc29sZS5sb2coLi4uYXJncylcbiAgfVxufVxuXG5nbG9iYWwubG9nID0gbG9nXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9saWIvbG9nLmpzXG4gKiovIiwiZXhwb3J0IGNvbnN0IG5hdGl2ZUNvbXBvbmVudE1hcCA9IHtcbiAgdGV4dDogdHJ1ZSxcbiAgaW1hZ2U6IHRydWUsXG4gIGNvbnRhaW5lcjogdHJ1ZSxcbiAgc2xpZGVyOiB7XG4gICAgdHlwZTogJ3NsaWRlcicsXG4gICAgYXBwZW5kOiAndHJlZSdcbiAgfSxcbiAgY2VsbDoge1xuICAgIHR5cGU6ICdjZWxsJyxcbiAgICBhcHBlbmQ6ICd0cmVlJ1xuICB9XG59XG5cbmV4cG9ydCBjb25zdCBjdXN0b21Db21wb25lbnRNYXAgPSB7fVxuXG5leHBvcnQgdmFyIGRlYnVnID0gZmFsc2VcblxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9saWIvY29uZmlnLmpzXG4gKiovIiwiLyoqXG4gKiBAZmlsZU92ZXJ2aWV3XG4gKiBXZWV4IGluc3RhbmNlIGNvbnN0cnVjdG9yICYgZGVmaW5pdGlvblxuICovXG5cbmltcG9ydCB7dHlwb2YsIGV4dGVuZH0gZnJvbSAnLi4vdXRpbCdcbmltcG9ydCAqIGFzIHBlcmYgZnJvbSAnLi4vcGVyZidcbmltcG9ydCAqIGFzIGJ1bmRsZSBmcm9tICcuL2J1bmRsZSdcbmltcG9ydCAqIGFzIGN0cmwgZnJvbSAnLi9jdHJsJ1xuaW1wb3J0IERpZmZlciBmcm9tICcuL2RpZmZlcidcblxuaW1wb3J0IEV2ZW50TWFuYWdlciBmcm9tICcuL2V2ZW50J1xuaW1wb3J0IExpc3RlbmVyIGZyb20gJy4vZG9tLWxpc3RlbmVyJ1xuaW1wb3J0IHtEb2N1bWVudCwgTm9kZX0gZnJvbSAnLi9kb20nXG5pbXBvcnQge3JlZ2lzdGVyQ29tcG9uZW50LCByZXF1aXJlQ29tcG9uZW50LCByZXF1aXJlTW9kdWxlfSBmcm9tICcuL3JlZ2lzdGVyJ1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBBcHBJbnN0YW5jZShpbnN0YW5jZUlkLCBvcHRpb25zKSB7XG4gIHBlcmYuc3RhcnQoJ2luaXRJbnN0YW5jZScsIGluc3RhbmNlSWQpXG4gIHRoaXMuaWQgPSBpbnN0YW5jZUlkXG4gIHRoaXMub3B0aW9ucyA9IG9wdGlvbnMgfHwge31cbiAgdGhpcy52bSA9IG51bGxcbiAgdGhpcy5kb2MgPSBuZXcgRG9jdW1lbnQoaW5zdGFuY2VJZClcbiAgdGhpcy5jdXN0b21Db21wb25lbnRNYXAgPSB7fVxuICB0aGlzLmNhbGxiYWNrcyA9IHt9XG4gIHRoaXMuZGlmZmVyID0gbmV3IERpZmZlcihpbnN0YW5jZUlkKVxuICB0aGlzLnVpZCA9IDBcbiAgdGhpcy5yZW5kZXJlZCA9IGZhbHNlXG4gIHRoaXMuZXZlbnRNYW5hZ2VyID0gbmV3IEV2ZW50TWFuYWdlcigpXG4gIHRoaXMubGlzdGVuZXIgPSBuZXcgTGlzdGVuZXIodGhpcy5pZCwgKHRhc2tzKSA9PiB7XG4gICAgdGhpcy5jYWxsVGFza3ModGFza3MpXG4gIH0pXG4gIHRoaXMuZG9jLnNldEV2ZW50TWFuYWdlcih0aGlzLmV2ZW50TWFuYWdlcilcbiAgdGhpcy5kb2Muc2V0TGlzdGVuZXIodGhpcy5saXN0ZW5lcilcblxuICBwZXJmLmVuZCgnaW5pdEluc3RhbmNlJywgaW5zdGFuY2VJZClcbn1cblxuZnVuY3Rpb24gbm9ybWFsaXplKGFwcCwgdikge1xuICB2YXIgdHlwZSA9IHR5cG9mKHYpXG5cbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSAndW5kZWZpbmVkJzpcbiAgICBjYXNlICdudWxsJzpcbiAgICAgIHJldHVybiAnJ1xuICAgIGNhc2UgJ3JlZ2V4cCc6XG4gICAgICByZXR1cm4gdi50b1N0cmluZygpXG4gICAgY2FzZSAnZGF0ZSc6XG4gICAgICByZXR1cm4gdi50b0lTT1N0cmluZygpXG4gICAgY2FzZSAnbnVtYmVyJzpcbiAgICBjYXNlICdzdHJpbmcnOlxuICAgIGNhc2UgJ2Jvb2xlYW4nOlxuICAgIGNhc2UgJ2FycmF5JzpcbiAgICBjYXNlICdvYmplY3QnOlxuICAgICAgaWYgKHYgaW5zdGFuY2VvZiBOb2RlKSB7XG4gICAgICAgIHJldHVybiB2LnJlZlxuICAgICAgfVxuICAgICAgcmV0dXJuIHZcbiAgICBjYXNlICdmdW5jdGlvbic6XG4gICAgICBhcHAuY2FsbGJhY2tzWysrYXBwLnVpZF0gPSB2XG4gICAgICByZXR1cm4gYXBwLnVpZC50b1N0cmluZygpXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh2KVxuICB9XG59XG5cbkFwcEluc3RhbmNlLnByb3RvdHlwZS5jYWxsVGFza3MgPSBmdW5jdGlvbiAodGFza3MpIHtcbiAgaWYgKHR5cG9mKHRhc2tzKSAhPT0gJ2FycmF5Jykge1xuICAgIHRhc2tzID0gW3Rhc2tzXVxuICB9XG5cbiAgdGFza3MuZm9yRWFjaCgodGFzaykgPT4ge1xuICAgIHRhc2suYXJncyA9IHRhc2suYXJncy5tYXAoYXJnID0+IG5vcm1hbGl6ZSh0aGlzLCBhcmcpKVxuICB9KVxuXG4gIGNhbGxOYXRpdmUodGhpcy5pZCwgdGFza3MsICctMScpXG59XG5cbmV4dGVuZChBcHBJbnN0YW5jZS5wcm90b3R5cGUsIGJ1bmRsZSwgY3RybCwge1xuICByZWdpc3RlckNvbXBvbmVudCxcbiAgcmVxdWlyZUNvbXBvbmVudCxcbiAgcmVxdWlyZU1vZHVsZVxufSlcblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vbGliL2FwcC9pbmRleC5qc1xuICoqLyIsIi8vLyBsYW5nLmpzXG5pbXBvcnQgQ29uZmlnIGZyb20gJy4uL2NvbmZpZydcblxuLyoqXG4gKiBDaGVjayBpcyBhIHN0cmluZyBzdGFydHMgd2l0aCAkIG9yIF9cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5cbmV4cG9ydCB2YXIgaXNSZXNlcnZlZCA9IChzdHIpID0+IHtcbiAgbGV0IGMgPSAoc3RyICsgJycpLmNoYXJDb2RlQXQoMClcbiAgcmV0dXJuIGMgPT09IDB4MjQgfHwgYyA9PT0gMHg1RlxufVxuXG4vKipcbiAqIENhbWVsaXplIGEgaHlwaGVuLWRlbG1pdGVkIHN0cmluZy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKi9cblxubGV0IGNhbWVsUkUgPSAvLShcXHcpL2dcbmZ1bmN0aW9uIHRvVXBwZXIgKF8sIGMpIHtcbiAgcmV0dXJuIGMgPyBjLnRvVXBwZXJDYXNlICgpIDogJydcbn1cbmV4cG9ydCB2YXIgY2FtZWxpemUgPSAoc3RyKSA9PiB7XG4gIHJldHVybiBzdHIucmVwbGFjZShjYW1lbFJFLCB0b1VwcGVyKVxufVxuXG4vKipcbiAqIFNpbXBsZSBiaW5kLCBmYXN0ZXIgdGhhbiBuYXRpdmVcbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHBhcmFtIHtPYmplY3R9IGN0eFxuICogQHJldHVybiB7RnVuY3Rpb259XG4gKi9cblxuZXhwb3J0IHZhciBiaW5kID0gZnVuY3Rpb24gKGZuLCBjdHgpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChhKSB7XG4gICAgbGV0IGwgPSBhcmd1bWVudHMubGVuZ3RoXG4gICAgcmV0dXJuIGxcbiAgICAgID8gbCA+IDFcbiAgICAgICAgPyBmbi5hcHBseShjdHgsIGFyZ3VtZW50cylcbiAgICAgICAgOiBmbi5jYWxsKGN0eCwgYSlcbiAgICAgIDogZm4uY2FsbChjdHgpXG4gIH1cbn1cblxuLyoqXG4gKiBDb252ZXJ0IGFuIEFycmF5LWxpa2Ugb2JqZWN0IHRvIGEgcmVhbCBBcnJheS5cbiAqXG4gKiBAcGFyYW0ge0FycmF5LWxpa2V9IGxpc3RcbiAqIEBwYXJhbSB7TnVtYmVyfSBbc3RhcnRdIC0gc3RhcnQgaW5kZXhcbiAqIEByZXR1cm4ge0FycmF5fVxuICovXG5cbmV4cG9ydCB2YXIgdG9BcnJheSA9IChsaXN0LCBzdGFydCkgPT4ge1xuICBzdGFydCA9IHN0YXJ0IHx8IDBcbiAgbGV0IGkgPSBsaXN0Lmxlbmd0aCAtIHN0YXJ0XG4gIGxldCByZXQgPSBuZXcgQXJyYXkoaSlcbiAgd2hpbGUgKGktLSkge1xuICAgIHJldFtpXSA9IGxpc3RbaSArIHN0YXJ0XVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuLyoqXG4gKiBNaXggcHJvcGVydGllcyBpbnRvIHRhcmdldCBvYmplY3QuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHRvXG4gKiBAcGFyYW0ge09iamVjdH0gZnJvbVxuICovXG5cbmV4cG9ydCB2YXIgZXh0ZW5kID0gKHRhcmdldCwgLi4uc3JjKSA9PiB7XG4gIGlmICh0eXBlb2YgT2JqZWN0LmFzc2lnbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIE9iamVjdC5hc3NpZ24odGFyZ2V0LCAuLi5zcmMpXG4gIH0gZWxzZSB7XG4gICAgY29uc3QgZmlyc3QgPSBzcmMuc2hpZnQoKVxuICAgIGZvciAoY29uc3Qga2V5IGluIGZpcnN0KSB7XG4gICAgICB0YXJnZXRba2V5XSA9IGZpcnN0W2tleV1cbiAgICB9XG4gICAgaWYgKHNyYy5sZW5ndGgpIHtcbiAgICAgIGV4dGVuZCh0YXJnZXQsIC4uLnNyYylcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRhcmdldFxufVxuXG4vKipcbiAqIFF1aWNrIG9iamVjdCBjaGVjayAtIHRoaXMgaXMgcHJpbWFyaWx5IHVzZWQgdG8gdGVsbFxuICogT2JqZWN0cyBmcm9tIHByaW1pdGl2ZSB2YWx1ZXMgd2hlbiB3ZSBrbm93IHRoZSB2YWx1ZVxuICogaXMgYSBKU09OLWNvbXBsaWFudCB0eXBlLlxuICpcbiAqIEBwYXJhbSB7Kn0gb2JqXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5cbmV4cG9ydCB2YXIgaXNPYmplY3QgPSAob2JqKSA9PiB7XG4gIHJldHVybiAhIShvYmogJiYgdHlwZW9mIG9iaiA9PT0gJ29iamVjdCcpXG59XG5cbi8qKlxuICogU3RyaWN0IG9iamVjdCB0eXBlIGNoZWNrLiBPbmx5IHJldHVybnMgdHJ1ZVxuICogZm9yIHBsYWluIEphdmFTY3JpcHQgb2JqZWN0cy5cbiAqXG4gKiBAcGFyYW0geyp9IG9ialxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xuXG5sZXQgdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nXG5leHBvcnQgdmFyIGlzUGxhaW5PYmplY3QgPSAob2JqKSA9PiB7XG4gIHJldHVybiB0b1N0cmluZy5jYWxsKG9iaikgPT09ICdbb2JqZWN0IE9iamVjdF0nXG59XG5cbi8qKlxuICogQXJyYXkgdHlwZSBjaGVjay5cbiAqXG4gKiBAcGFyYW0geyp9IG9ialxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xuXG5leHBvcnQgdmFyIGlzQXJyYXkgPSAob2JqKSA9PiB7XG4gIHJldHVybiBBcnJheS5pc0FycmF5KG9iailcbn1cblxuZXhwb3J0IHZhciBzdHJpbmdpZnkgPSAoeCkgPT4ge1xuICByZXR1cm4gdHlwZW9mIHggPT09ICd1bmRlZmluZWQnIHx8IHggPT09IG51bGwgfHwgdHlwZW9mKHgpID09PSAnZnVuY3Rpb24nXG4gICAgPyAnJ1xuICAgIDogdHlwZW9mIHggPT09ICdvYmplY3QnXG4gICAgICA/IHggaW5zdGFuY2VvZiBSZWdFeHBcbiAgICAgICAgPyB4LnRvU3RyaW5nKClcbiAgICAgICAgOiB4IGluc3RhbmNlb2YgRGF0ZVxuICAgICAgICAgID8gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh4KSlcbiAgICAgICAgICA6IEpTT04uc3RyaW5naWZ5KHgpXG4gICAgICA6IHgudG9TdHJpbmcoKVxufVxuXG5leHBvcnQgdmFyIHR5cG9mID0gKHYpID0+IHtcbiAgbGV0IHMgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodilcbiAgcmV0dXJuIHMuc3Vic3RyaW5nKDgsIHMubGVuZ3RoIC0gMSkudG9Mb3dlckNhc2UoKVxufVxuXG5leHBvcnQgdmFyIG5vcm1hbGl6ZSA9ICh2KSA9PiB7XG4gIGxldCB0eXBlID0gdHlwb2YodilcblxuICBzd2l0Y2godHlwZSkge1xuICAgIGNhc2UgJ3VuZGVmaW5lZCc6XG4gICAgY2FzZSAnbnVsbCc6XG4gICAgICByZXR1cm4gJydcbiAgICBjYXNlICdyZWdleHAnOlxuICAgICAgcmV0dXJuIHYudG9TdHJpbmcoKVxuICAgIGNhc2UgJ2RhdGUnOlxuICAgICAgcmV0dXJuIHYudG9JU09TdHJpbmcoKVxuICAgIGNhc2UgJ251bWJlcic6XG4gICAgY2FzZSAnc3RyaW5nJzpcbiAgICBjYXNlICdib29sZWFuJzpcbiAgICBjYXNlICdhcnJheSc6XG4gICAgY2FzZSAnb2JqZWN0JzpcbiAgICBjYXNlICdmdW5jdGlvbic6XG4gICAgICByZXR1cm4gdlxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodilcbiAgfVxufVxuXG4vKipcbiAqIERlZmluZSBhIG5vbi1lbnVtZXJhYmxlIHByb3BlcnR5XG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICogQHBhcmFtIHtTdHJpbmd9IGtleVxuICogQHBhcmFtIHsqfSB2YWxcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gW2VudW1lcmFibGVdXG4gKi9cblxuZXhwb3J0IHZhciBkZWZpbmUgPSAob2JqLCBrZXksIHZhbCwgZW51bWVyYWJsZSkgPT4ge1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqLCBrZXksIHtcbiAgICB2YWx1ZTogdmFsLFxuICAgIGVudW1lcmFibGU6ICEhZW51bWVyYWJsZSxcbiAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICBjb25maWd1cmFibGU6IHRydWVcbiAgfSlcbn1cblxuLyoqXG4gKiBNYW51YWwgaW5kZXhPZiBiZWNhdXNlIGl0J3Mgc2xpZ2h0bHkgZmFzdGVyIHRoYW5cbiAqIG5hdGl2ZS5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJcbiAqIEBwYXJhbSB7Kn0gb2JqXG4gKi9cblxuZXhwb3J0IHZhciBpbmRleE9mID0gKGFyciwgb2JqKSA9PiB7XG4gIGZvciAobGV0IGkgPSAwLCBsID0gYXJyLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGlmIChhcnJbaV0gPT09IG9iaikgcmV0dXJuIGlcbiAgfVxuICByZXR1cm4gLTFcbn1cblxuXG4vLy8gZGVidWcuanNcblxuXG5jb25zdCBoYXNDb25zb2xlID0gdHlwZW9mIGNvbnNvbGUgIT09ICd1bmRlZmluZWQnXG5cbi8qKlxuICogTG9nIGEgbWVzc2FnZS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbXNnXG4gKi9cblxuZXhwb3J0IHZhciBsb2cgPSAobXNnKSA9PiB7XG4gIGNvbnN0IF9jb25maWcgPSBDb25maWcgfHwge31cbiAgaWYgKGhhc0NvbnNvbGUgJiYgX2NvbmZpZy5kZWJ1Zykge1xuICAgIGNvbnNvbGUubG9nLmNhbGwodGhpcywgJ1tpbmZvXTogJywgbXNnKVxuICB9XG59XG5cbi8qKlxuICogV2UndmUgZ290IGEgcHJvYmxlbSBoZXJlLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtc2dcbiAqL1xuXG5leHBvcnQgdmFyIHdhcm4gPSAobXNnKSA9PiB7XG4gIC8vIGlmIChoYXNDb25zb2xlICYmICghY29uZmlnLnNpbGVudCB8fCBjb25maWcuZGVidWcpKSB7XG4gIGlmIChoYXNDb25zb2xlKSB7XG4gICAgY29uc29sZS53YXJuLmNhbGwodGhpcywgJ1t3YXJuXTogJywgbXNnKVxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgIC8vIGlmIChjb25maWcuZGVidWcpIHtcbiAgICAvLyAgIC8qIGpzaGludCBkZWJ1ZzogdHJ1ZSAqL1xuICAgIC8vICAgZGVidWdnZXJcbiAgICAvLyB9XG4gIH1cbn1cblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vbGliL3V0aWwvaW5kZXguanNcbiAqKi8iLCIvKipcbiAqIEBmaWxlT3ZlcnZpZXdcbiAqIGFwaSB0aGF0IGludm9rZWQgYnkganMgYnVuZGxlIGNvZGVcbiAqXG4gKiAtIGRlZmluZShuYW1lLCBmYWN0b3J5KTogZGVmaW5lIGEgbmV3IGNvbXBvc2VkIGNvbXBvbmVudCB0eXBlXG4gKiAtIGJvb3RzdHJhcCh0eXBlLCBjb25maWcsIGRhdGEpOiByZXF1aXJlIGEgY2VydGFpbiB0eXBlICZcbiAqICAgICAgICAgcmVuZGVyIHdpdGggKG9wdGlvbmFsKSBkYXRhXG4gKlxuICogZGVwcmVjYXRlZDpcbiAqIC0gcmVnaXN0ZXIodHlwZSwgb3B0aW9ucyk6IHJlZ2lzdGVyIGEgbmV3IGNvbXBvc2VkIGNvbXBvbmVudCB0eXBlXG4gKiAtIHJlbmRlcih0eXBlLCBkYXRhKTogcmVuZGVyIGJ5IGEgY2VydGFpbiB0eXBlIHdpdGggKG9wdGlvbmFsKSBkYXRhXG4gKiAtIHJlcXVpcmUodHlwZSkoZGF0YSk6IHJlcXVpcmUgYSB0eXBlIHRoZW4gcmVuZGVyIHdpdGggZGF0YVxuICovXG5cbmltcG9ydCBzZW12ZXIgZnJvbSAnc2VtdmVyJ1xuaW1wb3J0ICogYXMgXyBmcm9tICcuLi91dGlsJ1xuaW1wb3J0ICogYXMgY29uZmlnIGZyb20gJy4uL2NvbmZpZydcbmltcG9ydCAqIGFzIHBlcmYgZnJvbSAnLi4vcGVyZidcbmltcG9ydCBWbSBmcm9tICcuLi92bSdcbmltcG9ydCAqIGFzIGRvd25ncmFkZSBmcm9tICcuL2Rvd25ncmFkZSdcblxuY29uc3QgV0VFWF9DT01QT05FTlRfUkVHID0gL15cXEB3ZWV4LWNvbXBvbmVudFxcLy9cbmNvbnN0IFdFRVhfTU9EVUxFX1JFRyA9IC9eXFxAd2VleC1tb2R1bGVcXC8vXG5jb25zdCBOT1JNQUxfTU9EVUxFX1JFRyA9IC9eXFwuezEsMn1cXC8vXG5jb25zdCBKU19TVVJGSVhfUkVHID0gL1xcLmpzJC9cblxuY29uc3QgaXNXZWV4Q29tcG9uZW50ID0gbmFtZSA9PiAhIW5hbWUubWF0Y2goV0VFWF9DT01QT05FTlRfUkVHKVxuY29uc3QgaXNXZWV4TW9kdWxlID0gbmFtZSA9PiAhIW5hbWUubWF0Y2goV0VFWF9NT0RVTEVfUkVHKVxuY29uc3QgaXNOb3JtYWxNb2R1bGUgPSBuYW1lID0+ICEhbmFtZS5tYXRjaChOT1JNQUxfTU9EVUxFX1JFRylcbmNvbnN0IGlzTnBtTW9kdWxlID0gbmFtZSA9PiAhaXNXZWV4Q29tcG9uZW50KG5hbWUpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAhaXNXZWV4TW9kdWxlKG5hbWUpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAhaXNOb3JtYWxNb2R1bGUobmFtZSlcblxuZnVuY3Rpb24gcmVtb3ZlV2VleFByZWZpeChzdHIpIHtcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKFdFRVhfQ09NUE9ORU5UX1JFRywgJycpXG4gICAgICAgICAgLnJlcGxhY2UoV0VFWF9NT0RVTEVfUkVHLCAnJylcbn1cblxuZnVuY3Rpb24gcmVtb3ZlSlNTdXJmaXgoc3RyKSB7XG4gIHJldHVybiBzdHIucmVwbGFjZShKU19TVVJGSVhfUkVHLCAnJylcbn1cblxubGV0IGNvbW1vbk1vZHVsZXMgPSB7fVxuXG5leHBvcnQgZnVuY3Rpb24gY2xlYXJDb21tb25Nb2R1bGVzKCkge1xuICBjb21tb25Nb2R1bGVzID0ge31cbn1cblxuLy8gZGVmaW5lKG5hbWUsIGZhY3RvcnkpIGZvciBwcmltYXJ5IHVzYWdlXG4vLyBvclxuLy8gZGVmaW5lKG5hbWUsIGRlcHMsIGZhY3RvcnkpIGZvciBjb21wYXRpYmlsaXR5XG4vLyBOb3RpY2U6IERPIE5PVCB1c2UgZnVuY3Rpb24gZGVmaW5lKCkge30sXG4vLyBpdCB3aWxsIGNhdXNlIGVycm9yIGFmdGVyIGJ1aWxkZWQgYnkgd2VicGFja1xuZXhwb3J0IHZhciBkZWZpbmUgPSBmdW5jdGlvbiAobmFtZSwgZGVwcywgZmFjdG9yeSkge1xuICBwZXJmLnN0YXJ0KCdkZWZpbmUnLCBuYW1lKVxuXG4gIGlmIChfLnR5cG9mKGRlcHMpID09PSAnZnVuY3Rpb24nKSB7XG4gICAgZmFjdG9yeSA9IGRlcHNcbiAgICBkZXBzID0gW11cbiAgfVxuXG4gIGxldCBfcmVxdWlyZSA9IChuYW1lKSA9PiB7XG4gICAgbGV0IGNsZWFuTmFtZVxuXG4gICAgaWYgKGlzV2VleENvbXBvbmVudChuYW1lKSkge1xuICAgICAgY2xlYW5OYW1lID0gcmVtb3ZlV2VleFByZWZpeChuYW1lKVxuICAgICAgcmV0dXJuIHRoaXMucmVxdWlyZUNvbXBvbmVudChjbGVhbk5hbWUpXG4gICAgfVxuICAgIGlmIChpc1dlZXhNb2R1bGUobmFtZSkpIHtcbiAgICAgIGNsZWFuTmFtZSA9IHJlbW92ZVdlZXhQcmVmaXgobmFtZSlcbiAgICAgIHJldHVybiB0aGlzLnJlcXVpcmVNb2R1bGUoY2xlYW5OYW1lKVxuICAgIH1cbiAgICBpZiAoaXNOb3JtYWxNb2R1bGUobmFtZSkpIHtcbiAgICAgIGNsZWFuTmFtZSA9IHJlbW92ZUpTU3VyZml4KG5hbWUpXG4gICAgICByZXR1cm4gY29tbW9uTW9kdWxlc1tuYW1lXVxuICAgIH1cbiAgICBpZiAoaXNOcG1Nb2R1bGUobmFtZSkpIHtcbiAgICAgIGNsZWFuTmFtZSA9IHJlbW92ZUpTU3VyZml4KG5hbWUpXG4gICAgICByZXR1cm4gY29tbW9uTW9kdWxlc1tuYW1lXVxuICAgIH1cbiAgfVxuICBsZXQgX21vZHVsZSA9IHtleHBvcnRzOiB7fX1cblxuICBsZXQgY2xlYW5OYW1lXG4gIGlmIChpc1dlZXhDb21wb25lbnQobmFtZSkpIHtcbiAgICBjbGVhbk5hbWUgPSByZW1vdmVXZWV4UHJlZml4KG5hbWUpXG5cbiAgICBmYWN0b3J5KF9yZXF1aXJlLCBfbW9kdWxlLmV4cG9ydHMsIF9tb2R1bGUpXG5cbiAgICB0aGlzLnJlZ2lzdGVyQ29tcG9uZW50KGNsZWFuTmFtZSwgX21vZHVsZS5leHBvcnRzKVxuICB9IGVsc2UgaWYgKGlzV2VleE1vZHVsZShuYW1lKSkge1xuICAgIGNsZWFuTmFtZSA9IHJlbW92ZVdlZXhQcmVmaXgobmFtZSlcblxuICAgIGZhY3RvcnkoX3JlcXVpcmUsIF9tb2R1bGUuZXhwb3J0cywgX21vZHVsZSlcblxuICAgIFZtLnJlZ2lzdGVyTW9kdWxlcyh7XG4gICAgICBbY2xlYW5OYW1lXTogX21vZHVsZS5leHBvcnRzXG4gICAgfSlcbiAgfSBlbHNlIGlmIChpc05vcm1hbE1vZHVsZShuYW1lKSkge1xuICAgIGNsZWFuTmFtZSA9IHJlbW92ZUpTU3VyZml4KG5hbWUpXG5cbiAgICBmYWN0b3J5KF9yZXF1aXJlLCBfbW9kdWxlLmV4cG9ydHMsIF9tb2R1bGUpXG5cbiAgICBjb21tb25Nb2R1bGVzW2NsZWFuTmFtZV0gPSBfbW9kdWxlLmV4cG9ydHNcbiAgfSBlbHNlIGlmIChpc05wbU1vZHVsZShuYW1lKSkge1xuICAgIGNsZWFuTmFtZSA9IHJlbW92ZUpTU3VyZml4KG5hbWUpXG5cbiAgICBmYWN0b3J5KF9yZXF1aXJlLCBfbW9kdWxlLmV4cG9ydHMsIF9tb2R1bGUpXG5cbiAgICBsZXQgZXhwb3J0cyA9IF9tb2R1bGUuZXhwb3J0c1xuICAgIGlmIChleHBvcnRzLnRlbXBsYXRlIHx8XG4gICAgICAgIGV4cG9ydHMuc3R5bGUgfHxcbiAgICAgICAgZXhwb3J0cy5tZXRob2RzKSB7XG4gICAgICAvLyBkb3duZ3JhZGUgdG8gb2xkIGRlZmluZSBtZXRob2QgKGRlZmluZSgnY29tcG9uZW50TmFtZScsIGZhY3RvcnkpKVxuICAgICAgLy8gdGhlIGV4cG9ydHMgY29udGFpbiBvbmUga2V5IG9mIHRlbXBsYXRlLCBzdHlsZSBvciBtZXRob2RzXG4gICAgICAvLyBidXQgaXQgaGFzIHJpc2shISFcbiAgICAgIHRoaXMucmVnaXN0ZXJDb21wb25lbnQoY2xlYW5OYW1lLCBleHBvcnRzKVxuICAgIH0gZWxzZSB7XG4gICAgICBjb21tb25Nb2R1bGVzW2NsZWFuTmFtZV0gPSBfbW9kdWxlLmV4cG9ydHNcbiAgICB9XG4gIH1cblxuICBwZXJmLmVuZCgnZGVmaW5lJywgbmFtZSlcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJvb3RzdHJhcChuYW1lLCBjb25maWcsIGRhdGEpIHtcbiAgbGV0IGNsZWFuTmFtZVxuXG4gIGlmIChpc1dlZXhDb21wb25lbnQobmFtZSkpIHtcbiAgICBjbGVhbk5hbWUgPSByZW1vdmVXZWV4UHJlZml4KG5hbWUpXG4gIH0gZWxzZSBpZiAoaXNOcG1Nb2R1bGUobmFtZSkpIHtcbiAgICBjbGVhbk5hbWUgPSByZW1vdmVKU1N1cmZpeChuYW1lKVxuICAgIC8vIGNoZWNrIGlmIGRlZmluZSBieSBvbGQgJ2RlZmluZScgbWV0aG9kXG4gICAgaWYgKCF0aGlzLmN1c3RvbUNvbXBvbmVudE1hcFtjbGVhbk5hbWVdKSB7XG4gICAgICByZXR1cm4gbmV3IEVycm9yKGBJdCdzIG5vdCBhIGNvbXBvbmVudDogJHtuYW1lfWApXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBuZXcgRXJyb3IoYFdyb25nIGNvbXBvbmVudCBuYW1lOiAke25hbWV9YClcbiAgfVxuXG4gIGNvbmZpZyA9IF8uaXNQbGFpbk9iamVjdChjb25maWcpID8gY29uZmlnIDoge31cblxuICBpZiAodHlwZW9mIGNvbmZpZy50cmFuc2Zvcm1lclZlcnNpb24gPT09ICdzdHJpbmcnICYmXG4gICAgdHlwZW9mIGdsb2JhbC5uZWVkVHJhbnNmb3JtZXJWZXJzaW9uID09PSAnc3RyaW5nJyAmJlxuICAgICFzZW12ZXIuc2F0aXNmaWVzKGNvbmZpZy50cmFuc2Zvcm1lclZlcnNpb24sXG4gICAgICBnbG9iYWwubmVlZFRyYW5zZm9ybWVyVmVyc2lvbikpIHtcbiAgICByZXR1cm4gbmV3IEVycm9yKGBKUyBCdW5kbGUgdmVyc2lvbjogJHtjb25maWcudHJhbnNmb3JtZXJWZXJzaW9ufSBgICtcbiAgICAgIGBub3QgY29tcGF0aWJsZSB3aXRoICR7Z2xvYmFsLm5lZWRUcmFuc2Zvcm1lclZlcnNpb259YClcbiAgfVxuXG4gIGxldCBfY2hlY2tEb3duZ3JhZGUgPSBkb3duZ3JhZGUuY2hlY2soY29uZmlnLmRvd25ncmFkZSlcbiAgaWYgKF9jaGVja0Rvd25ncmFkZS5pc0Rvd25ncmFkZSkge1xuICAgIHRoaXMuY2FsbFRhc2tzKFt7XG4gICAgICBtb2R1bGU6ICdpbnN0YW5jZVdyYXAnLFxuICAgICAgbWV0aG9kOiAnZXJyb3InLFxuICAgICAgYXJnczogW1xuICAgICAgICBfY2hlY2tEb3duZ3JhZGUuZXJyb3JUeXBlLFxuICAgICAgICBfY2hlY2tEb3duZ3JhZGUuY29kZSxcbiAgICAgICAgX2NoZWNrRG93bmdyYWRlLmVycm9yTWVzc2FnZVxuICAgICAgXVxuICAgIH1dKVxuICAgIHJldHVybiBuZXcgRXJyb3IoYERvd25ncmFkZTogJHtjb25maWcuZG93bmdyYWRlfWApXG4gIH1cblxuICBwZXJmLnN0YXJ0KCdjcmVhdGUgdm0nLCBjbGVhbk5hbWUpXG5cbiAgdGhpcy52bSA9IG5ldyBWbShjbGVhbk5hbWUsIHtfYXBwOiB0aGlzfSwgbnVsbCwgZGF0YSwge1xuICAgICdob29rOnJlYWR5JzogKCkgPT4ge1xuICAgICAgcGVyZi5lbmQoJ2NyZWF0ZSB2bScsIGNsZWFuTmFtZSlcbiAgICB9XG4gIH0pXG59XG5cbi8qKlxuICogQGRlcHJlY2F0ZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyKHR5cGUsIG9wdGlvbnMpIHtcbiAgcGVyZi5zdGFydCgncmVnaXN0ZXInLCB0eXBlKVxuICB0aGlzLnJlZ2lzdGVyQ29tcG9uZW50KHR5cGUsIG9wdGlvbnMpXG4gIHBlcmYuZW5kKCdyZWdpc3RlcicsIHR5cGUpXG59XG5cbi8qKlxuICogQGRlcHJlY2F0ZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlbmRlcih0eXBlLCBkYXRhKSB7XG4gIHJldHVybiB0aGlzLmJvb3RzdHJhcCh0eXBlLCB7fSwgZGF0YSlcbn1cblxuLyoqXG4gKiBAZGVwcmVjYXRlZFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVxdWlyZSh0eXBlKSB7XG4gIHJldHVybiAoZGF0YSkgPT4ge1xuICAgIHJldHVybiB0aGlzLmJvb3RzdHJhcCh0eXBlLCB7fSwgZGF0YSlcbiAgfVxufVxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9saWIvYXBwL2J1bmRsZS5qc1xuICoqLyIsImV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IFNlbVZlcjtcblxuLy8gVGhlIGRlYnVnIGZ1bmN0aW9uIGlzIGV4Y2x1ZGVkIGVudGlyZWx5IGZyb20gdGhlIG1pbmlmaWVkIHZlcnNpb24uXG4vKiBub21pbiAqLyB2YXIgZGVidWc7XG4vKiBub21pbiAqLyBpZiAodHlwZW9mIHByb2Nlc3MgPT09ICdvYmplY3QnICYmXG4gICAgLyogbm9taW4gKi8gcHJvY2Vzcy5lbnYgJiZcbiAgICAvKiBub21pbiAqLyBwcm9jZXNzLmVudi5OT0RFX0RFQlVHICYmXG4gICAgLyogbm9taW4gKi8gL1xcYnNlbXZlclxcYi9pLnRlc3QocHJvY2Vzcy5lbnYuTk9ERV9ERUJVRykpXG4gIC8qIG5vbWluICovIGRlYnVnID0gZnVuY3Rpb24oKSB7XG4gICAgLyogbm9taW4gKi8gdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApO1xuICAgIC8qIG5vbWluICovIGFyZ3MudW5zaGlmdCgnU0VNVkVSJyk7XG4gICAgLyogbm9taW4gKi8gY29uc29sZS5sb2cuYXBwbHkoY29uc29sZSwgYXJncyk7XG4gICAgLyogbm9taW4gKi8gfTtcbi8qIG5vbWluICovIGVsc2VcbiAgLyogbm9taW4gKi8gZGVidWcgPSBmdW5jdGlvbigpIHt9O1xuXG4vLyBOb3RlOiB0aGlzIGlzIHRoZSBzZW12ZXIub3JnIHZlcnNpb24gb2YgdGhlIHNwZWMgdGhhdCBpdCBpbXBsZW1lbnRzXG4vLyBOb3QgbmVjZXNzYXJpbHkgdGhlIHBhY2thZ2UgdmVyc2lvbiBvZiB0aGlzIGNvZGUuXG5leHBvcnRzLlNFTVZFUl9TUEVDX1ZFUlNJT04gPSAnMi4wLjAnO1xuXG52YXIgTUFYX0xFTkdUSCA9IDI1NjtcbnZhciBNQVhfU0FGRV9JTlRFR0VSID0gTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIgfHwgOTAwNzE5OTI1NDc0MDk5MTtcblxuLy8gVGhlIGFjdHVhbCByZWdleHBzIGdvIG9uIGV4cG9ydHMucmVcbnZhciByZSA9IGV4cG9ydHMucmUgPSBbXTtcbnZhciBzcmMgPSBleHBvcnRzLnNyYyA9IFtdO1xudmFyIFIgPSAwO1xuXG4vLyBUaGUgZm9sbG93aW5nIFJlZ3VsYXIgRXhwcmVzc2lvbnMgY2FuIGJlIHVzZWQgZm9yIHRva2VuaXppbmcsXG4vLyB2YWxpZGF0aW5nLCBhbmQgcGFyc2luZyBTZW1WZXIgdmVyc2lvbiBzdHJpbmdzLlxuXG4vLyAjIyBOdW1lcmljIElkZW50aWZpZXJcbi8vIEEgc2luZ2xlIGAwYCwgb3IgYSBub24temVybyBkaWdpdCBmb2xsb3dlZCBieSB6ZXJvIG9yIG1vcmUgZGlnaXRzLlxuXG52YXIgTlVNRVJJQ0lERU5USUZJRVIgPSBSKys7XG5zcmNbTlVNRVJJQ0lERU5USUZJRVJdID0gJzB8WzEtOV1cXFxcZConO1xudmFyIE5VTUVSSUNJREVOVElGSUVSTE9PU0UgPSBSKys7XG5zcmNbTlVNRVJJQ0lERU5USUZJRVJMT09TRV0gPSAnWzAtOV0rJztcblxuXG4vLyAjIyBOb24tbnVtZXJpYyBJZGVudGlmaWVyXG4vLyBaZXJvIG9yIG1vcmUgZGlnaXRzLCBmb2xsb3dlZCBieSBhIGxldHRlciBvciBoeXBoZW4sIGFuZCB0aGVuIHplcm8gb3Jcbi8vIG1vcmUgbGV0dGVycywgZGlnaXRzLCBvciBoeXBoZW5zLlxuXG52YXIgTk9OTlVNRVJJQ0lERU5USUZJRVIgPSBSKys7XG5zcmNbTk9OTlVNRVJJQ0lERU5USUZJRVJdID0gJ1xcXFxkKlthLXpBLVotXVthLXpBLVowLTktXSonO1xuXG5cbi8vICMjIE1haW4gVmVyc2lvblxuLy8gVGhyZWUgZG90LXNlcGFyYXRlZCBudW1lcmljIGlkZW50aWZpZXJzLlxuXG52YXIgTUFJTlZFUlNJT04gPSBSKys7XG5zcmNbTUFJTlZFUlNJT05dID0gJygnICsgc3JjW05VTUVSSUNJREVOVElGSUVSXSArICcpXFxcXC4nICtcbiAgICAgICAgICAgICAgICAgICAnKCcgKyBzcmNbTlVNRVJJQ0lERU5USUZJRVJdICsgJylcXFxcLicgK1xuICAgICAgICAgICAgICAgICAgICcoJyArIHNyY1tOVU1FUklDSURFTlRJRklFUl0gKyAnKSc7XG5cbnZhciBNQUlOVkVSU0lPTkxPT1NFID0gUisrO1xuc3JjW01BSU5WRVJTSU9OTE9PU0VdID0gJygnICsgc3JjW05VTUVSSUNJREVOVElGSUVSTE9PU0VdICsgJylcXFxcLicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJygnICsgc3JjW05VTUVSSUNJREVOVElGSUVSTE9PU0VdICsgJylcXFxcLicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJygnICsgc3JjW05VTUVSSUNJREVOVElGSUVSTE9PU0VdICsgJyknO1xuXG4vLyAjIyBQcmUtcmVsZWFzZSBWZXJzaW9uIElkZW50aWZpZXJcbi8vIEEgbnVtZXJpYyBpZGVudGlmaWVyLCBvciBhIG5vbi1udW1lcmljIGlkZW50aWZpZXIuXG5cbnZhciBQUkVSRUxFQVNFSURFTlRJRklFUiA9IFIrKztcbnNyY1tQUkVSRUxFQVNFSURFTlRJRklFUl0gPSAnKD86JyArIHNyY1tOVU1FUklDSURFTlRJRklFUl0gK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd8JyArIHNyY1tOT05OVU1FUklDSURFTlRJRklFUl0gKyAnKSc7XG5cbnZhciBQUkVSRUxFQVNFSURFTlRJRklFUkxPT1NFID0gUisrO1xuc3JjW1BSRVJFTEVBU0VJREVOVElGSUVSTE9PU0VdID0gJyg/OicgKyBzcmNbTlVNRVJJQ0lERU5USUZJRVJMT09TRV0gK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3wnICsgc3JjW05PTk5VTUVSSUNJREVOVElGSUVSXSArICcpJztcblxuXG4vLyAjIyBQcmUtcmVsZWFzZSBWZXJzaW9uXG4vLyBIeXBoZW4sIGZvbGxvd2VkIGJ5IG9uZSBvciBtb3JlIGRvdC1zZXBhcmF0ZWQgcHJlLXJlbGVhc2UgdmVyc2lvblxuLy8gaWRlbnRpZmllcnMuXG5cbnZhciBQUkVSRUxFQVNFID0gUisrO1xuc3JjW1BSRVJFTEVBU0VdID0gJyg/Oi0oJyArIHNyY1tQUkVSRUxFQVNFSURFTlRJRklFUl0gK1xuICAgICAgICAgICAgICAgICAgJyg/OlxcXFwuJyArIHNyY1tQUkVSRUxFQVNFSURFTlRJRklFUl0gKyAnKSopKSc7XG5cbnZhciBQUkVSRUxFQVNFTE9PU0UgPSBSKys7XG5zcmNbUFJFUkVMRUFTRUxPT1NFXSA9ICcoPzotPygnICsgc3JjW1BSRVJFTEVBU0VJREVOVElGSUVSTE9PU0VdICtcbiAgICAgICAgICAgICAgICAgICAgICAgJyg/OlxcXFwuJyArIHNyY1tQUkVSRUxFQVNFSURFTlRJRklFUkxPT1NFXSArICcpKikpJztcblxuLy8gIyMgQnVpbGQgTWV0YWRhdGEgSWRlbnRpZmllclxuLy8gQW55IGNvbWJpbmF0aW9uIG9mIGRpZ2l0cywgbGV0dGVycywgb3IgaHlwaGVucy5cblxudmFyIEJVSUxESURFTlRJRklFUiA9IFIrKztcbnNyY1tCVUlMRElERU5USUZJRVJdID0gJ1swLTlBLVphLXotXSsnO1xuXG4vLyAjIyBCdWlsZCBNZXRhZGF0YVxuLy8gUGx1cyBzaWduLCBmb2xsb3dlZCBieSBvbmUgb3IgbW9yZSBwZXJpb2Qtc2VwYXJhdGVkIGJ1aWxkIG1ldGFkYXRhXG4vLyBpZGVudGlmaWVycy5cblxudmFyIEJVSUxEID0gUisrO1xuc3JjW0JVSUxEXSA9ICcoPzpcXFxcKygnICsgc3JjW0JVSUxESURFTlRJRklFUl0gK1xuICAgICAgICAgICAgICcoPzpcXFxcLicgKyBzcmNbQlVJTERJREVOVElGSUVSXSArICcpKikpJztcblxuXG4vLyAjIyBGdWxsIFZlcnNpb24gU3RyaW5nXG4vLyBBIG1haW4gdmVyc2lvbiwgZm9sbG93ZWQgb3B0aW9uYWxseSBieSBhIHByZS1yZWxlYXNlIHZlcnNpb24gYW5kXG4vLyBidWlsZCBtZXRhZGF0YS5cblxuLy8gTm90ZSB0aGF0IHRoZSBvbmx5IG1ham9yLCBtaW5vciwgcGF0Y2gsIGFuZCBwcmUtcmVsZWFzZSBzZWN0aW9ucyBvZlxuLy8gdGhlIHZlcnNpb24gc3RyaW5nIGFyZSBjYXB0dXJpbmcgZ3JvdXBzLiAgVGhlIGJ1aWxkIG1ldGFkYXRhIGlzIG5vdCBhXG4vLyBjYXB0dXJpbmcgZ3JvdXAsIGJlY2F1c2UgaXQgc2hvdWxkIG5vdCBldmVyIGJlIHVzZWQgaW4gdmVyc2lvblxuLy8gY29tcGFyaXNvbi5cblxudmFyIEZVTEwgPSBSKys7XG52YXIgRlVMTFBMQUlOID0gJ3Y/JyArIHNyY1tNQUlOVkVSU0lPTl0gK1xuICAgICAgICAgICAgICAgIHNyY1tQUkVSRUxFQVNFXSArICc/JyArXG4gICAgICAgICAgICAgICAgc3JjW0JVSUxEXSArICc/Jztcblxuc3JjW0ZVTExdID0gJ14nICsgRlVMTFBMQUlOICsgJyQnO1xuXG4vLyBsaWtlIGZ1bGwsIGJ1dCBhbGxvd3MgdjEuMi4zIGFuZCA9MS4yLjMsIHdoaWNoIHBlb3BsZSBkbyBzb21ldGltZXMuXG4vLyBhbHNvLCAxLjAuMGFscGhhMSAocHJlcmVsZWFzZSB3aXRob3V0IHRoZSBoeXBoZW4pIHdoaWNoIGlzIHByZXR0eVxuLy8gY29tbW9uIGluIHRoZSBucG0gcmVnaXN0cnkuXG52YXIgTE9PU0VQTEFJTiA9ICdbdj1cXFxcc10qJyArIHNyY1tNQUlOVkVSU0lPTkxPT1NFXSArXG4gICAgICAgICAgICAgICAgIHNyY1tQUkVSRUxFQVNFTE9PU0VdICsgJz8nICtcbiAgICAgICAgICAgICAgICAgc3JjW0JVSUxEXSArICc/JztcblxudmFyIExPT1NFID0gUisrO1xuc3JjW0xPT1NFXSA9ICdeJyArIExPT1NFUExBSU4gKyAnJCc7XG5cbnZhciBHVExUID0gUisrO1xuc3JjW0dUTFRdID0gJygoPzo8fD4pPz0/KSc7XG5cbi8vIFNvbWV0aGluZyBsaWtlIFwiMi4qXCIgb3IgXCIxLjIueFwiLlxuLy8gTm90ZSB0aGF0IFwieC54XCIgaXMgYSB2YWxpZCB4UmFuZ2UgaWRlbnRpZmVyLCBtZWFuaW5nIFwiYW55IHZlcnNpb25cIlxuLy8gT25seSB0aGUgZmlyc3QgaXRlbSBpcyBzdHJpY3RseSByZXF1aXJlZC5cbnZhciBYUkFOR0VJREVOVElGSUVSTE9PU0UgPSBSKys7XG5zcmNbWFJBTkdFSURFTlRJRklFUkxPT1NFXSA9IHNyY1tOVU1FUklDSURFTlRJRklFUkxPT1NFXSArICd8eHxYfFxcXFwqJztcbnZhciBYUkFOR0VJREVOVElGSUVSID0gUisrO1xuc3JjW1hSQU5HRUlERU5USUZJRVJdID0gc3JjW05VTUVSSUNJREVOVElGSUVSXSArICd8eHxYfFxcXFwqJztcblxudmFyIFhSQU5HRVBMQUlOID0gUisrO1xuc3JjW1hSQU5HRVBMQUlOXSA9ICdbdj1cXFxcc10qKCcgKyBzcmNbWFJBTkdFSURFTlRJRklFUl0gKyAnKScgK1xuICAgICAgICAgICAgICAgICAgICcoPzpcXFxcLignICsgc3JjW1hSQU5HRUlERU5USUZJRVJdICsgJyknICtcbiAgICAgICAgICAgICAgICAgICAnKD86XFxcXC4oJyArIHNyY1tYUkFOR0VJREVOVElGSUVSXSArICcpJyArXG4gICAgICAgICAgICAgICAgICAgJyg/OicgKyBzcmNbUFJFUkVMRUFTRV0gKyAnKT8nICtcbiAgICAgICAgICAgICAgICAgICBzcmNbQlVJTERdICsgJz8nICtcbiAgICAgICAgICAgICAgICAgICAnKT8pPyc7XG5cbnZhciBYUkFOR0VQTEFJTkxPT1NFID0gUisrO1xuc3JjW1hSQU5HRVBMQUlOTE9PU0VdID0gJ1t2PVxcXFxzXSooJyArIHNyY1tYUkFOR0VJREVOVElGSUVSTE9PU0VdICsgJyknICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcoPzpcXFxcLignICsgc3JjW1hSQU5HRUlERU5USUZJRVJMT09TRV0gKyAnKScgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJyg/OlxcXFwuKCcgKyBzcmNbWFJBTkdFSURFTlRJRklFUkxPT1NFXSArICcpJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnKD86JyArIHNyY1tQUkVSRUxFQVNFTE9PU0VdICsgJyk/JyArXG4gICAgICAgICAgICAgICAgICAgICAgICBzcmNbQlVJTERdICsgJz8nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcpPyk/JztcblxudmFyIFhSQU5HRSA9IFIrKztcbnNyY1tYUkFOR0VdID0gJ14nICsgc3JjW0dUTFRdICsgJ1xcXFxzKicgKyBzcmNbWFJBTkdFUExBSU5dICsgJyQnO1xudmFyIFhSQU5HRUxPT1NFID0gUisrO1xuc3JjW1hSQU5HRUxPT1NFXSA9ICdeJyArIHNyY1tHVExUXSArICdcXFxccyonICsgc3JjW1hSQU5HRVBMQUlOTE9PU0VdICsgJyQnO1xuXG4vLyBUaWxkZSByYW5nZXMuXG4vLyBNZWFuaW5nIGlzIFwicmVhc29uYWJseSBhdCBvciBncmVhdGVyIHRoYW5cIlxudmFyIExPTkVUSUxERSA9IFIrKztcbnNyY1tMT05FVElMREVdID0gJyg/On4+PyknO1xuXG52YXIgVElMREVUUklNID0gUisrO1xuc3JjW1RJTERFVFJJTV0gPSAnKFxcXFxzKiknICsgc3JjW0xPTkVUSUxERV0gKyAnXFxcXHMrJztcbnJlW1RJTERFVFJJTV0gPSBuZXcgUmVnRXhwKHNyY1tUSUxERVRSSU1dLCAnZycpO1xudmFyIHRpbGRlVHJpbVJlcGxhY2UgPSAnJDF+JztcblxudmFyIFRJTERFID0gUisrO1xuc3JjW1RJTERFXSA9ICdeJyArIHNyY1tMT05FVElMREVdICsgc3JjW1hSQU5HRVBMQUlOXSArICckJztcbnZhciBUSUxERUxPT1NFID0gUisrO1xuc3JjW1RJTERFTE9PU0VdID0gJ14nICsgc3JjW0xPTkVUSUxERV0gKyBzcmNbWFJBTkdFUExBSU5MT09TRV0gKyAnJCc7XG5cbi8vIENhcmV0IHJhbmdlcy5cbi8vIE1lYW5pbmcgaXMgXCJhdCBsZWFzdCBhbmQgYmFja3dhcmRzIGNvbXBhdGlibGUgd2l0aFwiXG52YXIgTE9ORUNBUkVUID0gUisrO1xuc3JjW0xPTkVDQVJFVF0gPSAnKD86XFxcXF4pJztcblxudmFyIENBUkVUVFJJTSA9IFIrKztcbnNyY1tDQVJFVFRSSU1dID0gJyhcXFxccyopJyArIHNyY1tMT05FQ0FSRVRdICsgJ1xcXFxzKyc7XG5yZVtDQVJFVFRSSU1dID0gbmV3IFJlZ0V4cChzcmNbQ0FSRVRUUklNXSwgJ2cnKTtcbnZhciBjYXJldFRyaW1SZXBsYWNlID0gJyQxXic7XG5cbnZhciBDQVJFVCA9IFIrKztcbnNyY1tDQVJFVF0gPSAnXicgKyBzcmNbTE9ORUNBUkVUXSArIHNyY1tYUkFOR0VQTEFJTl0gKyAnJCc7XG52YXIgQ0FSRVRMT09TRSA9IFIrKztcbnNyY1tDQVJFVExPT1NFXSA9ICdeJyArIHNyY1tMT05FQ0FSRVRdICsgc3JjW1hSQU5HRVBMQUlOTE9PU0VdICsgJyQnO1xuXG4vLyBBIHNpbXBsZSBndC9sdC9lcSB0aGluZywgb3IganVzdCBcIlwiIHRvIGluZGljYXRlIFwiYW55IHZlcnNpb25cIlxudmFyIENPTVBBUkFUT1JMT09TRSA9IFIrKztcbnNyY1tDT01QQVJBVE9STE9PU0VdID0gJ14nICsgc3JjW0dUTFRdICsgJ1xcXFxzKignICsgTE9PU0VQTEFJTiArICcpJHxeJCc7XG52YXIgQ09NUEFSQVRPUiA9IFIrKztcbnNyY1tDT01QQVJBVE9SXSA9ICdeJyArIHNyY1tHVExUXSArICdcXFxccyooJyArIEZVTExQTEFJTiArICcpJHxeJCc7XG5cblxuLy8gQW4gZXhwcmVzc2lvbiB0byBzdHJpcCBhbnkgd2hpdGVzcGFjZSBiZXR3ZWVuIHRoZSBndGx0IGFuZCB0aGUgdGhpbmdcbi8vIGl0IG1vZGlmaWVzLCBzbyB0aGF0IGA+IDEuMi4zYCA9PT4gYD4xLjIuM2BcbnZhciBDT01QQVJBVE9SVFJJTSA9IFIrKztcbnNyY1tDT01QQVJBVE9SVFJJTV0gPSAnKFxcXFxzKiknICsgc3JjW0dUTFRdICtcbiAgICAgICAgICAgICAgICAgICAgICAnXFxcXHMqKCcgKyBMT09TRVBMQUlOICsgJ3wnICsgc3JjW1hSQU5HRVBMQUlOXSArICcpJztcblxuLy8gdGhpcyBvbmUgaGFzIHRvIHVzZSB0aGUgL2cgZmxhZ1xucmVbQ09NUEFSQVRPUlRSSU1dID0gbmV3IFJlZ0V4cChzcmNbQ09NUEFSQVRPUlRSSU1dLCAnZycpO1xudmFyIGNvbXBhcmF0b3JUcmltUmVwbGFjZSA9ICckMSQyJDMnO1xuXG5cbi8vIFNvbWV0aGluZyBsaWtlIGAxLjIuMyAtIDEuMi40YFxuLy8gTm90ZSB0aGF0IHRoZXNlIGFsbCB1c2UgdGhlIGxvb3NlIGZvcm0sIGJlY2F1c2UgdGhleSdsbCBiZVxuLy8gY2hlY2tlZCBhZ2FpbnN0IGVpdGhlciB0aGUgc3RyaWN0IG9yIGxvb3NlIGNvbXBhcmF0b3IgZm9ybVxuLy8gbGF0ZXIuXG52YXIgSFlQSEVOUkFOR0UgPSBSKys7XG5zcmNbSFlQSEVOUkFOR0VdID0gJ15cXFxccyooJyArIHNyY1tYUkFOR0VQTEFJTl0gKyAnKScgK1xuICAgICAgICAgICAgICAgICAgICdcXFxccystXFxcXHMrJyArXG4gICAgICAgICAgICAgICAgICAgJygnICsgc3JjW1hSQU5HRVBMQUlOXSArICcpJyArXG4gICAgICAgICAgICAgICAgICAgJ1xcXFxzKiQnO1xuXG52YXIgSFlQSEVOUkFOR0VMT09TRSA9IFIrKztcbnNyY1tIWVBIRU5SQU5HRUxPT1NFXSA9ICdeXFxcXHMqKCcgKyBzcmNbWFJBTkdFUExBSU5MT09TRV0gKyAnKScgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJ1xcXFxzKy1cXFxccysnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcoJyArIHNyY1tYUkFOR0VQTEFJTkxPT1NFXSArICcpJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnXFxcXHMqJCc7XG5cbi8vIFN0YXIgcmFuZ2VzIGJhc2ljYWxseSBqdXN0IGFsbG93IGFueXRoaW5nIGF0IGFsbC5cbnZhciBTVEFSID0gUisrO1xuc3JjW1NUQVJdID0gJyg8fD4pPz0/XFxcXHMqXFxcXConO1xuXG4vLyBDb21waWxlIHRvIGFjdHVhbCByZWdleHAgb2JqZWN0cy5cbi8vIEFsbCBhcmUgZmxhZy1mcmVlLCB1bmxlc3MgdGhleSB3ZXJlIGNyZWF0ZWQgYWJvdmUgd2l0aCBhIGZsYWcuXG5mb3IgKHZhciBpID0gMDsgaSA8IFI7IGkrKykge1xuICBkZWJ1ZyhpLCBzcmNbaV0pO1xuICBpZiAoIXJlW2ldKVxuICAgIHJlW2ldID0gbmV3IFJlZ0V4cChzcmNbaV0pO1xufVxuXG5leHBvcnRzLnBhcnNlID0gcGFyc2U7XG5mdW5jdGlvbiBwYXJzZSh2ZXJzaW9uLCBsb29zZSkge1xuICBpZiAodmVyc2lvbiBpbnN0YW5jZW9mIFNlbVZlcilcbiAgICByZXR1cm4gdmVyc2lvbjtcblxuICBpZiAodHlwZW9mIHZlcnNpb24gIT09ICdzdHJpbmcnKVxuICAgIHJldHVybiBudWxsO1xuXG4gIGlmICh2ZXJzaW9uLmxlbmd0aCA+IE1BWF9MRU5HVEgpXG4gICAgcmV0dXJuIG51bGw7XG5cbiAgdmFyIHIgPSBsb29zZSA/IHJlW0xPT1NFXSA6IHJlW0ZVTExdO1xuICBpZiAoIXIudGVzdCh2ZXJzaW9uKSlcbiAgICByZXR1cm4gbnVsbDtcblxuICB0cnkge1xuICAgIHJldHVybiBuZXcgU2VtVmVyKHZlcnNpb24sIGxvb3NlKTtcbiAgfSBjYXRjaCAoZXIpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG5leHBvcnRzLnZhbGlkID0gdmFsaWQ7XG5mdW5jdGlvbiB2YWxpZCh2ZXJzaW9uLCBsb29zZSkge1xuICB2YXIgdiA9IHBhcnNlKHZlcnNpb24sIGxvb3NlKTtcbiAgcmV0dXJuIHYgPyB2LnZlcnNpb24gOiBudWxsO1xufVxuXG5cbmV4cG9ydHMuY2xlYW4gPSBjbGVhbjtcbmZ1bmN0aW9uIGNsZWFuKHZlcnNpb24sIGxvb3NlKSB7XG4gIHZhciBzID0gcGFyc2UodmVyc2lvbi50cmltKCkucmVwbGFjZSgvXls9dl0rLywgJycpLCBsb29zZSk7XG4gIHJldHVybiBzID8gcy52ZXJzaW9uIDogbnVsbDtcbn1cblxuZXhwb3J0cy5TZW1WZXIgPSBTZW1WZXI7XG5cbmZ1bmN0aW9uIFNlbVZlcih2ZXJzaW9uLCBsb29zZSkge1xuICBpZiAodmVyc2lvbiBpbnN0YW5jZW9mIFNlbVZlcikge1xuICAgIGlmICh2ZXJzaW9uLmxvb3NlID09PSBsb29zZSlcbiAgICAgIHJldHVybiB2ZXJzaW9uO1xuICAgIGVsc2VcbiAgICAgIHZlcnNpb24gPSB2ZXJzaW9uLnZlcnNpb247XG4gIH0gZWxzZSBpZiAodHlwZW9mIHZlcnNpb24gIT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBWZXJzaW9uOiAnICsgdmVyc2lvbik7XG4gIH1cblxuICBpZiAodmVyc2lvbi5sZW5ndGggPiBNQVhfTEVOR1RIKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3ZlcnNpb24gaXMgbG9uZ2VyIHRoYW4gJyArIE1BWF9MRU5HVEggKyAnIGNoYXJhY3RlcnMnKVxuXG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTZW1WZXIpKVxuICAgIHJldHVybiBuZXcgU2VtVmVyKHZlcnNpb24sIGxvb3NlKTtcblxuICBkZWJ1ZygnU2VtVmVyJywgdmVyc2lvbiwgbG9vc2UpO1xuICB0aGlzLmxvb3NlID0gbG9vc2U7XG4gIHZhciBtID0gdmVyc2lvbi50cmltKCkubWF0Y2gobG9vc2UgPyByZVtMT09TRV0gOiByZVtGVUxMXSk7XG5cbiAgaWYgKCFtKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgVmVyc2lvbjogJyArIHZlcnNpb24pO1xuXG4gIHRoaXMucmF3ID0gdmVyc2lvbjtcblxuICAvLyB0aGVzZSBhcmUgYWN0dWFsbHkgbnVtYmVyc1xuICB0aGlzLm1ham9yID0gK21bMV07XG4gIHRoaXMubWlub3IgPSArbVsyXTtcbiAgdGhpcy5wYXRjaCA9ICttWzNdO1xuXG4gIGlmICh0aGlzLm1ham9yID4gTUFYX1NBRkVfSU5URUdFUiB8fCB0aGlzLm1ham9yIDwgMClcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG1ham9yIHZlcnNpb24nKVxuXG4gIGlmICh0aGlzLm1pbm9yID4gTUFYX1NBRkVfSU5URUdFUiB8fCB0aGlzLm1pbm9yIDwgMClcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG1pbm9yIHZlcnNpb24nKVxuXG4gIGlmICh0aGlzLnBhdGNoID4gTUFYX1NBRkVfSU5URUdFUiB8fCB0aGlzLnBhdGNoIDwgMClcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIHBhdGNoIHZlcnNpb24nKVxuXG4gIC8vIG51bWJlcmlmeSBhbnkgcHJlcmVsZWFzZSBudW1lcmljIGlkc1xuICBpZiAoIW1bNF0pXG4gICAgdGhpcy5wcmVyZWxlYXNlID0gW107XG4gIGVsc2VcbiAgICB0aGlzLnByZXJlbGVhc2UgPSBtWzRdLnNwbGl0KCcuJykubWFwKGZ1bmN0aW9uKGlkKSB7XG4gICAgICBpZiAoL15bMC05XSskLy50ZXN0KGlkKSkge1xuICAgICAgICB2YXIgbnVtID0gK2lkXG4gICAgICAgIGlmIChudW0gPj0gMCAmJiBudW0gPCBNQVhfU0FGRV9JTlRFR0VSKVxuICAgICAgICAgIHJldHVybiBudW1cbiAgICAgIH1cbiAgICAgIHJldHVybiBpZDtcbiAgICB9KTtcblxuICB0aGlzLmJ1aWxkID0gbVs1XSA/IG1bNV0uc3BsaXQoJy4nKSA6IFtdO1xuICB0aGlzLmZvcm1hdCgpO1xufVxuXG5TZW1WZXIucHJvdG90eXBlLmZvcm1hdCA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLnZlcnNpb24gPSB0aGlzLm1ham9yICsgJy4nICsgdGhpcy5taW5vciArICcuJyArIHRoaXMucGF0Y2g7XG4gIGlmICh0aGlzLnByZXJlbGVhc2UubGVuZ3RoKVxuICAgIHRoaXMudmVyc2lvbiArPSAnLScgKyB0aGlzLnByZXJlbGVhc2Uuam9pbignLicpO1xuICByZXR1cm4gdGhpcy52ZXJzaW9uO1xufTtcblxuU2VtVmVyLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy52ZXJzaW9uO1xufTtcblxuU2VtVmVyLnByb3RvdHlwZS5jb21wYXJlID0gZnVuY3Rpb24ob3RoZXIpIHtcbiAgZGVidWcoJ1NlbVZlci5jb21wYXJlJywgdGhpcy52ZXJzaW9uLCB0aGlzLmxvb3NlLCBvdGhlcik7XG4gIGlmICghKG90aGVyIGluc3RhbmNlb2YgU2VtVmVyKSlcbiAgICBvdGhlciA9IG5ldyBTZW1WZXIob3RoZXIsIHRoaXMubG9vc2UpO1xuXG4gIHJldHVybiB0aGlzLmNvbXBhcmVNYWluKG90aGVyKSB8fCB0aGlzLmNvbXBhcmVQcmUob3RoZXIpO1xufTtcblxuU2VtVmVyLnByb3RvdHlwZS5jb21wYXJlTWFpbiA9IGZ1bmN0aW9uKG90aGVyKSB7XG4gIGlmICghKG90aGVyIGluc3RhbmNlb2YgU2VtVmVyKSlcbiAgICBvdGhlciA9IG5ldyBTZW1WZXIob3RoZXIsIHRoaXMubG9vc2UpO1xuXG4gIHJldHVybiBjb21wYXJlSWRlbnRpZmllcnModGhpcy5tYWpvciwgb3RoZXIubWFqb3IpIHx8XG4gICAgICAgICBjb21wYXJlSWRlbnRpZmllcnModGhpcy5taW5vciwgb3RoZXIubWlub3IpIHx8XG4gICAgICAgICBjb21wYXJlSWRlbnRpZmllcnModGhpcy5wYXRjaCwgb3RoZXIucGF0Y2gpO1xufTtcblxuU2VtVmVyLnByb3RvdHlwZS5jb21wYXJlUHJlID0gZnVuY3Rpb24ob3RoZXIpIHtcbiAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiBTZW1WZXIpKVxuICAgIG90aGVyID0gbmV3IFNlbVZlcihvdGhlciwgdGhpcy5sb29zZSk7XG5cbiAgLy8gTk9UIGhhdmluZyBhIHByZXJlbGVhc2UgaXMgPiBoYXZpbmcgb25lXG4gIGlmICh0aGlzLnByZXJlbGVhc2UubGVuZ3RoICYmICFvdGhlci5wcmVyZWxlYXNlLmxlbmd0aClcbiAgICByZXR1cm4gLTE7XG4gIGVsc2UgaWYgKCF0aGlzLnByZXJlbGVhc2UubGVuZ3RoICYmIG90aGVyLnByZXJlbGVhc2UubGVuZ3RoKVxuICAgIHJldHVybiAxO1xuICBlbHNlIGlmICghdGhpcy5wcmVyZWxlYXNlLmxlbmd0aCAmJiAhb3RoZXIucHJlcmVsZWFzZS5sZW5ndGgpXG4gICAgcmV0dXJuIDA7XG5cbiAgdmFyIGkgPSAwO1xuICBkbyB7XG4gICAgdmFyIGEgPSB0aGlzLnByZXJlbGVhc2VbaV07XG4gICAgdmFyIGIgPSBvdGhlci5wcmVyZWxlYXNlW2ldO1xuICAgIGRlYnVnKCdwcmVyZWxlYXNlIGNvbXBhcmUnLCBpLCBhLCBiKTtcbiAgICBpZiAoYSA9PT0gdW5kZWZpbmVkICYmIGIgPT09IHVuZGVmaW5lZClcbiAgICAgIHJldHVybiAwO1xuICAgIGVsc2UgaWYgKGIgPT09IHVuZGVmaW5lZClcbiAgICAgIHJldHVybiAxO1xuICAgIGVsc2UgaWYgKGEgPT09IHVuZGVmaW5lZClcbiAgICAgIHJldHVybiAtMTtcbiAgICBlbHNlIGlmIChhID09PSBiKVxuICAgICAgY29udGludWU7XG4gICAgZWxzZVxuICAgICAgcmV0dXJuIGNvbXBhcmVJZGVudGlmaWVycyhhLCBiKTtcbiAgfSB3aGlsZSAoKytpKTtcbn07XG5cbi8vIHByZW1pbm9yIHdpbGwgYnVtcCB0aGUgdmVyc2lvbiB1cCB0byB0aGUgbmV4dCBtaW5vciByZWxlYXNlLCBhbmQgaW1tZWRpYXRlbHlcbi8vIGRvd24gdG8gcHJlLXJlbGVhc2UuIHByZW1ham9yIGFuZCBwcmVwYXRjaCB3b3JrIHRoZSBzYW1lIHdheS5cblNlbVZlci5wcm90b3R5cGUuaW5jID0gZnVuY3Rpb24ocmVsZWFzZSwgaWRlbnRpZmllcikge1xuICBzd2l0Y2ggKHJlbGVhc2UpIHtcbiAgICBjYXNlICdwcmVtYWpvcic6XG4gICAgICB0aGlzLnByZXJlbGVhc2UubGVuZ3RoID0gMDtcbiAgICAgIHRoaXMucGF0Y2ggPSAwO1xuICAgICAgdGhpcy5taW5vciA9IDA7XG4gICAgICB0aGlzLm1ham9yKys7XG4gICAgICB0aGlzLmluYygncHJlJywgaWRlbnRpZmllcik7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdwcmVtaW5vcic6XG4gICAgICB0aGlzLnByZXJlbGVhc2UubGVuZ3RoID0gMDtcbiAgICAgIHRoaXMucGF0Y2ggPSAwO1xuICAgICAgdGhpcy5taW5vcisrO1xuICAgICAgdGhpcy5pbmMoJ3ByZScsIGlkZW50aWZpZXIpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAncHJlcGF0Y2gnOlxuICAgICAgLy8gSWYgdGhpcyBpcyBhbHJlYWR5IGEgcHJlcmVsZWFzZSwgaXQgd2lsbCBidW1wIHRvIHRoZSBuZXh0IHZlcnNpb25cbiAgICAgIC8vIGRyb3AgYW55IHByZXJlbGVhc2VzIHRoYXQgbWlnaHQgYWxyZWFkeSBleGlzdCwgc2luY2UgdGhleSBhcmUgbm90XG4gICAgICAvLyByZWxldmFudCBhdCB0aGlzIHBvaW50LlxuICAgICAgdGhpcy5wcmVyZWxlYXNlLmxlbmd0aCA9IDA7XG4gICAgICB0aGlzLmluYygncGF0Y2gnLCBpZGVudGlmaWVyKTtcbiAgICAgIHRoaXMuaW5jKCdwcmUnLCBpZGVudGlmaWVyKTtcbiAgICAgIGJyZWFrO1xuICAgIC8vIElmIHRoZSBpbnB1dCBpcyBhIG5vbi1wcmVyZWxlYXNlIHZlcnNpb24sIHRoaXMgYWN0cyB0aGUgc2FtZSBhc1xuICAgIC8vIHByZXBhdGNoLlxuICAgIGNhc2UgJ3ByZXJlbGVhc2UnOlxuICAgICAgaWYgKHRoaXMucHJlcmVsZWFzZS5sZW5ndGggPT09IDApXG4gICAgICAgIHRoaXMuaW5jKCdwYXRjaCcsIGlkZW50aWZpZXIpO1xuICAgICAgdGhpcy5pbmMoJ3ByZScsIGlkZW50aWZpZXIpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdtYWpvcic6XG4gICAgICAvLyBJZiB0aGlzIGlzIGEgcHJlLW1ham9yIHZlcnNpb24sIGJ1bXAgdXAgdG8gdGhlIHNhbWUgbWFqb3IgdmVyc2lvbi5cbiAgICAgIC8vIE90aGVyd2lzZSBpbmNyZW1lbnQgbWFqb3IuXG4gICAgICAvLyAxLjAuMC01IGJ1bXBzIHRvIDEuMC4wXG4gICAgICAvLyAxLjEuMCBidW1wcyB0byAyLjAuMFxuICAgICAgaWYgKHRoaXMubWlub3IgIT09IDAgfHwgdGhpcy5wYXRjaCAhPT0gMCB8fCB0aGlzLnByZXJlbGVhc2UubGVuZ3RoID09PSAwKVxuICAgICAgICB0aGlzLm1ham9yKys7XG4gICAgICB0aGlzLm1pbm9yID0gMDtcbiAgICAgIHRoaXMucGF0Y2ggPSAwO1xuICAgICAgdGhpcy5wcmVyZWxlYXNlID0gW107XG4gICAgICBicmVhaztcbiAgICBjYXNlICdtaW5vcic6XG4gICAgICAvLyBJZiB0aGlzIGlzIGEgcHJlLW1pbm9yIHZlcnNpb24sIGJ1bXAgdXAgdG8gdGhlIHNhbWUgbWlub3IgdmVyc2lvbi5cbiAgICAgIC8vIE90aGVyd2lzZSBpbmNyZW1lbnQgbWlub3IuXG4gICAgICAvLyAxLjIuMC01IGJ1bXBzIHRvIDEuMi4wXG4gICAgICAvLyAxLjIuMSBidW1wcyB0byAxLjMuMFxuICAgICAgaWYgKHRoaXMucGF0Y2ggIT09IDAgfHwgdGhpcy5wcmVyZWxlYXNlLmxlbmd0aCA9PT0gMClcbiAgICAgICAgdGhpcy5taW5vcisrO1xuICAgICAgdGhpcy5wYXRjaCA9IDA7XG4gICAgICB0aGlzLnByZXJlbGVhc2UgPSBbXTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3BhdGNoJzpcbiAgICAgIC8vIElmIHRoaXMgaXMgbm90IGEgcHJlLXJlbGVhc2UgdmVyc2lvbiwgaXQgd2lsbCBpbmNyZW1lbnQgdGhlIHBhdGNoLlxuICAgICAgLy8gSWYgaXQgaXMgYSBwcmUtcmVsZWFzZSBpdCB3aWxsIGJ1bXAgdXAgdG8gdGhlIHNhbWUgcGF0Y2ggdmVyc2lvbi5cbiAgICAgIC8vIDEuMi4wLTUgcGF0Y2hlcyB0byAxLjIuMFxuICAgICAgLy8gMS4yLjAgcGF0Y2hlcyB0byAxLjIuMVxuICAgICAgaWYgKHRoaXMucHJlcmVsZWFzZS5sZW5ndGggPT09IDApXG4gICAgICAgIHRoaXMucGF0Y2grKztcbiAgICAgIHRoaXMucHJlcmVsZWFzZSA9IFtdO1xuICAgICAgYnJlYWs7XG4gICAgLy8gVGhpcyBwcm9iYWJseSBzaG91bGRuJ3QgYmUgdXNlZCBwdWJsaWNseS5cbiAgICAvLyAxLjAuMCBcInByZVwiIHdvdWxkIGJlY29tZSAxLjAuMC0wIHdoaWNoIGlzIHRoZSB3cm9uZyBkaXJlY3Rpb24uXG4gICAgY2FzZSAncHJlJzpcbiAgICAgIGlmICh0aGlzLnByZXJlbGVhc2UubGVuZ3RoID09PSAwKVxuICAgICAgICB0aGlzLnByZXJlbGVhc2UgPSBbMF07XG4gICAgICBlbHNlIHtcbiAgICAgICAgdmFyIGkgPSB0aGlzLnByZXJlbGVhc2UubGVuZ3RoO1xuICAgICAgICB3aGlsZSAoLS1pID49IDApIHtcbiAgICAgICAgICBpZiAodHlwZW9mIHRoaXMucHJlcmVsZWFzZVtpXSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgIHRoaXMucHJlcmVsZWFzZVtpXSsrO1xuICAgICAgICAgICAgaSA9IC0yO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoaSA9PT0gLTEpIC8vIGRpZG4ndCBpbmNyZW1lbnQgYW55dGhpbmdcbiAgICAgICAgICB0aGlzLnByZXJlbGVhc2UucHVzaCgwKTtcbiAgICAgIH1cbiAgICAgIGlmIChpZGVudGlmaWVyKSB7XG4gICAgICAgIC8vIDEuMi4wLWJldGEuMSBidW1wcyB0byAxLjIuMC1iZXRhLjIsXG4gICAgICAgIC8vIDEuMi4wLWJldGEuZm9vYmx6IG9yIDEuMi4wLWJldGEgYnVtcHMgdG8gMS4yLjAtYmV0YS4wXG4gICAgICAgIGlmICh0aGlzLnByZXJlbGVhc2VbMF0gPT09IGlkZW50aWZpZXIpIHtcbiAgICAgICAgICBpZiAoaXNOYU4odGhpcy5wcmVyZWxlYXNlWzFdKSlcbiAgICAgICAgICAgIHRoaXMucHJlcmVsZWFzZSA9IFtpZGVudGlmaWVyLCAwXTtcbiAgICAgICAgfSBlbHNlXG4gICAgICAgICAgdGhpcy5wcmVyZWxlYXNlID0gW2lkZW50aWZpZXIsIDBdO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGluY3JlbWVudCBhcmd1bWVudDogJyArIHJlbGVhc2UpO1xuICB9XG4gIHRoaXMuZm9ybWF0KCk7XG4gIHRoaXMucmF3ID0gdGhpcy52ZXJzaW9uO1xuICByZXR1cm4gdGhpcztcbn07XG5cbmV4cG9ydHMuaW5jID0gaW5jO1xuZnVuY3Rpb24gaW5jKHZlcnNpb24sIHJlbGVhc2UsIGxvb3NlLCBpZGVudGlmaWVyKSB7XG4gIGlmICh0eXBlb2YobG9vc2UpID09PSAnc3RyaW5nJykge1xuICAgIGlkZW50aWZpZXIgPSBsb29zZTtcbiAgICBsb29zZSA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIHRyeSB7XG4gICAgcmV0dXJuIG5ldyBTZW1WZXIodmVyc2lvbiwgbG9vc2UpLmluYyhyZWxlYXNlLCBpZGVudGlmaWVyKS52ZXJzaW9uO1xuICB9IGNhdGNoIChlcikge1xuICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbmV4cG9ydHMuZGlmZiA9IGRpZmY7XG5mdW5jdGlvbiBkaWZmKHZlcnNpb24xLCB2ZXJzaW9uMikge1xuICBpZiAoZXEodmVyc2lvbjEsIHZlcnNpb24yKSkge1xuICAgIHJldHVybiBudWxsO1xuICB9IGVsc2Uge1xuICAgIHZhciB2MSA9IHBhcnNlKHZlcnNpb24xKTtcbiAgICB2YXIgdjIgPSBwYXJzZSh2ZXJzaW9uMik7XG4gICAgaWYgKHYxLnByZXJlbGVhc2UubGVuZ3RoIHx8IHYyLnByZXJlbGVhc2UubGVuZ3RoKSB7XG4gICAgICBmb3IgKHZhciBrZXkgaW4gdjEpIHtcbiAgICAgICAgaWYgKGtleSA9PT0gJ21ham9yJyB8fCBrZXkgPT09ICdtaW5vcicgfHwga2V5ID09PSAncGF0Y2gnKSB7XG4gICAgICAgICAgaWYgKHYxW2tleV0gIT09IHYyW2tleV0pIHtcbiAgICAgICAgICAgIHJldHVybiAncHJlJytrZXk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gJ3ByZXJlbGVhc2UnO1xuICAgIH1cbiAgICBmb3IgKHZhciBrZXkgaW4gdjEpIHtcbiAgICAgIGlmIChrZXkgPT09ICdtYWpvcicgfHwga2V5ID09PSAnbWlub3InIHx8IGtleSA9PT0gJ3BhdGNoJykge1xuICAgICAgICBpZiAodjFba2V5XSAhPT0gdjJba2V5XSkge1xuICAgICAgICAgIHJldHVybiBrZXk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0cy5jb21wYXJlSWRlbnRpZmllcnMgPSBjb21wYXJlSWRlbnRpZmllcnM7XG5cbnZhciBudW1lcmljID0gL15bMC05XSskLztcbmZ1bmN0aW9uIGNvbXBhcmVJZGVudGlmaWVycyhhLCBiKSB7XG4gIHZhciBhbnVtID0gbnVtZXJpYy50ZXN0KGEpO1xuICB2YXIgYm51bSA9IG51bWVyaWMudGVzdChiKTtcblxuICBpZiAoYW51bSAmJiBibnVtKSB7XG4gICAgYSA9ICthO1xuICAgIGIgPSArYjtcbiAgfVxuXG4gIHJldHVybiAoYW51bSAmJiAhYm51bSkgPyAtMSA6XG4gICAgICAgICAoYm51bSAmJiAhYW51bSkgPyAxIDpcbiAgICAgICAgIGEgPCBiID8gLTEgOlxuICAgICAgICAgYSA+IGIgPyAxIDpcbiAgICAgICAgIDA7XG59XG5cbmV4cG9ydHMucmNvbXBhcmVJZGVudGlmaWVycyA9IHJjb21wYXJlSWRlbnRpZmllcnM7XG5mdW5jdGlvbiByY29tcGFyZUlkZW50aWZpZXJzKGEsIGIpIHtcbiAgcmV0dXJuIGNvbXBhcmVJZGVudGlmaWVycyhiLCBhKTtcbn1cblxuZXhwb3J0cy5tYWpvciA9IG1ham9yO1xuZnVuY3Rpb24gbWFqb3IoYSwgbG9vc2UpIHtcbiAgcmV0dXJuIG5ldyBTZW1WZXIoYSwgbG9vc2UpLm1ham9yO1xufVxuXG5leHBvcnRzLm1pbm9yID0gbWlub3I7XG5mdW5jdGlvbiBtaW5vcihhLCBsb29zZSkge1xuICByZXR1cm4gbmV3IFNlbVZlcihhLCBsb29zZSkubWlub3I7XG59XG5cbmV4cG9ydHMucGF0Y2ggPSBwYXRjaDtcbmZ1bmN0aW9uIHBhdGNoKGEsIGxvb3NlKSB7XG4gIHJldHVybiBuZXcgU2VtVmVyKGEsIGxvb3NlKS5wYXRjaDtcbn1cblxuZXhwb3J0cy5jb21wYXJlID0gY29tcGFyZTtcbmZ1bmN0aW9uIGNvbXBhcmUoYSwgYiwgbG9vc2UpIHtcbiAgcmV0dXJuIG5ldyBTZW1WZXIoYSwgbG9vc2UpLmNvbXBhcmUoYik7XG59XG5cbmV4cG9ydHMuY29tcGFyZUxvb3NlID0gY29tcGFyZUxvb3NlO1xuZnVuY3Rpb24gY29tcGFyZUxvb3NlKGEsIGIpIHtcbiAgcmV0dXJuIGNvbXBhcmUoYSwgYiwgdHJ1ZSk7XG59XG5cbmV4cG9ydHMucmNvbXBhcmUgPSByY29tcGFyZTtcbmZ1bmN0aW9uIHJjb21wYXJlKGEsIGIsIGxvb3NlKSB7XG4gIHJldHVybiBjb21wYXJlKGIsIGEsIGxvb3NlKTtcbn1cblxuZXhwb3J0cy5zb3J0ID0gc29ydDtcbmZ1bmN0aW9uIHNvcnQobGlzdCwgbG9vc2UpIHtcbiAgcmV0dXJuIGxpc3Quc29ydChmdW5jdGlvbihhLCBiKSB7XG4gICAgcmV0dXJuIGV4cG9ydHMuY29tcGFyZShhLCBiLCBsb29zZSk7XG4gIH0pO1xufVxuXG5leHBvcnRzLnJzb3J0ID0gcnNvcnQ7XG5mdW5jdGlvbiByc29ydChsaXN0LCBsb29zZSkge1xuICByZXR1cm4gbGlzdC5zb3J0KGZ1bmN0aW9uKGEsIGIpIHtcbiAgICByZXR1cm4gZXhwb3J0cy5yY29tcGFyZShhLCBiLCBsb29zZSk7XG4gIH0pO1xufVxuXG5leHBvcnRzLmd0ID0gZ3Q7XG5mdW5jdGlvbiBndChhLCBiLCBsb29zZSkge1xuICByZXR1cm4gY29tcGFyZShhLCBiLCBsb29zZSkgPiAwO1xufVxuXG5leHBvcnRzLmx0ID0gbHQ7XG5mdW5jdGlvbiBsdChhLCBiLCBsb29zZSkge1xuICByZXR1cm4gY29tcGFyZShhLCBiLCBsb29zZSkgPCAwO1xufVxuXG5leHBvcnRzLmVxID0gZXE7XG5mdW5jdGlvbiBlcShhLCBiLCBsb29zZSkge1xuICByZXR1cm4gY29tcGFyZShhLCBiLCBsb29zZSkgPT09IDA7XG59XG5cbmV4cG9ydHMubmVxID0gbmVxO1xuZnVuY3Rpb24gbmVxKGEsIGIsIGxvb3NlKSB7XG4gIHJldHVybiBjb21wYXJlKGEsIGIsIGxvb3NlKSAhPT0gMDtcbn1cblxuZXhwb3J0cy5ndGUgPSBndGU7XG5mdW5jdGlvbiBndGUoYSwgYiwgbG9vc2UpIHtcbiAgcmV0dXJuIGNvbXBhcmUoYSwgYiwgbG9vc2UpID49IDA7XG59XG5cbmV4cG9ydHMubHRlID0gbHRlO1xuZnVuY3Rpb24gbHRlKGEsIGIsIGxvb3NlKSB7XG4gIHJldHVybiBjb21wYXJlKGEsIGIsIGxvb3NlKSA8PSAwO1xufVxuXG5leHBvcnRzLmNtcCA9IGNtcDtcbmZ1bmN0aW9uIGNtcChhLCBvcCwgYiwgbG9vc2UpIHtcbiAgdmFyIHJldDtcbiAgc3dpdGNoIChvcCkge1xuICAgIGNhc2UgJz09PSc6XG4gICAgICBpZiAodHlwZW9mIGEgPT09ICdvYmplY3QnKSBhID0gYS52ZXJzaW9uO1xuICAgICAgaWYgKHR5cGVvZiBiID09PSAnb2JqZWN0JykgYiA9IGIudmVyc2lvbjtcbiAgICAgIHJldCA9IGEgPT09IGI7XG4gICAgICBicmVhaztcbiAgICBjYXNlICchPT0nOlxuICAgICAgaWYgKHR5cGVvZiBhID09PSAnb2JqZWN0JykgYSA9IGEudmVyc2lvbjtcbiAgICAgIGlmICh0eXBlb2YgYiA9PT0gJ29iamVjdCcpIGIgPSBiLnZlcnNpb247XG4gICAgICByZXQgPSBhICE9PSBiO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnJzogY2FzZSAnPSc6IGNhc2UgJz09JzogcmV0ID0gZXEoYSwgYiwgbG9vc2UpOyBicmVhaztcbiAgICBjYXNlICchPSc6IHJldCA9IG5lcShhLCBiLCBsb29zZSk7IGJyZWFrO1xuICAgIGNhc2UgJz4nOiByZXQgPSBndChhLCBiLCBsb29zZSk7IGJyZWFrO1xuICAgIGNhc2UgJz49JzogcmV0ID0gZ3RlKGEsIGIsIGxvb3NlKTsgYnJlYWs7XG4gICAgY2FzZSAnPCc6IHJldCA9IGx0KGEsIGIsIGxvb3NlKTsgYnJlYWs7XG4gICAgY2FzZSAnPD0nOiByZXQgPSBsdGUoYSwgYiwgbG9vc2UpOyBicmVhaztcbiAgICBkZWZhdWx0OiB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG9wZXJhdG9yOiAnICsgb3ApO1xuICB9XG4gIHJldHVybiByZXQ7XG59XG5cbmV4cG9ydHMuQ29tcGFyYXRvciA9IENvbXBhcmF0b3I7XG5mdW5jdGlvbiBDb21wYXJhdG9yKGNvbXAsIGxvb3NlKSB7XG4gIGlmIChjb21wIGluc3RhbmNlb2YgQ29tcGFyYXRvcikge1xuICAgIGlmIChjb21wLmxvb3NlID09PSBsb29zZSlcbiAgICAgIHJldHVybiBjb21wO1xuICAgIGVsc2VcbiAgICAgIGNvbXAgPSBjb21wLnZhbHVlO1xuICB9XG5cbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIENvbXBhcmF0b3IpKVxuICAgIHJldHVybiBuZXcgQ29tcGFyYXRvcihjb21wLCBsb29zZSk7XG5cbiAgZGVidWcoJ2NvbXBhcmF0b3InLCBjb21wLCBsb29zZSk7XG4gIHRoaXMubG9vc2UgPSBsb29zZTtcbiAgdGhpcy5wYXJzZShjb21wKTtcblxuICBpZiAodGhpcy5zZW12ZXIgPT09IEFOWSlcbiAgICB0aGlzLnZhbHVlID0gJyc7XG4gIGVsc2VcbiAgICB0aGlzLnZhbHVlID0gdGhpcy5vcGVyYXRvciArIHRoaXMuc2VtdmVyLnZlcnNpb247XG5cbiAgZGVidWcoJ2NvbXAnLCB0aGlzKTtcbn1cblxudmFyIEFOWSA9IHt9O1xuQ29tcGFyYXRvci5wcm90b3R5cGUucGFyc2UgPSBmdW5jdGlvbihjb21wKSB7XG4gIHZhciByID0gdGhpcy5sb29zZSA/IHJlW0NPTVBBUkFUT1JMT09TRV0gOiByZVtDT01QQVJBVE9SXTtcbiAgdmFyIG0gPSBjb21wLm1hdGNoKHIpO1xuXG4gIGlmICghbSlcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIGNvbXBhcmF0b3I6ICcgKyBjb21wKTtcblxuICB0aGlzLm9wZXJhdG9yID0gbVsxXTtcbiAgaWYgKHRoaXMub3BlcmF0b3IgPT09ICc9JylcbiAgICB0aGlzLm9wZXJhdG9yID0gJyc7XG5cbiAgLy8gaWYgaXQgbGl0ZXJhbGx5IGlzIGp1c3QgJz4nIG9yICcnIHRoZW4gYWxsb3cgYW55dGhpbmcuXG4gIGlmICghbVsyXSlcbiAgICB0aGlzLnNlbXZlciA9IEFOWTtcbiAgZWxzZVxuICAgIHRoaXMuc2VtdmVyID0gbmV3IFNlbVZlcihtWzJdLCB0aGlzLmxvb3NlKTtcbn07XG5cbkNvbXBhcmF0b3IucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLnZhbHVlO1xufTtcblxuQ29tcGFyYXRvci5wcm90b3R5cGUudGVzdCA9IGZ1bmN0aW9uKHZlcnNpb24pIHtcbiAgZGVidWcoJ0NvbXBhcmF0b3IudGVzdCcsIHZlcnNpb24sIHRoaXMubG9vc2UpO1xuXG4gIGlmICh0aGlzLnNlbXZlciA9PT0gQU5ZKVxuICAgIHJldHVybiB0cnVlO1xuXG4gIGlmICh0eXBlb2YgdmVyc2lvbiA9PT0gJ3N0cmluZycpXG4gICAgdmVyc2lvbiA9IG5ldyBTZW1WZXIodmVyc2lvbiwgdGhpcy5sb29zZSk7XG5cbiAgcmV0dXJuIGNtcCh2ZXJzaW9uLCB0aGlzLm9wZXJhdG9yLCB0aGlzLnNlbXZlciwgdGhpcy5sb29zZSk7XG59O1xuXG5cbmV4cG9ydHMuUmFuZ2UgPSBSYW5nZTtcbmZ1bmN0aW9uIFJhbmdlKHJhbmdlLCBsb29zZSkge1xuICBpZiAoKHJhbmdlIGluc3RhbmNlb2YgUmFuZ2UpICYmIHJhbmdlLmxvb3NlID09PSBsb29zZSlcbiAgICByZXR1cm4gcmFuZ2U7XG5cbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFJhbmdlKSlcbiAgICByZXR1cm4gbmV3IFJhbmdlKHJhbmdlLCBsb29zZSk7XG5cbiAgdGhpcy5sb29zZSA9IGxvb3NlO1xuXG4gIC8vIEZpcnN0LCBzcGxpdCBiYXNlZCBvbiBib29sZWFuIG9yIHx8XG4gIHRoaXMucmF3ID0gcmFuZ2U7XG4gIHRoaXMuc2V0ID0gcmFuZ2Uuc3BsaXQoL1xccypcXHxcXHxcXHMqLykubWFwKGZ1bmN0aW9uKHJhbmdlKSB7XG4gICAgcmV0dXJuIHRoaXMucGFyc2VSYW5nZShyYW5nZS50cmltKCkpO1xuICB9LCB0aGlzKS5maWx0ZXIoZnVuY3Rpb24oYykge1xuICAgIC8vIHRocm93IG91dCBhbnkgdGhhdCBhcmUgbm90IHJlbGV2YW50IGZvciB3aGF0ZXZlciByZWFzb25cbiAgICByZXR1cm4gYy5sZW5ndGg7XG4gIH0pO1xuXG4gIGlmICghdGhpcy5zZXQubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBTZW1WZXIgUmFuZ2U6ICcgKyByYW5nZSk7XG4gIH1cblxuICB0aGlzLmZvcm1hdCgpO1xufVxuXG5SYW5nZS5wcm90b3R5cGUuZm9ybWF0ID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMucmFuZ2UgPSB0aGlzLnNldC5tYXAoZnVuY3Rpb24oY29tcHMpIHtcbiAgICByZXR1cm4gY29tcHMuam9pbignICcpLnRyaW0oKTtcbiAgfSkuam9pbignfHwnKS50cmltKCk7XG4gIHJldHVybiB0aGlzLnJhbmdlO1xufTtcblxuUmFuZ2UucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLnJhbmdlO1xufTtcblxuUmFuZ2UucHJvdG90eXBlLnBhcnNlUmFuZ2UgPSBmdW5jdGlvbihyYW5nZSkge1xuICB2YXIgbG9vc2UgPSB0aGlzLmxvb3NlO1xuICByYW5nZSA9IHJhbmdlLnRyaW0oKTtcbiAgZGVidWcoJ3JhbmdlJywgcmFuZ2UsIGxvb3NlKTtcbiAgLy8gYDEuMi4zIC0gMS4yLjRgID0+IGA+PTEuMi4zIDw9MS4yLjRgXG4gIHZhciBociA9IGxvb3NlID8gcmVbSFlQSEVOUkFOR0VMT09TRV0gOiByZVtIWVBIRU5SQU5HRV07XG4gIHJhbmdlID0gcmFuZ2UucmVwbGFjZShociwgaHlwaGVuUmVwbGFjZSk7XG4gIGRlYnVnKCdoeXBoZW4gcmVwbGFjZScsIHJhbmdlKTtcbiAgLy8gYD4gMS4yLjMgPCAxLjIuNWAgPT4gYD4xLjIuMyA8MS4yLjVgXG4gIHJhbmdlID0gcmFuZ2UucmVwbGFjZShyZVtDT01QQVJBVE9SVFJJTV0sIGNvbXBhcmF0b3JUcmltUmVwbGFjZSk7XG4gIGRlYnVnKCdjb21wYXJhdG9yIHRyaW0nLCByYW5nZSwgcmVbQ09NUEFSQVRPUlRSSU1dKTtcblxuICAvLyBgfiAxLjIuM2AgPT4gYH4xLjIuM2BcbiAgcmFuZ2UgPSByYW5nZS5yZXBsYWNlKHJlW1RJTERFVFJJTV0sIHRpbGRlVHJpbVJlcGxhY2UpO1xuXG4gIC8vIGBeIDEuMi4zYCA9PiBgXjEuMi4zYFxuICByYW5nZSA9IHJhbmdlLnJlcGxhY2UocmVbQ0FSRVRUUklNXSwgY2FyZXRUcmltUmVwbGFjZSk7XG5cbiAgLy8gbm9ybWFsaXplIHNwYWNlc1xuICByYW5nZSA9IHJhbmdlLnNwbGl0KC9cXHMrLykuam9pbignICcpO1xuXG4gIC8vIEF0IHRoaXMgcG9pbnQsIHRoZSByYW5nZSBpcyBjb21wbGV0ZWx5IHRyaW1tZWQgYW5kXG4gIC8vIHJlYWR5IHRvIGJlIHNwbGl0IGludG8gY29tcGFyYXRvcnMuXG5cbiAgdmFyIGNvbXBSZSA9IGxvb3NlID8gcmVbQ09NUEFSQVRPUkxPT1NFXSA6IHJlW0NPTVBBUkFUT1JdO1xuICB2YXIgc2V0ID0gcmFuZ2Uuc3BsaXQoJyAnKS5tYXAoZnVuY3Rpb24oY29tcCkge1xuICAgIHJldHVybiBwYXJzZUNvbXBhcmF0b3IoY29tcCwgbG9vc2UpO1xuICB9KS5qb2luKCcgJykuc3BsaXQoL1xccysvKTtcbiAgaWYgKHRoaXMubG9vc2UpIHtcbiAgICAvLyBpbiBsb29zZSBtb2RlLCB0aHJvdyBvdXQgYW55IHRoYXQgYXJlIG5vdCB2YWxpZCBjb21wYXJhdG9yc1xuICAgIHNldCA9IHNldC5maWx0ZXIoZnVuY3Rpb24oY29tcCkge1xuICAgICAgcmV0dXJuICEhY29tcC5tYXRjaChjb21wUmUpO1xuICAgIH0pO1xuICB9XG4gIHNldCA9IHNldC5tYXAoZnVuY3Rpb24oY29tcCkge1xuICAgIHJldHVybiBuZXcgQ29tcGFyYXRvcihjb21wLCBsb29zZSk7XG4gIH0pO1xuXG4gIHJldHVybiBzZXQ7XG59O1xuXG4vLyBNb3N0bHkganVzdCBmb3IgdGVzdGluZyBhbmQgbGVnYWN5IEFQSSByZWFzb25zXG5leHBvcnRzLnRvQ29tcGFyYXRvcnMgPSB0b0NvbXBhcmF0b3JzO1xuZnVuY3Rpb24gdG9Db21wYXJhdG9ycyhyYW5nZSwgbG9vc2UpIHtcbiAgcmV0dXJuIG5ldyBSYW5nZShyYW5nZSwgbG9vc2UpLnNldC5tYXAoZnVuY3Rpb24oY29tcCkge1xuICAgIHJldHVybiBjb21wLm1hcChmdW5jdGlvbihjKSB7XG4gICAgICByZXR1cm4gYy52YWx1ZTtcbiAgICB9KS5qb2luKCcgJykudHJpbSgpLnNwbGl0KCcgJyk7XG4gIH0pO1xufVxuXG4vLyBjb21wcmlzZWQgb2YgeHJhbmdlcywgdGlsZGVzLCBzdGFycywgYW5kIGd0bHQncyBhdCB0aGlzIHBvaW50LlxuLy8gYWxyZWFkeSByZXBsYWNlZCB0aGUgaHlwaGVuIHJhbmdlc1xuLy8gdHVybiBpbnRvIGEgc2V0IG9mIEpVU1QgY29tcGFyYXRvcnMuXG5mdW5jdGlvbiBwYXJzZUNvbXBhcmF0b3IoY29tcCwgbG9vc2UpIHtcbiAgZGVidWcoJ2NvbXAnLCBjb21wKTtcbiAgY29tcCA9IHJlcGxhY2VDYXJldHMoY29tcCwgbG9vc2UpO1xuICBkZWJ1ZygnY2FyZXQnLCBjb21wKTtcbiAgY29tcCA9IHJlcGxhY2VUaWxkZXMoY29tcCwgbG9vc2UpO1xuICBkZWJ1ZygndGlsZGVzJywgY29tcCk7XG4gIGNvbXAgPSByZXBsYWNlWFJhbmdlcyhjb21wLCBsb29zZSk7XG4gIGRlYnVnKCd4cmFuZ2UnLCBjb21wKTtcbiAgY29tcCA9IHJlcGxhY2VTdGFycyhjb21wLCBsb29zZSk7XG4gIGRlYnVnKCdzdGFycycsIGNvbXApO1xuICByZXR1cm4gY29tcDtcbn1cblxuZnVuY3Rpb24gaXNYKGlkKSB7XG4gIHJldHVybiAhaWQgfHwgaWQudG9Mb3dlckNhc2UoKSA9PT0gJ3gnIHx8IGlkID09PSAnKic7XG59XG5cbi8vIH4sIH4+IC0tPiAqIChhbnksIGtpbmRhIHNpbGx5KVxuLy8gfjIsIH4yLngsIH4yLngueCwgfj4yLCB+PjIueCB+PjIueC54IC0tPiA+PTIuMC4wIDwzLjAuMFxuLy8gfjIuMCwgfjIuMC54LCB+PjIuMCwgfj4yLjAueCAtLT4gPj0yLjAuMCA8Mi4xLjBcbi8vIH4xLjIsIH4xLjIueCwgfj4xLjIsIH4+MS4yLnggLS0+ID49MS4yLjAgPDEuMy4wXG4vLyB+MS4yLjMsIH4+MS4yLjMgLS0+ID49MS4yLjMgPDEuMy4wXG4vLyB+MS4yLjAsIH4+MS4yLjAgLS0+ID49MS4yLjAgPDEuMy4wXG5mdW5jdGlvbiByZXBsYWNlVGlsZGVzKGNvbXAsIGxvb3NlKSB7XG4gIHJldHVybiBjb21wLnRyaW0oKS5zcGxpdCgvXFxzKy8pLm1hcChmdW5jdGlvbihjb21wKSB7XG4gICAgcmV0dXJuIHJlcGxhY2VUaWxkZShjb21wLCBsb29zZSk7XG4gIH0pLmpvaW4oJyAnKTtcbn1cblxuZnVuY3Rpb24gcmVwbGFjZVRpbGRlKGNvbXAsIGxvb3NlKSB7XG4gIHZhciByID0gbG9vc2UgPyByZVtUSUxERUxPT1NFXSA6IHJlW1RJTERFXTtcbiAgcmV0dXJuIGNvbXAucmVwbGFjZShyLCBmdW5jdGlvbihfLCBNLCBtLCBwLCBwcikge1xuICAgIGRlYnVnKCd0aWxkZScsIGNvbXAsIF8sIE0sIG0sIHAsIHByKTtcbiAgICB2YXIgcmV0O1xuXG4gICAgaWYgKGlzWChNKSlcbiAgICAgIHJldCA9ICcnO1xuICAgIGVsc2UgaWYgKGlzWChtKSlcbiAgICAgIHJldCA9ICc+PScgKyBNICsgJy4wLjAgPCcgKyAoK00gKyAxKSArICcuMC4wJztcbiAgICBlbHNlIGlmIChpc1gocCkpXG4gICAgICAvLyB+MS4yID09ID49MS4yLjAtIDwxLjMuMC1cbiAgICAgIHJldCA9ICc+PScgKyBNICsgJy4nICsgbSArICcuMCA8JyArIE0gKyAnLicgKyAoK20gKyAxKSArICcuMCc7XG4gICAgZWxzZSBpZiAocHIpIHtcbiAgICAgIGRlYnVnKCdyZXBsYWNlVGlsZGUgcHInLCBwcik7XG4gICAgICBpZiAocHIuY2hhckF0KDApICE9PSAnLScpXG4gICAgICAgIHByID0gJy0nICsgcHI7XG4gICAgICByZXQgPSAnPj0nICsgTSArICcuJyArIG0gKyAnLicgKyBwICsgcHIgK1xuICAgICAgICAgICAgJyA8JyArIE0gKyAnLicgKyAoK20gKyAxKSArICcuMCc7XG4gICAgfSBlbHNlXG4gICAgICAvLyB+MS4yLjMgPT0gPj0xLjIuMyA8MS4zLjBcbiAgICAgIHJldCA9ICc+PScgKyBNICsgJy4nICsgbSArICcuJyArIHAgK1xuICAgICAgICAgICAgJyA8JyArIE0gKyAnLicgKyAoK20gKyAxKSArICcuMCc7XG5cbiAgICBkZWJ1ZygndGlsZGUgcmV0dXJuJywgcmV0KTtcbiAgICByZXR1cm4gcmV0O1xuICB9KTtcbn1cblxuLy8gXiAtLT4gKiAoYW55LCBraW5kYSBzaWxseSlcbi8vIF4yLCBeMi54LCBeMi54LnggLS0+ID49Mi4wLjAgPDMuMC4wXG4vLyBeMi4wLCBeMi4wLnggLS0+ID49Mi4wLjAgPDMuMC4wXG4vLyBeMS4yLCBeMS4yLnggLS0+ID49MS4yLjAgPDIuMC4wXG4vLyBeMS4yLjMgLS0+ID49MS4yLjMgPDIuMC4wXG4vLyBeMS4yLjAgLS0+ID49MS4yLjAgPDIuMC4wXG5mdW5jdGlvbiByZXBsYWNlQ2FyZXRzKGNvbXAsIGxvb3NlKSB7XG4gIHJldHVybiBjb21wLnRyaW0oKS5zcGxpdCgvXFxzKy8pLm1hcChmdW5jdGlvbihjb21wKSB7XG4gICAgcmV0dXJuIHJlcGxhY2VDYXJldChjb21wLCBsb29zZSk7XG4gIH0pLmpvaW4oJyAnKTtcbn1cblxuZnVuY3Rpb24gcmVwbGFjZUNhcmV0KGNvbXAsIGxvb3NlKSB7XG4gIGRlYnVnKCdjYXJldCcsIGNvbXAsIGxvb3NlKTtcbiAgdmFyIHIgPSBsb29zZSA/IHJlW0NBUkVUTE9PU0VdIDogcmVbQ0FSRVRdO1xuICByZXR1cm4gY29tcC5yZXBsYWNlKHIsIGZ1bmN0aW9uKF8sIE0sIG0sIHAsIHByKSB7XG4gICAgZGVidWcoJ2NhcmV0JywgY29tcCwgXywgTSwgbSwgcCwgcHIpO1xuICAgIHZhciByZXQ7XG5cbiAgICBpZiAoaXNYKE0pKVxuICAgICAgcmV0ID0gJyc7XG4gICAgZWxzZSBpZiAoaXNYKG0pKVxuICAgICAgcmV0ID0gJz49JyArIE0gKyAnLjAuMCA8JyArICgrTSArIDEpICsgJy4wLjAnO1xuICAgIGVsc2UgaWYgKGlzWChwKSkge1xuICAgICAgaWYgKE0gPT09ICcwJylcbiAgICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4wIDwnICsgTSArICcuJyArICgrbSArIDEpICsgJy4wJztcbiAgICAgIGVsc2VcbiAgICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4wIDwnICsgKCtNICsgMSkgKyAnLjAuMCc7XG4gICAgfSBlbHNlIGlmIChwcikge1xuICAgICAgZGVidWcoJ3JlcGxhY2VDYXJldCBwcicsIHByKTtcbiAgICAgIGlmIChwci5jaGFyQXQoMCkgIT09ICctJylcbiAgICAgICAgcHIgPSAnLScgKyBwcjtcbiAgICAgIGlmIChNID09PSAnMCcpIHtcbiAgICAgICAgaWYgKG0gPT09ICcwJylcbiAgICAgICAgICByZXQgPSAnPj0nICsgTSArICcuJyArIG0gKyAnLicgKyBwICsgcHIgK1xuICAgICAgICAgICAgICAgICcgPCcgKyBNICsgJy4nICsgbSArICcuJyArICgrcCArIDEpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4nICsgcCArIHByICtcbiAgICAgICAgICAgICAgICAnIDwnICsgTSArICcuJyArICgrbSArIDEpICsgJy4wJztcbiAgICAgIH0gZWxzZVxuICAgICAgICByZXQgPSAnPj0nICsgTSArICcuJyArIG0gKyAnLicgKyBwICsgcHIgK1xuICAgICAgICAgICAgICAnIDwnICsgKCtNICsgMSkgKyAnLjAuMCc7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlYnVnKCdubyBwcicpO1xuICAgICAgaWYgKE0gPT09ICcwJykge1xuICAgICAgICBpZiAobSA9PT0gJzAnKVxuICAgICAgICAgIHJldCA9ICc+PScgKyBNICsgJy4nICsgbSArICcuJyArIHAgK1xuICAgICAgICAgICAgICAgICcgPCcgKyBNICsgJy4nICsgbSArICcuJyArICgrcCArIDEpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4nICsgcCArXG4gICAgICAgICAgICAgICAgJyA8JyArIE0gKyAnLicgKyAoK20gKyAxKSArICcuMCc7XG4gICAgICB9IGVsc2VcbiAgICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4nICsgcCArXG4gICAgICAgICAgICAgICcgPCcgKyAoK00gKyAxKSArICcuMC4wJztcbiAgICB9XG5cbiAgICBkZWJ1ZygnY2FyZXQgcmV0dXJuJywgcmV0KTtcbiAgICByZXR1cm4gcmV0O1xuICB9KTtcbn1cblxuZnVuY3Rpb24gcmVwbGFjZVhSYW5nZXMoY29tcCwgbG9vc2UpIHtcbiAgZGVidWcoJ3JlcGxhY2VYUmFuZ2VzJywgY29tcCwgbG9vc2UpO1xuICByZXR1cm4gY29tcC5zcGxpdCgvXFxzKy8pLm1hcChmdW5jdGlvbihjb21wKSB7XG4gICAgcmV0dXJuIHJlcGxhY2VYUmFuZ2UoY29tcCwgbG9vc2UpO1xuICB9KS5qb2luKCcgJyk7XG59XG5cbmZ1bmN0aW9uIHJlcGxhY2VYUmFuZ2UoY29tcCwgbG9vc2UpIHtcbiAgY29tcCA9IGNvbXAudHJpbSgpO1xuICB2YXIgciA9IGxvb3NlID8gcmVbWFJBTkdFTE9PU0VdIDogcmVbWFJBTkdFXTtcbiAgcmV0dXJuIGNvbXAucmVwbGFjZShyLCBmdW5jdGlvbihyZXQsIGd0bHQsIE0sIG0sIHAsIHByKSB7XG4gICAgZGVidWcoJ3hSYW5nZScsIGNvbXAsIHJldCwgZ3RsdCwgTSwgbSwgcCwgcHIpO1xuICAgIHZhciB4TSA9IGlzWChNKTtcbiAgICB2YXIgeG0gPSB4TSB8fCBpc1gobSk7XG4gICAgdmFyIHhwID0geG0gfHwgaXNYKHApO1xuICAgIHZhciBhbnlYID0geHA7XG5cbiAgICBpZiAoZ3RsdCA9PT0gJz0nICYmIGFueVgpXG4gICAgICBndGx0ID0gJyc7XG5cbiAgICBpZiAoeE0pIHtcbiAgICAgIGlmIChndGx0ID09PSAnPicgfHwgZ3RsdCA9PT0gJzwnKSB7XG4gICAgICAgIC8vIG5vdGhpbmcgaXMgYWxsb3dlZFxuICAgICAgICByZXQgPSAnPDAuMC4wJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIG5vdGhpbmcgaXMgZm9yYmlkZGVuXG4gICAgICAgIHJldCA9ICcqJztcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGd0bHQgJiYgYW55WCkge1xuICAgICAgLy8gcmVwbGFjZSBYIHdpdGggMFxuICAgICAgaWYgKHhtKVxuICAgICAgICBtID0gMDtcbiAgICAgIGlmICh4cClcbiAgICAgICAgcCA9IDA7XG5cbiAgICAgIGlmIChndGx0ID09PSAnPicpIHtcbiAgICAgICAgLy8gPjEgPT4gPj0yLjAuMFxuICAgICAgICAvLyA+MS4yID0+ID49MS4zLjBcbiAgICAgICAgLy8gPjEuMi4zID0+ID49IDEuMi40XG4gICAgICAgIGd0bHQgPSAnPj0nO1xuICAgICAgICBpZiAoeG0pIHtcbiAgICAgICAgICBNID0gK00gKyAxO1xuICAgICAgICAgIG0gPSAwO1xuICAgICAgICAgIHAgPSAwO1xuICAgICAgICB9IGVsc2UgaWYgKHhwKSB7XG4gICAgICAgICAgbSA9ICttICsgMTtcbiAgICAgICAgICBwID0gMDtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChndGx0ID09PSAnPD0nKSB7XG4gICAgICAgIC8vIDw9MC43LnggaXMgYWN0dWFsbHkgPDAuOC4wLCBzaW5jZSBhbnkgMC43Lnggc2hvdWxkXG4gICAgICAgIC8vIHBhc3MuICBTaW1pbGFybHksIDw9Ny54IGlzIGFjdHVhbGx5IDw4LjAuMCwgZXRjLlxuICAgICAgICBndGx0ID0gJzwnXG4gICAgICAgIGlmICh4bSlcbiAgICAgICAgICBNID0gK00gKyAxXG4gICAgICAgIGVsc2VcbiAgICAgICAgICBtID0gK20gKyAxXG4gICAgICB9XG5cbiAgICAgIHJldCA9IGd0bHQgKyBNICsgJy4nICsgbSArICcuJyArIHA7XG4gICAgfSBlbHNlIGlmICh4bSkge1xuICAgICAgcmV0ID0gJz49JyArIE0gKyAnLjAuMCA8JyArICgrTSArIDEpICsgJy4wLjAnO1xuICAgIH0gZWxzZSBpZiAoeHApIHtcbiAgICAgIHJldCA9ICc+PScgKyBNICsgJy4nICsgbSArICcuMCA8JyArIE0gKyAnLicgKyAoK20gKyAxKSArICcuMCc7XG4gICAgfVxuXG4gICAgZGVidWcoJ3hSYW5nZSByZXR1cm4nLCByZXQpO1xuXG4gICAgcmV0dXJuIHJldDtcbiAgfSk7XG59XG5cbi8vIEJlY2F1c2UgKiBpcyBBTkQtZWQgd2l0aCBldmVyeXRoaW5nIGVsc2UgaW4gdGhlIGNvbXBhcmF0b3IsXG4vLyBhbmQgJycgbWVhbnMgXCJhbnkgdmVyc2lvblwiLCBqdXN0IHJlbW92ZSB0aGUgKnMgZW50aXJlbHkuXG5mdW5jdGlvbiByZXBsYWNlU3RhcnMoY29tcCwgbG9vc2UpIHtcbiAgZGVidWcoJ3JlcGxhY2VTdGFycycsIGNvbXAsIGxvb3NlKTtcbiAgLy8gTG9vc2VuZXNzIGlzIGlnbm9yZWQgaGVyZS4gIHN0YXIgaXMgYWx3YXlzIGFzIGxvb3NlIGFzIGl0IGdldHMhXG4gIHJldHVybiBjb21wLnRyaW0oKS5yZXBsYWNlKHJlW1NUQVJdLCAnJyk7XG59XG5cbi8vIFRoaXMgZnVuY3Rpb24gaXMgcGFzc2VkIHRvIHN0cmluZy5yZXBsYWNlKHJlW0hZUEhFTlJBTkdFXSlcbi8vIE0sIG0sIHBhdGNoLCBwcmVyZWxlYXNlLCBidWlsZFxuLy8gMS4yIC0gMy40LjUgPT4gPj0xLjIuMCA8PTMuNC41XG4vLyAxLjIuMyAtIDMuNCA9PiA+PTEuMi4wIDwzLjUuMCBBbnkgMy40Lnggd2lsbCBkb1xuLy8gMS4yIC0gMy40ID0+ID49MS4yLjAgPDMuNS4wXG5mdW5jdGlvbiBoeXBoZW5SZXBsYWNlKCQwLFxuICAgICAgICAgICAgICAgICAgICAgICBmcm9tLCBmTSwgZm0sIGZwLCBmcHIsIGZiLFxuICAgICAgICAgICAgICAgICAgICAgICB0bywgdE0sIHRtLCB0cCwgdHByLCB0Yikge1xuXG4gIGlmIChpc1goZk0pKVxuICAgIGZyb20gPSAnJztcbiAgZWxzZSBpZiAoaXNYKGZtKSlcbiAgICBmcm9tID0gJz49JyArIGZNICsgJy4wLjAnO1xuICBlbHNlIGlmIChpc1goZnApKVxuICAgIGZyb20gPSAnPj0nICsgZk0gKyAnLicgKyBmbSArICcuMCc7XG4gIGVsc2VcbiAgICBmcm9tID0gJz49JyArIGZyb207XG5cbiAgaWYgKGlzWCh0TSkpXG4gICAgdG8gPSAnJztcbiAgZWxzZSBpZiAoaXNYKHRtKSlcbiAgICB0byA9ICc8JyArICgrdE0gKyAxKSArICcuMC4wJztcbiAgZWxzZSBpZiAoaXNYKHRwKSlcbiAgICB0byA9ICc8JyArIHRNICsgJy4nICsgKCt0bSArIDEpICsgJy4wJztcbiAgZWxzZSBpZiAodHByKVxuICAgIHRvID0gJzw9JyArIHRNICsgJy4nICsgdG0gKyAnLicgKyB0cCArICctJyArIHRwcjtcbiAgZWxzZVxuICAgIHRvID0gJzw9JyArIHRvO1xuXG4gIHJldHVybiAoZnJvbSArICcgJyArIHRvKS50cmltKCk7XG59XG5cblxuLy8gaWYgQU5ZIG9mIHRoZSBzZXRzIG1hdGNoIEFMTCBvZiBpdHMgY29tcGFyYXRvcnMsIHRoZW4gcGFzc1xuUmFuZ2UucHJvdG90eXBlLnRlc3QgPSBmdW5jdGlvbih2ZXJzaW9uKSB7XG4gIGlmICghdmVyc2lvbilcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgaWYgKHR5cGVvZiB2ZXJzaW9uID09PSAnc3RyaW5nJylcbiAgICB2ZXJzaW9uID0gbmV3IFNlbVZlcih2ZXJzaW9uLCB0aGlzLmxvb3NlKTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuc2V0Lmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKHRlc3RTZXQodGhpcy5zZXRbaV0sIHZlcnNpb24pKVxuICAgICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufTtcblxuZnVuY3Rpb24gdGVzdFNldChzZXQsIHZlcnNpb24pIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzZXQubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoIXNldFtpXS50ZXN0KHZlcnNpb24pKVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKHZlcnNpb24ucHJlcmVsZWFzZS5sZW5ndGgpIHtcbiAgICAvLyBGaW5kIHRoZSBzZXQgb2YgdmVyc2lvbnMgdGhhdCBhcmUgYWxsb3dlZCB0byBoYXZlIHByZXJlbGVhc2VzXG4gICAgLy8gRm9yIGV4YW1wbGUsIF4xLjIuMy1wci4xIGRlc3VnYXJzIHRvID49MS4yLjMtcHIuMSA8Mi4wLjBcbiAgICAvLyBUaGF0IHNob3VsZCBhbGxvdyBgMS4yLjMtcHIuMmAgdG8gcGFzcy5cbiAgICAvLyBIb3dldmVyLCBgMS4yLjQtYWxwaGEubm90cmVhZHlgIHNob3VsZCBOT1QgYmUgYWxsb3dlZCxcbiAgICAvLyBldmVuIHRob3VnaCBpdCdzIHdpdGhpbiB0aGUgcmFuZ2Ugc2V0IGJ5IHRoZSBjb21wYXJhdG9ycy5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNldC5sZW5ndGg7IGkrKykge1xuICAgICAgZGVidWcoc2V0W2ldLnNlbXZlcik7XG4gICAgICBpZiAoc2V0W2ldLnNlbXZlciA9PT0gQU5ZKVxuICAgICAgICBjb250aW51ZTtcblxuICAgICAgaWYgKHNldFtpXS5zZW12ZXIucHJlcmVsZWFzZS5sZW5ndGggPiAwKSB7XG4gICAgICAgIHZhciBhbGxvd2VkID0gc2V0W2ldLnNlbXZlcjtcbiAgICAgICAgaWYgKGFsbG93ZWQubWFqb3IgPT09IHZlcnNpb24ubWFqb3IgJiZcbiAgICAgICAgICAgIGFsbG93ZWQubWlub3IgPT09IHZlcnNpb24ubWlub3IgJiZcbiAgICAgICAgICAgIGFsbG93ZWQucGF0Y2ggPT09IHZlcnNpb24ucGF0Y2gpXG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gVmVyc2lvbiBoYXMgYSAtcHJlLCBidXQgaXQncyBub3Qgb25lIG9mIHRoZSBvbmVzIHdlIGxpa2UuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmV4cG9ydHMuc2F0aXNmaWVzID0gc2F0aXNmaWVzO1xuZnVuY3Rpb24gc2F0aXNmaWVzKHZlcnNpb24sIHJhbmdlLCBsb29zZSkge1xuICB0cnkge1xuICAgIHJhbmdlID0gbmV3IFJhbmdlKHJhbmdlLCBsb29zZSk7XG4gIH0gY2F0Y2ggKGVyKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiByYW5nZS50ZXN0KHZlcnNpb24pO1xufVxuXG5leHBvcnRzLm1heFNhdGlzZnlpbmcgPSBtYXhTYXRpc2Z5aW5nO1xuZnVuY3Rpb24gbWF4U2F0aXNmeWluZyh2ZXJzaW9ucywgcmFuZ2UsIGxvb3NlKSB7XG4gIHJldHVybiB2ZXJzaW9ucy5maWx0ZXIoZnVuY3Rpb24odmVyc2lvbikge1xuICAgIHJldHVybiBzYXRpc2ZpZXModmVyc2lvbiwgcmFuZ2UsIGxvb3NlKTtcbiAgfSkuc29ydChmdW5jdGlvbihhLCBiKSB7XG4gICAgcmV0dXJuIHJjb21wYXJlKGEsIGIsIGxvb3NlKTtcbiAgfSlbMF0gfHwgbnVsbDtcbn1cblxuZXhwb3J0cy52YWxpZFJhbmdlID0gdmFsaWRSYW5nZTtcbmZ1bmN0aW9uIHZhbGlkUmFuZ2UocmFuZ2UsIGxvb3NlKSB7XG4gIHRyeSB7XG4gICAgLy8gUmV0dXJuICcqJyBpbnN0ZWFkIG9mICcnIHNvIHRoYXQgdHJ1dGhpbmVzcyB3b3Jrcy5cbiAgICAvLyBUaGlzIHdpbGwgdGhyb3cgaWYgaXQncyBpbnZhbGlkIGFueXdheVxuICAgIHJldHVybiBuZXcgUmFuZ2UocmFuZ2UsIGxvb3NlKS5yYW5nZSB8fCAnKic7XG4gIH0gY2F0Y2ggKGVyKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuLy8gRGV0ZXJtaW5lIGlmIHZlcnNpb24gaXMgbGVzcyB0aGFuIGFsbCB0aGUgdmVyc2lvbnMgcG9zc2libGUgaW4gdGhlIHJhbmdlXG5leHBvcnRzLmx0ciA9IGx0cjtcbmZ1bmN0aW9uIGx0cih2ZXJzaW9uLCByYW5nZSwgbG9vc2UpIHtcbiAgcmV0dXJuIG91dHNpZGUodmVyc2lvbiwgcmFuZ2UsICc8JywgbG9vc2UpO1xufVxuXG4vLyBEZXRlcm1pbmUgaWYgdmVyc2lvbiBpcyBncmVhdGVyIHRoYW4gYWxsIHRoZSB2ZXJzaW9ucyBwb3NzaWJsZSBpbiB0aGUgcmFuZ2UuXG5leHBvcnRzLmd0ciA9IGd0cjtcbmZ1bmN0aW9uIGd0cih2ZXJzaW9uLCByYW5nZSwgbG9vc2UpIHtcbiAgcmV0dXJuIG91dHNpZGUodmVyc2lvbiwgcmFuZ2UsICc+JywgbG9vc2UpO1xufVxuXG5leHBvcnRzLm91dHNpZGUgPSBvdXRzaWRlO1xuZnVuY3Rpb24gb3V0c2lkZSh2ZXJzaW9uLCByYW5nZSwgaGlsbywgbG9vc2UpIHtcbiAgdmVyc2lvbiA9IG5ldyBTZW1WZXIodmVyc2lvbiwgbG9vc2UpO1xuICByYW5nZSA9IG5ldyBSYW5nZShyYW5nZSwgbG9vc2UpO1xuXG4gIHZhciBndGZuLCBsdGVmbiwgbHRmbiwgY29tcCwgZWNvbXA7XG4gIHN3aXRjaCAoaGlsbykge1xuICAgIGNhc2UgJz4nOlxuICAgICAgZ3RmbiA9IGd0O1xuICAgICAgbHRlZm4gPSBsdGU7XG4gICAgICBsdGZuID0gbHQ7XG4gICAgICBjb21wID0gJz4nO1xuICAgICAgZWNvbXAgPSAnPj0nO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnPCc6XG4gICAgICBndGZuID0gbHQ7XG4gICAgICBsdGVmbiA9IGd0ZTtcbiAgICAgIGx0Zm4gPSBndDtcbiAgICAgIGNvbXAgPSAnPCc7XG4gICAgICBlY29tcCA9ICc8PSc7XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignTXVzdCBwcm92aWRlIGEgaGlsbyB2YWwgb2YgXCI8XCIgb3IgXCI+XCInKTtcbiAgfVxuXG4gIC8vIElmIGl0IHNhdGlzaWZlcyB0aGUgcmFuZ2UgaXQgaXMgbm90IG91dHNpZGVcbiAgaWYgKHNhdGlzZmllcyh2ZXJzaW9uLCByYW5nZSwgbG9vc2UpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLy8gRnJvbSBub3cgb24sIHZhcmlhYmxlIHRlcm1zIGFyZSBhcyBpZiB3ZSdyZSBpbiBcImd0clwiIG1vZGUuXG4gIC8vIGJ1dCBub3RlIHRoYXQgZXZlcnl0aGluZyBpcyBmbGlwcGVkIGZvciB0aGUgXCJsdHJcIiBmdW5jdGlvbi5cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHJhbmdlLnNldC5sZW5ndGg7ICsraSkge1xuICAgIHZhciBjb21wYXJhdG9ycyA9IHJhbmdlLnNldFtpXTtcblxuICAgIHZhciBoaWdoID0gbnVsbDtcbiAgICB2YXIgbG93ID0gbnVsbDtcblxuICAgIGNvbXBhcmF0b3JzLmZvckVhY2goZnVuY3Rpb24oY29tcGFyYXRvcikge1xuICAgICAgaWYgKGNvbXBhcmF0b3Iuc2VtdmVyID09PSBBTlkpIHtcbiAgICAgICAgY29tcGFyYXRvciA9IG5ldyBDb21wYXJhdG9yKCc+PTAuMC4wJylcbiAgICAgIH1cbiAgICAgIGhpZ2ggPSBoaWdoIHx8IGNvbXBhcmF0b3I7XG4gICAgICBsb3cgPSBsb3cgfHwgY29tcGFyYXRvcjtcbiAgICAgIGlmIChndGZuKGNvbXBhcmF0b3Iuc2VtdmVyLCBoaWdoLnNlbXZlciwgbG9vc2UpKSB7XG4gICAgICAgIGhpZ2ggPSBjb21wYXJhdG9yO1xuICAgICAgfSBlbHNlIGlmIChsdGZuKGNvbXBhcmF0b3Iuc2VtdmVyLCBsb3cuc2VtdmVyLCBsb29zZSkpIHtcbiAgICAgICAgbG93ID0gY29tcGFyYXRvcjtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIElmIHRoZSBlZGdlIHZlcnNpb24gY29tcGFyYXRvciBoYXMgYSBvcGVyYXRvciB0aGVuIG91ciB2ZXJzaW9uXG4gICAgLy8gaXNuJ3Qgb3V0c2lkZSBpdFxuICAgIGlmIChoaWdoLm9wZXJhdG9yID09PSBjb21wIHx8IGhpZ2gub3BlcmF0b3IgPT09IGVjb21wKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gSWYgdGhlIGxvd2VzdCB2ZXJzaW9uIGNvbXBhcmF0b3IgaGFzIGFuIG9wZXJhdG9yIGFuZCBvdXIgdmVyc2lvblxuICAgIC8vIGlzIGxlc3MgdGhhbiBpdCB0aGVuIGl0IGlzbid0IGhpZ2hlciB0aGFuIHRoZSByYW5nZVxuICAgIGlmICgoIWxvdy5vcGVyYXRvciB8fCBsb3cub3BlcmF0b3IgPT09IGNvbXApICYmXG4gICAgICAgIGx0ZWZuKHZlcnNpb24sIGxvdy5zZW12ZXIpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSBlbHNlIGlmIChsb3cub3BlcmF0b3IgPT09IGVjb21wICYmIGx0Zm4odmVyc2lvbiwgbG93LnNlbXZlcikpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vc2VtdmVyL3NlbXZlci5qc1xuICoqLyIsIi8vIHNoaW0gZm9yIHVzaW5nIHByb2Nlc3MgaW4gYnJvd3NlclxuXG52YXIgcHJvY2VzcyA9IG1vZHVsZS5leHBvcnRzID0ge307XG52YXIgcXVldWUgPSBbXTtcbnZhciBkcmFpbmluZyA9IGZhbHNlO1xudmFyIGN1cnJlbnRRdWV1ZTtcbnZhciBxdWV1ZUluZGV4ID0gLTE7XG5cbmZ1bmN0aW9uIGNsZWFuVXBOZXh0VGljaygpIHtcbiAgICBkcmFpbmluZyA9IGZhbHNlO1xuICAgIGlmIChjdXJyZW50UXVldWUubGVuZ3RoKSB7XG4gICAgICAgIHF1ZXVlID0gY3VycmVudFF1ZXVlLmNvbmNhdChxdWV1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgIH1cbiAgICBpZiAocXVldWUubGVuZ3RoKSB7XG4gICAgICAgIGRyYWluUXVldWUoKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGRyYWluUXVldWUoKSB7XG4gICAgaWYgKGRyYWluaW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIHRpbWVvdXQgPSBzZXRUaW1lb3V0KGNsZWFuVXBOZXh0VGljayk7XG4gICAgZHJhaW5pbmcgPSB0cnVlO1xuXG4gICAgdmFyIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgICB3aGlsZShsZW4pIHtcbiAgICAgICAgY3VycmVudFF1ZXVlID0gcXVldWU7XG4gICAgICAgIHF1ZXVlID0gW107XG4gICAgICAgIHdoaWxlICgrK3F1ZXVlSW5kZXggPCBsZW4pIHtcbiAgICAgICAgICAgIGlmIChjdXJyZW50UXVldWUpIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50UXVldWVbcXVldWVJbmRleF0ucnVuKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgICAgICBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgfVxuICAgIGN1cnJlbnRRdWV1ZSA9IG51bGw7XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbiAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG59XG5cbnByb2Nlc3MubmV4dFRpY2sgPSBmdW5jdGlvbiAoZnVuKSB7XG4gICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCAtIDEpO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcXVldWUucHVzaChuZXcgSXRlbShmdW4sIGFyZ3MpKTtcbiAgICBpZiAocXVldWUubGVuZ3RoID09PSAxICYmICFkcmFpbmluZykge1xuICAgICAgICBzZXRUaW1lb3V0KGRyYWluUXVldWUsIDApO1xuICAgIH1cbn07XG5cbi8vIHY4IGxpa2VzIHByZWRpY3RpYmxlIG9iamVjdHNcbmZ1bmN0aW9uIEl0ZW0oZnVuLCBhcnJheSkge1xuICAgIHRoaXMuZnVuID0gZnVuO1xuICAgIHRoaXMuYXJyYXkgPSBhcnJheTtcbn1cbkl0ZW0ucHJvdG90eXBlLnJ1biA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmZ1bi5hcHBseShudWxsLCB0aGlzLmFycmF5KTtcbn07XG5wcm9jZXNzLnRpdGxlID0gJ2Jyb3dzZXInO1xucHJvY2Vzcy5icm93c2VyID0gdHJ1ZTtcbnByb2Nlc3MuZW52ID0ge307XG5wcm9jZXNzLmFyZ3YgPSBbXTtcbnByb2Nlc3MudmVyc2lvbiA9ICcnOyAvLyBlbXB0eSBzdHJpbmcgdG8gYXZvaWQgcmVnZXhwIGlzc3Vlc1xucHJvY2Vzcy52ZXJzaW9ucyA9IHt9O1xuXG5mdW5jdGlvbiBub29wKCkge31cblxucHJvY2Vzcy5vbiA9IG5vb3A7XG5wcm9jZXNzLmFkZExpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3Mub25jZSA9IG5vb3A7XG5wcm9jZXNzLm9mZiA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUxpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlQWxsTGlzdGVuZXJzID0gbm9vcDtcbnByb2Nlc3MuZW1pdCA9IG5vb3A7XG5cbnByb2Nlc3MuYmluZGluZyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmJpbmRpbmcgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcblxucHJvY2Vzcy5jd2QgPSBmdW5jdGlvbiAoKSB7IHJldHVybiAnLycgfTtcbnByb2Nlc3MuY2hkaXIgPSBmdW5jdGlvbiAoZGlyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmNoZGlyIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5wcm9jZXNzLnVtYXNrID0gZnVuY3Rpb24oKSB7IHJldHVybiAwOyB9O1xuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L3Byb2Nlc3MvYnJvd3Nlci5qc1xuICoqLyIsIi8qKlxuICogQGZpbGVPdmVydmlld1xuICogVmlld01vZGVsIENvbnN0cnVjdG9yICYgZGVmaW5pdGlvblxuICovXG5cbmltcG9ydCB7ZXh0ZW5kLCB0b0FycmF5fSBmcm9tICcuLi91dGlsJ1xuXG5pbXBvcnQgKiBhcyBzY29wZSBmcm9tICcuL2luc3RhbmNlL3Njb3BlJ1xuaW1wb3J0ICogYXMgY29tcGlsZXIgZnJvbSAnLi9jb21waWxlcidcbmltcG9ydCAqIGFzIGRpcmVjdGl2ZSBmcm9tICcuL2RpcmVjdGl2ZSdcbmltcG9ydCAqIGFzIGRvbUhlbHBlciBmcm9tICcuL2RvbS1oZWxwZXInXG5pbXBvcnQgKiBhcyBldmVudHMgZnJvbSAnLi9ldmVudHMnXG4vLyBpbXBvcnQgKiBhcyBtb2R1bGVzIGZyb20gJy4vLi4vYXBpL21vZHVsZXMnXG4vLyBpbXBvcnQgKiBhcyBhcGkgZnJvbSAnLi8uLi9hcGkvYXBpJ1xuXG5pbXBvcnQge3JlZ2lzdGVyTW9kdWxlcywgcmVnaXN0ZXJNZXRob2RzfSBmcm9tICcuLi9hcHAvcmVnaXN0ZXInXG5cbmZ1bmN0aW9uIGNhbGxPbGRSZWFkeUVudHJ5KHZtLCBjb21wb25lbnQpIHtcbiAgaWYgKGNvbXBvbmVudC5tZXRob2RzICYmXG4gICAgICBjb21wb25lbnQubWV0aG9kcy5yZWFkeSkge1xuICAgIGNvbXBvbmVudC5tZXRob2RzLnJlYWR5LmNhbGwodm0pXG4gIH1cbn1cblxuLyoqXG4gKiBWaWV3TW9kZWwgY29uc3RydWN0b3JcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdHlwZVxuICogQHBhcmFtIHtvYmplY3R9IHBhcmVudFZtICAgd2hpY2ggY29udGFpbnMgX2FwcFxuICogQHBhcmFtIHtvYmplY3R9IHBhcmVudEVsICAgcm9vdCBlbGVtZW50IG9yIGZyYWcgYmxvY2tcbiAqIEBwYXJhbSB7b2JqZWN0fSBtZXJnZWREYXRhIGV4dGVybmFsIGRhdGFcbiAqIEBwYXJhbSB7b2JqZWN0fSBleHRlcm5hbEV2ZW50cyBleHRlcm5hbCBldmVudHNcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gVm0oXG4gIHR5cGUsXG4gIHBhcmVudFZtLFxuICBwYXJlbnRFbCxcbiAgbWVyZ2VkRGF0YSxcbiAgZXh0ZXJuYWxFdmVudHNcbikge1xuICB0aGlzLl9wYXJlbnQgPSBwYXJlbnRWbS5fcmVhbFBhcmVudCA/IHBhcmVudFZtLl9yZWFsUGFyZW50IDogcGFyZW50Vm1cbiAgdGhpcy5fYXBwID0gcGFyZW50Vm0uX2FwcFxuICBwYXJlbnRWbS5fY2hpbGRyZW5WbXMgJiYgcGFyZW50Vm0uX2NoaWxkcmVuVm1zLnB1c2godGhpcylcblxuICBjb25zdCBjb21wb25lbnQgPSB0aGlzLl9hcHAuY3VzdG9tQ29tcG9uZW50TWFwW3R5cGVdIHx8IHt9XG4gIGNvbnN0IGRhdGEgPSBjb21wb25lbnQuZGF0YSB8fCB7fVxuXG4gIHRoaXMuX29wdGlvbnMgPSBjb21wb25lbnRcbiAgdGhpcy5fbWV0aG9kcyA9IGNvbXBvbmVudC5tZXRob2RzIHx8IHt9XG4gIHRoaXMuX2NvbXB1dGVkID0gY29tcG9uZW50LmNvbXB1dGVkIHx8IHt9XG4gIHRoaXMuX2NzcyA9IGNvbXBvbmVudC5zdHlsZSB8fCB7fVxuICB0aGlzLl9pZHMgPSB7fVxuICB0aGlzLl93YXRjaGVycyA9IFtdXG4gIHRoaXMuX3ZtRXZlbnRzID0ge31cbiAgdGhpcy5fY2hpbGRyZW5WbXMgPSBbXVxuICB0aGlzLl90eXBlID0gdHlwZVxuXG4gIC8vIGJpbmQgZXZlbnRzIGFuZCBsaWZlY3ljbGVzXG4gIHRoaXMuX2luaXRFdmVudHMoZXh0ZXJuYWxFdmVudHMpXG5cbiAgdGhpcy4kZW1pdCgnaG9vazppbml0JylcbiAgdGhpcy5faW5pdGVkID0gdHJ1ZVxuICAvLyBwcm94eSBkYXRhIGFuZCBtZXRob2RzXG4gIC8vIG9ic2VydmUgZGF0YSBhbmQgYWRkIHRoaXMgdG8gdm1zXG4gIHRoaXMuX2RhdGEgPSB0eXBlb2YgZGF0YSA9PT0gJ2Z1bmN0aW9uJyA/IGRhdGEoKSA6IGRhdGFcbiAgaWYgKG1lcmdlZERhdGEpIHtcbiAgICBleHRlbmQodGhpcy5fZGF0YSwgbWVyZ2VkRGF0YSlcbiAgfVxuICB0aGlzLl9pbml0U2NvcGUoKVxuXG4gIHRoaXMuJGVtaXQoJ2hvb2s6Y3JlYXRlZCcpXG4gIHRoaXMuX2NyZWF0ZWQgPSB0cnVlXG4gIC8vIGJhY2t3YXJkIG9sZCByZWFkeSBlbnRyeVxuICBjYWxsT2xkUmVhZHlFbnRyeSh0aGlzLCBjb21wb25lbnQpXG5cbiAgLy8gaWYgbm8gcGFyZW50RWxlbWVudCB0aGVuIHNwZWNpZnkgdGhlIGRvY3VtZW50RWxlbWVudFxuICB0aGlzLl9wYXJlbnRFbCA9IHBhcmVudEVsIHx8IHRoaXMuX2FwcC5kb2MuZG9jdW1lbnRFbGVtZW50XG4gIHRoaXMuX2J1aWxkKClcbn1cblxuZXh0ZW5kKFZtLnByb3RvdHlwZSwgc2NvcGUsIGNvbXBpbGVyLCBkaXJlY3RpdmUsIGRvbUhlbHBlciwgZXZlbnRzKVxuZXh0ZW5kKFZtLCB7XG4gIHJlZ2lzdGVyTW9kdWxlcyxcbiAgcmVnaXN0ZXJNZXRob2RzXG59KVxuLy8gVm0ucmVnaXN0ZXJNb2R1bGVzKG1vZHVsZXMpXG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL2xpYi92bS9pbmRleC5qc1xuICoqLyIsInZhciBfID0gcmVxdWlyZSgnLi4vdXRpbCcpXG52YXIgT2JzZXJ2ZXIgPSByZXF1aXJlKCcuLi9vYnNlcnZlcicpXG52YXIgRGVwID0gcmVxdWlyZSgnLi4vb2JzZXJ2ZXIvZGVwJylcblxuLyoqXG4gKiBTZXR1cCB0aGUgc2NvcGUgb2YgYW4gaW5zdGFuY2UsIHdoaWNoIGNvbnRhaW5zOlxuICogLSBvYnNlcnZlZCBkYXRhXG4gKiAtIGNvbXB1dGVkIHByb3BlcnRpZXNcbiAqIC0gdXNlciBtZXRob2RzXG4gKiAtIG1ldGEgcHJvcGVydGllc1xuICovXG5cbmV4cG9ydHMuX2luaXRTY29wZSA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5faW5pdERhdGEoKVxuICB0aGlzLl9pbml0Q29tcHV0ZWQoKVxuICB0aGlzLl9pbml0TWV0aG9kcygpXG4gIC8vIHRoaXMuX2luaXRNZXRhKClcbn1cblxuLyoqXG4gKiBJbml0aWFsaXplIHRoZSBkYXRhLiBcbiAqL1xuXG5leHBvcnRzLl9pbml0RGF0YSA9IGZ1bmN0aW9uICgpIHtcbiAgLy8gcHJveHkgZGF0YSBvbiBpbnN0YW5jZVxuICB2YXIgZGF0YSA9IHRoaXMuX2RhdGFcbiAgdmFyIGksIGtleVxuICAvLyAvLyBtYWtlIHN1cmUgYWxsIHByb3BzIHByb3BlcnRpZXMgYXJlIG9ic2VydmVkXG4gIC8vIHZhciBwcm9wcyA9IHRoaXMuJG9wdGlvbnMucHJvcHNcbiAgLy8gaWYgKHByb3BzKSB7XG4gIC8vICAgaSA9IHByb3BzLmxlbmd0aFxuICAvLyAgIHdoaWxlIChpLS0pIHtcbiAgLy8gICAgIGtleSA9IF8uY2FtZWxpemUocHJvcHNbaV0pXG4gIC8vICAgICBpZiAoIShrZXkgaW4gZGF0YSkpIHtcbiAgLy8gICAgICAgZGF0YVtrZXldID0gbnVsbFxuICAvLyAgICAgfVxuICAvLyAgIH1cbiAgLy8gfVxuICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKGRhdGEpXG4gIGkgPSBrZXlzLmxlbmd0aFxuICB3aGlsZSAoaS0tKSB7XG4gICAga2V5ID0ga2V5c1tpXVxuICAgIGlmICghXy5pc1Jlc2VydmVkKGtleSkpIHtcbiAgICAgIHRoaXMuX3Byb3h5KGtleSlcbiAgICB9XG4gIH1cbiAgLy8gb2JzZXJ2ZSBkYXRhXG4gIE9ic2VydmVyLmNyZWF0ZShkYXRhKS5hZGRWbSh0aGlzKVxufVxuXG4vLyAvKipcbi8vICAqIFN3YXAgdGhlIGlzbnRhbmNlJ3MgJGRhdGEuIENhbGxlZCBpbiAkZGF0YSdzIHNldHRlci5cbi8vICAqXG4vLyAgKiBAcGFyYW0ge09iamVjdH0gbmV3RGF0YVxuLy8gICovXG5cbi8vIGV4cG9ydHMuX3NldERhdGEgPSBmdW5jdGlvbiAobmV3RGF0YSkge1xuLy8gICBuZXdEYXRhID0gbmV3RGF0YSB8fCB7fVxuLy8gICB2YXIgb2xkRGF0YSA9IHRoaXMuX2RhdGFcbi8vICAgdGhpcy5fZGF0YSA9IG5ld0RhdGFcbi8vICAgdmFyIGtleXMsIGtleSwgaVxuLy8gICAvLyB1bnByb3h5IGtleXMgbm90IHByZXNlbnQgaW4gbmV3IGRhdGFcbi8vICAga2V5cyA9IE9iamVjdC5rZXlzKG9sZERhdGEpXG4vLyAgIGkgPSBrZXlzLmxlbmd0aFxuLy8gICB3aGlsZSAoaS0tKSB7XG4vLyAgICAga2V5ID0ga2V5c1tpXVxuLy8gICAgIGlmICghXy5pc1Jlc2VydmVkKGtleSkgJiYgIShrZXkgaW4gbmV3RGF0YSkpIHtcbi8vICAgICAgIHRoaXMuX3VucHJveHkoa2V5KVxuLy8gICAgIH1cbi8vICAgfVxuLy8gICAvLyBwcm94eSBrZXlzIG5vdCBhbHJlYWR5IHByb3hpZWQsXG4vLyAgIC8vIGFuZCB0cmlnZ2VyIGNoYW5nZSBmb3IgY2hhbmdlZCB2YWx1ZXNcbi8vICAga2V5cyA9IE9iamVjdC5rZXlzKG5ld0RhdGEpXG4vLyAgIGkgPSBrZXlzLmxlbmd0aFxuLy8gICB3aGlsZSAoaS0tKSB7XG4vLyAgICAga2V5ID0ga2V5c1tpXVxuLy8gICAgIGlmICghdGhpcy5oYXNPd25Qcm9wZXJ0eShrZXkpICYmICFfLmlzUmVzZXJ2ZWQoa2V5KSkge1xuLy8gICAgICAgLy8gbmV3IHByb3BlcnR5XG4vLyAgICAgICB0aGlzLl9wcm94eShrZXkpXG4vLyAgICAgfVxuLy8gICB9XG4vLyAgIG9sZERhdGEuX19vYl9fLnJlbW92ZVZtKHRoaXMpXG4vLyAgIE9ic2VydmVyLmNyZWF0ZShuZXdEYXRhKS5hZGRWbSh0aGlzKVxuLy8gICB0aGlzLl9kaWdlc3QoKVxuLy8gfVxuXG4vKipcbiAqIFByb3h5IGEgcHJvcGVydHksIHNvIHRoYXRcbiAqIHZtLnByb3AgPT09IHZtLl9kYXRhLnByb3BcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30ga2V5XG4gKi9cblxuZXhwb3J0cy5fcHJveHkgPSBmdW5jdGlvbiAoa2V5KSB7XG4gIC8vIG5lZWQgdG8gc3RvcmUgcmVmIHRvIHNlbGYgaGVyZVxuICAvLyBiZWNhdXNlIHRoZXNlIGdldHRlci9zZXR0ZXJzIG1pZ2h0XG4gIC8vIGJlIGNhbGxlZCBieSBjaGlsZCBpbnN0YW5jZXMhXG4gIHZhciBzZWxmID0gdGhpc1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoc2VsZiwga2V5LCB7XG4gICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgZ2V0OiBmdW5jdGlvbiBwcm94eUdldHRlciAoKSB7XG4gICAgICByZXR1cm4gc2VsZi5fZGF0YVtrZXldXG4gICAgfSxcbiAgICBzZXQ6IGZ1bmN0aW9uIHByb3h5U2V0dGVyICh2YWwpIHtcbiAgICAgIHNlbGYuX2RhdGFba2V5XSA9IHZhbFxuICAgIH1cbiAgfSlcbn1cblxuLyoqXG4gKiBVbnByb3h5IGEgcHJvcGVydHkuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGtleVxuICovXG5cbmV4cG9ydHMuX3VucHJveHkgPSBmdW5jdGlvbiAoa2V5KSB7XG4gIGRlbGV0ZSB0aGlzW2tleV1cbn1cblxuLy8gLyoqXG4vLyAgKiBGb3JjZSB1cGRhdGUgb24gZXZlcnkgd2F0Y2hlciBpbiBzY29wZS5cbi8vICAqL1xuXG4vLyBleHBvcnRzLl9kaWdlc3QgPSBmdW5jdGlvbiAoKSB7XG4vLyAgIHZhciBpID0gdGhpcy5fd2F0Y2hlcnMubGVuZ3RoXG4vLyAgIHdoaWxlIChpLS0pIHtcbi8vICAgICB0aGlzLl93YXRjaGVyc1tpXS51cGRhdGUoKVxuLy8gICB9XG4vLyAgIHZhciBjaGlsZHJlbiA9IHRoaXMuX2NoaWxkcmVuXG4vLyAgIGkgPSBjaGlsZHJlbi5sZW5ndGhcbi8vICAgd2hpbGUgKGktLSkge1xuLy8gICAgIHZhciBjaGlsZCA9IGNoaWxkcmVuW2ldXG4vLyAgICAgaWYgKGNoaWxkLiRvcHRpb25zLmluaGVyaXQpIHtcbi8vICAgICAgIGNoaWxkLl9kaWdlc3QoKVxuLy8gICAgIH1cbi8vICAgfVxuLy8gfVxuXG4vKipcbiAqIFNldHVwIGNvbXB1dGVkIHByb3BlcnRpZXMuIFRoZXkgYXJlIGVzc2VudGlhbGx5XG4gKiBzcGVjaWFsIGdldHRlci9zZXR0ZXJzXG4gKi9cblxuZnVuY3Rpb24gbm9vcCAoKSB7fVxuZXhwb3J0cy5faW5pdENvbXB1dGVkID0gZnVuY3Rpb24gKCkge1xuICAvLyB2YXIgY29tcHV0ZWQgPSB0aGlzLiRvcHRpb25zLmNvbXB1dGVkXG4gIHZhciBjb21wdXRlZCA9IHRoaXMuX2NvbXB1dGVkXG4gIGlmIChjb21wdXRlZCkge1xuICAgIGZvciAodmFyIGtleSBpbiBjb21wdXRlZCkge1xuICAgICAgdmFyIHVzZXJEZWYgPSBjb21wdXRlZFtrZXldXG4gICAgICB2YXIgZGVmID0ge1xuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgdXNlckRlZiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBkZWYuZ2V0ID0gXy5iaW5kKHVzZXJEZWYsIHRoaXMpXG4gICAgICAgIGRlZi5zZXQgPSBub29wXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkZWYuZ2V0ID0gdXNlckRlZi5nZXRcbiAgICAgICAgICA/IF8uYmluZCh1c2VyRGVmLmdldCwgdGhpcylcbiAgICAgICAgICA6IG5vb3BcbiAgICAgICAgZGVmLnNldCA9IHVzZXJEZWYuc2V0XG4gICAgICAgICAgPyBfLmJpbmQodXNlckRlZi5zZXQsIHRoaXMpXG4gICAgICAgICAgOiBub29wXG4gICAgICB9XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywga2V5LCBkZWYpXG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogU2V0dXAgaW5zdGFuY2UgbWV0aG9kcy4gTWV0aG9kcyBtdXN0IGJlIGJvdW5kIHRvIHRoZVxuICogaW5zdGFuY2Ugc2luY2UgdGhleSBtaWdodCBiZSBjYWxsZWQgYnkgY2hpbGRyZW5cbiAqIGluaGVyaXRpbmcgdGhlbS5cbiAqL1xuXG5leHBvcnRzLl9pbml0TWV0aG9kcyA9IGZ1bmN0aW9uICgpIHtcbiAgLy8gdmFyIG1ldGhvZHMgPSB0aGlzLiRvcHRpb25zLm1ldGhvZHNcbiAgdmFyIG1ldGhvZHMgPSB0aGlzLl9tZXRob2RzXG4gIGlmIChtZXRob2RzKSB7XG4gICAgZm9yICh2YXIga2V5IGluIG1ldGhvZHMpIHtcbiAgICAgIHRoaXNba2V5XSA9IF8uYmluZChtZXRob2RzW2tleV0sIHRoaXMpXG4gICAgfVxuICB9XG59XG5cbi8vIC8qKlxuLy8gICogSW5pdGlhbGl6ZSBtZXRhIGluZm9ybWF0aW9uIGxpa2UgJGluZGV4LCAka2V5ICYgJHZhbHVlLlxuLy8gICovXG5cbi8vIGV4cG9ydHMuX2luaXRNZXRhID0gZnVuY3Rpb24gKCkge1xuLy8gICB2YXIgbWV0YXMgPSB0aGlzLiRvcHRpb25zLl9tZXRhXG4vLyAgIGlmIChtZXRhcykge1xuLy8gICAgIGZvciAodmFyIGtleSBpbiBtZXRhcykge1xuLy8gICAgICAgdGhpcy5fZGVmaW5lTWV0YShrZXksIG1ldGFzW2tleV0pXG4vLyAgICAgfVxuLy8gICB9XG4vLyB9XG5cbi8vIC8qKlxuLy8gICogRGVmaW5lIGEgbWV0YSBwcm9wZXJ0eSwgZS5nICRpbmRleCwgJGtleSwgJHZhbHVlXG4vLyAgKiB3aGljaCBvbmx5IGV4aXN0cyBvbiB0aGUgdm0gaW5zdGFuY2UgYnV0IG5vdCBpbiAkZGF0YS5cbi8vICAqXG4vLyAgKiBAcGFyYW0ge1N0cmluZ30ga2V5XG4vLyAgKiBAcGFyYW0geyp9IHZhbHVlXG4vLyAgKi9cblxuLy8gZXhwb3J0cy5fZGVmaW5lTWV0YSA9IGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG4vLyAgIHZhciBkZXAgPSBuZXcgRGVwKClcbi8vICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIGtleSwge1xuLy8gICAgIGVudW1lcmFibGU6IHRydWUsXG4vLyAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuLy8gICAgIGdldDogZnVuY3Rpb24gbWV0YUdldHRlciAoKSB7XG4vLyAgICAgICBpZiAoT2JzZXJ2ZXIudGFyZ2V0KSB7XG4vLyAgICAgICAgIE9ic2VydmVyLnRhcmdldC5hZGREZXAoZGVwKVxuLy8gICAgICAgfVxuLy8gICAgICAgcmV0dXJuIHZhbHVlXG4vLyAgICAgfSxcbi8vICAgICBzZXQ6IGZ1bmN0aW9uIG1ldGFTZXR0ZXIgKHZhbCkge1xuLy8gICAgICAgaWYgKHZhbCAhPT0gdmFsdWUpIHtcbi8vICAgICAgICAgdmFsdWUgPSB2YWxcbi8vICAgICAgICAgZGVwLm5vdGlmeSgpXG4vLyAgICAgICB9XG4vLyAgICAgfVxuLy8gICB9KVxuLy8gfVxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9saWIvdm0vaW5zdGFuY2Uvc2NvcGUuanNcbiAqKi8iLCIvLyByZXF1aXJlZCBmb3IgY29kZSBpbiBpbnN0YW5jZS9vYnNlcnZlclxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuLi91dGlsJylcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL2xpYi92bS91dGlsLmpzXG4gKiovIiwidmFyIF8gPSByZXF1aXJlKCcuLi91dGlsJylcbnZhciBjb25maWcgPSByZXF1aXJlKCcuLi9jb25maWcnKVxudmFyIERlcCA9IHJlcXVpcmUoJy4vZGVwJylcbnZhciBhcnJheU1ldGhvZHMgPSByZXF1aXJlKCcuL2FycmF5JylcbnZhciBhcnJheUtleXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhhcnJheU1ldGhvZHMpXG5yZXF1aXJlKCcuL29iamVjdCcpXG5cbnZhciB1aWQgPSAwXG5cbi8qKlxuICogVHlwZSBlbnVtc1xuICovXG5cbnZhciBBUlJBWSAgPSAwXG52YXIgT0JKRUNUID0gMVxuXG4vKipcbiAqIEF1Z21lbnQgYW4gdGFyZ2V0IE9iamVjdCBvciBBcnJheSBieSBpbnRlcmNlcHRpbmdcbiAqIHRoZSBwcm90b3R5cGUgY2hhaW4gdXNpbmcgX19wcm90b19fXG4gKlxuICogQHBhcmFtIHtPYmplY3R8QXJyYXl9IHRhcmdldFxuICogQHBhcmFtIHtPYmplY3R9IHByb3RvXG4gKi9cblxuZnVuY3Rpb24gcHJvdG9BdWdtZW50ICh0YXJnZXQsIHNyYykge1xuICB0YXJnZXQuX19wcm90b19fID0gc3JjXG59XG5cbi8qKlxuICogQXVnbWVudCBhbiB0YXJnZXQgT2JqZWN0IG9yIEFycmF5IGJ5IGRlZmluaW5nXG4gKiBoaWRkZW4gcHJvcGVydGllcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdHxBcnJheX0gdGFyZ2V0XG4gKiBAcGFyYW0ge09iamVjdH0gcHJvdG9cbiAqL1xuXG5mdW5jdGlvbiBjb3B5QXVnbWVudCAodGFyZ2V0LCBzcmMsIGtleXMpIHtcbiAgdmFyIGkgPSBrZXlzLmxlbmd0aFxuICB2YXIga2V5XG4gIHdoaWxlIChpLS0pIHtcbiAgICBrZXkgPSBrZXlzW2ldXG4gICAgXy5kZWZpbmUodGFyZ2V0LCBrZXksIHNyY1trZXldKVxuICB9XG59XG5cbi8qKlxuICogT2JzZXJ2ZXIgY2xhc3MgdGhhdCBhcmUgYXR0YWNoZWQgdG8gZWFjaCBvYnNlcnZlZFxuICogb2JqZWN0LiBPbmNlIGF0dGFjaGVkLCB0aGUgb2JzZXJ2ZXIgY29udmVydHMgdGFyZ2V0XG4gKiBvYmplY3QncyBwcm9wZXJ0eSBrZXlzIGludG8gZ2V0dGVyL3NldHRlcnMgdGhhdFxuICogY29sbGVjdCBkZXBlbmRlbmNpZXMgYW5kIGRpc3BhdGNoZXMgdXBkYXRlcy5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gdmFsdWVcbiAqIEBwYXJhbSB7TnVtYmVyfSB0eXBlXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuXG5mdW5jdGlvbiBPYnNlcnZlciAodmFsdWUsIHR5cGUpIHtcbiAgdGhpcy5pZCA9ICsrdWlkXG4gIHRoaXMudmFsdWUgPSB2YWx1ZVxuICB0aGlzLmFjdGl2ZSA9IHRydWVcbiAgdGhpcy5kZXBzID0gW11cbiAgXy5kZWZpbmUodmFsdWUsICdfX29iX18nLCB0aGlzKVxuICBpZiAodHlwZSA9PT0gQVJSQVkpIHtcbiAgICB2YXIgYXVnbWVudCA9IGNvbmZpZy5wcm90byAmJiBfLmhhc1Byb3RvXG4gICAgICA/IHByb3RvQXVnbWVudFxuICAgICAgOiBjb3B5QXVnbWVudFxuICAgIGF1Z21lbnQodmFsdWUsIGFycmF5TWV0aG9kcywgYXJyYXlLZXlzKVxuICAgIHRoaXMub2JzZXJ2ZUFycmF5KHZhbHVlKVxuICB9IGVsc2UgaWYgKHR5cGUgPT09IE9CSkVDVCkge1xuICAgIHRoaXMud2Fsayh2YWx1ZSlcbiAgfVxufVxuXG5PYnNlcnZlci50YXJnZXQgPSBudWxsXG5cbnZhciBwID0gT2JzZXJ2ZXIucHJvdG90eXBlXG5cbi8qKlxuICogQXR0ZW1wdCB0byBjcmVhdGUgYW4gb2JzZXJ2ZXIgaW5zdGFuY2UgZm9yIGEgdmFsdWUsXG4gKiByZXR1cm5zIHRoZSBuZXcgb2JzZXJ2ZXIgaWYgc3VjY2Vzc2Z1bGx5IG9ic2VydmVkLFxuICogb3IgdGhlIGV4aXN0aW5nIG9ic2VydmVyIGlmIHRoZSB2YWx1ZSBhbHJlYWR5IGhhcyBvbmUuXG4gKlxuICogQHBhcmFtIHsqfSB2YWx1ZVxuICogQHJldHVybiB7T2JzZXJ2ZXJ8dW5kZWZpbmVkfVxuICogQHN0YXRpY1xuICovXG5cbk9ic2VydmVyLmNyZWF0ZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICBpZiAoXG4gICAgdmFsdWUgJiZcbiAgICB2YWx1ZS5oYXNPd25Qcm9wZXJ0eSgnX19vYl9fJykgJiZcbiAgICB2YWx1ZS5fX29iX18gaW5zdGFuY2VvZiBPYnNlcnZlclxuICApIHtcbiAgICByZXR1cm4gdmFsdWUuX19vYl9fXG4gIH0gZWxzZSBpZiAoXy5pc0FycmF5KHZhbHVlKSkge1xuICAgIHJldHVybiBuZXcgT2JzZXJ2ZXIodmFsdWUsIEFSUkFZKVxuICB9IGVsc2UgaWYgKFxuICAgIF8uaXNQbGFpbk9iamVjdCh2YWx1ZSkgJiZcbiAgICAhdmFsdWUuX2lzVnVlIC8vIGF2b2lkIFZ1ZSBpbnN0YW5jZVxuICApIHtcbiAgICByZXR1cm4gbmV3IE9ic2VydmVyKHZhbHVlLCBPQkpFQ1QpXG4gIH1cbn1cblxuLyoqXG4gKiBXYWxrIHRocm91Z2ggZWFjaCBwcm9wZXJ0eSBhbmQgY29udmVydCB0aGVtIGludG9cbiAqIGdldHRlci9zZXR0ZXJzLiBUaGlzIG1ldGhvZCBzaG91bGQgb25seSBiZSBjYWxsZWQgd2hlblxuICogdmFsdWUgdHlwZSBpcyBPYmplY3QuIFByb3BlcnRpZXMgcHJlZml4ZWQgd2l0aCBgJGAgb3IgYF9gXG4gKiBhbmQgYWNjZXNzb3IgcHJvcGVydGllcyBhcmUgaWdub3JlZC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gKi9cblxucC53YWxrID0gZnVuY3Rpb24gKG9iaikge1xuICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKG9iailcbiAgdmFyIGkgPSBrZXlzLmxlbmd0aFxuICB2YXIga2V5LCBwcmVmaXhcbiAgd2hpbGUgKGktLSkge1xuICAgIGtleSA9IGtleXNbaV1cbiAgICBwcmVmaXggPSBrZXkuY2hhckNvZGVBdCgwKVxuICAgIGlmIChwcmVmaXggIT09IDB4MjQgJiYgcHJlZml4ICE9PSAweDVGKSB7IC8vIHNraXAgJCBvciBfXG4gICAgICB0aGlzLmNvbnZlcnQoa2V5LCBvYmpba2V5XSlcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBUcnkgdG8gY2FyZXRlIGFuIG9ic2VydmVyIGZvciBhIGNoaWxkIHZhbHVlLFxuICogYW5kIGlmIHZhbHVlIGlzIGFycmF5LCBsaW5rIGRlcCB0byB0aGUgYXJyYXkuXG4gKlxuICogQHBhcmFtIHsqfSB2YWxcbiAqIEByZXR1cm4ge0RlcHx1bmRlZmluZWR9XG4gKi9cblxucC5vYnNlcnZlID0gZnVuY3Rpb24gKHZhbCkge1xuICByZXR1cm4gT2JzZXJ2ZXIuY3JlYXRlKHZhbClcbn1cblxuLyoqXG4gKiBPYnNlcnZlIGEgbGlzdCBvZiBBcnJheSBpdGVtcy5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBpdGVtc1xuICovXG5cbnAub2JzZXJ2ZUFycmF5ID0gZnVuY3Rpb24gKGl0ZW1zKSB7XG4gIHZhciBpID0gaXRlbXMubGVuZ3RoXG4gIHdoaWxlIChpLS0pIHtcbiAgICB0aGlzLm9ic2VydmUoaXRlbXNbaV0pXG4gIH1cbn1cblxuLyoqXG4gKiBDb252ZXJ0IGEgcHJvcGVydHkgaW50byBnZXR0ZXIvc2V0dGVyIHNvIHdlIGNhbiBlbWl0XG4gKiB0aGUgZXZlbnRzIHdoZW4gdGhlIHByb3BlcnR5IGlzIGFjY2Vzc2VkL2NoYW5nZWQuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGtleVxuICogQHBhcmFtIHsqfSB2YWxcbiAqL1xuXG5wLmNvbnZlcnQgPSBmdW5jdGlvbiAoa2V5LCB2YWwpIHtcbiAgdmFyIG9iID0gdGhpc1xuICB2YXIgY2hpbGRPYiA9IG9iLm9ic2VydmUodmFsKVxuICB2YXIgZGVwID0gbmV3IERlcCgpXG4gIGlmIChjaGlsZE9iKSB7XG4gICAgY2hpbGRPYi5kZXBzLnB1c2goZGVwKVxuICB9XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYi52YWx1ZSwga2V5LCB7XG4gICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBPYnNlcnZlci50YXJnZXQgaXMgYSB3YXRjaGVyIHdob3NlIGdldHRlciBpc1xuICAgICAgLy8gY3VycmVudGx5IGJlaW5nIGV2YWx1YXRlZC5cbiAgICAgIGlmIChvYi5hY3RpdmUgJiYgT2JzZXJ2ZXIudGFyZ2V0KSB7XG4gICAgICAgIE9ic2VydmVyLnRhcmdldC5hZGREZXAoZGVwKVxuICAgICAgfVxuICAgICAgcmV0dXJuIHZhbFxuICAgIH0sXG4gICAgc2V0OiBmdW5jdGlvbiAobmV3VmFsKSB7XG4gICAgICBpZiAobmV3VmFsID09PSB2YWwpIHJldHVyblxuICAgICAgLy8gcmVtb3ZlIGRlcCBmcm9tIG9sZCB2YWx1ZVxuICAgICAgdmFyIG9sZENoaWxkT2IgPSB2YWwgJiYgdmFsLl9fb2JfX1xuICAgICAgaWYgKG9sZENoaWxkT2IpIHtcbiAgICAgICAgb2xkQ2hpbGRPYi5kZXBzLiRyZW1vdmUoZGVwKVxuICAgICAgfVxuICAgICAgdmFsID0gbmV3VmFsXG4gICAgICAvLyBhZGQgZGVwIHRvIG5ldyB2YWx1ZVxuICAgICAgdmFyIG5ld0NoaWxkT2IgPSBvYi5vYnNlcnZlKG5ld1ZhbClcbiAgICAgIGlmIChuZXdDaGlsZE9iKSB7XG4gICAgICAgIG5ld0NoaWxkT2IuZGVwcy5wdXNoKGRlcClcbiAgICAgIH1cbiAgICAgIGRlcC5ub3RpZnkoKVxuICAgIH1cbiAgfSlcbn1cblxuLyoqXG4gKiBOb3RpZnkgY2hhbmdlIG9uIGFsbCBzZWxmIGRlcHMgb24gYW4gb2JzZXJ2ZXIuXG4gKiBUaGlzIGlzIGNhbGxlZCB3aGVuIGEgbXV0YWJsZSB2YWx1ZSBtdXRhdGVzLiBlLmcuXG4gKiB3aGVuIGFuIEFycmF5J3MgbXV0YXRpbmcgbWV0aG9kcyBhcmUgY2FsbGVkLCBvciBhblxuICogT2JqZWN0J3MgJGFkZC8kZGVsZXRlIGFyZSBjYWxsZWQuXG4gKi9cblxucC5ub3RpZnkgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBkZXBzID0gdGhpcy5kZXBzXG4gIGZvciAodmFyIGkgPSAwLCBsID0gZGVwcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBkZXBzW2ldLm5vdGlmeSgpXG4gIH1cbn1cblxuLyoqXG4gKiBBZGQgYW4gb3duZXIgdm0sIHNvIHRoYXQgd2hlbiAkYWRkLyRkZWxldGUgbXV0YXRpb25zXG4gKiBoYXBwZW4gd2UgY2FuIG5vdGlmeSBvd25lciB2bXMgdG8gcHJveHkgdGhlIGtleXMgYW5kXG4gKiBkaWdlc3QgdGhlIHdhdGNoZXJzLiBUaGlzIGlzIG9ubHkgY2FsbGVkIHdoZW4gdGhlIG9iamVjdFxuICogaXMgb2JzZXJ2ZWQgYXMgYW4gaW5zdGFuY2UncyByb290ICRkYXRhLlxuICpcbiAqIEBwYXJhbSB7VnVlfSB2bVxuICovXG5cbnAuYWRkVm0gPSBmdW5jdGlvbiAodm0pIHtcbiAgKHRoaXMudm1zID0gdGhpcy52bXMgfHwgW10pLnB1c2godm0pXG59XG5cbi8qKlxuICogUmVtb3ZlIGFuIG93bmVyIHZtLiBUaGlzIGlzIGNhbGxlZCB3aGVuIHRoZSBvYmplY3QgaXNcbiAqIHN3YXBwZWQgb3V0IGFzIGFuIGluc3RhbmNlJ3MgJGRhdGEgb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7VnVlfSB2bVxuICovXG5cbnAucmVtb3ZlVm0gPSBmdW5jdGlvbiAodm0pIHtcbiAgdGhpcy52bXMuJHJlbW92ZSh2bSlcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBPYnNlcnZlclxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9saWIvdm0vb2JzZXJ2ZXIvaW5kZXguanNcbiAqKi8iLCJtb2R1bGUuZXhwb3J0cyA9IHtwcm90bzogdHJ1ZX1cblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vbGliL3ZtL2NvbmZpZy5qc1xuICoqLyIsInZhciBfID0gcmVxdWlyZSgnLi4vdXRpbCcpXG5cbi8qKlxuICogQSBkZXAgaXMgYW4gb2JzZXJ2YWJsZSB0aGF0IGNhbiBoYXZlIG11bHRpcGxlXG4gKiBkaXJlY3RpdmVzIHN1YnNjcmliaW5nIHRvIGl0LlxuICpcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5cbmZ1bmN0aW9uIERlcCAoKSB7XG4gIHRoaXMuc3VicyA9IFtdXG59XG5cbnZhciBwID0gRGVwLnByb3RvdHlwZVxuXG4vKipcbiAqIEFkZCBhIGRpcmVjdGl2ZSBzdWJzY3JpYmVyLlxuICpcbiAqIEBwYXJhbSB7RGlyZWN0aXZlfSBzdWJcbiAqL1xuXG5wLmFkZFN1YiA9IGZ1bmN0aW9uIChzdWIpIHtcbiAgdGhpcy5zdWJzLnB1c2goc3ViKVxufVxuXG4vKipcbiAqIFJlbW92ZSBhIGRpcmVjdGl2ZSBzdWJzY3JpYmVyLlxuICpcbiAqIEBwYXJhbSB7RGlyZWN0aXZlfSBzdWJcbiAqL1xuXG5wLnJlbW92ZVN1YiA9IGZ1bmN0aW9uIChzdWIpIHtcbiAgdGhpcy5zdWJzLiRyZW1vdmUoc3ViKVxufVxuXG4vKipcbiAqIE5vdGlmeSBhbGwgc3Vic2NyaWJlcnMgb2YgYSBuZXcgdmFsdWUuXG4gKi9cblxucC5ub3RpZnkgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIHN0YWJsaXplIHRoZSBzdWJzY3JpYmVyIGxpc3QgZmlyc3RcbiAgdmFyIHN1YnMgPSBfLnRvQXJyYXkodGhpcy5zdWJzKVxuICBmb3IgKHZhciBpID0gMCwgbCA9IHN1YnMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgc3Vic1tpXS51cGRhdGUoKVxuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gRGVwXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9saWIvdm0vb2JzZXJ2ZXIvZGVwLmpzXG4gKiovIiwidmFyIF8gPSByZXF1aXJlKCcuLi91dGlsJylcbnZhciBhcnJheVByb3RvID0gQXJyYXkucHJvdG90eXBlXG52YXIgYXJyYXlNZXRob2RzID0gT2JqZWN0LmNyZWF0ZShhcnJheVByb3RvKVxuXG4vKipcbiAqIEludGVyY2VwdCBtdXRhdGluZyBtZXRob2RzIGFuZCBlbWl0IGV2ZW50c1xuICovXG5cbjtbXG4gICdwdXNoJyxcbiAgJ3BvcCcsXG4gICdzaGlmdCcsXG4gICd1bnNoaWZ0JyxcbiAgJ3NwbGljZScsXG4gICdzb3J0JyxcbiAgJ3JldmVyc2UnXG5dXG4uZm9yRWFjaChmdW5jdGlvbiAobWV0aG9kKSB7XG4gIC8vIGNhY2hlIG9yaWdpbmFsIG1ldGhvZFxuICB2YXIgb3JpZ2luYWwgPSBhcnJheVByb3RvW21ldGhvZF1cbiAgXy5kZWZpbmUoYXJyYXlNZXRob2RzLCBtZXRob2QsIGZ1bmN0aW9uIG11dGF0b3IgKCkge1xuICAgIC8vIGF2b2lkIGxlYWtpbmcgYXJndW1lbnRzOlxuICAgIC8vIGh0dHA6Ly9qc3BlcmYuY29tL2Nsb3N1cmUtd2l0aC1hcmd1bWVudHNcbiAgICB2YXIgaSA9IGFyZ3VtZW50cy5sZW5ndGhcbiAgICB2YXIgYXJncyA9IG5ldyBBcnJheShpKVxuICAgIHdoaWxlIChpLS0pIHtcbiAgICAgIGFyZ3NbaV0gPSBhcmd1bWVudHNbaV1cbiAgICB9XG4gICAgdmFyIHJlc3VsdCA9IG9yaWdpbmFsLmFwcGx5KHRoaXMsIGFyZ3MpXG4gICAgdmFyIG9iID0gdGhpcy5fX29iX19cbiAgICB2YXIgaW5zZXJ0ZWRcbiAgICBzd2l0Y2ggKG1ldGhvZCkge1xuICAgICAgY2FzZSAncHVzaCc6XG4gICAgICAgIGluc2VydGVkID0gYXJnc1xuICAgICAgICBicmVha1xuICAgICAgY2FzZSAndW5zaGlmdCc6XG4gICAgICAgIGluc2VydGVkID0gYXJnc1xuICAgICAgICBicmVha1xuICAgICAgY2FzZSAnc3BsaWNlJzpcbiAgICAgICAgaW5zZXJ0ZWQgPSBhcmdzLnNsaWNlKDIpXG4gICAgICAgIGJyZWFrXG4gICAgfVxuICAgIGlmIChpbnNlcnRlZCkgb2Iub2JzZXJ2ZUFycmF5KGluc2VydGVkKVxuICAgIC8vIG5vdGlmeSBjaGFuZ2VcbiAgICBvYi5ub3RpZnkoKVxuICAgIHJldHVybiByZXN1bHRcbiAgfSlcbn0pXG5cbi8qKlxuICogU3dhcCB0aGUgZWxlbWVudCBhdCB0aGUgZ2l2ZW4gaW5kZXggd2l0aCBhIG5ldyB2YWx1ZVxuICogYW5kIGVtaXRzIGNvcnJlc3BvbmRpbmcgZXZlbnQuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IGluZGV4XG4gKiBAcGFyYW0geyp9IHZhbFxuICogQHJldHVybiB7Kn0gLSByZXBsYWNlZCBlbGVtZW50XG4gKi9cblxuXy5kZWZpbmUoXG4gIGFycmF5UHJvdG8sXG4gICckc2V0JyxcbiAgZnVuY3Rpb24gJHNldCAoaW5kZXgsIHZhbCkge1xuICAgIGlmIChpbmRleCA+PSB0aGlzLmxlbmd0aCkge1xuICAgICAgdGhpcy5sZW5ndGggPSBpbmRleCArIDFcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc3BsaWNlKGluZGV4LCAxLCB2YWwpWzBdXG4gIH1cbilcblxuLyoqXG4gKiBDb252ZW5pZW5jZSBtZXRob2QgdG8gcmVtb3ZlIHRoZSBlbGVtZW50IGF0IGdpdmVuIGluZGV4LlxuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSBpbmRleFxuICogQHBhcmFtIHsqfSB2YWxcbiAqL1xuXG5fLmRlZmluZShcbiAgYXJyYXlQcm90byxcbiAgJyRyZW1vdmUnLFxuICBmdW5jdGlvbiAkcmVtb3ZlIChpbmRleCkge1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgIGlmICghdGhpcy5sZW5ndGgpIHJldHVyblxuICAgIGlmICh0eXBlb2YgaW5kZXggIT09ICdudW1iZXInKSB7XG4gICAgICBpbmRleCA9IF8uaW5kZXhPZih0aGlzLCBpbmRleClcbiAgICB9XG4gICAgaWYgKGluZGV4ID4gLTEpIHtcbiAgICAgIHRoaXMuc3BsaWNlKGluZGV4LCAxKVxuICAgIH1cbiAgfVxuKVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFycmF5TWV0aG9kc1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vbGliL3ZtL29ic2VydmVyL2FycmF5LmpzXG4gKiovIiwidmFyIF8gPSByZXF1aXJlKCcuLi91dGlsJylcbnZhciBvYmpQcm90byA9IE9iamVjdC5wcm90b3R5cGVcblxuLyoqXG4gKiBBZGQgYSBuZXcgcHJvcGVydHkgdG8gYW4gb2JzZXJ2ZWQgb2JqZWN0XG4gKiBhbmQgZW1pdHMgY29ycmVzcG9uZGluZyBldmVudFxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBrZXlcbiAqIEBwYXJhbSB7Kn0gdmFsXG4gKiBAcHVibGljXG4gKi9cblxuXy5kZWZpbmUoXG4gIG9ialByb3RvLFxuICAnJGFkZCcsXG4gIGZ1bmN0aW9uICRhZGQgKGtleSwgdmFsKSB7XG4gICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoa2V5KSkgcmV0dXJuXG4gICAgdmFyIG9iID0gdGhpcy5fX29iX19cbiAgICBpZiAoIW9iIHx8IF8uaXNSZXNlcnZlZChrZXkpKSB7XG4gICAgICB0aGlzW2tleV0gPSB2YWxcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBvYi5jb252ZXJ0KGtleSwgdmFsKVxuICAgIG9iLm5vdGlmeSgpXG4gICAgaWYgKG9iLnZtcykge1xuICAgICAgdmFyIGkgPSBvYi52bXMubGVuZ3RoXG4gICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgIHZhciB2bSA9IG9iLnZtc1tpXVxuICAgICAgICB2bS5fcHJveHkoa2V5KVxuICAgICAgICAvLyB2bS5fZGlnZXN0KCkgLy8gdG9kb1xuICAgICAgfVxuICAgIH1cbiAgfVxuKVxuXG4vKipcbiAqIFNldCBhIHByb3BlcnR5IG9uIGFuIG9ic2VydmVkIG9iamVjdCwgY2FsbGluZyBhZGQgdG9cbiAqIGVuc3VyZSB0aGUgcHJvcGVydHkgaXMgb2JzZXJ2ZWQuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGtleVxuICogQHBhcmFtIHsqfSB2YWxcbiAqIEBwdWJsaWNcbiAqL1xuXG5fLmRlZmluZShcbiAgb2JqUHJvdG8sXG4gICckc2V0JyxcbiAgZnVuY3Rpb24gJHNldCAoa2V5LCB2YWwpIHtcbiAgICB0aGlzLiRhZGQoa2V5LCB2YWwpXG4gICAgdGhpc1trZXldID0gdmFsXG4gIH1cbilcblxuLyoqXG4gKiBEZWxldGVzIGEgcHJvcGVydHkgZnJvbSBhbiBvYnNlcnZlZCBvYmplY3RcbiAqIGFuZCBlbWl0cyBjb3JyZXNwb25kaW5nIGV2ZW50XG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGtleVxuICogQHB1YmxpY1xuICovXG5cbl8uZGVmaW5lKFxuICBvYmpQcm90byxcbiAgJyRkZWxldGUnLFxuICBmdW5jdGlvbiAkZGVsZXRlIChrZXkpIHtcbiAgICBpZiAoIXRoaXMuaGFzT3duUHJvcGVydHkoa2V5KSkgcmV0dXJuXG4gICAgZGVsZXRlIHRoaXNba2V5XVxuICAgIHZhciBvYiA9IHRoaXMuX19vYl9fXG4gICAgaWYgKCFvYiB8fCBfLmlzUmVzZXJ2ZWQoa2V5KSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIG9iLm5vdGlmeSgpXG4gICAgaWYgKG9iLnZtcykge1xuICAgICAgdmFyIGkgPSBvYi52bXMubGVuZ3RoXG4gICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgIHZhciB2bSA9IG9iLnZtc1tpXVxuICAgICAgICB2bS5fdW5wcm94eShrZXkpXG4gICAgICAgIC8vIHZtLl9kaWdlc3QoKSAvLyB0b2RvXG4gICAgICB9XG4gICAgfVxuICB9XG4pXG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL2xpYi92bS9vYnNlcnZlci9vYmplY3QuanNcbiAqKi8iLCIgLyoqXG4gKiBAZmlsZU92ZXJ2aWV3XG4gKiBWaWV3TW9kZWwgdGVtcGxhdGUgcGFyc2VyICYgZGF0YS1iaW5kaW5nIHByb2Nlc3NcbiAqXG4gKiByZXF1aXJlZDpcbiAqIGluZGV4LmpzOiBWbVxuICogZG9tLWhlbHBlci5qczogX2NyZWF0ZUVsZW1lbnQsIF9jcmVhdGVCbG9ja1xuICogZG9tLWhlbHBlci5qczogX2F0dGFjaFRhcmdldCwgX21vdmVUYXJnZXQsIF9yZW1vdmVUYXJnZXRcbiAqIGRpcmVjdGl2ZS5qczogX2JpbmRFbGVtZW50LCBfYmluZFN1YlZtLCBfd2F0Y2hcbiAqIGV2ZW50cy5qczogJG9uXG4gKi9cblxuLyoqXG4gKiBidWlsZChleHRlcm5hbERpcnMpXG4gKiAgIGNyZWF0ZVZtKClcbiAqICAgbWVyZ2UoZXh0ZXJuYWxEaXJzLCBkaXJzKVxuICogICBnZW5lcmF0ZSh0ZW1wbGF0ZSwgcGFyZW50Tm9kZSlcbiAqICAgICBpZiAodHlwZSBpcyBjb250ZW50KSBjcmVhdGUgY29udGVudE5vZGVcbiAqICAgICBlbHNlIGlmIChkaXJzIGhhdmUgdi1mb3IpIGZvcmVhY2ggLT4gY3JlYXRlIGNvbnRleHRcbiAqICAgICAgIC0+IGdlbmVyYXRlKHRlbXBsYXRlV2l0aG91dEZvciwgcGFyZW50Tm9kZSk6IGRpZmYobGlzdCkgb25jaGFuZ2VcbiAqICAgICBlbHNlIGlmIChkaXJzIGhhdmUgdi1pZikgYXNzZXJ0XG4gKiAgICAgICAtPiBnZW5lcmF0ZSh0ZW1wbGF0ZVdpdGhvdXRJZiwgcGFyZW50Tm9kZSk6IHRvZ2dsZShzaG93bikgb25jaGFuZ2VcbiAqICAgICBlbHNlIGlmICh0eXBlIGlzIG5hdGl2ZSlcbiAqICAgICAgIHNldChkaXJzKTogdXBkYXRlKGlkL2F0dHIvc3R5bGUvY2xhc3MpIG9uY2hhbmdlXG4gKiAgICAgICBhcHBlbmQodGVtcGxhdGUsIHBhcmVudE5vZGUpXG4gKiAgICAgICBmb3JlYWNoIGNoaWxkTm9kZXMgLT4gZ2VuZXJhdGUoY2hpbGROb2RlLCB0ZW1wbGF0ZSlcbiAqICAgICBlbHNlIGlmICh0eXBlIGlzIGN1c3RvbSlcbiAqICAgICAgIGFkZENoaWxkVm0odm0sIHBhcmVudFZtKVxuICogICAgICAgYnVpbGQoZXh0ZXJuYWxEaXJzKVxuICogICAgICAgZm9yZWFjaCBjaGlsZE5vZGVzIC0+IGdlbmVyYXRlKGNoaWxkTm9kZSwgdGVtcGxhdGUpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfYnVpbGQoKSB7XG4gIGNvbnN0IG9wdCA9IHRoaXMuX29wdGlvbnMgfHwge31cbiAgY29uc3QgdGVtcGxhdGUgPSBvcHQudGVtcGxhdGUgfHwge31cblxuICBpZiAob3B0LnJlcGxhY2UpIHtcbiAgICBpZiAodGVtcGxhdGUuY2hpbGRyZW4gJiYgdGVtcGxhdGUuY2hpbGRyZW4ubGVuZ3RoID09PSAxKSB7XG4gICAgICB0aGlzLl9nZW5lcmF0ZSh0ZW1wbGF0ZS5jaGlsZHJlblswXSwgdGhpcy5fcGFyZW50RWwpXG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgdGhpcy5fZ2VuZXJhdGUodGVtcGxhdGUuY2hpbGRyZW4sIHRoaXMuX3BhcmVudEVsKVxuICAgIH1cbiAgfVxuICBlbHNlIHtcbiAgICB0aGlzLl9nZW5lcmF0ZSh0ZW1wbGF0ZSwgdGhpcy5fcGFyZW50RWwpXG4gIH1cblxuICB0aGlzLiRlbWl0KCdob29rOnJlYWR5JylcbiAgdGhpcy5fcmVhZHkgPSB0cnVlXG59XG5cbi8qKlxuICogR2VuZXJhdGUgZWxlbWVudHMgYnkgY2hpbGQgb3IgY2hpbGRyZW4gYW5kIGFwcGVuZCB0byBwYXJlbnQgZWxlbWVudHMuXG4gKiBSb290IGVsZW1lbnQgaW5mbyB3b3VsZCBiZSBtZXJnZWQgaWYgaGFzLiBUaGUgZmlyc3QgYXJndW1lbnQgbWF5IGJlIGFuIGFycmF5XG4gKiBpZiB0aGUgcm9vdCBlbGVtZW50IHdpdGggb3B0aW9ucy5yZXBsYWNlIGhhcyBub3Qgb25seSBvbmUgY2hpbGQuXG4gKlxuICogQHBhcmFtICB7b2JqZWN0fGFycmF5fSB0YXJnZXRcbiAqIEBwYXJhbSAge29iamVjdH0gcGFyZW50RWxcbiAqIEBwYXJhbSAge29iamVjdH0gY29udGV4dFxuICovXG5leHBvcnQgZnVuY3Rpb24gX2dlbmVyYXRlKHRhcmdldCwgcGFyZW50RWwsIGNvbnRleHQpIHtcblxuICBpZiAoQXJyYXkuaXNBcnJheSh0YXJnZXQpKSB7XG4gICAgY29uc3QgZnJhZ0Jsb2NrID0gdGhpcy5fY3JlYXRlQmxvY2socGFyZW50RWwpXG4gICAgdGFyZ2V0LmZvckVhY2goKGNoaWxkKSA9PiB7XG4gICAgICB0aGlzLl9nZW5lcmF0ZShjaGlsZCwgZnJhZ0Jsb2NrLCBjb250ZXh0KVxuICAgIH0pXG4gICAgcmV0dXJuXG4gIH1cblxuICBjb250ZXh0ID0gY29udGV4dCB8fCB7fVxuXG4gIGlmICh0YXJnZXQudHlwZSA9PT0gJ2NvbnRlbnQnIHx8IHRhcmdldC50eXBlID09PSAnc2xvdCcpIHtcbiAgICB0aGlzLl9jb250ZW50ID0gdGhpcy5fY3JlYXRlQmxvY2socGFyZW50RWwpXG4gICAgcmV0dXJuXG4gIH1cblxuICBpZiAoIWNvbnRleHQuaGFzT3duUHJvcGVydHkoJ3JlcGVhdCcpICYmIHRhcmdldC5yZXBlYXQpIHtcbiAgICBjb25zdCBleHByZXNzaW9uID0gdGFyZ2V0LnJlcGVhdC5leHByZXNzaW9uIHx8IHRhcmdldC5yZXBlYXRcbiAgICBjb25zdCBsaXN0ID0gZXhwcmVzc2lvbi5jYWxsKHRoaXMpXG4gICAgY29uc3QgcmVwZWF0SWQgPSBsYXRlc3RSZXBlYXRJZCsrXG4gICAgY29uc3QgbGF0ZXN0SXRlbUlkID0gbWFya0xpc3QobGlzdCwgcmVwZWF0SWQpXG5cbiAgICBjb25zdCBmcmFnQmxvY2sgPSB0aGlzLl9jcmVhdGVCbG9jayhwYXJlbnRFbClcbiAgICBmcmFnQmxvY2suY2hpbGRyZW4gPSBbXVxuICAgIGZyYWdCbG9jay5kYXRhID0gbGlzdC5zbGljZSgwKVxuXG4gICAgdGhpcy5fY2hlY2tSZXBlYXQodGFyZ2V0LCBmcmFnQmxvY2ssIHJlcGVhdElkLCBsYXRlc3RJdGVtSWQpXG5cbiAgICBsaXN0LmZvckVhY2goKGl0ZW0sIGluZGV4KSA9PiB7XG4gICAgICBpZiAodHlwZW9mIGl0ZW0gPT09ICdvYmplY3QnKSB7XG4gICAgICAgIGl0ZW0uSU5ERVggPSBpbmRleFxuICAgICAgfVxuICAgICAgdGhpcy5fZ2VuZXJhdGUodGFyZ2V0LCBmcmFnQmxvY2ssIHtyZXBlYXQ6IGl0ZW19KVxuICAgIH0pXG5cbiAgICByZXR1cm5cbiAgfVxuXG4gIGxldCBzdWJDb250ZXh0ID0gdGhpc1xuICBpZiAoY29udGV4dC5yZXBlYXQgJiYgIWNvbnRleHQuc2hvd24pIHtcbiAgICBzdWJDb250ZXh0ID0gdGhpcy5fbWVyZ2VDb250ZXh0KGNvbnRleHQucmVwZWF0KVxuICB9XG5cbiAgaWYgKCFjb250ZXh0Lmhhc093blByb3BlcnR5KCdzaG93bicpICYmIHRhcmdldC5zaG93bikge1xuICAgIGNvbnN0IGRpc3BsYXkgPSB0YXJnZXQuc2hvd24uY2FsbChzdWJDb250ZXh0KVxuICAgIGNvbnN0IG5ld0NvbnRleHQgPSB7c2hvd246IHRydWV9XG4gICAgY29uc3QgZnJhZ0Jsb2NrID0gc3ViQ29udGV4dC5fY3JlYXRlQmxvY2socGFyZW50RWwpXG5cbiAgICBpZiAocGFyZW50RWwuZWxlbWVudCAmJiBwYXJlbnRFbC5jaGlsZHJlbikge1xuICAgICAgcGFyZW50RWwuY2hpbGRyZW4ucHVzaChmcmFnQmxvY2spXG4gICAgfVxuXG4gICAgaWYgKGNvbnRleHQucmVwZWF0KSB7XG4gICAgICBuZXdDb250ZXh0LnJlcGVhdCA9IGNvbnRleHQucmVwZWF0XG4gICAgfVxuXG4gICAgZnJhZ0Jsb2NrLmRpc3BsYXkgPSAhIWRpc3BsYXlcbiAgICBzdWJDb250ZXh0Ll9jaGVja0Rpc3BsYXkodGFyZ2V0LCBmcmFnQmxvY2ssIG5ld0NvbnRleHQpXG5cbiAgICBpZiAoZGlzcGxheSkge1xuICAgICAgc3ViQ29udGV4dC5fZ2VuZXJhdGUodGFyZ2V0LCBmcmFnQmxvY2ssIG5ld0NvbnRleHQpXG4gICAgfVxuXG4gICAgcmV0dXJuXG4gIH1cblxuICBsZXQgdHlwZUdldHRlciA9IHRhcmdldC50eXBlXG4gIGxldCB0eXBlID0gdHlwZUdldHRlclxuXG4gIGlmICh0eXBlb2YgdHlwZUdldHRlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHR5cGUgPSB0eXBlR2V0dGVyLmNhbGwoc3ViQ29udGV4dClcblxuICAgIGlmICghY29udGV4dC5oYXNPd25Qcm9wZXJ0eSgndHlwZScpKSB7XG4gICAgICBjb25zdCBuZXdDb250ZXh0ID0ge3R5cGU6IHR5cGV9XG4gICAgICBjb25zdCBmcmFnQmxvY2sgPSBzdWJDb250ZXh0Ll9jcmVhdGVCbG9jayhwYXJlbnRFbClcblxuICAgICAgaWYgKHBhcmVudEVsLmVsZW1lbnQgJiYgcGFyZW50RWwuY2hpbGRyZW4pIHtcbiAgICAgICAgcGFyZW50RWwuY2hpbGRyZW4ucHVzaChmcmFnQmxvY2spXG4gICAgICB9XG5cbiAgICAgIHN1YkNvbnRleHQuX3dhdGNoKHR5cGVHZXR0ZXIsICh2YWx1ZSkgPT4ge1xuICAgICAgICBzdWJDb250ZXh0Ll9yZW1vdmVCbG9jayhmcmFnQmxvY2ssIHRydWUpXG4gICAgICAgIHN1YkNvbnRleHQuX2dlbmVyYXRlKHRhcmdldCwgZnJhZ0Jsb2NrLCB7dHlwZTogdmFsdWV9KVxuICAgICAgfSlcblxuICAgICAgc3ViQ29udGV4dC5fZ2VuZXJhdGUodGFyZ2V0LCBmcmFnQmxvY2ssIG5ld0NvbnRleHQpXG5cbiAgICAgIHJldHVyblxuICAgIH1cbiAgfVxuXG4gIGxldCBpc0NvbXBvbmVudFxuICBpZiAodGhpcy5fYXBwICYmIHRoaXMuX2FwcC5jdXN0b21Db21wb25lbnRNYXAgJiYgdHlwZSkge1xuICAgIGlzQ29tcG9uZW50ID0gdGhpcy5fYXBwLmN1c3RvbUNvbXBvbmVudE1hcFt0eXBlXVxuICB9XG4gIGVsc2Uge1xuICAgIGlzQ29tcG9uZW50ID0gdGFyZ2V0LmNvbXBvbmVudFxuICB9XG5cbiAgaWYgKGlzQ29tcG9uZW50KSB7XG4gICAgY29uc3QgVm0gPSB0aGlzLmNvbnN0cnVjdG9yXG4gICAgY29uc3Qgc3ViVm0gPSBuZXcgVm0odHlwZSwgc3ViQ29udGV4dCwgcGFyZW50RWwsIHVuZGVmaW5lZCwge1xuICAgICAgJ2hvb2s6aW5pdCc6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc3ViQ29udGV4dC5fc2V0SWQodGFyZ2V0LmlkLCBudWxsLCB0aGlzKVxuICAgICAgfSxcbiAgICAgICdob29rOmNyZWF0ZWQnOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHN1YkNvbnRleHQuX2JpbmRTdWJWbSh0aGlzLCB0YXJnZXQsIGNvbnRleHQucmVwZWF0KVxuICAgICAgfSxcbiAgICAgICdob29rOnJlYWR5JzogZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5fY29udGVudCkge1xuICAgICAgICAgIHN1YkNvbnRleHQuX3NldENoaWxkcmVuKHRhcmdldCwgdGhpcy5fY29udGVudClcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pXG4gICAgc3ViQ29udGV4dC5fYmluZFN1YlZtQWZ0ZXJJbml0aWFsaXplZChzdWJWbSwgdGFyZ2V0KVxuICAgIHJldHVyblxuICB9XG5cbiAgY29uc3QgZWxlbWVudCA9IHN1YkNvbnRleHQuX2dlbmVyYXRlRWxlbWVudCh0eXBlLCB0YXJnZXQsIHBhcmVudEVsKVxuICBjb25zdCB0cmVlTW9kZSA9IHRhcmdldC5hcHBlbmQgPT09ICd0cmVlJ1xuICBpZiAoIXRyZWVNb2RlKSB7XG4gICAgc3ViQ29udGV4dC5fYXR0YWNoVGFyZ2V0KGVsZW1lbnQsIHBhcmVudEVsKVxuICB9XG4gIHN1YkNvbnRleHQuX3NldENoaWxkcmVuKHRhcmdldCwgZWxlbWVudClcbiAgaWYgKHRyZWVNb2RlKSB7XG4gICAgc3ViQ29udGV4dC5fYXR0YWNoVGFyZ2V0KGVsZW1lbnQsIHBhcmVudEVsKVxuICB9XG59XG5cbi8qKlxuICogR2VuZXJhdGUgZWxlbWVudCBmcm9tIHRlbXBsYXRlIGFuZCBhdHRhY2ggdG8gdGhlIGRlc3QgaWYgbmVlZGVkLlxuICogVGhlIHRpbWUgdG8gYXR0YWNoIGRlcGVuZHMgb24gd2hldGhlciB0aGUgbW9kZSBzdGF0dXMgaXMgbm9kZSBvciB0cmVlLlxuICpcbiAqIEBwYXJhbSAge29iamVjdH0gdGVtcGxhdGVcbiAqIEBwYXJhbSAge29iamVjdH0gZGVzdFxuICovXG5leHBvcnQgZnVuY3Rpb24gX2dlbmVyYXRlRWxlbWVudCh0eXBlLCB0ZW1wbGF0ZSwgZGVzdCkge1xuXG4gIHRoaXMuX2FwcGx5TmFpdHZlQ29tcG9uZW50T3B0aW9ucyh0ZW1wbGF0ZSlcblxuICBsZXQgZWxlbWVudFxuICBpZiAoZGVzdC5yZWYgPT09ICdfZG9jdW1lbnRFbGVtZW50Jykge1xuICAgIC8vIGlmIGl0cyBwYXJlbnQgaXMgZG9jdW1lbnRFbGVtZW50IHRoZW4gaXQncyBhIGJvZHlcbiAgICBlbGVtZW50ID0gdGhpcy5fY3JlYXRlQm9keSh0eXBlKVxuICB9IGVsc2Uge1xuICAgIGVsZW1lbnQgPSB0aGlzLl9jcmVhdGVFbGVtZW50KHR5cGUpXG4gIH1cbiAgLy8gVE9ETyBpdCB3YXMgYSByb290IGVsZW1lbnQgd2hlbiBub3QgaW4gYSBmcmFnbWVudFxuICBpZiAoIXRoaXMuX3Jvb3RFbCkge1xuICAgIHRoaXMuX3Jvb3RFbCA9IGVsZW1lbnRcbiAgfVxuXG4gIHRoaXMuX2JpbmRFbGVtZW50KGVsZW1lbnQsIHRlbXBsYXRlKVxuXG4gIGlmICh0ZW1wbGF0ZS5hdHRyICYmIHRlbXBsYXRlLmF0dHIuYXBwZW5kKSB7IC8vIGJhY2t3YXJkLCBhcHBlbmQgcHJvcCBpbiBhdHRyXG4gICAgZWxlbWVudC5hcHBlbmQgPSB0ZW1wbGF0ZS5hdHRyLmFwcGVuZFxuICB9XG5cbiAgcmV0dXJuIGVsZW1lbnRcbn1cblxuLyoqXG4gKiBTZXQgYWxsIGNoaWxkcmVuIHRvIGEgY2VydGFpbiBwYXJlbnQgZWxlbWVudC5cbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gdGVtcGxhdGVcbiAqIEBwYXJhbSB7b2JqZWN0fSBwYXJlbnRFbFxuICovXG5leHBvcnQgZnVuY3Rpb24gX3NldENoaWxkcmVuKHRlbXBsYXRlLCBwYXJlbnRFbCkge1xuICBjb25zdCBjaGlsZHJlbiA9IHRlbXBsYXRlLmNoaWxkcmVuXG4gIGlmIChjaGlsZHJlbiAmJiBjaGlsZHJlbi5sZW5ndGgpIHtcbiAgICBjaGlsZHJlbi5mb3JFYWNoKChjaGlsZCkgPT4ge1xuICAgICAgdGhpcy5fZ2VuZXJhdGUoY2hpbGQsIHBhcmVudEVsKVxuICAgIH0pXG4gIH1cbn1cblxuLyoqXG4gKiBXYXRjaCB0aGUgbGlzdCB1cGRhdGUgYW5kIHJlZnJlc2ggdGhlIGNoYW5nZXMuXG4gKlxuICogQHBhcmFtICB7b2JqZWN0fSB0YXJnZXRcbiAqIEBwYXJhbSAge29iamVjdH0gZnJhZ0Jsb2NrXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfY2hlY2tSZXBlYXQodGFyZ2V0LCBmcmFnQmxvY2ssIHJlcGVhdElkLCBsYXRlc3RJdGVtSWQpIHtcbiAgY29uc3QgZXhwcmVzc2lvbiA9IHRhcmdldC5yZXBlYXQuZXhwcmVzc2lvbiB8fCB0YXJnZXQucmVwZWF0XG4gIGNvbnN0IGNoaWxkcmVuID0gZnJhZ0Jsb2NrLmNoaWxkcmVuXG5cbiAgdGhpcy5fd2F0Y2hCbG9jayhmcmFnQmxvY2ssIGV4cHJlc3Npb24sICdyZXBlYXQnLCAodmFsdWUpID0+IHtcbiAgICBpZiAoIWZyYWdCbG9jaykge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY29uc3Qgb2xkQ2hpbGRyZW4gPSBjaGlsZHJlbi5zbGljZSgpXG4gICAgY29uc3Qgb2xkVmFsdWUgPSBmcmFnQmxvY2suZGF0YS5zbGljZSgpXG4gICAgLy8gMS4gY29sbGVjdCBhbGwgbmV3IHJlZnMgdHJhY2sgYnlcbiAgICBjb25zdCB0cmFja01hcCA9IHt9XG4gICAgY29uc3QgcmV1c2VkTWFwID0ge31cbiAgICB2YWx1ZS5mb3JFYWNoKChpdGVtLCBpbmRleCkgPT4ge1xuICAgICAgbGV0IGtleSA9IGl0ZW1bYF9fd3hfcmVwZWF0XyR7cmVwZWF0SWR9X19gXVxuICAgICAgaWYgKCFrZXkpIHtcbiAgICAgICAga2V5ID0gbGF0ZXN0SXRlbUlkKytcbiAgICAgICAgc2V0UmVwZWF0SXRlbUlkKGl0ZW0sIHJlcGVhdElkLCBrZXkpXG4gICAgICB9XG4gICAgICB0cmFja01hcFtrZXldID0gaXRlbVxuICAgIH0pXG5cbiAgICAvLyAyLiByZW1vdmUgdW51c2VkIGVsZW1lbnQgZm9yZWFjaCBvbGQgaXRlbVxuICAgIGNvbnN0IHJldXNlZExpc3QgPSBbXVxuICAgIG9sZFZhbHVlLmZvckVhY2goKGl0ZW0sIGluZGV4KSA9PiB7XG4gICAgICBjb25zdCBrZXkgPSBpdGVtW2BfX3d4X3JlcGVhdF8ke3JlcGVhdElkfV9fYF1cbiAgICAgIGlmICh0cmFja01hcC5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgIHJldXNlZE1hcFtrZXldID0ge2l0ZW0sIGluZGV4LCB0YXJnZXQ6IG9sZENoaWxkcmVuW2luZGV4XX1cbiAgICAgICAgcmV1c2VkTGlzdC5wdXNoKGl0ZW0pXG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgdGhpcy5fcmVtb3ZlVGFyZ2V0KG9sZENoaWxkcmVuW2luZGV4XSlcbiAgICAgIH1cbiAgICB9KVxuXG4gICAgLy8gMy4gY3JlYXRlIG5ldyBlbGVtZW50IGZvcmVhY2ggbmV3IGl0ZW1cbiAgICBjaGlsZHJlbi5sZW5ndGggPSAwXG4gICAgZnJhZ0Jsb2NrLmRhdGEgPSB2YWx1ZS5zbGljZSgpXG4gICAgZnJhZ0Jsb2NrLnVwZGF0ZU1hcmsgPSBmcmFnQmxvY2suc3RhcnRcblxuICAgIHZhbHVlLmZvckVhY2goKGl0ZW0sIGluZGV4KSA9PiB7XG4gICAgICBjb25zdCBrZXkgPSBpdGVtW2BfX3d4X3JlcGVhdF8ke3JlcGVhdElkfV9fYF1cbiAgICAgIGNvbnN0IHJldXNlZCA9IHJldXNlZE1hcFtrZXldXG4gICAgICBpZiAodHlwZW9mIGl0ZW0gPT09ICdvYmplY3QnKSB7XG4gICAgICAgIGl0ZW0uSU5ERVggPSBpbmRleFxuICAgICAgfVxuICAgICAgaWYgKHJldXNlZCkge1xuICAgICAgICBpZiAocmV1c2VkLml0ZW0gPT09IHJldXNlZExpc3RbMF0pIHtcbiAgICAgICAgICByZXVzZWRMaXN0LnNoaWZ0KClcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXVzZWRMaXN0LiRyZW1vdmUocmV1c2VkLml0ZW0pXG4gICAgICAgICAgdGhpcy5fbW92ZVRhcmdldChyZXVzZWQudGFyZ2V0LCBmcmFnQmxvY2sudXBkYXRlTWFyaywgdHJ1ZSlcbiAgICAgICAgfVxuICAgICAgICBjaGlsZHJlbi5wdXNoKHJldXNlZC50YXJnZXQpXG4gICAgICAgIGZyYWdCbG9jay51cGRhdGVNYXJrID0gcmV1c2VkLnRhcmdldFxuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHRoaXMuX2dlbmVyYXRlKHRhcmdldCwgZnJhZ0Jsb2NrLCB7cmVwZWF0OiBpdGVtfSlcbiAgICAgIH1cbiAgICB9KVxuXG4gICAgZGVsZXRlIGZyYWdCbG9jay51cGRhdGVNYXJrXG4gIH0pXG59XG5cbmxldCBsYXRlc3RSZXBlYXRJZCA9IDFcblxuZnVuY3Rpb24gbWFya0xpc3QobGlzdCwgcmVwZWF0SWQpIHtcbiAgbGV0IGxhdGVzdEl0ZW1JZCA9IDFcbiAgbGlzdC5mb3JFYWNoKChpdGVtKSA9PiB7XG4gICAgc2V0UmVwZWF0SXRlbUlkKGl0ZW0sIHJlcGVhdElkLCBsYXRlc3RJdGVtSWQrKylcbiAgfSlcbiAgcmV0dXJuIGxhdGVzdEl0ZW1JZFxufVxuXG5mdW5jdGlvbiBzZXRSZXBlYXRJdGVtSWQoaXRlbSwgcmVwZWF0SWQsIGl0ZW1JZCkge1xuICBjb25zdCBrZXkgPSBgX193eF9yZXBlYXRfJHtyZXBlYXRJZH1fX2BcbiAgaWYgKHR5cGVvZiBpdGVtID09PSAnb2JqZWN0Jykge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShpdGVtLCBrZXksIHtcbiAgICAgIHZhbHVlOiBpdGVtSWRcbiAgICB9KVxuICB9XG59XG5cbi8qKlxuICogV2F0Y2ggdGhlIGRpc3BsYXkgdXBkYXRlIGFuZCBhZGQvcmVtb3ZlIHRoZSBlbGVtZW50LlxuICpcbiAqIEBwYXJhbSAge29iamVjdH0gdGFyZ2V0XG4gKiBAcGFyYW0gIHtvYmplY3R9IGZyYWdCbG9ja1xuICogQHBhcmFtICB7b2JqZWN0fSBjb250ZXh0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfY2hlY2tEaXNwbGF5KHRhcmdldCwgZnJhZ0Jsb2NrLCBjb250ZXh0KSB7XG5cbiAgdGhpcy5fd2F0Y2hCbG9jayhmcmFnQmxvY2ssIHRhcmdldC5zaG93biwgJ3Nob3duJywgKHZhbHVlKSA9PiB7XG4gICAgaWYgKCFmcmFnQmxvY2sgfHwgISFmcmFnQmxvY2suZGlzcGxheSA9PT0gISF2YWx1ZSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIGZyYWdCbG9jay5kaXNwbGF5ID0gdmFsdWVcbiAgICBpZiAodmFsdWUpIHtcbiAgICAgIHRoaXMuX2dlbmVyYXRlKHRhcmdldCwgZnJhZ0Jsb2NrLCBjb250ZXh0KVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHRoaXMuX3JlbW92ZUJsb2NrKGZyYWdCbG9jaywgdHJ1ZSlcbiAgICB9XG4gIH0pXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBfd2F0Y2hCbG9jayhmcmFnQmxvY2ssIGNhbGMsIHR5cGUsIGhhbmRsZXIpIHtcbiAgY29uc3QgZGlmZmVyID0gdGhpcyAmJiB0aGlzLl9hcHAgJiYgdGhpcy5fYXBwLmRpZmZlclxuICBjb25zdCBjb25maWcgPSB7fVxuICBjb25zdCBkZXB0aCA9IChmcmFnQmxvY2suZWxlbWVudC5kZXB0aCB8fCAwKSArIDFcblxuICB0aGlzLl93YXRjaChjYWxjLCAodmFsdWUpID0+IHtcbiAgICBjb25maWcubGF0ZXN0VmFsdWUgPSB2YWx1ZVxuICAgIGlmIChkaWZmZXIgJiYgIWNvbmZpZy5yZWNvcmRlZCkge1xuICAgICAgZGlmZmVyLmFwcGVuZCh0eXBlLCBkZXB0aCwgZnJhZ0Jsb2NrLmJsb2NrSWQsICgpID0+IHtcbiAgICAgICAgY29uc3QgbGF0ZXN0VmFsdWUgPSBjb25maWcubGF0ZXN0VmFsdWVcbiAgICAgICAgaGFuZGxlcihsYXRlc3RWYWx1ZSlcbiAgICAgICAgY29uZmlnLnJlY29yZGVkID0gZmFsc2VcbiAgICAgICAgY29uZmlnLmxhdGVzdFZhbHVlID0gdW5kZWZpbmVkXG4gICAgICB9KVxuICAgIH1cbiAgICBjb25maWcucmVjb3JkZWQgPSB0cnVlXG4gIH0pXG59XG5cbi8qKlxuICogQ2xvbmUgYSBjb250ZXh0IGFuZCBtZXJnZSBjZXJ0YWluIGRhdGEuXG4gKlxuICogQHBhcmFtICB7b2JqZWN0fSBtZXJnZWREYXRhXG4gKiBAcmV0dXJuIHtvYmplY3R9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfbWVyZ2VDb250ZXh0KG1lcmdlZERhdGEpIHtcbiAgY29uc3QgY29udGV4dCA9IE9iamVjdC5jcmVhdGUodGhpcylcbiAgY29udGV4dC5fZGF0YSA9IG1lcmdlZERhdGFcbiAgY29udGV4dC5faW5pdERhdGEoKVxuICBjb250ZXh0Ll9yZWFsUGFyZW50ID0gdGhpc1xuICByZXR1cm4gY29udGV4dFxufVxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9saWIvdm0vY29tcGlsZXIuanNcbiAqKi8iLCIvKipcbiAqIEBmaWxlT3ZlcnZpZXdcbiAqIERpcmVjdGl2ZSBQYXJzZXJcbiAqL1xuXG5pbXBvcnQge2JpbmQsIGV4dGVuZH0gZnJvbSAnLi4vdXRpbCdcblxuaW1wb3J0IFdhdGNoZXIgZnJvbSAnLi93YXRjaGVyJ1xuaW1wb3J0IHtuYXRpdmVDb21wb25lbnRNYXB9IGZyb20gJy4uL2NvbmZpZydcblxuY29uc3QgU0VUVEVSUyA9IHtcbiAgYXR0cjogJ3NldEF0dHInLFxuICBzdHlsZTogJ3NldFN0eWxlJyxcbiAgZXZlbnQ6ICdhZGRFdmVudCdcbn1cblxuLyoqXG4gKiBhcHBseSB0aGUgbmF0aXZlIGNvbXBvbmVudCdzIG9wdGlvbnMoc3BlY2lmaWVkIGJ5IHRlbXBsYXRlLnR5cGUpXG4gKiB0byB0aGUgdGVtcGxhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9hcHBseU5haXR2ZUNvbXBvbmVudE9wdGlvbnModGVtcGxhdGUpIHtcbiAgY29uc3Qge3R5cGV9ID0gdGVtcGxhdGVcbiAgY29uc3Qgb3B0aW9ucyA9IG5hdGl2ZUNvbXBvbmVudE1hcFt0eXBlXVxuXG4gIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ29iamVjdCcpIHtcbiAgICBleHRlbmQodGVtcGxhdGUsIG9wdGlvbnMpXG4gIH1cbn1cblxuLyoqXG4gKiBiaW5kIGFsbCBpZCwgYXR0ciwgY2xhc3NuYW1lcywgc3R5bGUsIGV2ZW50cyB0byBhbiBlbGVtZW50XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfYmluZEVsZW1lbnQoZWwsIHRlbXBsYXRlKSB7XG4gIHRoaXMuX3NldElkKHRlbXBsYXRlLmlkLCBlbCwgdGhpcylcbiAgdGhpcy5fc2V0QXR0cihlbCwgdGVtcGxhdGUuYXR0cilcbiAgdGhpcy5fc2V0Q2xhc3MoZWwsIHRlbXBsYXRlLmNsYXNzTGlzdClcbiAgdGhpcy5fc2V0U3R5bGUoZWwsIHRlbXBsYXRlLnN0eWxlKVxuICB0aGlzLl9iaW5kRXZlbnRzKGVsLCB0ZW1wbGF0ZS5ldmVudHMpXG59XG5cbi8qKlxuICogYmluZCBhbGwgcHJvcHMgdG8gc3ViIHZtIGFuZCBiaW5kIGFsbCBzdHlsZSwgZXZlbnRzIHRvIHRoZSByb290IGVsZW1lbnRcbiAqIG9mIHRoZSBzdWIgdm0gaWYgaXQgZG9lc24ndCBoYXZlIGEgcmVwbGFjZWQgbXVsdGktbm9kZSBmcmFnbWVudFxuICovXG5leHBvcnQgZnVuY3Rpb24gX2JpbmRTdWJWbShzdWJWbSwgdGVtcGxhdGUsIHJlcGVhdEl0ZW0pIHtcbiAgc3ViVm0gPSBzdWJWbSB8fCB7fVxuICB0ZW1wbGF0ZSA9IHRlbXBsYXRlIHx8IHt9XG5cbiAgY29uc3Qgb3B0aW9ucyA9IHN1YlZtLl9vcHRpb25zIHx8IHt9XG5cbiAgLy8gYmluZCBwcm9wc1xuICBsZXQgcHJvcHMgPSBvcHRpb25zLnByb3BzXG5cbiAgaWYgKEFycmF5LmlzQXJyYXkocHJvcHMpKSB7XG4gICAgcHJvcHMgPSBwcm9wcy5yZWR1Y2UoKHJlc3VsdCwgdmFsdWUpID0+IHtcbiAgICAgIHJlc3VsdFt2YWx1ZV0gPSB0cnVlXG4gICAgICByZXR1cm4gcmVzdWx0XG4gICAgfSwge30pXG4gIH1cblxuICBtZXJnZVByb3BzKHJlcGVhdEl0ZW0sIHByb3BzLCB0aGlzLCBzdWJWbSlcbiAgbWVyZ2VQcm9wcyh0ZW1wbGF0ZS5hdHRyLCBwcm9wcywgdGhpcywgc3ViVm0pXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBfYmluZFN1YlZtQWZ0ZXJJbml0aWFsaXplZChzdWJWbSwgdGVtcGxhdGUpIHtcbiAgbWVyZ2VDbGFzc1N0eWxlKHRlbXBsYXRlLmNsYXNzTGlzdCwgdGhpcywgc3ViVm0pXG4gIG1lcmdlU3R5bGUodGVtcGxhdGUuc3R5bGUsIHRoaXMsIHN1YlZtKVxuICBtZXJnZUV2ZW50KHRlbXBsYXRlLmV2ZW50cywgdGhpcywgc3ViVm0pXG59XG5cbmZ1bmN0aW9uIG1lcmdlUHJvcHModGFyZ2V0LCBwcm9wcywgdm0sIHN1YlZtKSB7XG4gIGlmICghdGFyZ2V0KSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgZm9yIChjb25zdCBrZXkgaW4gdGFyZ2V0KSB7XG4gICAgaWYgKCFwcm9wcyB8fCBwcm9wc1trZXldKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHRhcmdldFtrZXldXG4gICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGNvbnN0IHJldHVyblZhbHVlID0gdm0uX3dhdGNoKHZhbHVlLCBmdW5jdGlvbiAodikge1xuICAgICAgICAgIHN1YlZtW2tleV0gPSB2XG4gICAgICAgIH0pXG4gICAgICAgIHN1YlZtW2tleV0gPSByZXR1cm5WYWx1ZVxuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHN1YlZtW2tleV0gPSB2YWx1ZVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBtZXJnZVN0eWxlKHRhcmdldCwgdm0sIHN1YlZtKSB7XG4gIGZvciAoY29uc3Qga2V5IGluIHRhcmdldCkge1xuICAgIGNvbnN0IHZhbHVlID0gdGFyZ2V0W2tleV1cbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBjb25zdCByZXR1cm5WYWx1ZSA9IHZtLl93YXRjaCh2YWx1ZSwgZnVuY3Rpb24gKHYpIHtcbiAgICAgICAgaWYgKHN1YlZtLl9yb290RWwpIHtcbiAgICAgICAgICBzdWJWbS5fcm9vdEVsLnNldFN0eWxlKGtleSwgdilcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICAgIHN1YlZtLl9yb290RWwuc2V0U3R5bGUoa2V5LCByZXR1cm5WYWx1ZSlcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBpZiAoc3ViVm0uX3Jvb3RFbCkge1xuICAgICAgICBzdWJWbS5fcm9vdEVsLnNldFN0eWxlKGtleSwgdmFsdWUpXG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIG1lcmdlQ2xhc3NTdHlsZSh0YXJnZXQsIHZtLCBzdWJWbSkge1xuICB2YXIgY3NzID0gdm0uX29wdGlvbnMgJiYgdm0uX29wdGlvbnMuc3R5bGUgfHwge31cblxuICBpZiAoIXN1YlZtLl9yb290RWwpIHtcbiAgICByZXR1cm5cbiAgfVxuXG4gIGlmICh0eXBlb2YgdGFyZ2V0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY29uc3QgdmFsdWUgPSB2bS5fd2F0Y2godGFyZ2V0LCAgdiA9PiB7XG4gICAgICBzZXRDbGFzc1N0eWxlKHN1YlZtLl9yb290RWwsIGNzcywgdilcbiAgICB9KVxuICAgIHNldENsYXNzU3R5bGUoc3ViVm0uX3Jvb3RFbCwgY3NzLCB2YWx1ZSlcbiAgfSBlbHNlIGlmICh0YXJnZXQpIHtcbiAgICBzZXRDbGFzc1N0eWxlKHN1YlZtLl9yb290RWwsIGNzcywgdGFyZ2V0KVxuICB9XG59XG5cbmZ1bmN0aW9uIG1lcmdlRXZlbnQodGFyZ2V0LCB2bSwgc3ViVm0pIHtcbiAgaWYgKHRhcmdldCAmJiBzdWJWbS5fcm9vdEVsKSB7XG4gICAgZm9yIChjb25zdCB0eXBlIGluIHRhcmdldCkge1xuICAgICAgY29uc3QgaGFuZGxlciA9IHZtW3RhcmdldFt0eXBlXV1cbiAgICAgIGlmIChoYW5kbGVyKSB7XG4gICAgICAgIHN1YlZtLl9yb290RWwuYWRkRXZlbnQodHlwZSwgYmluZChoYW5kbGVyLCB2bSkpXG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogYmluZCBpZCB0byBhbiBlbGVtZW50XG4gKiBlYWNoIGlkIGlzIHVuaXF1ZSBpbiBhIHdob2xlIHZtXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfc2V0SWQoaWQsIGVsLCB2bSkge1xuICBjb25zdCBtYXAgPSBPYmplY3QuY3JlYXRlKG51bGwpXG5cbiAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMobWFwLCB7XG4gICAgdm06IHtcbiAgICAgIHZhbHVlOiB2bSxcbiAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgIGNvbmZpZ3VyYWJsZTogZmFsc2VcbiAgICB9LFxuICAgIGVsOiB7XG4gICAgICBnZXQ6ICgpID0+IGVsIHx8IHZtLl9yb290RWwsXG4gICAgICBjb25maWd1cmFibGU6IGZhbHNlXG4gICAgfVxuICB9KVxuXG4gIGlmICh0eXBlb2YgaWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjb25zdCBoYW5kbGVyID0gaWRcbiAgICBpZCA9IGhhbmRsZXIuY2FsbCh0aGlzKVxuICAgIGlmIChpZCkge1xuICAgICAgdGhpcy5faWRzW2lkXSA9IG1hcFxuICAgIH1cbiAgICB0aGlzLl93YXRjaChoYW5kbGVyLCAobmV3SWQpID0+IHtcbiAgICAgIGlmIChuZXdJZCkge1xuICAgICAgICB0aGlzLl9pZHNbbmV3SWRdID0gbWFwXG4gICAgICB9XG4gICAgfSlcbiAgfVxuICBlbHNlIGlmIChpZCAmJiB0eXBlb2YgaWQgPT09ICdzdHJpbmcnKSB7XG4gICAgdGhpcy5faWRzW2lkXSA9IG1hcFxuICB9XG59XG5cbi8qKlxuICogYmluZCBhdHRyIHRvIGFuIGVsZW1lbnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9zZXRBdHRyKGVsLCBhdHRyKSB7XG4gIHRoaXMuX2JpbmREaXIoZWwsICdhdHRyJywgYXR0cilcbn1cblxuZnVuY3Rpb24gc2V0Q2xhc3NTdHlsZShlbCwgY3NzLCBjbGFzc0xpc3QpIHtcbiAgY29uc3QgY2xhc3NTdHlsZSA9IHt9XG4gIGNvbnN0IGxlbmd0aCA9IGNsYXNzTGlzdC5sZW5ndGhcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3Qgc3R5bGUgPSBjc3NbY2xhc3NMaXN0W2ldXVxuICAgIGlmIChzdHlsZSkge1xuICAgICAgZm9yIChjb25zdCBrZXkgaW4gc3R5bGUpIHtcbiAgICAgICAgY2xhc3NTdHlsZVtrZXldID0gc3R5bGVba2V5XVxuICAgICAgfVxuICAgIH1cbiAgfVxuICBlbC5zZXRDbGFzc1N0eWxlKGNsYXNzU3R5bGUpXG59XG5cbi8qKlxuICogYmluZCBjbGFzc25hbWVzIHRvIGFuIGVsZW1lbnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9zZXRDbGFzcyhlbCwgY2xhc3NMaXN0KSB7XG5cbiAgaWYgKHR5cGVvZiBjbGFzc0xpc3QgIT09ICdmdW5jdGlvbicgJiYgIUFycmF5LmlzQXJyYXkoY2xhc3NMaXN0KSkge1xuICAgIHJldHVyblxuICB9XG4gIGlmIChBcnJheS5pc0FycmF5KGNsYXNzTGlzdCkgJiYgIWNsYXNzTGlzdC5sZW5ndGgpIHtcbiAgICBlbC5zZXRDbGFzc1N0eWxlKHt9KVxuICAgIHJldHVyblxuICB9XG5cbiAgY29uc3Qgc3R5bGUgPSB0aGlzLl9vcHRpb25zICYmIHRoaXMuX29wdGlvbnMuc3R5bGUgfHwge31cbiAgaWYgKHR5cGVvZiBjbGFzc0xpc3QgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMuX3dhdGNoKGNsYXNzTGlzdCwgIHYgPT4ge1xuICAgICAgc2V0Q2xhc3NTdHlsZShlbCwgc3R5bGUsIHYpXG4gICAgfSlcbiAgICBzZXRDbGFzc1N0eWxlKGVsLCBzdHlsZSwgdmFsdWUpXG4gIH1cbiAgZWxzZSB7XG4gICAgc2V0Q2xhc3NTdHlsZShlbCwgc3R5bGUsIGNsYXNzTGlzdClcbiAgfVxufVxuXG4vKipcbiAqIGJpbmQgc3R5bGUgdG8gYW4gZWxlbWVudFxuICovXG5leHBvcnQgZnVuY3Rpb24gX3NldFN0eWxlKGVsLCBzdHlsZSkge1xuICB0aGlzLl9iaW5kRGlyKGVsLCAnc3R5bGUnLCBzdHlsZSlcbn1cblxuLyoqXG4gKiBhZGQgYW4gZXZlbnQgdHlwZSBhbmQgaGFuZGxlciB0byBhbiBlbGVtZW50IGFuZCBnZW5lcmF0ZSBhIGRvbSB1cGRhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9zZXRFdmVudChlbCwgdHlwZSwgaGFuZGxlcikge1xuICBlbC5hZGRFdmVudCh0eXBlLCBiaW5kKGhhbmRsZXIsIHRoaXMpKVxufVxuXG4vKipcbiAqIGFkZCBhbGwgZXZlbnRzIG9mIGFuIGVsZW1lbnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9iaW5kRXZlbnRzKGVsLCBldmVudHMpIHtcbiAgaWYgKCFldmVudHMpIHtcbiAgICByZXR1cm5cbiAgfVxuICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoZXZlbnRzKVxuICBsZXQgaSA9IGtleXMubGVuZ3RoXG4gIHdoaWxlIChpLS0pIHtcbiAgICBjb25zdCBrZXkgPSBrZXlzW2ldXG4gICAgbGV0IGhhbmRsZXIgPSBldmVudHNba2V5XVxuICAgIGlmICh0eXBlb2YgaGFuZGxlciA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGhhbmRsZXIgPSB0aGlzW2hhbmRsZXJdXG4gICAgfVxuICAgIHRoaXMuX3NldEV2ZW50KGVsLCBrZXksIGhhbmRsZXIpXG4gIH1cbn1cblxuLyoqXG4gKiBzZXQgYSBzZXJpZXMgb2YgbWVtYmVycyBhcyBhIGtpbmQgb2YgYW4gZWxlbWVudFxuICogZm9yIGV4YW1wbGU6IHN0eWxlLCBhdHRyLCAuLi5cbiAqIGlmIHRoZSB2YWx1ZSBpcyBhIGZ1bmN0aW9uIHRoZW4gYmluZCB0aGUgZGF0YSBjaGFuZ2VzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfYmluZERpcihlbCwgbmFtZSwgZGF0YSkge1xuICBpZiAoIWRhdGEpIHtcbiAgICByZXR1cm5cbiAgfVxuICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoZGF0YSlcbiAgbGV0IGkgPSBrZXlzLmxlbmd0aFxuICB3aGlsZSAoaS0tKSB7XG4gICAgY29uc3Qga2V5ID0ga2V5c1tpXVxuICAgIGNvbnN0IHZhbHVlID0gZGF0YVtrZXldXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgY29uc3QgdXBkYXRlID0gdmFsdWVcbiAgICAgIHRoaXMuX2JpbmRLZXkoZWwsIG5hbWUsIGtleSwgdXBkYXRlKVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGVsW1NFVFRFUlNbbmFtZV1dKGtleSwgdmFsdWUpXG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogYmluZCBkYXRhIGNoYW5nZXMgdG8gYSBjZXJ0YWluIGtleSB0byBhIG5hbWUgc2VyaWVzIGluIGFuIGVsZW1lbnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9iaW5kS2V5KGVsLCBuYW1lLCBrZXksIGNhbGMpIHtcbiAgY29uc3QgbWV0aG9kTmFtZSA9IFNFVFRFUlNbbmFtZV1cbiAgY29uc3Qgb2JqID0gZWxbbmFtZV1cbiAgLy8gd2F0Y2ggdGhlIGNhbGMsIGFuZCByZXR1cm5zIGEgdmFsdWUgYnkgY2FsYy5jYWxsKClcbiAgY29uc3QgdmFsdWUgPSB0aGlzLl93YXRjaChjYWxjLCAodmFsdWUpID0+IHtcbiAgICBmdW5jdGlvbiBoYW5kbGVyKCkge1xuICAgICAgZWxbbWV0aG9kTmFtZV0oa2V5LCB2YWx1ZSlcbiAgICB9XG4gICAgY29uc3QgZGlmZmVyID0gdGhpcyAmJiB0aGlzLl9hcHAgJiYgdGhpcy5fYXBwLmRpZmZlclxuICAgIGlmIChkaWZmZXIpIHtcbiAgICAgIGRpZmZlci5hcHBlbmQoJ2VsZW1lbnQnLCBlbC5kZXB0aCwgZWwucmVmLCBoYW5kbGVyKVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGhhbmRsZXIoKVxuICAgIH1cbiAgfSlcblxuICBlbFttZXRob2ROYW1lXShrZXksIHZhbHVlKVxufVxuXG4vKipcbiAqIHdhdGNoIGEgY2FsYyBmdW5jdGlvbiBhbmQgY2FsbGJhY2sgaWYgdGhlIGNhbGMgdmFsdWUgY2hhbmdlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gX3dhdGNoKGNhbGMsIGNhbGxiYWNrKSB7XG4gIGNvbnN0IHdhdGNoZXIgPSBuZXcgV2F0Y2hlcih0aGlzLCBjYWxjLCBmdW5jdGlvbiAodmFsdWUsIG9sZFZhbHVlKSB7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcgJiYgdmFsdWUgPT09IG9sZFZhbHVlKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgY2FsbGJhY2sodmFsdWUpXG4gIH0pXG5cbiAgcmV0dXJuIHdhdGNoZXIudmFsdWVcbn1cblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vbGliL3ZtL2RpcmVjdGl2ZS5qc1xuICoqLyIsIi8qKlxuICogVGhlIE1JVCBMaWNlbnNlIChNSVQpXG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDEzLTIwMTUgWXV4aSBFdmFuIFlvdVxuICpcbiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbiAqIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWxcbiAqIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHNcbiAqIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGxcbiAqIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuICogZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbiAqXG4gKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuICogYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4gKlxuICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbiAqIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbiAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG4gKiBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOXG4gKiBUSEUgU09GVFdBUkUuXG4gKi9cblxudmFyIF8gPSByZXF1aXJlKCcuL3V0aWwnKVxuLy8gdmFyIGNvbmZpZyA9IHJlcXVpcmUoJy4vY29uZmlnJylcbnZhciBPYnNlcnZlciA9IHJlcXVpcmUoJy4vb2JzZXJ2ZXInKVxuLy8gdmFyIGV4cFBhcnNlciA9IHJlcXVpcmUoJy4vcGFyc2Vycy9leHByZXNzaW9uJylcbi8vIHZhciBiYXRjaGVyID0gcmVxdWlyZSgnLi9iYXRjaGVyJylcbnZhciB1aWQgPSAwXG5cbi8qKlxuICogQSB3YXRjaGVyIHBhcnNlcyBhbiBleHByZXNzaW9uLCBjb2xsZWN0cyBkZXBlbmRlbmNpZXMsXG4gKiBhbmQgZmlyZXMgY2FsbGJhY2sgd2hlbiB0aGUgZXhwcmVzc2lvbiB2YWx1ZSBjaGFuZ2VzLlxuICogVGhpcyBpcyB1c2VkIGZvciBib3RoIHRoZSAkd2F0Y2goKSBhcGkgYW5kIGRpcmVjdGl2ZXMuXG4gKlxuICogQHBhcmFtIHtWdWV9IHZtXG4gKiBAcGFyYW0ge1N0cmluZ30gZXhwcmVzc2lvblxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2JcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKiAgICAgICAgICAgICAgICAgLSB7QXJyYXl9IGZpbHRlcnNcbiAqICAgICAgICAgICAgICAgICAtIHtCb29sZWFufSB0d29XYXlcbiAqICAgICAgICAgICAgICAgICAtIHtCb29sZWFufSBkZWVwXG4gKiAgICAgICAgICAgICAgICAgLSB7Qm9vbGVhbn0gdXNlclxuICogICAgICAgICAgICAgICAgIC0ge0Z1bmN0aW9ufSBbcHJlUHJvY2Vzc11cbiAqIEBjb25zdHJ1Y3RvclxuICovXG5cbi8vIGZ1bmN0aW9uIFdhdGNoZXIgKHZtLCBleHByZXNzaW9uLCBjYiwgb3B0aW9ucykge1xuZnVuY3Rpb24gV2F0Y2hlciAodm0sIHVwZGF0ZSwgY2IpIHtcbiAgdGhpcy52bSA9IHZtXG4gIHZtLl93YXRjaGVycy5wdXNoKHRoaXMpXG4gIC8vIHRoaXMuZXhwcmVzc2lvbiA9IGV4cHJlc3Npb25cbiAgdGhpcy5jYiA9IGNiXG4gIHRoaXMuaWQgPSArK3VpZCAvLyB1aWQgZm9yIGJhdGNoaW5nXG4gIHRoaXMuYWN0aXZlID0gdHJ1ZVxuICAvLyBvcHRpb25zID0gb3B0aW9ucyB8fCB7fVxuICAvLyB0aGlzLmRlZXAgPSAhIW9wdGlvbnMuZGVlcFxuICAvLyB0aGlzLnVzZXIgPSAhIW9wdGlvbnMudXNlclxuICAvLyB0aGlzLnR3b1dheSA9ICEhb3B0aW9ucy50d29XYXlcbiAgLy8gdGhpcy5maWx0ZXJzID0gb3B0aW9ucy5maWx0ZXJzXG4gIC8vIHRoaXMucHJlUHJvY2VzcyA9IG9wdGlvbnMucHJlUHJvY2Vzc1xuICB0aGlzLmRlcHMgPSBbXVxuICB0aGlzLm5ld0RlcHMgPSBbXVxuICAvLyBwYXJzZSBleHByZXNzaW9uIGZvciBnZXR0ZXIvc2V0dGVyXG4gIC8vIHZhciByZXMgPSBleHBQYXJzZXIucGFyc2UoZXhwcmVzc2lvbiwgb3B0aW9ucy50d29XYXkpXG4gIC8vIHRoaXMuZ2V0dGVyID0gcmVzLmdldFxuICAvLyB0aGlzLnNldHRlciA9IHJlcy5zZXRcbiAgdGhpcy5nZXR0ZXIgPSB1cGRhdGVcbiAgdGhpcy52YWx1ZSA9IHRoaXMuZ2V0KClcbn1cblxudmFyIHAgPSBXYXRjaGVyLnByb3RvdHlwZVxuXG4vKipcbiAqIEFkZCBhIGRlcGVuZGVuY3kgdG8gdGhpcyBkaXJlY3RpdmUuXG4gKlxuICogQHBhcmFtIHtEZXB9IGRlcFxuICovXG5cbnAuYWRkRGVwID0gZnVuY3Rpb24gKGRlcCkge1xuICB2YXIgbmV3RGVwcyA9IHRoaXMubmV3RGVwc1xuICB2YXIgb2xkID0gdGhpcy5kZXBzXG4gIGlmIChfLmluZGV4T2YobmV3RGVwcywgZGVwKSA8IDApIHtcbiAgICBuZXdEZXBzLnB1c2goZGVwKVxuICAgIHZhciBpID0gXy5pbmRleE9mKG9sZCwgZGVwKVxuICAgIGlmIChpIDwgMCkge1xuICAgICAgZGVwLmFkZFN1Yih0aGlzKVxuICAgIH0gZWxzZSB7XG4gICAgICBvbGRbaV0gPSBudWxsXG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogRXZhbHVhdGUgdGhlIGdldHRlciwgYW5kIHJlLWNvbGxlY3QgZGVwZW5kZW5jaWVzLlxuICovXG5cbnAuZ2V0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmJlZm9yZUdldCgpXG4gIHZhciB2bSA9IHRoaXMudm1cbiAgdmFyIHZhbHVlXG4gIHRyeSB7XG4gICAgdmFsdWUgPSB0aGlzLmdldHRlci5jYWxsKHZtLCB2bSlcbiAgfSBjYXRjaCAoZSkge1xuICAgIC8vIGlmIChjb25maWcud2FybkV4cHJlc3Npb25FcnJvcnMpIHtcbiAgICAvLyAgIF8ud2FybihcbiAgICAvLyAgICAgJ0Vycm9yIHdoZW4gZXZhbHVhdGluZyBleHByZXNzaW9uIFwiJyArXG4gICAgLy8gICAgIHRoaXMuZXhwcmVzc2lvbiArICdcIjpcXG4gICAnICsgZVxuICAgIC8vICAgKVxuICAgIC8vIH1cbiAgICBfLndhcm4oJ0Vycm9yIHdoZW4gdXBkYXRlXCInKVxuICB9XG4gIC8vIFwidG91Y2hcIiBldmVyeSBwcm9wZXJ0eSBzbyB0aGV5IGFyZSBhbGwgdHJhY2tlZCBhc1xuICAvLyBkZXBlbmRlbmNpZXMgZm9yIGRlZXAgd2F0Y2hpbmdcbiAgaWYgKHRoaXMuZGVlcCkge1xuICAgIHRyYXZlcnNlKHZhbHVlKVxuICB9XG4gIGlmICh0aGlzLnByZVByb2Nlc3MpIHtcbiAgICB2YWx1ZSA9IHRoaXMucHJlUHJvY2Vzcyh2YWx1ZSlcbiAgfVxuICBpZiAodGhpcy5maWx0ZXJzKSB7XG4gICAgdmFsdWUgPSB2bS5fYXBwbHlGaWx0ZXJzKHZhbHVlLCBudWxsLCB0aGlzLmZpbHRlcnMsIGZhbHNlKVxuICB9XG4gIHRoaXMuYWZ0ZXJHZXQoKVxuICByZXR1cm4gdmFsdWVcbn1cblxuLy8gLyoqXG4vLyAgKiBTZXQgdGhlIGNvcnJlc3BvbmRpbmcgdmFsdWUgd2l0aCB0aGUgc2V0dGVyLlxuLy8gICpcbi8vICAqIEBwYXJhbSB7Kn0gdmFsdWVcbi8vICAqL1xuXG4vLyBwLnNldCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuLy8gICB2YXIgdm0gPSB0aGlzLnZtXG4vLyAgIGlmICh0aGlzLmZpbHRlcnMpIHtcbi8vICAgICB2YWx1ZSA9IHZtLl9hcHBseUZpbHRlcnMoXG4vLyAgICAgICB2YWx1ZSwgdGhpcy52YWx1ZSwgdGhpcy5maWx0ZXJzLCB0cnVlKVxuLy8gICB9XG4vLyAgIHRyeSB7XG4vLyAgICAgdGhpcy5zZXR0ZXIuY2FsbCh2bSwgdm0sIHZhbHVlKVxuLy8gICB9IGNhdGNoIChlKSB7XG4vLyAgICAgLy8gaWYgKGNvbmZpZy53YXJuRXhwcmVzc2lvbkVycm9ycykge1xuLy8gICAgICAgXy53YXJuKFxuLy8gICAgICAgICAnRXJyb3Igd2hlbiBldmFsdWF0aW5nIHNldHRlciBcIicgK1xuLy8gICAgICAgICB0aGlzLmV4cHJlc3Npb24gKyAnXCI6XFxuICAgJyArIGVcbi8vICAgICAgIClcbi8vICAgICAvLyB9XG4vLyAgIH1cbi8vIH1cblxuLyoqXG4gKiBQcmVwYXJlIGZvciBkZXBlbmRlbmN5IGNvbGxlY3Rpb24uXG4gKi9cblxucC5iZWZvcmVHZXQgPSBmdW5jdGlvbiAoKSB7XG4gIE9ic2VydmVyLnRhcmdldCA9IHRoaXNcbn1cblxuLyoqXG4gKiBDbGVhbiB1cCBmb3IgZGVwZW5kZW5jeSBjb2xsZWN0aW9uLlxuICovXG5cbnAuYWZ0ZXJHZXQgPSBmdW5jdGlvbiAoKSB7XG4gIE9ic2VydmVyLnRhcmdldCA9IG51bGxcbiAgdmFyIGkgPSB0aGlzLmRlcHMubGVuZ3RoXG4gIHdoaWxlIChpLS0pIHtcbiAgICB2YXIgZGVwID0gdGhpcy5kZXBzW2ldXG4gICAgaWYgKGRlcCkge1xuICAgICAgZGVwLnJlbW92ZVN1Yih0aGlzKVxuICAgIH1cbiAgfVxuICB0aGlzLmRlcHMgPSB0aGlzLm5ld0RlcHNcbiAgdGhpcy5uZXdEZXBzID0gW11cbn1cblxuLyoqXG4gKiBTdWJzY3JpYmVyIGludGVyZmFjZS5cbiAqIFdpbGwgYmUgY2FsbGVkIHdoZW4gYSBkZXBlbmRlbmN5IGNoYW5nZXMuXG4gKi9cblxuLy8gcC51cGRhdGUgPSBmdW5jdGlvbiAoKSB7XG4vLyAgIGlmICghY29uZmlnLmFzeW5jIHx8IGNvbmZpZy5kZWJ1Zykge1xuLy8gICAgIHRoaXMucnVuKClcbi8vICAgfSBlbHNlIHtcbi8vICAgICBiYXRjaGVyLnB1c2godGhpcylcbi8vICAgfVxuLy8gfVxuXG4vLyAvKipcbi8vICAqIEJhdGNoZXIgam9iIGludGVyZmFjZS5cbi8vICAqIFdpbGwgYmUgY2FsbGVkIGJ5IHRoZSBiYXRjaGVyLlxuLy8gICovXG5cbi8vIHAucnVuID0gZnVuY3Rpb24gKCkge1xucC51cGRhdGUgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmFjdGl2ZSkge1xuICAgIHZhciB2YWx1ZSA9IHRoaXMuZ2V0KClcbiAgICBpZiAoXG4gICAgICB2YWx1ZSAhPT0gdGhpcy52YWx1ZSB8fFxuICAgICAgQXJyYXkuaXNBcnJheSh2YWx1ZSkgfHxcbiAgICAgIHRoaXMuZGVlcFxuICAgICkge1xuICAgICAgdmFyIG9sZFZhbHVlID0gdGhpcy52YWx1ZVxuICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlXG4gICAgICB0aGlzLmNiKHZhbHVlLCBvbGRWYWx1ZSlcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBSZW1vdmUgc2VsZiBmcm9tIGFsbCBkZXBlbmRlbmNpZXMnIHN1YmNyaWJlciBsaXN0LlxuICovXG5cbnAudGVhcmRvd24gPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmFjdGl2ZSkge1xuICAgIC8vIHJlbW92ZSBzZWxmIGZyb20gdm0ncyB3YXRjaGVyIGxpc3RcbiAgICAvLyB3ZSBjYW4gc2tpcCB0aGlzIGlmIHRoZSB2bSBpZiBiZWluZyBkZXN0cm95ZWRcbiAgICAvLyB3aGljaCBjYW4gaW1wcm92ZSB0ZWFyZG93biBwZXJmb3JtYW5jZS5cbiAgICBpZiAoIXRoaXMudm0uX2lzQmVpbmdEZXN0cm95ZWQpIHtcbiAgICAgIHRoaXMudm0uX3dhdGNoZXJzLiRyZW1vdmUodGhpcylcbiAgICB9XG4gICAgdmFyIGkgPSB0aGlzLmRlcHMubGVuZ3RoXG4gICAgd2hpbGUgKGktLSkge1xuICAgICAgdGhpcy5kZXBzW2ldLnJlbW92ZVN1Yih0aGlzKVxuICAgIH1cbiAgICB0aGlzLmFjdGl2ZSA9IGZhbHNlXG4gICAgdGhpcy52bSA9IHRoaXMuY2IgPSB0aGlzLnZhbHVlID0gbnVsbFxuICB9XG59XG5cblxuLyoqXG4gKiBSZWNydXNpdmVseSB0cmF2ZXJzZSBhbiBvYmplY3QgdG8gZXZva2UgYWxsIGNvbnZlcnRlZFxuICogZ2V0dGVycywgc28gdGhhdCBldmVyeSBuZXN0ZWQgcHJvcGVydHkgaW5zaWRlIHRoZSBvYmplY3RcbiAqIGlzIGNvbGxlY3RlZCBhcyBhIFwiZGVlcFwiIGRlcGVuZGVuY3kuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICovXG5cbmZ1bmN0aW9uIHRyYXZlcnNlIChvYmopIHtcbiAgdmFyIGtleSwgdmFsLCBpXG4gIGZvciAoa2V5IGluIG9iaikge1xuICAgIHZhbCA9IG9ialtrZXldXG4gICAgaWYgKF8uaXNBcnJheSh2YWwpKSB7XG4gICAgICBpID0gdmFsLmxlbmd0aFxuICAgICAgd2hpbGUgKGktLSkge3RyYXZlcnNlKHZhbFtpXSl9XG4gICAgfSBlbHNlIGlmIChfLmlzT2JqZWN0KHZhbCkpIHtcbiAgICAgIHRyYXZlcnNlKHZhbClcbiAgICB9XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBXYXRjaGVyXG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL2xpYi92bS93YXRjaGVyLmpzXG4gKiovIiwiLyoqXG4gKiBAZmlsZU92ZXJ2aWV3IERvY3VtZW50ICYgRWxlbWVudCBIZWxwZXJzLlxuICpcbiAqIHJlcXVpcmVkOlxuICogRG9jdW1lbnQjOiBjcmVhdGVFbGVtZW50LCBjcmVhdGVDb21tZW50LCBnZXRSZWZcbiAqIEVsZW1lbnQjOiBhcHBlbmRDaGlsZCwgaW5zZXJ0QmVmb3JlLCByZW1vdmVDaGlsZCwgbmV4dFNpYmxpbmdcbiAqL1xuXG4vKipcbiAqIENyZWF0ZSBhIGJvZHkgYnkgdHlwZVxuICogVXNpbmcgdGhpcy5fYXBwLmRvY1xuICpcbiAqIEBwYXJhbSAge3N0cmluZ30gdHlwZVxuICovXG5leHBvcnQgZnVuY3Rpb24gX2NyZWF0ZUJvZHkodHlwZSkge1xuICBjb25zdCBkb2MgPSB0aGlzLl9hcHAuZG9jXG4gIHJldHVybiBkb2MuY3JlYXRlQm9keSh0eXBlKVxufVxuXG4vKipcbiAqIENyZWF0ZSBhbiBlbGVtZW50IGJ5IHR5cGVcbiAqIFVzaW5nIHRoaXMuX2FwcC5kb2NcbiAqXG4gKiBAcGFyYW0gIHtzdHJpbmd9IHR5cGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9jcmVhdGVFbGVtZW50KHR5cGUpIHtcbiAgY29uc3QgZG9jID0gdGhpcy5fYXBwLmRvY1xuICByZXR1cm4gZG9jLmNyZWF0ZUVsZW1lbnQodHlwZSlcbn1cblxuLyoqXG4gKiBDcmVhdGUgYW5kIHJldHVybiBhIGZyYWcgYmxvY2sgZm9yIGFuIGVsZW1lbnQuXG4gKiBUaGUgZnJhZyBibG9jayBoYXMgYSBzdGFydGVyLCBlbmRlciBhbmQgdGhlIGVsZW1lbnQgaXRzZWxmLlxuICpcbiAqIEBwYXJhbSAge29iamVjdH0gZWxlbWVudFxuICovXG5leHBvcnQgZnVuY3Rpb24gX2NyZWF0ZUJsb2NrKGVsZW1lbnQpIHtcbiAgY29uc3Qgc3RhcnQgPSB0aGlzLl9jcmVhdGVCbG9ja1N0YXJ0KClcbiAgY29uc3QgZW5kID0gdGhpcy5fY3JlYXRlQmxvY2tFbmQoKVxuICBjb25zdCBibG9ja0lkID0gbGFzdGVzdEJsb2NrSWQrK1xuICBpZiAoZWxlbWVudC5lbGVtZW50KSB7XG4gICAgZWxlbWVudC5lbGVtZW50Lmluc2VydEJlZm9yZShzdGFydCwgZWxlbWVudC5lbmQpXG4gICAgZWxlbWVudC5lbGVtZW50Lmluc2VydEJlZm9yZShlbmQsIGVsZW1lbnQuZW5kKVxuICAgIGVsZW1lbnQgPSBlbGVtZW50LmVsZW1lbnRcbiAgfVxuICBlbHNlIHtcbiAgICBlbGVtZW50LmFwcGVuZENoaWxkKHN0YXJ0KVxuICAgIGVsZW1lbnQuYXBwZW5kQ2hpbGQoZW5kKVxuICB9XG4gIHJldHVybiB7c3RhcnQsIGVuZCwgZWxlbWVudCwgYmxvY2tJZH1cbn1cblxubGV0IGxhc3Rlc3RCbG9ja0lkID0gMVxuXG4vKipcbiAqIENyZWF0ZSBhbmQgcmV0dXJuIGEgYmxvY2sgc3RhcnRlci5cbiAqIFVzaW5nIHRoaXMuX2FwcC5kb2NcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9jcmVhdGVCbG9ja1N0YXJ0KCkge1xuICBjb25zdCBkb2MgPSB0aGlzLl9hcHAuZG9jXG4gIGNvbnN0IGFuY2hvciA9IGRvYy5jcmVhdGVDb21tZW50KCdzdGFydCcpXG4gIHJldHVybiBhbmNob3Jcbn1cblxuLyoqXG4gKiBDcmVhdGUgYW5kIHJldHVybiBhIGJsb2NrIGVuZGVyLlxuICogVXNpbmcgdGhpcy5fYXBwLmRvY1xuICovXG5leHBvcnQgZnVuY3Rpb24gX2NyZWF0ZUJsb2NrRW5kKCkge1xuICBjb25zdCBkb2MgPSB0aGlzLl9hcHAuZG9jXG4gIGNvbnN0IGFuY2hvciA9IGRvYy5jcmVhdGVDb21tZW50KCdlbmQnKVxuICByZXR1cm4gYW5jaG9yXG59XG5cbi8qKlxuICogQXR0YWNoIHRhcmdldCB0byBhIGNlcnRhaW4gZGVzdCB1c2luZyBhcHBlbmRDaGlsZCBieSBkZWZhdWx0LlxuICogSWYgdGhlIGRlc3QgaXMgYSBmcmFnIGJsb2NrIHRoZW4gaW5zZXJ0IGJlZm9yZSB0aGUgZW5kZXIuXG4gKiBJZiB0aGUgdGFyZ2V0IGlzIGEgZnJhZyBibG9jayB0aGVuIGF0dGFjaCB0aGUgc3RhcnRlciBhbmQgZW5kZXIgaW4gb3JkZXIuXG4gKlxuICogQHBhcmFtICB7b2JqZWN0fSB0YXJnZXRcbiAqIEBwYXJhbSAge29iamVjdH0gZGVzdFxuICovXG5leHBvcnQgZnVuY3Rpb24gX2F0dGFjaFRhcmdldCh0YXJnZXQsIGRlc3QpIHtcblxuICBpZiAoZGVzdC5lbGVtZW50KSB7XG4gICAgY29uc3QgYmVmb3JlID0gZGVzdC5lbmRcbiAgICBjb25zdCBhZnRlciA9IGRlc3QudXBkYXRlTWFya1xuICAgIC8vIHB1c2ggbmV3IHRhcmdldCBmb3Igd2F0Y2ggbGlzdCB1cGRhdGUgbGF0ZXJcbiAgICBpZiAoZGVzdC5jaGlsZHJlbikge1xuICAgICAgZGVzdC5jaGlsZHJlbi5wdXNoKHRhcmdldClcbiAgICB9XG4gICAgLy8gZm9yIGNoZWNrIHJlcGVhdCBjYXNlXG4gICAgaWYgKGFmdGVyKSB7XG4gICAgICB0aGlzLl9tb3ZlVGFyZ2V0KHRhcmdldCwgYWZ0ZXIpXG4gICAgICBkZXN0LnVwZGF0ZU1hcmsgPSB0YXJnZXQuZWxlbWVudCA/IHRhcmdldC5lbmQgOiB0YXJnZXRcbiAgICB9XG4gICAgZWxzZSBpZiAodGFyZ2V0LmVsZW1lbnQpIHtcbiAgICAgIGRlc3QuZWxlbWVudC5pbnNlcnRCZWZvcmUodGFyZ2V0LnN0YXJ0LCBiZWZvcmUpXG4gICAgICBkZXN0LmVsZW1lbnQuaW5zZXJ0QmVmb3JlKHRhcmdldC5lbmQsIGJlZm9yZSlcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBkZXN0LmVsZW1lbnQuaW5zZXJ0QmVmb3JlKHRhcmdldCwgYmVmb3JlKVxuICAgIH1cbiAgfVxuICBlbHNlIHtcbiAgICBpZiAodGFyZ2V0LmVsZW1lbnQpIHtcbiAgICAgIGRlc3QuYXBwZW5kQ2hpbGQodGFyZ2V0LnN0YXJ0KVxuICAgICAgZGVzdC5hcHBlbmRDaGlsZCh0YXJnZXQuZW5kKVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGRlc3QuYXBwZW5kQ2hpbGQodGFyZ2V0KVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIE1vdmUgdGFyZ2V0IGJlZm9yZSBhIGNlcnRhaW4gZWxlbWVudC4gVGhlIHRhcmdldCBtYXliZSBibG9jayBvciBlbGVtZW50LlxuICpcbiAqIEBwYXJhbSAge29iamVjdH0gdGFyZ2V0XG4gKiBAcGFyYW0gIHtvYmplY3R9IGJlZm9yZVxuICovXG5leHBvcnQgZnVuY3Rpb24gX21vdmVUYXJnZXQodGFyZ2V0LCBhZnRlcikge1xuICBpZiAodGFyZ2V0LmVsZW1lbnQpIHtcbiAgICB0aGlzLl9tb3ZlQmxvY2sodGFyZ2V0LCBhZnRlcilcbiAgfVxuICBlbHNlIHtcbiAgICB0aGlzLl9tb3ZlRWxlbWVudCh0YXJnZXQsIGFmdGVyKVxuICB9XG59XG5cbi8qKlxuICogTW92ZSBlbGVtZW50IGJlZm9yZSBhIGNlcnRhaW4gZWxlbWVudC5cbiAqXG4gKiBAcGFyYW0gIHtvYmplY3R9IGVsZW1lbnRcbiAqIEBwYXJhbSAge29iamVjdH0gYmVmb3JlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfbW92ZUVsZW1lbnQoZWxlbWVudCwgYWZ0ZXIpIHtcbiAgY29uc3QgZG9jID0gdGhpcy5fYXBwLmRvY1xuICBjb25zdCBwYXJlbnQgPSBkb2MuZ2V0UmVmKGFmdGVyLnBhcmVudFJlZilcblxuICBpZiAocGFyZW50KSB7XG4gICAgcGFyZW50Lmluc2VydEFmdGVyKGVsZW1lbnQsIGFmdGVyKVxuICB9XG59XG5cbi8qKlxuICogTW92ZSBhbGwgZWxlbWVudHMgb2YgdGhlIGJsb2NrIGJlZm9yZSBhIGNlcnRhaW4gZWxlbWVudC5cbiAqXG4gKiBAcGFyYW0gIHtvYmplY3R9IGZyYWdCbG9ja1xuICogQHBhcmFtICB7b2JqZWN0fSBiZWZvcmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9tb3ZlQmxvY2soZnJhZ0Jsb2NrLCBhZnRlcikge1xuICBjb25zdCBkb2MgPSB0aGlzLl9hcHAuZG9jXG4gIGNvbnN0IHBhcmVudCA9IGRvYy5nZXRSZWYoYWZ0ZXIucGFyZW50UmVmKVxuXG4gIGlmIChwYXJlbnQpIHtcbiAgICBsZXQgZWwgPSBmcmFnQmxvY2suc3RhcnRcbiAgICBjb25zdCBncm91cCA9IFtlbF1cblxuICAgIHdoaWxlIChlbCAmJiBlbCAhPT0gZnJhZ0Jsb2NrLmVuZCkge1xuICAgICAgZWwgPSBlbC5uZXh0KClcbiAgICAgIGdyb3VwLnB1c2goZWwpXG4gICAgfVxuXG4gICAgbGV0IHRlbXAgPSBhZnRlclxuICAgIGdyb3VwLmZvckVhY2goKGVsKSA9PiB7XG4gICAgICBwYXJlbnQuaW5zZXJ0QWZ0ZXIoZWwsIHRlbXApXG4gICAgICB0ZW1wID0gZWxcbiAgICB9KVxuICB9XG59XG5cbi8qKlxuICogUmVtb3ZlIHRhcmdldCBmcm9tIERPTSB0cmVlLlxuICogSWYgdGhlIHRhcmdldCBpcyBhIGZyYWcgYmxvY2sgdGhlbiBjYWxsIF9yZW1vdmVCbG9ja1xuICpcbiAqIEBwYXJhbSAge29iamVjdH0gdGFyZ2V0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfcmVtb3ZlVGFyZ2V0KHRhcmdldCkge1xuXG4gIGlmICh0YXJnZXQuZWxlbWVudCkge1xuICAgIHRoaXMuX3JlbW92ZUJsb2NrKHRhcmdldClcbiAgfVxuICBlbHNlIHtcbiAgICB0aGlzLl9yZW1vdmVFbGVtZW50KHRhcmdldClcbiAgfVxufVxuXG4vKipcbiAqIFJlbW92ZSBhIGNlcnRhaW4gZWxlbWVudC5cbiAqIFVzaW5nIHRoaXMuX2FwcC5kb2NcbiAqXG4gKiBAcGFyYW0gIHtvYmplY3R9IHRhcmdldFxuICovXG5leHBvcnQgZnVuY3Rpb24gX3JlbW92ZUVsZW1lbnQodGFyZ2V0KSB7XG4gIGNvbnN0IGRvYyA9IHRoaXMuX2FwcC5kb2NcbiAgY29uc3QgcGFyZW50ID0gZG9jLmdldFJlZih0YXJnZXQucGFyZW50UmVmKVxuXG4gIGlmIChwYXJlbnQpIHtcbiAgICBwYXJlbnQucmVtb3ZlQ2hpbGQodGFyZ2V0KVxuICB9XG59XG5cbi8qKlxuICogUmVtb3ZlIGEgZnJhZyBibG9jay5cbiAqIFRoZSBzZWNvbmQgcGFyYW0gZGVjaWRlcyB3aGV0aGVyIHRoZSBibG9jayBzZWxmIHNob3VsZCBiZSByZW1vdmVkIHRvby5cbiAqXG4gKiBAcGFyYW0gIHtvYmplY3R9ICBmcmFnQmxvY2tcbiAqIEBwYXJhbSAge0Jvb2xlYW59IHByZXNlcnZlQmxvY2s9ZmFsc2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9yZW1vdmVCbG9jayhmcmFnQmxvY2ssIHByZXNlcnZlQmxvY2sgPSBmYWxzZSkge1xuICBjb25zdCByZXN1bHQgPSBbXVxuICBsZXQgZWwgPSBmcmFnQmxvY2suc3RhcnQubmV4dCgpXG5cbiAgd2hpbGUgKGVsICYmIGVsICE9PSBmcmFnQmxvY2suZW5kKSB7XG4gICAgcmVzdWx0LnB1c2goZWwpXG4gICAgZWwgPSBlbC5uZXh0KClcbiAgfVxuXG4gIGlmICghcHJlc2VydmVCbG9jaykge1xuICAgIHRoaXMuX3JlbW92ZUVsZW1lbnQoZnJhZ0Jsb2NrLnN0YXJ0KVxuICB9XG4gIHJlc3VsdC5mb3JFYWNoKChlbCkgPT4ge1xuICAgIHRoaXMuX3JlbW92ZUVsZW1lbnQoZWwpXG4gIH0pXG4gIGlmICghcHJlc2VydmVCbG9jaykge1xuICAgIHRoaXMuX3JlbW92ZUVsZW1lbnQoZnJhZ0Jsb2NrLmVuZClcbiAgfVxufVxuXG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL2xpYi92bS9kb20taGVscGVyLmpzXG4gKiovIiwiZnVuY3Rpb24gRXZ0KHR5cGUsIGRldGFpbCkge1xuICBpZiAoZGV0YWlsIGluc3RhbmNlb2YgRXZ0KSB7XG4gICAgcmV0dXJuIGRldGFpbFxuICB9XG5cbiAgdGhpcy50aW1lc3RhbXAgPSBEYXRlLm5vdygpXG4gIHRoaXMuZGV0YWlsID0gZGV0YWlsXG4gIHRoaXMudHlwZSA9IHR5cGVcblxuICBsZXQgc2hvdWxkU3RvcCA9IGZhbHNlXG4gIHRoaXMuc3RvcCA9IGZ1bmN0aW9uICgpIHtcbiAgICBzaG91bGRTdG9wID0gdHJ1ZVxuICB9XG4gIHRoaXMuaGFzU3RvcHBlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gc2hvdWxkU3RvcFxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiAkZW1pdCh0eXBlLCBkZXRhaWwpIHtcbiAgY29uc3QgZXZlbnRzID0gdGhpcy5fdm1FdmVudHNcbiAgY29uc3QgaGFuZGxlckxpc3QgPSBldmVudHNbdHlwZV1cbiAgaWYgKGhhbmRsZXJMaXN0KSB7XG4gICAgbGV0IGV2dCA9IG5ldyBFdnQodHlwZSwgZGV0YWlsKVxuICAgIGhhbmRsZXJMaXN0LmZvckVhY2goKGhhbmRsZXIpID0+IHtcbiAgICAgIGhhbmRsZXIuY2FsbCh0aGlzLCBldnQpXG4gICAgfSlcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gJGRpc3BhdGNoKHR5cGUsIGRldGFpbCkge1xuICBjb25zdCBldnQgPSBuZXcgRXZ0KHR5cGUsIGRldGFpbClcbiAgdGhpcy4kZW1pdCh0eXBlLCBldnQpXG5cbiAgaWYgKCFldnQuaGFzU3RvcHBlZCgpICYmIHRoaXMuX3BhcmVudCAmJiB0aGlzLl9wYXJlbnQuJGRpc3BhdGNoKSB7XG4gICAgdGhpcy5fcGFyZW50LiRkaXNwYXRjaCh0eXBlLCBldnQpXG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uICRicm9hZGNhc3QodHlwZSwgZGV0YWlsKSB7XG4gIGNvbnN0IGV2dCA9IG5ldyBFdnQodHlwZSwgZGV0YWlsKVxuICB0aGlzLiRlbWl0KHR5cGUsIGV2dClcblxuICBpZiAoIWV2dC5oYXNTdG9wcGVkKCkgJiYgdGhpcy5fY2hpbGRyZW5WbXMpIHtcbiAgICB0aGlzLl9jaGlsZHJlblZtcy5mb3JFYWNoKChzdWJWbSkgPT4ge1xuICAgICAgc3ViVm0uJGJyb2FkY2FzdCh0eXBlLCBldnQpXG4gICAgfSlcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gJG9uKHR5cGUsIGhhbmRsZXIpIHtcbiAgaWYgKCF0eXBlIHx8IHR5cGVvZiBoYW5kbGVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgY29uc3QgZXZlbnRzID0gdGhpcy5fdm1FdmVudHNcbiAgY29uc3QgaGFuZGxlckxpc3QgPSBldmVudHNbdHlwZV0gfHwgW11cbiAgaGFuZGxlckxpc3QucHVzaChoYW5kbGVyKVxuICBldmVudHNbdHlwZV0gPSBoYW5kbGVyTGlzdFxuXG4gIC8vIGZpeGVkIG9sZCB2ZXJzaW9uIGxpZmVjeWNsZSBkZXNpZ25cbiAgaWYgKHR5cGUgPT09ICdob29rOnJlYWR5JyAmJiB0aGlzLl9yZWFkeSkge1xuICAgIHRoaXMuJGVtaXQoJ2hvb2s6cmVhZHknKVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiAkb2ZmKHR5cGUsIGhhbmRsZXIpIHtcbiAgaWYgKCF0eXBlKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgY29uc3QgZXZlbnRzID0gdGhpcy5fdm1FdmVudHNcbiAgaWYgKCFoYW5kbGVyKSB7XG4gICAgZGVsZXRlIGV2ZW50c1t0eXBlXVxuICAgIHJldHVyblxuICB9XG4gIGNvbnN0IGhhbmRsZXJMaXN0ID0gZXZlbnRzW3R5cGVdXG4gIGlmICghaGFuZGxlckxpc3QpIHtcbiAgICByZXR1cm5cbiAgfVxuICBoYW5kbGVyTGlzdC4kcmVtb3ZlKGhhbmRsZXIpXG59XG5cbmNvbnN0IExJRkVfQ1lDTEVfVFlQRVMgPSBbJ2luaXQnLCAnY3JlYXRlZCcsICdyZWFkeSddXG5cbmV4cG9ydCBmdW5jdGlvbiBfaW5pdEV2ZW50cyhleHRlcm5hbEV2ZW50cykge1xuICBjb25zdCBvcHRpb25zID0gdGhpcy5fb3B0aW9ucyB8fCB7fVxuICBjb25zdCBldmVudHMgPSBvcHRpb25zLmV2ZW50cyB8fCB7fVxuICBmb3IgKGNvbnN0IHR5cGUxIGluIGV2ZW50cykge1xuICAgIHRoaXMuJG9uKHR5cGUxLCBldmVudHNbdHlwZTFdKVxuICB9XG4gIGZvciAoY29uc3QgdHlwZTIgaW4gZXh0ZXJuYWxFdmVudHMpIHtcbiAgICB0aGlzLiRvbih0eXBlMiwgZXh0ZXJuYWxFdmVudHNbdHlwZTJdKVxuICB9XG4gIExJRkVfQ1lDTEVfVFlQRVMuZm9yRWFjaCgodHlwZSkgPT4ge1xuICAgIHRoaXMuJG9uKGBob29rOiR7dHlwZX1gLCBvcHRpb25zW3R5cGVdKVxuICB9KVxufVxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9saWIvdm0vZXZlbnRzLmpzXG4gKiovIiwibGV0IG5hdGl2ZU1vZHVsZXMgPSB7fVxuXG5mdW5jdGlvbiBhc3NpZ25Nb2R1bGVzKG1vZHVsZXMsIGlmUmVwbGFjZSkge1xuXG4gIGZvciAoY29uc3QgbW9kdWxlTmFtZSBpbiBtb2R1bGVzKSB7XG5cbiAgICAvLyBpbml0IGBtb2R1bGVzW21vZHVsZU5hbWVdW11gXG4gICAgbGV0IG1ldGhvZHMgPSBuYXRpdmVNb2R1bGVzW21vZHVsZU5hbWVdXG4gICAgaWYgKCFtZXRob2RzKSB7XG4gICAgICBtZXRob2RzID0ge31cbiAgICAgIG5hdGl2ZU1vZHVsZXNbbW9kdWxlTmFtZV0gPSBtZXRob2RzXG4gICAgfVxuXG4gICAgLy8gcHVzaCBlYWNoIG5vbi1leGlzdGVkIG5ldyBtZXRob2RcbiAgICBtb2R1bGVzW21vZHVsZU5hbWVdLmZvckVhY2goZnVuY3Rpb24gKG1ldGhvZCkge1xuICAgICAgaWYgKHR5cGVvZiBtZXRob2QgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIG1ldGhvZCA9IHtcbiAgICAgICAgICBuYW1lOiBtZXRob2RcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoIW1ldGhvZHNbbWV0aG9kLm5hbWVdIHx8IGlmUmVwbGFjZSkge1xuICAgICAgICBtZXRob2RzW21ldGhvZC5uYW1lXSA9IG1ldGhvZFxuICAgICAgfVxuICAgIH0pXG4gIH1cbn1cblxuZnVuY3Rpb24gYXNzaWduQXBpcyhDdG9yLCBhcGlzKSB7XG4gIGNvbnN0IHAgPSBDdG9yLnByb3RvdHlwZVxuXG4gIGZvciAoY29uc3QgYXBpTmFtZSBpbiBhcGlzKSB7XG4gICAgaWYgKCFwLmhhc093blByb3BlcnR5KGFwaU5hbWUpKSB7XG4gICAgICBwW2FwaU5hbWVdID0gYXBpc1thcGlOYW1lXVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gY2xlYXJNb2R1bGVzKCkge1xuICBuYXRpdmVNb2R1bGVzID0ge31cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldE1vZHVsZShtb2R1bGVOYW1lKSB7XG4gIHJldHVybiBuYXRpdmVNb2R1bGVzW21vZHVsZU5hbWVdXG59XG5cbi8qKlxuICogQGNvbnRleHQgYSBpbnN0YW5jZSBvZiBBcHBJbnN0YW5jZVxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVxdWlyZU1vZHVsZShtb2R1bGVOYW1lKSB7XG4gIGNvbnN0IG1ldGhvZHMgPSBuYXRpdmVNb2R1bGVzW21vZHVsZU5hbWVdXG4gIGNvbnN0IHRhcmdldCA9IHt9XG5cbiAgZm9yIChjb25zdCBtZXRob2ROYW1lIGluIG1ldGhvZHMpIHtcbiAgICB0YXJnZXRbbWV0aG9kTmFtZV0gPSAoLi4uYXJncykgPT4gdGhpcy5jYWxsVGFza3Moe1xuICAgICAgbW9kdWxlOiBtb2R1bGVOYW1lLFxuICAgICAgbWV0aG9kOiBtZXRob2ROYW1lLFxuICAgICAgYXJnczogYXJnc1xuICAgIH0pXG4gIH1cblxuICByZXR1cm4gdGFyZ2V0XG59XG5cbi8qKlxuICogQGNvbnRleHQgVm1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyTW9kdWxlcyhtb2R1bGVzLCBpZlJlcGxhY2UpIHtcbiAgYXNzaWduTW9kdWxlcyhtb2R1bGVzLCBpZlJlcGxhY2UpXG59XG5cbi8qKlxuICogQGNvbnRleHQgVm1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyTWV0aG9kcyhhcGlzKSB7XG4gIGFzc2lnbkFwaXModGhpcywgYXBpcylcbn1cblxuLyoqXG4gKiBAY29udGV4dCBhIGluc3RhbmNlIG9mIEFwcEluc3RhbmNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXF1aXJlQ29tcG9uZW50KG5hbWUpIHtcbiAgY29uc3Qge2N1c3RvbUNvbXBvbmVudE1hcH0gPSB0aGlzXG4gIHJldHVybiBjdXN0b21Db21wb25lbnRNYXBbbmFtZV1cbn1cblxuLyoqXG4gKiBAY29udGV4dCBhIGluc3RhbmNlIG9mIEFwcEluc3RhbmNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWdpc3RlckNvbXBvbmVudChuYW1lLCBleHBvcnRzKSB7XG4gIGNvbnN0IHtjdXN0b21Db21wb25lbnRNYXB9ID0gdGhpc1xuXG4gIGlmIChjdXN0b21Db21wb25lbnRNYXBbbmFtZV0pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGRlZmluZSBhIGNvbXBvbmVudCgke25hbWV9KSB0aGF0IGFscmVhZHkgZXhpc3RzYClcbiAgfVxuXG4gIGN1c3RvbUNvbXBvbmVudE1hcFtuYW1lXSA9IGV4cG9ydHNcbn1cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL2xpYi9hcHAvcmVnaXN0ZXIuanNcbiAqKi8iLCJpbXBvcnQgc2VtdmVyIGZyb20gJ3NlbXZlcidcbmltcG9ydCB7ZXh0ZW5kLCBpc1BsYWluT2JqZWN0LCB0eXBvZn0gIGZyb20gJy4uL3V0aWwnXG5cbi8qKlxuICogW25vcm1hbGl6ZVZlcnNpb24gZGVzY3JpcHRpb25dXG4gKiBAcGFyYW0gIHtTdHJpbmd9IFZlcnNpb24uIGllOiAxLCAxLjAsIDEuMC4wXG4gKiBAcmV0dXJuIHtTdHJpbmd9IFZlcnNpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZVZlcnNpb24gKHYpIHtcbiAgY29uc3QgaXNWYWxpZCA9IHNlbXZlci52YWxpZCh2KSA/IHRydWUgOiBmYWxzZVxuICBpZiAoaXNWYWxpZCkge1xuICAgIHJldHVybiB2XG4gIH1cblxuICB2ID0gdHlwZW9mICh2KSA9PT0gJ3N0cmluZycgPyB2IDogJydcbiAgY29uc3Qgc3BsaXQgPSB2LnNwbGl0KCcuJylcbiAgbGV0IGkgPSAwXG4gIGxldCByZXN1bHQgPSBbXVxuXG4gIHdoaWxlIChpIDwgMykge1xuICAgIGNvbnN0IHMgPSB0eXBlb2YgKHNwbGl0W2ldKSA9PT0gJ3N0cmluZycgJiYgc3BsaXRbaV0gPyBzcGxpdFtpXSA6ICcwJ1xuICAgIHJlc3VsdC5wdXNoKHMpXG4gICAgaSsrXG4gIH1cblxuICByZXR1cm4gcmVzdWx0LmpvaW4oJy4nKVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RXJyb3IgKGtleSwgdmFsLCBjcml0ZXJpYSkge1xuICBsZXQgcmVzdWx0ID0ge1xuICAgIGlzRG93bmdyYWRlOiB0cnVlLFxuICAgIGVycm9yVHlwZTogMSxcbiAgICBjb2RlOiAxMDAwXG4gIH1cbiAgbGV0IGdldE1zZyA9IGZ1bmN0aW9uIChrZXksIHZhbCwgY3JpdGVyaWEpIHtcbiAgICByZXR1cm4gJ0Rvd25ncmFkZVsnICsga2V5ICsgJ10gOjogZGV2aWNlSW5mbyAnXG4gICAgICArIHZhbCArICcgbWF0Y2hlZCBjcml0ZXJpYSAnICsgY3JpdGVyaWFcbiAgfVxuICBjb25zdCBfa2V5ID0ga2V5LnRvTG93ZXJDYXNlKClcblxuICByZXN1bHQuZXJyb3JNZXNzYWdlID0gZ2V0TXNnKGtleSwgdmFsLCBjcml0ZXJpYSlcblxuICBpZiAoX2tleS5pbmRleE9mKCdvc3ZlcnNpb24nKSA+PSAwKSB7XG4gICAgcmVzdWx0LmNvZGUgPSAxMDAxXG4gIH1lbHNlIGlmIChfa2V5LmluZGV4T2YoJ2FwcHZlcnNpb24nKSA+PSAwKSB7XG4gICAgcmVzdWx0LmNvZGUgPSAxMDAyXG4gIH1lbHNlIGlmIChfa2V5LmluZGV4T2YoJ3dlZXh2ZXJzaW9uJykgPj0gMCkge1xuICAgIHJlc3VsdC5jb2RlID0gMTAwM1xuICB9ZWxzZSBpZiAoX2tleS5pbmRleE9mKCdkZXZpY2Vtb2RlbCcpID49IDApIHtcbiAgICByZXN1bHQuY29kZSA9IDEwMDRcbiAgfVxuXG4gIHJldHVybiByZXN1bHRcbn1cblxuLyoqXG4gKiBXRUVYIGZyYW1ld29yayBpbnB1dChkZXZpY2VJbmZvKVxuICoge1xuICogICBwbGF0Zm9ybTogJ2lPUycgb3IgJ2FuZHJvaWQnXG4gKiAgIG9zVmVyc2lvbjogJzEuMC4wJyBvciAnMS4wJyBvciAnMSdcbiAqICAgYXBwVmVyc2lvbjogJzEuMC4wJyBvciAnMS4wJyBvciAnMSdcbiAqICAgd2VleFZlcnNpb246ICcxLjAuMCcgb3IgJzEuMCcgb3IgJzEnXG4gKiAgIGREZXZpY2VNb2RlbDogJ01PREVMX05BTUUnXG4gKiB9XG4gKlxuICogZG93bmdyYWRlIGNvbmZpZyhjb25maWcpXG4gKiB7XG4gKiAgIGlvczoge1xuICogICAgIG9zVmVyc2lvbjogJz4xLjAuMCcgb3IgJz49MS4wLjAnIG9yICc8MS4wLjAnIG9yICc8PTEuMC4wJyBvciAnMS4wLjAnXG4gKiAgICAgYXBwVmVyc2lvbjogJz4xLjAuMCcgb3IgJz49MS4wLjAnIG9yICc8MS4wLjAnIG9yICc8PTEuMC4wJyBvciAnMS4wLjAnXG4gKiAgICAgd2VleFZlcnNpb246ICc+MS4wLjAnIG9yICc+PTEuMC4wJyBvciAnPDEuMC4wJyBvciAnPD0xLjAuMCcgb3IgJzEuMC4wJ1xuICogICAgIGRldmljZU1vZGVsOiBbJ21vZGVsQScsICdtb2RlbEInLCAuLi5dXG4gKiAgIH0sXG4gKiAgIGFuZHJvaWQ6IHtcbiAqICAgICBvc1ZlcnNpb246ICc+MS4wLjAnIG9yICc+PTEuMC4wJyBvciAnPDEuMC4wJyBvciAnPD0xLjAuMCcgb3IgJzEuMC4wJ1xuICogICAgIGFwcFZlcnNpb246ICc+MS4wLjAnIG9yICc+PTEuMC4wJyBvciAnPDEuMC4wJyBvciAnPD0xLjAuMCcgb3IgJzEuMC4wJ1xuICogICAgIHdlZXhWZXJzaW9uOiAnPjEuMC4wJyBvciAnPj0xLjAuMCcgb3IgJzwxLjAuMCcgb3IgJzw9MS4wLjAnIG9yICcxLjAuMCdcbiAqICAgICBkZXZpY2VNb2RlbDogWydtb2RlbEEnLCAnbW9kZWxCJywgLi4uXVxuICogICB9XG4gKiB9XG4gKlxuICpcbiAqIEBwYXJhbSAge29iamVjdH0gZGV2aWNlSW5mbyBXZWV4IFNESyBmcmFtZXdvcmsgaW5wdXRcbiAqIEBwYXJhbSAge29iamVjdH0gY29uZmlnICAgICB1c2VyIGlucHV0XG4gKiBAcmV0dXJuIHtPYmplY3R9ICAgICAgICAgICAgeyBpc0Rvd25ncmFkZTogdHJ1ZS9mYWxzZSwgZXJyb3JNZXNzYWdlLi4uIH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNoZWNrIChjb25maWcsIGRldmljZUluZm8pIHtcbiAgZGV2aWNlSW5mbyA9IGRldmljZUluZm8gfHwgZ2xvYmFsLldYRW52aXJvbm1lbnRcbiAgZGV2aWNlSW5mbyA9IGlzUGxhaW5PYmplY3QoZGV2aWNlSW5mbykgPyBkZXZpY2VJbmZvIDoge31cbiAgY29uZmlnID0gaXNQbGFpbk9iamVjdChjb25maWcpID8gY29uZmlnIDoge31cbiAgY29uc3QgcGxhdGZvcm0gPSBkZXZpY2VJbmZvLnBsYXRmb3JtIHx8ICd1bmtub3cnXG4gIGNvbnN0IGRQbGF0Zm9ybSA9IHBsYXRmb3JtLnRvTG93ZXJDYXNlKClcbiAgY29uc3QgY09iaiA9IGNvbmZpZ1tkUGxhdGZvcm1dIHx8IHt9XG5cbiAgbGV0IHJlc3VsdCA9IHtcbiAgICBpc0Rvd25ncmFkZTogZmFsc2UgLy8gZGVmYXV0bCBpcyBwYXNzXG4gIH1cblxuICBmb3IgKGxldCBpIGluIGRldmljZUluZm8pIHtcbiAgICBjb25zdCBrZXkgPSBpXG4gICAgY29uc3Qga2V5TG93ZXIgPSBrZXkudG9Mb3dlckNhc2UoKVxuICAgIGNvbnN0IHZhbCA9IGRldmljZUluZm9baV1cbiAgICBjb25zdCBpc1ZlcnNpb24gPSBrZXlMb3dlci5pbmRleE9mKCd2ZXJzaW9uJykgPj0gMCA/IHRydWUgOiBmYWxzZVxuICAgIGNvbnN0IGlzRGV2aWNlTW9kZWwgPSBrZXlMb3dlci5pbmRleE9mKCdkZXZpY2Vtb2RlbCcpID49IDAgPyB0cnVlIDogZmFsc2VcbiAgICBjb25zdCBjcml0ZXJpYSA9IGNPYmpbaV1cblxuICAgIGlmIChjcml0ZXJpYSAmJiBpc1ZlcnNpb24pIHtcbiAgICAgIGNvbnN0IGMgPSB0aGlzLm5vcm1hbGl6ZVZlcnNpb24oY3JpdGVyaWEpXG4gICAgICBjb25zdCBkID0gdGhpcy5ub3JtYWxpemVWZXJzaW9uKGRldmljZUluZm9baV0pXG5cbiAgICAgIGlmIChzZW12ZXIuc2F0aXNmaWVzKGQsIGMpKSB7XG4gICAgICAgIHJlc3VsdCA9IGV4dGVuZCh0aGlzLmdldEVycm9yKGtleSwgdmFsLCBjcml0ZXJpYSkpXG4gICAgICAgIGJyZWFrXG4gICAgICB9XG4gICAgfWVsc2UgaWYgKGlzRGV2aWNlTW9kZWwpIHtcbiAgICAgIGNvbnN0IF9jcml0ZXJpYSA9IHR5cG9mKGNyaXRlcmlhKSA9PT0gJ2FycmF5JyA/IGNyaXRlcmlhIDogW2NyaXRlcmlhXVxuICAgICAgaWYgKF9jcml0ZXJpYS5pbmRleE9mKHZhbCkgPj0gMCkge1xuICAgICAgICByZXN1bHQgPSBleHRlbmQodGhpcy5nZXRFcnJvcihrZXksIHZhbCwgY3JpdGVyaWEpKVxuICAgICAgICBicmVha1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXN1bHRcbn1cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL2xpYi9hcHAvZG93bmdyYWRlLmpzXG4gKiovIiwiLyoqXG4gKiBAZmlsZU92ZXJ2aWV3XG4gKiBpbnN0YW5jZSBjb250cm9scyBmcm9tIG5hdGl2ZVxuICpcbiAqIC0gaW5pdCBidW5kbGVcbiAqIC0gZmlyZSBldmVudFxuICogLSBjYWxsYmFja1xuICogLSBkZXN0cm95XG4gKlxuICogY29ycmVzcG9uZGVkIHdpdGggdGhlIEFQSSBvZiBpbnN0YW5jZSBtYW5hZ2VyIChmcmFtZXdvcmsuanMpXG4gKi9cblxuaW1wb3J0IHtcbiAgYmluZCwgZXh0ZW5kXG59XG5mcm9tICcuLi91dGlsJ1xuaW1wb3J0ICogYXMgcGVyZiBmcm9tICcuLi9wZXJmJ1xuaW1wb3J0IExpc3RlbmVyLCB7Y3JlYXRlQWN0aW9ufSBmcm9tICcuL2RvbS1saXN0ZW5lcidcblxuZXhwb3J0IGZ1bmN0aW9uIGluaXQoY29kZSwgZGF0YSkge1xuICB2YXIgcmVzdWx0XG4gIC8vIEBzZWU6IGxpYi9hcHAvYnVuZGxlLmpzXG4gIGNvbnN0IGRlZmluZSA9IGJpbmQodGhpcy5kZWZpbmUsIHRoaXMpXG4gIGNvbnN0IGJvb3RzdHJhcCA9IChuYW1lLCBjb25maWcsIF9kYXRhKSA9PiB7XG4gICAgcmVzdWx0ID0gdGhpcy5ib290c3RyYXAobmFtZSwgY29uZmlnLCBfZGF0YSB8fCBkYXRhKVxuICAgIHRoaXMuZG9jLmxpc3RlbmVyLmNyZWF0ZUZpbmlzaCgpXG4gICAgdGhpcy5kb2MuY2xvc2UoKVxuICB9XG5cbiAgLy8gYmFja3dhcmQocmVnaXN0ZXIvcmVuZGVyKVxuICBjb25zdCByZWdpc3RlciA9IGJpbmQodGhpcy5yZWdpc3RlciwgdGhpcylcbiAgY29uc3QgcmVuZGVyID0gKG5hbWUsIF9kYXRhKSA9PiB7XG4gICAgcmVzdWx0ID0gdGhpcy5ib290c3RyYXAobmFtZSwge30sIF9kYXRhKVxuICB9XG5cbiAgY29uc3QgcmVxdWlyZSA9IG5hbWUgPT4gX2RhdGEgPT4ge1xuICAgIHJlc3VsdCA9IHRoaXMuYm9vdHN0cmFwKG5hbWUsIHt9LCBfZGF0YSlcbiAgfVxuXG4gIGNvbnN0IGRvY3VtZW50ID0gdGhpcy5kb2NcblxuICBwZXJmLnN0YXJ0KCdydW4gYnVuZGxlJywgdGhpcy5pZClcblxuICBsZXQgZnVuY3Rpb25Cb2R5XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICBpZiAodHlwZW9mIGNvZGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAvLyBgZnVuY3Rpb24gKCkgey4uLn1gIC0+IGB7Li4ufWBcbiAgICAvLyBub3QgdmVyeSBzdHJpY3RcbiAgICBmdW5jdGlvbkJvZHkgPSBjb2RlLnRvU3RyaW5nKCkuc3Vic3RyKDEyKVxuICB9IGVsc2UgaWYgKGNvZGUpIHtcbiAgICBmdW5jdGlvbkJvZHkgPSBjb2RlLnRvU3RyaW5nKClcbiAgfVxuXG4gIGxldCBmbiA9IG5ldyBGdW5jdGlvbihcbiAgICAnZGVmaW5lJyxcbiAgICAncmVxdWlyZScsXG4gICAgJ2RvY3VtZW50JyxcbiAgICAnYm9vdHN0cmFwJyxcbiAgICAncmVnaXN0ZXInLFxuICAgICdyZW5kZXInLFxuICAgICdfX3dlZXhfZGVmaW5lX18nLCAvLyBhbGlhcyBmb3IgZGVmaW5lXG4gICAgJ19fd2VleF9ib290c3RyYXBfXycsIC8vIGFsaWFzIGZvciBib290c3RyYXBcbiAgICBmdW5jdGlvbkJvZHlcbiAgKVxuXG4gIGZuKFxuICAgIGRlZmluZSxcbiAgICByZXF1aXJlLFxuICAgIGRvY3VtZW50LFxuICAgIGJvb3RzdHJhcCxcbiAgICByZWdpc3RlcixcbiAgICByZW5kZXIsXG4gICAgZGVmaW5lLFxuICAgIGJvb3RzdHJhcClcblxuICBwZXJmLmVuZCgncnVuIGJ1bmRsZScsIHRoaXMuaWQpXG4gIHJldHVybiByZXN1bHRcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRlc3Ryb3koKSB7XG4gIHRoaXMuaWQgPSAnJ1xuICB0aGlzLmV2ZW50TWFuYWdlciA9IG51bGxcbiAgdGhpcy5vcHRpb25zID0gbnVsbFxuICB0aGlzLmJsb2NrcyA9IG51bGxcbiAgdGhpcy52bSA9IG51bGxcbiAgdGhpcy5kb2MgPSBudWxsXG4gIHRoaXMuY3VzdG9tQ29tcG9uZW50TWFwID0gbnVsbFxuICB0aGlzLmNhbGxiYWNrcyA9IG51bGxcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFJvb3RFbGVtZW50KCkge1xuICBjb25zdCBkb2MgPSB0aGlzLmRvYyB8fCB7fVxuICBjb25zdCBib2R5ID0gZG9jLmJvZHkgfHwge31cbiAgcmV0dXJuIGJvZHkudG9KU09OID8gYm9keS50b0pTT04oKSA6IHt9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVBY3Rpb25zKGFkZG9uVGFza3MpIHtcbiAgdGhpcy5kaWZmZXIuZmx1c2goKVxuICBjb25zdCB0YXNrcyA9IFtdXG4gIGlmICh0aGlzLmxpc3RlbmVyICYmIHRoaXMubGlzdGVuZXIudXBkYXRlcy5sZW5ndGgpIHtcbiAgICB0YXNrcy5wdXNoKC4uLnRoaXMubGlzdGVuZXIudXBkYXRlcylcbiAgICB0aGlzLmxpc3RlbmVyLnVwZGF0ZXMgPSBbXVxuICB9XG4gIGlmIChhZGRvblRhc2tzICYmIGFkZG9uVGFza3MubGVuZ3RoKSB7XG4gICAgdGFza3MucHVzaCguLi5hZGRvblRhc2tzKVxuICB9XG4gIGlmICh0YXNrcy5sZW5ndGgpIHtcbiAgICB0aGlzLmNhbGxUYXNrcyh0YXNrcylcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZmlyZUV2ZW50KHJlZiwgdHlwZSwgZSwgZG9tQ2hhbmdlcykge1xuICBpZiAoQXJyYXkuaXNBcnJheShyZWYpKSB7XG4gICAgcmVmLnNvbWUoKHJlZikgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuZmlyZUV2ZW50KHJlZiwgdHlwZSwgZSkgIT09IGZhbHNlXG4gICAgfSlcbiAgICByZXR1cm5cbiAgfVxuXG4gIGNvbnN0IGVsID0gdGhpcy5kb2MuZ2V0UmVmKHJlZilcblxuICBpZiAoZWwpIHtcbiAgICBwZXJmLnN0YXJ0KCdtYW5hZ2UgZXZlbnQnLCByZWYgKyAnLScgKyB0eXBlKVxuICAgIGUgPSBlIHx8IHt9XG4gICAgZS50eXBlID0gdHlwZVxuICAgIGUudGFyZ2V0ID0gZWxcbiAgICBlLnRpbWVzdGFtcCA9IERhdGUubm93KClcbiAgICBpZiAoZG9tQ2hhbmdlcykge1xuICAgICAgdXBkYXRlRWxlbWVudChlbCwgZG9tQ2hhbmdlcylcbiAgICB9XG4gICAgY29uc3QgcmVzdWx0ID0gdGhpcy5ldmVudE1hbmFnZXIuZmlyZShlbCwgdHlwZSwgZSlcbiAgICBwZXJmLmVuZCgnbWFuYWdlIGV2ZW50JywgcmVmICsgJy0nICsgdHlwZSlcbiAgICB0aGlzLnVwZGF0ZUFjdGlvbnMoKVxuICAgIHJldHVybiByZXN1bHRcbiAgfVxuXG4gIHJldHVybiBuZXcgRXJyb3IoYGludmFsaWQgZWxlbWVudCByZWZlcmVuY2UgXCIke3JlZn1cImApXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjYWxsYmFjayhjYWxsYmFja0lkLCBkYXRhLCBpZktlZXBBbGl2ZSkge1xuICBjb25zdCBjYWxsYmFjayA9IHRoaXMuY2FsbGJhY2tzW2NhbGxiYWNrSWRdXG5cbiAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNhbGxiYWNrKGRhdGEpIC8vIGRhdGEgaXMgYWxyZWFkeSBhIG9iamVjdCwgQHNlZTogbGliL2ZyYW1ld29yay5qc1xuXG4gICAgaWYgKHR5cGVvZiBpZktlZXBBbGl2ZSA9PT0gJ3VuZGVmaW5lZCcgfHwgaWZLZWVwQWxpdmUgPT09IGZhbHNlKSB7XG4gICAgICB0aGlzLmNhbGxiYWNrc1tjYWxsYmFja0lkXSA9IHVuZGVmaW5lZFxuICAgIH1cblxuICAgIHRoaXMudXBkYXRlQWN0aW9ucygpXG4gICAgcmV0dXJuXG4gIH1cblxuICByZXR1cm4gbmV3IEVycm9yKGBpbnZhbGlkIGNhbGxiYWNrIGlkIFwiJHtjYWxsYmFja0lkfVwiYClcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlZnJlc2hEYXRhKGRhdGEpIHtcbiAgY29uc3Qgdm0gPSB0aGlzLnZtXG5cbiAgaWYgKHZtICYmIGRhdGEpIHtcbiAgICBpZiAodHlwZW9mIHZtLnJlZnJlc2hEYXRhID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB2bS5yZWZyZXNoRGF0YShkYXRhKVxuICAgIH0gZWxzZSB7XG4gICAgICBleHRlbmQodm0sIGRhdGEpXG4gICAgfVxuICAgIHRoaXMudXBkYXRlQWN0aW9ucyhbY3JlYXRlQWN0aW9uKCdyZWZyZXNoRmluaXNoJywgW10pXSlcbiAgICByZXR1cm5cbiAgfVxuXG4gIHJldHVybiBuZXcgRXJyb3IoYGludmFsaWQgZGF0YSBcIiR7ZGF0YX1cImApXG59XG5cbmZ1bmN0aW9uIHVwZGF0ZUVsZW1lbnQoZWwsIGNoYW5nZXMpIHtcbiAgY29uc3QgYXR0cnMgPSBjaGFuZ2VzLmF0dHJzIHx8IHt9XG4gIGZvciAoY29uc3QgbmFtZSBpbiBhdHRycykge1xuICAgIGVsLnNldEF0dHIobmFtZSwgYXR0cnMpXG4gIH1cbiAgY29uc3Qgc3R5bGUgPSBjaGFuZ2VzLnN0eWxlIHx8IHt9XG4gIGZvciAoY29uc3QgbmFtZSBpbiBzdHlsZSkge1xuICAgIGVsLnNldFN0eWxlKG5hbWUsIHN0eWxlW25hbWVdKVxuICB9XG59XG5cblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vbGliL2FwcC9jdHJsLmpzXG4gKiovIiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gTGlzdGVuZXIoaWQsIGhhbmRsZXIpIHtcbiAgdGhpcy5pZCA9IGlkXG4gIHRoaXMuYmF0Y2hlZCA9IGZhbHNlXG4gIHRoaXMudXBkYXRlcyA9IFtdXG4gIGlmICh0eXBlb2YgaGFuZGxlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHRoaXMuaGFuZGxlciA9IGhhbmRsZXJcbiAgfVxufVxuXG5MaXN0ZW5lci5wcm90b3R5cGUuY3JlYXRlRmluaXNoID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gIGNvbnN0IGhhbmRsZXIgPSB0aGlzLmhhbmRsZXJcbiAgaGFuZGxlcihbY3JlYXRlQWN0aW9uKCdjcmVhdGVGaW5pc2gnLCBbXSldLCBjYWxsYmFjaylcbn1cblxuTGlzdGVuZXIucHJvdG90eXBlLmNyZWF0ZUJvZHkgPSBmdW5jdGlvbiAoZWxlbWVudCwgcmVmKSB7XG4gIGNvbnN0IGFjdGlvbnMgPSBbY3JlYXRlQWN0aW9uKCdjcmVhdGVCb2R5JywgW2VsZW1lbnQudG9KU09OKCldKV1cbiAgdGhpcy5hZGRBY3Rpb25zKGFjdGlvbnMpXG59XG5cbkxpc3RlbmVyLnByb3RvdHlwZS5hZGRFbGVtZW50ID0gZnVuY3Rpb24gKGVsZW1lbnQsIHJlZiwgaW5kZXgpIHtcbiAgaWYgKCEoaW5kZXggPj0gMCkpIHtcbiAgICBpbmRleCA9IC0xXG4gIH1cbiAgdGhpcy5hZGRBY3Rpb25zKGNyZWF0ZUFjdGlvbignYWRkRWxlbWVudCcsIFtyZWYsIGVsZW1lbnQudG9KU09OKCksIGluZGV4XSkpXG59XG5cbkxpc3RlbmVyLnByb3RvdHlwZS5yZW1vdmVFbGVtZW50ID0gZnVuY3Rpb24gKHJlZikge1xuICBpZiAoQXJyYXkuaXNBcnJheShyZWYpKSB7XG4gICAgY29uc3QgYWN0aW9ucyA9IHJlZi5tYXAoKHIpID0+IGNyZWF0ZUFjdGlvbigncmVtb3ZlRWxlbWVudCcsIFtyXSkpXG4gICAgdGhpcy5hZGRBY3Rpb25zKGFjdGlvbnMpXG4gIH1cbiAgZWxzZSB7XG4gICAgdGhpcy5hZGRBY3Rpb25zKGNyZWF0ZUFjdGlvbigncmVtb3ZlRWxlbWVudCcsIFtyZWZdKSlcbiAgfVxufVxuXG5MaXN0ZW5lci5wcm90b3R5cGUubW92ZUVsZW1lbnQgPSBmdW5jdGlvbiAodGFyZ2V0UmVmLCBwYXJlbnRSZWYsIGluZGV4KSB7XG4gIHRoaXMuYWRkQWN0aW9ucyhjcmVhdGVBY3Rpb24oJ21vdmVFbGVtZW50JywgW3RhcmdldFJlZiwgcGFyZW50UmVmLCBpbmRleF0pKVxufVxuXG5MaXN0ZW5lci5wcm90b3R5cGUuc2V0QXR0ciA9IGZ1bmN0aW9uIChyZWYsIGtleSwgdmFsdWUpIHtcbiAgY29uc3QgcmVzdWx0ID0ge31cbiAgcmVzdWx0W2tleV0gPSB2YWx1ZVxuICB0aGlzLmFkZEFjdGlvbnMoY3JlYXRlQWN0aW9uKCd1cGRhdGVBdHRycycsIFtyZWYsIHJlc3VsdF0pKVxufVxuXG5MaXN0ZW5lci5wcm90b3R5cGUuc2V0U3R5bGUgPSBmdW5jdGlvbiAocmVmLCBrZXksIHZhbHVlKSB7XG4gIGNvbnN0IHJlc3VsdCA9IHt9XG4gIHJlc3VsdFtrZXldID0gdmFsdWVcbiAgdGhpcy5hZGRBY3Rpb25zKGNyZWF0ZUFjdGlvbigndXBkYXRlU3R5bGUnLCBbcmVmLCByZXN1bHRdKSlcbn1cblxuTGlzdGVuZXIucHJvdG90eXBlLnNldFN0eWxlcyA9IGZ1bmN0aW9uIChyZWYsIHN0eWxlKSB7XG4gIHRoaXMuYWRkQWN0aW9ucyhjcmVhdGVBY3Rpb24oJ3VwZGF0ZVN0eWxlJywgW3JlZiwgc3R5bGVdKSlcbn1cblxuTGlzdGVuZXIucHJvdG90eXBlLmFkZEV2ZW50ID0gZnVuY3Rpb24gKHJlZiwgdHlwZSkge1xuICB0aGlzLmFkZEFjdGlvbnMoY3JlYXRlQWN0aW9uKCdhZGRFdmVudCcsIFtyZWYsIHR5cGVdKSlcbn1cblxuTGlzdGVuZXIucHJvdG90eXBlLnJlbW92ZUV2ZW50ID0gZnVuY3Rpb24gKHJlZiwgdHlwZSkge1xuICB0aGlzLmFkZEFjdGlvbnMoY3JlYXRlQWN0aW9uKCdyZW1vdmVFdmVudCcsIFtyZWYsIHR5cGVdKSlcbn1cblxuTGlzdGVuZXIucHJvdG90eXBlLmhhbmRsZXIgPSBmdW5jdGlvbiAoYWN0aW9ucywgY2IpIHtcbiAgY2IgJiYgY2IoKVxufVxuXG5MaXN0ZW5lci5wcm90b3R5cGUuYWRkQWN0aW9ucyA9IGZ1bmN0aW9uIChhY3Rpb25zKSB7XG4gIGNvbnN0IHVwZGF0ZXMgPSB0aGlzLnVwZGF0ZXNcbiAgY29uc3QgaGFuZGxlciA9IHRoaXMuaGFuZGxlclxuXG4gIGlmICghQXJyYXkuaXNBcnJheShhY3Rpb25zKSkge1xuICAgIGFjdGlvbnMgPSBbYWN0aW9uc11cbiAgfVxuXG4gIGlmICh0aGlzLmJhdGNoZWQpIHtcbiAgICB1cGRhdGVzLnB1c2guYXBwbHkodXBkYXRlcywgYWN0aW9ucylcbiAgfVxuICBlbHNlIHtcbiAgICBoYW5kbGVyKGFjdGlvbnMpXG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUFjdGlvbihuYW1lLCBhcmdzKSB7XG4gIHJldHVybiB7bW9kdWxlOiAnZG9tJywgbWV0aG9kOiBuYW1lLCBhcmdzOiBhcmdzfVxufVxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9saWIvYXBwL2RvbS1saXN0ZW5lci5qc1xuICoqLyIsImV4cG9ydCBkZWZhdWx0IGNsYXNzIERpZmZlciB7XG4gIGNvbnN0cnVjdG9yIChpZCkge1xuICAgIHRoaXMuaWQgPSBpZFxuICAgIHRoaXMubWFwID0gW11cbiAgICB0aGlzLmhvb2tzID0gW11cbiAgfVxuICBpc0VtcHR5ICgpIHtcbiAgICByZXR1cm4gdGhpcy5tYXAubGVuZ3RoID09PSAwXG4gIH1cbiAgYXBwZW5kICh0eXBlLCBkZXB0aCwgcmVmLCBoYW5kbGVyKSB7XG4gICAgY29uc3QgbWFwID0gdGhpcy5tYXBcbiAgICBpZiAoIW1hcFtkZXB0aF0pIHtcbiAgICAgIG1hcFtkZXB0aF0gPSB7fVxuICAgIH1cbiAgICBjb25zdCBncm91cCA9IG1hcFtkZXB0aF1cbiAgICBpZiAoIWdyb3VwW3R5cGVdKSB7XG4gICAgICBncm91cFt0eXBlXSA9IHt9XG4gICAgfVxuICAgIGlmICh0eXBlID09PSAnZWxlbWVudCcpIHtcbiAgICAgIGlmICghZ3JvdXBbdHlwZV1bcmVmXSkge1xuICAgICAgICBncm91cFt0eXBlXVtyZWZdID0gW11cbiAgICAgIH1cbiAgICAgIGdyb3VwW3R5cGVdW3JlZl0ucHVzaChoYW5kbGVyKVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGdyb3VwW3R5cGVdW3JlZl0gPSBoYW5kbGVyXG4gICAgfVxuICB9XG4gIGZsdXNoICgpIHtcbiAgICBjb25zdCBtYXAgPSB0aGlzLm1hcC5zbGljZSgpXG4gICAgdGhpcy5tYXAubGVuZ3RoID0gMFxuICAgIG1hcC5mb3JFYWNoKChncm91cCkgPT4ge1xuICAgICAgY2FsbFR5cGVNYXAoZ3JvdXAsICdyZXBlYXQnKVxuICAgICAgY2FsbFR5cGVNYXAoZ3JvdXAsICdzaG93bicpXG4gICAgICBjYWxsVHlwZUxpc3QoZ3JvdXAsICdlbGVtZW50JylcbiAgICB9KVxuXG4gICAgY29uc3QgaG9va3MgPSB0aGlzLmhvb2tzLnNsaWNlKClcbiAgICB0aGlzLmhvb2tzLmxlbmd0aCA9IDBcbiAgICBob29rcy5mb3JFYWNoKChmbikgPT4ge1xuICAgICAgZm4oKVxuICAgIH0pXG5cbiAgICBpZiAoIXRoaXMuaXNFbXB0eSgpKSB7XG4gICAgICB0aGlzLmZsdXNoKClcbiAgICB9XG4gIH1cbiAgdGhlbiAoZm4pIHtcbiAgICB0aGlzLmhvb2tzLnB1c2goZm4pXG4gIH1cbn1cblxuZnVuY3Rpb24gY2FsbFR5cGVNYXAoZ3JvdXAsIHR5cGUpIHtcbiAgY29uc3QgbWFwID0gZ3JvdXBbdHlwZV1cbiAgZm9yIChjb25zdCByZWYgaW4gbWFwKSB7XG4gICAgbWFwW3JlZl0oKVxuICB9XG59XG5cbmZ1bmN0aW9uIGNhbGxUeXBlTGlzdChncm91cCwgdHlwZSkge1xuICBjb25zdCBtYXAgPSBncm91cFt0eXBlXVxuICBmb3IgKGNvbnN0IHJlZiBpbiBtYXApIHtcbiAgICBjb25zdCBsaXN0ID0gbWFwW3JlZl1cbiAgICBsaXN0LmZvckVhY2goKGhhbmRsZXIpID0+IHtoYW5kbGVyKCl9KVxuICB9XG59XG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL2xpYi9hcHAvZGlmZmVyLmpzXG4gKiovIiwiLyoqXG4gKiBAZmlsZU92ZXJ2aWV3IGV2ZW50IG1hbmFnZXJcbiAqL1xuXG5pbXBvcnQgKiBhcyBfIGZyb20gJy4uL3V0aWwnXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEV2ZW50TWFuYWdlcigpIHtcbiAgdGhpcy5lbHMgPSBbXVxuICB0aGlzLnRhcmdldHMgPSBbXVxufVxuXG5FdmVudE1hbmFnZXIucHJvdG90eXBlLl9nZXQgPSBmdW5jdGlvbiAoZWwsIGZvcmNlKSB7XG4gIHZhciBpbmRleCA9IF8uaW5kZXhPZih0aGlzLmVscywgZWwpXG4gIHZhciB0YXJnZXRcbiAgaWYgKGluZGV4ID49IDApIHtcbiAgICB0YXJnZXQgPSB0aGlzLnRhcmdldHNbaW5kZXhdXG4gIH1cbiAgZWxzZSBpZiAoZm9yY2UpIHtcbiAgICB0YXJnZXQgPSB7ZWw6IGVsLCBldmVudHM6IHt9fVxuICAgIHRoaXMuZWxzLnB1c2goZWwpXG4gICAgdGhpcy50YXJnZXRzLnB1c2godGFyZ2V0KVxuICB9XG4gIHJldHVybiB0YXJnZXRcbn1cblxuRXZlbnRNYW5hZ2VyLnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiAoZWwsIHR5cGUsIGhhbmRsZXIpIHtcbiAgaWYgKHR5cGVvZiBlbCAhPT0gJ29iamVjdCcgfHwgIWVsIHx8XG4gICAgdHlwZW9mIHR5cGUgIT09ICdzdHJpbmcnIHx8ICF0eXBlIHx8XG4gICAgdHlwZW9mIGhhbmRsZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm5cbiAgfVxuICB2YXIgdGFyZ2V0ID0gdGhpcy5fZ2V0KGVsLCB0cnVlKVxuICB0YXJnZXQuZXZlbnRzW3R5cGVdID0gaGFuZGxlclxufVxuXG5FdmVudE1hbmFnZXIucHJvdG90eXBlLnJlbW92ZSA9IGZ1bmN0aW9uIChlbCwgdHlwZSkge1xuICBpZiAodHlwZW9mIGVsICE9PSAnb2JqZWN0JyB8fCAhZWwgfHxcbiAgICB0eXBlb2YgdHlwZSAhPT0gJ3N0cmluZycgfHwgIXR5cGUpIHtcbiAgICByZXR1cm5cbiAgfVxuICB2YXIgdGFyZ2V0ID0gdGhpcy5fZ2V0KGVsKVxuICBpZiAodGFyZ2V0KSB7XG4gICAgZGVsZXRlIHRhcmdldC5ldmVudHNbdHlwZV1cbiAgfVxufVxuXG5FdmVudE1hbmFnZXIucHJvdG90eXBlLmZpcmUgPSBmdW5jdGlvbiAoZWwsIHR5cGUsIGUpIHtcbiAgdmFyIHRhcmdldCA9IHRoaXMuX2dldChlbClcbiAgdmFyIGhhbmRsZXIsIGVsXG4gIGlmICh0YXJnZXQpIHtcbiAgICBlbCA9IHRhcmdldC5lbFxuICAgIGhhbmRsZXIgPSB0YXJnZXQuZXZlbnRzW3R5cGVdXG4gICAgaWYgKHR5cGVvZiBoYW5kbGVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gaGFuZGxlci5jYWxsKGVsLCBlKVxuICAgIH1cbiAgfVxufVxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9saWIvYXBwL2V2ZW50LmpzXG4gKiovIiwiLyoqXG4gKiBAZmlsZU92ZXJ2aWV3XG4gKiBBIHNpbXBsZSB2aXJ0dWFsIGRvbSBpbXBsZW1lbnRhdGlvblxuICovXG5cbmNvbnN0IERFRkFVTFRfVEFHX05BTUUgPSAnZGl2J1xuXG5leHBvcnQgY29uc3QgaW5zdGFuY2VNYXAgPSB7fVxuXG5leHBvcnQgZnVuY3Rpb24gRG9jdW1lbnQoaWQpIHtcbiAgaWQgPSBpZCA/IGlkLnRvU3RyaW5nKCkgOiAnJ1xuICB0aGlzLmlkID0gaWRcbiAgdGhpcy5uZXh0UmVmID0gMVxuICB0aGlzLm5vZGVNYXAgPSB7fVxuICB0aGlzLmxpc3RlbmVyID0gbnVsbFxuICB0aGlzLmV2ZW50TWFuYWdlciA9IG51bGxcbiAgdGhpcy5jbG9zZWQgPSBmYWxzZVxuICBpbnN0YW5jZU1hcFtpZF0gPSB0aGlzXG5cbiAgdGhpcy5jcmVhdGVEb2N1bWVudEVsZW1lbnQoKVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZGVzdHJveURvY3VtZW50KGlkKSB7XG4gIGRlbGV0ZSBpbnN0YW5jZU1hcFtpZF1cbn1cblxuRG9jdW1lbnQucHJvdG90eXBlLm9wZW4gPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuY2xvc2VkID0gZmFsc2VcbiAgaWYgKHRoaXMubGlzdGVuZXIpIHtcbiAgICB0aGlzLmxpc3RlbmVyLmJhdGNoZWQgPSBmYWxzZVxuICB9XG59XG5Eb2N1bWVudC5wcm90b3R5cGUuY2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuY2xvc2VkID0gdHJ1ZVxuICBpZiAodGhpcy5saXN0ZW5lcikge1xuICAgIHRoaXMubGlzdGVuZXIuYmF0Y2hlZCA9IHRydWVcbiAgfVxufVxuXG5Eb2N1bWVudC5wcm90b3R5cGUuc2V0RXZlbnRNYW5hZ2VyID0gZnVuY3Rpb24gKGV2ZW50TWFuYWdlcikge1xuICB0aGlzLmV2ZW50TWFuYWdlciA9IGV2ZW50TWFuYWdlclxufVxuXG5Eb2N1bWVudC5wcm90b3R5cGUuc2V0TGlzdGVuZXIgPSBmdW5jdGlvbiAobGlzdGVuZXIpIHtcbiAgdGhpcy5saXN0ZW5lciA9IGxpc3RlbmVyXG4gIGxpc3RlbmVyLmJhdGNoZWQgPSAhIXRoaXMuY2xvc2VkXG59XG5cbkRvY3VtZW50LnByb3RvdHlwZS5hZGRSZWYgPSBmdW5jdGlvbiAoZWwpIHtcbiAgZWwucmVmID0gdGhpcy5uZXh0UmVmLnRvU3RyaW5nKClcbiAgdGhpcy5ub2RlTWFwW2VsLnJlZl0gPSBlbFxuICB0aGlzLm5leHRSZWYrK1xufVxuXG5Eb2N1bWVudC5wcm90b3R5cGUuZ2V0UmVmID0gZnVuY3Rpb24gKHJlZikge1xuICByZXR1cm4gdGhpcy5ub2RlTWFwW3JlZl1cbn1cblxuRG9jdW1lbnQucHJvdG90eXBlLnJlbW92ZVJlZiA9IGZ1bmN0aW9uIChyZWYpIHtcbiAgZGVsZXRlIHRoaXMubm9kZU1hcFtyZWZdXG59XG5cbkRvY3VtZW50LnByb3RvdHlwZS5jcmVhdGVEb2N1bWVudEVsZW1lbnQgPSBmdW5jdGlvbiAodHlwZSwgcHJvcHMpIHtcbiAgaWYgKCF0aGlzLmRvY3VtZW50RWxlbWVudCkge1xuICAgIHRoaXMuZG9jdW1lbnRFbGVtZW50ID0gbmV3IEVsZW1lbnQodHlwZSwgcHJvcHMsIHRoaXMpXG4gICAgdGhpcy5ub2RlTWFwLl9kb2N1bWVudEVsZW1lbnQgPSB0aGlzLmRvY3VtZW50RWxlbWVudFxuICAgIHRoaXMuZG9jdW1lbnRFbGVtZW50LnJlZiA9ICdfZG9jdW1lbnRFbGVtZW50J1xuICAgIHRoaXMuZG9jdW1lbnRFbGVtZW50LmF0dGFjaGVkID0gdHJ1ZVxuICB9XG5cbiAgcmV0dXJuIHRoaXMuZG9jdW1lbnRFbGVtZW50XG59XG5cbkRvY3VtZW50LnByb3RvdHlwZS5jcmVhdGVCb2R5ID0gZnVuY3Rpb24gKHR5cGUsIHByb3BzKSB7XG4gIGlmICghdGhpcy5ib2R5KSB7XG4gICAgdGhpcy5ib2R5ID0gbmV3IEVsZW1lbnQodHlwZSwgcHJvcHMsIHRoaXMpXG4gICAgdGhpcy5ub2RlTWFwLl9yb290ID0gdGhpcy5ib2R5XG4gICAgdGhpcy5ib2R5LnJlZiA9ICdfcm9vdCdcbiAgICB0aGlzLmJvZHkuZGVwdGggPSAxXG4gIH1cblxuICByZXR1cm4gdGhpcy5ib2R5XG59XG5cbkRvY3VtZW50LnByb3RvdHlwZS5jcmVhdGVFbGVtZW50ID0gZnVuY3Rpb24gKHRhZ05hbWUsIHByb3BzKSB7XG4gIHJldHVybiBuZXcgRWxlbWVudCh0YWdOYW1lLCBwcm9wcywgdGhpcylcbn1cblxuRG9jdW1lbnQucHJvdG90eXBlLmNyZWF0ZUNvbW1lbnQgPSBmdW5jdGlvbiAodGV4dCkge1xuICByZXR1cm4gbmV3IENvbW1lbnQodGV4dCwgdGhpcylcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIE5vZGUoKSB7XG59XG5cbk5vZGUucHJvdG90eXBlLmNyZWF0ZSA9IGZ1bmN0aW9uIChpbnN0YW5jZUlkKSB7XG4gIHRoaXMucGFyZW50UmVmID0gbnVsbFxuICB0aGlzLmF0dGFjaGVkID0gZmFsc2VcbiAgaWYgKGluc3RhbmNlSWQpIHtcbiAgICB0aGlzLmluc3RhbmNlSWQgPSBpbnN0YW5jZUlkXG4gICAgY29uc3QgZG9jID0gaW5zdGFuY2VNYXBbaW5zdGFuY2VJZF1cbiAgICBkb2MuYWRkUmVmKHRoaXMpXG4gIH1cbn1cblxuTm9kZS5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcbiAgY29uc3QgcmVmID0gdGhpcy5yZWZcbiAgY29uc3QgaW5zdGFuY2VJZCA9IHRoaXMuaW5zdGFuY2VJZFxuICBpZiAoaW5zdGFuY2VJZCkge1xuICAgIGNvbnN0IGRvYyA9IGluc3RhbmNlTWFwW2luc3RhbmNlSWRdXG4gICAgZG9jLnJlbW92ZVJlZihyZWYpXG4gIH1cblxuICBjb25zdCBjaGlsZHJlbiA9IHRoaXMuY2hpbGRyZW4gfHwgW11cbiAgY29uc3QgbGVuZ3RoID0gY2hpbGRyZW4ubGVuZ3RoXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICBjaGlsZHJlbltpXS5kZXN0cm95KClcbiAgfVxufVxuXG5Ob2RlLnByb3RvdHlwZS5nZXRSZW5kZXJlciA9IGZ1bmN0aW9uICgpIHtcbiAgY29uc3QgZG9jID0gaW5zdGFuY2VNYXBbdGhpcy5pbnN0YW5jZUlkXVxuICByZXR1cm4gZG9jLmxpc3RlbmVyXG59XG5cbk5vZGUucHJvdG90eXBlLm5leHQgPSBmdW5jdGlvbiAoKSB7XG4gIGNvbnN0IGluc3RhbmNlSWQgPSB0aGlzLmluc3RhbmNlSWRcbiAgY29uc3QgZG9jID0gaW5zdGFuY2VNYXBbaW5zdGFuY2VJZF1cbiAgY29uc3QgcGFyZW50ID0gZG9jLmdldFJlZih0aGlzLnBhcmVudFJlZilcbiAgaWYgKHBhcmVudCkge1xuICAgIHJldHVybiBwYXJlbnQuY2hpbGRyZW5bcGFyZW50LmNoaWxkcmVuLmluZGV4T2YodGhpcykgKyAxXVxuICB9XG59XG5cbk5vZGUucHJvdG90eXBlLnByZXYgPSBmdW5jdGlvbiAoKSB7XG4gIGNvbnN0IGluc3RhbmNlSWQgPSB0aGlzLmluc3RhbmNlSWRcbiAgY29uc3QgZG9jID0gaW5zdGFuY2VNYXBbaW5zdGFuY2VJZF1cbiAgY29uc3QgcGFyZW50ID0gZG9jLmdldFJlZih0aGlzLnBhcmVudFJlZilcbiAgaWYgKHBhcmVudCkge1xuICAgIHJldHVybiBwYXJlbnQuY2hpbGRyZW5bcGFyZW50LmNoaWxkcmVuLmluZGV4T2YodGhpcykgLSAxXVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBFbGVtZW50KHR5cGU9REVGQVVMVF9UQUdfTkFNRSwgcHJvcHMsIG93bmVyRG9jdW1lbnQpIHtcbiAgcHJvcHMgPSBwcm9wcyB8fCB7fVxuICB0aGlzLmNyZWF0ZShvd25lckRvY3VtZW50LmlkKVxuICB0aGlzLm93bmVyRG9jdW1lbnQgPSBvd25lckRvY3VtZW50XG4gIHRoaXMudHlwZSA9IHR5cGVcbiAgdGhpcy5hdHRyID0gcHJvcHMuYXR0ciB8fCB7fVxuICB0aGlzLmNsYXNzU3R5bGUgPSBwcm9wcy5jbGFzc1N0eWxlIHx8IHt9XG4gIHRoaXMuc3R5bGUgPSBwcm9wcy5zdHlsZSB8fCB7fVxuICB0aGlzLmV2ZW50ID0gW11cbiAgdGhpcy5jaGlsZHJlbiA9IFtdXG4gIHRoaXMucHVyZUNoaWxkcmVuID0gW11cbn1cblxuRWxlbWVudC5wcm90b3R5cGUgPSBuZXcgTm9kZSgpXG5cbkVsZW1lbnQucHJvdG90eXBlLmFwcGVuZENoaWxkID0gZnVuY3Rpb24gKG5vZGUpIHtcblxuICByZW1vdmVJZkV4aXN0ZWQobm9kZSlcbiAgbm9kZS5wYXJlbnRSZWYgPSB0aGlzLnJlZlxuICB0aGlzLmNoaWxkcmVuLnB1c2gobm9kZSlcblxuICBpZiAodGhpcy5hdHRhY2hlZCkge1xuICAgIHNldEF0dGFjaGVkKG5vZGUsIHRoaXMuZGVwdGgpXG4gIH1cbiAgZWxzZSB7XG4gICAgc2V0RGV0YWNoZWQobm9kZSlcbiAgfVxuXG4gIGlmIChub2RlIGluc3RhbmNlb2YgRWxlbWVudCkge1xuICAgIHRoaXMucHVyZUNoaWxkcmVuLnB1c2gobm9kZSlcblxuICAgIGlmICh0aGlzLmF0dGFjaGVkKSB7XG4gICAgICBjb25zdCByZW5kZXJlciA9IHRoaXMuZ2V0UmVuZGVyZXIoKVxuICAgICAgaWYgKHJlbmRlcmVyKSB7XG4gICAgICAgIGlmICh0aGlzLnJlZiA9PT0gJ19kb2N1bWVudEVsZW1lbnQnKSB7XG4gICAgICAgICAgLy8gaWYgaXRzIHBhcmVudCBpcyBkb2N1bWVudEVsZW1lbnQgdGhlbiBpdCdzIGEgYm9keVxuICAgICAgICAgIHJlbmRlcmVyLmNyZWF0ZUJvZHkobm9kZSwgdGhpcy5yZWYpXG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgcmVuZGVyZXIuYWRkRWxlbWVudChub2RlLCB0aGlzLnJlZilcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5FbGVtZW50LnByb3RvdHlwZS5pbnNlcnRCZWZvcmUgPSBmdW5jdGlvbiAobm9kZSwgYmVmb3JlKSB7XG5cbiAgaWYgKG5vZGUucGFyZW50UmVmID09PSB0aGlzLnJlZikge1xuICAgIG1vdmVCZWZvcmUobm9kZSwgYmVmb3JlLCB0aGlzLmNoaWxkcmVuKVxuICAgIGlmIChub2RlIGluc3RhbmNlb2YgRWxlbWVudCkge1xuICAgICAgY29uc3QgcHVyZUJlZm9yZUluZGV4ID0gbW92ZVB1cmVCZWZvcmUobm9kZSwgYmVmb3JlLCB0aGlzLnB1cmVDaGlsZHJlbilcbiAgICAgIGlmIChwdXJlQmVmb3JlSW5kZXggPj0gMCAmJiB0aGlzLmF0dGFjaGVkKSB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVyID0gdGhpcy5nZXRSZW5kZXJlcigpXG4gICAgICAgIGlmIChyZW5kZXJlcikge1xuICAgICAgICAgIHJlbmRlcmVyLm1vdmVFbGVtZW50KG5vZGUucmVmLCB0aGlzLnJlZiwgcHVyZUJlZm9yZUluZGV4KVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVyblxuICB9XG5cbiAgcmVtb3ZlSWZFeGlzdGVkKG5vZGUpXG5cbiAgY29uc3QgY2hpbGRyZW4gPSB0aGlzLmNoaWxkcmVuXG4gIGNvbnN0IGluZGV4ID0gY2hpbGRyZW4uaW5kZXhPZihiZWZvcmUpXG5cbiAgbm9kZS5wYXJlbnRSZWYgPSB0aGlzLnJlZlxuICBpZiAodGhpcy5hdHRhY2hlZCkge1xuICAgIHNldEF0dGFjaGVkKG5vZGUsIHRoaXMuZGVwdGgpXG4gIH1cbiAgZWxzZSB7XG4gICAgc2V0RGV0YWNoZWQobm9kZSlcbiAgfVxuICBjaGlsZHJlbi5zcGxpY2UoaW5kZXgsIDAsIG5vZGUpXG5cbiAgaWYgKG5vZGUgaW5zdGFuY2VvZiBFbGVtZW50KSB7XG4gICAgY29uc3QgcHVyZUNoaWxkcmVuID0gdGhpcy5wdXJlQ2hpbGRyZW5cbiAgICBjb25zdCBwdXJlSW5kZXggPSBnZXRQdXJlQWZ0ZXIoYmVmb3JlLCBwdXJlQ2hpbGRyZW4pXG5cbiAgICBwdXJlQ2hpbGRyZW4uc3BsaWNlKHB1cmVJbmRleCwgMCwgbm9kZSlcblxuICAgIGlmICh0aGlzLmF0dGFjaGVkKSB7XG4gICAgICBjb25zdCByZW5kZXJlciA9IHRoaXMuZ2V0UmVuZGVyZXIoKVxuICAgICAgaWYgKHJlbmRlcmVyKSB7XG4gICAgICAgIHJlbmRlcmVyLmFkZEVsZW1lbnQobm9kZSwgdGhpcy5yZWYsIHB1cmVJbmRleClcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuRWxlbWVudC5wcm90b3R5cGUuaW5zZXJ0QWZ0ZXIgPSBmdW5jdGlvbiAobm9kZSwgYWZ0ZXIpIHtcblxuICBpZiAobm9kZS5wYXJlbnRSZWYgPT09IHRoaXMucmVmKSB7XG4gICAgbW92ZUFmdGVyKG5vZGUsIGFmdGVyLCB0aGlzLmNoaWxkcmVuKVxuICAgIGlmIChub2RlIGluc3RhbmNlb2YgRWxlbWVudCkge1xuICAgICAgY29uc3QgcHVyZUFmdGVySW5kZXggPSBtb3ZlUHVyZUFmdGVyKG5vZGUsIGFmdGVyLCB0aGlzLnB1cmVDaGlsZHJlbilcbiAgICAgIGlmIChwdXJlQWZ0ZXJJbmRleCA+PSAwICYmIHRoaXMuYXR0YWNoZWQpIHtcbiAgICAgICAgY29uc3QgcmVuZGVyZXIgPSB0aGlzLmdldFJlbmRlcmVyKClcbiAgICAgICAgaWYgKHJlbmRlcmVyKSB7XG4gICAgICAgICAgcmVuZGVyZXIubW92ZUVsZW1lbnQobm9kZS5yZWYsIHRoaXMucmVmLCBwdXJlQWZ0ZXJJbmRleClcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm5cbiAgfVxuXG4gIHJlbW92ZUlmRXhpc3RlZChub2RlKVxuXG4gIGNvbnN0IGNoaWxkcmVuID0gdGhpcy5jaGlsZHJlblxuICBjb25zdCBpbmRleCA9IGNoaWxkcmVuLmluZGV4T2YoYWZ0ZXIpXG5cbiAgbm9kZS5wYXJlbnRSZWYgPSB0aGlzLnJlZlxuICBpZiAodGhpcy5hdHRhY2hlZCkge1xuICAgIHNldEF0dGFjaGVkKG5vZGUsIHRoaXMuZGVwdGgpXG4gIH1cbiAgZWxzZSB7XG4gICAgc2V0RGV0YWNoZWQobm9kZSlcbiAgfVxuICBjaGlsZHJlbi5zcGxpY2UoaW5kZXggKyAxLCAwLCBub2RlKVxuXG4gIGlmIChub2RlIGluc3RhbmNlb2YgRWxlbWVudCkge1xuICAgIGNvbnN0IHB1cmVDaGlsZHJlbiA9IHRoaXMucHVyZUNoaWxkcmVuXG4gICAgY29uc3QgcHVyZUluZGV4ID0gZ2V0UHVyZUJlZm9yZShhZnRlciwgcHVyZUNoaWxkcmVuKVxuXG4gICAgcHVyZUNoaWxkcmVuLnNwbGljZShwdXJlSW5kZXggKyAxLCAwLCBub2RlKVxuXG4gICAgaWYgKHRoaXMuYXR0YWNoZWQpIHtcbiAgICAgIGNvbnN0IHJlbmRlcmVyID0gdGhpcy5nZXRSZW5kZXJlcigpXG4gICAgICBpZiAocmVuZGVyZXIpIHtcbiAgICAgICAgcmVuZGVyZXIuYWRkRWxlbWVudChub2RlLCB0aGlzLnJlZiwgcHVyZUluZGV4ICsgMSlcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuRWxlbWVudC5wcm90b3R5cGUucmVtb3ZlQ2hpbGQgPSBmdW5jdGlvbiAobm9kZSwgcHJlc2VydmVkKSB7XG4gIGNvbnN0IGNoaWxkcmVuID0gdGhpcy5jaGlsZHJlblxuICBjb25zdCBpbmRleCA9IGNoaWxkcmVuLmluZGV4T2Yobm9kZSlcblxuICBzZXREZXRhY2hlZChub2RlKVxuXG4gIGlmIChpbmRleCA+PSAwKSB7XG4gICAgbm9kZS5wYXJlbnRSZWYgPSBudWxsXG4gICAgY2hpbGRyZW4uc3BsaWNlKGluZGV4LCAxKVxuICAgIGlmICghcHJlc2VydmVkKSB7XG4gICAgICBub2RlLmRlc3Ryb3koKVxuICAgIH1cbiAgfVxuXG4gIGlmIChub2RlIGluc3RhbmNlb2YgRWxlbWVudCkge1xuICAgIHRoaXMucHVyZUNoaWxkcmVuLiRyZW1vdmUobm9kZSlcbiAgICBpZiAodGhpcy5hdHRhY2hlZCkge1xuICAgICAgY29uc3QgcmVuZGVyZXIgPSB0aGlzLmdldFJlbmRlcmVyKClcbiAgICAgIGlmIChyZW5kZXJlcikge1xuICAgICAgICByZW5kZXJlci5yZW1vdmVFbGVtZW50KG5vZGUucmVmKVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5FbGVtZW50LnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgY29uc3QgY2hpbGRyZW4gPSB0aGlzLmNoaWxkcmVuXG4gIGNvbnN0IGxlbmd0aCA9IGNoaWxkcmVuLmxlbmd0aFxuICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgY2hpbGQgPSBjaGlsZHJlbltpXVxuICAgIGNoaWxkLnBhcmVudFJlZiA9IG51bGxcbiAgICBzZXREZXRhY2hlZChjaGlsZClcbiAgICBjaGlsZC5kZXN0cm95KClcbiAgfVxuICBjaGlsZHJlbi5sZW5ndGggPSAwXG5cbiAgaWYgKHRoaXMuYXR0YWNoZWQpIHtcbiAgICBjb25zdCByZWZzID0gdGhpcy5wdXJlQ2hpbGRyZW4ubWFwKChjaGlsZCkgPT4gY2hpbGQucmVmKVxuICAgIHRoaXMucHVyZUNoaWxkcmVuLmxlbmd0aCA9IDBcbiAgICBjb25zdCByZW5kZXJlciA9IHRoaXMuZ2V0UmVuZGVyZXIoKVxuICAgIGlmIChyZW5kZXJlcikge1xuICAgICAgcmVuZGVyZXIucmVtb3ZlRWxlbWVudChyZWZzKVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBtb3ZlQmVmb3JlKG5vZGUsIGJlZm9yZSwgY2hpbGRyZW4pIHtcbiAgY29uc3QgdGFyZ2V0SW5kZXggPSBjaGlsZHJlbi5pbmRleE9mKG5vZGUpXG4gIGNvbnN0IGJlZm9yZUluZGV4ID0gY2hpbGRyZW4uaW5kZXhPZihiZWZvcmUpXG5cbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgaWYgKHRhcmdldEluZGV4ID09PSBiZWZvcmVJbmRleCB8fCB0YXJnZXRJbmRleCArIDEgPT09IGJlZm9yZUluZGV4KSB7XG4gICAgcmV0dXJuIC0xXG4gIH1cblxuICBjb25zdCBuZXdJbmRleCA9IHRhcmdldEluZGV4IDwgYmVmb3JlSW5kZXggPyBiZWZvcmVJbmRleCAtIDEgOiBiZWZvcmVJbmRleFxuICBjaGlsZHJlbi5zcGxpY2UodGFyZ2V0SW5kZXgsIDEpXG4gIGNoaWxkcmVuLnNwbGljZShuZXdJbmRleCwgMCwgbm9kZSlcblxuICByZXR1cm4gYmVmb3JlSW5kZXhcbn1cblxuZnVuY3Rpb24gbW92ZVB1cmVCZWZvcmUobm9kZSwgYmVmb3JlLCBwdXJlQ2hpbGRyZW4pIHtcbiAgY29uc3QgcHVyZVRhcmdldEluZGV4ID0gcHVyZUNoaWxkcmVuLmluZGV4T2Yobm9kZSlcbiAgY29uc3QgcHVyZUJlZm9yZUluZGV4ID0gZ2V0UHVyZUFmdGVyKGJlZm9yZSwgcHVyZUNoaWxkcmVuKVxuXG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gIGlmIChwdXJlVGFyZ2V0SW5kZXggPT09IHB1cmVCZWZvcmVJbmRleCB8fFxuICAgIHB1cmVUYXJnZXRJbmRleCArIDEgPT09IHB1cmVCZWZvcmVJbmRleCkge1xuICAgIHJldHVybiAtMVxuICB9XG5cbiAgY29uc3QgcHVyZU5ld0luZGV4ID0gcHVyZVRhcmdldEluZGV4IDwgcHVyZUJlZm9yZUluZGV4XG4gICAgPyBwdXJlQmVmb3JlSW5kZXggLSAxXG4gICAgOiBwdXJlQmVmb3JlSW5kZXhcblxuICBwdXJlQ2hpbGRyZW4uc3BsaWNlKHB1cmVUYXJnZXRJbmRleCwgMSlcbiAgcHVyZUNoaWxkcmVuLnNwbGljZShwdXJlTmV3SW5kZXgsIDAsIG5vZGUpXG5cbiAgcmV0dXJuIHB1cmVCZWZvcmVJbmRleFxufVxuXG5mdW5jdGlvbiBnZXRQdXJlQWZ0ZXIobm9kZSwgcHVyZUNoaWxkcmVuKSB7XG4gIGxldCBwdXJlSW5kZXggPSBwdXJlQ2hpbGRyZW4uaW5kZXhPZihub2RlKVxuICB3aGlsZSAobm9kZSAmJiBwdXJlSW5kZXggPCAwKSB7XG4gICAgbm9kZSA9IG5vZGUubmV4dCgpXG4gICAgcHVyZUluZGV4ID0gcHVyZUNoaWxkcmVuLmluZGV4T2Yobm9kZSlcbiAgfVxuICBpZiAocHVyZUluZGV4IDwgMCkge1xuICAgIHB1cmVJbmRleCA9IHB1cmVDaGlsZHJlbi5sZW5ndGhcbiAgfVxuICByZXR1cm4gcHVyZUluZGV4XG59XG5cbmZ1bmN0aW9uIG1vdmVBZnRlcihub2RlLCBhZnRlciwgY2hpbGRyZW4pIHtcbiAgY29uc3QgdGFyZ2V0SW5kZXggPSBjaGlsZHJlbi5pbmRleE9mKG5vZGUpXG4gIGNvbnN0IGFmdGVySW5kZXggPSBjaGlsZHJlbi5pbmRleE9mKGFmdGVyKVxuXG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gIGlmICh0YXJnZXRJbmRleCA9PT0gYWZ0ZXJJbmRleCB8fCB0YXJnZXRJbmRleCA9PT0gYWZ0ZXJJbmRleCArIDEpIHtcbiAgICByZXR1cm4gLTFcbiAgfVxuXG4gIGNvbnN0IG5ld0luZGV4ID0gdGFyZ2V0SW5kZXggPCBhZnRlckluZGV4ID8gYWZ0ZXJJbmRleCA6IGFmdGVySW5kZXggKyAxXG4gIGNoaWxkcmVuLnNwbGljZSh0YXJnZXRJbmRleCwgMSlcbiAgY2hpbGRyZW4uc3BsaWNlKG5ld0luZGV4LCAwLCBub2RlKVxuXG4gIHJldHVybiBhZnRlckluZGV4XG59XG5cbmZ1bmN0aW9uIG1vdmVQdXJlQWZ0ZXIobm9kZSwgYWZ0ZXIsIHB1cmVDaGlsZHJlbikge1xuICBjb25zdCBwdXJlVGFyZ2V0SW5kZXggPSBwdXJlQ2hpbGRyZW4uaW5kZXhPZihub2RlKVxuICBjb25zdCBwdXJlQWZ0ZXJJbmRleCA9IGdldFB1cmVCZWZvcmUoYWZ0ZXIsIHB1cmVDaGlsZHJlbilcblxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICBpZiAocHVyZVRhcmdldEluZGV4ID09PSBwdXJlQWZ0ZXJJbmRleCB8fFxuICAgIHB1cmVUYXJnZXRJbmRleCA9PT0gcHVyZUFmdGVySW5kZXggKyAxKSB7XG4gICAgcmV0dXJuIC0xXG4gIH1cblxuICBjb25zdCBwdXJlTmV3SW5kZXggPSBwdXJlVGFyZ2V0SW5kZXggPCBwdXJlQWZ0ZXJJbmRleFxuICAgID8gcHVyZUFmdGVySW5kZXhcbiAgICA6IHB1cmVBZnRlckluZGV4ICsgMVxuXG4gIHB1cmVDaGlsZHJlbi5zcGxpY2UocHVyZVRhcmdldEluZGV4LCAxKVxuICBwdXJlQ2hpbGRyZW4uc3BsaWNlKHB1cmVOZXdJbmRleCwgMCwgbm9kZSlcblxuICByZXR1cm4gcHVyZUFmdGVySW5kZXggKyAxXG59XG5cbmZ1bmN0aW9uIGdldFB1cmVCZWZvcmUobm9kZSwgcHVyZUNoaWxkcmVuKSB7XG4gIGxldCBwdXJlSW5kZXggPSBwdXJlQ2hpbGRyZW4uaW5kZXhPZihub2RlKVxuICB3aGlsZSAobm9kZSAmJiBwdXJlSW5kZXggPCAwKSB7XG4gICAgbm9kZSA9IG5vZGUucHJldigpXG4gICAgcHVyZUluZGV4ID0gcHVyZUNoaWxkcmVuLmluZGV4T2Yobm9kZSlcbiAgfVxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICBpZiAocHVyZUluZGV4IDwgMCkge1xuICAgIHB1cmVJbmRleCA9IC0xXG4gIH1cbiAgcmV0dXJuIHB1cmVJbmRleFxufVxuXG5mdW5jdGlvbiBzZXRBdHRhY2hlZChub2RlLCBkZXB0aCkge1xuICBpZiAobm9kZS5yZWYgPT09ICdfcm9vdCcpIHtcbiAgICBkZXB0aCA9IDFcbiAgfVxuICBlbHNlIHtcbiAgICBkZXB0aCA9IGRlcHRoID4gMCA/IGRlcHRoICsgMSA6IDBcbiAgfVxuICBub2RlLmF0dGFjaGVkID0gdHJ1ZVxuICBub2RlLmRlcHRoID0gZGVwdGhcbiAgaWYgKG5vZGUuY2hpbGRyZW4pIHtcbiAgICBub2RlLmNoaWxkcmVuLmZvckVhY2goKHN1YikgPT4ge1xuICAgICAgc2V0QXR0YWNoZWQoc3ViLCBkZXB0aClcbiAgICB9KVxuICB9XG59XG5cbmZ1bmN0aW9uIHNldERldGFjaGVkKG5vZGUpIHtcbiAgbm9kZS5hdHRhY2hlZCA9IGZhbHNlXG4gIG5vZGUuZGVwdGggPSAwXG4gIGlmIChub2RlLmNoaWxkcmVuKSB7XG4gICAgbm9kZS5jaGlsZHJlbi5mb3JFYWNoKChzdWIpID0+IHtcbiAgICAgIHNldERldGFjaGVkKHN1YilcbiAgICB9KVxuICB9XG59XG5cbmZ1bmN0aW9uIHJlbW92ZUlmRXhpc3RlZChub2RlKSB7XG4gIGNvbnN0IGRvYyA9IGluc3RhbmNlTWFwW25vZGUuaW5zdGFuY2VJZF1cbiAgaWYgKGRvYykge1xuICAgIGNvbnN0IGV4aXN0ZWROb2RlID0gZG9jLmdldFJlZihub2RlLnJlZilcbiAgICBpZiAoZXhpc3RlZE5vZGUpIHtcbiAgICAgIGNvbnN0IGV4aXN0ZWRQYXJlbnQgPSBkb2MuZ2V0UmVmKGV4aXN0ZWROb2RlLnBhcmVudFJlZilcbiAgICAgIGlmIChleGlzdGVkUGFyZW50ICYmIGV4aXN0ZWRQYXJlbnQucmVtb3ZlQ2hpbGQpIHtcbiAgICAgICAgZXhpc3RlZFBhcmVudC5yZW1vdmVDaGlsZChleGlzdGVkTm9kZSwgdHJ1ZSlcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuRWxlbWVudC5wcm90b3R5cGUuc2V0QXR0ciA9IGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG4gIGlmICh0aGlzLmF0dHJba2V5XSA9PT0gdmFsdWUpIHtcbiAgICByZXR1cm5cbiAgfVxuICB0aGlzLmF0dHJba2V5XSA9IHZhbHVlXG4gIGlmICh0aGlzLmF0dGFjaGVkKSB7XG4gICAgY29uc3QgcmVuZGVyZXIgPSB0aGlzLmdldFJlbmRlcmVyKClcbiAgICBpZiAocmVuZGVyZXIpIHtcbiAgICAgIHJlbmRlcmVyLnNldEF0dHIodGhpcy5yZWYsIGtleSwgdmFsdWUpXG4gICAgfVxuICB9XG59XG5cbkVsZW1lbnQucHJvdG90eXBlLnNldFN0eWxlID0gZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgaWYgKHRoaXMuc3R5bGVba2V5XSA9PT0gdmFsdWUpIHtcbiAgICByZXR1cm5cbiAgfVxuICB0aGlzLnN0eWxlW2tleV0gPSB2YWx1ZVxuICBpZiAodGhpcy5hdHRhY2hlZCkge1xuICAgIGNvbnN0IHJlbmRlcmVyID0gdGhpcy5nZXRSZW5kZXJlcigpXG4gICAgaWYgKHJlbmRlcmVyKSB7XG4gICAgICByZW5kZXJlci5zZXRTdHlsZSh0aGlzLnJlZiwga2V5LCB2YWx1ZSlcbiAgICB9XG4gIH1cbn1cblxuRWxlbWVudC5wcm90b3R5cGUuc2V0Q2xhc3NTdHlsZSA9IGZ1bmN0aW9uIChjbGFzc1N0eWxlKSB7XG4gIHRoaXMuY2xhc3NTdHlsZSA9IGNsYXNzU3R5bGVcbiAgaWYgKHRoaXMuYXR0YWNoZWQpIHtcbiAgICBjb25zdCByZW5kZXJlciA9IHRoaXMuZ2V0UmVuZGVyZXIoKVxuICAgIGlmIChyZW5kZXJlcikge1xuICAgICAgcmVuZGVyZXIuc2V0U3R5bGVzKHRoaXMucmVmLCB0aGlzLnRvU3R5bGUoKSlcbiAgICB9XG4gIH1cbn1cblxuRWxlbWVudC5wcm90b3R5cGUuYWRkRXZlbnQgPSBmdW5jdGlvbiAodHlwZSwgaGFuZGxlcikge1xuICBjb25zdCBpbmRleCA9IHRoaXMuZXZlbnQuaW5kZXhPZih0eXBlKVxuXG4gIGlmIChpbmRleCA8IDApIHtcbiAgICB0aGlzLmV2ZW50LnB1c2godHlwZSlcbiAgICBsZXQgZXZlbnRNYW5hZ2VyID0gdGhpcy5vd25lckRvY3VtZW50LmV2ZW50TWFuYWdlclxuICAgIGV2ZW50TWFuYWdlci5hZGQodGhpcywgdHlwZSwgaGFuZGxlcilcblxuICAgIGlmICh0aGlzLmF0dGFjaGVkKSB7XG4gICAgICBjb25zdCByZW5kZXJlciA9IHRoaXMuZ2V0UmVuZGVyZXIoKVxuICAgICAgaWYgKHJlbmRlcmVyKSB7XG4gICAgICAgIHJlbmRlcmVyLmFkZEV2ZW50KHRoaXMucmVmLCB0eXBlKVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5FbGVtZW50LnByb3RvdHlwZS5yZW1vdmVFdmVudCA9IGZ1bmN0aW9uICh0eXBlKSB7XG4gIGNvbnN0IGluZGV4ID0gdGhpcy5ldmVudC5pbmRleE9mKHR5cGUpXG5cbiAgaWYgKGluZGV4ID49IDApIHtcbiAgICB0aGlzLmV2ZW50LnNwbGljZShpbmRleCwgMSlcbiAgICBsZXQgZXZlbnRNYW5hZ2VyID0gdGhpcy5vd25lckRvY3VtZW50LmV2ZW50TWFuYWdlclxuICAgIGV2ZW50TWFuYWdlci5yZW1vdmUodGhpcywgdHlwZSlcblxuICAgIGlmICh0aGlzLmF0dGFjaGVkKSB7XG4gICAgICBjb25zdCByZW5kZXJlciA9IHRoaXMuZ2V0UmVuZGVyZXIoKVxuICAgICAgaWYgKHJlbmRlcmVyKSB7XG4gICAgICAgIHJlbmRlcmVyLnJlbW92ZUV2ZW50KHRoaXMucmVmLCB0eXBlKVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5FbGVtZW50LnByb3RvdHlwZS50b1N0eWxlID0gZnVuY3Rpb24gKCkge1xuICBjb25zdCByZXN1bHQgPSB7fVxuICBjb25zdCBjbGFzc1N0eWxlID0gdGhpcy5jbGFzc1N0eWxlXG4gIGNvbnN0IHN0eWxlID0gdGhpcy5zdHlsZVxuICBmb3IgKGNvbnN0IG5hbWUgaW4gY2xhc3NTdHlsZSkge1xuICAgIHJlc3VsdFtuYW1lXSA9IGNsYXNzU3R5bGVbbmFtZV1cbiAgfVxuICBmb3IgKGNvbnN0IG5hbWUgaW4gc3R5bGUpIHtcbiAgICByZXN1bHRbbmFtZV0gPSBzdHlsZVtuYW1lXVxuICB9XG4gIHJldHVybiByZXN1bHRcbn1cblxuRWxlbWVudC5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gKCkge1xuICBjb25zdCByZXN1bHQgPSB7XG4gICAgcmVmOiB0aGlzLnJlZi50b1N0cmluZygpLFxuICAgIHR5cGU6IHRoaXMudHlwZSxcbiAgICBhdHRyOiB0aGlzLmF0dHIsXG4gICAgc3R5bGU6IHRoaXMudG9TdHlsZSgpXG4gIH1cblxuICBpZiAodGhpcy5ldmVudCAmJiB0aGlzLmV2ZW50Lmxlbmd0aCkge1xuICAgIHJlc3VsdC5ldmVudCA9IHRoaXMuZXZlbnRcbiAgfVxuICBpZiAodGhpcy5wdXJlQ2hpbGRyZW4gJiYgdGhpcy5wdXJlQ2hpbGRyZW4ubGVuZ3RoKSB7XG4gICAgcmVzdWx0LmNoaWxkcmVuID0gdGhpcy5wdXJlQ2hpbGRyZW4ubWFwKChjaGlsZCkgPT4gY2hpbGQudG9KU09OKCkpXG4gIH1cblxuICByZXR1cm4gcmVzdWx0XG59XG5cbkVsZW1lbnQucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gJzwnICsgdGhpcy50eXBlICtcbiAgICAnIGF0dHI9JyArIEpTT04uc3RyaW5naWZ5KHRoaXMuYXR0cikgK1xuICAgICcgc3R5bGU9JyArIEpTT04uc3RyaW5naWZ5KHRoaXMudG9TdHlsZSgpKSArICc+JyArXG4gICAgdGhpcy5wdXJlQ2hpbGRyZW4ubWFwKChjaGlsZCkgPT4gY2hpbGQudG9TdHJpbmcoKSkuam9pbignJykgK1xuICAgICc8LycgKyB0aGlzLnR5cGUgKyAnPidcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIENvbW1lbnQodmFsdWUsIG93bmVyRG9jdW1lbnQpIHtcbiAgdGhpcy5jcmVhdGUob3duZXJEb2N1bWVudC5pZClcbiAgdGhpcy50eXBlID0gJ2NvbW1lbnQnXG4gIHRoaXMudmFsdWUgPSB2YWx1ZVxufVxuXG5Db21tZW50LnByb3RvdHlwZSA9IG5ldyBOb2RlKClcblxuQ29tbWVudC5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiAnPCEtLSAnICsgdGhpcy52YWx1ZSArICcgLS0+J1xufVxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9saWIvYXBwL2RvbS5qc1xuICoqLyIsIm1vZHVsZS5leHBvcnRzID0ge1xuXHRcIm5hbWVcIjogXCJ3ZWV4LWpzZnJhbWV3b3JrXCIsXG5cdFwidmVyc2lvblwiOiBcIjAuMTMuN1wiLFxuXHRcImRlc2NyaXB0aW9uXCI6IFwiSlMgRnJhbWV3b3JrIGZvciBXZWV4IHNvbHV0aW9uIHdoaWNoIGlzIGEgZXh0ZW5kYWJsZSBjcm9zcy1wbGF0Zm9ybSBzb2x1dGlvbiBmb3IgZHluYW1pYyBwcm9ncmFtbWluZyBhbmQgcHVibGlzaGluZyBwcm9qZWN0c1wiLFxuXHRcIm1haW5cIjogXCJpbmRleC5qc1wiLFxuXHRcInNjcmlwdHNcIjoge1xuXHRcdFwiZGV2XCI6IFwid2VicGFjayAtLXdhdGNoIC0tY29uZmlnIC4vd2VicGFjay5jb25maWcuanNcIixcblx0XHRcImJ1aWxkXCI6IFwid2VicGFjayAtLWNvbmZpZyAuL3dlYnBhY2suY29uZmlnLmpzXCIsXG5cdFx0XCJjb21wcmVzc1wiOiBcInVnbGlmeWpzIGRpc3QvaW5kZXguanMgLW8gZGlzdC9pbmRleC5taW4uanNcIixcblx0XHRcImxpbnRcIjogXCJqc2NzIC0tY29uZmlnIC5qc2NzcmMgcG9seWZpbGwvKi5qcyBwb2x5ZmlsbC9fX3Rlc3RfXy8qLmpzIGxpYi8qLmpzIGxpYi9fX3Rlc3RfXy8qLmpzIGxpYi9hcHAvKi5qcyBsaWIvYXBwL19fdGVzdF9fLyouanMgbGliL3ZtLyouanMgbGliL3ZtL19fdGVzdF9fLyouanNcIixcblx0XHRcInRlc3RcIjogXCJtb2NoYSAtLWNvbXBpbGVycyBqczpiYWJlbC1jb3JlL3JlZ2lzdGVyIHBvbHlmaWxsL19fdGVzdF9fLyouanMgbGliL19fdGVzdF9fLyouanMgbGliLyoqL19fdGVzdF9fLyouanNcIixcblx0XHRcImNvdmVyXCI6IFwiYmFiZWwtbm9kZSBub2RlX21vZHVsZXMvaXNwYXJ0YS9iaW4vaXNwYXJ0YSBjb3ZlciAtLXJlcG9ydCB0ZXh0IG5vZGVfbW9kdWxlcy9tb2NoYS9iaW4vX21vY2hhIC0tIC0tcmVwb3J0ZXIgZG90IGxpYi9fX3Rlc3RfXy8qLmpzIGxpYi8qKi9fX3Rlc3RfXy8qLmpzXCIsXG5cdFx0XCJjaVwiOiBcIm5wbSBydW4gbGludCAmJiBucG0gcnVuIGNvdmVyXCJcblx0fSxcblx0XCJyZXBvc2l0b3J5XCI6IHtcblx0XHRcInR5cGVcIjogXCJnaXRcIixcblx0XHRcInVybFwiOiBcImdpdEBnaXRodWIuY29tOmFsaWJhYmEvd2VleC5naXRcIlxuXHR9LFxuXHRcImF1dGhvclwiOiBbXG5cdFx0e1xuXHRcdFx0XCJuYW1lXCI6IFwiamluamlhbmdcIixcblx0XHRcdFwiZW1haWxcIjogXCJ6aGFvamluamlhbmdAbWUuY29tXCJcblx0XHR9LFxuXHRcdHtcblx0XHRcdFwibmFtZVwiOiBcIlRlcnJ5IEtpbmdcIixcblx0XHRcdFwiZW1haWxcIjogXCJ0ZXJyeWtpbmdjaGFAZ21haWwuY29tXCJcblx0XHR9XG5cdF0sXG5cdFwiY29udHJpYnV0b3JzXCI6IFtcblx0XHR7XG5cdFx0XHRcIm5hbWVcIjogXCJwdXNoaW1pbmdcIixcblx0XHRcdFwiZW1haWxcIjogXCJwdXNoaW1pbmdAZ21haWwuY29tXCJcblx0XHR9LFxuXHRcdHtcblx0XHRcdFwibmFtZVwiOiBcImlza2VuaHVhbmdcIixcblx0XHRcdFwiZW1haWxcIjogXCJpc2tlbmh1YW5nQGdtYWlsLmNvbVwiXG5cdFx0fSxcblx0XHR7XG5cdFx0XHRcIm5hbWVcIjogXCJ5dWFueWFuXCIsXG5cdFx0XHRcImVtYWlsXCI6IFwieXVhbnlhbi5jYW9AZ21haWwuY29tXCJcblx0XHR9XG5cdF0sXG5cdFwia2V5d29yZHNcIjogW1xuXHRcdFwid2VleFwiLFxuXHRcdFwibXZ2bVwiLFxuXHRcdFwiYnJvd3NlclwiLFxuXHRcdFwiaHlicmlkXCIsXG5cdFx0XCJmcmFtZXdvcmtcIlxuXHRdLFxuXHRcImxpY2Vuc2VcIjogXCJBcGFjaGUtMi4wXCIsXG5cdFwiZGVwZW5kZW5jaWVzXCI6IHtcblx0XHRcInNlbXZlclwiOiBcIn41LjEuMFwiLFxuXHRcdFwiY29yZS1qc1wiOiBcIn4yLjEuMVwiXG5cdH0sXG5cdFwiZGV2RGVwZW5kZW5jaWVzXCI6IHtcblx0XHRcImJhYmVsLWNsaVwiOiBcIn42LjQuNVwiLFxuXHRcdFwiYmFiZWwtY29yZVwiOiBcIn42LjQuNVwiLFxuXHRcdFwiYmFiZWwtbG9hZGVyXCI6IFwifjYuMi4xXCIsXG5cdFx0XCJiYWJlbC1wcmVzZXQtZXMyMDE1XCI6IFwifjYuMy4xM1wiLFxuXHRcdFwiY2hhaVwiOiBcIn4zLjIuMFwiLFxuXHRcdFwiaXNwYXJ0YVwiOiBcIn40LjAuMFwiLFxuXHRcdFwiaXN0YW5idWxcIjogXCJ+MC40LjJcIixcblx0XHRcImpzY3NcIjogXCJ+Mi45LjBcIixcblx0XHRcImpzb24tbG9hZGVyXCI6IFwiXjAuNS40XCIsXG5cdFx0XCJtb2NoYVwiOiBcIn4yLjMuNFwiLFxuXHRcdFwic2lub25cIjogXCJ+MS4xNy4yXCIsXG5cdFx0XCJzaW5vbi1jaGFpXCI6IFwifjIuOC4wXCIsXG5cdFx0XCJ1Z2xpZnktanNcIjogXCJeMi42LjJcIixcblx0XHRcIndhdGNoLWNsaVwiOiBcIn4wLjIuMVwiLFxuXHRcdFwid2VicGFja1wiOiBcIn4xLjEyLjEyXCJcblx0fSxcblx0XCJvcHRpb25hbERlcGVuZGVuY2llc1wiOiB7XG5cdFx0XCJ3ZWV4LXRyYW5zZm9ybWVyXCI6IFwifjAuM1wiXG5cdH1cbn07XG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL3BhY2thZ2UuanNvblxuICoqIG1vZHVsZSBpZCA9IDEwNVxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLyoqXG4gKiBAZmlsZU92ZXJ2aWV3IFRoZSBhcGkgZm9yIGludm9raW5nIHdpdGggXCIkXCIgcHJlZml4XG4gKi9cbmltcG9ydCB7dHlwb2YsIGV4dGVuZH0gZnJvbSAnLi4vdXRpbCdcblxuLyoqXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBjb21tb25cbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG4vKipcbiAqIEBkZXByZWNhdGVkIHVzZSAkdm0gaW5zdGVhZFxuICogZmluZCB0aGUgdm0gYnkgaWRcbiAqIE5vdGU6IHRoZXJlIGlzIG9ubHkgb25lIGlkIGluIHdob2xlIGNvbXBvbmVudFxuICogQHBhcmFtICB7c3RyaW5nfSBpZFxuICogQHJldHVybiB7Vm19XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiAkKGlkKSB7XG4gIG5hdGl2ZUxvZygnW1dBUk5JTkddIHRoZSBWbSMkIGFwaSBpcyBkZXByZWNhdGVkLCBwbGVhc2UgdXNlIFZtIyR2bSBpbnN0ZWFkJylcbiAgY29uc3QgaW5mbyA9IHRoaXMuX2lkc1tpZF1cbiAgaWYgKGluZm8pIHtcbiAgICByZXR1cm4gaW5mby52bVxuICB9XG59XG5cbi8qKlxuICogZmluZCB0aGUgZWxlbWVudCBieSBpZFxuICogTm90ZTogdGhlcmUgaXMgb25seSBvbmUgaWQgaW4gd2hvbGUgY29tcG9uZW50XG4gKiBAcGFyYW0gIHtzdHJpbmd9IGlkXG4gKiBAcmV0dXJuIHtFbGVtZW50fVxuICovXG5leHBvcnQgZnVuY3Rpb24gJGVsKGlkKSB7XG4gIGNvbnN0IGluZm8gPSB0aGlzLl9pZHNbaWRdXG4gIGlmIChpbmZvKSB7XG4gICAgcmV0dXJuIGluZm8uZWxcbiAgfVxufVxuXG4vKipcbiAqIGZpbmQgdGhlIHZtIG9mIHRoZSBjdXN0b20gY29tcG9uZW50IGJ5IGlkXG4gKiBOb3RlOiB0aGVyZSBpcyBvbmx5IG9uZSBpZCBpbiB3aG9sZSBjb21wb25lbnRcbiAqIEBwYXJhbSAge3N0cmluZ30gaWRcbiAqIEByZXR1cm4ge1ZtfVxuICovXG5leHBvcnQgZnVuY3Rpb24gJHZtKGlkKSB7XG4gIGNvbnN0IGluZm8gPSB0aGlzLl9pZHNbaWRdXG4gIGlmIChpbmZvKSB7XG4gICAgcmV0dXJuIGluZm8udm1cbiAgfVxufVxuXG4vKipcbiAqIEZpcmUgd2hlbiBkaWZmZXIgcmVuZGVyaW5nIGZpbmlzaGVkXG4gKlxuICogQHBhcmFtICB7RnVuY3Rpb259IGZuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiAkcmVuZGVyVGhlbihmbikge1xuICBjb25zdCBhcHAgPSB0aGlzLl9hcHBcbiAgY29uc3QgZGlmZmVyID0gYXBwLmRpZmZlclxuICByZXR1cm4gZGlmZmVyLnRoZW4oKCkgPT4ge1xuICAgIGZuKClcbiAgfSlcbn1cblxuLyoqXG4gKiBzY3JvbGwgYW4gZWxlbWVudCBzcGVjaWZpZWQgYnkgaWQgaW50byB2aWV3LCBcbiAqIG1vcmVvdmVyIHNwZWNpZnkgYSBudW1iZXIgb2Ygb2Zmc2V0IG9wdGlvbmFsbHlcbiAqIEBwYXJhbSAge3N0cmluZ30gaWRcbiAqIEBwYXJhbSAge251bWJlcn0gb2Zmc2V0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiAkc2Nyb2xsVG8oaWQsIG9mZnNldCkge1xuICBjb25zdCBlbCA9IHRoaXMuJGVsKGlkKVxuICBpZiAoZWwpIHtcbiAgICBjb25zdCBkb20gPSB0aGlzLl9hcHAucmVxdWlyZU1vZHVsZSgnZG9tJylcbiAgICBkb20uc2Nyb2xsVG9FbGVtZW50KGVsLnJlZiwge29mZnNldDogb2Zmc2V0fSlcbiAgfVxufVxuXG4vKipcbiAqIHBlcmZvcm0gdHJhbnNpdGlvbiBhbmltYXRpb24gb24gYW4gZWxlbWVudCBzcGVjaWZpZWQgYnkgaWRcbiAqIEBwYXJhbSAge3N0cmluZ30gICBpZFxuICogQHBhcmFtICB7b2JqZWN0fSAgIG9wdGlvbnNcbiAqIEBwYXJhbSAge29iamVjdH0gICBvcHRpb25zLnN0eWxlc1xuICogQHBhcmFtICB7b2JqZWN0fSAgIG9wdGlvbnMuZHVyYXRpb24obXMpXG4gKiBAcGFyYW0gIHtvYmplY3R9ICAgW29wdGlvbnMudGltaW5nRnVuY3Rpb25dXG4gKiBAcGFyYW0gIHtvYmplY3R9ICAgW29wdGlvbnMuZGVsYXk9MChtcyldXG4gKiBAcGFyYW0gIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uICR0cmFuc2l0aW9uKGlkLCBvcHRpb25zLCBjYWxsYmFjaykge1xuICBjb25zdCBlbCA9IHRoaXMuJGVsKGlkKVxuICBpZiAoZWwgJiYgb3B0aW9ucyAmJiBvcHRpb25zLnN0eWxlcykge1xuICAgIGNvbnN0IGFuaW1hdGlvbiA9IHRoaXMuX2FwcC5yZXF1aXJlTW9kdWxlKCdhbmltYXRpb24nKVxuICAgIGFuaW1hdGlvbi50cmFuc2l0aW9uKGVsLnJlZiwgb3B0aW9ucywgKC4uLmFyZ3MpID0+IHtcbiAgICAgIHRoaXMuX3NldFN0eWxlKGVsLCBvcHRpb25zLnN0eWxlcylcbiAgICAgIGNhbGxiYWNrICYmIGNhbGxiYWNrKC4uLmFyZ3MpXG4gICAgfSlcbiAgfVxufVxuXG4vKipcbiAqIGdldCBzb21lIGNvbmZpZ1xuICogQHJldHVybiB7b2JqZWN0fSBzb21lIGNvbmZpZyBmb3IgYXBwIGluc3RhbmNlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gYnVuZGxlVXJsXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IGRlYnVnXG4gKiBAcHJvcGVydHkge29iamVjdH0gZW52XG4gKiBAcHJvcGVydHkge3N0cmluZ30gZW52LndlZXhWZXJzaW9uKGV4LiAxLjAuMClcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBlbnYuYXBwTmFtZShleC4gVEIvVE0pXG4gKiBAcHJvcGVydHkge3N0cmluZ30gZW52LmFwcFZlcnNpb24oZXguIDUuMC4wKVxuICogQHByb3BlcnR5IHtzdHJpbmd9IGVudi5wbGF0Zm9ybShleC4gaU9TL0FuZHJvaWQpXG4gKiBAcHJvcGVydHkge3N0cmluZ30gZW52Lm9zVmVyc2lvbihleC4gNy4wLjApXG4gKiBAcHJvcGVydHkge3N0cmluZ30gZW52LmRldmljZU1vZGVsICoqbmF0aXZlIG9ubHkqKlxuICogQHByb3BlcnR5IHtudW1iZXJ9IGVudi5bZGV2aWNlV2lkdGg9NzUwXVxuICogQHByb3BlcnR5IHtudW1iZXJ9IGVudi5kZXZpY2VIZWlnaHRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uICRnZXRDb25maWcoY2FsbGJhY2spIHtcbiAgY29uc3QgY29uZmlnID0gZXh0ZW5kKHtcbiAgICBlbnY6IGdsb2JhbC5XWEVudmlyb25tZW50IHx8IHt9XG4gIH0sIHRoaXMuX2FwcC5vcHRpb25zKVxuICBpZiAodHlwb2YoY2FsbGJhY2spID09PSAnZnVuY3Rpb24nKSB7XG4gICAgbmF0aXZlTG9nKCdbV0FSTklOR10gdGhlIGNhbGxiYWNrIG9mIFZtIyRnZXRDb25maWcoY2FsbGJhY2spIGlzIGRlcHJlY2F0ZWQsICcgK1xuICAgICAgJ3RoaXMgYXBpIG5vdyBjYW4gZGlyZWN0bHkgUkVUVVJOIGNvbmZpZyBpbmZvLicpXG4gICAgY2FsbGJhY2soY29uZmlnKVxuICB9XG4gIHJldHVybiBjb25maWdcbn1cblxuLyoqXG4gKiByZXF1ZXN0IG5ldHdvcmsgdmlhIGh0dHAgcHJvdG9jb2xcbiAqIEBwYXJhbSAge29iamVjdH0gICBwYXJhbXNcbiAqIEBwYXJhbSAge0Z1bmN0aW9ufSBjYWxsYmFja1xuICovXG5leHBvcnQgZnVuY3Rpb24gJHNlbmRIdHRwKHBhcmFtcywgY2FsbGJhY2spIHtcbiAgY29uc3Qgc3RyZWFtID0gdGhpcy5fYXBwLnJlcXVpcmVNb2R1bGUoJ3N0cmVhbScpXG4gIHN0cmVhbS5zZW5kSHR0cChwYXJhbXMsIGNhbGxiYWNrKVxufVxuXG4vKipcbiAqIG9wZW4gYSB1cmxcbiAqIEBwYXJhbSAge3N0cmluZ30gdXJsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiAkb3BlblVSTCh1cmwpIHtcbiAgY29uc3QgZXZlbnQgPSB0aGlzLl9hcHAucmVxdWlyZU1vZHVsZSgnZXZlbnQnKVxuICBldmVudC5vcGVuVVJMKHVybClcbn1cblxuLyoqXG4gKiBzZXQgYSB0aXRsZSBmb3IgcGFnZVxuICogQHBhcmFtICB7c3RyaW5nfSB0aXRsZVxuICovXG5leHBvcnQgZnVuY3Rpb24gJHNldFRpdGxlKHRpdGxlKSB7XG4gIGNvbnN0IHBhZ2VJbmZvID0gdGhpcy5fYXBwLnJlcXVpcmVNb2R1bGUoJ3BhZ2VJbmZvJylcbiAgcGFnZUluZm8uc2V0VGl0bGUodGl0bGUpXG59XG5cbi8qKlxuICogaW52b2tlIGEgbmF0aXZlIG1ldGhvZCBieSBzcGVjaWZpbmcgdGhlIG5hbWUgb2YgbW9kdWxlIGFuZCBtZXRob2RcbiAqIEBwYXJhbSAge3N0cmluZ30gbW9kdWxlTmFtZVxuICogQHBhcmFtICB7c3RyaW5nfSBtZXRob2ROYW1lXG4gKiBAcGFyYW0gIHsuLi4qfSB0aGUgcmVzdCBhcmd1bWVudHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uICRjYWxsKG1vZHVsZU5hbWUsIG1ldGhvZE5hbWUsIC4uLmFyZ3MpIHtcbiAgY29uc3QgbW9kdWxlID0gdGhpcy5fYXBwLnJlcXVpcmVNb2R1bGUobW9kdWxlTmFtZSlcbiAgaWYgKG1vZHVsZSAmJiBtb2R1bGVbbWV0aG9kTmFtZV0pIHtcbiAgICBtb2R1bGVbbWV0aG9kTmFtZV0oLi4uYXJncylcbiAgfVxufVxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9saWIvYXBpL21ldGhvZHMuanNcbiAqKi8iXSwic291cmNlUm9vdCI6IiJ9
\ No newline at end of file
diff --git a/test/spec/a.we b/test/spec/a.we
new file mode 100644
index 0000000..1335e77
--- /dev/null
+++ b/test/spec/a.we
@@ -0,0 +1,3 @@
+<template>
+    <div><text>Hello Weex</text></div>
+</template>
\ No newline at end of file
diff --git a/test/spec/b.we b/test/spec/b.we
new file mode 100644
index 0000000..603ef5c
--- /dev/null
+++ b/test/spec/b.we
@@ -0,0 +1,10 @@
+<template>
+    <div><text class="hi">Hello Weex</text></div>
+</template>
+
+<style>
+.hi {
+    font-size: 26px;
+    color: red;
+}
+</style>
\ No newline at end of file
diff --git a/test/spec/c.we b/test/spec/c.we
new file mode 100644
index 0000000..874fdb7
--- /dev/null
+++ b/test/spec/c.we
@@ -0,0 +1,22 @@
+<template>
+    <div>
+        <text class="hello">Hello {{name}}</text>
+    </div>
+</template>
+
+
+<style>
+.hello {
+    font-size: 26px;
+    color: red;
+}
+</style>
+
+
+<script>
+export function data() {
+    return {
+        name: 'Weex'
+    }
+}
+</script>
\ No newline at end of file
diff --git a/test/spec/d.we b/test/spec/d.we
new file mode 100644
index 0000000..8d6c8f1
--- /dev/null
+++ b/test/spec/d.we
@@ -0,0 +1,46 @@
+<element name="name">
+    <template>
+        <div><text class="name">{{name}}</text></div>
+    </template>
+
+    <style>
+    .name {
+        font-size: 26px;
+        color: red;
+    }
+    </style>
+
+    <script>
+    module.exports = {
+        data: function() {
+            return {
+                name: ''
+            }
+        }
+    }
+    </script>
+</element>
+
+<template>
+    <div style="flex-direction: row;">
+        <text class="hello">Hello</text>
+        <name name="{{name}}"></name>
+    </div>
+</template>
+
+
+<style>
+.hello {
+    font-size: 26px;
+    color: green;
+}
+</style>
+
+
+<script>
+export function data() {
+    return {
+        name: 'Weex'
+    }
+}
+</script>
\ No newline at end of file
diff --git a/test/spec/data.json b/test/spec/data.json
new file mode 100644
index 0000000..b8e9b40
--- /dev/null
+++ b/test/spec/data.json
@@ -0,0 +1,3 @@
+{
+    "name": "Weex"
+}
\ No newline at end of file
diff --git a/test/spec/e.we b/test/spec/e.we
new file mode 100644
index 0000000..8e287cc
--- /dev/null
+++ b/test/spec/e.we
@@ -0,0 +1,61 @@
+<element name="hi">
+    <template>
+        <div><text class="hi">{{hi}}</text></div>
+    </template>
+
+    <style>
+    .hi {
+        font-size: 26px;
+        color: green;
+    }
+    </style>
+
+    <script>
+    module.exports = {
+        data: function() {
+            return {
+                hi: ''
+            }
+        }
+    }
+    </script>
+</element>
+
+<element name="name">
+    <template>
+        <div><text class="name">{{name}}</text></div>
+    </template>
+
+    <style>
+    .name {
+        font-size: 26px;
+        color: red;
+    }
+    </style>
+
+    <script>
+    module.exports = {
+        data: function() {
+            return {
+                name: ''
+            }
+        }
+    }
+    </script>
+</element>
+
+<template>
+    <div style="flex-direction: row;">
+        <hi hi="{{hi}}"></hi>
+        <name name="{{name}}"></name>
+    </div>
+</template>
+
+<script>
+export function data() {
+    return {
+        hi: 'Hello',
+        name: 'Weex'
+    }
+}
+</script>
\ No newline at end of file
diff --git a/test/spec/f.css b/test/spec/f.css
new file mode 100644
index 0000000..11d03bc
--- /dev/null
+++ b/test/spec/f.css
@@ -0,0 +1,3 @@
+.wrap {
+    flex-direction: row;
+}
\ No newline at end of file
diff --git a/test/spec/f.html b/test/spec/f.html
new file mode 100644
index 0000000..3229bc9
--- /dev/null
+++ b/test/spec/f.html
@@ -0,0 +1,4 @@
+<div class="wrap">
+    <hi hi="{{hi}}"></hi>
+    <name name="{{name}}"></name>
+</div>  
\ No newline at end of file
diff --git a/test/spec/f.js b/test/spec/f.js
new file mode 100644
index 0000000..65d0da9
--- /dev/null
+++ b/test/spec/f.js
@@ -0,0 +1,6 @@
+export function data() {
+    return {
+        hi: 'Hello',
+        name: 'Weex'
+    }
+}
\ No newline at end of file
diff --git a/test/spec/f.we b/test/spec/f.we
new file mode 100644
index 0000000..b955e53
--- /dev/null
+++ b/test/spec/f.we
@@ -0,0 +1,5 @@
+<element name="hi" src="./hi.we"></element>
+<element name="name" src="./name.we"></element>
+<template src="./f.html"></template>
+<style src="./f.css"></style>
+<script src="./f.js"></script>
\ No newline at end of file
diff --git a/test/spec/g.we b/test/spec/g.we
new file mode 100644
index 0000000..f4c462e
--- /dev/null
+++ b/test/spec/g.we
@@ -0,0 +1,27 @@
+<element name="name1" src="./name.we"></element>
+
+<template>
+    <div class="wrap">
+        <hi1 hi="{{hi}}"></hi1>
+        <name1 name="{{name}}"></name1>
+    </div>
+</template>
+
+<style>
+    .wrap {
+        flex-direction: row;
+    }
+</style>
+
+<script>
+import './hi.we?name=hi1'
+
+export default {
+    data() {
+        return {
+            hi: 'Hello',
+            name: 'Weex'
+        }
+    }
+}
+</script>
\ No newline at end of file
diff --git a/test/spec/getName.js b/test/spec/getName.js
new file mode 100644
index 0000000..8ef944c
--- /dev/null
+++ b/test/spec/getName.js
@@ -0,0 +1 @@
+export default () => 'Weex'
\ No newline at end of file
diff --git a/test/spec/h.we b/test/spec/h.we
new file mode 100644
index 0000000..45ef9fa
--- /dev/null
+++ b/test/spec/h.we
@@ -0,0 +1,23 @@
+<template>
+    <div class="wrap">
+        <hi hi="{{hi}}"></hi>
+        <name name="{{name}}"></name>
+    </div>
+</template>
+
+<style>
+    .wrap {
+        flex-direction: row;
+    }
+</style>
+
+<script>
+export default {
+    data() {
+        return {
+            hi: 'Hello',
+            name: 'Weex'
+        }
+    }
+}
+</script>
\ No newline at end of file
diff --git a/test/spec/hi.we b/test/spec/hi.we
new file mode 100644
index 0000000..88dbef1
--- /dev/null
+++ b/test/spec/hi.we
@@ -0,0 +1,20 @@
+<template>
+    <div><text class="hi">{{hi}}</text></div>
+</template>
+
+<style>
+.hi {
+    font-size: 26px;
+    color: green;
+}
+</style>
+
+<script>
+export default {
+    data() {
+        return {
+            hi: ''
+        }
+    }
+}
+</script>
\ No newline at end of file
diff --git a/test/spec/i.we b/test/spec/i.we
new file mode 100644
index 0000000..f0fc21f
--- /dev/null
+++ b/test/spec/i.we
@@ -0,0 +1,22 @@
+<template>
+    <div>
+        <text class="hello">Hello {{name}}</text>
+    </div>
+</template>
+
+
+<style>
+.hello {
+    font-size: 26px;
+    color: red;
+}
+</style>
+
+
+<script type="config">
+{
+    downgrade: true
+}
+</script>
+
+<script type="data" src="./data.json"></script>
\ No newline at end of file
diff --git a/test/spec/j.we b/test/spec/j.we
new file mode 100644
index 0000000..75d7cf9
--- /dev/null
+++ b/test/spec/j.we
@@ -0,0 +1,28 @@
+<template>
+    <div class="wrap">
+        <text>{{hi}}</text>
+        <text>{{name}}</text>
+    </div>
+</template>
+
+<style>
+    .wrap {
+        flex-direction: row;
+    }
+</style>
+
+<script>
+import modal from '@weex-module/modal'
+
+export default {
+    ready() {
+        modal.toast({'message': 'ready'})
+    },
+    data() {
+        return {
+            hi: 'Hello',
+            name: 'Weex'
+        }
+    }
+}
+</script>
\ No newline at end of file
diff --git a/test/spec/k.we b/test/spec/k.we
new file mode 100644
index 0000000..88b1443
--- /dev/null
+++ b/test/spec/k.we
@@ -0,0 +1,43 @@
+<template lang="jade">
+.wrap
+    text.text-hi {{hi}}
+    text.text-name {{name}}
+</template>
+
+<style lang="cssnext">
+    :root {
+        --mainColor: red;
+        --subColor: green;
+        --normalFont: {
+            font-size: 26px;
+        };
+    }
+
+    .wrap {
+        flex-direction: row;
+    }
+
+    .text-hi {
+        color: var(--mainColor);
+        @apply --normalFont;
+    }
+
+    .text-name {
+        color: var(--subColor);
+        @apply --normalFont;
+    }
+</style>
+
+<script lang="coffee">
+modal = require '@weex-module/modal'
+
+module.exports = 
+    ready: () -> 
+        modal.toast({'message': 'ready'})
+
+    data: () ->
+        return {
+            hi: 'Hello',
+            name: 'Weex'
+        }
+</script>
\ No newline at end of file
diff --git a/test/spec/l.we b/test/spec/l.we
new file mode 100644
index 0000000..95d14cc
--- /dev/null
+++ b/test/spec/l.we
@@ -0,0 +1,29 @@
+<template>
+    <div>
+        <text class="hello">Hello {{name}}</text>
+    </div>
+</template>
+
+
+<style>
+.hello {
+    font-size: 26px;
+    color: red;
+}
+</style>
+
+
+<script>
+import modal from '@weex-module/modal'
+import getName from './getName.js'
+
+export function ready() {
+    modal.toast({message: this.name})
+}
+
+export function data() {
+    return {
+        name: getName()
+    }
+}
+</script>
\ No newline at end of file
diff --git a/test/spec/m.we b/test/spec/m.we
new file mode 100644
index 0000000..7f25542
--- /dev/null
+++ b/test/spec/m.we
@@ -0,0 +1,29 @@
+<template>
+    <div>
+        <text class="hello">Hello {{name}}</text>
+    </div>
+</template>
+
+
+<style>
+.hello {
+    font-size: 26px;
+    color: red;
+}
+</style>
+
+
+<script>
+import toast from './toast.js'
+
+export default {
+    ready() {
+        toast(this.name)
+    },
+    data() {
+        return {
+            name: 'Weex'
+        }
+    }
+}
+</script>
\ No newline at end of file
diff --git a/test/spec/n.we b/test/spec/n.we
new file mode 100644
index 0000000..b0b7292
--- /dev/null
+++ b/test/spec/n.we
@@ -0,0 +1,37 @@
+<element name="hi">
+<template>
+    <div><text class="hi">{{hi}}</text></div>
+</template>
+
+<style>
+.hi {
+    font-size: 26px;
+    color: green;
+}
+</style>
+
+<script>
+export default {
+    data() {
+        console.log('Hi Component Comment')
+        return {
+            hi: ''
+        }
+    }
+}
+</script>
+</element>
+
+<element name="name" src="./name.we"></element>
+
+<template src="./f.html"></template>
+<style src="./f.css"></style>
+<script>
+export function data() {
+    console.log('N comment')
+    return {
+        hi: 'Hello',
+        name: 'Weex'
+    }
+}
+</script>
\ No newline at end of file
diff --git a/test/spec/name.css b/test/spec/name.css
new file mode 100644
index 0000000..3c6e476
--- /dev/null
+++ b/test/spec/name.css
@@ -0,0 +1,4 @@
+.name {
+    font-size: 26px;
+    color: red;
+}
\ No newline at end of file
diff --git a/test/spec/name.html b/test/spec/name.html
new file mode 100644
index 0000000..258e5e5
--- /dev/null
+++ b/test/spec/name.html
@@ -0,0 +1 @@
+<div><text class="name">{{name}}</text></div>
diff --git a/test/spec/name.js b/test/spec/name.js
new file mode 100644
index 0000000..d52e553
--- /dev/null
+++ b/test/spec/name.js
@@ -0,0 +1,8 @@
+export default {
+    data() {
+        console.log('Name Component Comment')
+        return {
+            name: ''
+        }
+    }
+}
\ No newline at end of file
diff --git a/test/spec/name.we b/test/spec/name.we
new file mode 100644
index 0000000..efa318e
--- /dev/null
+++ b/test/spec/name.we
@@ -0,0 +1,3 @@
+<template src="./name.html"></template>
+<style src="./name.css"></style>
+<script src="./name.js"></script>
\ No newline at end of file
diff --git a/test/spec/toast.js b/test/spec/toast.js
new file mode 100644
index 0000000..af59d1b
--- /dev/null
+++ b/test/spec/toast.js
@@ -0,0 +1,8 @@
+var modal
+__weex_define__('@weex-component/toast', [], function(__weex_require__) {
+    modal = __weex_require__('@weex-module/modal')
+})
+
+module.exports = function(msg) {
+    modal.toast({message: msg})
+}
\ No newline at end of file
diff --git a/test/test.js b/test/test.js
index fb27960..575cb60 100644
--- a/test/test.js
+++ b/test/test.js
@@ -1,161 +1,164 @@
-var fs = require('fs');
-var path =require('path');
+'use strict';
 
-var chai = require('chai');
-var sinon = require('sinon');
-var sinonChai = require('sinon-chai');
-var expect = chai.expect;
+const fs = require('fs');
+const path =require('path');
+
+const chai = require('chai');
+const sinon = require('sinon');
+const sinonChai = require('sinon-chai');
+const expect = chai.expect;
 chai.use(sinonChai);
 
-var webpack = require('webpack')
-var SourceMapConsumer = require('source-map').SourceMapConsumer
-
-require('./lib/jsfm');
-var createInstance = global.createInstance;
-var getRoot = global.getRoot;
-
-describe('loader', () => {
-
-  before(function() {
-    global.callNative = sinon.spy();
-  });
-
-  after(function() {
-    global.callNative = undefined;
-  });
-
-  it('simple case', function() {
-    var name = 'a.js';
-
-    var actualCodePath = path.resolve(__dirname, 'actual', name);
-    var actualCodeContent = fs.readFileSync(actualCodePath, { encoding: 'utf8' });
-
-    var expectCodePath = path.resolve(__dirname, 'expect', name);
-    var expectCodeContent = fs.readFileSync(expectCodePath, { encoding: 'utf8' });
+const Base64 = require('js-base64').Base64;
+const SourceMap = require('source-map');
 
 
-    var actualResult = createInstance('actual/' + name, actualCodeContent);
-    var actualJson = getRoot('actual/' + name);
 
-    var expectResult = createInstance('expect/' + name, expectCodeContent);
-    var expectJson = getRoot('expect/' + name);
+function getActualString(name) {
+  const filepath = path.resolve(__dirname, 'actual', `${name}.js`);
+  const result = fs.readFileSync(filepath, 'utf-8');
+  return result.toString();
+} 
 
-    expect(actualJson).eql(expectJson);
-  });
+function getExpectJSON(name) {
+  const filepath = path.resolve(__dirname, 'expect', `${name}.js`);
+  const result = fs.readFileSync(filepath, 'utf-8');
+  return JSON.parse(result.toString());
+}
 
-  it('element tag, 3rd-party js, implicit component', function() {
-    var name = 'b.js';
+function stringifyActual(json) {
+  return JSON.stringify(json, function(key, value) {
+    if (typeof value === 'function') {
+      value = value.toString();
+    }
+    return value;
+  }, '  ');
+}
 
-    var actualCodePath = path.resolve(__dirname, 'actual', name);
-    var actualCodeContent = fs.readFileSync(actualCodePath, { encoding: 'utf8' });
+function extractMap(actualStr) {
+  const mapStr = actualStr.match(/\/\/\# sourceMappingURL=data:application\/json;charset=utf-8;base64,([0-9a-zA-Z=+\/]+)/)
+  if (mapStr) {
+    return JSON.parse(Base64.decode(mapStr[1]));
+  }
+}
 
-    var expectCodePath = path.resolve(__dirname, 'expect', name);
-    var expectCodeContent = fs.readFileSync(expectCodePath, { encoding: 'utf8' });
+describe('build', () => {
+  let __weex_define__;
+  let __weex_bootstrap__;
+  let components;
+  let requireStub;
+  let bootstrapStub;
 
+  function expectActual(name) {
+    const actualStr = getActualString(name);
+    const fn = new Function('__weex_define__', '__weex_bootstrap__', actualStr);
+    fn(__weex_define__, __weex_bootstrap__);
 
-    var actualResult = createInstance('actual/' + name, actualCodeContent);
-    var actualJson = getRoot('actual/' + name);
+    // const filepath = path.resolve(__dirname, 'expect', `${name}.js`);
+    // fs.writeFileSync(filepath, stringifyActual(components), 'utf-8');
 
-    var expectResult = createInstance('expect/' + name, expectCodeContent);
-    var expectJson = getRoot('expect/' + name);
+    const expectJSON = getExpectJSON(name);
+    expect(JSON.parse(stringifyActual(components))).eql(expectJSON);
+    expect(components).to.include.keys(__weex_bootstrap__.firstCall.args[0]);
 
-    expect(actualJson).eql(expectJson);
-  });
+    return actualStr;
+  }
 
-  it('with config & data case', function() {
-    var name = 'z.js';
+  beforeEach(() => {
+    components = {};
+    requireStub = sinon.stub();
+    bootstrapStub = sinon.stub();
 
-    var actualCodePath = path.resolve(__dirname, 'actual', name);
-    var actualCodeContent = fs.readFileSync(actualCodePath, { encoding: 'utf8' });
+    __weex_define__ = function(componentName, deps, factory) {
+      var __weex_require__ = requireStub;
+      var __weex_exports__ = {};
+      var __weex_module__ = {exports : __weex_exports__}
 
-    var expectCodePath = path.resolve(__dirname, 'expect', name);
-    var expectCodeContent = fs.readFileSync(expectCodePath, { encoding: 'utf8' });
-
-
-    var actualResult = createInstance('actual/' + name, actualCodeContent);
-    var actualJson = getRoot('actual/' + name);
-
-    var expectResult = createInstance('expect/' + name, expectCodeContent);
-    var expectJson = getRoot('expect/' + name);
-
-    expect(actualJson).eql(expectJson);
-  });
-
-  it('ignore include same name element file', function() {
-    var name = 'samename.js';
-
-    var actualCodePath = path.resolve(__dirname, 'actual', name);
-    var actualCodeContent = fs.readFileSync(actualCodePath, { encoding: 'utf8' });
-
-    var matches = actualCodeContent.match(/"type"\: "samename"/g)
-    expect(matches.length).eql(1);
-  });
-
-  it('support source map', function() {
-    var name = 'sourcemap'
-
-    var mapPath = path.resolve(__dirname, 'actual', name + '.js.map');
-    var map = fs.readFileSync(mapPath, { encoding: 'utf8' });
-    var smc = new SourceMapConsumer(JSON.parse(map))
-
-    var oriPath = path.resolve(__dirname, 'expect', name + '.we');
-    var ori = fs.readFileSync(oriPath, { encoding: 'utf8' });
-
-    var genPath = path.resolve(__dirname, 'actual', name + '.js');
-    var gen = fs.readFileSync(genPath, { encoding: 'utf8' });
-
-    function matchPos(code, regexp) {
-      var line, col
-      code.split(/\r?\n/g).some(function (l, i) {
-        if (regexp.test(l)) {
-          line = i + 1
-          col = l.length
-          return true
-        }
-      })
-      return { line: line, col: col }
+      factory(__weex_require__, __weex_exports__, __weex_module__)
+      components[componentName] = __weex_module__.exports
     }
 
-    function checkPos(regexp) {
-      var genPos = matchPos(gen, regexp)
-      var oriPos = matchPos(ori, regexp)
+    __weex_bootstrap__ = bootstrapStub;
 
-      var pos = smc.originalPositionFor({
-        line: genPos.line,
-        column: genPos.col
-      })
-
-      expect(pos.source.indexOf('sourcemap.we') > -1)
-      expect(pos.line).to.equal(oriPos.line)
-    }
-
-    checkPos(/console\.log\(1\)/)
-    checkPos(/console\.log\(2\)/)
-    checkPos(/console\.log\(4\)/)
-    checkPos(/console\.log\(5\)/)
-    checkPos(/console\.log\(6\)/)
-    checkPos(/console\.log\(7\)/)
-    checkPos(/console\.log\(8\)/)
-    checkPos(/console\.log\(9\)/)
-    checkPos(/console\.log\(0\)/)
-  })
-
-  it('exports case', function() {
-    var name = 'exports.js';
-
-    var actualCodePath = path.resolve(__dirname, 'actual', name);
-    var actualCodeContent = fs.readFileSync(actualCodePath, { encoding: 'utf8' });
-
-    var expectCodePath = path.resolve(__dirname, 'expect', name);
-    var expectCodeContent = fs.readFileSync(expectCodePath, { encoding: 'utf8' });
-
-
-    var actualResult = createInstance('actual/' + name, actualCodeContent);
-    var actualJson = getRoot('actual/' + name);
-
-    var expectResult = createInstance('expect/' + name, expectCodeContent);
-    var expectJson = getRoot('expect/' + name);
-
-    expect(actualJson).eql(expectJson);
   });
-})
+
+  it('single template', () => {
+    expectActual('a');
+  });
+
+  it('template with style', () => {
+    expectActual('b');
+  });
+
+  it('template with style and script', () => {
+    expectActual('c');
+  });
+
+  it('template with single inline element', () => {
+    expectActual('d');
+  });
+
+  it('template with multiple inline elements', () => {
+    expectActual('e');
+  });
+
+  it('parted files specifed in src', () => {
+    expectActual('f');
+  });
+
+  it('component by requiring src and specifing alias', () => {
+    expectActual('g');
+    expect(requireStub.callCount).eql(0);
+  });
+
+  it('component under same folder', () => {
+    expectActual('h');
+  });
+
+  it('template with config and data', () => {
+    expectActual('i');
+    expect(bootstrapStub.firstCall.args[1]).is.not.undefined;
+    expect(bootstrapStub.firstCall.args[2]).is.not.undefined;
+  });
+
+  it('template and use weex module', () => {
+    expectActual('j');
+    expect(requireStub.callCount).eql(1);
+    expect(requireStub.firstCall.args).eql(['@weex-module/modal']);
+  });
+
+  it('template by using custom language', () => {
+    expectActual('k');
+    expect(requireStub.callCount).eql(1);
+    expect(requireStub.firstCall.args).eql(['@weex-module/modal']);
+  });
+
+  it('template and require commonjs module', () => {
+    expectActual('l');
+    expect(requireStub.callCount).eql(1);
+    expect(requireStub.firstCall.args).eql(['@weex-module/modal']);
+  });
+
+  it('template and use weex module in commonjs module', () => {
+    expectActual('m');
+    expect(requireStub.callCount).eql(1);
+    expect(requireStub.firstCall.args).eql(['@weex-module/modal']);
+  });
+
+  it.skip('template with sourcemap', () => {
+    const actualStr = expectActual('n');
+    const map = extractMap(actualStr);
+    const smc = new SourceMap.SourceMapConsumer(map);
+
+    // new Array(276).fill(0).forEach((n, i) => {
+    //   i = i + 1
+    //   const original = smc.originalPositionFor({
+    //     line: i,
+    //     column: 0
+    //   })
+    //   if (original.source) {
+    //     console.log(i, original.line, original.source)
+    //   }
+    // })
+  });
+})
\ No newline at end of file
diff --git a/test/webpack.config.js b/test/webpack.config.js
index 5266dae..07b12d1 100644
--- a/test/webpack.config.js
+++ b/test/webpack.config.js
@@ -1,14 +1,19 @@
 var path = require('path')
+var cssnext = require('postcss-cssnext')
+
+var entry = {}
+var start = 'a'
+var end = 'n'
+var count = end.charCodeAt(0) - start.charCodeAt(0)
+
+new Array(count + 1).fill(0)
+  .forEach((n, i) => {
+    var name = String.fromCharCode(i + start.charCodeAt(0))
+    entry[name] = path.resolve(__dirname, 'spec', name + '.we?entry')
+  })
 
 module.exports = {
-  entry: {
-    sourcemap: path.resolve(__dirname, 'expect/sourcemap.we?entry=true'),
-    samename: path.resolve(__dirname, 'expect/samename.we?entry=true'),
-    exports: path.resolve(__dirname, 'expect/exports.we?entry=true'),
-    a: path.resolve(__dirname, 'a.js?entry=true'),
-    b: path.resolve(__dirname, 'expect/b.we?entry=true'),
-    z: path.resolve(__dirname, 'expect/z.we?entry=true')
-  },
+  entry: entry,
   output: {
     path: path.resolve(__dirname, 'actual'),
     filename: '[name].js'
@@ -18,30 +23,28 @@
     loaders: [
       {
         test: /\.we(\?[^?]+)?$/,
-        loaders: ['index.js']
+        loaders: ['lib/loader.js']
       },
       {
-        test: /\.js(\?[^?]+)?$/,
-        exclude: [
-          path.resolve(__dirname, 'lib')
-        ],
-        loaders: ['index.js?type=script', 'babel?presets[]=es2015']
-      },
-      {
-        test: /\.css(\?[^?]+)?$/,
-        loaders: ['index.js?type=style']
-      },
-      {
-        test: /\.less(\?[^?]+)?$/,
-        loaders: ['index.js?type=style', 'less']
-      },
-      {
-        test: /\.tpl(\?[^?]+)?$/,
-        loaders: ['index.js?type=tpl']
+        test: /\.js/,
+        loaders: ['babel?presets[]=es2015']
       }
     ]
   },
+  devtool: 'inline-source-map',
   resolveLoader: {
     modulesDirectories: ['./', './node_modules']
+  },
+  postcss: function() {
+    return [cssnext({
+      browsers: ['last 1 version']
+    })]
+  },
+  weex: {
+    lang: {
+      cssnext: ['postcss'],
+      jade: ['jade-html'],
+      coffee: ['coffee']
+    }
   }
 }